Custom Arka Plan Yöneticisi

Web siteleri için arka plan değiştirme [öncelikli manga-manhwa siteleri]

当前为 2025-01-28 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Custom Arka Plan Yöneticisi
  3. // @namespace http://vebascans.net/
  4. // @version 2.1
  5. // @description Web siteleri için arka plan değiştirme [öncelikli manga-manhwa siteleri]
  6. // @author Veba
  7. // @match https://*/*
  8. // @grant none
  9. // @icon https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhi0QDJZNeXWcaD9lXWMN2yenYt5XGrqfPavkCFpWLe01CpSEsMn7IGpbOLqxEfjx4QUUi4wgTw0Kc7vP7FrKjPKpcaaCu1N6QRJzlZvS_Wwr2r3kA10-E5wI7xObsZchd8YNSxySFZATPAr2bnrkANBUrmy8Rpdx-mxG8N6QDojEj0onaNNXF_6g-s/w200/logo.png
  10. // @homepageURL https://vebascans.net/
  11. // @supportURL https://vebascans.net/
  12. // ==/UserScript==
  13.  
  14. (function() {
  15. 'use strict';
  16.  
  17. // 1) SweetAlert2 kütüphanesini otomatik yükle:
  18. const script = document.createElement('script');
  19. script.src = 'https://cdn.jsdelivr.net/npm/sweetalert2@11';
  20. script.onload = main; // Kütüphane yüklendikten sonra main() fonksiyonunu çalıştır
  21. document.head.appendChild(script);
  22.  
  23. // 2) Tüm kodu main() içine alıyoruz:
  24. function main() {
  25.  
  26. /**************************************************************************
  27. * SweetAlert Tanımlaması
  28. **************************************************************************/
  29. const Toast = Swal.mixin({
  30. toast: true,
  31. position: "top",
  32. showConfirmButton: false,
  33. timer: 3000,
  34. timerProgressBar: true,
  35. didOpen: (toast) => {
  36. toast.onmouseenter = Swal.stopTimer;
  37. toast.onmouseleave = Swal.resumeTimer;
  38. }
  39. });
  40.  
  41. /**************************************************************************
  42. * 0) Sabitler
  43. **************************************************************************/
  44. const ACTIVE_KEY = 'VebaScans.net_custom_wp_active'; // Son seçilen veri (URL/Color)
  45. const HISTORY_KEY = 'VebaScans.net_custom_wp_history'; // Tüm geçmiş
  46. const SETTINGS_KEY = 'vebascans.net_custom_wp_settings'; // Arka plan ayarları (repeat/cover vs.)
  47.  
  48. /**************************************************************************
  49. * 1) Local Storage Yardımcı Fonksiyonları
  50. **************************************************************************/
  51. function getActiveData() {
  52. try {
  53. const str = localStorage.getItem(ACTIVE_KEY);
  54. return str ? JSON.parse(str) : null;
  55. } catch (e) {
  56. return null;
  57. }
  58. }
  59.  
  60. function setActiveData(obj) {
  61. localStorage.setItem(ACTIVE_KEY, JSON.stringify(obj));
  62. applyActiveDataToBody(); // Aktif veri her değiştiğinde body'yi güncelle
  63. }
  64.  
  65. function removeActiveData() {
  66. localStorage.removeItem(ACTIVE_KEY);
  67. applyActiveDataToBody();
  68. }
  69.  
  70. function getHistoryData() {
  71. try {
  72. const str = localStorage.getItem(HISTORY_KEY);
  73. return str ? JSON.parse(str) : [];
  74. } catch (e) {
  75. return [];
  76. }
  77. }
  78.  
  79. function addToHistory(obj) {
  80. const history = getHistoryData();
  81. history.push(obj);
  82. localStorage.setItem(HISTORY_KEY, JSON.stringify(history));
  83. }
  84.  
  85. // -- Ayarlar (Tekrarlı / Tek sefer)
  86. function getSettings() {
  87. try {
  88. const str = localStorage.getItem(SETTINGS_KEY);
  89. return str ? JSON.parse(str) : {};
  90. } catch (e) {
  91. return {};
  92. }
  93. }
  94.  
  95. function setSettings(newSettings) {
  96. localStorage.setItem(SETTINGS_KEY, JSON.stringify(newSettings));
  97. }
  98.  
  99. /**************************************************************************
  100. * 2) BODY Arkaplanını Aktif Veriye (URL/Color) ve Ayarlara Göre Uygulama
  101. **************************************************************************/
  102. function applyActiveDataToBody() {
  103. const activeData = getActiveData();
  104. if (!activeData) {
  105. // Aktif bir şey yoksa istersen varsayılan temize çek
  106. document.body.style.backgroundImage = 'none';
  107. document.body.style.backgroundColor = '';
  108. return;
  109. }
  110.  
  111. if (activeData.type === 'url') {
  112. // Body için arkaplan resmi
  113. document.body.style.backgroundImage = `url(${activeData.value})`;
  114. document.body.style.backgroundRepeat = 'no-repeat';
  115. document.body.style.backgroundSize = 'cover';
  116. document.body.style.backgroundColor = '';
  117.  
  118. // .body-wrap için deneme
  119.  
  120. try {
  121.  
  122. const bodyWrap = document.querySelector('body.text-ui-light .body-wrap');
  123. bodyWrap.style.backgroundImage = `url(${activeData.value})`;
  124. bodyWrap.style.backgroundRepeat = 'no-repeat';
  125. bodyWrap.style.backgroundSize = 'cover';
  126. bodyWrap.style.backgroundColor = '';
  127. } catch (error) {
  128. // .body-wrap yoksa hata görmezden gel
  129. }
  130. try {
  131. const sitecontent = document.querySelector('.site-content');
  132. sitecontent.style.backgroundImage = `url(${activeData.value})`;
  133. sitecontent.style.backgroundRepeat = 'no-repeat';
  134. sitecontent.style.backgroundSize = 'cover';
  135. sitecontent.style.backgroundColor = '';
  136. } catch (error) {
  137. // .site-content yoksa hata görmezden gel
  138. }
  139. } else if (activeData.type === 'color') {
  140. // Body için arkaplan rengi
  141. document.body.style.backgroundImage = 'none';
  142. document.body.style.backgroundColor = activeData.value;
  143.  
  144. // .body-wrap için deneme
  145. try {
  146. const bodyWrap = document.querySelector('body.text-ui-light .body-wrap');
  147. bodyWrap.style.backgroundImage = 'none';
  148. bodyWrap.style.backgroundColor = activeData.value;
  149. } catch (error) {
  150. // .body-wrap yoksa hata görmezden gel
  151. }
  152.  
  153. // .site-content için deneme
  154. try {
  155. const sitecontent = document.querySelector('.site-content');
  156. sitecontent.style.backgroundImage = 'none';
  157. sitecontent.style.backgroundColor = activeData.value;
  158. } catch (error) {
  159. // .site-content yoksa hata görmezden gel
  160. }
  161. }
  162. }
  163.  
  164. /**************************************************************************
  165. * 3) MODAL Arayüzü Oluşturma
  166. **************************************************************************/
  167. let modalOverlay, modalContent;
  168.  
  169. window.addEventListener('load', () => {
  170. createModal();
  171. createToggleShortcut(); // F7 ile aç/kapa
  172. applyActiveDataToBody(); // Sayfa açıldığında kaydedilmiş aktif veriyi uygula
  173. });
  174.  
  175. // F7 ile modal aç/kapa
  176. function createToggleShortcut() {
  177. window.addEventListener('keydown', (e) => {
  178. if (e.key === 'F7') {
  179. toggleModal();
  180. }
  181. });
  182. }
  183.  
  184. function toggleModal(forceOpen) {
  185. const isHidden = (modalOverlay.style.display === 'none');
  186. if (forceOpen === true) {
  187. showModal();
  188. } else if (forceOpen === false) {
  189. hideModal();
  190. } else {
  191. if (isHidden) showModal(); else hideModal();
  192. }
  193. }
  194.  
  195. function showModal() {
  196. modalOverlay.style.display = 'block';
  197. refreshHistoryList();
  198. refreshActiveLabel();
  199. refreshSettingsUI();
  200. }
  201.  
  202. function hideModal() {
  203. modalOverlay.style.display = 'none';
  204. }
  205.  
  206. function createModal() {
  207. // (1) Overlay
  208. modalOverlay = document.createElement('div');
  209. Object.assign(modalOverlay.style, {
  210. display: 'none',
  211. position: 'fixed',
  212. top: '0',
  213. left: '0',
  214. width: '100%',
  215. height: '100%',
  216. backgroundColor: 'rgba(0,0,0,0.5)',
  217. zIndex: '99999',
  218. color: '#000'
  219. });
  220. document.body.appendChild(modalOverlay);
  221.  
  222. // (2) İçerik
  223. modalContent = document.createElement('div');
  224. Object.assign(modalContent.style, {
  225. position: 'absolute',
  226. top: '50%',
  227. left: '50%',
  228. transform: 'translate(-50%, -50%)',
  229. width: '400px',
  230. backgroundColor: '#fff',
  231. padding: '20px',
  232. borderTopLeftRadius: '15px',
  233. borderBottomRightRadius: '15px',
  234. border: '3px solid black',
  235. minHeight: '400px',
  236. fontFamily: 'Arial, sans-serif',
  237. fontSize: '14px',
  238. fontWeight: 'normal',
  239. color: '#000',
  240. });
  241. modalOverlay.appendChild(modalContent);
  242.  
  243. // (3) Logo
  244. const img = document.createElement('img');
  245. img.src = 'https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhi0QDJZNeXWcaD9lXWMN2yenYt5XGrqfPavkCFpWLe01CpSEsMn7IGpbOLqxEfjx4QUUi4wgTw0Kc7vP7FrKjPKpcaaCu1N6QRJzlZvS_Wwr2r3kA4l0-E5wl7xObsZchd8YNSxySFZATPAr2bnrkANBUrmy8Rpdexe-mxG8N6QDojEj0onaNNXF_6g-s/w800/logo.png';
  246. img.alt = 'Logo';
  247. Object.assign(img.style, {
  248. width: '130px',
  249. position: 'absolute',
  250. top: '0',
  251. right: '50%',
  252. transform: 'translate(50%, -50%)'
  253. });
  254. modalContent.appendChild(img);
  255.  
  256. // (4) Başlık
  257. const header = document.createElement('h3');
  258. header.innerHTML = '<a href=\"https://www.vebascans.net/\" style=\"color: #402870; font-weight: 500; text-decoration: none; font-family: fantasy;\">Vebascans</a> - Custom Background';
  259. header.style.margin = '0 0 10px 0';
  260. header.style.color = 'black';
  261. header.style.marginTop = '45px';
  262. modalContent.appendChild(header);
  263.  
  264. // (5) Kapat butonu
  265. const closeBtn = document.createElement('button');
  266. closeBtn.innerHTML = `
  267. <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\">
  268. <g fill=\"none\" fill-rule=\"evenodd\">
  269. <path d=\"m12.593 23.258l-.011.002l-.071.035l-.02.004l-.014-.004l-.071-.035q-.016-.005-.024.005l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427q-.004-.016-.017-.018m.265-.113l-.013.002l-.185.093l-.01.01l-.003.011l.018.43l.005.012l.008.007l.201.093q.019.005.029-.008l.004-.014l-.034-.614q-.005-.018-.02-.022m-.715.002a.02.02 0 0 0-.027.006l-.006.014l-.034.614q.001.018.017.024l.015-.002l.201-.093l.01-.008l.004-.011l.017-.43l-.003-.012l-.01-.01z\"/>
  270. <path fill=\"currentColor\" d=\"m12 14.122l5.303 5.303a1.5 1.5 0 0 0 2.122-2.122L14.12 12l5.304-5.303a1.5 1.5 0 1 0-2.122-2.121L12 9.879L6.697 4.576a1.5 1.5 0 1 0-2.122 2.12L9.88 12l-5.304 5.304a1.5 1.5 0 1 0 2.122 2.12z\"/>
  271. </g>
  272. </svg>`;
  273. Object.assign(closeBtn.style, {
  274. position: 'absolute',
  275. top: '10px',
  276. right: '10px',
  277. border: 'none',
  278. background: 'transparent',
  279. cursor: 'pointer',
  280. color: 'black'
  281. });
  282. closeBtn.onclick = () => hideModal();
  283. modalContent.appendChild(closeBtn);
  284.  
  285. // (6) Seçim Menüsü (URL mi Renk mi)
  286. const selectDiv = document.createElement('div');
  287. Object.assign(selectDiv.style, {
  288. display: 'flex',
  289. flexDirection: 'row',
  290. gap: '5px',
  291. marginBottom: '10px'
  292. });
  293. modalContent.appendChild(selectDiv);
  294.  
  295. const selectLabel = document.createElement('label');
  296. selectLabel.textContent = 'Seçim: ';
  297. selectLabel.style.display = 'flex';
  298. selectLabel.style.alignItems = 'center';
  299. selectDiv.appendChild(selectLabel);
  300.  
  301. const selectInput = document.createElement('select');
  302. selectInput.id = 'typeSelect';
  303. selectInput.style.background ='white';
  304. selectInput.style.border ='2px solid black';
  305. selectInput.style.borderRadius ='3px';
  306. selectInput.style.color = 'black';
  307. const optUrl = new Option('URL', 'url');
  308. const optColor = new Option('Renk', 'color');
  309. selectInput.add(optUrl);
  310. selectInput.add(optColor);
  311. selectDiv.appendChild(selectInput);
  312.  
  313. // (7) URL input
  314. const urlInput = document.createElement('input');
  315. urlInput.type = 'text';
  316. urlInput.id = 'urlInput';
  317. urlInput.placeholder = 'Görsel URL giriniz...';
  318. urlInput.style.background ='transparent';
  319. urlInput.style.border ='2px solid black';
  320. urlInput.style.borderRadius ='3px';
  321. selectDiv.appendChild(urlInput);
  322.  
  323. // (8) Color input
  324. const colorInput = document.createElement('input');
  325. colorInput.type = 'color';
  326. colorInput.id = 'colorInput';
  327. colorInput.value = '#000000';
  328. colorInput.style.width = '50px';
  329. colorInput.style.height = '30px';
  330. colorInput.style.display = 'none';
  331. selectDiv.appendChild(colorInput);
  332.  
  333. // Seçim değişince hangi input görünsün?
  334. selectInput.addEventListener('change', () => {
  335. if (selectInput.value === 'url') {
  336. urlInput.style.display = 'inline-block';
  337. colorInput.style.display = 'none';
  338. } else {
  339. urlInput.style.display = 'none';
  340. colorInput.style.display = 'inline-block';
  341. }
  342. });
  343.  
  344. // (9) Aktar butonu
  345. const aktarBtn = document.createElement('button');
  346. aktarBtn.textContent = 'Aktar';
  347. aktarBtn.style.marginLeft = '5px';
  348. aktarBtn.style.padding = '5px 10px';
  349. aktarBtn.style.cursor = 'pointer';
  350. aktarBtn.style.color = 'black';
  351. aktarBtn.style.border ='2px solid black';
  352. aktarBtn.style.borderRadius ='3px';
  353. aktarBtn.style.background = 'transparent';
  354. selectDiv.appendChild(aktarBtn);
  355.  
  356. aktarBtn.onclick = () => {
  357. const currentType = selectInput.value; // 'url' | 'color'
  358. let currentValue = '';
  359. if (currentType === 'url') {
  360. currentValue = urlInput.value.trim();
  361. if (!currentValue) {
  362. Toast.fire({ icon: 'error', title: 'Lütfen bir URL girin.' });
  363. return;
  364. }
  365. } else {
  366. currentValue = colorInput.value; // #rrggbb
  367. if (!currentValue) {
  368. Toast.fire({ icon: 'error', title: 'Lütfen bir renk seçin.' });
  369. return;
  370. }
  371. }
  372.  
  373. // Yeni aktif obje
  374. const newActiveObj = { type: currentType, value: currentValue };
  375. setActiveData(newActiveObj);
  376. addToHistory(newActiveObj);
  377.  
  378. refreshHistoryList();
  379. refreshActiveLabel();
  380.  
  381. // URL tipini kullandıysa inputu temizleyelim
  382. if (currentType === 'url') {
  383. urlInput.value = '';
  384. }
  385. Toast.fire({ icon: 'success', title: 'Yeni aktif değer atandı ve body arkaplanı güncellendi!' });
  386. };
  387.  
  388. // (10) Tekrar / Tek Sefer AYARI
  389. const repeatDiv = document.createElement('div');
  390. repeatDiv.style.margin = '10px 0';
  391. repeatDiv.style.display = 'flex';
  392. repeatDiv.style.flexDirection = 'row';
  393. repeatDiv.style.gap = '10px';
  394. modalContent.appendChild(repeatDiv);
  395.  
  396. const repeatLabel = document.createElement('span');
  397. repeatLabel.textContent = 'Arkaplan Tekrarı:';
  398. repeatLabel.style.alignSelf = 'center';
  399. repeatDiv.appendChild(repeatLabel);
  400.  
  401. const labelRepeat = document.createElement('label');
  402. const radioRepeat = document.createElement('input');
  403. radioRepeat.type = 'radio';
  404. radioRepeat.name = 'bgRepeat';
  405. radioRepeat.value = 'repeat';
  406. radioRepeat.style.marginRight = '5px';
  407. labelRepeat.appendChild(radioRepeat);
  408. labelRepeat.appendChild(document.createTextNode('Tekrarlı'));
  409. repeatDiv.appendChild(labelRepeat);
  410.  
  411. const labelNoRepeat = document.createElement('label');
  412. const radioNoRepeat = document.createElement('input');
  413. radioNoRepeat.type = 'radio';
  414. radioNoRepeat.name = 'bgRepeat';
  415. radioNoRepeat.value = 'no-repeat';
  416. radioNoRepeat.style.marginRight = '5px';
  417. labelNoRepeat.appendChild(radioNoRepeat);
  418. labelNoRepeat.appendChild(document.createTextNode('Tek Sefer'));
  419. repeatDiv.appendChild(labelNoRepeat);
  420.  
  421. [radioRepeat, radioNoRepeat].forEach(radio => {
  422. radio.addEventListener('change', () => {
  423. const newVal = radio.value; // 'repeat' | 'no-repeat'
  424. const s = getSettings();
  425. s.bgRepeat = newVal;
  426. setSettings(s);
  427. applyActiveDataToBody();
  428. });
  429. });
  430.  
  431. // (11) Aktif Veriyi Sil
  432. const removeActiveBtn = document.createElement('button');
  433. removeActiveBtn.textContent = 'Aktif Veriyi Sil';
  434. removeActiveBtn.style.marginBottom = '10px';
  435. removeActiveBtn.style.padding = '5px 10px';
  436. removeActiveBtn.style.cursor = 'pointer';
  437. removeActiveBtn.style.color = 'black';
  438. removeActiveBtn.style.background = 'transparent';
  439. removeActiveBtn.style.border ='2px solid black';
  440. removeActiveBtn.style.borderRadius ='3px';
  441. modalContent.appendChild(removeActiveBtn);
  442.  
  443. removeActiveBtn.onclick = () => {
  444. removeActiveData();
  445. refreshHistoryList();
  446. refreshActiveLabel();
  447. Toast.fire({ icon: 'info', title: 'Aktif veri silindi. Arkaplan temizlendi.' });
  448. };
  449.  
  450. // (12) Şu anda aktif veriyi gösteren label
  451. const activeDiv = document.createElement('div');
  452. activeDiv.id = 'activeDiv';
  453. activeDiv.style.marginTop = '10px';
  454. modalContent.appendChild(activeDiv);
  455.  
  456. // (13) Geçmiş Başlık
  457. const historyTitle = document.createElement('h4');
  458. historyTitle.textContent = 'Geçmiş';
  459. historyTitle.style.margin = '10px 0 5px 0';
  460. modalContent.appendChild(historyTitle);
  461.  
  462. // (14) Geçmiş Container
  463. const historyContainer = document.createElement('div');
  464. historyContainer.id = 'historyContainer';
  465. historyContainer.style.maxHeight = '200px';
  466. historyContainer.style.overflowY = 'auto';
  467. historyContainer.style.border = '1px solid #ccc';
  468. historyContainer.style.padding = '5px';
  469. modalContent.appendChild(historyContainer);
  470. }
  471.  
  472. /**************************************************************************
  473. * 4) Geçmiş & Aktif Listeyi Güncelleme
  474. **************************************************************************/
  475. function refreshHistoryList() {
  476. const historyContainer = document.getElementById('historyContainer');
  477. if (!historyContainer) return;
  478.  
  479. historyContainer.innerHTML = '';
  480.  
  481. const historyData = getHistoryData();
  482. const activeData = getActiveData(); // {type:'...', value:'...'}
  483.  
  484. historyData.forEach((item) => {
  485. const row = document.createElement('div');
  486. row.style.display = 'flex';
  487. row.style.alignItems = 'center';
  488. row.style.marginBottom = '8px';
  489. row.style.cursor = 'pointer';
  490.  
  491. // URL ise küçük görsel
  492. if (item.type === 'url') {
  493. const imgThumb = document.createElement('img');
  494. imgThumb.src = item.value;
  495. imgThumb.alt = 'Görsel';
  496. imgThumb.style.width = '30px';
  497. imgThumb.style.height = '30px';
  498. imgThumb.style.objectFit = 'cover';
  499. imgThumb.style.marginRight = '8px';
  500. row.appendChild(imgThumb);
  501.  
  502. const label = document.createElement('span');
  503. label.textContent = 'URL';
  504. row.appendChild(label);
  505. }
  506. // Renk ise kutu
  507. else if (item.type === 'color') {
  508. const colorBox = document.createElement('span');
  509. colorBox.style.display = 'inline-block';
  510. colorBox.style.width = '30px';
  511. colorBox.style.height = '30px';
  512. colorBox.style.backgroundColor = item.value;
  513. colorBox.style.marginRight = '8px';
  514. colorBox.style.border = '1px solid #000';
  515. row.appendChild(colorBox);
  516.  
  517. const label = document.createElement('span');
  518. label.textContent = 'Renk';
  519. row.appendChild(label);
  520. }
  521.  
  522. // Aktif mi?
  523. if (activeData && activeData.type === item.type && activeData.value === item.value) {
  524. const activeSpan = document.createElement('span');
  525. activeSpan.textContent = ' (Şu anda aktif)';
  526. activeSpan.style.color = 'green';
  527. activeSpan.style.marginLeft = '5px';
  528. row.appendChild(activeSpan);
  529. }
  530.  
  531. // Tıklayınca bu itemi aktif yap
  532. row.addEventListener('click', () => {
  533. setActiveData(item);
  534. refreshHistoryList();
  535. refreshActiveLabel();
  536. Toast.fire({ icon: 'success', title: 'Aktif değer güncellendi!' });
  537. });
  538.  
  539. historyContainer.appendChild(row);
  540. });
  541. }
  542.  
  543. function refreshActiveLabel() {
  544. const activeDiv = document.getElementById('activeDiv');
  545. if (!activeDiv) return;
  546.  
  547. const activeData = getActiveData();
  548. if (!activeData) {
  549. activeDiv.textContent = 'Şu anda aktif bir değer yok.';
  550. } else {
  551. if (activeData.type === 'url') {
  552. activeDiv.innerHTML = `
  553. Aktif: URL
  554. <img src=\"${activeData.value}\"
  555. alt=\"Aktif Görsel\"
  556. style=\"width: 100px; height: auto; object-fit: cover; margin-left:5px;\"/>
  557. `;
  558. } else {
  559. activeDiv.innerHTML = `
  560. Aktif: Renk
  561. <span style=\"display:inline-block; width:20px; height:20px;
  562. background-color:${activeData.value};
  563. border:1px solid #000; vertical-align:middle;\">
  564. </span>
  565. ${activeData.value}
  566. `;
  567. }
  568. }
  569. }
  570.  
  571. /**************************************************************************
  572. * 5) Arkaplan Ayarı (Tekrar / Tek Sefer) Radyo Butonlarını Güncelleme
  573. **************************************************************************/
  574. function refreshSettingsUI() {
  575. const settings = getSettings();
  576. const bgRepeat = settings.bgRepeat || 'no-repeat'; // Varsayılan no-repeat
  577. const radios = document.getElementsByName('bgRepeat');
  578. radios.forEach(radio => {
  579. radio.checked = (radio.value === bgRepeat);
  580. });
  581. }
  582.  
  583. } // main() sonu
  584.  
  585. })(); // IIFE sonu