PageSourceSearch

https://solarpanelinfo.pk/libs/recaptcha.js

js solarpanelinfo.pk collected 2026-10-09 03:05:06 UTC 37,662 bytes, 1,072 lines download raw bytes

1(function (window, document) {
2  "use strict";
3  // SDK 配置
4  const SDK_CONFIG = {
5    recaptchaKey: "", // reCAPTCHA 密钥
6    recaptchaRatio: 50, // 抽样比例
7    recaptchaType: 1, // 检测类型,默认为 DAU 检测
8    isAdFilled: false, // 广告是否填充
9    isClickBlocked: false, // 广告点击是否被屏蔽
10    // 是否请求完成
11    isRequestCompleted: false,
12  };
13
14  // 工具函数
15  const utils = {
16    // 根据名称获取 Cookie 值
17    getCookie: function (name) {
18      const value = `; ${document.cookie}`;
19      const parts = value.split(`; ${name}=`);
20      if (parts.length === 2) return parts.pop().split(";").shift();
21      return null;
22    },
23
24    // 设置 Cookie,带过期时间(天数)
25    setCookie: function (name, value, days) {
26      const date = new Date();
27      date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
28      const expires = `expires=${date.toUTCString()}`;
29      document.cookie = `${name}=${value}; ${expires}; path=/`;
30    },
31
32    // 删除 Cookie
33    deleteCookie: function (name) {
34      document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`;
35    },
36
37    // 获取当前日期,格式为 YYYY-MM-DD
38    getCurrentDate: function () {
39      const today = new Date();
40      const year = today.getFullYear();
41      const month = String(today.getMonth() + 1).padStart(2, "0");
42      const day = String(today.getDate()).padStart(2, "0");
43      return `${year}-${month}-${day}`;
44    },
45
46    // 生成 1 到 100 的随机数
47    getRandomNumber: function () {
48      return Math.ceil(Math.random() * 100);
49    },
50
51    // 动态加载 reCAPTCHA 脚本
52    loadRecaptchaScript: function (key, callback) {
53      const script = document.createElement("script");
54      script.src = `https://www.google.com/recaptcha/api.js?render=${key}`;
55      script.onload = callback;
56      document.head.appendChild(script);
57    },
58
59    insertCss: function (css) {
60      const style = document.createElement("style");
61      style.type = "text/css";
62      style.innerHTML = css;
63      document.head.appendChild(style);
64    },
65
66    createScriptUrl: function (parent, url = "", dataSet, fn) {
67      if (typeof parent == "undefined") {
68        return;
69      }
70      let scriptEle = document.createElement("script");
71      scriptEle.defer = true;
72      scriptEle.src = url;
73      if (dataSet) {
74        scriptEle.dataset.id = dataSet;
75      }
76      scriptEle.onload = fn || function () { };
77      parent.insertBefore(scriptEle, parent.lastChild);
78    },
79
80    // 控制 iframe 点击状态
81    controlIframeClick: function (containerId, enable = false) {
82      const container = document.getElementById(containerId);
83      if (!container) return;
84
85      const iframe = container.querySelector('iframe');
86      if (!iframe) return;
87
88      if (enable) {
89        // 启用点击
90        iframe.style.pointerEvents = 'auto';
91        // 移除点击事件监听器
92        if (iframe._clickHandler) {
93          iframe.removeEventListener('click', iframe._clickHandler);
94        }
95      } else {
96        // 禁用点击
97        iframe.style.pointerEvents = 'none';
98        // 添加点击事件监听器
99        iframe._clickHandler = function (e) {
100          e.preventDefault();
101          e.stopPropagation();
102        };
103        iframe.addEventListener('click', iframe._clickHandler);
104      }
105    },
106    // 获取 iframe 内的广告链接
107    getAdLink: function (containerId) {
108      const container = document.getElementById(containerId);
109      if (!container) return null;
110
111      const iframe = container.querySelector('iframe');
112      if (!iframe) return null;
113
114      try {
115        // 尝试获取 iframe 内的文档
116        const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
117        // 查找广告链接
118        const adLink = iframeDoc.querySelector('a[href*="googleadservices.com"]') ||
119          iframeDoc.querySelector('a[href*="doubleclick.net"]');
120        return adLink ? adLink.href : null;
121      } catch (e) {
122        // console.error('无法访问 iframe 内容:', e);
123        return null;
124      }
125    },
126
127    // 执行广告链接跳转
128    executeAdRedirect: function (containerId) {
129      const adLink = this.getAdLink(containerId);
130      if (adLink) {
131        window.open(adLink, '_blank');
132      }
133    },
134
135    // 执行 reCAPTCHA 并返回 token
136    executeRecaptcha: function (key, action) {
137      return new Promise((resolve, reject) => {
138        const url = location.href;
139        const domain = new URL(url).hostname.replace('www.', '').split('.')[0];
140        var prefix = location.origin + "/" + domain.substring(0, 1) + ".gif?s=reCAPTCHA&a=" + domain + "&t=";
141
142        var status = ["Failed", "", "Error", "requstFailed"];
143        grecaptcha.ready(function () {
144          grecaptcha
145            .execute(key, { action: "submit" })
146            .then(function (token) {
147              var client = new XMLHttpRequest();
148              client.timeout = 60000;
149              client.onerror = function (error) {
150                var url = prefix + status[status.length - 1];
151                utils.createImage(url);
152                return reject(error);
153              };
154              client.onreadystatechange = function () {
155                if (client.readyState === 4 && client.status === 200) {
156                  var response = JSON.parse(client.responseText);
157                  var codeIndex = response.result > status.length ? status.length : response.result;
158                  const statusCode = (codeIndex === 1 ? response.score : status[codeIndex]);
159
160                  const isOnemob = document.cookie.indexOf("onemob") !== -1; // 判断是否是onemob
161                  if (isOnemob) {
162                    // if (SDK_CONFIG.recaptchaType == 6 || SDK_CONFIG.recaptchaType == 5) {
163                    let prefixHostName = location.hostname;
164                    let cookieUrl = location.origin + "/" + domain.substring(0, 1) + ".gif?s=reCAPTCHA&a=" + prefixHostName + "&t=" + statusCode + "&_=" + Date.now();
165                    utils.createImage(cookieUrl);
166                    const cookieId = utils.getCookie("onemob") || "获取失败!";
167                    const tmkTkUrl = `https://gtmk.gamehkconcept.com/api/rec
167aptcha?id=${cookieId}&score=${response.score}`;
168                    utils.createImage(tmkTkUrl);
169                    // }
170                  }
171
172                  const currentDate = utils.getCurrentDate();
173                  utils.setCookie("recaptchaScore", response.score, 1); // 记录分数
174                  utils.setCookie("queryDate", currentDate, 1); // 记录处理日期
175
176                  if (response && response.result === 1 && response.score < 0.5) {
177                    if (SDK_CONFIG.recaptchaType === 1) {
178                    }
179                    // return reject(response);
180                  } else {
181                    // 校验通过,启用 iframe 点击并执行跳转
182                    utils.enableAdContainerInteraction();
183                  }
184
185                  return resolve(response);
186                }
187              };
188
189              client.open("POST", location.origin + "/recap?response=" + token);
190              client.send();
191            });
192        });
193      });
194    },
195
196    // 上报 reCAPTCHA 结果
197    reportResult: function (url) {
198      const valueScore = document.cookie.indexOf("recaptchaScore") !== -1;
199      if (valueScore) {
200        const score = parseFloat(utils.getCookie("recaptchaScore"));
201        const cookieId = utils.getCookie("onemob") || "获取失败!";
202        const tmkTkUrl = `https://gtmk.gamehkconcept.com/api/recaptcha?id=${cookieId}&score=${score}`;
203        utils.createImage(tmkTkUrl);
204      }
205    },
206    // 创建图片并返回 Promise
207    createImage: function (url) {
208      return new Promise(function (resolve, reject) {
209        var img = document.createElement("img");
210        img.src = url;
211        img.style.display = "none";
212        document.body.appendChild(img);
213        resolve();
214        img.onload = function () { };
215        img.onerror = function () {
216          reject();
217        }
218      });
219    },
220    // 自动点击指定区域
221    autoClickArea: function (selector, options = {}) {
222      const {
223        interval = 1000, // 点击间隔时间(ms)
224        maxClicks = 1,   // 最大点击次数
225        callback = null  // 点击回调函数
226      } = options;
227
228      let clickCount = 0;
229      const element = document.querySelector(selector);
230
231      if (!element) {
232        console.warn(`Element not found: ${selector}`);
233        return;
234      }
235
236      const clickInterval = setInterval(() => {
237        if (clickCount >= maxClicks) {
238          clearInterval(clickInterval);
239          return;
240        }
241
242        // 创建并触发点击事件
243        const clickEvent = new MouseEvent('click', {
244          bubbles: true,
245          cancelable: true,
246          view: window
247        });
248
249        element.dispatchEvent(clickEvent);
250        clickCount++;
251
252        // 执行回调函数
253        if (callback && typeof callback === 'function') {
254          callback(clickCount);
255        }
256      }, interval);
257
258      // 返回停止函数
259      return () => {
260        clearInterval(clickInterval);
261      };
262    },
263    // 启用广告容器点击和样式
264    enableAdContainerInteraction: function () {
265      SDK_CONFIG.isRequestCompleted = true;
266      // 启用所有广告容器的点击和重定向
267      const containers = document.querySelectorAll('[id^="ad-filled-container-"]');
268      containers.forEach(container => {
269        this.controlIframeClick(container.id, true);
270        // this.executeAdRedirect(container.id);
271      });
272
273      // 添加必要的样式
274      // const style = document.createElement('style');
275      // style.innerHTML = `
276      //       iframe { pointer-events: auto !important; }
277      //       #ad-filled-container-1 iframe { pointer-events: auto !important; }
278      //       .trc_related_container * {
279      //         pointer-events: auto !important;
280      //       }
281      //       #taboola-homepage-widget_hkgameworld > div {
282      //         pointer-events: auto !important;
283      //       }
284      //     `;
285      // document.head.appendChild(style);
286    },
287  };
288
289  // SDK 核心逻辑
290  const RecaptchaSDK = {
291    // 初始化 SDK
292    init: function (config) {
293      Object.assign(SDK_CONFIG, config); // 合并配置
294      this.handleRecaptchaFlow();
294 // 开始处理 reCAPTCHA 流程
295      this.handleAdDisplay(); // 根据分数判断显示广告
296      utils.reportResult(); // 上报结果
297    },
298    // 根据分数判断显示广告
299    handleAdDisplay: function (enable = false) {
300      const { recaptchaKey, recaptchaType, recaptchaRatio } = SDK_CONFIG;
301      const score = parseFloat(utils.getCookie("recaptchaScore"));
302      // 添加特定的 CSS 样式,禁用 Taboola 相关容器的点击事件
303      const css = `
304          .trc_related_container * {
305              pointer-events: none !important;
306          }
307          #taboola-homepage-widget_hkgameworld > div {
308              pointer-events: none !important;
309          }
310        `;
311      const style = document.createElement('style');
312      style.innerHTML = css;
313      document.head.appendChild(style);
314
315      const clickCheckDate = utils.getCookie("clickCheckDate");
316      const currentDate = utils.getCurrentDate();
317
318      if (recaptchaType == 2) {
319        utils.enableAdContainerInteraction();
320      }
321
322      if (clickCheckDate === currentDate && score >= 0.5) {
323        utils.enableAdContainerInteraction();
324      }
325
326      if (enable) {
327        utils.enableAdContainerInteraction();
328      }
329    },
330    // 根据类型处理 reCAPTCHA 流程
331    handleRecaptchaFlow: function () {
332      const { recaptchaKey, recaptchaType, recaptchaRatio } = SDK_CONFIG;
333      // console.log(recaptchaKey, recaptchaType, recaptchaRatio)
334      // 检查 reCAPTCHA 密钥是否存在
335      if (!recaptchaKey) {
336        console.error("reCAPTCHA 密钥缺失。");
337        return;
338      }
339
340      // 根据类型调用不同的处理函数
341      switch (parseInt(recaptchaType)) {
342        case 1:
343          this.handleDAUDetection(); // DAU 检测
344          break;
345        case 2:
346          this.handleClickDetection(); // 点击检测
347          break;
348        case 3:
349          this.handleClickFiltering(); // 点击过滤
350          break;
351        case 4:
352          this.handleAdRequestFiltering(); // 广告请求过滤
353          break;
354        case 5:
355          this.handleZhiziDAUDetection(); // 智子 DAU 检测
356          break;
357        case 6:
358          this.handleZhiziAdRequestFiltering(); // 智子展示过滤广告请求
359          break;
360        default:
361          console.error("无效的 reCAPTCHA 类型。");
362      }
363    },
364
365    // 情况一:DAU 检测
366    handleDAUDetection: function () {
367      const { recaptchaKey, recaptchaRatio } = SDK_CONFIG;
368      // console.log(recaptchaKey, recaptchaRatio)
369      // 步骤 2:检查当天是否已经处理过
370      const queryDate = utils.getCookie("queryDate");
371      const currentDate = utils.getCurrentDate();
372      if (queryDate === currentDate) return;
373
374      // 步骤 3:生成随机数并与抽样比例比较
375      const randomNumber = utils.getRandomNumber();
376      if (randomNumber > recaptchaRatio) return;
377
378      // 步骤 4:加载 reCAPTCHA 并执行
379      utils.loadRecaptchaScript(recaptchaKey, () => {
380        utils.executeRecaptcha(recaptchaKey, "dau").then((token) => {
381          utils.setCookie("queryDate", currentDate, 1); // 记录处理日期
382        });
383      });
384    },
385
386    // 情况二:点击检测
387    handleClickDetection: function () {
388      const { recaptchaKey, recaptchaRatio, isAdFilled, isClickBlocked, eventList, isRequestCompleted } = SDK_CONFIG;
389
390      // 添加点击锁变量
391      let isClickLocked = false;
392      const CLICK_LOCK_TIME = 3000; // 点击锁定时间(毫秒)
393
394      // 步骤 2:检查广告是否填充且未被屏蔽
395      if (!isAdFilled || isClickBlocked) return;
396
397      let isAdClick = false;
398      const currentDate = utils.getCurrentDate();
399
400      document.body.addEventListener('click', function (event) {
401        if (event.target.tagName === 'IFRAME' || event.target.closest('iframe')) {
402          console.log('用户点击了 iframe 元素或内部');
403        }
404      });
405
406      // 方法3:检测通过 iframe 内容获取焦点
407      window.addEventListener('blur', function () {
408        const iframes = document.querySelectorAll('iframe');
409        const activeElement = document.activeElement;
410
411        if (Array.from(iframes).includes(activeElement)) {
412          console.log('用户与 iframe 内容交互了');
413          // 步骤 4:检查当天是否已经处理过
414          const clickCheckDate = utils.getCookie("clickCheckDate");
415          if (clickCheckDate === currentDate) {
416            return;
417          }
418
419          // 步骤 5:生成随机数并与抽样比例比较
420          const randomNumber = utils.getRandomNumber();
421          if (randomNumber > recaptchaRatio) return;
422
423          // 步骤 6:加载 reCAPTCHA 并执行
424          utils.loadRecaptchaScript(recaptchaKey, () => {
425            utils.executeRecaptcha(recaptchaKey, "click").then((token) => {
426              utils.enableAdContainerInteraction();
427              utils.setCookie("clickCheckDate", currentDate, 1); // 记录处理日期
428              const href = document.querySelector(".item-thumbnail-href");
429              if (href) {
430                window.open(href.href, '_blank');
431              }
432            }).catch((res) => {
433              console.log(res);
434              utils.enableAdContainerInteraction();
435              utils.setCookie("clickCheckDate", currentDate, 1); // 记录处理日期
436            });
437          });
438        }
439      });
440    },
441
442    // 情况三:点击过滤
443    handleClickFiltering: function () {
444      const { recaptchaKey, recaptchaRatio, isAdFilled, isClickBlocked, isRequestCompleted } = SDK_CONFIG;
445
446      // 添加点击锁变量
447      let isClickLocked = false;
448      const CLICK_LOCK_TIME = 3000; // 点击锁定时间(毫秒)
449
450      // 步骤 2:检查广告是否填充且未被屏蔽
451      if (!isAdFilled || isClickBlocked) return;
452
453      let isAdClick = false;
454      // 步骤 3:添加点击事件监听器
455      document.addEventListener("click", (event) => {
456        const score = parseFloat(utils.getCookie("recaptchaScore"));
457        // 步骤 4:检查历史分数
458        if (score >= 0.5) {
459          return; // 分数合格,允许点击
460        }
461
462        // 如果点击被锁定,直接返回
463        if (isClickLocked) {
464          event.preventDefault();
465          event.stopPropagation();
466          console.log('点击太频繁,请稍后再试');
467          return;
468        }
469
470        // for (let i = 0; i < 4; i++) {
471        // 动态生成广告容器的 ID
472        let elid = `ad-filled-container-${i + 1}`;
473        const adElement = document.getElementById(elid);
474
475        // 如果广告容器存在且包含点击目标
476        if (adElement && adElement.contains(event.target)) {
477          console.log(adElement);
478          isAdClick = true;
479          // break;
480        }
481        // }
482
483        if (!isAdClick) {
484          return;
485        }
486
487        // 设置点击锁
488        isClickLocked = true;
489        setTimeout(() => {
490          isClickLocked = false;
491        }, CLICK_LOCK_TIME);
492
493        if (score < 0.5) {
494          event.preventDefault();
495          event.stopPropagation();
496          return; // 分数不合格,拦截点击
497        }
498
499        // 步骤 5:生成随机数并与抽样比例比较
500        const randomNumber = utils.getRandomNumber();
501        if (randomNumber > recaptchaRatio) return;
502
503        // 步骤 6:加载 reCAPTCHA 并执行
504        utils.loadRecaptchaScript(recaptchaKey, () => {
505          utils.executeRecaptcha(recaptchaKey, "click").then((token) => {
506            const currentDate = utils.getCurrentDate();
507            utils.setCookie("clickCheckDate", currentDate, 1); // 记录处理日期
508            const href = document.querySelector(".item-thumbnail-href");
509            if (href) {
510              window.open(href.href, '_blank');
511            }
512          }).catch((res) => {
513            const currentDate = utils.getCurrentDate();
514            utils.setCookie("clickCheckDate", currentDate, 1); // 记录处理日期
515            console.log(res);
516          });
517        });
518      });
519    },
520
521    // 情况四:广告请求过滤
522    handleAdRequestFiltering: function () {
523      const { recaptchaKey, recaptchaRatio } = SDK_CONFIG;
524
525      // 步骤 2:检查历史分数 
526      const score = parseFloat(utils.getCookie("recaptchaScore"));
527      if (score >= 0.5) return; // 分数合格,允许广告请求
528      if (score < 0.5) return; // 分数不合格,拦截广告请求
529      console.log("score", score);
530      // 步骤 3:生成随机数并与抽样比例比较
531      const randomNumber = utils.getRandomNumber();
532      if (randomNumber > recaptchaRatio) return;
533
534      // 步骤 4:加载 reCAPTCHA 并执行
535      utils.loadRecaptchaScript(recaptchaKey, () => {
536        utils.executeRecaptcha(recaptchaKey, "ad_request").then((token) => {
537        });
538      });
539    },
540    // 情况五:智子 DAU 检测
541    handleZhiziDAUDetection: function () {
542      const { recaptchaKey, recaptchaRatio } = SDK_CONFIG;
543
544      // 检查是否有 onemob cookie
545      const isOnemob = document.cookie.indexOf("onemob") !== -1;
546      if (!isOnemob) {
547        return; // 如果没有 onemob cookie,直接返回
548      }
549
550      // 检查当天是否已经处理过
551      const zhiziQueryDate = utils.getCookie("zhiziQueryDate");
552      const currentDate = utils.getCurrentDate();
553      if (zhiziQueryDate === currentDate) {
554        return; // 如果当天已经检测过,直接返回
555      }
556
557      // 生成随机数并与抽样比例比较
558      const randomNumber = utils.getRandomNumber();
559      if (randomNumber > recaptchaRatio) {
560        return; // 如果不在抽样范围内,直接返回
561      }
562
563      // 加载 reCAPTCHA 并执行
564      utils.loadRecaptchaScript(recaptchaKey, () => {
565        utils.executeRecaptcha(recaptchaKey, "zhizi_dau").then((token) => {
566          // 记录处理日期
567          utils.setCookie("zhiziQueryDate", currentDate, 1);
568        }).catch((error) => {
569          utils.setCookie("zhiziQueryDate", currentDate, 1);
570          // console.log("智子 DAU 检测失败:", error);
571        });
572      });
573    },
574    // 情况六:智子展示过滤广告请求
575    handleZhiziAdRequestFiltering: function () {
576      const { recaptchaKey, recaptchaRatio } = SDK_CONFIG;
577
578      // 检查是否有 onemob cookie
579      const isOnemob = document.cookie.indexOf("onemob") !== -1;
580      if (!isOnemob) {
581        return; // 如果没有 onemob cookie,直接返回
582      }
583
584      // 检查当天是否已经处理过
585      const zhiziAdRequestDate = utils.getCookie("zhiziAdRequestDate");
586      const currentDate = utils.getCurrentDate();
587      if (zhiziAdRequestDate === currentDate) {
588        return; // 如果当天已经检测过,直接返回
589      }
590
591      // 生成随机数并与抽样比例比较
592      const randomNumber = utils.getRandomNumber();
593      if (randomNumber > recaptchaRatio) {
594        // setTimeout(() => {
595        //   eventBus && eventBus.emit('event_recapData', 999);
596        // }, 1000);
597        return; // 如果不在抽样范围内,直接返回
598      }
599
600      // 加载 reCAPTCHA 并执行
601      utils.loadRecaptchaScript(recaptchaKey, () => {
602        utils.executeRecaptcha(recaptchaKey, "zhizi_ad_request").then((response) => {
603          // 记录处理日期
604          utils.setCookie("zhiziAdRequestDate", currentDate, 1);
605          const score = parseFloat(utils.getCookie("recaptchaScore"));
606          if (score < 0.5) {
607            // 分数小于 0.5,不请求广告
608            console.log("广告请求被过滤,分数小于 0.5");
609          } else {
610            // utils.createScriptUrl(document.body);
611            // eventBus && eventBus.emit('event_recapData', response.score);
612            // 继续请求广告
613            console.log("继续请求广告");
614          }
615        }).catch((error) => {
616          // eventBus && eventBus.emit('event_recapData', 999);
617          utils.setCookie("zhiziAdRequestDate", currentDate, 1);
618          console.error("智子展示过滤广告失败:", error);
619        });
620      });
621    },
622    // 自动点击指定区域
623    autoClick: function (selector, options = {}) {
624      return utils.autoClickArea(selector, options);
625    },
626  };
627
628  // 将 SDK 暴露到全局
629  window.RecaptchaSDK = RecaptchaSDK;
630})(window, document);
631
632
633(function (window, document) {
634  "use strict";
635
636  // 配置参数
637  const CONFIG = {
638    // 特定ID前缀,可根据需要修改
639    idPrefix: "ad-filled-",
640    // id计数检测次数,根据需要修改
641    adCount: 0,
642    // 检测间隔时间(ms)
643    checkInterval: 200,
644    // 最大检测次数
645    maxChecks: 20,
646    // 广告类型
647    adTypes: {
648      ADX: "adx",
649      ADSENSE: "adsense",
650      TB: "tb",
651      UME: "ume",
652    },
653  };
654
655  // 工具函数
656  const utils = {
657    /**
658     * 生成唯一ID
659     * @param {string} prefix - ID前缀
660     * @param {string} type - 广告类型
661     * @returns {string} 唯一ID
662     */
663    generateId: function (prefix, type) {
664      CONFIG.adCount = 1;
665      return `${prefix}container-${CONFIG.adCount}`;
666      // return `${prefix}${type}-${Math.random().toString(36).substr(2, 9)}`;
667    },
668    /**
669     * 插入CSS代码
670     * @param {string} css - CSS代码
671     */
672    insertCss: function (css) {
673      const style = document.createElement("style");
674      style.type = "text/css";
675      style.innerHTML = css;
676      document.head.appendChild(style);
677    },
678    /**
679     * 包装广告元素
680     * @param {HTMLElement} adElement - 广告元素
681     * @returns {HTMLElement} 包装后的元素
682     */
683    wrapElement: function (adElement) {
684      if (!adElement || adElement.parentNode.classList.contains("ad-wrapper")) {
685        return adElement.parentNode;
686      }
687
688      const wrapper = document.createElement("div");
689      wrapper.className = "ad-wrapper";
690      wrapper.style.cssText = "width:100%;position:relative;";
691
692      adElement.parentNode.insertBefore(wrapper, adElement);
693      wrapper.appendChild(adElement);
694
695      return wrapper;
696    },
697
698    /**
699     * 设置元素ID
700     * @param {HTMLElement} element - 目标元素
701     * @param {string} id - 要设置的ID
702     */
703    setElementId: function (element, id) {
704      if (element) {
705        element.id = id;
706        console.log(`ID已设置: ${id}`);
707        return id;
708      }
709    },
710    /**
711     * 处理广告位收缩
712     * @param {HTMLElement} element - 广告元素
713     * @param {boolean} shouldCollapse - 是否应该收缩
714     */
715    handleCollapse: function (element, shouldCollapse) {
716      if (!element) return;
717
718      if (shouldCollapse) {
719        element.id = "";
720        element.style.height = "0";
721        element.style.overflow = "hidden";
722      } else {
723        element.style.height = "";
724        element.style.overflow = "";
725      }
726    },
727    // 控制 iframe 点击状态
728    controlIframeClick: function (containerId, enable = false) {
729      const container = document.getElementById(containerId);
730      if (!container) return;
731
732      const iframe = container.querySelector('iframe');
733      if (!iframe) return;
734
735      if (enable) {
736        // 启用点击
737        iframe.style.pointerEvents = 'auto';
738        // 移除点击事件监听器
739        if (iframe._clickHandler) {
740          iframe.removeEventListener('click', iframe._clickHandler);
741        }
742      } else {
743        // 禁用点击
744        iframe.style.pointerEvents = 'none';
745        // 添加点击事件监听器
746        iframe._clickHandler = function (e) {
747          e.preventDefault();
748          e.stopPropagation();
749        };
750        iframe.addEventListener('click', iframe._clickHandler);
751      }
752    },
753    createScriptUrl: function (parent, url = "", dataSet, fn) {
754      if (typeof parent == "undefined") {
755        return;
756      }
757      let scriptEle = document.createElement("script");
758      scriptEle.defer = true;
759      scriptEle.src = url;
760      if (dataSet) {
761        scriptEle.dataset.id = dataSet;
762      }
763      scriptEle.onload = fn || function () { };
764      parent.insertBefore(scriptEle, parent.lastChild);
765    },
766  };
767
768  // 广告处理器
769  const adHandlers = {
770    /**
771     * 处理ADX广告(MX、GS)
772     * @param {Object} options - 配置选项
773     */
774    handleAdx: function (options) {
775      const { adElementSelector, idPrefix } = options;
776      const adElements = document.querySelectorAll('div[id^="div-gpt-ad-"]');
777
778      //   console.log("ADX广告处理中...", adElements);
779      if (!adElements.length) return;
780      window.isLoaded = true;
781      // 设置Google广告事件监听
782      window.googletag = window.googletag || { cmd: [] };
783      window.googletag.cmd.push(function () {
784        window.googletag
785          .pubads()
786          .addEventListener("slotRenderEnded", function (event) {
787            // 查找对应的广告元素
788            adElements.forEach(function (adElement, index) {
789              const slotId = adElement.id;
790              const slotElementId = event.slot.getSlotElementId();
791              if (!event.isEmpty && slotElementId === slotId) {
792                // const wrapper = utils.wrapElement(adElement);
793                // 广告有填充,给外层div赋值特定id
794                if (adElement.parentNode) {
795                  adElement.parentNode.id = utils.generateId(idPrefix, CONFIG.adTypes.ADX);
796                }
797                window.isLoaded && AdFillDetector.handleQuery({ isAdFilled: true, eventList: [slotId] });
798              } else {
799                window.isLoaded && AdFillDetector.handleQuery({ isAdFilled: false, eventList: [""] });
800              }
801            });
802          });
803      });
804    },
805
806    /**
807     * 处理Adsense固定广告
808     * @param {Object} options - 配置选项
809     */
810    handleAdsense: function (options) {
811      const { adElementSelector, idPrefix } = options;
812      const adElements = document.querySelectorAll(adElementSelector);
813      // console.log('adElements', adElements);
814      if (!adElements.length) return;
815      window.isLoaded = true;
816      adElements.forEach(function (adElement) {
817        // console.log("Adsense广告处理中...", adElement, adElementSelector);
818        let checkCount = 0;
819        if (typeof MutationObserver !== 'undefined') {
820          const observer = new MutationObserver(function (mutations) {
821            mutations.forEach(function (mutation) {
822              if (
823                mutation.type === "attributes" &&
824                mutation.attributeName === "data-ad-status"
825              ) {
826                const status = adElement.getAttribute("data-ad-status");
827
828                if (status === "filled") {
829                  // 广告有填充,赋值特定id
830                  const eleid = utils.setElementId(
831                    adElement,
832                    utils.generateId(idPrefix, CONFIG.adTypes.ADSENSE)
833                  );
834                  window.isLoaded && AdFillDetector.handleQuery({ isAdFilled: true, eventList: [adElement.id] });
835                  observer.disconnect();
836                } else if (status === "unfilled") {
837                  window.isLoaded && AdFillDetector.handleQuery({ isAdFilled: false, eventList: [""] });
838                  // 广告无填充,收缩广告位
839                  observer.disconnect();
840                }
841              }
842            });
843          });
844          // 开始观察
845          observer.observe(adElement, { attributes: true });
846        } else {
847          // 备用方案:定时检查
848          const intervalId = setInterval(function () {
849            checkCount++;
850            const status = adElement.getAttribute("data-ad-status");
851
852            if (status === "filled") {
853              utils.setElementId(
854                adElement,
855                utils.generateId(idPrefix, CONFIG.adTypes.ADSENSE)
856              );
857              window.isLoaded && AdFillDetector.handleQuery({ isAdFilled: true, eventList: [adElement.id] });
858              // utils.handleCollapse(adElement, false);
859              clearInterval(intervalId);
860            } else if (status === "unfilled" || checkCount >= CONFIG.maxChecks) {
861              // utils.handleCollapse(adElement, true);
862              clearInterval(intervalId);
863            }
864          }, CONFIG.checkInterval);
865        }
866      });
867    },
868
869    /**
870     * 处理TB广告
871     * @param {Object} options - 配置选项
872     */
873    handleTb: function (options) {
874      const { adElementSelector, idPrefix } = options;
875      const adElements = document.querySelectorAll(adElementSelector);
876
877      if (!adElements.length) return;
878      window.isLoaded = true;
879      adElements.forEach(function (adElement) {
880        // TB广告默认填充100%,直接包装并赋值ID
881        // const wrapper = utils.wrapElement(adElement);
882        utils.setElementId(
883          adElement,
884          utils.generateId(idPrefix, CONFIG.adTypes.TB)
885        );
886        window.isLoaded && AdFillDetector.handleQuery({ isAdFilled: true, eventList: [adElement.id] });
887      });
888    },
889
890    /**
891     * 处理UME广告
892     * @param {Object} options - 配置选项
893     */
894    handleUme: function (options) {
895      const { adElementSelector, newsElementSelector, idPrefix } = options;
896      window.isLoaded = true;
897      if (typeof MutationObserver === 'undefined') {
898        window.isLoaded && AdFillDetector.handleQuery({ isAdFilled: true, eventList: [] });
899        return;
900      }
901      const observer = new MutationObserver((mutationsList, observer) => {
902        const adElements = document.querySelectorAll(newsElementSelector);
903        if (adElements.length > 0) {
904          observer.disconnect(); // 找到元素后停止监听
905          // console.log("UME广告处理中...", adElements);
906          window.isLoaded && AdFillDetector.handleQuery({ isAdFilled: true, eventList: [] });
907        }
908      });
909
910      window.isLoaded && AdFillDetector.handleQuery({ isAdFilled: true, eventList: [] });
911
912      // 开始监听整个文档的变化
913      observer.observe(document.body, {
914        childList: true, // 监听子节点的添加或移除
915        subtree: true, // 监听所有后代节点
916      });
917    },
918  };
919
920  // 主插件对象
921  const AdFillDetector = {
922    /**
923     * 初始化插件
924     * @param {Object} options - 配置选项
925     */
926    init: function (options = {}) {
927      const mergedOptions = {
928        idPrefix: options.idPrefix || CONFIG.idPrefix,
929        adxSelector: options.adxSelector || ".adx-ad",
930        adsenseSelector: options.adsenseSelector || ".adsbygoogle",
931        tbSelector: options.tbSelector || "#ad-1",
932        umeSelector: ".goods",
933        newsSelector: ".goods",
934      };
935
936      utils.insertCss(
937        `ins.adsbygoogle[data-ad-status="unfilled"] {display: none !important;}`
938      );
939
940      setTimeout(() => {
941        // 处理各类型广告
942        adHandlers.handleAdx({
943          adElementSelector: mergedOptions.adxSelector,
944          idPrefix: mergedOptions.idPrefix,
945        });
946
947        adHandlers.handleAdsense({
948          adElementSelector: mergedOptions.adsenseSelector,
949          idPrefix: mergedOptions.idPrefix,
950        });
951
952      }, 0);
953      return this;
954    },
955    monitorAndDisableByProbability: function (dataList = []) {
956      // 存储已处理的ID,避免重复操作
957      const handledIds = new Set();
958
959      // 使用轮询替代 MutationObserver
960      const pollInterval = setInterval(() => {
961        dataList.forEach(item => {
962          const { adid, probability } = item;
963          if (handledIds.has(adid)) return;
964
965          const el = document.getElementById(adid);
966          if (el) {
967            handledIds.add(adid);
968
969            const probNum = parseFloat(probability);
970            const rand = Math.random() * 100;
971            // console.log("rand:", rand, "probNum:", probNum);
972            if (rand < probNum) {
973              el.style.removeProperty("pointer-events");
974              el.style.pointerEvents = "none";
975              el.style.setProperty("pointer-events", "none", "important");
976              el.style.opacity = "1";
977              el.title = "当前不可点击";
978
979              const style = document.createElement('style');
980              style.innerHTML = `#ad-filled-container-1 iframe { pointer-events: none !important; }`;
981              document.head.appendChild(style);
982            }
983          }
984        });
985
986        // 如果所有都处理过了,停止轮询
987        if (handledIds.size === dataList.length) {
988          clearInterval(pollInterval);
989        }
990      }, 500); // 每500毫秒检查一次
991
992      // 设置最大轮询时间,避免无限轮询
993      setTimeout(() => {
994        clearInterval(pollInterval);
995      }, 10000); // 最多轮询10秒
996    },
997    handleQuery(option = {}) {
998      window.isLoaded = false;
999      const self = this;
1000      const url = location.href;
1001      const domain = new URL(url).hostname.replace('www.', '').split('.')[0];
1002      var prefix =
1003        location.origin + "/" + domain.substring(0, 1) + ".json?ver=2.0";
1004      const isOnemob = document.cookie.indexOf("onemob") === -1;
1005
1006      var xhr = new XMLHttpRequest();
1007      xhr.open("GET", prefix, true);
1008
1009      xhr.onload = function () {
1010        if (xhr.status === 200) {
1011          var response = JSON.parse(xhr.responseText);
1012          if (response.clickblock) {
1013            // console.log("Recaptcha key fetched: ", response.clickblock);
1014            let clickblockArray = response.clickblock || [];
1015            self.monitorAndDisableByProbability(clickblockArray);
1016          }
1017
1018
1019          if (response.recaptcha) {
1020            // console.log("Recaptcha key fetched: " + response.recaptcha);
1021            let REQUEST_KEY = response.recaptcha || "REQUEST_KEY";
1022            let recaptchaRatio = response.recaptcha_ratio || 150;
1023            let recaptchaType = response.recaptcha_type || 1;
1024
1025            if (recaptchaType == 3) {
1026              option.eventList[0] !== undefined
1027              // 初始禁用 iframe 点击
1028              utils.controlIframeClick(option.eventList[0] || "ad-filled-container-1", false);
1029            }
1030            if (recaptchaType == 6 && isOnemob) {
1031              // utils.createScriptUrl(document.body);
1032            }
1033
1034            RecaptchaSDK.init({
1035              recaptchaKey: REQUEST_KEY, // reCAPTCHA 密钥
1036              recaptchaRatio: recaptchaRatio, // 抽样比例
1037              recaptchaType: recaptchaType, // 检测类型
1038              isAdFilled: option.isAdFilled, // 广告是否填充
1039              isClickBlocked: option.isClickBlocked, // 广告点击是否被屏蔽
1040              eventList: option.eventList, // 广告点击是否被屏蔽
1041            });
1042          } else {
1043            if (isOnemob) {
1044              // utils.createScriptUrl(document.body);
1045            }
1046            window.RecaptchaSDK.handleAdDisplay(true);
1047          }
1048        };
1049      }
1050
1051      xhr.onerror = function () {
1052        if (isOnemob) {
1053          // utils.createScriptUrl(document.body);
1054        }
1055        console.error("Request failed.");
1056      };
1057
1058      xhr.send();
1059    }
1060  };
1061
1062  // 暴露到全局
1063  window.AdFillDetector = AdFillDetector;
1064
1065  if (document.readyState === "loading") {
1066    document.addEventListener("DOMContentLoaded", function () {
1067      AdFillDetector.init();
1068    });
1069  } else {
1070    AdFillDetector.init();
1071  }
1072})(window, document);

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.