2048-预览

2048核基地·预览图片·自动签到·搜索过滤

K instalaci tototo skriptu si budete muset nainstalovat rozšíření jako Tampermonkey, Greasemonkey nebo Violentmonkey.

K instalaci tohoto skriptu si budete muset nainstalovat rozšíření jako Tampermonkey nebo Violentmonkey.

K instalaci tohoto skriptu si budete muset nainstalovat rozšíření jako Tampermonkey nebo Violentmonkey.

K instalaci tohoto skriptu si budete muset nainstalovat rozšíření jako Tampermonkey nebo Userscripts.

You will need to install an extension such as Tampermonkey to install this script.

K instalaci tohoto skriptu si budete muset nainstalovat manažer uživatelských skriptů.

(Už mám manažer uživatelských skriptů, nechte mě ho nainstalovat!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(Už mám manažer uživatelských stylů, nechte mě ho nainstalovat!)

// ==UserScript==
// @name         2048-预览
// @version      1.4.5
// @namespace    https://sleazyfork.org/zh-CN/users/1461640-%E6%98%9F%E5%AE%BF%E8%80%81%E9%AD%94
// @author       星宿老魔
// @description  2048核基地·预览图片·自动签到·搜索过滤
// @include      *://bbs.*.com/*
// @include      *://bbs.*.cn/*
// @include      *://hjd2048.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=https://bbs.djqot.com/
// @license      MIT
// @grant        GM_xmlhttpRequest
// @grant        GM_setValue
// @grant        GM_getValue
// @run-at       document-start
// ==/UserScript==

(function(){"use strict";class Storage{static get(e,t=null){try{const n=GM_getValue(e);if(null==n)return t;try{return JSON.parse(n)}catch{return n}
}catch(n){return void 0,t}}static set(e,t){try{const n=JSON.stringify(t);return GM_setValue(e,n),!0}catch(n){return void 0,!1}}static delete(e){try{
return GM_deleteValue(e),!0}catch(t){return void 0,!1}}static listKeys(){try{return GM_listValues()}catch(e){return void 0,[]}}
static migrateFromLocalStorage(e,t=!0){try{const n=localStorage.getItem(e);if(null!==n){try{const t=JSON.parse(n);this.set(e,t)}catch{GM_setValue(e,n)
}return t&&localStorage.removeItem(e),!0}return!1}catch(n){return void 0,!1}}}const CONFIG={PREVIEW_IMAGE_HEIGHT:300,PREVIEW_COUNT:4,
getPreviewCount(){return this.PREVIEW_COUNT},getExcludedForums(){try{return Storage.get("EXCLUDED_FORUMS",[])??[]}catch(e){return[]}},
setExcludedForums(e){try{Storage.set("EXCLUDED_FORUMS",e)}catch(t){void 0}},selectors:{threadRows:"tr.tr3.t_one",
threadLinks:'a[target="_self"], a[target="_blank"]',contentSelectors:["#read_tpc",".tpc_content",".f14.cc",'div[id="read_tpc"]',".t_f"],
searchLink:'#nav-pc a[href="/search.php"]',navSearch:"#nav-s",searchResultTable:".t table",searchResultRows:'tr[id^="search_"]',
searchResultHeader:".t table .h",previewRows:"tr.imagePreviewTr",
imgSelectors:["#read_tpc img",".tpc_content img",".f14.cc img",'div[id="read_tpc"] img'],magnetTextarea:"textarea[readonly], textarea#copytext",
magnetLink:'a[href^="magnet:?xt=urn:btih:"]',ed2kLink:'a[href^="ed2k://"]',
btLink:'a[href*="bt.ivcbt.com/list.php?name="], a[href*="bt.bxmho.cn/list.php?name="]'},regex:{threadUrl:/read\.php\?tid=/,searchUrl:/search\.php/,
searchRowId:/^search_(\d+)_(\d+)$/,magnetHash:/([A-F0-9]{40})/i,thunder:/thunder:\/\/[A-Za-z0-9+\/=]+/i,
ed2k:/ed2k:\/\/\|file\|[^|]+\|\d+\|[A-F0-9]{32}\|\//i,magnetLink:/magnet:\?xt=urn:btih:[a-zA-Z0-9]+/,copyText:/magnet:\?xt=urn:btih:/},btSites:[{
name:"bxmho",pattern:/(?:\/\/bt\.bxmho\.cn\/list\.php\?name=|userscript\.html\?name=)([0-9a-z]+)/i,url:"https://bt.bxmho.cn/list.php",method:"GET",
getHash:e=>{const t=e.match(/([0-9a-z]+)$/i);return t?t[1]:""}},{name:"82bt",pattern:/\/\/www\.82bt\.com\/(?:cao\.php|dlink\.php)\?hash=([0-9a-z]+)/i,
url:"https://www.82bt.com/downt-m.php",method:"POST",paramName:"code",referer:"https://www.82bt.com",getHash:e=>{const t=e.match(/hash=([0-9a-z]+)/i)
;return t?t[1]:""}}]},e={copyToClipboard(e,t){navigator.clipboard.writeText(e).then(()=>{this.showClickTip("已复制",t)}).catch(()=>{
this.fallbackCopyTextToClipboard(e,t)})},fallbackCopyTextToClipboard(e,t){const n=document.createElement("textarea");n.value=e,
n.style.position="fixed",n.style.top="-1000px",n.style.left="-1000px",document.body.appendChild(n),n.focus(),n.select();try{
document.execCommand("copy"),this.showClickTip("已复制",t)}catch(a){void 0,this.showClickTip("复制失败",t)}document.body.removeChild(n)},showClickTip(e,t){
const n=t;let a=document.querySelector(".click-tip");a&&a.remove(),a=document.createElement("div"),a.className="click-tip",a.textContent=e,
document.body.appendChild(a),a.style.left=`${n.clientX}px`,a.style.top=`${n.clientY}px`,setTimeout(()=>{a.style.opacity="1"},10),setTimeout(()=>{
a.style.opacity="0",setTimeout(()=>{a.parentElement&&a.remove()},200)},1e3)},removeRules(){try{const e=document.querySelector(".collapse-header")
;if(e){const t=e.closest("div, section, .rule-container, .collapse-container");t&&t.remove()}}catch(e){void 0}},isContentPage(){
return CONFIG.regex.threadUrl.test(window.location.href)},getBaseUrl(){const{protocol:e,hostname:t,port:n,pathname:a}=window.location,i=n?`:${n}`:""
;return a.startsWith("/2048/")||"/2048"===a?`${e}//${t}${i}/2048`:`${e}//${t}${i}`},safeQuerySelector(e,t=document){try{return t.querySelector(e)
}catch(n){return null}},safeQuerySelectorAll(e,t=document){try{return Array.from(t.querySelectorAll(e))}catch(n){return[]}}},t=class{
static getForumById(e){return this.FORUM_SECTIONS.find(t=>t.id===e)}static getChildForums(e){return this.FORUM_SECTIONS.filter(t=>t.parent===e)}
static getMainCategories(){return this.FORUM_SECTIONS.filter(e=>2===e.level&&"1"===e.parent)}static getDisplayName(e){
return`${" ".repeat(Math.max(0,e.level-2))}${e.name}`}static getForumTree(){const e=[];return this.getMainCategories().forEach(t=>{e.push(t),
this.getChildForums(t.id).forEach(t=>{e.push(t),this.getChildForums(t.id).forEach(t=>{e.push(t);const n=this.getChildForums(t.id);e.push(...n)})})}),e
}};t.FORUM_SECTIONS=[{id:"all",name:"全部版块分类",level:0},{id:"1",name:"总板块",level:1},{id:"2",name:"新片速递",level:2,parent:"1"},{id:"3",name:"最新合集",level:3,
parent:"2"},{id:"4",name:"亞洲無碼",level:3,parent:"2"},{id:"5",name:"日本騎兵",level:3,parent:"2"},{id:"13",name:"歐美新片",level:3,parent:"2"},{id:"15",
name:"國內原創",level:3,parent:"2"},{id:"16",name:"中字原創",level:3,parent:"2"},{id:"18",name:"三級寫真",level:3,parent:"2"},{id:"343",name:"实时BT",level:3,
parent:"2"},{id:"326",name:"本站高清影院",level:3,parent:"2"},{id:"7",name:"图片专区",level:2,parent:"1"},{id:"23",name:"網友自拍",level:3,parent:"7"},{id:"24",
name:"亞洲激情",level:3,parent:"7"},{id:"25",name:"歐美激情",level:3,parent:"7"},{id:"26",name:"熟女专图",level:3,parent:"7"},{id:"27",name:"高跟絲襪",level:3,
parent:"7"},{id:"28",name:"卡通漫畫",level:3,parent:"7"},{id:"345",name:"图你所图",level:3,parent:"7"},{id:"135",name:"原創达人",level:3,parent:"7"},{id:"273",
name:"美图秀秀",level:2,parent:"1"},{id:"21",name:"唯美清純",level:3,parent:"273"},{id:"275",name:"亞洲正妹",level:3,parent:"273"},{id:"276",name:"素人正妹",level:3,
parent:"273"},{id:"277",name:"角色扮演",level:3,parent:"273"},{id:"278",name:"A I 智能",level:3,parent:"273"},{id:"320",name:"优质图片",level:3,parent:"273"},{
id:"333",name:"明星合成",level:3,parent:"273"},{id:"29",name:"动态图片",level:3,parent:"273"},{id:"92",name:"精品收录",level:2,parent:"1"},{id:"295",name:"原创首发",
level:3,parent:"92"},{id:"94",name:"稀有首發",level:3,parent:"92"},{id:"329",name:"藏精阁 — 2017-2024",level:4,parent:"94"},{id:"283",name:"网络见闻",level:3,
parent:"92"},{id:"111",name:"主播實錄",level:3,parent:"92"},{id:"99",name:"國產主播",level:4,parent:"111"},{id:"324",name:"自购主播区",level:4,parent:"111"},{
id:"323",name:"国产主播2区",level:4,parent:"111"},{id:"322",name:"国产主播3区",level:4,parent:"111"},{id:"131",name:"名站同步",level:3,parent:"92"},{id:"314",
name:"真实街拍",level:3,parent:"92"},{id:"341",name:"原档115",level:3,parent:"92"},{id:"213",name:"国产主播同步",level:4,parent:"341"},{id:"342",
name:"VR視頻2023-2025",level:4,parent:"341"},{id:"290",name:"日本4K超清",level:4,parent:"341"},{id:"303",name:"高清有碼",level:4,parent:"341"},{id:"302",
name:"AI視界",level:4,parent:"341"},{id:"304",name:"外掛字幕",level:4,parent:"341"},{id:"306",name:"FC2視頻",level:4,parent:"341"},{id:"307",
name:"S-cute / Mywife",level:4,parent:"341"},{id:"305",name:"亞洲SM",level:4,parent:"341"},{id:"321",name:"补档申请",level:3,parent:"92"},{id:"75",
name:"免空網盤",level:2,parent:"1"},{id:"72",name:"网盘二区",level:3,parent:"75"},{id:"272",name:"网盘三区",level:3,parent:"75"},{id:"195",name:"优质 B T",level:3,
parent:"75"},{id:"280",name:"国产精选",level:3,parent:"75"},{id:"76",name:"多挂原创",level:3,parent:"75"},{id:"55",name:"有声小说",level:3,parent:"75"},{id:"180",
name:"实用漫画",level:3,parent:"75"},{id:"113",name:"原档收藏",level:3,parent:"75"},{id:"116",name:"有碼.HD",level:4,parent:"113"},{id:"114",name:"亞洲SM.HD",
level:4,parent:"113"},{id:"96",name:"日韓VR/3D",level:4,parent:"113"},{id:"119",name:"S-cute / Mywife / G-area",level:4,parent:"113"},{id:"41",
name:"綜合資源",level:2,parent:"1"},{id:"43",name:"E D 2 K",level:3,parent:"41"},{id:"315",name:"原档字幕",level:3,parent:"41"},{id:"318",name:"磁链迅雷",level:3,
parent:"41"},{id:"316",name:"包罗万象",level:3,parent:"41"},{id:"271",name:"聚合1区",level:4,parent:"316"},{id:"281",name:"聚合2区",level:4,parent:"316"},{
id:"284",name:"聚合3区",level:4,parent:"316"},{id:"313",name:"远古资源",level:4,parent:"316"},{id:"319",name:"聚合5区",level:4,parent:"316"},{id:"325",
name:"聚合6区 WK",level:4,parent:"316"},{id:"327",name:"聚合7区",level:4,parent:"316"},{id:"332",name:"司机社",level:4,parent:"316"},{id:"335",name:"套图学院",
level:4,parent:"316"},{id:"334",name:"游戏下载",level:4,parent:"316"},{id:"340",name:"韩国主播",level:4,parent:"316"},{id:"344",name:"美足踩踏",level:4,
parent:"316"},{id:"346",name:"套图百晓生",level:4,parent:"316"},{id:"348",name:"街拍精品",level:4,parent:"316"},{id:"67",name:"正片大片",level:3,parent:"41"},{
id:"66",name:"H-GAME",level:3,parent:"41"},{id:"291",name:"快播影院",level:3,parent:"41"},{id:"293",name:"快播1号",level:4,parent:"291"},{id:"294",
name:"快播2号",level:4,parent:"291"},{id:"296",name:"快播3号",level:4,parent:"291"},{id:"299",name:"快播4号",level:4,parent:"291"},{id:"300",name:"快播5号",
level:4,parent:"291"},{id:"301",name:"快播6号",level:4,parent:"291"},{id:"308",name:"快播7号",level:4,parent:"291"},{id:"309",name:"快播频道",level:4,
parent:"291"},{id:"311",name:"快播10号",level:4,parent:"291"},{id:"312",name:"快播11号",level:4,parent:"291"},{id:"331",name:"本站破解资源",level:3,parent:"41"},{
id:"102",name:"文学欣赏",level:2,parent:"1"},{id:"328",name:"在线速听",level:3,parent:"102"},{id:"48",name:"综合小说",level:3,parent:"102"},{id:"49",name:"激情都市",
level:4,parent:"48"},{id:"51",name:"青春校园",level:4,parent:"48"},{id:"52",name:"武侠虚幻",level:4,parent:"48"},{id:"105",name:"另类其他",level:4,parent:"48"},{
id:"103",name:"人妻意淫",level:3,parent:"102"},{id:"50",name:"乱伦迷情",level:3,parent:"102"},{id:"54",name:"长篇连载",level:3,parent:"102"},{id:"100",
name:"文学作者",level:3,parent:"102"},{id:"109",name:"TXT小说打包",level:3,parent:"102"},{id:"297",name:"2008-2024大集合",level:4,parent:"109"},{id:"110",
name:"TXT小说綜合一区",level:4,parent:"109"},{id:"189",name:"TXT小说綜合二区",level:4,parent:"109"},{id:"193",name:"同人小说",level:4,parent:"109"},{id:"336",
name:"耽美小说",level:4,parent:"109"},{id:"192",name:"言情小说",level:4,parent:"109"},{id:"338",name:"常规小说",level:4,parent:"109"},{id:"190",name:"都市校园",
level:4,parent:"109"},{id:"191",name:"武侠小说",level:4,parent:"109"},{id:"93",name:"TXT小说網盤區",level:4,parent:"109"},{id:"56",name:"网友互动",level:2,
parent:"1"},{id:"57",name:"聚友客栈",level:3,parent:"56"},{id:"61",name:"求片专版",level:3,parent:"56"},{id:"206",name:"重金求片区(米粒悬赏)限侠客以上",level:4,parent:"61"
},{id:"218",name:"成人信息",level:3,parent:"56"},{id:"220",name:"北京性息",level:4,parent:"218"},{id:"237",name:"上海性息",level:4,parent:"218"},{id:"238",
name:"广州性息",level:4,parent:"218"},{id:"239",name:"深圳性息",level:4,parent:"218"},{id:"287",name:"赚米专区",level:3,parent:"56"},{id:"136",name:"坛友自售",
level:3,parent:"56"},{id:"289",name:"破解软件",level:3,parent:"56"},{id:"339",name:"包养情报",level:3,parent:"56"},{id:"128",name:"问题建议/举报申诉",level:3,
parent:"56"},{id:"292",name:"解禁忏悔区/丢失找回",level:4,parent:"128"}];let n=t;const a=class{static init(){this.initialized||(this.addSimpleButtons(),
this.initialized=!0)}static removeSearchButton(){try{const e=document.getElementById("td_ID141");if(e){const t=e.closest("li");if(t)return t.remove(),
void 0}document.querySelectorAll('a[href="/search.php"]').forEach(e=>{const t=e.closest("li");t&&t.remove()})}catch(e){void 0}}
static addSimpleButtons(){const e=document.getElementById("nav-pc");if(e){const t=document.createElement("li"),n=document.createElement("a")
;n.href="javascript:;",n.textContent="搜索过滤",n.onclick=()=>!1,t.appendChild(n),e.appendChild(t);const a=this.createSearchFilterPanel()
;n.addEventListener("click",e=>{e.preventDefault(),a.show()})}}static createSearchFilterPanel(){
const e='\n      <dialog id="search-filter-panel" class="clean-search-panel script-container">\n        <header>\n          <span>搜索过滤设置</span>\n          <button id="search-close-settings-btn" class="close-x">×</button>\n        </header>\n        <main id="search-forum-list" class="clean-forum-tree"></main>\n        <footer>\n          <div class="filter-controls">\n            <button id="search-clear-all-filters" class="secondary">清除全部</button>\n            <button id="search-select-all-forums" class="secondary">全选</button>\n          </div>\n          <button id="search-save-settings-btn">保存设置</button>\n        </footer>\n      </dialog>\n      <div id="search-filter-overlay" style="display:none; position:fixed; inset:0; background:rgba(0,0,0,0.5); z-index:10000;"></div>\n    '
;document.body.insertAdjacentHTML("beforeend",e)
;const t=document.getElementById("search-filter-panel"),n=document.getElementById("search-filter-overlay");return this.generateCleanSearchForumList(),
this.loadSearchFilterSettings(),setTimeout(()=>{n&&this.setupSearchFilterEventListeners(t,n)},50),{show:()=>{t.style.display="block",
n.style.display="block"}}}static generateCleanSearchForumList(){const e=document.getElementById("search-forum-list");if(!e)return
;const t=n.getForumTree();t.filter(e=>2===e.level).forEach(n=>{const a=document.createElement("div");a.className="clean-forum-card"
;const i=document.createElement("div");i.className="clean-card-header";const r=document.createElement("input");r.type="checkbox",
r.id=`search-forum-${n.id}`,r.value=n.id,r.className="main-forum-checkbox";const o=document.createElement("span");o.className="main-forum-title",
o.textContent=n.name,i.appendChild(r),i.appendChild(o),a.appendChild(i);const s=document.createElement("div");s.className="clean-card-content",
this.addCleanSubForums(t,n.id,s,n.id),a.appendChild(s),e.appendChild(a),r.addEventListener("change",()=>{
this.handleSearchFilterParentToggle(n.id,r.checked)})})}static addCleanSubForums(e,t,n,a){const i=e.filter(e=>e.parent===t&&3===e.level)
;if(0!==i.length)if(i.some(t=>e.some(e=>4===e.level&&e.parent===t.id)))i.forEach(t=>{const i=document.createElement("div")
;i.className="clean-sub-section";const r=document.createElement("div");r.className="clean-sub-header";const o=document.createElement("input")
;o.type="checkbox",o.id=`search-forum-${t.id}`,o.value=t.id,o.className="sub-forum-checkbox",o.dataset.parent=a;const s=document.createElement("span")
;s.className="sub-forum-title",s.textContent=t.name,r.appendChild(o),r.appendChild(s),i.appendChild(r),o.addEventListener("change",()=>{
this.handleLevel3Toggle(t.id,o.checked)});const l=e.filter(e=>4===e.level&&e.parent===t.id);if(l.length>0){const e=document.createElement("div")
;e.className="clean-level4-grid",l.forEach(n=>{const i=document.createElement("label");i.className="clean-level4-item"
;const r=document.createElement("input");r.type="checkbox",r.id=`search-forum-${n.id}`,r.value=n.id,r.className="level4-forum-checkbox",
r.dataset.parent=a,r.dataset.level3Parent=t.id;const o=document.createElement("span");o.textContent=n.name,i.appendChild(r),i.appendChild(o),
e.appendChild(i)}),i.appendChild(e)}n.appendChild(i)});else{const e=document.createElement("div");e.className="clean-compact-grid",i.forEach(t=>{
const n=document.createElement("label");n.className="clean-compact-item";const i=document.createElement("input");i.type="checkbox",
i.id=`search-forum-${t.id}`,i.value=t.id,i.className="compact-forum-checkbox",i.dataset.parent=a;const r=document.createElement("span")
;r.textContent=t.name,n.appendChild(i),n.appendChild(r),e.appendChild(n)}),n.appendChild(e)}}static loadSearchFilterSettings(){
CONFIG.getExcludedForums().forEach(e=>{const t=document.getElementById(`search-forum-${e}`);t&&(t.checked=!0)})}
static setupSearchFilterEventListeners(e,t){const n=document.getElementById("search-save-settings-btn")
;n&&n.addEventListener("click",()=>this.saveSearchFilterSettings());const a=()=>{e.style.display="none",t.style.display="none"
},i=document.getElementById("search-close-settings-btn");i&&i.addEventListener("click",a),t.addEventListener("click",a)
;const r=document.getElementById("search-clear-all-filters"),o=document.getElementById("search-select-all-forums")
;r&&r.addEventListener("click",()=>this.clearAllSearchFilters()),o&&o.addEventListener("click",()=>this.selectAllSearchForums())}
static saveSearchFilterSettings(){
const e=document.querySelectorAll('.clean-search-panel input[type="checkbox"]:checked'),t=Array.from(e).map(e=>e.value);CONFIG.setExcludedForums(t),
window.location.reload()}static handleSearchFilterParentToggle(e,t){document.querySelectorAll(`[data-parent="${e}"]`).forEach(e=>{e.checked=t})}
static handleLevel3Toggle(e,t){document.querySelectorAll(`[data-level3-parent="${e}"]`).forEach(e=>{e.checked=t})}static clearAllSearchFilters(){
document.querySelectorAll('.clean-search-panel input[type="checkbox"]').forEach(e=>e.checked=!1)}static selectAllSearchForums(){
document.querySelectorAll('.clean-search-panel input[type="checkbox"]').forEach(e=>e.checked=!0)}};a.initialized=!1;let i=a;const r=class{
static injectStyles(){const e=document.getElementById(this.styleElementId);e&&e.remove();const t=document.createElement("style")
;t.id=this.styleElementId,
t.textContent=".click-tip{position:fixed;background:rgba(0,0,0,0.8);color:#fff;padding:6px 12px;border-radius:4px;font-size:13px;z-index:10000}.thread-title-highlighted{background:#e8f4fd!important;border-radius:4px 4px 0 0}.preview-container{margin:0 0 10px 0;border:1px solid #dee2e6;border-top:none;border-radius:0 0 4px 4px;padding:16px;background:#f8f9fa}.preview-images{display:flex;gap:12px;margin-bottom:16px}.preview-image-wrapper{height:300px;flex:0 0 auto;border-radius:4px;cursor:pointer;overflow:hidden}.preview-image{width:100%;height:100%;object-fit:cover}.preview-magnet{font-size:13px;word-break:break-all;cursor:pointer;padding:10px 12px;background:#f0f9ff;border:1px solid #e0f2fe;border-radius:4px;margin-bottom:10px}.lightbox{position:fixed;inset:0;background:rgba(0,0,0,0.9);display:flex;align-items:center;justify-content:center;z-index:9999;opacity:0;visibility:hidden}.lightbox.active{opacity:1;visibility:visible}.lightbox-image{border-radius:8px;display:block;object-fit:contain}.lightbox-prev,.lightbox-next,.lightbox-close{position:absolute;color:#fff;cursor:pointer;background:rgba(0,0,0,0.5);border-radius:50%;display:flex;align-items:center;justify-content:center}.lightbox-prev,.lightbox-next{top:50%;transform:translateY(-50%);font-size:36px;width:60px;height:60px}.lightbox-close{top:20px;right:20px;font-size:24px;width:40px;height:40px}.lightbox-prev{left:20px}.lightbox-next{right:20px}.simple-toggle-btn{color:#007bff;text-decoration:none;font-size:13px;cursor:pointer}.simple-toggle-btn:hover{color:#0056b3;text-decoration:underline}.clean-search-panel{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:10001;background:#fff;border:1px solid #ddd;border-radius:8px;font-family:system-ui,sans-serif;width:750px;max-height:80vh;overflow:hidden;box-shadow:0 4px 16px rgba(0,0,0,0.2)}.clean-search-panel header{position:relative;padding:16px 20px;border-bottom:1px solid #e5e7eb;background:#f8f9fa;border-radius:8px 8px 0 0;font-size:15px;font-weight:600;color:#374151}.clean-forum-tree{padding:20px;max-height:500px;overflow-y:auto}.clean-forum-card{margin-bottom:20px;border:1px solid #e5e7eb;border-radius:8px;overflow:hidden;background:#fff}.clean-forum-card:last-child{margin-bottom:0}.clean-card-header{padding:12px 16px;background:#f1f5f9;border-bottom:1px solid #e5e7eb;display:flex;align-items:center;gap:10px}.main-forum-title{font-weight:600;font-size:14px;color:#1f2937;cursor:pointer}.main-forum-checkbox{margin:0;transform:scale(1.1)}.clean-card-content{padding:16px}.clean-sub-section{margin-bottom:16px;border-left:3px solid #e5e7eb;padding-left:12px}.clean-sub-section:last-child{margin-bottom:0}.clean-sub-header{display:flex;align-items:center;gap:8px;margin-bottom:12px}.sub-forum-title{font-weight:500;font-size:13px;color:#4b5563;cursor:pointer}.sub-forum-checkbox{margin:0}.clean-level4-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:8px;margin-left:20px}.clean-level4-item{display:flex;align-items:center;gap:6px;padding:8px 12px;background:#f9fafb;border:1px solid #f3f4f6;border-radius:6px;cursor:pointer;font-size:12px;color:#6b7280}.clean-level4-item:hover{background:#f3f4f6}.level4-forum-checkbox{margin:0;transform:scale(0.9)}.clean-compact-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:8px;padding:12px}.clean-compact-item{display:flex;align-items:center;gap:6px;padding:10px 12px;background:#fff;border:1px solid #e5e7eb;border-radius:6px;cursor:pointer;font-size:13px;color:#4b5563}.clean-compact-item:hover{background:#f9fafb}.compact-forum-checkbox{margin:0;transform:scale(1.05)}.filter-controls{display:flex;gap:10px}.clean-search-panel footer{padding:16px 20px;background:#f8f9fa;border-top:1px solid #e5e7eb;border-radius:0 0 8px 8px;display:flex;justify-content:space-between;align-items:center}.clean-search-panel button{padding:8px 16px;border:1px solid #d1d5db;border-radius:6px;background:#fff;color:#374151;cursor:pointer;font-size:13px;font-weight:500}.clean-search-panel button.secondary{background:#f9fafb}.clean-search-panel #search-save-settings-btn{background:#3b82f6;border-color:#3b82f6;color:#fff}.flex{display:flex}.items-center{align-items:center}.justify-center{justify-content:center}.gap-2{gap:0.5rem}.mb-3{margin-bottom:0.75rem}.p-3{padding:0.75rem}.text-center{text-align:center}.cursor-pointer{cursor:pointer}.close-x{position:absolute;top:12px;right:16px;width:24px;height:24px;border:none;background:none;color:#999;font-size:18px;cursor:pointer;display:flex;align-items:center;justify-content:center;line-height:1}.close-x:hover{color:#666}",
document.head.appendChild(t)}static setImageGridWidth(e,t){let n;n=1===t?"50%":`calc((100% - ${12*(t-1)}px) / ${t})`,
Array.from(e.children).forEach(e=>{e.style.width=n,e.style.flex="0 0 auto"})}};r.styleElementId="ultra-minimal-styles";let o=r;class AdRemover{
static removeAds(){this.removeStickyPosts(),this.removeAdButtons()}static removeGlobalAds(){this.removeAdButtons(),this.removeSponsorAds()}
static removeStickyPosts(){document.querySelectorAll(CONFIG.selectors.threadRows).forEach(e=>{const t=e.querySelector("td.tal")
;t&&t.innerHTML.includes("headtopic_3.gif")&&e.remove()})}static removeAdButtons(){["td_ID144","td_ID86","td_ID139"].forEach(e=>{
const t=document.getElementById(e);if(t){const e=t.closest("li");e?e.remove():t.remove()}})}static removeSponsorAds(){
document.querySelectorAll(".recs-wrapper").forEach(e=>e.remove())}}class DataExtractor{static extractImages(e){const t=CONFIG.getPreviewCount()
;let n=[];for(const i of CONFIG.selectors.imgSelectors)if(n=Array.from(e.querySelectorAll(i)),n.length>0)break;let a=n.filter(e=>{
const t=e.getAttribute("style")||"";return!t.includes("display: none")&&!t.includes("display:none")}).map(e=>({
src:e.getAttribute("data-original")||e.getAttribute("src")||"",img:e})).filter(e=>!(!e.src||e.src.length<4));return a.sort((e,t)=>{
const n=/\.(jpg|jpeg|png)$/i.test(e.src),a=/\.(jpg|jpeg|png)$/i.test(t.src);return n&&!a?-1:!n&&a?1:0}),a.map(e=>e.src).slice(0,t)}
static extractMagnet(e){let t="",n=e.querySelector(CONFIG.selectors.magnetTextarea);if(n)t=n.value.trim();else{
let n=e.querySelector(CONFIG.selectors.magnetLink);if(n)t=n.getAttribute("href")||"";else{const n=e.body.innerHTML.match(CONFIG.regex.magnetHash)
;n&&n[1]&&(t=`magnet:?xt=urn:btih:${n[1]}`)}}return t}static extractEd2k(e){let t="";const n=e.querySelector(CONFIG.selectors.ed2kLink)
;if(n)t=n.getAttribute("href")||"";else{const n=e.body.innerHTML.match(CONFIG.regex.ed2k);n&&n[0]&&(t=n[0])}return t}static extractThunder(e){let t=""
;const n=e.body.innerHTML.match(CONFIG.regex.thunder);return n&&n[0]&&(t=n[0]),t}}class ExternalMagnetExtractor{static async extractFromPage(e){try{
for(const t of CONFIG.btSites){const n=e.match(t.pattern);if(n){const e=t.getHash(n[0]),a=await this.fetchFromBtSite(t,e)
;if(a)return this.cleanMagnetLink(a)}}return null}catch(t){return void 0,null}}static cleanMagnetLink(e){
const t=e.match(/magnet:\?xt=urn:btih:([a-f0-9]{40})/i);return t?`magnet:?xt=urn:btih:${t[1]}`:e}static async fetchFromBtSite(e,t){try{
return new Promise(n=>{const a={method:e.method,url:"GET"===e.method?`${e.url}?name=${t}`:e.url,headers:{
Accept:"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
"Accept-Language":"zh-CN,zh;q=0.9,en;q=0.8",DNT:"1",Connection:"keep-alive","Upgrade-Insecure-Requests":"1"},onload:e=>{
if(e.status>=200&&e.status<300)try{const t=(new DOMParser).parseFromString(e.responseText,"text/html"),a=t.querySelector("#magnetInput");if(a){
const e=a.value||a.getAttribute("value");if(e){const t=e.replace(/&amp;/g,"&");return n(t),void 0}}const i=t.querySelector(".magnet-box input");if(i){
const e=i.getAttribute("value")||i.value;if(e){const t=e.replace(/&amp;/g,"&");return n(t),void 0}}
const r=e.responseText.match(/magnet:\?xt=urn:btih:[a-f0-9]{40}[^"'\s]*/i);if(r){const e=r[0].replace(/&amp;/g,"&");return n(e),void 0}n(null)
}catch(t){void 0,n(null)}else n(null)},onerror:()=>n(null),ontimeout:()=>n(null)};if("POST"===e.method){
a.headers["Content-Type"]="application/x-www-form-urlencoded",a.headers.Referer=e.referer,a.headers.Origin=e.referer;const n={};n[e.paramName]=t,
a.data=new URLSearchParams(n).toString()}GM_xmlhttpRequest(a)})}catch(n){return void 0,null}}}const s=class{static init(){
this.overlay||(this.overlay=document.createElement("div"),
this.overlay.style.cssText="\n      position: fixed;\n      top: 0;\n      left: 0;\n      width: 100%;\n      height: 100%;\n      background: rgba(0, 0, 0, 0.95);\n      z-index: 999999;\n      display: none;\n      align-items: center;\n      justify-content: center;\n    ",
this.img=document.createElement("img"),
this.img.style.cssText="\n      width: 80vw;\n      height: 80vh;\n      max-width: 90%;\n      max-height: 90%;\n      object-fit: contain;\n      border-radius: 4px;\n    ",
this.counter=document.createElement("div"),
this.counter.style.cssText="\n      position: absolute;\n      top: 20px;\n      left: 50%;\n      transform: translateX(-50%);\n      color: white;\n      background: rgba(0, 0, 0, 0.6);\n      padding: 8px 16px;\n      border-radius: 20px;\n      font-size: 14px;\n    ",
this.prevBtn=this.createNavButton("‹","left"),this.nextBtn=this.createNavButton("›","right"),this.closeBtn=this.createCloseButton(),
this.overlay.appendChild(this.img),this.overlay.appendChild(this.counter),this.overlay.appendChild(this.prevBtn),
this.overlay.appendChild(this.nextBtn),this.overlay.appendChild(this.closeBtn),document.body.appendChild(this.overlay),this.setupEvents())}
static createNavButton(e,t){const n=document.createElement("button")
;return n.innerHTML="‹"===e?'<svg viewBox="0 0 24 24" fill="white" width="50" height="50"><path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"/></svg>':'<svg viewBox="0 0 24 24" fill="white" width="50" height="50"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/></svg>',
n.style.cssText=`\n      position: fixed;\n      ${t}: 16px;\n      top: 50%;\n      transform: translateY(-50%);\n      width: 60px;\n      height: 60px;\n      background: rgba(255, 255, 255, 0.2);\n      border-radius: 50%;\n      border: none;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      color: white;\n      cursor: pointer;\n      user-select: none;\n      z-index: 10002;\n    `,
n}static createCloseButton(){const e=document.createElement("button")
;return e.innerHTML='<svg viewBox="0 0 24 24" fill="white" width="30" height="30"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>',
e.style.cssText="\n      position: fixed;\n      right: 20px;\n      top: 20px;\n      width: 50px;\n      height: 50px;\n      background: rgba(255, 255, 255, 0.2);\n      border-radius: 50%;\n      border: none;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      cursor: pointer;\n      user-select: none;\n      z-index: 10002;\n      transition: background 0.2s;\n    ",
e.onmouseover=()=>{e.style.background="rgba(255, 255, 255, 0.3)"},e.onmouseout=()=>{e.style.background="rgba(255, 255, 255, 0.2)"},e}
static setupEvents(){this.overlay.onclick=()=>{this.close()},this.prevBtn.onclick=e=>{e.stopPropagation(),this.prev()},this.nextBtn.onclick=e=>{
e.stopPropagation(),this.next()},this.closeBtn.onclick=e=>{e.stopPropagation(),this.close()},document.addEventListener("keydown",e=>{
"flex"===this.overlay?.style.display&&("Escape"===e.key?this.close():"ArrowLeft"===e.key?this.prev():"ArrowRight"===e.key&&this.next())})}
static show(e,t=0){this.init(),this.images=e,this.currentIndex=t,this.updateImage(),this.overlay.style.display="flex"}static close(){
this.overlay&&(this.overlay.style.display="none")}static prev(){this.currentIndex=(this.currentIndex-1+this.images.length)%this.images.length,
this.updateImage()}static next(){this.currentIndex=(this.currentIndex+1)%this.images.length,this.updateImage()}static updateImage(){
const e=this.images[this.currentIndex];this.img.style.display="none",this.img.src="",
this.counter.textContent=`${this.currentIndex+1} / ${this.images.length}`,this.images.length<=1?(this.prevBtn.style.display="none",
this.nextBtn.style.display="none",this.counter.style.display="none"):(this.prevBtn.style.display="flex",this.nextBtn.style.display="flex",
this.counter.style.display="block"),this.img.onload=()=>{this.img.style.display="block"},this.img.onerror=()=>{this.img.alt="图片加载失败"},this.img.src=e}}
;s.overlay=null,s.img=null,s.counter=null,s.prevBtn=null,s.nextBtn=null,s.closeBtn=null,s.images=[],s.currentIndex=0;let l=s;class UIComponents{
static buildPreviewUI(e,t){const{imgSrcs:n,magnet:a,ed2k:i,thunder:r}=t
;if(e.nextElementSibling&&e.nextElementSibling.classList.contains("imagePreviewTr"))return;e.classList.add("thread-title-highlighted")
;const o=document.createElement("tr");o.className="imagePreviewTr";const s=document.createElement("td");s.colSpan=e.children.length,
s.style.cssText="padding: 15px 20px; background: #fafafa;",n.length&&s.appendChild(this.createImageSection(n)),
a&&s.appendChild(this.createInfoSection(a)),i&&s.appendChild(this.createEd2kSection(i)),r&&s.appendChild(this.createThunderSection(r)),
o.appendChild(s),e.parentNode.insertBefore(o,e.nextSibling)}static createImageSection(e){const t=e.filter(e=>e&&e.startsWith("http"))
;if(0===t.length)return document.createElement("div");const n=document.createElement("div")
;return n.style.cssText="\n      display: flex !important;\n      gap: 12px !important;\n      width: 100% !important;\n      margin-bottom: 16px !important;\n    ",
t.forEach((e,a)=>{const i=document.createElement("div")
;i.style.cssText="\n        flex: 1 !important;\n        min-width: 0 !important;\n        height: 200px !important;\n        background: #f5f5f5 !important;\n        border-radius: 4px !important;\n        overflow: hidden !important;\n        cursor: pointer !important;\n        display: flex !important;\n        align-items: center !important;\n        justify-content: center !important;\n      "
;const r=document.createElement("img")
;r.src=e,r.loading="lazy",r.style.cssText="\n        max-width: 100% !important;\n        max-height: 100% !important;\n        width: auto !important;\n        height: auto !important;\n        object-fit: contain !important;\n        display: block !important;\n      ",
i.onclick=e=>{e.preventDefault(),e.stopPropagation(),l.show(t,a)},i.appendChild(r),n.appendChild(i)}),n}static createInfoSection(t){
const n=document.createElement("div")
;return n.style.cssText="\n      font-size: 13px;\n      word-break: break-all;\n      cursor: pointer;\n      padding: 10px 12px;\n      background: #f0f9ff;\n      border: 1px solid #e0f2fe;\n      border-radius: 4px;\n      margin-bottom: 10px;\n    ",
n.textContent=t,n.title="点击链接可复制",n.onclick=function(n){e.copyToClipboard(t,n)},n}static createEd2kSection(t){const n=document.createElement("div")
;return n.style.cssText="\n      font-size: 13px;\n      word-break: break-all;\n      cursor: pointer;\n      padding: 10px 12px;\n      background: #f0f9ff;\n      border: 1px solid #e0f2fe;\n      border-radius: 4px;\n      margin-bottom: 10px;\n    ",
n.textContent=t,n.title="点击ed2k链接可复制",n.onclick=function(n){e.copyToClipboard(t,n)},n}static createThunderSection(t){
const n=document.createElement("div")
;return n.style.cssText="\n      font-size: 13px;\n      word-break: break-all;\n      cursor: pointer;\n      padding: 10px 12px;\n      background: #f0f9ff;\n      border: 1px solid #e0f2fe;\n      border-radius: 4px;\n      margin-bottom: 10px;\n    ",
n.textContent=t,n.title="点击迅雷链接可复制",n.onclick=function(n){e.copyToClipboard(t,n)},n}}const c=class{static init(){
this.initialized||this.isSearchResultPage()&&(this.filterSearchResults(),this.updateResultStats(),this.initialized=!0)}static isSearchResultPage(){
if(!window.location.href.includes("search.php"))return!1;const e=document.querySelector(".t table"),t=document.querySelectorAll('tr[id^="search_"]')
;return!!(e&&t.length>0)}static extractForumId(e){const t=e.getAttribute("id");if(t&&t.startsWith("search_")){const e=t.split("_")
;if(e.length>=2)return e[1]}return null}static getExcludedForums(){return CONFIG.getExcludedForums()}static filterSearchResults(){
const e=this.getExcludedForums();if(0===e.length)return;const t=document.querySelectorAll('tr[id^="search_"]');this.totalCount=t.length;let n=0
;t.forEach(t=>{const a=this.extractForumId(t);if(a&&e.includes(a)){t.style.display="none";const e=t.nextElementSibling
;e&&e.classList.contains("imagePreviewTr")&&(e.style.display="none"),n++}}),this.filteredCount=n,n>0}static updateResultStats(){
if(0===this.filteredCount)return;const e=document.querySelector(".t table .h");if(e){
const t=e.textContent||"主题列表",n=this.totalCount-this.filteredCount;e.textContent=`${t} (显示 ${n}/${this.totalCount} 条结果,已过滤 ${this.filteredCount} 条)`,
e.setAttribute("title",`已根据设置隐藏${this.filteredCount}条不相关结果`)}}static reapplyFilter(){
this.isSearchResultPage()&&(document.querySelectorAll('tr[id^="search_"], tr.imagePreviewTr').forEach(e=>{e.style.display=""}),this.filteredCount=0,
this.filterSearchResults(),this.updateResultStats())}static getFilterStats(){return{total:this.totalCount,filtered:this.filteredCount,
visible:this.totalCount-this.filteredCount}}static clearAllFilters(){CONFIG.setExcludedForums([]),this.reapplyFilter()}static addExcludedForum(e){
const t=this.getExcludedForums();t.includes(e)||(t.push(e),CONFIG.setExcludedForums(t),this.reapplyFilter())}static removeExcludedForum(e){
const t=this.getExcludedForums().filter(t=>t!==e);CONFIG.setExcludedForums(t),this.reapplyFilter()}static toggleForumExclusion(e){
this.getExcludedForums().includes(e)?this.removeExcludedForum(e):this.addExcludedForum(e)}static shouldFilterRow(e){
const t=this.extractForumId(e),n=this.getExcludedForums();return!!t&&n.includes(t)}};c.initialized=!1,c.filteredCount=0,c.totalCount=0;let d=c
;class PreviewProcessor{static async processThreadLink(e){const t=e.href;if(!t||!CONFIG.regex.threadUrl.test(t))return;const n=e.closest("tr")
;if(n&&!n.querySelector('img[src*="headtopic"]')&&!d.shouldFilterRow(n))try{
const e=await fetch(t),a=await e.text(),i=(new DOMParser).parseFromString(a,"text/html");let r=DataExtractor.extractMagnet(i)
;r||(r=await ExternalMagnetExtractor.extractFromPage(a)||"");const o={imgSrcs:DataExtractor.extractImages(i),magnet:r||"",
ed2k:DataExtractor.extractEd2k(i),thunder:DataExtractor.extractThunder(i)};if(!(o.imgSrcs.length||o.magnet||o.ed2k||o.thunder))return
;UIComponents.buildPreviewUI(n,o)}catch(a){void 0}}}const p=class{static initContainer(){
return this.container||(this.container=document.createElement("div"),this.container.id="toast-container",Object.assign(this.container.style,{
position:"fixed",top:"20px",right:"20px",zIndex:"99999",pointerEvents:"none"}),document.body.appendChild(this.container)),this.container}
static show(e,t="info",n=4e3){const a=this.initContainer(),i=document.createElement("div");i.textContent=e,Object.assign(i.style,{padding:"12px 20px",
marginBottom:"10px",borderRadius:"6px",color:"white",boxShadow:"0 2px 12px rgba(0,0,0,0.15)",opacity:"0",transform:"translateX(100%)",
transition:"all 0.3s ease-out",fontSize:"14px",fontWeight:"400",maxWidth:"300px",wordWrap:"break-word",pointerEvents:"auto",cursor:"pointer"})
;const r={success:"#10B981",error:"#EF4444",warning:"#F59E0B",info:"#3B82F6"};return i.style.backgroundColor=r[t],i.addEventListener("click",()=>{
this.removeToast(i)}),a.appendChild(i),setTimeout(()=>{i.style.opacity="1",i.style.transform="translateX(0)"},10),n>0&&setTimeout(()=>{
this.removeToast(i)},n),i}static removeToast(e){e.style.opacity="0",e.style.transform="translateX(100%)",setTimeout(()=>{e.parentNode&&e.remove()
},300)}static success(e,t=4e3){return this.show(e,"success",t)}static error(e,t=5e3){return this.show(e,"error",t)}static warning(e,t=4e3){
return this.show(e,"warning",t)}static info(e,t=3e3){return this.show(e,"info",t)}};p.container=null;let h=p;const m=class{static get CHECK_IN_URL(){
return`${e.getBaseUrl()}/hack.php?H_name=qiandao`}static get FORUM_URL(){return`${e.getBaseUrl()}/thread.php?fid=${this.FORUM_ID}`}
static syncStatusFromCache(e){try{const t=this.getStatusCache(),n=this.getTodayDate();t&&t.date===n&&t.signed?(void 0,
this.updateButtonStatus(e,!0)):(void 0,e&&(e.textContent="自动签到",e.title="点击自动签到"))}catch(t){void 0,e&&(e.textContent="自动签到",e.title="点击自动签到")}}
static async initStatusCheck(e){try{const t=this.getTodayDate();void 0;const n=await this.getCheckInStats();if(!n)return void 0,
this.updateButtonStatus(e,!1),void 0;const a=this.parseSignDate(n.lastSignTime)===t;void 0,this.setStatusCache(a,n.lastSignTime),
this.updateButtonStatus(e,a)}catch(t){void 0}}static async execute(e){try{void 0;const n=this.getTodayDate();h.show("正在检查签到状态...","info",2e3)
;const a=await this.getCheckInStats();let i=!1;if(a){if(i=this.parseSignDate(a.lastSignTime)===n,i)return void 0,h.show("✅ 今天已经签到过了","success",2e3),
this.setStatusCache(!0,a.lastSignTime),this.updateButtonStatus(e,!0),void 0}else void 0;const r=this.getReplyStatus()
;if(r&&r.date===n&&r.replied)void 0,h.show("今日已回帖,直接进入签到...","info",2e3);else{h.show("开始自动回复帖子...","info",2e3);try{await this.autoReply(),
this.setReplyStatus(!0),h.show("✅ 回帖成功!等待2秒后打开签到页...","success",2e3),await this.sleep(2e3)}catch(t){return void 0,
h.show("回复帖子失败: "+t.message,"error",3e3),void 0}}const o=["kx","fd","yl"],s=o[Math.floor(Math.random()*o.length)];await this.sleep(500),
await this.checkHasCaptcha()?(void 0,h.show("检测到验证码,请完成验证","info",2e3),this.openCheckInPopup(e,s)):(void 0,h.show("正在自动签到...","info",2e3),
await this.autoCheckInWithoutCaptcha(s)?(h.show("✅ 签到成功!","success",3e3),this.setStatusCache(!0,""),this.updateButtonStatus(e,!0),
setTimeout(()=>window.location.reload(),1500)):h.show("❌ 签到失败,请重试","error",3e3))}catch(t){void 0,h.show("自动签到失败: "+t.message,"error",3e3)}}
static async getCheckInStats(){try{void 0;const e=await fetch(this.CHECK_IN_URL,{credentials:"include",cache:"no-cache"}),t=await e.text();void 0
;const n=(new DOMParser).parseFromString(t,"text/html")
;if(void 0,t.includes("slider_captcha")||t.includes("sliderbox")||t.includes("verify_token")||t.includes("验证码")||t.includes("captcha")||t.includes("verifycode")){
void 0;const e=[".stats",".signarea .stats",".qiandao_text",".sign-info",'div[class*="stat"]','div[class*="sign"]'];let a=null
;for(const t of e)if(a=n.querySelector(t),a){void 0;break}if(!a){void 0
;const e=t.match(/累计签到[::]\s*(\d+)\s*天/),n=t.match(/本月[::]\s*(\d+)\s*天/),a=t.match(/上次签到[::]\s*(\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2})/);if(e||n||a){
return void 0,{totalDays:e?parseInt(e[1]):0,monthDays:n?parseInt(n[1]):0,lastSignTime:a?a[1]:""}}return void 0,null}const i=a.textContent||"";void 0
;const r=i.match(/累计签到[::]\s*(\d+)\s*天/),o=r?parseInt(r[1]):0,s=i.match(/本月[::]\s*(\d+)\s*天/),l=s?parseInt(s[1]):0,c=i.match(/上次签到[::]\s*(\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2})/)
;return void 0,{totalDays:o,monthDays:l,lastSignTime:c?c[1]:""}}{void 0;const e=n.querySelector("td.tac")||n.querySelector('td[class*="tac"]');if(!e){
void 0
;const e=t.match(/您累计已签到[::]\s*<b>(\d+)<\/b>\s*天/),n=t.match(/您本月已累计签到[::]\s*<b>(\d+)<\/b>\s*天/),a=t.match(/您上次签到时间[::]\s*<font[^>]*>(\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2})<\/font>/)
;if(e||n||a){return void 0,{totalDays:e?parseInt(e[1]):0,monthDays:n?parseInt(n[1]):0,lastSignTime:a?a[1]:""}}return void 0,null}
const a=e.textContent||"",i=e.innerHTML||"";void 0
;const r=i.match(/您累计已签到[::]\s*<b>(\d+)<\/b>\s*天/)||a.match(/您累计已签到[::]\s*(\d+)\s*天/),o=r?parseInt(r[1]):0,s=i.match(/您本月已累计签到[::]\s*<b>(\d+)<\/b>\s*天/)||a.match(/您本月已累计签到[::]\s*(\d+)\s*天/),l=s?parseInt(s[1]):0,c=i.match(/您上次签到时间[::]\s*<font[^>]*>(\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2})<\/font>/)||a.match(/您上次签到时间[::]\s*(\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2})/)
;return void 0,{totalDays:o,monthDays:l,lastSignTime:c?c[1]:""}}}catch(e){return void 0,null}}static parseSignDate(e){if(!e)return""
;const t=e.match(/(\d{4}-\d{2}-\d{2})/);return t?t[1]:""}static async checkHasCaptcha(){try{void 0;const e=await fetch(this.CHECK_IN_URL,{
credentials:"include",cache:"no-cache"
}),t=await e.text(),n=t.includes("slider_captcha")||t.includes("sliderbox")||t.includes("verify_token")||t.includes("slider")||t.includes("captcha"),a=t.includes("验证码")||t.includes("captcha")||t.includes("verifycode")
;return void 0,n||a}catch(e){return void 0,!0}}static getCurrentUsername(){try{
const e=document.querySelector('#td_userinfomore[href*="u.php?action=show"]');if(e){
const t=e.textContent?.trim()||e.querySelector("span")?.textContent?.trim();if(t)return void 0,t}
const t=document.querySelectorAll('a[href*="u.php?action=show"]');for(const n of t){const e=n.textContent?.trim()
;if(e&&e.length>0&&e.length<50)return void 0,e}return void 0,null}catch(e){return void 0,null}}static checkLoginStatus(){
const e=document.querySelector('#td_userinfomore[href*="u.php?action=show"]'),t=document.querySelector('a[href="login.php"]');return void 0,!!e&&!t}
static async autoCheckInWithoutCaptcha(e){try{const t=this.checkLoginStatus();if(this.getCurrentUsername(),!t)return void 0,!1;void 0
;const n=await fetch(this.CHECK_IN_URL,{credentials:"include",cache:"no-cache"});void 0
;const a=await n.text(),i=new DOMParser,r=i.parseFromString(a,"text/html");let o=r.querySelector("#input_bbb"),s=r.querySelector("#randstr_bbb")
;o||(o=r.querySelector('input[name="hycode"]')),s||(s=r.querySelector('input[name="hyrandstr"]'))
;const l=o?.value||"",c=s?.value||"",d=r.querySelector("form"),p=d?Array.from(d.querySelectorAll('input[type="hidden"]')):[];void 0
;const h=new URLSearchParams;h.append("action","qiandao"),h.append("qdxq",e);for(const e of p){const t=e.name,n=e.value;t&&h.append(t,n)}
h.has("method")||h.append("method","AND"),h.has("sch_area")||h.append("sch_area","0"),h.has("f_fid")||h.append("f_fid","0"),
h.has("sch_time")||h.append("sch_time","all"),h.append("hycode",l),h.append("hyrandstr",c);const m=await fetch(this.CHECK_IN_URL,{method:"POST",
credentials:"include",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:h.toString()});void 0
;const u=await m.text(),g=u.includes("签到成功")||u.includes("恭喜你签到成功"),f=u.includes("今天已签到")||u.includes("今日已签到"),v=u.includes("必须绑定邮箱")||u.includes("绑定邮箱")
;if(u.includes("提示信息")||u.includes("错误"),void 0,v)return void 0,!1;if(!g&&!f){void 0;const e=i.parseFromString(u,"text/html");let t=""
;const n=e.querySelector('div[class*="msg"], div[class*="tip"], div[class*="error"]');if(n&&(t=n.textContent?.trim()||""),!t){
const n=e.querySelector("title");n&&n.textContent?.includes("提示")&&(t=n.textContent)}if(!t){
const e=[/<div[^>]*class="[^"]*msg[^"]*"[^>]*>([^<]+)<\/div>/i,/<div[^>]*class="[^"]*tip[^"]*"[^>]*>([^<]+)<\/div>/i,/<div[^>]*class="[^"]*error[^"]*"[^>]*>([^<]+)<\/div>/i,/alert\(['"]([^'"]+)['"]\)/i,/提示[::]\s*([^<\n]+)/i,/错误[::]\s*([^<\n]+)/i]
;for(const n of e){const e=u.match(n);if(e&&e[1]){t=e[1].trim();break}}}t,void 0}return g||f}catch(t){return void 0,!1}}
static async openCheckInPopup(e,t){void 0,h.show("🎯 请完成滑块验证","info",2e3);try{const n=document.createElement("div");n.id="checkin-slider-modal",
n.style.cssText="\n        position: fixed;\n        top: 120px;\n        right: 20px;\n        background: #fff;\n        border-radius: 16px;\n        box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);\n        padding: 20px;\n        z-index: 99999;\n        animation: slideIn 0.3s;\n        width: 380px;\n      "
;const a=document.createElement("div")
;a.style.cssText="\n        display: flex;\n        justify-content: space-between;\n        align-items: center;\n        margin-bottom: 16px;\n      "
;const i=document.createElement("div")
;i.textContent="🎯 签到验证",i.style.cssText="\n        font-size: 16px;\n        font-weight: 600;\n        color: #333;\n      "
;const r=document.createElement("button")
;r.textContent="✕",r.style.cssText="\n        width: 28px;\n        height: 28px;\n        border: none;\n        border-radius: 50%;\n        background: #f0f0f0;\n        color: #666;\n        font-size: 18px;\n        cursor: pointer;\n        transition: 0.2s;\n      ",
r.onmouseover=()=>r.style.background="#e0e0e0",r.onmouseout=()=>r.style.background="#f0f0f0",r.onclick=()=>n.remove(),a.appendChild(i),
a.appendChild(r);const o=document.createElement("div")
;o.style.cssText="\n        position: relative;\n        width: 360px;\n        height: 300px;\n        overflow: hidden;\n        border-radius: 8px;\n        background: #fafafa;\n      "
;const s=document.createElement("iframe")
;s.src=this.CHECK_IN_URL,s.style.cssText="\n        width: 1200px;\n        height: 2000px;\n        border: none;\n        position: absolute;\n        top: -600px;\n        left: -420px;\n        transform: scale(1);\n      ",
o.appendChild(s),n.appendChild(a),n.appendChild(o),document.body.appendChild(n),s.onload=()=>{try{void 0;try{
const e=s.contentDocument||s.contentWindow?.document;if(e){const t=e.querySelector("#slider_captcha, .sliderbox");if(t){
const e=t.getBoundingClientRect();void 0,s.style.top=`-${e.top-10}px`,s.style.left=`-${e.left-20}px`,h.show("✅ 验证加载完成,请拖动滑块","success",2e3)
}else void 0,h.show("⚠️ 请在下方完成滑块验证","info",2e3)}}catch(a){void 0,h.show("✅ 验证加载完成,请拖动滑块","success",2e3)}const i=setInterval(()=>{try{
const a=s.contentDocument||s.contentWindow?.document;if(!a)return;const r=a.querySelector("#verify_token");if(r&&r.value){clearInterval(i)
;const a=r.value;void 0,h.show("✅ 验证成功,正在签到...","info",2e3),n.remove(),this.submitCheckInWithToken(a,t).then(t=>{t?(h.show("✅ 签到成功!","success",3e3),
this.setStatusCache(!0,""),this.updateButtonStatus(e,!0),setTimeout(()=>window.location.reload(),1500)):h.show("❌ 签到失败,请重试","error",3e3)})}}catch(a){}
},500);setTimeout(()=>clearInterval(i),6e4)}catch(i){void 0}};const l=document.createElement("style")
;l.textContent="\n        @keyframes slideIn {\n          from {\n            transform: translateX(400px);\n            opacity: 0;\n          }\n          to {\n            transform: translateX(0);\n            opacity: 1;\n          }\n        }\n      ",
document.querySelector("#checkin-slider-animation")||(l.id="checkin-slider-animation",document.head.appendChild(l))}catch(n){void 0,
h.show("❌ 加载失败: "+n.message,"error",3e3)}}static async submitCheckInWithToken(e,t){try{const n=new URLSearchParams;n.append("action","qiandao"),
n.append("qdxq",t),n.append("verify_token",e);const a=await fetch(this.CHECK_IN_URL,{method:"POST",credentials:"include",headers:{
"Content-Type":"application/x-www-form-urlencoded"},body:n.toString()
}),i=await a.text(),r=i.includes("签到成功")||i.includes("恭喜你签到成功"),o=i.includes("今天已签到")||i.includes("今日已签到");return void 0,r||o}catch(n){return void 0,
!1}}static getTodayDate(){const e=new Date;return`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,"0")}-${String(e.getDate()).padStart(2,"0")}`
}static getStatusCache(){try{return Storage.get(this.STATUS_CACHE_KEY,null)}catch{return null}}static setStatusCache(e,t=""){try{const n={
date:this.getTodayDate(),signed:e,lastSignDate:t,timestamp:Date.now()};Storage.set(this.STATUS_CACHE_KEY,n)}catch(n){void 0}}static getReplyStatus(){
try{return Storage.get(this.REPLY_CACHE_KEY,null)}catch{return null}}static setReplyStatus(e){try{const t={date:this.getTodayDate(),replied:e,
timestamp:Date.now()};Storage.set(this.REPLY_CACHE_KEY,t)}catch(t){void 0}}static updateButtonStatus(e,t){e&&(t?(e.textContent="今日已签 ✓",
e.style.opacity="0.6",e.style.cursor="not-allowed",e.style.pointerEvents="none",e.title="今天已经签到过了"):(e.textContent="自动签到",e.style.opacity="1",
e.style.cursor="pointer",e.style.pointerEvents="",e.title="点击自动签到"))}static async autoReply(){void 0;const e=await this.getRecentThreads();if(void 0,
0===e.length)throw new Error("未找到可回复的帖子(两天内无新帖)");void 0;const t=await this.findUnrepliedThread(e);if(!t)throw new Error("未找到可回复的帖子(所有帖子都已回复)")
;void 0,await this.replyThread(t)}static async getRecentThreads(){try{const e=await fetch(this.FORUM_URL,{credentials:"include"
}),t=await e.text(),n=(new DOMParser).parseFromString(t,"text/html"),a=[],i=new Date,r=new Date(i.getTime()-1728e5),o=n.querySelectorAll("tr.tr3.t_one")
;for(const s of Array.from(o)){if(s.querySelector('img[src*="headtopic"]'))continue;const e=s.querySelectorAll('a[href*="read.php?tid="]');let t=null
;for(const a of Array.from(e))if((a.textContent?.trim()||"").length>3){t=a;break}if(!t)continue;const n=t.textContent?.trim()||""
;if(!n||"⊙"===n)continue;const i=t.href,o=i.match(/tid=(\d+)/);if(!o)continue;const l=o[1],c=s.querySelector("td:last-child")?.textContent?.trim()||""
;this.isWithinTwoDays(c,r)&&a.push({tid:l,title:n,url:i,date:c})}return void 0,a}catch(e){return void 0,[]}}static isWithinTwoDays(e,t){
return!!(e.includes("小时前")||e.includes("分钟前")||e.includes("今天")||"昨天"===e)||!!e.match(/(\d{4})-(\d{2})-(\d{2})/)&&new Date(e)>=t}
static async findUnrepliedThread(e){const t=this.getRepliedThreads();for(const n of e)if(!t.includes(n.tid))return n;return e[0]||null}
static async replyThread(t){try{void 0;const n=await fetch(t.url,{credentials:"include"
}),a=await n.text(),i=(new DOMParser).parseFromString(a,"text/html").querySelector('form[name="FORM"]');if(!i)throw void 0,new Error("未找到回复表单");void 0
;const r=this.getRandomReply();void 0;const o=new FormData;o.append("step","2"),o.append("tid",t.tid),o.append("atc_content",r),
o.append("atc_title","RE: "+t.title.substring(0,50));void 0,i.querySelectorAll('input[type="hidden"]').forEach(e=>{const t=e.name,n=e.value
;t&&n&&o.append(t,n)});const s=await fetch(`${e.getBaseUrl()}/post.php?`,{method:"POST",credentials:"include",body:o});void 0;const l=await s.text()
;if(void 0,!s.ok||l.includes("错误")||l.includes("失败"))throw void 0,new Error("回复请求失败");void 0,this.saveRepliedThread(t.tid)}catch(n){throw void 0,n}}
static getRandomReply(){return this.REPLY_POOL[Math.floor(Math.random()*this.REPLY_POOL.length)]}static getRepliedThreads(){try{
const e=Date.now()-6048e5,t=(Storage.get("REPLIED_THREADS_TIME",[])||[]).filter(t=>t.time>e);return Storage.set("REPLIED_THREADS_TIME",t),
t.map(e=>e.tid)}catch{return[]}}static saveRepliedThread(e){try{const t=Storage.get("REPLIED_THREADS_TIME",[])||[];t.push({tid:e,time:Date.now()}),
Storage.set("REPLIED_THREADS_TIME",t)}catch(t){void 0}}static sleep(e){return new Promise(t=>setTimeout(t,e))}};m.FORUM_ID="57",
m.REPLY_CACHE_KEY="DAILY_REPLY_STATUS_V3",m.STATUS_CACHE_KEY="CHECK_IN_STATUS_V3",
m.REPLY_POOL=["楼主辛苦了,内容很棒!","感谢分享,内容很有价值!","楼主辛苦了,非常感谢分享!","内容不错,感谢楼主分享!","感谢楼主的分享!","楼主辛苦了,收藏了!","感谢分享,非常有用!","楼主辛苦了,谢谢分享!","内容很棒,感谢楼主!","感谢分享,收藏了!","非常感谢楼主的分享!","内容不错,谢谢分享!"]
;let u=m;class CheckInInfoPanel{static async waitForElement(e,t=5e3){const n=Date.now();for(;Date.now()-n<t;){const t=document.querySelector(e)
;if(t)return t;await new Promise(e=>setTimeout(e,100))}return null}static async init(){try{void 0
;const e=["#head #banner","#banner","td#banner",'td[id="banner"]',"#head table td:last-child",'#head table td[align="right"]'];let t=null
;for(const a of e)if(t=await this.waitForElement(a,2e3),t){void 0;break}if(!t){void 0;return document.querySelector("#head, head"),0,void 0}
const n=await u.getCheckInStats();if(!n)return void 0,void 0;void 0,this.createInfoPanel(t,n)}catch(e){void 0}}static createInfoPanel(e,t){
e.innerHTML=""
;const n=this.getTodayDate(),a=this.parseSignDate(t.lastSignTime)===n,i=a?"✅":"⏰",r=a?"今日已签":"待签到",o=a?"rgba(144, 238, 144, 0.9)":"rgba(255, 215, 0, 0.9)",s=document.createElement("div")
;s.className="checkin-info-panel",
s.style.cssText='\n      display: inline-flex;\n      align-items: center;\n      gap: 16px;\n      padding: 10px 20px;\n      background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n      border-radius: 10px;\n      box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);\n      font-family: "PingFang SC", "Microsoft YaHei", sans-serif;\n      color: #fff;\n      font-size: 13px;\n      line-height: 1.5;\n    '
;const l=document.createElement("div")
;l.style.cssText="\n      text-align: center;\n      border-right: 1px solid rgba(255, 255, 255, 0.25);\n      padding-right: 16px;\n    ",
l.innerHTML=`\n      <div style="font-size: 10px; opacity: 0.85; margin-bottom: 2px;">累计</div>\n      <div style="font-size: 18px; font-weight: 700;">\n        ${t.totalDays}<span style="font-size: 11px; opacity: 0.9; margin-left: 2px;">天</span>\n      </div>\n    `
;const c=document.createElement("div")
;c.style.cssText="\n      text-align: center;\n      border-right: 1px solid rgba(255, 255, 255, 0.25);\n      padding-right: 16px;\n    ",
c.innerHTML=`\n      <div style="font-size: 10px; opacity: 0.85; margin-bottom: 2px;">本月</div>\n      <div style="font-size: 18px; font-weight: 700;">\n        ${t.monthDays}<span style="font-size: 11px; opacity: 0.9; margin-left: 2px;">天</span>\n      </div>\n    `
;const d=document.createElement("div")
;d.style.cssText="\n      text-align: center;\n      border-right: 1px solid rgba(255, 255, 255, 0.25);\n      padding-right: 16px;\n      max-width: 140px;\n    ",
d.innerHTML=`\n      <div style="font-size: 10px; opacity: 0.85; margin-bottom: 2px;">上次签到</div>\n      <div style="font-size: 11px; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">\n        ${t.lastSignTime||"暂无"}\n      </div>\n    `
;const p=document.createElement("div");p.style.cssText="\n      display: flex;\n      align-items: center;\n      gap: 10px;\n    "
;const h=document.createElement("div")
;h.style.cssText=`\n      font-size: 12px;\n      font-weight: 600;\n      color: ${o};\n      white-space: nowrap;\n    `,h.textContent=`${i} ${r}`
;const m=document.createElement("button")
;m.textContent=a?"已签到":"签到",m.style.cssText=`\n      padding: 6px 16px;\n      background: ${a?"rgba(255, 255, 255, 0.15)":"rgba(255, 255, 255, 0.95)"};\n      color: ${a?"rgba(255, 255, 255, 0.6)":"#667eea"};\n      border: none;\n      border-radius: 6px;\n      font-size: 13px;\n      font-weight: 600;\n      cursor: ${a?"not-allowed":"pointer"};\n      transition: all 0.2s;\n      white-space: nowrap;\n      box-shadow: ${a?"none":"0 2px 6px rgba(0, 0, 0, 0.1)"};\n    `,
a||(m.onmouseover=()=>{m.style.background="#fff",m.style.transform="translateY(-1px)",m.style.boxShadow="0 3px 10px rgba(0, 0, 0, 0.15)"},
m.onmouseout=()=>{m.style.background="rgba(255, 255, 255, 0.95)",m.style.transform="translateY(0)",m.style.boxShadow="0 2px 6px rgba(0, 0, 0, 0.1)"},
m.onclick=()=>{u.execute(m)}),p.appendChild(h),p.appendChild(m),s.appendChild(l),s.appendChild(c),s.appendChild(d),s.appendChild(p),e.appendChild(s)
;const g=document.createElement("style")
;g.textContent="\n      @media (max-width: 768px) {\n        .checkin-info-panel {\n          flex-direction: column !important;\n          gap: 12px !important;\n          padding: 10px 16px !important;\n          font-size: 12px !important;\n        }\n        .checkin-info-panel > div {\n          border-right: none !important;\n          padding-right: 0 !important;\n          border-bottom: 1px solid rgba(255, 255, 255, 0.3);\n          padding-bottom: 10px;\n        }\n        .checkin-info-panel > div:last-child {\n          border-bottom: none !important;\n          padding-bottom: 0 !important;\n        }\n      }\n    ",
document.head.appendChild(g)}static getTodayDate(){const e=new Date
;return`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,"0")}-${String(e.getDate()).padStart(2,"0")}`}static parseSignDate(e){if(!e)return""
;const t=e.match(/(\d{4}-\d{2}-\d{2})/);return t?t[1]:""}}class App2048{static isLoggedIn(){
if(document.querySelector('#td_userinfomore[href*="u.php?action=show"]'))return void 0,!0;const e=document.querySelector('a[href="login.php"]')
;if(e&&e.textContent?.includes("登录"))return void 0,!1;const t=document.querySelector('a[href="register.php"]')
;return t&&t.textContent?.includes("注册"),void 0,!1}static is2048Site(){const e=document.title
;return!(!e.includes("2048")&&!e.includes("人人为我"))||!!document.querySelector('a[href="/2048"] img[src="/2048/logo.png"], a[href*="hack.php?H_name=qiandao"], .tr3.t_one, .f14.cc, #read_tpc')
}static async displayThreadImages(){if(e.isContentPage())return;e.removeRules();const t=e.safeQuerySelectorAll(CONFIG.selectors.threadLinks)
;t.length&&await Promise.all(t.map(e=>PreviewProcessor.processThreadLink(e)))}static isSearchPage(){
return CONFIG.regex.searchUrl.test(window.location.href)&&null!==document.querySelector(CONFIG.selectors.searchResultTable)}static async main(){
if(this.is2048Site())try{i.init(),o.injectStyles();const t=window.location.pathname,n=window.location.href;void 0;if(void 0,
("/"===t||"/index.php"===t||"/2048"===t||"/2048/"===t||"/2048/index.php"===t||!t||""===t||"/index.php"===t&&!n.includes("?")||t.endsWith("/")&&!n.includes("thread")&&!n.includes("read"))&&this.isLoggedIn()&&(void 0,
CheckInInfoPanel.init().catch(e=>{})),e.isContentPage())return;this.isSearchPage()?(d.init(),await this.displayThreadImages()):(AdRemover.removeAds(),
await this.displayThreadImages())}catch(t){void 0}}}AdRemover.removeGlobalAds(),
"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>{AdRemover.removeGlobalAds(),App2048.main()
}):(AdRemover.removeGlobalAds(),App2048.main()),window.addEventListener("load",()=>{AdRemover.removeGlobalAds()})})();