1function toggleAds() { 2 const remainingAds = document.querySelector('.remaining-ads'); 3 const button = document.querySelector('.toggle-button'); 4 5 if (remainingAds.classList.contains('adhidden')) { 6 // æ¾ç¤ºå¹¿å 7 remainingAds.classList.remove('adhidden'); 8 remainingAds.style.display = 'flex'; // 强å¶è®¾ç½®æ¾ç¤ºæ ·å¼ 9 // éåç§»é¤åå ç´ .icon-ad ç hidden ç±» 10 const ads = remainingAds.querySelectorAll('.icon-ad'); 11 ads.forEach(ad => { 12 ad.classList.remove('adhidden'); 13 }); 14 button.textContent = 'æ¶èµ·'; 15 } else { 16 // éè广å 17 remainingAds.classList.add('adhidden'); 18 remainingAds.style.display = 'none'; // 强å¶éèæ ·å¼ 19 20 button.textContent = 'å±å¼æ´å¤'; 21 } 22} 23 24 25async function fetchAndRenderSiteData() { 26 try { 27 const response = await fetch(`/site.json?timestamp=${Date.now()}`); 28 if (!response.ok) { 29 throw new Error('Failed to fetch site data'); 30 } 31 32 const encrypted = await response.text(); 33 const siteData = decodeSiteData(encrypted); 34 window.renderSiteSections(siteData); 35 attachUmamiAdTracking(); 36 document.querySelectorAll(".site-link-section").forEach(linkHandleEvent); 37 } catch (error) { 38 console.error('Error fetching or rendering site data:', error); 39 } 40} 41 42document.addEventListener('DOMContentLoaded', function () { 43 if (window.hasExecuted) return; 44 window.hasExecuted = true; 45 fetchAndRenderSiteData(); 46 const urlParams = new URLSearchParams(window.location.search); 47 const ref = urlParams.get('ref'); 48 if (!ref) return; 49 const today = new Date().toISOString().slice(0, 10); 50 const domain = location.hostname; 51 const cacheKey = `umami_ref_logged_${ref}_${today}_${domain}`; 52 if (localStorage.getItem(cacheKey)) return; 53 const timer = setInterval(() => { 54 if (typeof window.umami === 'object' && typeof umami.track === 'function') { 55 umami.track('ref_visit', { 56 ref, 57 date: today 58 }); 59 60 localStorage.setItem(cacheKey, '1'); 61 clearInterval(timer); 62 } 63 }, 200); 64}); 65 66 67function attachUmamiAdTracking() { 68 // 徿 广åç¹å»ç»è®¡ 69 document.querySelectorAll('.ad-link').forEach(link => { 70 link.addEventListener('click', function () { 71 if (typeof umami?.track === 'function') { 72 umami.track('ad_click', { 73 url: link.href, 74 title: link.querySelector('img')?.alt || '', 75 76 }); 77 } 78 }); 79 }); 80 // æ¨ªå¹ å¹¿åç¹å»ç»è®¡ï¼Banner/Banner2ï¼ 81 document.querySelectorAll('.streamer-box a, .streamer-box2 a, .site-banner-link').forEach(link => { 82 link.addEventListener('click', function () { 83 if (typeof umami?.track === 'function') { 84 umami.track('banner_click', { 85 url: link.href, 86 title: link.querySelector('img')?.alt || '', 87 88 }); 89 } 90 }); 91 }); 92} 93 94function linkHandleEvent(linkContainer) { 95 linkContainer.querySelectorAll('.referrerLink').forEach(link => { 96 link.addEventListener('click', function () { 97 if (typeof umami.track === 'function') { 98 umami.track('outbound_click', { 99 url: link.href, 100 title: link.textContent || '', 101 102 }); 103 } 104 105 }); 106 }); 107} 108 109class Banner2 { 110 constructor(nodeId, data) { 111 this.nodeId = nodeId; 112 this.node = document.getElementById(nodeId); 113 this.data = data; 114 this.bannerParent = undefined; 115 this.banner = undefined; 116 this.prevBtn = undefined; 117 this.nextBtn = undefined; 118 this.currentIndex = 0; // å½åå¾çç´¢å¼ 119 this.totalImages = 0; 120 this.autoSwitchInterval = 3000; // èªå¨åæ¢é´éæ¶é´ï¼æ¯«ç§ï¼ 121 this.autoSwitchTimer = undefined; // èªå¨åæ¢ç宿¶å¨ 122 this.liWidth = 0; 123 } 124
125 initCSS() { 126 let style = document.createElement('style'); 127 style.innerHTML = ` 128 .streamer-container2 { 129 width: 100%; 130 overflow-x: auto; 131 padding: 0 5px; 132 } 133 .streamer-box2 { 134 list-style: none; 135 padding: 0; 136 margin: 0; 137 } 138 .streamer-box2 li { 139 width: 100%; 140 max-width: 960px; 141 flex-shrink: 0; 142 margin: 2px auto; 143 } 144 .streamer-box2 li a { 145 display: block; 146 } 147 .streamer-box2 li img { 148 width: 100%; 149 height: auto; 150 max-height: 120px; 151 display: block; 152 } 153 @media screen and (max-width: 640px) { 154 .streamer-box2 li { 155 width: 100%; 156 } 157 } 158 `; 159 document.head.appendChild(style); 160 return this; 161 } 162 163 initDOM() { 164 this.node.innerHTML = '<div class="streamer-container2" id="streamer-container2-' + this.nodeId + '">' + 165 '<ul class="streamer-box2" id="streamer-box2-' + this.nodeId + '">' + 166 '</ul>' + 167 '</div>'; 168 return this; 169 } 170 171 initBanner() { 172 for (let i = 0; i < this.totalImages; i++) { 173 const li = document.createElement('li'); 174 li.innerHTML = `<a href="${this.data[i].url}" target="_blank" rel="noopener"><img src="${this.data[i].logo}"></a>`; 175 this.banner.appendChild(li); 176 } 177 } 178 179 init() { 180 this.initDOM(); 181 this.bannerParent = document.getElementById('streamer-container2-'+this.nodeId); 182 this.banner = document.getElementById('streamer-box2-'+this.nodeId); 183 this.totalImages = this.data.length; 184 this.initBanner(); 185 } 186 187 static getRandChar2(length) { 188 const letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; 189 let result = ''; 190 for (let i = 0; i < length; i++) { 191 result += letters.charAt(Math.floor(Math.random() * letters.length)); 192 } 193 return result; 194 } 195} 196 197class Banner { 198 constructor(nodeId, data) { 199 this.nodeId = nodeId; 200 this.node = document.getElementById(nodeId); 201 this.data = data; 202 this.bannerParent = undefined; 203 this.banner = undefined; 204 this.prevBtn = undefined; 205 this.nextBtn = undefined; 206 this.currentIndex = 0; // å½åå¾çç´¢å¼ 207 this.totalImages = 0; 208 this.autoSwitchInterval = 3000; // èªå¨åæ¢é´éæ¶é´ï¼æ¯«ç§ï¼ 209 this.autoSwitchTimer = undefined; // èªå¨åæ¢ç宿¶å¨ 210 this.liWidth = 0; 211 } 212 213 init() { 214 //this.initCSS(); 215 this.initDOM(); 216 this.bannerParent = document.getElementById('streamer-container-'+this.nodeId); 217 this.banner = document.getElementById('streamer-box-'+this.nodeId); 218 this.prevBtn = document.getElementById('prevBtn-'+this.nodeId); 219 this.nextBtn = document.getElementById('nextBtn-'+this.nodeId); 220 this.currentIndex = 0; // å½åå¾çç´¢å¼ 221 this.totalImages = this.data.length; 222 this.initBanner(); 223 this.startAutoSwitch(); 224 this.initEvent(); 225 } 226 227 initCSS() { 228 let style = document.createElement('style'); 229 style.innerHTML = `.streamer-container{position:relative;width:100%;max-width:960px;height:auto;margin:0 auto;overflow:hidden} 230 .streamer-box{display:flex;flex-wrap:nowrap;transition:transform .5s ease-in-out;list-style:none;padding: 0;margin: 0;} 231 .streamer-box li{height:auto;overflow:hidden} 232 .streamer-box li a{display:block;} 233 .streamer-box li img{max-width:100%;border: 0;} 234 .streamer-container .btn{position:absolute;top:50%;transform:translateY(-50%);background-color:rgba(0,0,0,.2);color:rgba(255,255,255,.6);border:none;padding:10px 15px;cursor:pointer;font-size:16px;z-index:2} 235 .streamer-container .btn:hover{background-color:rgba(0,0,0,.7)} 236 .streamer-container .btn.prev{left:10px} 237 .streamer-container .btn.next{right:10px} 238 @media screen and (max-width:640px){ 239 .streamer-container .btn{padding:0 3px;background-color:rgba(0,0,0,.2);color:rgba(255,255,255,.6)} 240 }`; 241 document.head.appendChild(style); 242 return this; 243 } 244 245 initDOM() { 246 this.node.innerHTML = '<div class="streamer-container" id="streamer-container-' + this.nodeId + '">' + 247 '<button class="btn prev" id="prevBtn-' + this.nodeId + '">â</button>' + 248 '<ul class="streamer-box" id="streamer-box-' + this.nodeId + '">' + 249 '</ul>' + 250 '<button class="btn next" id="nextBtn-' + this.nodeId + '">â¶</button>' + 251 '</div>'; 252 return this; 253 } 254 255 initBanner() { 256 this.liWidth = this.bannerParent.offsetWidth; 257 let ulWidth = this.liWidth * this.totalImages; 258 this.banner.style.width = ulWidth + 'px'; 259 260 for (let i = 0; i < this.totalImages; i++) { 261 const li = document.createElement('li'); 262 li.style.width = this.liWidth + 'px'; 263 li.innerHTML = `<a href="${this.data[i].url}" target="_blank"><img src="${this.data[i].logo}"></a>`; 264 this.banner.appendChild(li); 265 } 266 } 267 268 updateBanner() { 269 const offset = -(this.currentIndex * this.liWidth); // 计ç®åç§»ç¾åæ¯ 270 this.banner.style.transform = `translateX(${offset}px)`; 271 } 272 273 startAutoSwitch() { 274 this.autoSwitchTimer = setInterval(() => { 275 this.currentIndex = (this.currentIndex + 1) % this.totalImages; 276 this.updateBanner(); 277 }, this.autoSwitchInterval); 278 } 279 280 stopAutoSwitch() { 281 clearInterval(this.autoSwitchTimer); 282 } 283 284 showPrev() { 285 this.currentIndex = (this.currentIndex - 1 + this.totalImages) % this.totalImages; 286 this.stopAutoSwitch() 287 this.updateBanner(); 288 this.startAutoSwitch(); 289 } 290 291 showNext() { 292 this.currentIndex = (this.currentIndex + 1) % this.totalImages; 293 this.stopAutoSwitch() 294 this.updateBanner(); 295 this.startAutoSwitch(); 296 } 297 298 resetAutoSwitch() { 299 clearInterval(this.autoSwitchTimer); 300 this.startAutoSwitch(); 301 } 302 303 initEvent() { 304 this.prevBtn.addEventListener('click', this.showPrev.bind(this)); 305 this.nextBtn.addEventListener('click', this.showNext.bind(this)); 306 } 307 308 static getRandChar2(length) { 309 const letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; 310 let result = ''; 311 for (let i = 0; i < length; i++) { 312 result += letters.charAt(Math.floor(Math.random() * letters.length)); 313 } 314 return result; 315 } 316} 317function decodeSiteData(data) { 318 if (typeof data !== 'string' || !data.trim()) { 319 console.error('â æ æçè¾å ¥æ°æ®'); 320 return null; 321 } 322 try { 323 data = data 324 .replace(/\//g, '0') 325 .replace(/@/g, '/') 326 .replace(/\./g, '+') 327 .split('') 328 .reverse() 329 .join(''); 330 const mod = data.length % 4; 331 if (mod !== 0) { 332 data = data.padEnd(data.length + (4 - mod), '='); 333 } 334 const binaryStr = atob(data); 335 const bytes = Uint8Array.from(binaryStr, c =>
335 c.charCodeAt(0)); 336 const decoded = new TextDecoder('utf-8').decode(bytes); 337 return JSON.parse(decoded); 338 } catch (error) { 339 console.error('â site.json è§£ç 失败:', error); 340 return null; 341 } 342}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.