sis001-预览

sis001第一会所综合社区,帖子图片预览,板块收纳,搜索优化

// ==UserScript==
// @name         sis001-预览
// @version      1.3.0
// @namespace    https://sleazyfork.org/zh-CN/users/1461640-%E6%98%9F%E5%AE%BF%E8%80%81%E9%AD%94
// @author       星宿老魔
// @description  sis001第一会所综合社区,帖子图片预览,板块收纳,搜索优化
// @match        https://sis001.com/*
// @match        https://*.sis001.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=sis001.com
// @license      MIT
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_deleteValue
// @run-at       document-start
// ==/UserScript==

(function(){"use strict";const e={ACCENT:"#00599F",BORDER_LIGHT:"#e3e6ea",BORDER_NORMAL:"#e9ecef",TEXT_PRIMARY:"#2c3e50",TEXT_SECONDARY:"#666",
TEXT_LIGHT:"#999",TEXT_ERROR:"#333"},t={SM:"6px",XL:"12px",ROUND:"50%",PILL:"999px"},n={MD:"8px",LG:"10px",XL:"12px",XXL:"16px"},i={
LIGHT:"0 2px 6px rgba(0,0,0,0.08)",NORMAL:"0 3px 12px rgba(0,0,0,0.08)"},a={GRADIENT:"linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%)",
WHITE_ALPHA:"rgba(255,255,255,0.9)",LIGHT_ALPHA:"rgba(248,249,250,0.6)"},r={select(e){return document.querySelector(e)},selectAll(e){
return document.querySelectorAll(e)},create(e,t={},n={}){const i=document.createElement(e);return Object.entries(t).forEach(([e,t])=>{
i.setAttribute(e,t)}),Object.entries(n).forEach(([e,t])=>{i.style[e]=t}),i},addStyle(e,t){const n=document.createElement("style");return t&&(n.id=t),
n.textContent=e,document.head.appendChild(n),n}},o={resolve(e,t){try{return new URL(t,e).href}catch(n){return void 0,t}},isHttp(e){
return/^https?:\/\//i.test(e)}},s={applyButtonStyle(t,options={}){
const{primary:n=!1}=options,i=["display:inline-flex","align-items:center","justify-content:center","height:28px","padding:0 12px","border-radius:6px","font-size:12px","line-height:1","cursor:pointer","user-select:none","white-space:nowrap","box-sizing:border-box"],a=n?`background:${e.ACCENT};color:#fff;border:1px solid ${e.ACCENT}`:`background:#fff;color:${e.TEXT_PRIMARY};border:1px solid ${e.BORDER_LIGHT}`
;t.style.cssText=[...i,a].join(";")},ensureToggleStyles(){if(document.querySelector('style[data-sis-toggle-style="1"]'))return
;const n=`.sis-toggle{display:inline-flex;align-items:center;gap:${t.SM};cursor:pointer;user-select:none;height:28px;padding:0 12px;border:1px solid ${e.BORDER_LIGHT};border-radius:${t.SM};background:#fff;box-shadow:${i.LIGHT};vertical-align:middle;box-sizing:border-box}.sis-toggle .sis-input{position:absolute;opacity:0;width:0;height:0}.sis-toggle .sis-switch{position:relative;width:30px;height:16px;background:#e5e7eb;border-radius:${t.PILL};box-shadow:inset 0 0 0 1px #d1d5db;flex:0 0 30px}.sis-toggle .sis-switch::before{content:"";position:absolute;top:2px;left:2px;width:12px;height:12px;background:#fff;border-radius:${t.ROUND};box-shadow:0 1px 2px rgba(0,0,0,.2)}.sis-toggle .sis-input:checked + .sis-text + .sis-switch{background:${e.ACCENT}}.sis-toggle .sis-input:checked + .sis-text + .sis-switch::before{transform:translateX(14px)}.sis-toggle .sis-text{color:${e.TEXT_ERROR};font-size:12px}`
;r.addStyle(n,"sis-toggle-styles").setAttribute("data-sis-toggle-style","1")}},c={createOverlay(){return r.create("div",{},{position:"fixed",
inset:"0",background:"rgba(0,0,0,0.4)",zIndex:"10001",display:"flex",alignItems:"center",justifyContent:"center"})},createPanel(e="480px"){
return r.create("div",{},{width:e,maxWidth:"92vw",maxHeight:"80vh",overflow:"auto",background:"#fff",borderRadius:"10px",
boxShadow:"0 10px 30px rgba(0,0,0,.2)"})},createHeader(e,t){const n=r.create("div",{},{padding:"12px 16px",borderBottom:"1px solid #e9ecef",
fontWeight:"600",display:"flex",justifyContent:"space-between",alignItems:"center"});n.textContent=e;const i=r.create("button")
;return i.textContent="×",s.applyButtonStyle(i),i.onclick=t,n.appendChild(i),n},createFooter(e,t,n="保存并刷新"){const i=r.create("div",{},{
padding:"12px 16px",borderTop:"1px solid #e9ecef",display:"flex",justifyContent:"flex-end",gap:"10px"}),a=r.create("button");a.textContent="取消",
s.applyButtonStyle(a),a.onclick=e;const o=r.create("button");return o.textContent=n,s.applyButtonStyle(o),o.onclick=t,i.appendChild(a),
i.appendChild(o),i}},l={waitForDOMContentLoaded(){return"loading"===document.readyState?new Promise(e=>{
document.addEventListener("DOMContentLoaded",()=>e(),{once:!0})}):Promise.resolve()},waitForWindowLoad(){
return"complete"!==document.readyState?new Promise(e=>{window.addEventListener("load",()=>e(),{once:!0})}):Promise.resolve()}},d=class{static init(){
this.setupMagnetLinks()}static setupMagnetLinks(){r.select(".t_msgfont")&&r.selectAll(".t_msgfont").forEach(e=>{this.processPost(e)})}
static processPost(e){if(this.processed.has(e))return;const t=/([a-fA-F0-9]{40})/g
;t.test(e.innerHTML)&&(e.innerHTML=e.innerHTML.replace(t,e=>`magnet:?xt=urn:btih:${e}`)),this.processed.add(e)}static refresh(){
this.setupMagnetLinks()}};d.processed=new WeakSet;let p=d;class AdRemover{static init(){this.injectHidingCSS(),this.removeRulesTable(),
this.removePublicMessages(),this.removeStickyTopics(),this.removeImportantTopics(),this.removeAdministrativeThreads(),setTimeout(()=>{
this.removeRulesTable(),this.removePublicMessages(),this.removeStickyTopics(),this.removeImportantTopics(),this.removeAdministrativeThreads()},1e3)}
static injectHidingCSS(){if(r.select('style[data-sis-ad-remover="1"]'))return
;const e='\n      /* 立即隐藏本版规则表格 */\n      table[summary="Rules and Recommend"] { display: none !important; }\n      \n      /* 立即隐藏公共消息 */\n      .maintable#pmprompt,\n      .box#pmprompt { display: none !important; }\n      \n      /* 立即隐藏固定主题和重要主题区块 */\n      thead.separation { display: none !important; }\n      tbody[id^="stickthread_"] { display: none !important; }\n      \n      /* 立即隐藏版务相关帖子(备用CSS) */\n      .sis-hide-admin { display: none !important; }\n    '
;r.addStyle(e).setAttribute("data-sis-ad-remover","1")}static removeRulesTable(){
const e=document.querySelector('table[summary="Rules and Recommend"]');e&&e.remove()}static removePublicMessages(){
const e=document.querySelector(".maintable#pmprompt");e&&e.remove();const t=document.querySelector(".box#pmprompt");t&&t.remove()}
static removeTopicsByType(e){document.querySelectorAll("thead.separation").forEach(t=>{const n=t.querySelectorAll("font");let i=!1;if(n.forEach(t=>{
e.some(e=>t.textContent?.includes(e))&&(i=!0)}),i){t.remove();let e=t.nextElementSibling
;for(;e&&"TBODY"===e.tagName&&e.id&&e.id.startsWith("stickthread_");){const t=e;e=e.nextElementSibling,t.remove()}}})}static removeStickyTopics(){
this.removeTopicsByType(["固定主題"])}static removeImportantTopics(){this.removeTopicsByType(["重要主題"])}static removeAdministrativeThreads(){
document.querySelectorAll('tbody[id^="stickthread_"], tbody[id^="normalthread_"]').forEach(e=>{
e.querySelectorAll('em a[href*="typeid=528"]').length>0&&(e.classList.add("sis-hide-admin"),setTimeout(()=>{e.remove()},10))})}static refresh(){
this.removeRulesTable(),this.removePublicMessages(),this.removeStickyTopics(),this.removeImportantTopics(),this.removeAdministrativeThreads()}}
class PostLayoutManager{static async transformPostLayout(e,t,n,i){const a=this.getTableColumnCount(e);e.innerHTML=""
;const o=r.create("tr"),s=r.create("td",{colspan:String(a)},{padding:"4px !important",border:"none !important",background:"transparent !important"
}),c=this.createPostContainer(),l=this.createTitleSection(t,n),d=this.createImageSection();c.appendChild(l),c.appendChild(d),s.appendChild(c),
o.appendChild(s),e.appendChild(o),await i(d)}static getTableColumnCount(e){const t=e.closest("table");if(t){
const e=t.querySelector("thead tr")||t.querySelector("tr:first-child");if(e){let t=0;if(e.querySelectorAll("th, td").forEach(e=>{
const n=parseInt(e.getAttribute("colspan")||"1");t+=n}),t>0)return t}}return 6}static createPostContainer(){return r.create("div",{
class:"new-post-layout"},{background:a.GRADIENT,border:`1px solid ${e.BORDER_LIGHT}`,borderRadius:t.XL,boxShadow:i.NORMAL,overflow:"hidden"})}
static createTitleSection(t,i){const o=r.create("div",{},{padding:`${n.XL} ${n.XXL}`,background:a.WHITE_ALPHA,
borderBottom:`1px solid ${e.BORDER_NORMAL}`}),s=r.create("a",{href:t},{fontWeight:"500",color:e.TEXT_PRIMARY,fontSize:"15px",lineHeight:"1.3",
textDecoration:"none",display:"block",wordBreak:"break-word"});return s.textContent=i||"无标题",o.appendChild(s),o}static createImageSection(){
const t=r.create("div",{},{padding:`${n.MD} ${n.XXL}`,background:a.LIGHT_ALPHA,display:"flex",gap:n.LG,minHeight:"60px",flexWrap:"nowrap",
alignItems:"center",overflow:"auto"}),i=r.create("div",{},{color:e.TEXT_SECONDARY,fontSize:"14px"});return i.textContent="正在加载图片预览...",
t.appendChild(i),t}}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 h={collectNames:"sis_board_collect_names",
favoriteNames:"sis_board_favorite_names",collectionOpen:"sis_board_collection_open",favoriteOpen:"sis_board_favorite_open",
searchFavForums:"sis_search_fav_forums",searchLastSelection:"sis_search_last_selection",searchFavAuto:"sis_search_fav_auto",
previewMaxImages:"sis_preview_max_images"},g={MAX_IMAGES_PER_POST:4};class Config{static getMaxImagesPerPost(){return g.MAX_IMAGES_PER_POST}
static getCollectedBoardNames(){try{const e=Storage.get(h.collectNames,"");if(!e)return[];const t=JSON.parse(e);return Array.isArray(t)?t:[]}catch(e){
return void 0,[]}}static setCollectedBoardNames(e){try{Storage.set(h.collectNames,JSON.stringify(e||[]))}catch(t){void 0}}
static getFavoriteBoardNames(){try{const e=Storage.get(h.favoriteNames,"");if(!e)return[];const t=JSON.parse(e);return Array.isArray(t)?t:[]}catch(e){
return void 0,[]}}static setFavoriteBoardNames(e){try{Storage.set(h.favoriteNames,JSON.stringify(e||[]))}catch(t){void 0}}static getCollectionOpen(){
try{return"1"===(Storage.get(h.collectionOpen,"0")??"0")}catch(e){return void 0,!1}}static setCollectionOpen(e){try{
Storage.set(h.collectionOpen,e?"1":"0")}catch(t){void 0}}static getFavoriteOpen(){try{return"1"===(Storage.get(h.favoriteOpen,"0")??"0")}catch(e){
return void 0,!1}}static setFavoriteOpen(e){try{Storage.set(h.favoriteOpen,e?"1":"0")}catch(t){void 0}}static getSearchFavForums(){try{
const e=Storage.get(h.searchFavForums,"");return e?JSON.parse(e):[]}catch(e){return void 0,[]}}static setSearchFavForums(e){try{
Storage.set(h.searchFavForums,JSON.stringify(e||[]))}catch(t){void 0}}static getSearchFavAuto(){try{
return"1"===(Storage.get(h.searchFavAuto,"0")??"0")}catch(e){return void 0,!1}}static setSearchFavAuto(e){try{Storage.set(h.searchFavAuto,e?"1":"0")
}catch(t){void 0}}static getSearchLastSelection(){try{const e=Storage.get(h.searchLastSelection,"");return e?JSON.parse(e):[]}catch(e){return void 0,
[]}}static setSearchLastSelection(e){try{Storage.set(h.searchLastSelection,JSON.stringify(e||[]))}catch(t){void 0}}}class ImageExtractor{
static extractAndGroupImages(e){const t=e.querySelector(".t_msgfont")||e.querySelector(".postmessage");if(!t)return{images:[],domainGroups:new Map}
;const n=t.cloneNode(!0);this.cleanContentClone(n)
;const i=Array.from(n.querySelectorAll("img")),a=i.filter(e=>this.isValidContentImage(e)),r=this.groupImagesByDomain(a);this.applyImageLimits(r)
;const o=Array.from(r.keys()),s=o[0]||"",c=r.get(s)||[];return this.logExtractionResults(c,i,o),{images:c,domainGroups:r}}static cleanContentClone(e){
e.querySelectorAll(".quote").forEach(e=>e.remove()),e.querySelectorAll(".ad_pip, .ad_thread3_0, .ad_thread4_0").forEach(e=>e.remove()),
e.querySelectorAll(".postratings, .comment_digg").forEach(e=>e.remove())}static isValidContentImage(e){
const t=e.getAttribute("onclick")||"",n=e.getAttribute("onload")||"",i=e.getAttribute("src")||e.src||""
;if(!i||i.length<=10||i.includes("data:"))return!1;if(!/\.(jpg|jpeg|png|gif|webp)(\?|$)/i.test(i))return!1
;if(i.includes("images/green001/")||i.includes("images/attachicons/")||i.includes("images/joinvip.gif")||i.includes("/ad_")||i.includes("advertisement"))return!1
;if(i.includes("images/smilies/")&&this.isSmallImage(e))return!1
;if(i.includes("images/common/")&&(i.match(/\/(she|mengmengda|yang|\d{5}SIS\d+)\.gif$/)||this.isSmallImage(e)))return!1
;const a=t.includes("zoom(this"),r=n.includes("attachimg(this");return a&&r}static groupImagesByDomain(e){const t=new Map;return e.forEach(e=>{
const n=this.getImageSource(e),i=this.extractDomain(n);t.has(i)||t.set(i,[]),t.get(i).push(e)}),t}static applyImageLimits(e){
const t=Config.getMaxImagesPerPost();Array.from(e.keys()).forEach(n=>{const i=e.get(n)||[];e.set(n,i.slice(0,t))})}static logExtractionResults(e,t,n){
e.length>0?void 0:t.length>5&&(void 0,
("localhost"===window.location.hostname||window.location.hostname.includes("dev"))&&t.slice(0,3).forEach((e,t)=>{e.getAttribute("src")||e.src,
e.getAttribute("onclick"),e.getAttribute("onload")}))}static isSmallImage(e){const t=e.getAttribute("width"),n=e.getAttribute("height");if(t||n){
const e=parseInt(t||"0",10),i=parseInt(n||"0",10);if(e>0&&e<=100||i>0&&i<=100)return!0}const i=e.style;if(i.width||i.height){
const e=parseInt(i.width,10),t=parseInt(i.height,10);if(e>0&&e<=100||t>0&&t<=100)return!0}
if(e.naturalWidth>0&&e.naturalHeight>0&&(e.naturalWidth<=100||e.naturalHeight<=100))return!0;const a=e.getAttribute("src")||""
;return[/\/meemo\d{3}\.gif$/i,/\/\w{2,6}\.gif$/i,/\/emoji_\w+\.gif$/i,/\/smiley_\w+\.gif$/i].some(e=>e.test(a))}static extractDomain(e){try{
return new URL(e).hostname}catch{return"unknown"}}static getImageSource(e){return e.getAttribute("src")||e.src||""}}const u=class{static get(e){
const t=this.cache.get(e);return t?Date.now()-t.timestamp>this.maxAge?(this.cache.delete(e),null):t:null}static set(e,t,n){
if(this.cache.size>=this.maxSize){const e=this.cache.keys().next().value;e&&this.cache.delete(e)}this.cache.set(e,{urls:t,domainGroups:n,
timestamp:Date.now(),extractedCount:t.length})}static cleanup(){const e=Date.now(),t=[];this.cache.forEach((n,i)=>{
e-n.timestamp>this.maxAge&&t.push(i)}),t.forEach(e=>this.cache.delete(e)),t.length>0}static getStats(){return{size:this.cache.size,
maxSize:this.maxSize}}static clear(){this.cache.clear()}};u.cache=new Map,u.maxSize=200,u.maxAge=18e5;let m=u;class ImageLoader{
static async loadImagesForPost(e,t,n,i=0){const a=2,r=m.get(e);if(r&&0===i)return void 0,t.innerHTML="",
0===r.urls.length?(this.showSimpleNoImageMessage(t),void 0):(n&&n(r.urls,r.domainGroups),void 0);try{const i=await fetch(e)
;if(!i.ok)throw new Error(`请求失败,状态码: ${i.status}`);const a=await i.text();if(a.includes("<b>Parse error</b>"))throw new Error("服务器返回PHP解析错误")
;const r=(new DOMParser).parseFromString(a,"text/html"),{images:s,domainGroups:c}=ImageExtractor.extractAndGroupImages(r);if(t.innerHTML="",
0===s.length)return this.showSimpleNoImageMessage(t),m.set(e,[],new Map),void 0;const l=s.map(t=>o.resolve(e,ImageExtractor.getImageSource(t)))
;return m.set(e,l,c),n&&n(l,c),void 0}catch(s){const r=s instanceof Error?s.message:"未知错误";0===i||r.includes("Parse error")||r.includes("500"),0
;const o=i<a,c=0===i?"重试":`重试 (${i}/${a})`;return this.showStaticFailureMessage(t,r.includes("403")||r.includes("权限")?"访问受限":"加载失败",o?()=>{
setTimeout(()=>{this.loadImagesForPost(e,t,n,i+1)},Math.min(1e3+1e3*i,3e3))}:void 0,c),void 0}}static showStaticFailureMessage(t,n,i,a="重试"){
t.innerHTML="",
t.style.cssText="\n      padding: 8px 20px;\n      background: transparent;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      height: auto;\n      min-height: 30px;\n      max-height: 30px;\n      gap: 10px;\n    "
;const o=r.create("div",{},{color:e.TEXT_LIGHT,fontSize:"13px",fontStyle:"italic",lineHeight:"1.2"});if(o.textContent=n,t.appendChild(o),i){
const n=r.create("button")
;n.textContent=a,n.style.cssText=`\n        padding: 2px 8px;\n        font-size: 11px;\n        margin-left: 8px;\n        cursor: pointer;\n        border: 1px solid ${e.TEXT_LIGHT};\n        background: transparent;\n        border-radius: 3px;\n        color: ${e.TEXT_LIGHT};\n      `,
n.onclick=e=>{e.stopPropagation(),i()},t.appendChild(n)}}static showSimpleNoImageMessage(t){t.innerHTML="",
t.style.cssText="\n      padding: 8px 20px;\n      background: transparent;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      height: auto;\n      min-height: 30px;\n      max-height: 30px;\n    "
;const n=r.create("div",{},{color:e.TEXT_LIGHT,fontSize:"13px",fontStyle:"italic",textAlign:"center",lineHeight:"1.2"});n.textContent="帖子内无图片内容",
t.appendChild(n)}}const f=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      max-width: 85%;\n      max-height: 85%;\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.overlay.appendChild(this.img),
this.overlay.appendChild(this.counter),this.overlay.appendChild(this.prevBtn),this.overlay.appendChild(this.nextBtn),
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="30" height="30"><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="30" height="30"><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: 40px;\n      height: 40px;\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 setupEvents(){this.overlay.onclick=e=>{e.target===this.overlay&&this.close()},this.prevBtn.onclick=e=>{e.stopPropagation(),this.prev()},
this.nextBtn.onclick=e=>{e.stopPropagation(),this.next()},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}}
;f.overlay=null,f.img=null,f.counter=null,f.prevBtn=null,f.nextBtn=null,f.images=[],f.currentIndex=0;let x=f;const y=class{
static injectStyles(options={}){if(this.injected)return;const e={...this.defaultOptions,...options},t=document.createElement("style")
;t.textContent=`\n      .shared-img-grid {\n        display: flex;\n        flex-wrap: nowrap;\n        align-items: flex-start;\n        gap: ${e.gap}px;\n        width: 100%;\n      }\n      \n      .shared-img-item {\n        overflow: hidden;\n        border-radius: ${e.borderRadius}px;\n        position: relative;\n        cursor: ${e.cursor};\n        min-height: ${e.minHeight}px;\n        max-height: ${e.maxHeight}px;\n        height: auto;\n        display: flex;\n        align-items: center;\n        justify-content: center;\n        background: ${e.backgroundColor};\n      }\n      \n      .shared-img-item-single {\n        overflow: hidden;\n        border-radius: ${e.borderRadius}px;\n        position: relative;\n        cursor: ${e.cursor};\n        min-height: ${e.minHeight}px;\n        max-height: ${e.maxHeight}px;\n        height: auto;\n        display: flex;\n        align-items: center;\n        justify-content: center;\n        background: ${e.backgroundColor};\n      }\n      \n      .shared-img {\n        max-width: 100%;\n        max-height: ${e.maxHeight}px;\n        width: auto;\n        height: auto;\n        object-fit: contain;\n      }\n    `,
document.head.appendChild(t),this.injected=!0}static createGrid(){const e=document.createElement("div");return e.className="shared-img-grid",e}
static createImageItem(e,t=!1,n){const i=document.createElement("div");i.className=t?"shared-img-item-single":"shared-img-item"
;const a=document.createElement("img");return a.className="shared-img",a.src=e,a.loading="lazy",n&&i.addEventListener("click",t=>{t.preventDefault(),
t.stopPropagation(),n(e)}),i.appendChild(a),i}static setGridWidth(e,t,n=8){const i=`calc((100% - ${(t-1)*n}px) / ${t})`
;Array.from(e.children).forEach(e=>{e.style.width=i,e.style.flex="0 0 auto"})}static create(e,t,options={}){this.injectStyles(options)
;const n=this.createGrid(),i=1===e.length;e.forEach((e,a)=>{const r=this.createImageItem(e,i,e=>{t&&t(e,a)});n.appendChild(r)})
;const a=options.gap||this.defaultOptions.gap;return this.setGridWidth(n,e.length,a),n}};y.injected=!1,y.defaultOptions={minHeight:200,maxHeight:400,
gap:8,backgroundColor:"#f5f5f5",borderRadius:4,cursor:"pointer"};let v=y;class ImageRenderer{static renderImages(e,t,n,i){e.innerHTML=""
;const a=Array.from(i.keys());if(0===a.length||0===t.length)return this.showGlobalFailure(e),void 0;const r=a[0],s=i.get(r)||[]
;if(0===s.length)return this.showGlobalFailure(e),void 0;const c=s.map(e=>o.resolve(n,ImageExtractor.getImageSource(e)))
;e.style.cssText="\n      padding: 16px 20px;\n      background: rgba(248, 250, 252, 0.7);\n    ";const l=v.create(c,(e,i)=>{
const a=t.map(e=>o.resolve(n||location.href,e));x.show(a,i)},{minHeight:150,maxHeight:280,gap:12,backgroundColor:"#f5f5f5",borderRadius:4})
;l.style.marginBottom="0",e.appendChild(l)}static showGlobalFailure(t){t.innerHTML="",
t.style.cssText="\n      padding: 8px 20px;\n      background: transparent;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      height: auto;\n      min-height: 30px;\n      max-height: 30px;\n    "
;const n=r.create("div",{},{fontSize:"12px",color:e.TEXT_SECONDARY,textAlign:"center",fontStyle:"italic"});n.textContent="帖子内可能无图",t.appendChild(n)}}
class ImagePreview{static async init(){await this.displayThreadImages()}static async displayThreadImages(){
if(r.select(".postmessage")||r.select("#postlist")||r.select(".plhin")||r.select(".t_msgfont"))return
;const e=window.location.href.includes("/search.php"),t=window.location.href.includes("/tag.php");let n=[];if(e||t){const e=r.selectAll("tbody")
;n=Array.from(e).filter(e=>{const t=e.querySelector('a[href*="thread-"], a[href*="viewthread.php"]'),n=e.querySelector(".icon");return t&&n})}else{
const e=r.selectAll('tbody[id^="normalthread_"]');n=Array.from(e)}const i=n.map(e=>async()=>{if(e.id&&e.id.startsWith("stickthread_"))return
;if(e.querySelector(".new-post-layout"))return;const t=e.querySelector('a[href*="thread-"], a[href*="viewthread.php"]');if(!t)return;const n=t.href
;let i=t.textContent?.trim()||"";if(!i){const t=e.querySelector('span[id^="thread_"]');t&&(i=t.textContent?.trim()||"")}
await PostLayoutManager.transformPostLayout(e,n,i,async e=>{await ImageLoader.loadImagesForPost(n,e,(t,i)=>{ImageRenderer.renderImages(e,t,n,i)})})})
;await Promise.all(i.map(e=>e()))}}class BoardManager{static init(){this.normalizeExclusiveLists(),this.setupBoardCollectionCollapse(),
this.setupBoardFavoriteSection()}static normalizeExclusiveLists(){
const e=new Set(Config.getFavoriteBoardNames()),t=new Set(Config.getCollectedBoardNames());let n=!1;e.forEach(e=>{t.has(e)&&(t.delete(e),n=!0)}),
n&&Config.setCollectedBoardNames(Array.from(t))}static findBoardElementsMap(){const e=new Map;return r.selectAll("div.mainbox.forumlist").forEach(t=>{
const n=t.querySelector("h3 > a"),i=n?.textContent?.trim()||"";i&&!e.has(i)&&e.set(i,t)}),e}static moveBoardsToContainer(e,t){
const n=this.findBoardElementsMap(),i=[];return e.forEach(e=>{const a=n.get(e);a&&(t.appendChild(a),i.push(e))}),i}
static setupBoardCollectionCollapse(){this.setupBoardSection({containerId:"board-collection-container",title:"板块收纳区",
getBoardNames:()=>Config.getCollectedBoardNames(),getOpenState:()=>Config.getCollectionOpen(),setOpenState:e=>Config.setCollectionOpen(e),
onSettings:()=>this.openBoardCollectSettings(),insertMethod:e=>this.insertContainer(e),emptyMessage:'未选择任何板块,可点击右侧"设置"进行选择。'})}
static setupBoardFavoriteSection(){this.setupBoardSection({containerId:"board-favorite-container",title:"板块收藏区",
getBoardNames:()=>Config.getFavoriteBoardNames(),getOpenState:()=>Config.getFavoriteOpen(),setOpenState:e=>Config.setFavoriteOpen(e),
onSettings:()=>this.openBoardFavoriteSettings(),insertMethod:e=>this.insertFavoriteContainer(e),emptyMessage:'未选择任何收藏板块,可点击右侧"设置"进行选择。'})}
static setupBoardSection(config){if(r.select(`#${config.containerId}`))return
;const e=new Set(config.getBoardNames()),t=Array.from(r.selectAll("div.mainbox.forumlist"));if(0===t.length)return;const n=t.filter(t=>{
const n=t.querySelector("h3 > a"),i=n?.textContent?.trim()||"";return i&&e.has(i)
}),i=this.createBoardContainer(config.containerId,config.title,n.length),{content:a}=this.setupContainerElements(i,{isOpen:config.getOpenState(),
onToggle:config.setOpenState,onSettings:config.onSettings,title:config.title,count:n.length});if(config.insertMethod(i),
0===n.length)this.showEmptyMessage(a,config.emptyMessage);else{const e=n.map(e=>{const t=e.querySelector("h3 > a");return t?.textContent?.trim()||""})
;this.moveBoardsToContainer(e,a)}}static createBoardContainer(e,t,n){return r.create("div",{id:e},{margin:"12px 0",border:"1px solid #e3e6ea",
borderRadius:"10px",boxShadow:"0 3px 12px rgba(0,0,0,0.08)",overflow:"hidden",background:"#fff"})}static setupContainerElements(e,options){
const t=r.create("div",{},{padding:"10px 14px",background:options.isOpen?"#f0f0f0":"linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%)",
border:options.isOpen?"2px solid #d0d0d0":"none",borderBottom:"1px solid #e9ecef",cursor:"pointer",userSelect:"none",display:"flex",
alignItems:"center",justifyContent:"space-between"}),n=r.create("span",{},{fontWeight:"600",color:"#2c3e50",fontSize:"14px"})
;n.textContent=`${options.title}(共 ${options.count} 个)`;const i=r.create("span",{},{fontSize:"12px",color:"#666"})
;i.textContent=options.isOpen?"[点击收起]":"[点击展开]";const a=r.create("button");a.textContent="设置",a.title="选择需要管理的板块",s.applyButtonStyle(a),
a.addEventListener("click",e=>{e.stopPropagation(),options.onSettings()});const o=r.create("div",{},{display:"flex",alignItems:"center",gap:"10px"})
;o.appendChild(i),o.appendChild(a),t.appendChild(n),t.appendChild(o);const c=r.create("div",{},{padding:"10px",background:"#fafafa",
border:"2px solid #d0d0d0",borderTop:"none",display:options.isOpen?"":"none"});return t.addEventListener("click",()=>{const e="none"===c.style.display
;c.style.display=e?"":"none",i.textContent=e?"[点击收起]":"[点击展开]",t.style.background=e?"#f0f0f0":"linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%)",
t.style.border=e?"2px solid #d0d0d0":"none",t.style.borderBottom="1px solid #e9ecef",options.onToggle(e)}),e.appendChild(t),e.appendChild(c),{
header:t,content:c,toggleHint:i}}static insertContainer(e){
const t=r.select('table.portalbox[summary="HeadBox"]')||r.select("#hottags")?.closest("table")||r.select("#hottags");if(t?.parentNode){
const n=t.parentNode;t.nextSibling?n.insertBefore(e,t.nextSibling):n.appendChild(e)}else document.body.appendChild(e)}
static insertFavoriteContainer(e){const t=r.select("#board-collection-container");if(t?.parentNode){const n=t.parentNode
;t.nextSibling?n.insertBefore(e,t.nextSibling):n.appendChild(e)}else this.insertContainer(e)}static showEmptyMessage(e,t){const n=r.create("div",{},{
color:"#666",fontSize:"12px"});n.textContent=t,e.appendChild(n)}static openBoardCollectSettings(){const e=this.getAllBoardNames()
;this.openBoardSettings(e,Config.getCollectedBoardNames(),"板块收纳设置","勾选需要收纳到顶部的板块:",e=>{const t=new Set(Config.getFavoriteBoardNames())
;e.forEach(e=>t.delete(e)),Config.setFavoriteBoardNames(Array.from(t)),Config.setCollectedBoardNames(e),location.reload()})}
static openBoardFavoriteSettings(){const e=this.getAllBoardNames()
;this.openBoardSettings(e,Config.getFavoriteBoardNames(),"板块收藏设置",'勾选需要加入"板块收藏区"的板块:',e=>{const t=new Set(Config.getCollectedBoardNames())
;e.forEach(e=>t.delete(e)),Config.setCollectedBoardNames(Array.from(t)),Config.setFavoriteBoardNames(e),location.reload()})}static getAllBoardNames(){
const e=Array.from(r.selectAll("div.mainbox.forumlist > h3 > a")).map(e=>e.textContent?.trim()||"").filter(Boolean);return Array.from(new Set(e))}
static openBoardSettings(e,t,n,i,a){const o=c.createOverlay(),s=c.createPanel("520px"),l=c.createHeader(n,()=>o.remove()),d=r.create("div",{},{
padding:"12px 16px"}),p=r.create("div",{},{color:"#666",marginBottom:"8px"});p.textContent=i,d.appendChild(p);const h=r.create("div",{},{
display:"grid",gridTemplateColumns:"1fr 1fr",gap:"6px"}),g=new Set(t);e.forEach(e=>{const t=r.create("label",{},{display:"flex",alignItems:"center",
gap:"6px",padding:"6px",border:"1px solid #eee",borderRadius:"6px"}),n=r.create("input",{type:"checkbox"});n.checked=g.has(e),n.onchange=()=>{
n.checked?g.add(e):g.delete(e)};const i=r.create("span");i.textContent=e,t.appendChild(n),t.appendChild(i),h.appendChild(t)}),d.appendChild(h)
;const u=c.createFooter(()=>o.remove(),()=>a(Array.from(g)));s.appendChild(l),s.appendChild(d),s.appendChild(u),o.appendChild(s),
document.body.appendChild(o)}}class SearchOptimizer{static init(){this.setupSearchFavorites()}static setupSearchFavorites(){
if(!/\/search\.php(\?|$)/.test(location.pathname+location.search))return;const e=r.select("#srchfid")
;e&&"SELECT"===e.tagName&&e.multiple&&(this.createSearchTools(e),this.setupTopGrouping(e),this.setupAutoRemember(e))}static createSearchTools(e){
const t=r.create("div",{},{margin:"6px 0",display:"flex",gap:"12px",alignItems:"center"}),n=r.create("button",{type:"button"},{height:"30px"})
;n.textContent="置顶设置",s.applyButtonStyle(n),n.addEventListener("click",t=>{t.preventDefault(),t.stopPropagation(),this.openSearchFavSettings(e)}),
s.ensureToggleStyles();const{switchWrap:i}=this.createToggleSwitch();t.appendChild(n),t.appendChild(i),e.parentNode?.insertBefore(t,e)}
static createToggleSwitch(){const e=r.create("label",{class:"sis-toggle"}),t=r.create("input",{type:"checkbox",class:"sis-input"})
;t.checked=Config.getSearchFavAuto();const n=r.create("span",{class:"sis-text"});n.textContent="多选记忆";const i=r.create("span",{class:"sis-switch"})
;return e.appendChild(t),e.appendChild(n),e.appendChild(i),t.addEventListener("change",()=>{if(Config.setSearchFavAuto(t.checked),t.checked){
const e=r.select("#srchfid");if(e){const t=Array.from(e.selectedOptions).map(e=>e.value).filter(Boolean);t.length>0&&Config.setSearchLastSelection(t)}
}}),{switchWrap:e,switchInput:t}}static setupTopGrouping(e){const t=Config.getSearchFavForums();if(0===t.length)return;const n=r.create("optgroup",{
label:"常用置顶"});e.insertBefore(n,e.firstChild);const options=Array.from(e.querySelectorAll("option"));t.forEach(e=>{
const t=options.find(t=>t.value===e);t&&n.appendChild(t)})}static setupAutoRemember(e){if(!Config.getSearchFavAuto())return
;const t=Config.getSearchLastSelection();t.length>0&&Array.from(e.options).forEach(e=>{e.selected=t.includes(e.value)}),
e.addEventListener("change",()=>{const t=Array.from(e.selectedOptions).map(e=>e.value).filter(Boolean);Config.setSearchLastSelection(t)})}
static openSearchFavSettings(e){
const t=Array.from(e.querySelectorAll("option")).filter(e=>e.value),n=c.createOverlay(),i=c.createPanel("1100px"),a=c.createHeader("置顶设置",()=>n.remove()),{body:r,favSet:o}=this.createPanelBody(e,t),s=c.createFooter(()=>n.remove(),()=>{
Config.setSearchFavForums(Array.from(o)),location.reload()});i.appendChild(a),i.appendChild(r),i.appendChild(s),n.appendChild(i),
document.body.appendChild(n)}static createPanelBody(e,t){const n=r.create("div",{},{padding:"12px 16px",display:"grid",
gridTemplateColumns:"repeat(auto-fit,minmax(260px,1fr))",gap:"12px"}),i=new Set(Config.getSearchFavForums())
;return this.organizeOptions(e,t).forEach(e=>{const t=this.createGroupCard(e,i);n.appendChild(t)}),{body:n,favSet:i}}static organizeOptions(e,t){
const n=[];Array.from(e.querySelectorAll("optgroup")).forEach(e=>{const options=Array.from(e.querySelectorAll("option")).filter(e=>e.value)
;options.length>0&&n.push({label:e.label||"分组",options:options})})
;const i=Array.from(e.children).filter(e=>"OPTION"===e.tagName&&e.value&&"all"!==e.value);return i.length>0&&n.unshift({label:"其他",options:i}),n}
static createGroupCard(e,t){const n=r.create("div",{},{border:"1px solid #e9ecef",borderRadius:"8px",overflow:"hidden",background:"#fff"
}),i=r.create("div",{},{padding:"8px 10px",background:"#f8f9fa",borderBottom:"1px solid #e9ecef",fontWeight:"600",color:"#2c3e50",fontSize:"12px"})
;i.textContent=e.label;const a=r.create("div",{},{padding:"8px 10px",display:"flex",flexDirection:"column",gap:"6px"});return e.options.forEach(e=>{
const n=r.create("label",{},{display:"flex",alignItems:"center",gap:"6px",padding:"6px",border:"1px solid #eee",borderRadius:"6px"
}),i=r.create("input",{type:"checkbox"});i.checked=t.has(e.value),i.onchange=()=>{i.checked?t.add(e.value):t.delete(e.value)};const o=r.create("span")
;o.textContent=e.textContent?.trim()||"",n.appendChild(i),n.appendChild(o),a.appendChild(n)}),n.appendChild(i),n.appendChild(a),n}}async function S(){
try{b(),AdRemover.init(),"loading"===document.readyState&&await l.waitForDOMContentLoaded(),p.init(),await l.waitForWindowLoad(),
await ImagePreview.init(),BoardManager.init(),SearchOptimizer.init(),setInterval(()=>{m.cleanup()},3e5)}catch(e){void 0}}function b(){
const e=document.querySelectorAll("a");for(let t=0;t<e.length;t++){const n=e[t];if(n.textContent&&n.textContent.includes("电脑版")){
window.location.href=n.href;break}}}S()})();