[{"articleStyle":3,"cacheFirst":false,"contentBlacklist":"","contentWhitelist":"","customOrder":-10106663,"enableJs":true,"enabled":true,"enabledCookieJar":true,"header":"{\"User-Agent\":\"Mozilla\/5.0 (Linux; Android 13) AppleWebKit\/537.36 (KHTML, like Gecko) Version\/4.0 Chrome\/120.0 Mobile Safari\/537.36\"}","injectJs":"(function(){function B(a){try{var t=Object.keys(window),e,n;for(e=0;e<t.length;e++){try{n=window[t[e]]}catch(i){continue}if(n&&typeof n==\"object\"&&a(n))return n}}catch(i){}return null}window.java||(window.java=B(function(a){return typeof a.ajaxAwait==\"function\"})),window.source||(window.source=B(function(a){return typeof a.getSource==\"function\"})),window.cache||(window.cache=B(function(a){return typeof a.get==\"function\"&&typeof a.put==\"function\"})),window.java&&(window.ajaxAwait||(window.ajaxAwait=function(a){return window.java.ajaxAwait(a)}),window.postAwait||(window.postAwait=function(a,t,e,n){return window.java.postAwait(a,t,e,n)}));try{with(window){window.AIDEFBASE=\"https:\/\/platform.aitools.cfd\/api\/v1\",window.AIFALLBACK=[[\"zhipu\/glm-4.7-flash\",\"GLM-4.7-Flash\"],[\"zhipu\/glm-4.6v-flash\",\"GLM-4.6V-Flash\"],[\"zhipu\/glm-4-flash\",\"GLM-4-Flash\"],[\"openai\/gpt-oss-20b\",\"GPT-OSS-20B\"],[\"google\/gemma-4-31b\",\"Gemma-4-31B\"]],window.AIKEYURL=\"https:\/\/platform.aitools.cfd\/api\/key\/generate\",window.AILMAX=60,window.CP_PRESET=[\"#FFFFFF\",\"#F1F2F7\",\"#E4E7F0\",\"#8A8FA8\",\"#5A5F73\",\"#2B2D42\",\"#000000\",\"#FF6B9D\",\"#E5484D\",\"#F2A33C\",\"#16A34A\",\"#22A7C2\",\"#7C6BD9\",\"#A855F7\",\"#FDF4DE\",\"#C3A875\"],window.DPROMS=[{n:\"深度翻译\",s:`你是精通双语的翻译与跨文化解读专家。\n请对选中的内容做「翻译 + 扩展解读」，严格按以下结构输出：\n\n## 一、译文\n给出自然、通顺、符合中文表达习惯的译文（若是中译英则给地道英文）。\n\n## 二、关键措辞\n挑出 3～6 个值得留意的词句，逐一说明：原意、你的译法、为什么这样译、还有哪些可选译法。\n\n## 三、背景与知识扩展\n补充与内容相关的背景知识、文化典故、专业术语或领域常识，帮助读者真正读懂。\n\n## 四、语言点赏析\n从语法、修辞、语气、风格等角度做简要赏析，指出原文的精妙或难点。\n\n要求：条理清晰、用小标题分段；信息密度高但不啰嗦；不确定之处明确标注，不要编造。`},{n:\"词语全景解读\",s:`你是网络文化与语言学研究者。\n请对选中的词句做「全景式解读」，严格按以下结构输出：\n\n## 一、基本释义\n字面含义、词性、读音\/写法变体。\n\n## 二、网络与口语含义\n在当前网络语境下的真实含义，与字面义的差异。\n\n## 三、来源与演变\n出处（梗\/事件\/平台）、传播路径、含义的流变过程。\n\n## 四、常见用法与搭配\n给出 4～8 个真实例句，覆盖不同语境。\n\n## 五、典型场景\n说明它常出现在哪些平台\/人群\/话题中（弹幕、评论区、贴吧、游戏、职场等）。\n\n## 六、感情色彩与避雷\n褒贬、亲疏、正式程度；哪些场合能用、哪些场合慎用或易冒犯。\n\n## 七、近义与对照\n列出 3～5 个近义表达并比较细微差别。\n\n要求：要点化、每条一行；不确定的来源标注\"待考\"，不要臆断。`},{n:\"润色与改写\",s:`你是资深文字编辑。\n请在【完全保留原意】的前提下优化选中的文字，按以下结构输出：\n\n## 一、润色稿\n直接给出优化后的成稿（这是主要输出，要能直接复制使用）。\n\n## 二、主要改动\n分条说明改了什么、为什么改（语病、啰嗦、逻辑、用词、节奏等）。\n\n## 三、风格备选\n再给 2 个不同风格的版本（如：简洁版 \/ 正式版 \/ 更有感染力版），并注明各自适用场景。\n\n## 四、提升建议\n指出原文最值得改进的一两个根本问题，给出可操作的写作建议。\n\n要求：只润色不篡改事实；不要无谓堆砌辞藻；保持作者原有语气除非明显不妥。`},{n:\"深度分析与思辨\",s:`你是跨学科的思考伙伴。\n请对选中的内容做有纵深的分析，严格按以下结构输出：\n\n## 一、核心观点\n用一两句话概括它真正在说什么。\n\n## 二、多层解读\n从不同角度拆解（至少 3 个角度：如逻辑层面、心理层面、社会\/历史层面、实用层面）。\n\n## 三、支撑与反驳\n它成立的前提是什么？有哪些有力的支持理由？又有哪些合理的质疑或反例？\n\n## 四、关联与延伸\n把它和更广阔的知识领域连起来（可涉历史、经济、心理、科学、哲学、艺术等），打开视野。\n\n## 五、启发与行动\n读者能从中带走什么？给出 2～3 条可落地的启发或行动建议。\n\n## 六、反过来想\n如果站在完全相反的立场，会怎么看？\n\n要求：观点明确、论据具体；区分\"事实\"与\"推测\"；不要和稀泥，也不要武断。`},{n:\"续写与创作\",s:`你是小说创作者。\n请接着选中的内容往下写，严格按以下要求：\n\n## 一、续写正文\n直接接着写，保持原有文风、人称、叙事节奏与世界观；长度适中，有推进不要原地打转。\n\n## 二、创作说明\n简要说明你为什么这样接（埋了什么伏笔、想营造什么情绪、后续可能走向）。\n\n## 三、可选分支\n再给 2 个不同走向的开头片段（如：温情向 \/ 悬疑向 \/ 冲突向），供作者选择。\n\n要求：不重复原文；人物行为符合已展现的性格；结尾留有余味，不要把所有话说尽。`},{n:\"一键优化提示词\",s:`你是提示词工程专家，擅长把粗糙的想法打磨成高质量的系统提示词。\n用户接下来给你的，是他准备拿去当提示词的一段文字。请你【不要回答这段文字本身的内容】，而是把它【扩展、改写、优化成一条成熟的提示词】。\n\n优化时按以下方向发力（突出一个\"多\"）：\n1. 角色更专业：为它设定一个最合适的专家身份，并点明该身份的知识范围与判断标准。\n2. 任务更多维：不只做一件事，而是拆成若干互相补充的维度（释义\/分析\/举例\/对比\/延伸\/启发等）。\n3. 结构更清晰：用小标题或编号规定输出结构，让回答层次分明、便于扫读。\n4. 知识更广：主动要求它调动跨领域知识（历史、社会、心理、科学、文化、实用场景等）。\n5. 深度更足：要求给出理由、依据、前提、反例与边界，而不是只给结论。\n6. 更有启发：要求补充别人容易忽略的角度、可迁移的方法、可落地的建议。\n7. 排版更好：明确要求分段、要点化、适当留白，必要时用表格。\n8. 约束更明确：说明长度、语气、禁止编造、不确定要标注等。\n\n请直接输出优化后的提示词全文（不要解释你的优化思路，不要加前后缀），要求可直接复制使用。`}],window.KAIL=\"x8t_ailog\",window.KCFG=\"x8t_aicfg\",window.KCIDX=\"x8t_aicfgidx\",window.KEN=\"x8t_aien\",window.KMODE=\"x8t_aimode\",window.KPOOL=\"x8t_aipool\",window.KPRO=\"x8t_aipro\",window.KRR=\"x8t_airr\",window.KTO=\"x8t_aito\",window._Z={},window._aiBtn=null,window._aiBusy=0,window._aiDrag=null,window._aiQ=\"\",window._aiRaw=\"\",window._aiSysTmp=\"\",window._aiT=0,window._aiTimer=0,window._aiSel=[],window.aiAddCfg=function(){var t=aiCfgs();t.push({n:\"新配置\",base:AIDEFBASE,key:\"\",model:AIFALLBACK[0][0],sys:\"\",auto:1}),aiSaveCfgs(t),aiSetIdx(t.length-1),aiEcho(),tip(\"✔ 已新建，填密钥即可用\",\"ok\")},window.aiAddPro=function(){var t=document.getElementById(\"aisys\"),e=t?String(t.value||\"\").trim():\"\";if(!e){tip(\"✘ 提示词是空的\",\"no\");return}var n=prompt(\"给这个提示词起个名字\",\"我的提示词\");if(n!==null){var i=aiPro();i.push({n:String(n||\"\").trim()||\"我的提示词\",s:e}),aiSavePro(i),aiEcho(),tip(\"✔ 已保存提示词\",\"ok\")}},window.aiAsk=function(t){if(t=String(t||\"\").trim(),!!t){var e=document.getElementById(\"aim\");e||(e=document.createElement(\"div\"),e.id=\"aim\",e.className=\"modal\",e.innerHTML='<div class=\"mbox\"><div class=\"phd\"><h3>✨ 问 AI<\/h3><button class=\"x\" type=\"button\" onclick=\"aiClose()\">✕<\/button><\/div><div id=\"aiedit\"><div class=\"aifold\"><button class=\"bt\" id=\"aifoldbtn\" type=\"button\" onclick=\"aiFoldToggle()\">⚙ 收起设置<\/button><\/div><div class=\"aifold-body\" id=\"aifoldbody\"><div class=\"srow\"><label>提供商<\/label><select id=\"aicfg2\" onchange=\"aiPickAskCfg(this.value)\"><\/select><button class=\"bt\" type=\"button\" style=\"flex:none;min-width:52px\" onclick=\"aiPullIntoPool(aiIdx())\">拉取<\/button><\/div><div class=\"srow\"><label>调用模式<\/label><select id=\"aimode2\" onchange=\"aiSetMode(this.value)\"><option value=\"single\">单一模型（只用 1 号）<\/option><option value=\"rr\">轮流调用<\/option><option value=\"cc\">并发调用<\/option><\/select><\/div><div class=\"srow\"><label>轮流数量<\/label><input type=\"number\" id=\"airrn2\" min=\"1\" max=\"20\" style=\"flex:none;width:64px\" onchange=\"aiSetRR(this.value)\"><label style=\"width:auto;flex:none\">超时(秒)<\/label><input type=\"number\" id=\"aito2\" min=\"5\" max=\"300\" style=\"flex:none;width:64px\" onchange=\"aiSetTO(this.value)\"><\/div><div class=\"aihint\">可在外观设置界面的问ai设置里，改变模型密钥和新增自定义模型。<\/div><\/div><div class=\"mlist\" id=\"aimlist\"><\/div><div class=\"mlist-btns\" id=\"aimlistbtns\"><\/div><div class=\"srow\"><label>提示词模板<\/label><select id=\"aipro2\" onchange=\"aiPickAskPro(this.value)\"><\/select><\/div><div class=\"prow\"><textarea id=\"aisys2\" rows=\"3\" placeholder=\"临时提示词：只对这一次生效，留空则用模板\/默认\"><\/textarea><button class=\"bt\" type=\"button\" title=\"保存为提示词模板\" onclick=\"aiSaveTmpPro()\">存为模板<\/button><button class=\"bt warn\" type=\"button\" title=\"删除当前选中的模板\" onclick=\"aiDelAskPro()\">删模板<\/button><\/div><div class=\"aihint ck\" onclick=\"aiHintT(this)\">📌 免费模型怎么配置更稳？（点开）<div class=\"ckb\" style=\"display:none;font-size:12px\">为了减少免费模型的延迟高出错率高的问题，可在外观设置按钮打开ai问答设置，点新建，再点击申请免费密钥（来自站点<b>https:\/\/platform.aitools.cfd\/<\/b>）简单命个序号名，然后就会自动保存新配置。<br>同一IP过一个小时又能申请一个免费密钥，WIFI和移动数据IP是不同的，所以一个小时能申请2个免费密钥。回到问ai面板，选新配置，点击拉取，选择一个就够了，因为一个key每3-5秒只能请求1次，再选新申请密钥的配置，又拉取一个，循环。然后你就能有足够多并发模式可用的免费模型了，然后并发模式下哪个请求快就显示哪个结果。<br>为了更好的体验，还是建议去智谱、硅基流动、agens等平台，都有免费版模型，登录注册一个apikey，在外观设置按钮中ai问答设置里添加新配置填入正确的baseurl和key即可，不会注册和填写就问豆包元宝ds<\/div><\/div><textarea id=\"aiq\" rows=\"6\" placeholder=\"要发送给 AI 的文字（可编辑）\"><\/textarea><div class=\"row\"><button class=\"bt pri\" style=\"flex:1\" onclick=\"aiSend()\">✨ 问一下<\/button><button class=\"bt\" style=\"flex:none;min-width:72px\" onclick=\"aiClose()\">取消<\/button><\/div><div class=\"row\"><button class=\"bt\" style=\"flex:1\" onclick=\"aiTest()\">⚡ 一键测试<\/button><button class=\"bt\" style=\"flex:none;min-width:56px\" onclick=\"aiTestClear()\">清除<\/button><button class=\"bt\" style=\"flex:none;min-width:56px\" onclick=\"aiViewLog()\">日志<\/button><\/div><pre class=\"aitest\" id=\"aitest\" style=\"display:none\"><\/pre><\/div><div id=\"aians\" style=\"display:none\"><div class=\"aiq\" id=\"aiqq\"><\/div><div class=\"aia\" id=\"aia\"><\/div><div class=\"aipick\" id=\"aipickwrap\" style=\"display:none\"><label>答案来源<\/label><select id=\"aipick\" onchange=\"aiConcPick(this.value)\"><option value=\"\">（暂无并发缓存）<\/option><\/select><\/div><div class=\"row\"><button class=\"bt\" onclick=\"aiBackEdit()\">改一下<\/button><button class=\"bt\" onclick=\"aiCopy()\">复制<\/button><button class=\"bt\" onclick=\"aiSend()\">重试<\/button><button class=\"bt pri\" onclick=\"aiClose()\">关闭<\/button><\/div><\/div><\/div>',document.body.appendChild(e)),e.className=\"modal on\",aiEchoAsk();var n=document.getElementById(\"aiq\");n&&(n.value=t),aiBackEdit()}},window.aiAskFetchModels=function(){aiModels(function(t){if(!(!t||!t.length)){var e=document.getElementById(\"aimpick2\");if(e){var n=\"\",i;for(i=0;i<t.length;i++)n+='<option value=\"'+esc(t[i][0])+'\">'+esc(t[i][1])+\"<\/option>\";e.innerHTML=n,tip(\"✔ 拉到 \"+t.length+\" 个模型，可在下拉里选\",\"ok\")}}})},window.aiBackEdit=function(){var t=document.getElementById(\"aiedit\"),e=document.getElementById(\"aians\");t&&(t.style.display=\"\"),e&&(e.style.display=\"none\")},window.aiBase=function(){var t=aiCfg();return String(t&&t.base||AIDEFBASE).replace(\/[\/]+$\/,\"\")},window.aiCall=function a(t,e,n,i,o){var r={method:\"POST\",headers:{\"Content-Type\":\"application\/json\",Authorization:\"Bearer \"+t.key},body:JSON.stringify({model:t.model,messages:e})},s=\"\";try{e&&e[0]&&e[0].role===\"system\"&&(s=e[0].content)}catch(c){}function d(c,u,l){try{aiLog({kind:\"问AI\",ok:!!c,model:t.model,sys:s,q:i,a:l||\"\",err:u||\"\",ms:_aiT0?new Date().getTime()-_aiT0:0})}catch(f){}}fetch(aiBase()+\"\/chat\/completions\",r).then(function(c){if((c.status===401||c.status===403)&&aiIsFree()&&t.auto!==0&&o<1)return n.className=\"aia wait\",n.textContent=\"密钥失效，正在自动申请新密钥…\",aiNewKey().then(function(l){if(!l)return n.className=\"aia err\",n.textContent=\"密钥失效，自动申请也没成功（每小时限 1 个），请稍后重试或手动填密钥。\",_aiBusy=0,d(!1,\"密钥失效且自动申请失败\"),null;var f=aiCfgs(),m=aiIdx();f[m]&&(f[m].key=l,aiSaveCfgs(f));var g=document.getElementById(\"aikey\");return g&&(g.value=l),t.key=l,tip(\"✔ 已自动换新密钥\",\"ok\"),a(t,e,n,i,o+1)});if(c.status===401||c.status===403)return _aiBusy=0,d(!1,\"HTTP \"+c.status+\" 密钥无效\"),n.className=\"aia err\",n.textContent=\"密钥无效（401），请重填或开启自动续期。\",null;if(c.status===429){var u=3;try{u=parseInt(c.headers.get(\"Retry-After\")||\"3\",10)||3}catch(l){}return _aiBusy=0,d(!1,\"HTTP 429 请求太频繁\"),n.className=\"aia err\",n.textContent=\"请求太频繁（每密钥 3 秒 1 次），请 \"+u+\" 秒后重试。\",null}return c.ok?c.text():(_aiBusy=0,d(!1,\"HTTP \"+c.status),n.className=\"aia err\",n.textContent=\"请求失败：HTTP \"+c.status,null)}).then(function(c){if(!(c===null||c===undefined)){_aiBusy=0;var u=\"\";try{var l=JSON.parse(c);u=((((l||{}).choices||[])[0]||{}).message||{}).content||\"\"}catch(f){u=\"\"}if(!u){d(!1,\"空回答: \"+String(c||\"\").slice(0,60)),n.className=\"aia err\",n.textContent=\"没拿到回答：\"+String(c||\"\").slice(0,200);return}_aiRaw=u,n.className=\"aia\",aiType(n,aiMd(u)),d(!0,\"\",u)}}).catch(function(c){_aiBusy=0,d(!1,String(c&&c.message?c.message:c)),n.className=\"aia err\",n.textContent=\"请求出错：\"+(c&&c.message?c.message:c)})},window.aiCfg=function(){var t=aiCfgs(),e=aiIdx();return t[e]||t[0]},window.aiCfgs=function(){var t=null;try{t=jload(KCFG,null)}catch(e){}return(!t||typeof t.length!=\"number\"||!t.length)&&(t=[{n:\"免费站\",base:AIDEFBASE,key:\"\",model:AIFALLBACK[0][0],sys:\"\",auto:1}]),t},window.aiClearLog=function(){try{jsave(KAIL,[])}catch(t){}tip(\"✔ 日志已清空\",\"ok\")},window.aiClose=function(){var t=document.getElementById(\"aim\");t&&(t.className=\"modal\")},window.aiCopy=function(){if(!_aiRaw){tip(\"✘ 还没有内容\",\"no\");return}try{if(window.java&&window.java.setClipboard){window.java.setClipboard(_aiRaw),tip(\"✔ 已复制\",\"ok\");return}}catch(t){}tip(\"✘ 复制失败，请长按选择文字\",\"no\")},window.aiDelCfg=function(){var t=aiCfgs(),e=aiIdx();if(t.length<=1){tip(\"✘ 至少保留一套配置\",\"no\");return}confirm(\"删除当前配置「\"+(t[e].n||\"\")+\"」？\")&&(t.splice(e,1),aiSaveCfgs(t),aiSetIdx(Math.max(0,e-1)),aiEcho(),tip(\"✔ 已删除\",\"ok\"))},window.aiDelPro=function(){var t=document.getElementById(\"aipro\"),e=t?parseInt(t.value,10):-1,n=aiPro();if(e<0||!n[e]){tip(\"✘ 先在下拉里选一条\",\"no\");return}confirm(\"删除提示词「\"+(n[e].n||\"\")+\"」？\")&&(n.splice(e,1),aiSavePro(n),aiEcho(),tip(\"✔ 已删除\",\"ok\"))},window.aiDupCfg=function(){var t=aiCfgs(),e=aiIdx();if(t[e]){var n={};for(var i in t[e])n[i]=t[e][i];n.n=(t[e].n||\"\")+\" 副本\",t.push(n),aiSaveCfgs(t),aiSetIdx(t.length-1),aiEcho(),tip(\"✔ 已复制\",\"ok\")}},window.aiEcho=function(){var t=aiCfg(),e,n=document.getElementById(\"aicfg\");n&&(n.innerHTML=aiOptsCfgs(),n.value=String(aiIdx()));var i=document.getElementById(\"ainame\");i&&(i.value=t.n||\"\");var o=document.getElementById(\"aibase\");o&&(o.value=t.base||\"\");var r=document.getElementById(\"aikey\");r&&(r.value=t.key||\"\");var s=document.getElementById(\"aimodel\");s&&(s.value=t.model||\"\");var d=document.getElementById(\"aisys\");d&&(d.value=t.sys||\"\");var c=document.getElementById(\"aimpick\");if(c&&!c.innerHTML){var u=\"\";for(e=0;e<AIFALLBACK.length;e++)u+='<option value=\"'+esc(AIFALLBACK[e][0])+'\">'+esc(AIFALLBACK[e][1])+\"<\/option>\";c.innerHTML=u}c&&t.model&&(c.value=t.model);var l=document.getElementById(\"aipro\");if(l){l.innerHTML=aiOptsPro();var f=aiPro();for(e=0;e<f.length;e++)if(f[e].s===(t.sys||\"\")){l.value=String(e);break}}var m=document.getElementById(\"ai0\");m&&(m.className=\"msw\"+(ST.aiOn?\"\":\" on\"));var g=document.getElementById(\"ai1\");g&&(g.className=\"msw\"+(ST.aiOn?\" on\":\"\"));var h=document.getElementById(\"aiauto0\");h&&(h.className=\"msw\"+(t.auto===0?\" on\":\"\"));var w=document.getElementById(\"aiauto1\");w&&(w.className=\"msw\"+(t.auto!==0?\" on\":\"\"))};var KAIL=\"x8t_ailog\",AILMAX=60;window.aiEchoAsk=function(){var t=aiCfg(),e,n;if(e=document.getElementById(\"aicfg2\"),e&&(e.innerHTML=aiOptsCfgs(),e.value=String(aiIdx())))e=document.getElementById(\"aipro2\"),e&&(e.innerHTML=aiOptsPro()),e=document.getElementById(\"aisys2\"),e&&(e.value=t.sys||\"\"),aiRenderModels(),e=document.getElementById(\"aimode2\"),e&&(e.value=aiMode()),e=document.getElementById(\"airrn2\"),e&&(e.value=String(aiRRN())),e=document.getElementById(\"aito2\"),e&&(e.value=String(Math.round(aiTimeout()\/1e3))),aiSyncModeUI()},window.aiEn=function(){var t=[];try{t=jload(KEN,null)}catch(e){}return t&&typeof t.length==\"number\"?t:[]},window.aiEnList=function(){var t=aiPool(),e=aiEn(),n=[],i,o;for(i=0;i<e.length;i++)for(o=0;o<t.length;o++)if(aiKeyOf(t[o])===e[i]){n.push(t[o]);break}return n},window.aiFetchModels=function(){aiModels(function(t){if(!(!t||!t.length)){var e=document.getElementById(\"aimpick\");if(e){var n=\"\",i;for(i=0;i<t.length;i++)n+='<option value=\"'+esc(t[i][0])+'\">'+esc(t[i][1])+\"<\/option>\";e.innerHTML=n}}})},window.aiGenKey=function(){tip(\"… 正在申请\"),aiNewKey().then(function(t){if(!t){tip(\"✘ 申请失败（该站每小时限 1 个），可稍后再试或手动填\",\"no\");return}aiSet(\"key\",t),tip(\"✔ 新密钥已填入\",\"ok\")})},window.aiIdx=function(){var t=0;try{t=parseInt(load(KCIDX)||\"0\",10)||0}catch(n){}var e=aiCfgs();return t<0&&(t=0),t>=e.length&&(t=e.length-1),t},window.aiInitBtn=function(){_aiBtn||(_aiBtn=document.createElement(\"button\"),_aiBtn.type=\"button\",_aiBtn.className=\"aisel\",_aiBtn.innerHTML=\"✨ 问 AI\",_aiBtn.onclick=function(t){killEv(t);var e=aiSelText();e&&aiAsk(e)},_aiBtn.style.display=\"none\",_aiBtn.style.position=\"fixed\",_aiBtn.style.zIndex=\"2147483647\",document.body.appendChild(_aiBtn),document.addEventListener(\"selectionchange\",function(){try{clearTimeout(_aiT)}catch(t){}_aiT=setTimeout(aiShowBtn,260)},!1))},window.aiIsFree=function(){return aiBase().indexOf(\"aitools.cfd\")>=0},window.aiKeyOf=function(t){return t.cfg+\"|\"+t.id},window.aiLog=function(t){try{t.t=new Date().getTime(),t.ts=aiTs(t.t);var e=[];try{e=jload(KAIL,null)}catch(n){}for((!e||typeof e.length!=\"number\")&&(e=[]),e.push(t);e.length>AILMAX;)e.shift();jsave(KAIL,e)}catch(n){}try{java.log(\"[AI] \"+String(t.kind||\"\")+\" \"+String(t.ok?\"OK\":\"FAIL\")+\" \"+String(t.msg||\"\"))}catch(n){}},window.aiLogText=function(){var t=[];try{t=jload(KAIL,null)}catch(r){}if(!t||!t.length)return\"（暂无日志）\";var e=[],n;for(n=t.length-1;n>=0;n--){var i=t[n],o=\"[\"+String(i.ts||\"\")+\"] \"+String(i.kind||\"\");i.kind===\"问AI\"?(o+=\" #\"+String(i.no||1)+\" | \"+String(i.pn||\"\")+\" \/ \"+String(i.model||\"\")+\" | \"+(i.ms||0)+\"ms | \"+(i.ok?\"成功\":\"失败 \"+String(i.err||\"\")),i.sys&&(o+=`\n  提示词: `+String(i.sys).slice(0,80)),o+=`\n  发送: `+String(i.q||\"\").slice(0,120),o+=`\n  返回: `+String(i.a||\"\").slice(0,200)):i.kind===\"测试\"&&(o+=\" | \"+String(i.name||\"\")+\" | 延迟 \"+(i.ms||0)+\"ms | \"+(i.ok?\"成功\":\"失败 \"+String(i.err||\"\")),i.a&&(o+=`\n  返回: `+String(i.a).slice(0,80))),e.push(o)}return e.join(`\n`)},window.aiMd=function(t){return t=String(t||\"\"),t=t.replace(\/&\/g,\"&amp;\").replace(\/<\/g,\"&lt;\").replace(\/>\/g,\"&gt;\"),t=t.replace(\/```[\\w]*\\n?([\\s\\S]*?)```\/g,function(e,n){return\"<pre><code>\"+n.replace(\/\\n$\/,\"\")+\"<\/code><\/pre>\"}),t=t.replace(\/`([^`\\n]+)`\/g,\"<code>$1<\/code>\"),t=t.replace(\/\\*\\*([^*\\n]+)\\*\\*\/g,\"<b>$1<\/b>\"),t=t.replace(\/^###[ \\t]+(.*)$\/gm,\"<h4>$1<\/h4>\"),t=t.replace(\/^##[ \\t]+(.*)$\/gm,\"<h3>$1<\/h3>\"),t=t.replace(\/^[-*][ \\t]+(.*)$\/gm,\"<li>$1<\/li>\"),t=t.replace(\/\\n\/g,\"<br>\"),t},window.aiMode=function(){var t=\"single\";try{t=String(load(KMODE)||\"single\")}catch(e){}return t===\"rr\"?\"rr\":(t===\"cc\"?\"cc\":\"single\")},window.aiModels=function(t){var e=aiCfg().key||\"\";if(!e){tip(\"✘ 先填 API 密钥再拉模型\",\"no\"),t&&t(null);return}fetch(aiBase()+\"\/models\",{headers:{Authorization:\"Bearer \"+e}}).then(function(n){return n.ok?n.text():null}).then(function(n){if(!n){tip(\"✘ 拉取失败, 请检查 Base URL 与密钥\",\"no\"),t&&t(null);return}var i=[];try{var o=JSON.parse(n);i=o&&o.data||[]}catch(c){i=[]}if(!i.length){tip(\"✘ 没拉到模型, 可手动填模型 ID\",\"no\"),t&&t(null);return}var r=[],s;for(s=0;s<i.length;s++){var d=i[s]&&i[s].id;d&&r.push([d,d])}if(!r.length){t&&t(null);return}tip(\"✔ 拉到 \"+r.length+\" 个模型\",\"ok\"),t&&t(r)}).catch(function(n){tip(\"✘ 拉取出错: \"+(n&&n.message?n.message:n),\"no\"),t&&t(null)})},window.aiNewKey=function(){return fetch(AIKEYURL,{method:\"POST\",headers:{\"Content-Type\":\"application\/json\"},body:\"{}\"}).then(function(t){return t.ok?t.text():null}).then(function(t){if(!t)return\"\";try{var e=JSON.parse(t);return e&&e.key?String(e.key):\"\"}catch(n){return\"\"}}).catch(function(){return\"\"})},window.aiOnce=function(t,e,n,i,o){return new Promise(function(r){var s=!1,d=new Date().getTime(),c=setTimeout(function(){s||(s=!0,r({ok:!1,err:\"超时 \"+Math.round(o\/1e3)+\" 秒\",ms:o}))},o),u={method:\"POST\",headers:{\"Content-Type\":\"application\/json\",Authorization:\"Bearer \"+e},body:JSON.stringify({model:n,messages:i})};fetch(t+\"\/chat\/completions\",u).then(function(l){if(!s){s=!0,clearTimeout(c);var f=new Date().getTime()-d;if(!l.ok){var m=\"HTTP \"+l.status;return l.status===429&&(m=\"HTTP 429 请求太频繁(每密钥3秒1次)\"),(l.status===401||l.status===403)&&(m=\"HTTP \"+l.status+\" 密钥无效\"),r({ok:!1,err:m,ms:f})}return l.text().then(function(g){var h=\"\";try{var w=JSON.parse(g);h=((((w||{}).choices||[])[0]||{}).message||{}).content||\"\"}catch(v){}if(!h)return r({ok:!1,err:\"空回答: \"+String(g||\"\").slice(0,60),ms:f});r({ok:!0,ans:h,ms:f})})}}).catch(function(l){s||(s=!0,clearTimeout(c),r({ok:!1,err:String(l&&l.message?l.message:l),ms:new Date().getTime()-d}))})})},window.aiOptsCfgs=function(){var t=aiCfgs(),e=\"\",n;for(n=0;n<t.length;n++)e+='<option value=\"'+n+'\">'+esc(t[n].n||\"配置\"+(n+1))+\"<\/option>\";return e},window.aiOptsPro=function(){var t=aiPro(),e='<option value=\"-1\">（不用提示词）<\/option>',n;for(n=0;n<t.length;n++)e+='<option value=\"'+n+'\">'+esc(t[n].n||\"提示词\"+(n+1))+\"<\/option>\";return e},window.aiPickAskCfg=function(t){aiSetIdx(parseInt(t,10)||0);var e=aiCfg(),n;n=document.getElementById(\"aisys2\"),n&&(n.value=e.sys||\"\")},window.aiPickAskPro=function(t){var e=parseInt(t,10),n=document.getElementById(\"aisys2\");if(e<0){n&&(n.value=\"\");return}var i=aiPro();i[e]&&n&&(n.value=i[e].s||\"\")},window.aiPickCfg=function(t){var e=parseInt(t,10)||0;aiSetIdx(e),aiEcho()},window.aiPickPro=function(t){var e=parseInt(t,10),n=aiPro();e<0||!n[e]||(aiSet(\"sys\",n[e].s),tip(\"✔ 已套用「\"+(n[e].n||\"\")+\"」\",\"ok\"))},window.aiPool=function(){var t=[];try{t=jload(KPOOL,null)}catch(e){}return t&&typeof t.length==\"number\"?t:[]},window.aiPro=function(){var t=null;try{t=jload(KPRO,null)}catch(e){}return(!t||typeof t.length!=\"number\"||!t.length)&&(t=DPROMS.slice(0)),t},window.aiPullIntoPool=function(t,e){var n=aiCfgs(),i=n[t];if(!i){e&&e(0);return}if(!i.key){tip(\"✘ 该提供商还没填密钥\",\"no\"),e&&e(0);return}var o=String(i.base||AIDEFBASE).replace(\/[\/]+$\/,\"\");fetch(o+\"\/models\",{headers:{Authorization:\"Bearer \"+i.key}}).then(function(r){return r.ok?r.text():null}).then(function(r){var s=[];try{s=JSON.parse(r||\"{}\").data||[]}catch(g){s=[]}var d=aiPool(),avail=[],u,l;for(u=0;u<s.length;u++){var f=s[u]&&s[u].id;if(f){var m=!1;for(l=0;l<d.length;l++)if(d[l].cfg===t&&d[l].id===f){m=!0;break}if(!m)avail.push(f)}}if(!avail.length){tip(\"没有新模型（都已添加）\",\"ok\"),e&&e(0);return}aiShowPicker(avail,function(sel){if(!sel||!sel.length){e&&e(0);return}var pp=aiPool(),c=0,k;for(k=0;k<sel.length;k++){var fid=sel[k],ex=!1;for(l=0;l<pp.length;l++)if(pp[l].cfg===t&&pp[l].id===fid){ex=!0;break}if(!ex)pp.push({cfg:t,id:fid,pn:i.n||\"配置\"+(t+1),mn:fid}),c++}c&&aiSavePool(pp),aiRenderModels(),tip(c?\"✔ 新增 \"+c+\" 个模型\":\"没有新模型\",\"ok\"),e&&e(c)})}).catch(function(r){tip(\"✘ 拉取失败: \"+(r&&r.message?r.message:r),\"no\"),e&&e(0)})},window.aiRRN=function(){var t=2;try{t=parseInt(load(KRR)||\"2\",10)||2}catch(e){t=2}return t<1&&(t=1),t>20&&(t=20),t},window.aiRenderModels=function(){var t=document.getElementById(\"aimlist\"),b=document.getElementById(\"aimlistbtns\");if(t){var e=aiPool(),n=aiEn(),i,o,r=[],s={};for(i=0;i<n.length;i++)for(o=0;o<e.length;o++)if(aiKeyOf(e[o])===n[i]){r.push(o),s[o]=1;break}for(o=0;o<e.length;o++)s[o]||r.push(o);var bt='<div class=\"mlist-btns\"><button class=\"bt\" type=\"button\" onclick=\"aiMoveUp()\">▲ 上移<\/button><button class=\"bt\" type=\"button\" onclick=\"aiMoveDown()\">▼ 下移<\/button><button class=\"bt\" type=\"button\" onclick=\"aiDel()\">✕ 删除<\/button><\/div>';if(!r.length){t.innerHTML='<div class=\"aihint\">还没有模型。选好提供商后点上面的「拉取」。<\/div>';if(b)b.innerHTML=bt;return}var d=0,c=\"\";for(i=0;i<r.length;i++){var u=r[i],l=e[u],f=n.indexOf(aiKeyOf(l))>=0;f&&d++;var sel=_aiSel.indexOf(u)>=0?\" selected\":\"\";c+='<div class=\"mrow'+(f?\" on\":\"\")+sel+'\" data-pi=\"'+u+'\" onclick=\"aiSelToggle('+u+')\"><span class=\"mno\">'+(f?d:\"·\")+'<\/span><input type=\"checkbox\"'+(f?\" checked\":\"\")+' onclick=\"event.stopPropagation()\" onchange=\"aiToggleEn('+u+')\"><span class=\"mname\">'+esc(l.pn)+\" \/ \"+esc(l.mn)+'<\/span><\/div>'}t.innerHTML=c;if(b)b.innerHTML=bt}};window.aiRetry=function(){aiSend()},window.aiRun=function(t,e){if(_aiBusy){tip(\"… 正在请求中\");return}var n=document.getElementById(\"aia\");if(n){n.className=\"aia wait\",n.textContent=\"思考中…\",_aiRaw=\"\";var i=aiEnList();if(!i.length){n.className=\"aia err\",n.textContent=\"没有启用的模型。请在模型列表里勾选，或先点「拉取」把模型加进来。\";return}var o=aiMode(),r=o===\"rr\"?Math.min(aiRRN(),i.length):1,s=typeof e==\"string\"?String(e).trim():\"\";_aiBusy=1;if(o===\"cc\"){aiRunConc(t,s,i,Math.min(aiRRN(),i.length),n);return}aiRunSeq(t,s,i,0,r,n)}},\nwindow._aiConcC=[];window._aiConcCur=\"\";window.buildConcPick=function(){var p=document.getElementById(\"aipick\"),w=document.getElementById(\"aipickwrap\");if(!p)return;if(_aiConcC.length<2){p.style.display=\"none\";if(w)w.style.display=\"none\";return}p.innerHTML=\"\";for(var i=0;i<_aiConcC.length;i++){var o=document.createElement(\"option\");var lab=_aiConcC[i].pn+\" \/ \"+_aiConcC[i].mn;o.value=String(i);o.textContent=lab;if(lab===_aiConcCur)o.selected=true;p.appendChild(o)}p.style.display=\"\";if(w)w.style.display=\"\"},window.aiConcPick=function(i){var idx=parseInt(i,10);if(isNaN(idx)||idx<0||idx>=_aiConcC.length)return;var c=_aiConcC[idx];_aiConcCur=c.pn+\" \/ \"+c.mn;_aiRaw=c.ans;var r=document.getElementById(\"aia\");if(r){r.className=\"aia\";r.textContent=aiMd(c.ans)}buildConcPick()},window.aiRunConc=function(t,e,list,n,r){var fired=Math.min(n,list.length);_aiConcC=[];_aiConcCur=\"\";var pick=document.getElementById(\"aipick\"),wr=document.getElementById(\"aipickwrap\");if(pick){pick.style.display=\"none\";pick.innerHTML=\"\"}if(wr)wr.style.display=\"none\";r.className=\"aia wait\";r.textContent=\"并发请求 \"+fired+\" 个模型（\"+list[0].pn+\" \/ \"+list[0].mn+\" 等）…\";var done=0,shown=false,cfgs=aiCfgs();if(!cfgs||typeof cfgs.length!==\"number\")cfgs=[cfgs];var fire=function(idx){var mod=list[idx],d=cfgs[mod.cfg]||cfgs[0]||{},u=String(d.base||AIDEFBASE).replace(\/[\/]+$\/,\"\"),msgs=[];e&&msgs.push({role:\"system\",content:e});msgs.push({role:\"user\",content:t});aiOnce(u,d.key,mod.id,msgs,aiTimeout()).then(function(f){aiLog({kind:\"问AI\",ok:f.ok,no:idx+1,pn:mod.pn,model:mod.mn,sys:e,q:t,a:f.ans||\"\",err:f.err||\"\",ms:f.ms||0});done++;if(f.ok){_aiConcC.push({pn:mod.pn,mn:mod.mn,ans:f.ans});if(!shown){shown=true;_aiBusy=0;_aiConcCur=mod.pn+\" \/ \"+mod.mn;_aiRaw=f.ans;r.className=\"aia\";aiType(r,aiMd(f.ans));tip(\"✔ 最快：\"+mod.pn+\" \/ \"+mod.mn+\" 已返回\",\"ok\")}buildConcPick()}if(done>=fired&&!shown){_aiBusy=0;r.className=\"aia err\";r.textContent=\"全部 \"+fired+\" 个模型请求都失败了。\"}}) };for(var k=0;k<fired;k++){fire(k)}},window.aiRunSeq=function a(t,e,n,i,o,r){if(i>=o||i>=n.length){_aiBusy=0,r.className=\"aia err\",r.textContent=\"已尝试 \"+Math.min(i,o)+\" 个模型，都失败了。\";return}var s=n[i],d=aiCfgs(),c=d[s.cfg]||d[0]||{},u=String(c.base||AIDEFBASE).replace(\/[\/]+$\/,\"\"),l=[];e&&l.push({role:\"system\",content:e}),l.push({role:\"user\",content:t}),r.className=\"aia wait\",r.textContent=\"[\"+(i+1)+\"\/\"+o+\"] \"+s.pn+\" \/ \"+s.mn+\" 请求中…\",aiOnce(u,c.key,s.id,l,aiTimeout()).then(function(f){if(aiLog({kind:\"问AI\",ok:f.ok,no:i+1,pn:s.pn,model:s.mn,sys:e,q:t,a:f.ans||\"\",err:f.err||\"\",ms:f.ms||0}),f.ok){_aiBusy=0,_aiRaw=f.ans,r.className=\"aia\",aiType(r,aiMd(f.ans)),i>0&&tip(\"✔ 1 号失败，已由序号 \"+(i+1)+\"（\"+s.mn+\"）返回\",\"ok\");return}a(t,e,n,i+1,o,r)})},window.aiSaveCfgs=function(t){try{jsave(KCFG,t)}catch(e){}},window.aiSaveEn=function(t){try{jsave(KEN,t)}catch(e){}},window.aiSavePool=function(t){try{jsave(KPOOL,t)}catch(e){}},window.aiSavePro=function(t){try{jsave(KPRO,t)}catch(e){}},window.aiSaveTmpPro=function(){var t=document.getElementById(\"aisys2\"),e=t?String(t.value||\"\").trim():\"\";if(!e){tip(\"✘ 提示词是空的\",\"no\");return}var n=prompt(\"给这个提示词起个名字\",\"我的提示词\");if(n!==null){var i=aiPro();i.push({n:String(n||\"\").trim()||\"我的提示词\",s:e}),aiSavePro(i),aiEchoAsk();var o=document.getElementById(\"aipro2\");o&&(o.value=String(i.length-1)),tip(\"✔ 已保存为提示词模板\",\"ok\")}},window.aiSelText=function(){try{var t=window.getSelection();return t?String(t.toString()||\"\").trim():\"\"}catch(e){return\"\"}},window.aiSend=function(){var t=document.getElementById(\"aiq\");if(t=t?String(t.value||\"\").trim():\"\",!t){tip(\"✘ 要说点什么吧\",\"no\");return}var e=aiCfg();if(!e.key){tip(\"✘ 还没填 API 密钥：外观设置 → AI 问答\",\"no\");return}var i=document.getElementById(\"aisys2\");i=i?String(i.value||\"\").trim():\"\",_aiSysTmp=i,_aiQ=t;var o=document.getElementById(\"aiedit\"),r=document.getElementById(\"aians\");o&&(o.style.display=\"none\"),r&&(r.style.display=\"\");var s=document.getElementById(\"aiqq\");s&&(s.textContent=t),aiRun(t,i)},window.aiSet=function(t,e){var n=aiCfgs(),i=aiIdx();n[i]&&(n[i][t]=e,aiSaveCfgs(n),tip(\"✔ 已保存\",\"ok\"),aiEcho())},window.aiSetAskModel=function(t){var e=document.getElementById(\"aimodel2\");e&&(e.value=String(t||\"\")),aiSet(\"model\",String(t||\"\"))},window.aiSetIdx=function(t){try{store(KCIDX,String(t))}catch(e){}},window.aiSetMode=function(t){var m=t===\"rr\"?\"rr\":(t===\"cc\"?\"cc\":\"single\");try{store(KMODE,m)}catch(e){}aiSyncModeUI(),tip(\"✔ 已切换为\"+(m===\"rr\"?\"轮流调用\":(m===\"cc\"?\"并发调用\":\"单一模型\")),\"ok\")},window.aiSetRR=function(t){var e=parseInt(t,10)||2;e<1&&(e=1),e>20&&(e=20);try{store(KRR,String(e))}catch(n){}tip(\"✔ 轮流数量 \"+e,\"ok\")},window.aiSetTO=function(t){var e=parseInt(t,10)||45;e<5&&(e=5),e>300&&(e=300);try{store(KTO,String(e))}catch(n){}tip(\"✔ 超时 \"+e+\" 秒\",\"ok\")},window.aiShowBtn=function(){if(ST.aiOn){var t=aiSelText();if(_aiBtn){if(t.length<2){_aiBtn.style.display=\"none\";return}try{var e=window.getSelection(),n=e.getRangeAt(0).getBoundingClientRect(),i=document.documentElement.clientWidth||window.innerWidth||320,o=window.innerHeight||document.documentElement.clientHeight||480,r=_aiBtn.offsetWidth||72,s=_aiBtn.offsetHeight||32,d=n.right+8,c=n.bottom+8;n.right+8+r>i&&(d=Math.max(4,i-r-8)),n.bottom+8+s>o&&(c=Math.max(4,n.top-s-8));try{var u=document.querySelector(\".fab\");if(u){var l=u.getBoundingClientRect();d<l.right+8&&d+r>l.left-8&&c<l.bottom+8&&c+s>l.top-8&&(c=Math.max(4,l.top-s-10))}}catch(f){}_aiBtn.style.left=Math.max(4,d)+\"px\",_aiBtn.style.top=c+\"px\"}catch(f){}_aiBtn.style.display=\"\"}}},window.aiSelToggle=function(u){var s=_aiSel,i=s.indexOf(u);i>=0?s.splice(i,1):s.push(u);aiRenderModels()},\nwindow.aiRenderOrder=function(){var e=aiPool(),n=aiEn(),i,o,r=[],s={};for(i=0;i<n.length;i++)for(o=0;o<e.length;o++)if(aiKeyOf(e[o])===n[i]){r.push(o),s[o]=1;break}for(o=0;o<e.length;o++)s[o]||r.push(o);return r},\nwindow.aiSelIdxInOrder=function(){var r=aiRenderOrder(),a=[],i;for(i=0;i<r.length;i++)if(_aiSel.indexOf(r[i])>=0)a.push(i);a.sort(function(x,y){return x-y});return a},\nwindow.aiReorder=function(nr){var e=aiPool(),n=aiEn(),i,key,ne=[],seen={};for(i=0;i<nr.length;i++){key=aiKeyOf(e[nr[i]]);if(n.indexOf(key)>=0)ne.push(key)}aiSaveEn(ne);var np=[];seen={};for(i=0;i<nr.length;i++){key=aiKeyOf(e[nr[i]]);if(!seen[key]){seen[key]=1;np.push(e[nr[i]])}}aiSavePool(np)},window.aiMoveUp=function(){var a=aiSelIdxInOrder();if(!a.length){tip(\"请先点选要上移的模型\",\"no\");return}var r=aiRenderOrder(),first=a[0];if(first<=0)return;var last=a[a.length-1],moved=r[first-1],nr=r.slice(0,first-1).concat(r.slice(first,last+1)).concat([moved]).concat(r.slice(last+1));aiReorder(nr),aiReselAfterMove(nr),aiRenderModels()},window.aiMoveDown=function(){var a=aiSelIdxInOrder();if(!a.length){tip(\"请先点选要下移的模型\",\"no\");return}var r=aiRenderOrder(),last=a[a.length-1];if(last>=r.length-1)return;var first=a[0],moved=r[last+1],nr=r.slice(0,first).concat([moved]).concat(r.slice(first,last+1)).concat(r.slice(last+2));aiReorder(nr),aiReselAfterMove(nr),aiRenderModels()},window.aiReselAfterMove=function(nr){for(var i=0;i<_aiSel.length;i++){var x=_aiSel[i];_aiSel[i]=x>=0&&x<nr.length?nr.indexOf(x):x}},\nwindow.aiDel=function(){var a=aiSelIdxInOrder();if(!a.length){tip(\"请先点选要删除的模型\",\"no\");return}if(!confirm(\"确定删除选中的模型吗？\"))return;var r=aiRenderOrder(),e=aiPool(),n=aiEn(),rm={},i,key,ne=[],np=[];for(i=0;i<a.length;i++){var pi=r[a[i]];rm[pi]=1}for(i=0;i<n.length;i++){key=aiKeyOf(e[i]);if(!rm[i]&&n.indexOf(key)>=0)ne.push(key)}var kept=[];for(i=0;i<e.length;i++){if(!rm[i])kept.push(e[i])}aiSaveEn(ne),aiSavePool(kept),_aiSel=[];aiRenderModels()},\nwindow.aiFoldToggle=function(){var b=document.getElementById(\"aifoldbody\"),m=document.getElementById(\"aimlist\"),k=document.getElementById(\"aimlistbtns\");if(!b)return;var on=b.style.display!==\"none\";b.style.display=on?\"none\":\"\";m&&(m.style.display=on?\"none\":\"\");k&&(k.style.display=on?\"none\":\"\");var btn=document.getElementById(\"aifoldbtn\");btn&&(btn.textContent=on?\"⚙ 展开设置\":\"⚙ 收起设置\")},\nwindow.aiShowPicker=function(list,cb){var ov=document.createElement(\"div\");ov.className=\"mpicker-overlay\";var html='<div class=\"mpicker\"><div class=\"mpicker-hd\">选择要添加的模型<\/div><div class=\"mpicker-list\">';for(var i=0;i<list.length;i++)html+='<label class=\"mpick\"><input type=\"checkbox\" value=\"'+esc(list[i])+'\"><span>'+esc(list[i])+'<\/span><\/label>';html+='<\/div><div class=\"mpicker-ft\"><button class=\"bt\" type=\"button\" id=\"mpickcancel\">取消<\/button><button class=\"bt pri\" type=\"button\" id=\"mpickok\">确认<\/button><\/div><\/div>';ov.innerHTML=html;document.body.appendChild(ov);function close(){ov.parentNode&&ov.parentNode.removeChild(ov)}ov.querySelector(\"#mpickcancel\").onclick=function(){close();cb([])};ov.querySelector(\"#mpickok\").onclick=function(){var sel=[],cks=ov.querySelectorAll(\"input[type=checkbox]:checked\");for(var k=0;k<cks.length;k++)sel.push(cks[k].value);close();cb(sel)}},window.aiSyncModeUI=function(){var t=aiMode(),e=document.getElementById(\"airrn2\"),l=null,p=e&&e.closest?e.closest(\"div\"):null;if(p){var lab=p.querySelector(\"label\");if(lab){try{while(lab.firstChild)lab.removeChild(lab.firstChild)}catch(x){}var span=document.createElement(\"span\");span.textContent=(t===\"cc\"?\"并发数量\":\"轮流数量\");lab.appendChild(span)}}e&&(e.disabled=(t!==\"rr\"&&t!==\"cc\"),e.style.opacity=(t!==\"rr\"&&t!==\"cc\")?\".45\":\"1\")},window.aiTest=function(){var t=aiEnList();if(!t.length){tip(\"✘ 没有启用的模型，先在列表里勾选\",\"no\");return}var e=document.getElementById(\"aitest\");if(!e)return;e.style.display=\"\",e.className=\"aitest wait\",e.textContent=\"测试中…\";var n=document.getElementById(\"aiq\"),i=n?String(n.value||\"\").trim():\"\";i||(i=\"只回复：OK\");var o=document.getElementById(\"aisys2\"),r=o?String(o.value||\"\").trim():\"\",s=[];r&&s.push({role:\"system\",content:r}),s.push({role:\"user\",content:i});var d=[],c=0,u=0;function l(){if(c>=t.length){e.className=\"aitest \"+(u===t.length?\"err\":\"ok\"),e.textContent=d.join(`\n`),tip(\"✔ 测试完成：\"+(t.length-u)+\"\/\"+t.length+\" 个成功\",\"ok\");return}var f=t[c],m=c+1,g=aiCfgs(),h=g[f.cfg]||g[0]||{},w=String(h.base||AIDEFBASE).replace(\/[\/]+$\/,\"\");e.className=\"aitest wait\",e.textContent=d.join(`\n`)+(d.length?`\n`:\"\")+\"[\"+m+\"\/\"+t.length+\"] \"+f.pn+\" \/ \"+f.mn+\" 测试中…\",aiOnce(w,h.key,f.id,s,aiTimeout()).then(function(v){aiLog({kind:\"测试\",ok:v.ok,name:\"#\"+m+\" \"+f.pn+\" \/ \"+f.mn,pn:f.pn,model:f.mn,ms:v.ms||0,err:v.err||\"\",a:v.ans||\"\",q:i,sys:r}),v.ok||u++,d.push(\"[\"+m+\"] \"+(v.ok?\"成功  延迟 \"+v.ms+\"ms\":\"失败  \"+String(v.err||\"\")+\"  (\"+(v.ms||0)+\"ms)\")+\"  \"+f.pn+\" \/ \"+f.mn+(v.ok&&v.ans?`\n     答: `+String(v.ans).slice(0,50):\"\")),c++,l()})}l()},window.aiTestClear=function(){var t=document.getElementById(\"aitest\");t&&(t.style.display=\"none\",t.textContent=\"\");try{jsave(KAIL,[])}catch(e){}};var _aiBtn=null,_aiT=0,_aiTimer=0,_aiQ=\"\",_aiRaw=\"\",_aiBusy=0,_aiSysTmp=\"\";window.aiTimeout=function(){var t=45;try{t=parseInt(load(KTO)||\"45\",10)||45}catch(e){t=45}return t<5&&(t=5),t>300&&(t=300),t*1e3},window.aiToggleEn=function(t){var e=aiPool();if(e[t]){var n=aiKeyOf(e[t]),i=aiEn(),o=i.indexOf(n);o>=0?i.splice(o,1):i.push(n),aiSaveEn(i),aiRenderModels(),tip(o>=0?\"已取消勾选\":\"已勾选，序号 \"+i.length,\"ok\")}},window.aiTs=function(t){try{var e=new Date(t),n=function(i){return(i<10?\"0\":\"\")+i};return n(e.getMonth()+1)+\"-\"+n(e.getDate())+\" \"+n(e.getHours())+\":\"+n(e.getMinutes())+\":\"+n(e.getSeconds())}catch(i){return\"\"}},window.aiType=function(t,e){var n=document.createElement(\"div\");n.innerHTML=e;var i=n.textContent||\"\";t.textContent=\"\";var o=0,r=Math.max(1,Math.ceil(i.length\/200));try{_aiTimer&&clearInterval(_aiTimer)}catch(s){}_aiTimer=setInterval(function(){o+=r,t.textContent=i.slice(0,o),o>=i.length&&(clearInterval(_aiTimer),_aiTimer=0,t.innerHTML=e)},16)},window.aiViewLog=function(){alert(aiLogText())},\/\/ BUGFIX 2026-09：详情页外观面板专用桥接函数。\n\/\/ 必须使用 window.detailBuildPanel，避免与启动页 startJs 的 buildPanel() 全局同名冲突。\nwindow.detailBuildPanel=function(){var t=\"<h3>🎨 外观设置<\/h3>\";return t+=sec(\"p1\",\"背景图片\",!1),t+='<div id=\"pbg\"><\/div>',t+='<div class=\"srow\"><label>保存到分类<\/label><select id=\"bcat\">'+catOpts(BGC)+\"<\/select><\/div>\",t+='<input type=\"text\" id=\"bi\" placeholder=\"图片网址 或 \/sdcard\/Pictures\/bg.jpg\">',t+='<div class=\"row\"><button class=\"bt\" onclick=\"addBG()\">保存并应用<\/button><button class=\"bt\" onclick=\"clearBG()\">清除背景<\/button><\/div>',t+='<div class=\"row\"><button class=\"bt\" onclick=\"wnUp(\\'bg\\')\">上传到背景图片云<\/button><button class=\"bt\" onclick=\"wnDown(\\'bg\\')\">从背景图片云下载<\/button><\/div>',t+=selrow(\"显示模式\",\"sbgFitO\",[[\"cover\",\"填充裁切\"],[\"contain\",\"完整显示\"],[\"fill\",\"拉伸\"]],\"upd('bgFit',this.value);applyBG()\"),t+=endsec(),t+=sec(\"p2\",\"头像外框\",!1),t+=`<div class=\"row\" style=\"margin-bottom:4px\"><button class=\"msw\" id=\"m1\" onclick=\"setFMode('under')\">衬于头像下方<\/button><button class=\"msw\" id=\"m2\" onclick=\"setFMode('over')\">浮于头像上方<\/button><\/div>`,t+='<div id=\"pfr\"><\/div>',t+='<div class=\"srow\"><label>保存到分类<\/label><select id=\"fcat\">'+catOpts(FRC)+\"<\/select><\/div>\",t+='<input type=\"text\" id=\"fi\" placeholder=\"外框网址（建议正方形透明 PNG）\">',t+='<div class=\"row\"><button class=\"bt\" onclick=\"addFrame()\">保存并应用<\/button><button class=\"bt\" onclick=\"clearFrame()\">清除外框<\/button><\/div>',t+='<div class=\"row\"><button class=\"bt\" onclick=\"wnUp(\\'fr\\')\">上传到头像框云<\/button><button class=\"bt\" onclick=\"wnDown(\\'fr\\')\">从头像框云下载<\/button><\/div>',t+='<div class=\"row\"><button class=\"bt\" onclick=\"frDecOpen()\">🎨 外框去底色<\/button>'+(FRDEC?'<button class=\"bt warn\" onclick=\"frDecClear()\">↺ 还原原图<\/button>':\"\")+\"<\/div>\",t+='<div class=\"hint\">JPG 外框常带纯色背景，套在头像上会挡住头像。去底色只处理<b>外框图<\/b>，结果对所有楼层头像生效并存在本机。<\/div>',t+=\"<h4>外框裁切与缩放<\/h4>\",t+=selrow(\"裁切模式\",\"sfrFitO\",[[\"contain\",\"完整显示\"],[\"cover\",\"填充裁切\"],[\"manual\",\"手动缩放（默认）\"]],\"upd('frFit',this.value);frFitUI()\"),t+=rrow(\"外框图缩放 %\",\"sfrZoom\",20,400,5,\"wfrZoom\"),t+=rrow(\"焦点X %\",\"sfrBX\",0,100,1,\"wfrBX\"),t+=rrow(\"焦点Y %\",\"sfrBY\",0,100,1,\"wfrBY\"),t+='<div class=\"hint\">选「手动缩放」才会出现下面三个滑块：缩放决定外框图在<b>大小固定<\/b>的遮罩容器里的放大倍数，焦点 X \/ Y 决定放大后显示它的哪个部位；<b>容器尺寸始终不变<\/b>，超出部分自动裁掉。<br>注意：这三个滑块只改变外框图<b>内部<\/b>的显示范围；「头像 \/ 外框 对位」分区里的「外框放大 \/ 左右 \/ 上下」移动的是<b>整个外框图层<\/b>，两者互不干扰。<\/div>',t+=\"<h4>外框遮罩形状<\/h4>\",t+='<div class=\"row\" style=\"margin-bottom:2px\"><button class=\"msw\" id=\"fmk1\" onclick=\"setFMask(1)\">圆形<\/button><button class=\"msw\" id=\"fmk0\" onclick=\"setFMask(0)\">方形<\/button><\/div>',t+=rrow(\"遮罩圆角(0~50)\",\"sfrMask\",0,50,1),t+='<div class=\"hint\">图层遮罩限制外框图层的可见形状（类似 PS 图层蒙版）。<br>· 圆形：遮罩成圆形，贴合圆形头像，适合纯色\/满铺的外框图。<br>· 方形：完整保留原图，适合中间透明的 PNG —— 透明部分会自然形成任意形状（花瓣、星星、边框等），此时方形遮罩才能完整显示它的设计。<\/div>',t+=endsec(),t+=sec(\"p3\",\"头像 \/ 外框 对位\",!1),t+=rrow(\"头像放大 %\",\"savScale\",50,200,5),t+=rrow(\"头像 左右\",\"savFx\",-20,20,1),t+=rrow(\"头像 上下\",\"savFy\",-20,20,1),t+=rrow(\"外框放大 %\",\"sfrScale\",50,200,5),t+=rrow(\"外框 左右\",\"sfrFx\",-20,20,1),t+=rrow(\"外框 上下\",\"sfrFy\",-20,20,1),t+=\"<h4>头像遮罩形状<\/h4>\",t+='<div class=\"row\" style=\"margin-bottom:2px\"><button class=\"msw\" id=\"amk1\" onclick=\"setAMask(1)\">圆形<\/button><button class=\"msw\" id=\"amk0\" onclick=\"setAMask(0)\">方形<\/button><\/div>',t+=rrow(\"遮罩圆角(0~50)\",\"savMask\",0,50,1),t+=endsec(),t+=sec(\"p4\",\"图片样式\",!1),t+='<div class=\"hint\">「单图宽度」决定一行显示几列：50%→2列，33%→3列，25%→4列，100%→单列大图。<\/div>',t+=rrow(\"单图宽度 %\",\"simgw\",20,100,1),t+=rrow(\"图片高度 px\",\"simgh\",60,400,10),t+=selrow(\"裁切模式\",\"simgfitO\",[[\"contain\",\"完整显示\"],[\"cover\",\"填充裁切\"],[\"fill\",\"拉伸\"]],\"upd('imgfit',this.value)\"),t+=rrow(\"焦点X %\",\"simgfx\",0,100,1),t+=rrow(\"焦点Y %\",\"simgfy\",0,100,1),t+=rrow(\"圆角\",\"simgrd\",0,24,1),t+=rrow(\"间距\",\"simggap\",0,20,1),t+='<div class=\"row\" style=\"margin-bottom:4px\"><button class=\"msw'+(ST.imgLazy?\"\":\" on\")+'\" id=\"ilz0\" onclick=\"setImgLazy(0)\">立即加载<\/button><button class=\"msw'+(ST.imgLazy?\" on\":\"\")+'\" id=\"ilz1\" onclick=\"setImgLazy(1)\">滚动加载<\/button><\/div>',t+='<div class=\"hint\">默认「滚动加载」：图片滚到附近才加载，省流量、首屏快。<br>若某些阅读 App 里正文图片<b>完全不显示<\/b>（老 WebView 不触发懒加载），改成「立即加载」即可。<\/div>',t+=endsec(),t+=sec(\"p5\",\"正文框 \/ 楼层框 边框与阴影\",!1),t+=rrow(\"正文框 边框\",\"spostBdW\",0,8,1),t+=crow(\"　颜色\",\"spostBdC\"),t+=rrow(\"正文框 阴影\",\"spostSh\",0,12,1),t+=crow(\"　阴影色\",\"spostShC\"),t+=rrow(\"楼层框 边框\",\"sreplyBdW\",0,8,1),t+=crow(\"　颜色\",\"sreplyBdC\"),t+=rrow(\"楼层框 阴影\",\"sreplySh\",0,12,1),t+=crow(\"　阴影色\",\"sreplyShC\"),t+=rrow(\"卡片圆角\",\"srd\",0,26,1),t+=endsec(),t+=sec(\"p6\",\"底色与文字\",!1),t+=crow(\"正文框底色\",\"spostBg\"),t+=rrow(\"　不透明度\",\"spostA\",0,100,1),t+=crow(\"正文字色\",\"spostTx\"),t+=crow(\"楼层框底色\",\"sreplyBg\"),t+=rrow(\"　不透明度\",\"sreplyA\",0,100,1),t+=crow(\"楼层字色\",\"sreplyTx\"),t+=crow(\"元信息色\",\"smetaTx\"),t+=rrow(\"正文字·阴影\",\"spostTxSh\",0,12,1),t+=crow(\"　阴影色\",\"spostTxShC\"),t+=rrow(\"楼层字·阴影\",\"sreplyTxSh\",0,12,1),t+=crow(\"　阴影色\",\"sreplyTxShC\"),t+='<div class=\"hint\">「正文\/楼层字·阴影」作用于帖子正文与楼层回复的文字本身（提升可读性），与「正文框 \/ 楼层框 边框与阴影」分区里的卡片外阴影是两回事。<\/div>',t+='<div class=\"hint\">元信息色：沙发\/时间\/观看数\/回复数\/全部回复\/分页 等字段。<\/div>',t+=rrow(\"楼层间距\",\"sgap\",0,30,1),t+=rrow(\"标题·字号\",\"sttFs\",14,30,1),t+=rrow(\"标题·字重\",\"sttFw\",300,900,100),t+=rrow(\"标题·行高\",\"sttLh\",120,220,5),t+=rrow(\"标题·字间距\",\"sttLs\",0,4,.5),t+='<div class=\"hint\">标题·字号\/字重\/行高\/字间距：帖子大标题的字体独立控制，不再跟随正文。<\/div>',t+=rrow(\"字号\",\"sfs\",12,22,1),t+=rrow(\"行高\",\"slh\",120,220,5),t+=rrow(\"字重\",\"sfw\",300,700,100),t+=rrow(\"字间距\",\"sls\",0,4,.5),t+=endsec(),t+=sec(\"p10\",\"引用框（楼层内嵌套）\",!1),t+=crow(\"底色\",\"sqBg\"),t+=rrow(\"　不透明度\",\"sqA\",0,100,1),t+=crow(\"文字色\",\"sqTx\"),t+=rrow(\"边框\",\"sqBdW\",0,8,1),t+=crow(\"　边框色\",\"sqBdC\"),t+=rrow(\"圆角\",\"sqRd\",0,20,1),t+=rrow(\"字号\",\"sqFs\",10,20,1),t+=rrow(\"行高\",\"sqLh\",120,220,5),t+=rrow(\"内边距\",\"sqPad\",0,24,1),t+=rrow(\"文字·阴影\",\"sqSh\",0,12,1),t+=crow(\"　阴影色\",\"sqShC\"),t+='<div class=\"hint\">引用文字的字号\/颜色现已对全部引用生效：论坛引用里的 &lt;font color\/size&gt; 表现属性会被强制覆盖，因此引用自楼主或任意楼层用户的文本都统一受上面几项控制。<\/div>',t+=endsec(),t+=sec(\"p11\",\"标题、正文、引用、回复\",!1),t+=rrow(\"标题→正文\",\"sttgap\",0,40,1),t+=rrow(\"楼层 上\",\"srpt\",0,32,1),t+=rrow(\"楼层 下\",\"srpb\",0,32,1),t+=rrow(\"楼层 左\",\"srpl\",0,32,1),t+=rrow(\"楼层 右\",\"srpr\",0,32,1),t+=rrow(\"沙发→下方\",\"shdgap\",0,40,1),t+=rrow(\"引用→沙发\",\"sqgapt\",0,40,1),t+=rrow(\"引用→正文\",\"sqgapb\",0,40,1),t+=rrow(\"正文→上方\",\"smsggapt\",0,40,1),t+='<div class=\"hint\">标题→正文：帖子大标题到正文的距离。<br>楼层 上\/下\/左\/右：文本块整体到楼层框四边的距离。<br>后四项为楼层内三类文本（沙发信息 \/ 引用 \/ 回复内容）之间的独立间距。<\/div>',t+=endsec(),t+=sec(\"p7\",\"按钮样式\",!1),t+=crow(\"按钮底色\",\"sbtnBg\"),t+=rrow(\"　不透明度\",\"sbtnA\",0,100,1),t+=crow(\"按钮字色\",\"sbtnTx\"),t+=rrow(\"边框粗细\",\"sbtnBdW\",0,8,1),t+=crow(\"　边框色\",\"sbtnBdC\"),t+=rrow(\"阴影\",\"sbtnSh\",0,12,1),t+=crow(\"　阴影色\",\"sbtnShC\"),t+=rrow(\"圆角\",\"sbtnRd\",0,24,1),t+=rrow(\"字号\",\"sbtnFs\",10,20,1),t+=rrow(\"大小\",\"sbtnPad\",4,20,1),t+=endsec(),t+=sec(\"p8\",\"按钮文字 \/ 图案\",!1),t+=trow(\"收藏\",\"sbtnLfav\",\"⭐ 收藏\"),t+=trow(\"点评\",\"sbtnLcmt\",\"💬 点评\"),t+=trow(\"回复\",\"sbtnLrep\",\"✏️ 回复\"),t+=trow(\"倒序\",\"sbtnLord\",\"🔃 倒序\"),t+=trow(\"正序\",\"sbtnLasc\",\"🔄 正序\"),t+=trow(\"只看楼主\",\"sbtnLop\",\"👤 只看楼主\"),t+=trow(\"重载\",\"sbtnLrl\",\"🔄 重载\"),t+=trow(\"发送\",\"sbtnLsend\",\"发送\"),t+=endsec(),t+=sec(\"p12\",\"设置弹窗外观\",!1),t+='<div class=\"hint\">以下各项只影响「设置弹窗」自身的外观，不影响帖子内容。<\/div>',t+=crow(\"弹窗·底色\",\"smBg\"),t+=rrow(\"弹窗·不透明度\",\"smA\",0,100,1),t+=crow(\"弹窗·文字色\",\"smTx\"),t+=crow(\"折叠分区·标题底色\",\"ssechBg\"),t+=rrow(\"折叠分区·标题不透明度\",\"ssechA\",0,100,1),t+='<div class=\"hint\">折叠分区标题 = 本弹窗中每个折叠项的标题条（如「背景图片」「图片样式」）。<br>半透明时会透出下方弹窗底色，建议把弹窗底色调深色更容易看出效果。<\/div>',t+=crow(\"预设分类·标题底色\",\"scatBg\"),t+=rrow(\"预设分类·标题不透明度\",\"scatA\",0,100,1),t+='<div class=\"hint\">预设分类标题 = 背景\/头像框预设列表里，每个分类（如「默认」）的标题条。<\/div>',t+=crow(\"滑块文字·颜色\",\"slbTx\"),t+='<div class=\"hint\">滑块文字 = 本面板所有设置项左侧的标签文字（如「弹窗·底色」）。<\/div>',t+=crow(\"标题文字·颜色\",\"shdTx\"),t+='<div class=\"hint\">标题文字 = 两类标题的字体颜色，由本项统一控制：<br>① 折叠分区标题（如「背景图片」「图片样式」）<br>② 预设分类标题（背景\/头像框列表中的「默认」等）<\/div>',t+=\"<h4>参数说明文字<\/h4>\",t+=rrow(\"字号\",\"shintFs\",8,20,1),t+=crow(\"颜色\",\"shintTx\"),t+=rrow(\"行高\",\"shintLh\",120,220,5),t+=rrow(\"字间距\",\"shintLs\",-2,8,.5),t+=rrow(\"阴影\",\"shintSh\",0,12,1),t+=crow(\"　阴影色\",\"shintShC\"),t+='<div class=\"hint\">参数说明文字 = 各类弹窗（外观设置、图片上传、图片网址等）内灰色的补充说明文本，由以上六项统一控制其字号、颜色、行高、字距与阴影。<\/div>',t+=endsec(),t+=sec(\"p13\",\"底部回复框\",!1),t+=crow(\"框底色\",\"sdBg\"),t+=rrow(\"　不透明度\",\"sdA\",0,100,1),t+=rrow(\"上边框\",\"sdBdW\",0,8,1),t+=crow(\"　边框色\",\"sdBdC\"),t+=rrow(\"圆角\",\"sdRd\",0,20,1),t+=endsec(),t+=sec(\"p14\",\"底部分页栏\",!1),t+='<div class=\"hint\">控制帖子底部的「‹ 上一页 \/ 第 N 页 \/ 下一页 ›」三个按钮，以及点中间页码弹出的选择框里的页码格子。与工具栏按钮（倒序\/只看楼主\/重载）互不干扰。<\/div>',t+=crow(\"底色\",\"spgBg\"),t+=rrow(\"　不透明度\",\"spgA\",0,100,1),t+=crow(\"文字色\",\"spgTx\"),t+=rrow(\"边框粗细\",\"spgBdW\",0,8,1),t+=crow(\"　边框色\",\"spgBdC\"),t+=rrow(\"圆角\",\"spgRd\",0,20,1),t+=rrow(\"字号\",\"spgFs\",10,20,1),t+=\"<h4>当前页码高亮<\/h4>\",t+=crow(\"底色\",\"spgOnBg\"),t+=crow(\"文字色\",\"spgOnTx\"),t+=endsec(),t+=sec(\"p9\",\"编辑按钮\",!1),t+=crow(\"底色\",\"sedBg\"),t+=rrow(\"　不透明度\",\"sedA\",0,100,1),t+=crow(\"文字色\",\"sedTx\"),t+=rrow(\"边框\",\"sedBdW\",0,8,1),t+=crow(\"　边框色\",\"sedBdC\"),t+=rrow(\"圆角\",\"sedRd\",0,20,1),t+=rrow(\"字号\",\"sedFs\",10,20,1),t+='<div class=\"hint\">「编辑」只会在你自己的主题帖与回复上出现（依据页面 discuz_uid 判定）。<\/div>',t+=endsec(),t+=sec(\"p16\",\"悬浮设置按钮\",!1),t+='<div class=\"hint\">长按该按钮约 0.6 秒可进入拖动模式，拖到合适位置松手即自动保存位置。<\/div>',t+='<div class=\"row\" style=\"margin-bottom:6px\"><button class=\"msw\" id=\"sh1\" onclick=\"setShape(1)\">圆形<\/button><button class=\"msw\" id=\"sh0\" onclick=\"setShape(0)\">方形<\/button><\/div>',t+=rrow(\"圆角(50=正圆)\",\"sfabRd\",0,50,1),t+=rrow(\"按钮大小\",\"sfabSz\",32,72,2),t+=\"<h4>按钮背景图<\/h4>\",t+='<div class=\"fprev\"><span>预览<\/span><div id=\"fabPrev\"><b id=\"fabPrevEmo\"><\/b><\/div><\/div>',t+='<div id=\"fabiList\"><\/div>',t+='<input type=\"text\" id=\"fabin\" placeholder=\"图片网址（支持动图）或 \/sdcard\/xx.gif\">',t+='<div class=\"row\"><button class=\"bt\" onclick=\"addFabBi()\">保存并应用<\/button><button class=\"bt\" onclick=\"clearFabBi()\">清除背景图<\/button><\/div>',t+=crow(\"背景底色\",\"sfabBg\"),t+=selrow(\"裁切模式\",\"sfabFitO\",[[\"manual\",\"手动缩放\"],[\"cover\",\"填充裁切\"],[\"contain\",\"完整显示\"]],\"upd('fabFit',this.value)\"),t+=rrow(\"缩放 %\",\"sfabScale\",100,500,10),t+=rrow(\"焦点 X %\",\"sfabBX\",0,100,1),t+=rrow(\"焦点 Y %\",\"sfabBY\",0,100,1),t+='<div class=\"hint\">只有「手动缩放」模式下支持焦点移动与缩放滑块。动图链接会自动播放。<\/div>',t+=trow(\"图标文字\",\"sfabEmo\",\"留空 = 纯图按钮（默认 🎨）\"),t+=\"<h4>边框 \/ 阴影 \/ 位置<\/h4>\",t+=rrow(\"边框粗细\",\"sfabBdW\",0,8,1),t+=crow(\"　边框色\",\"sfabBdC\"),t+=rrow(\"阴影大小\",\"sfabSh\",0,20,1),t+=crow(\"　阴影色\",\"sfabShC\"),t+=rrow(\"位置·距右\",\"sfabX\",0,320,1),t+=rrow(\"位置·距底\",\"sfabY\",0,640,1),t+=endsec(),t+=sec(\"p17\",\"用户名字体样式\",!1),t+='<div class=\"hint\">用户名（楼主名 \/ 楼层作者名）的字体独立设置，不再跟随正文。<br>彩虹渐变需开启开关，多色用英文逗号分隔，支持任意多层次。<\/div>',t+=\"<h4>帖子正文的用户名<\/h4>\",t+='<div class=\"row\" style=\"margin-bottom:4px\"><button class=\"msw\" id=\"oi0\" onclick=\"setOpnIt(0)\">正常<\/button><button class=\"msw\" id=\"oi1\" onclick=\"setOpnIt(1)\">斜体<\/button><\/div>',t+=rrow(\"字号\",\"sopnFs\",10,26,1),t+=rrow(\"字重\",\"sopnFw\",300,900,100),t+=crow(\"颜色\",\"sopnTx\"),t+=rrow(\"阴影\",\"sopnSh\",0,12,1),t+=crow(\"　阴影色\",\"sopnShC\"),t+='<div class=\"row\" style=\"margin:6px 0 2px\"><button class=\"msw\" id=\"or0\" onclick=\"setOpnRb(0)\">纯色<\/button><button class=\"msw\" id=\"or1\" onclick=\"setOpnRb(1)\">彩虹渐变<\/button><\/div>',t+=trow(\"彩虹色(逗号分隔)\",\"sopnRbC\",\"#FF6B9D,#7C6BD9,#22A7C2\"),t+=rrow(\"渐变角度\",\"sopnRbD\",0,360,5),t+=\"<h4>回复楼层的用户名<\/h4>\",t+='<div class=\"row\" style=\"margin-bottom:4px\"><button class=\"msw\" id=\"ri0\" onclick=\"setRnIt(0)\">正常<\/button><button class=\"msw\" id=\"ri1\" onclick=\"setRnIt(1)\">斜体<\/button><\/div>',t+=rrow(\"字号\",\"srnFs\",10,26,1),t+=rrow(\"字重\",\"srnFw\",300,900,100),t+=crow(\"颜色\",\"srnTx\"),t+=rrow(\"阴影\",\"srnSh\",0,12,1),t+=crow(\"　阴影色\",\"srnShC\"),t+='<div class=\"row\" style=\"margin:6px 0 2px\"><button class=\"msw\" id=\"rr0\" onclick=\"setRnRb(0)\">纯色<\/button><button class=\"msw\" id=\"rr1\" onclick=\"setRnRb(1)\">彩虹渐变<\/button><\/div>',t+=trow(\"彩虹色(逗号分隔)\",\"srnRbC\",\"#FF6B9D,#7C6BD9,#22A7C2\"),t+=rrow(\"渐变角度\",\"srnRbD\",0,360,5),t+=endsec(),t+=sec(\"p18\",\"点评框（楼层内的点评）\",!1),t+='<div class=\"hint\">楼层正文下方的「点评」区块。底色与边框作用于整个点评框，点评者名 \/ 时间 \/ 点评内容三段文字各有独立字号与颜色。<\/div>',t+=\"<h4>点评框<\/h4>\",t+=crow(\"底色\",\"scmtBg\"),t+=rrow(\"　不透明度\",\"scmtA\",0,100,1),t+=rrow(\"边框\",\"scmtBdW\",0,8,1),t+=crow(\"　边框色\",\"scmtBdC\"),t+=rrow(\"圆角\",\"scmtRd\",0,24,1),t+=rrow(\"内边距\",\"scmtPad\",0,24,1),t+=rrow(\"上方间距\",\"scmtGap\",0,24,1),t+=rrow(\"阴影\",\"scmtSh\",0,12,1),t+=crow(\"　阴影色\",\"scmtShC\"),t+=rrow(\"框内基准字号\",\"scmtFs\",8,22,1),t+=rrow(\"框内行高 %\",\"scmtLh\",100,220,5),t+=crow(\"框内文字色\",\"scmtTx\"),t+=\"<h4>点评者名（🌸 之后）<\/h4>\",t+=crow(\"颜色\",\"scmtNTx\"),t+=\"<h4>点评时间<\/h4>\",t+=crow(\"颜色\",\"scmtTTx\"),t+=\"<h4>点评内容<\/h4>\",t+=crow(\"颜色\",\"scmtCTx\"),t+=rrow(\"字号\",\"scmtCFs\",8,24,1),t+=rrow(\"行高 %\",\"scmtCLh\",100,220,5),t+=endsec(),t+=sec(\"p19\",\"头像旁元素 XY 坐标\",!1),t+='<div class=\"hint\">把「用户名 \/ 时间 \/ 沙发等楼层号 \/ 观看数 \/ 回复数」相对所在容器挪位：横向 ±120、纵向 ±80；横 \/ 纵各占一行，滑块更长、更好对准。<br>位移用 transform，<b>原位置仍会占位<\/b>，所以下面的正文不会被顶动。<br>注意：卡片开了长列表性能优化（content-visibility），挪到卡片边界外的部分会被裁掉，这是预期行为。<\/div>',t+=xyrow(\"用户名\",\"un\"),t+=xyrow(\"时间\",\"tm\"),t+=xyrow(\"楼层号（沙发类）\",\"fl\"),t+=xyrow(\"观看数\",\"vw\"),t+=xyrow(\"回复数\",\"rp\"),t+=endsec(),t+=sec(\"p20\",\"首屏性能（楼层分批渲染）\",!1),t+='<div class=\"hint\">实测 150 楼的帖子：JS 拼接只要 1ms，真正的大头是浏览器要一次性构建约 2000 个 DOM 节点。<br>开启分批后，首屏只渲染前 N 楼（节点降至约 10%），剩余楼层滚动到接近底部时自动补上（每次补 60 楼）。<br>★ 与已有的 content-visibility 是<b>互补<\/b>的：后者只跳过屏幕外的布局\/绘制，跳不过 DOM 构建。<br>设为 <b>0<\/b> 则恢复「一次渲染全部」（旧行为，首屏较慢但滚动不会有任何停顿）。<\/div>',t+=rrow(\"首屏楼层数（0=不分批）\",\"sfirstN\",0,60,1),t+=`<div class=\"row\"><button class=\"bt\" onclick=\"upd('firstN',0);sv('sfirstN',0);setV('sfirstN',0);tip('已设为不分批，下次加载生效')\">恢复不分批<\/button><button class=\"bt\" onclick=\"upd('firstN',12);sv('sfirstN',12);setV('sfirstN',12);tip('已设为首屏 12 楼')\">默认 12 楼<\/button><\/div>`,t+=\"<h4>批量<\/h4>\",t+='<div class=\"row\"><button class=\"bt\" onclick=\"resetXY()\">全部复位到 (0,0)<\/button><\/div>',t+=endsec(),t+=sec(\"p15\",\"配置备份 \/ 恢复\",!1),t+='<div class=\"hint\">把全部自定义（颜色、间距、背景、头像框、分类）导出成文本保存；换机或缓存被清理后粘贴回来即可一键还原。<\/div>',t+='<div class=\"row\"><button class=\"bt\" onclick=\"exportCfg()\">📤 导出配置<\/button><button class=\"bt\" onclick=\"importCfgPanel()\">📥 导入配置<\/button><\/div>',t+='<div class=\"row\"><button class=\"bt\" onclick=\"saveCfgLocal()\">💾 存本机备份<\/button><button class=\"bt\" onclick=\"loadCfgLocal()\">📂 读本机备份<\/button><\/div>',t+='<div class=\"row\"><button class=\"bt\" onclick=\"darkPreset()\">🌙 深色配色<\/button><button class=\"bt\" onclick=\"lightPreset()\">☀️ 浅色默认<\/button><\/div>',t+='<h4 style=\"margin-top:14px\">我的配置方案<\/h4>',t+='<div class=\"hint\">把当前全部外观配置保存为命名方案，可一键切换、重命名或删除；「深色配色 \/ 浅色默认」为内置预设。<\/div>',t+='<div class=\"catadd\"><input type=\"text\" id=\"profName\" placeholder=\"方案名称，如：护眼绿\"><\/div>',t+='<div class=\"row\"><button class=\"bt\" onclick=\"cancelRen()\">✖ 取消<\/button><button class=\"bt pri\" id=\"profBtn\" onclick=\"saveProfile()\">💾 保存方案<\/button><\/div>',t+='<div id=\"profList\"><\/div>',t+=endsec(),t+=sec(\"pAI\",\"AI 问答\",!1),t+='<div class=\"hint\">选中正文里的文字会浮出「✨ 问 AI」按钮。<br>默认用免费免登录的 <b>platform.aitools.cfd<\/b>，密钥可自动申请；也可自己填 Base URL \/ 密钥 \/ 模型，接任何 OpenAI 兼容服务。<\/div>',t+=`<div class=\"srow\"><label>开关<\/label><span class=\"dec-sw\"><button class=\"msw\" id=\"ai0\" onclick=\"upd('aiOn',0)\">关<\/button><button class=\"msw\" id=\"ai1\" onclick=\"upd('aiOn',1)\">开<\/button><\/span><\/div>`,t+='<div class=\"srow\"><label>配置<\/label><select id=\"aicfg\" onchange=\"aiPickCfg(this.value)\"><\/select><\/div>',t+='<div class=\"row\"><button class=\"bt\" onclick=\"aiAddCfg()\">＋ 新建<\/button><button class=\"bt\" onclick=\"aiDupCfg()\">复制<\/button><button class=\"bt warn\" onclick=\"aiDelCfg()\">删除<\/button><\/div>',t+=`<div class=\"srow\"><label>名称<\/label><input type=\"text\" id=\"ainame\" onchange=\"aiSet('n',this.value)\"><\/div>`,t+=`<div class=\"srow\"><label>Base<\/label><input type=\"text\" id=\"aibase\" placeholder=\"https:\/\/...\/v1\" onchange=\"aiSet('base',this.value)\"><\/div>`,t+=`<div class=\"srow\"><label>密钥<\/label><input type=\"text\" id=\"aikey\" placeholder=\"sk-...\" onchange=\"aiSet('key',this.value)\"><\/div>`,t+='<div class=\"row\"><button class=\"bt\" onclick=\"aiGenKey()\">↻ 申请免费密钥<\/button><button class=\"bt\" onclick=\"aiFetchModels()\">拉取模型<\/button><\/div>',t+=`<div class=\"srow\"><label>模型<\/label><input type=\"text\" id=\"aimodel\" placeholder=\"模型 ID，可手填\" onchange=\"aiSet('model',this.value)\"><\/div>`,t+=`<select id=\"aimpick\" onchange=\"aiSet('model',this.value)\"><\/select>`,t+=`<div class=\"srow\"><label>自动续期<\/label><span class=\"dec-sw\"><button class=\"msw\" id=\"aiauto0\" onclick=\"aiSet('auto',0)\">关<\/button><button class=\"msw\" id=\"aiauto1\" onclick=\"aiSet('auto',1)\">开<\/button><\/span><\/div>`,t+='<div class=\"hint\">密钥失效（401）时自动去免费站申请新密钥并覆盖。该站每小时限申请 1 个，且实测密钥约 1 小时过期，开着更省心。<\/div>',t+='<div class=\"srow\"><label>提示词<\/label><select id=\"aipro\" onchange=\"aiPickPro(this.value)\"><\/select><\/div>',t+=`<textarea id=\"aisys\" rows=\"4\" placeholder=\"系统提示词（选中文字会作为用户消息一起发送）\" onchange=\"aiSet('sys',this.value)\"><\/textarea>`,t+='<div class=\"row\"><button class=\"bt\" onclick=\"aiAddPro()\">＋ 存为新提示词<\/button><button class=\"bt warn\" onclick=\"aiDelPro()\">删提示词<\/button><\/div>',t+='<div class=\"hint\">预设：翻译 \/ 词语含义（含网络用语、常见用法、出现场景）\/ 润色改写 \/ 续写。改完点「存为新提示词」即可新增，也可在下拉里切换。<\/div>',t+=endsec(),t+='<div class=\"row\"><button class=\"bt\" onclick=\"resetStyle()\">恢复全部默认<\/button><button class=\"bt pri\" onclick=\"closeBG()\">完成<\/button><\/div>',t+='<div class=\"row\" style=\"margin-top:6px\"><button class=\"bt\" onclick=\"eggOpen()\">🎆 芝麻开门<\/button><\/div>',t},window.eggOpen=function(){var p=\"\";try{p=String(prompt(\"🔑 请输入彩蛋密码：\")||\"\").trim()}catch(e){}if(p!==\"260906\"){try{tip(\"✘ 密码错误\",\"no\")}catch(e){}return}try{tip(\"🎉 芝麻开门！正在获取便签正文…\",\"ok\")}catch(e){}var u=\"https:\/\/webnote.cc\/p\/92aa47ca96e34c85@260906\";try{if(typeof java!=\"undefined\"&&java&&typeof java.open==\"function\"){java.open(\"rss\",u);return}}catch(e){}try{if(typeof java!=\"undefined\"&&java&&typeof java.open==\"function\"){java.open(\"web\",u);return}}catch(e){}try{location.href=u}catch(e){}},window.cpDrag=function(t,e){function n(i){i.touches&&i.preventDefault&&i.preventDefault();var o=i.touches&&i.touches[0]||i,r=t.getBoundingClientRect();e(Math.min(1,Math.max(0,(o.clientX-r.left)\/r.width)),Math.min(1,Math.max(0,(o.clientY-r.top)\/r.height)))}t.addEventListener(\"touchstart\",n,{passive:!1}),t.addEventListener(\"touchmove\",n,{passive:!1}),t.addEventListener(\"mousedown\",function(i){n(i);var o=function(s){n(s)},r=function(){document.removeEventListener(\"mousemove\",o),document.removeEventListener(\"mouseup\",r)};document.addEventListener(\"mousemove\",o),document.addEventListener(\"mouseup\",r)})},window.cpHexIn=function(){var t=h2r(cv(\"cpHex\")),e=rgb2hsv(t.r,t.g,t.b);CP.h=e.h,CP.s=e.s,CP.v=e.v,cpSync(1)},window.cpInit=function(){var t=document.getElementById(\"cpSv\");t&&cpDrag(t,function(u,l){CP.s=u,CP.v=1-l,cpSync()});var e=document.getElementById(\"cpHue\");e&&cpDrag(e,function(u){CP.h=u*360,cpSync()});for(var n=[\"cpR\",\"cpG\",\"cpB\"],i=0;i<n.length;i++){var o=document.getElementById(n[i]);o&&(o.oninput=cpRgbIn)}var r=document.getElementById(\"cpHex\");r&&(r.oninput=cpHexIn);var s=document.getElementById(\"cpPreset\");if(s){for(var d=\"\",c=0;c<CP_PRESET.length;c++)d+='<button class=\"psw\" style=\"background:'+CP_PRESET[c]+`\" onclick=\"cpUse('`+CP_PRESET[c]+`')\" title=\"`+CP_PRESET[c]+'\"><\/button>';s.innerHTML=d}},window.cpRgbIn=function(){var t=parseInt(cv(\"cpR\"),10)||0,e=parseInt(cv(\"cpG\"),10)||0,n=parseInt(cv(\"cpB\"),10)||0,i=rgb2hsv(Math.min(255,Math.max(0,t)),Math.min(255,Math.max(0,e)),Math.min(255,Math.max(0,n)));CP.h=i.h,CP.s=i.s,CP.v=i.v,cpSync()},window.cpSync=function(t){var e=hsv2rgb(CP.h,CP.s,CP.v);CP.hex=r2h(e.r,e.g,e.b);var n=hsv2rgb(CP.h,1,1),i=document.getElementById(\"cpSv\");i&&(i.style.background=\"linear-gradient(to top,#000,rgba(0,0,0,0)),linear-gradient(to right,#fff,\"+r2h(n.r,n.g,n.b)+\")\");var o=document.getElementById(\"cpSvC\");o&&(o.style.left=CP.s*100+\"%\",o.style.top=(1-CP.v)*100+\"%\",o.style.background=CP.hex);var r=document.getElementById(\"cpHueC\");r&&(r.style.left=CP.h\/360*100+\"%\"),setV(\"cpR\",Math.round(e.r)),setV(\"cpG\",Math.round(e.g)),setV(\"cpB\",Math.round(e.b)),t||setV(\"cpHex\",CP.hex.toUpperCase());var s=document.getElementById(\"cpNew\");s&&(s.style.background=CP.hex)},window.cpUse=function(t){var e=h2r(t),n=rgb2hsv(e.r,e.g,e.b);CP.h=n.h,CP.s=n.s,CP.v=n.v,cpSync()},window.zAnchor=function(t,e,n,i){var o=zGet(t),r=document.getElementById(t+\"Prev\");if(!(!r||!e||!o.s)){var s=r.clientWidth||0,d=r.clientHeight||0,c=(n-(s\/2+o.x))\/o.s,u=(i-(d\/2+o.y))\/o.s,l=o.s*e;l<1&&(l=1),l>8&&(l=8),o.s=l,o.x=n-c*l-s\/2,o.y=i-u*l-d\/2,zClampView(t),zApply(t)}},window.zApply=function(t){var e=zGet(t),n=document.getElementById(t+\"Img\");n&&(n.style.transform=\"translate(\"+e.x+\"px,\"+e.y+\"px) scale(\"+e.s+\")\",n.style.imageRendering=e.s>=3?\"pixelated\":\"auto\");var i=document.getElementById(t+\"ZoomV\");i&&(i.textContent=e.s.toFixed(1)+\"x\");var o=document.getElementById(t+\"Zoom\");if(o){var r=Math.round(e.s*10);+o.value!==r&&(o.value=r)}},window.zBind=function(t){var e=document.getElementById(t+\"Prev\");if(!e||e._zb)return;e._zb=1;var n=zGet(t),i=null,o=0;function r(w,v){var p=e.getBoundingClientRect();return{x:w-p.left,y:v-p.top}}function s(w){for(var v=[],p=0;p<w.touches.length;p++)v.push({x:w.touches[p].clientX,y:w.touches[p].clientY});return v}function d(w,v){var p=w.x-v.x,S=w.y-v.y;return Math.sqrt(p*p+S*S)}function c(w,v){return{x:(w.x+v.x)\/2,y:(w.y+v.y)\/2}}function u(){return document.body&&document.body.contains(e)}function l(w){if(u()){n.moved=0,zMeasure(t);var v=w.touches;if(v&&v.length>=2){var p=s(w);o=d(p[0],p[1]),i=null}else v&&v.length===1?i={x:v[0].clientX,y:v[0].clientY}:i={x:w.clientX,y:w.clientY}}}function f(w){if(u()){var v=w.touches;if(v&&v.length>=2){var p=s(w),S=d(p[0],p[1]),x=c(p[0],p[1]);if(o>0&&S>0){var C=r(x.x,x.y);zAnchor(t,S\/o,C.x,C.y)}o=S,n.moved=1,w.cancelable&&w.preventDefault();return}if(i){var I=v?v[0].clientX:w.clientX,E=v?v[0].clientY:w.clientY,A=I-i.x,T=E-i.y;(Math.abs(A)>3||Math.abs(T)>3)&&(n.moved=1),n.x+=A,n.y+=T,zClampView(t),zApply(t),i={x:I,y:E},w.cancelable&&w.preventDefault()}}}function m(w){w&&w.touches&&w.touches.length||(i=null,o=0,setTimeout(function(){n.moved=0},80))}function g(){zReset(t)}e.addEventListener(\"touchstart\",l,!1),e.addEventListener(\"touchmove\",f,!1),e.addEventListener(\"touchend\",m,!1),e.addEventListener(\"touchcancel\",m,!1),e.addEventListener(\"mousedown\",l,!1),e.addEventListener(\"dblclick\",g,!1),window.addEventListener(\"mousemove\",f,!1),window.addEventListener(\"mouseup\",m,!1);try{var h=document.getElementById(t+\"Img\");h&&(h.draggable=!1,h.addEventListener(\"dragstart\",function(w){w.cancelable&&w.preventDefault()},!1))}catch(w){}},window.zClampView=function(t){var e=zGet(t),n=document.getElementById(t+\"Prev\");if(n){var i=n.clientWidth||0,o=n.clientHeight||0,r=((e.bw||0)*e.s-i)\/2;r<0&&(r=0);var s=((e.bh||0)*e.s-o)\/2;s<0&&(s=0),e.x>r&&(e.x=r),e.x<-r&&(e.x=-r),e.y>s&&(e.y=s),e.y<-s&&(e.y=-s)}},window.zGet=function(t){return _Z[t]||(_Z[t]={s:1,x:0,y:0,bw:0,bh:0,moved:0}),_Z[t]},window.zMeasure=function(t){var e=zGet(t),n=document.getElementById(t+\"Img\");n&&(e.bw=n.offsetWidth||0,e.bh=n.offsetHeight||0)},window.zOpen=function(t){var e=zGet(t);e.s=1,e.x=0,e.y=0,e.moved=0,zBind(t),zApply(t)},window.zReset=function(t){var e=zGet(t);e.s=1,e.x=0,e.y=0,zMeasure(t),zApply(t)},window.zSet=function(t,e){var n=document.getElementById(t+\"Prev\");if(n){var i=zGet(t);i.s&&zAnchor(t,(+e||1)\/i.s,(n.clientWidth||0)\/2,(n.clientHeight||0)\/2)}},window.zSlider=function(t,e){zSet(t,(+e.value||10)\/10)}}}catch(a){}window.aiDelAskPro=function(){var t=document.getElementById(\"aipro2\"),e=t?parseInt(t.value,10):-1,n=aiPro();if(e<0||!n[e]){tip(\"✘ 先在下拉里选一条\",\"no\");return}confirm(\"删除提示词「\"+(n[e].n||\"\")+\"」？\")&&(n.splice(e,1),aiSavePro(n),aiEchoAsk(),tip(\"✔ 已删除\",\"ok\"))},window.aiHintT=function(t){if(!t)return;var b=t.querySelector(\".ckb\");if(b)b.style.display=(b.style.display!==\"none\")?\"none\":\"block\"};try{typeof window.cpInit==\"function\"&&window.cpInit()}catch(a){}try{typeof window.aiInitBtn==\"function\"&&window.aiInitBtn()}catch(a){}var b=document.getElementById(\"app\");if(b){if(typeof window.__p8page!=\"function\"){(b.textContent||\"\").trim()||(b.innerHTML='<div style=\"padding:16px;color:#c00;font-size:13px;line-height:1.7\">页面脚本未加载。<br>请检查订阅源的 style 字段(详情页主脚本)是否完整。<\/div>');return}if(!b.firstChild||(b.textContent||\"\").trim()===\"\")try{window.__p8page()}catch(a){try{b.innerHTML='<pre style=\"padding:12px;color:#c00;white-space:pre-wrap;word-break:break-all;font-size:12px\">'+(a&&a.stack?a.stack:a)+\"<\/pre>\"}catch(t){}return}(!b.firstChild||(b.textContent||\"\").trim()===\"\")&&(b.innerHTML='<div style=\"padding:16px;color:#c00;font-size:13px;line-height:1.7\">页面脚本已执行，但没有渲染出内容。<br>可能是正文解析失败。<\/div>');try{for(var k=document.querySelectorAll(\".loading,.spinner,.mask-loading\"),y=0;y<k.length;y++)k[y]&&k[y].parentNode&&k[y].parentNode.removeChild(k[y])}catch(a){}}})();\n\n;(function(){\nvar NS=document.createElement('style');\nNS.textContent='.novel-read-btn{display:inline-block;padding:6px 16px;margin:4px 0;background:#1890ff;color:#fff!important;border-radius:4px;font-size:14px;text-decoration:none!important;cursor:pointer;border:none;line-height:1.5}.novel-read-btn:active{background:#096dd9}.novel-modal-overlay{position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,.6);z-index:1;display:flex;align-items:center;justify-content:center}.novel-modal{background:#fff;width:90%;max-width:600px;max-height:80vh;border-radius:8px;overflow:hidden;display:flex;flex-direction:column}.novel-modal-header{padding:12px 16px;border-bottom:1px solid #eee;display:flex;justify-content:space-between;align-items:center;font-weight:bold;font-size:16px}.novel-modal-close{cursor:pointer;font-size:20px;color:#999}.novel-modal-body{padding:16px;overflow-y:auto;flex:1;font-size:16px;line-height:1.8;white-space:pre-wrap;word-break:break-word;color:#333}.novel-loading{text-align:center;color:#999;padding:40px}';\ndocument.head.appendChild(NS);\n;(function(){var NS=document.createElement('style');NS.textContent=\".mrow.selected{background:var(--pkbg,#e8f0fe)!important;outline:2px solid var(--pk,#4285f4);outline-offset:-2px;border-radius:6px}\\n.mlist-btns{display:flex;gap:6px;margin-top:8px;justify-content:center;flex-wrap:wrap}\\n.mlist-btns .bt{flex:1;min-width:72px;max-width:120px}\\n.mlist-btns .bt:disabled{opacity:.4;cursor:not-allowed}\\n#aimlist{max-height:42vh;overflow-y:auto;overflow-x:hidden}\\n.mpicker-overlay{position:absolute;inset:0;background:rgba(0,0,0,.5);display:flex;align-items:center;justify-content:center;z-index:9999}\\n.mpicker{background:var(--bg);border-radius:12px;width:90%;max-width:400px;max-height:70vh;display:flex;flex-direction:column;box-shadow:0 8px 32px rgba(0,0,0,.3)}\\n.mpicker-hd{padding:12px 16px;font-weight:700;border-bottom:1px solid var(--bd);flex:none}\\n.mpicker-list{flex:1;overflow:auto;padding:8px 12px}\\n.mpicker-list label.mpick{display:flex;align-items:center;gap:8px;padding:8px;border-radius:6px;cursor:pointer}\\n.mpicker-list label.mpick:hover{background:var(--hbg)}\\n.mpicker-ft{padding:10px 16px;border-top:1px solid var(--bd);display:flex;gap:8px;justify-content:flex-end;flex:none}\\n.aifold{font-size:13px;text-align:center;margin:6px 0}\\n.aifold .bt{min-width:96px}\\n.aifold-body{overflow:visible}\\n#aim .phd{display:flex;align-items:center;justify-content:space-between;padding:12px 14px;border-bottom:1px solid rgba(0,0,0,.08)}\\n#aim .phd h3{margin:0;font-size:16px;color:#333;padding-left:2px}\\n#aim .phd .x{width:30px;height:30px;border:none;border-radius:50%;background:var(--pk,#4285f4);color:#fff;font-size:17px;font-weight:bold;line-height:1;cursor:pointer;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:opacity .15s}\\n#aim .phd .x:hover{opacity:.8}\\n\";document.head.appendChild(NS);})();\n\nfunction fetchNovelGbk(url){\n    return new Promise(function(resolve){\n        try{\n            var p=ajaxAwait(url);\n\n            if(p&&typeof p.then===\"function\"){\n                p.then(function(html){\n                    if(typeof html===\"string\"){\n                        resolve(html);\n                    }else{\n                        resolve(String(html||\"\"));\n                    }\n                }).catch(function(err){\n                    console.log(\"千白羽论坛LOG: ajaxAwait error: \"+err);\n                    resolve(\"\");\n                });\n            }else{\n                resolve(typeof p===\"string\"?p:String(p||\"\"));\n            }\n        }catch(e){\n            console.log(\"千白羽论坛LOG: ajaxAwait exception: \"+e);\n            resolve(\"\");\n        }\n    });\n}\nfunction cleanNovelHtml(html){\n  var m=html.match(\/<div[^>]*id=[\"']content[\"'][^>]*>([\\s\\S]*?)<\\\/div>\/i);\n  if(!m)return '未能提取正文内容';\n  var t=m[1]\n    .replace(\/<br\\s*\\\/?>\/gi,'\\n')\n    .replace(\/<[^>]+>\/g,'')\n    .replace(\/&nbsp;\/g,' ')\n    .replace(\/&lt;\/g,'<').replace(\/&gt;\/g,'>').replace(\/&amp;\/g,'&')\n    .replace(\/\\n\\s*\\n\/g,'\\n\\n')\n    .trim();\n  return t||'正文为空';\n}\nfunction showNovelModal(title,content){\n  var ov=document.createElement('div');\n  ov.className='novel-modal-overlay';\n  ov.innerHTML='<div class=\"novel-modal\"><div class=\"novel-modal-header\"><span>'+title.replace(\/<\/g,'&lt;')+'<\/span><span class=\"novel-modal-close\">&times;<\/span><\/div><div class=\"novel-modal-body\">'+content+'<\/div><\/div>';\n  document.body.appendChild(ov);\n  ov.querySelector('.novel-modal-close').onclick=function(){ov.remove();};\n  ov.onclick=function(e){if(e.target===ov)ov.remove();};\n}\nfunction initNovelButtons(){\n  var processed={};\n\n  function addButton(href,title,parent,oldNode){\n    if(!href||!title)return;\n\n    href=String(href).trim();\n    title=String(title).replace(\/^\\s+|\\s+$\/g,'');\n\n    if(!\/xiaoxiaoshuo8\/i.test(href))return;\n    if(!\/\\.html(?:[?#].*)?$\/i.test(href))return;\n\n    var key=href+'|'+title;\n    if(processed[key])return;\n    processed[key]=1;\n\n    var btn=document.createElement('button');\n    btn.className='novel-read-btn';\n    btn.textContent='\\uD83D\\uDCD6 '+title;\n    btn.setAttribute('data-novel-url',href);\n\n    btn.onclick=(function(h,t){\n      return function(e){\n        if(e){\n          if(e.preventDefault)e.preventDefault();\n          if(e.stopPropagation)e.stopPropagation();\n        }\n\n        showNovelModal(t,'<div class=\"novel-loading\">加载中...<\/div>');\n\n        fetchNovelGbk(h).then(function(raw){\n          var text=cleanNovelHtml(raw);\n          var body=document.querySelector('.novel-modal-body');\n          if(body)body.textContent=text;\n        });\n      };\n    })(href,title);\n\n    if(oldNode&&oldNode.parentNode){\n      oldNode.parentNode.replaceChild(btn,oldNode);\n    }else if(parent){\n      parent.appendChild(btn);\n    }\n  }\n\n  \/* ① 处理页面中真正存在的 <a> *\/\n  var links=document.querySelectorAll('a[href]');\n  for(var i=0;i<links.length;i++){\n    var a=links[i];\n    var href=a.getAttribute('href')||a.href||'';\n    var title=(a.textContent||'').trim();\n\n    addButton(href,title,a.parentNode,a);\n  }\n\n  \/* ② 处理正文文本里被转义\/嵌套的 <a> *\/\n  var walker=document.createTreeWalker(\n    document.body,\n    NodeFilter.SHOW_TEXT,\n    null,\n    false\n  );\n\n  var nodes=[];\n  var node;\n\n  while(node=walker.nextNode()){\n    if(node.parentNode&&node.parentNode.closest&&\n       node.parentNode.closest('.novel-read-btn'))continue;\n\n    var txt=node.nodeValue||'';\n\n    if(!\/xiaoxiaoshuo8\/i.test(txt))continue;\n    if(!\/\\.html\/i.test(txt))continue;\n    if(!\/<a\\b\/i.test(txt)&&!\/&lt;\\s*a\\b\/i.test(txt))continue;\n\n    nodes.push(node);\n  }\n\n  for(var ni=0;ni<nodes.length;ni++){\n    var textNode=nodes[ni];\n    var raw=textNode.nodeValue||'';\n\n    \/*\n     * 同时支持：\n     * <a href=\"...\">章节<\/a>\n     * &lt;a href=\"...\"&gt;章节&lt;\/a&gt;\n     *\/\n    var decoded=raw\n      .replace(\/&lt;\/gi,'<')\n      .replace(\/&gt;\/gi,'>')\n      .replace(\/&quot;\/gi,'\"')\n      .replace(\/&#39;\/gi,\"'\")\n      .replace(\/&amp;\/gi,'&');\n\n    var re=\/<a\\b[^>]*\\bhref\\s*=\\s*[\"']([^\"']+)[\"'][^>]*>([\\s\\S]*?)<\\\/a>\/gi;\n    var matches=[];\n    var m;\n\n    while(m=re.exec(decoded)){\n      var href=m[1];\n      var title=m[2]\n        .replace(\/<[^>]+>\/g,'')\n        .replace(\/&nbsp;\/gi,' ')\n        .trim();\n\n      if(!\/xiaoxiaoshuo8\/i.test(href))continue;\n      if(!\/\\.html(?:[?#].*)?$\/i.test(href))continue;\n      if(!title)continue;\n\n      matches.push({\n        href:href,\n        title:title\n      });\n    }\n\n    if(!matches.length)continue;\n\n    var frag=document.createDocumentFragment();\n\n    for(var mi=0;mi<matches.length;mi++){\n      var item=matches[mi];\n\n      var btn=document.createElement('button');\n      btn.className='novel-read-btn';\n      btn.textContent='\\uD83D\\uDCD6 '+item.title;\n      btn.setAttribute('data-novel-url',item.href);\n\n      btn.onclick=(function(h,t){\n        return function(e){\n          if(e){\n            if(e.preventDefault)e.preventDefault();\n            if(e.stopPropagation)e.stopPropagation();\n          }\n\n          showNovelModal(t,'<div class=\"novel-loading\">加载中...<\/div>');\n\n          fetchNovelGbk(h).then(function(raw){\n            var content=cleanNovelHtml(raw);\n            var body=document.querySelector('.novel-modal-body');\n            if(body)body.textContent=content;\n          });\n        };\n      })(item.href,item.title);\n\n      frag.appendChild(btn);\n      frag.appendChild(document.createElement('br'));\n    }\n\n    if(textNode.parentNode){\n      textNode.parentNode.replaceChild(frag,textNode);\n    }\n  }\n}\n\nif(document.readyState==='complete'){\n  setTimeout(initNovelButtons,600);\n}else{\n  window.addEventListener('load',function(){\n    setTimeout(initNovelButtons,600);\n  });\n}\nif(document.readyState==='complete'){setTimeout(initNovelButtons,600);}\nelse{window.addEventListener('load',function(){setTimeout(initNovelButtons,600);});}\n\n\/\/ ====E批补充覆盖:需求1(收藏\/点评\/回复假成功修复)+需求3(附件按钮)====\nfunction __tip(t,e){var n;try{n=document.querySelector(\".tip\")}catch(x){n=null}if(n&&n.remove)n.remove();var r=document.createElement(\"div\");r.className=\"tip \"+(e||\"\");r.textContent=t;try{document.body.appendChild(r)}catch(x){}\nsetTimeout(function(){try{r.remove()}catch(x){}},3000);}\nfunction __abs(p){var b=location.href.match(\/^https?:\\\/\\\/[^\/]+\/);return (b?b[0]:\"\")+\"\/\"+String(p||\"\").replace(\/^\\\/\/,\"\");}\nfunction __g(re,src,d){try{var m=String(src||\"\").match(re);return m&&m[1]?m[1]:d}catch(e){return d}}\nfunction __vig(t){var e=String(t||\"\"),n=e.match(\/<!\\[CDATA\\[([\\s\\S]*?)\\]\\]>\/),r=n?n[1]:e;if(\/请先登录|需要登录|您还未登录|登录后才能|mod=logging\/.test(e))return {ok:false,msg:\"需要先登录(订阅源→登录)\"};if(\/System Error|非法字符|已经被系统拒绝\/.test(e))return {ok:false,msg:\"服务器拒绝(站点防护)\"};if(\/抱歉[，,]\/.test(e)){var a=e.match(\/抱歉[，,]([^。！!]{0,60})\/);return {ok:false,msg:a?\"抱歉，\"+a[1]:\"失败：\"+e.slice(0,60)}}if(\/无权|没有权限|权限不足\/.test(r))return {ok:false,msg:\"没有权限\"};if(\/succeedhandle|succeed|success|成功\/i.test(e))return {ok:true,msg:\"操作成功\"};if(!String(e||\"\").trim())return {ok:false,msg:\"服务器无响应(可能未登录或请求被拦截)\"};return {ok:false,msg:\"操作未确认成功\",raw:e.slice(0,60)};}\nfunction __post(url,body,okFn,failFn){fetch(url,{method:\"POST\",body:body,credentials:\"include\",headers:{\"Content-Type\":\"application\/x-www-form-urlencoded\"}}).then(function(a){return a.text()}).then(function(a){var r=__vig(a);r.ok?(okFn&&okFn(a,r)):(__tip(\"✘ \"+r.msg,\"no\"),failFn&&failFn(a,r))},function(){__tip(\"✘ 网络错误\",\"no\");failFn&&failFn(null,null)});}\nfunction __params(){var h=(document.documentElement?document.documentElement.innerHTML:\"\")+\" \"+location.href;var t=__g(\/tid=(\\d+)\/,h,\"\"),f=__g(\/fid=(\\d+)\/,h,\"\")||\"2\",fh=__g(\/formhash['\"':]?\\s*[:=]\\s*['\"]?([a-f0-9]{8})\/,h,\"\");return {tid:t,fid:f,formhash:fh};}\nfunction __pid(){try{var l=document.querySelectorAll('.plc[id^=\"pid\"]');if(l&&l.length)return l[0].id.replace(\/^pid\/,\"\")}catch(e){}try{var m=document.documentElement.innerHTML.match(\/class=\"plc[^\"]*\" id=\"pid(\\d+)\"\/);return m?m[1]:null}catch(e){}return null;}\nvar __MyFav=function(){var p=__params();if(!p.formhash){__tip(\"✘ 缺少 formhash：未登录或页面未就绪\",\"no\");return}__tip(\"发送中…\",\"wait\");__post(__abs(\"home.php?mod=spacecp&ac=favorite&type=thread&id=\"+p.tid+\"&mobile=2&inajax=1\"),\"favoritesubmit=true&formhash=\"+p.formhash,function(){__tip(\"✔ 收藏成功\",\"ok\")});};\nvar __MyCmt=function(){var c,tt;try{c=document.getElementById(\"ci\")}catch(x){c=null}tt=c?c.value.trim():\"\";if(!tt){__tip(\"✘ 请输入点评内容\",\"no\");return}var p=__params();if(!p.formhash){__tip(\"✘ 缺少 formhash\",\"no\");return}var tgt;try{tgt=(typeof window.Ht!==\"undefined\")?window.Ht:null}catch(x){tgt=null}__tip(\"发送中…\",\"wait\");__post(__abs(\"forum.php?mod=misc&action=comment&tid=\"+p.tid+\"&pid=\"+(tgt||\"0\")+\"&mobile=2&inajax=1\"),\"message=\"+encodeURIComponent(tt)+\"&formhash=\"+p.formhash,function(){__tip(\"✔ 点评成功\",\"ok\");try{if(typeof window.closeCmt===\"function\")window.closeCmt()}catch(x){}});};\nvar __MyReply=function(){var el,tt;try{el=document.getElementById(\"ri\")}catch(x){el=null}tt=el?el.value.trim():\"\";if(!tt){__tip(\"✘ 请输入内容\",\"no\");return}var p=__params();if(!p.formhash){__tip(\"✘ 缺少 formhash\",\"no\");return}var tgt;try{tgt=(typeof window.Ht!==\"undefined\")?window.Ht:null}catch(x){tgt=null}__tip(\"发送中…\",\"wait\");__post(__abs(\"forum.php?mod=post&action=reply&fid=\"+p.fid+\"&tid=\"+p.tid+(tgt?\"&reppost=\"+tgt:\"\")+\"&mobile=2&inajax=1\"),\"message=\"+encodeURIComponent(tt)+\"&formhash=\"+p.formhash+\"&replysubmit=yes\",function(){if(el)el.value=\"\";try{if(typeof window.Ht!==\"undefined\")window.Ht=null}catch(x){}__tip(\"✔ 回复成功\",\"ok\")});};\nvar __MyAttach=function(){var msg=\"不支持本地上传，请从右上角打开外置浏览器再上传附件图片\";var ov=document.createElement('div');ov.style.cssText='position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,.6);z-index:99999;display:flex;align-items:center;justify-content:center;';var box=document.createElement('div');box.style.cssText='background:#fff;border-radius:12px;padding:30px 26px;max-width:82%;text-align:center;box-shadow:0 6px 24px rgba(0,0,0,.3);color:#333;';var t=document.createElement('div');t.style.cssText='font-size:22px;line-height:1.6;font-weight:700;white-space:pre-line;';t.textContent=msg;var ok=document.createElement('button');ok.style.cssText='margin-top:22px;padding:10px 36px;background:#1890ff;color:#fff;border:none;border-radius:6px;font-size:16px;';ok.textContent='知道了';ok.onclick=function(){ov.remove();};box.appendChild(t);box.appendChild(ok);ov.appendChild(box);ov.onclick=function(e){if(e.target===ov)ov.remove();};document.body.appendChild(ov);};\nvar __MyEdit=function(){var pid;try{pid=window.Cn}catch(x){pid=null}if(!pid){__tip(\"✘ 无目标楼层\",\"no\");return}var t;try{t=document.getElementById(\"ei\").value.trim()}catch(x){t=\"\"}if(!t){__tip(\"✘ 内容不能为空\",\"no\");return}var p=__params();if(!p.formhash){__tip(\"✘ 缺少 formhash\",\"no\");return}__tip(\"保存中…\",\"wait\");var s=\"\";try{s=(document.getElementById(\"et\").value||\"\").trim()}catch(x){}var isFirst=(String(pid)===String(p.tid));if(!s&&isFirst){try{var h=document.querySelector(\".tt\");if(h&&h.textContent){s=h.textContent.trim()}}catch(x){}if(!s){try{s=(document.title||\"\").replace(\/\\s+[-_|–—]\\s*[^\\-_|–—]*$\/,\"\").trim()}catch(x){}}}var edbody=\"message=\"+encodeURIComponent(t)+\"&formhash=\"+p.formhash+\"&editsubmit=yes\";if(s){edbody+=\"&subject=\"+encodeURIComponent(s)}__post(__abs(\"forum.php?mod=post&action=edit&tid=\"+p.tid+\"&pid=\"+pid+\"&mobile=2&inajax=1\"),edbody,function(){__tip(\"✔ 已保存\",\"ok\");try{if(typeof window.closeEditM===\"function\")window.closeEditM()}catch(x){}try{if(typeof window.nav===\"function\")window.nav(location.href)}catch(x){}});};\n(function(){function R(){window.doFav=__MyFav;window.submitCmt=__MyCmt;window.sendReply=__MyReply;window.attachDlg=__MyAttach;window.submitEdit=__MyEdit;}R();setTimeout(R,300);setTimeout(R,800);setTimeout(R,1600);})();\n\/* 双保险：编辑页自定义提交（接管原生 mod=post&action=edit） *\/\n(function(){\n  function initEdit(){\n    var box=document.getElementById('webrecon_edit');\n    if(!box) return;\n    var et=document.getElementById('et'), ei=document.getElementById('ei'), btn=document.getElementById('wr_submit');\n    if(!et||!ei||!btn) return;\n    btn.addEventListener('click', function(){\n      var t=String(ei.value||'').trim();\n      if(!t){ __tip('✘ 内容不能为空','no'); return; }\n      var s=String(et.value||'').trim();\n      var tid=box.getAttribute('data-tid'), pid=box.getAttribute('data-pid'), fh=box.getAttribute('data-formhash');\n      if(!s && String(pid)==String(tid)){ s=(document.title||'').replace(\/[\\s_\\-–|].*$\/,'').trim(); }\n      var p=new URLSearchParams();\n      var hs=box.parentNode?box.parentNode.querySelectorAll('input[type=hidden]'):[];\n      for(var i=0;i<hs.length;i++){ if(hs[i].name) p.append(hs[i].name, hs[i].value); }\n      p.set('subject', s); p.set('message', t); p.set('formhash', fh); p.set('editsubmit','yes'); p.set('inajax','1');\n      __tip('保存中…','');\n      __post(box.getAttribute('data-action'), p.toString(), function(a,r){ __tip('✔ 已保存','ok'); setTimeout(function(){ try{ if(history.length>1) history.back(); else location.reload(); }catch(e){ location.reload(); } }, 800); }, function(){ __tip('✘ 保存失败','no'); });\n    });\n  }\n  if(typeof document!=='undefined'){ if(document.readyState!=='loading') initEdit(); else document.addEventListener('DOMContentLoaded', initEdit); }\n})();\n})();\n","lastUpdateTime":1788193970216,"loadWithBaseUrl":true,"loginUrl":"https:\/\/bbs.xiaoxiaoshuo8.com\/member.php?mod=logging&action=login&mobile=2","preload":false,"preloadJs":"var _x8=1;try{window.java=java;window.source=source;window.cache=cache;window.ajaxAwait=ajaxAwait;}catch(e){}","ruleArticles":"@js:\n(function(){\n  \/* v58: 原来这里会同步 java.ajax 请求一次【电脑版】列表页(mobile=no, 54KB \/ TTFB 1.4s)\n     去抓「最后发表」再回填 data-last。该字段已整体删除, 这个请求也就没必要了。\n     ★ 它还是【同步阻塞】的: 每次从门户页点进帖子, 都要干等这个慢请求回来才出目录,\n       慢或超时就表现为「进不去详情页 \/ 卡在加载中几十秒 \/ 日志不报错」。 *\/\n  var body=String(result||'');\n  try{ java.setContent(body, baseUrl); }catch(e){}\n  return java.getElements('class.murl||class.list');\n})()","ruleContent":"@js:\n(function(){\ntry{\n\nfunction wnEsc(t){return String(t==null?'':t).replace(\/&\/g,'&amp;').replace(\/<\/g,'&lt;').replace(\/>\/g,'&gt;').replace(\/\"\/g,'&quot;');}\nfunction isWebnoteUrl(u){u=String(u||'');return \/webnote\\.cc\\\/p\\\/[A-Za-z0-9]+\/i.test(u);}\nfunction webnotePage(src,url){\n  var u=String(url||''),sm=String(src||''),m=u.match(\/webnote\\.cc\\\/p\\\/([A-Za-z0-9]+)(?:@([^?#\\\/]*))?\/i);\n  if(!m)m=sm.match(\/webnote\\.cc\\\/p\\\/([A-Za-z0-9]+)(?:@([^?#\\\/]*))?\/i);\n  var id='',pwd='';\n  if(m){id=m[1]||'';try{pwd=decodeURIComponent(m[2]||'')}catch(e){pwd=m[2]||''}}\n  if(!id){return '<div class=\"card post\"><h2 class=\"tt\">云便签<\/h2><div class=\"msg\">无法识别的便签地址<\/div><\/div>';}\n  \/* 1) rhino 端 java.ajax 预取(网络栈可用则直接内嵌正文) *\/\n  var preTxt='';\n  try{\n    if(typeof java!=='undefined'&&java&&typeof java.ajax==='function'){\n      var api='https:\/\/api-webnote.txttool.cn\/netcut\/note\/info\/';\n      var apiBody='note_id='+id+'&note_pwd='+encodeURIComponent(pwd);\n      var jr=java.ajax(api,{method:'POST',body:apiBody,headers:{\n        'Content-Type':'application\/x-www-form-urlencoded; charset=UTF-8',\n        'Origin':'https:\/\/webnote.cc','Referer':u,\n        'Accept':'application\/json, text\/javascript, *\/*; q=0.01',\n        'X-Requested-With':'XMLHttpRequest'}});\n      var jo=(typeof jr==='string')?JSON.parse(jr):jr;\n      if(jo&&jo.status===1&&jo.data)preTxt=jo.data.note_content||'';\n    }\n  }catch(e){preTxt='';}\n  \/* 把 note_content([{title,content}]) 拼成 主楼层标题+正文 *\/\n  function blocksToHtml(txt){\n    try{\n      var arr=JSON.parse(txt||'[]'),tt='',cc='',i;\n      for(i=0;i<arr.length;i++){if(i===0)tt=arr[i].title||'';if(arr[i].content)cc+=(cc?'\\n\\n':'')+arr[i].content;}\n      return '<h2 class=\"tt\">'+wnEsc(tt)+'<\/h2><div class=\"msg\">'+wnEsc(cc)+'<\/div>';\n    }catch(e){return '';}\n  }\n  var pbody=preTxt?blocksToHtml(preTxt):'';\n  var css=':root{--bg:#F4F5F9;--postbg:#FFFFFF;--posttx:#2B2D42;--postbdw:1px;--postbdc:#E4E7F0;--postsh:none;--rd:14px;--fs:15px;--lh:1.65;--gap:8px;--tttx:#1F2430;--ttfs:20px;--ttfw:700;--ttlh:1.35;--ttgap:8px;--msggapt:8px;--metatx:#8A8FA8}';\n  var html='<!DOCTYPE html><html lang=\"zh-CN\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">'\n    +'<style>'+css+'html,body{margin:0;background:var(--bg);color:var(--posttx);font-family:-apple-system,\"PingFang SC\",\"Microsoft YaHei\",Roboto,sans-serif;font-size:var(--fs);line-height:var(--lh)}'\n    +'#app{max-width:760px;margin:0 auto;padding:12px 10px}.card.post{background:var(--postbg);border:var(--postbdw) solid var(--postbdc);box-shadow:var(--postsh);border-radius:var(--rd);padding:14px 12px;margin-top:6px;overflow-wrap:break-word;word-break:break-word}'\n    +'.card.post .tt{font-size:var(--ttfs);font-weight:var(--ttfw);line-height:var(--ttlh);color:var(--tttx);margin:0 0 var(--ttgap)}'\n    +'.card.post .msg{white-space:pre-wrap;color:var(--posttx);margin-top:var(--msggapt)}'\n    +'.wnbadge{font-size:12px;color:var(--metatx,#8A8FA8);padding:2px 2px 6px;letter-spacing:.3px}'\n    +'<\/style><\/head><body><div id=\"app\"><div class=\"wnbadge\">🔔 webnote 便签 · 书源解析<\/div><div class=\"card post\" id=\"wnpost\"'+(pbody?' data-loaded=\"1\"':'')+'>'\n    +(pbody?pbody:'<h2 class=\"tt\">云便签<\/h2><div class=\"msg\" id=\"wnL\">正在获取便签内容…(v2)<\/div>')\n    +'<\/div><\/div>'\n    +'<script>(function(){var id=\"'+id.replace(\/\"\/g,'')+'\",pwd='+JSON.stringify(pwd)+';'\n    +'function esc(t){return String(t==null?\"\":t).replace(\/&\/g,\"&amp;\").replace(\/<\/g,\"&lt;\").replace(\/>\/g,\"&gt;\");}'\n    +'try{var p=document.getElementById(\"wnpost\");if(!p||p.getAttribute(\"data-loaded\")===\"1\")return;}catch(x){return;}'\n    +'var ac=(typeof AbortController!==\"undefined\")?new AbortController():null;var to=ac?setTimeout(function(){ac.abort();},8000):0;'\n    +'fetch(\"https:\/\/api-webnote.txttool.cn\/netcut\/note\/info\/\",{method:\"POST\",headers:{\"Content-Type\":\"application\/x-www-form-urlencoded; charset=UTF-8\",\"Origin\":\"https:\/\/webnote.cc\",\"Accept\":\"application\/json\",\"X-Requested-With\":\"XMLHttpRequest\"},body:\"note_id=\"+encodeURIComponent(id)+\"&note_pwd=\"+encodeURIComponent(pwd),signal:ac?ac.signal:undefined})'\n    +'.then(function(r){if(to)clearTimeout(to);return r.json();}).then(function(d){'\n    +'if(!d||d.status!==1)throw new Error(\"api_bad\");'\n    +'var arr=JSON.parse(d.data.note_content||\"[]\"),tt=\"\",cc=\"\",i;'\n    +'for(i=0;i<arr.length;i++){if(i===0)tt=arr[i].title||\"\";if(arr[i].content)cc+=(cc?\"\\\\n\\\\n\":\"\")+arr[i].content;}'\n    +'var p=document.getElementById(\"wnpost\");if(!p)return;'\n    +'p.innerHTML=\\'<h2 class=\"tt\">\\'+esc(tt)+\\'<\/h2><div class=\"msg\">\\'+esc(cc)+\\'<\/div>\\';'\n    +'p.setAttribute(\"data-loaded\",\"1\");'\n    +'}).catch(function(e){var el=document.getElementById(\"wnL\");if(!el)return;if(to)clearTimeout(to);var nm=(e&&e.name)||\"\";el.textContent=(nm===\"AbortError\")?\"⏱ 请求超时(8s)：网络或风控拦截。可复制链接到系统浏览器打开。\":(nm===\"TypeError\")?\"⚠️ 网络\/跨域被拦(TypeError)。可复制链接到系统浏览器打开。\":((e&&e.message===\"api_bad\")?\"❌ 服务器返回失败：密钥错误或已失效。\":\"❌ \"+(e&&e.message||\"获取失败\")+\"。可复制链接到系统浏览器打开。\");});'\n    +'})();'+'<'+'\/script>'\n    +'<\/body><\/html>';\n  return html;\n}\nfunction isEditPage(u){return String(u||'').indexOf('mod=post')>=0&&String(u||'').indexOf('action=edit')>=0;}\nfunction buildEditPage(src,url){\n  var s=String(src||'');\n  function attr(re){var m=String(s).match(re);return m?m[1]:'';}\n  var formhash=attr(\/name=\"formhash\"[^>]*value=\"([^\"]*)\"\/i)||attr(\/formhash=([a-f0-9]+)\/i);\n  var subject=attr(\/<input[^>]+name=\"subject\"[^>]*value=\"([^\"]*)\"\/i)||attr(\/<input[^>]+value=\"([^\"]*)\"[^>]*name=\"subject\"[^>]*>\/i);\n  var mm=String(s).match(\/<textarea[^>]+name=\"message\"[^>]*>([\\s\\S]*?)<\\\/textarea>\/i);\n  var message=mm?mm[1]:'';\n  function qp(p){var m=String(url).match(new RegExp('[?&]'+p+'=([^&]+)'));return m?decodeURIComponent(m[1]):'';}\n  var tid=qp('tid'),pid=qp('pid'),fid=qp('fid');\n  function dec(t){return String(t==null?'':t).replace(\/&lt;\/g,'<').replace(\/&gt;\/g,'>').replace(\/&quot;\/g,'\"').replace(\/&#39;\/g,\"'\").replace(\/&amp;\/g,'&');}\n  function esc(t){return String(t==null?'':t).replace(\/&\/g,'&amp;').replace(\/<\/g,'&lt;').replace(\/>\/g,'&gt;').replace(\/\"\/g,'&quot;');}\n  var fa=attr(\/<form[^>]+action=\"([^\"]*)\"\/i);\n  var action=fa?(fa+(fa.indexOf('?')>=0?'&':'?')+'inajax=1'):('forum.php?mod=post&action=edit&tid='+esc(tid)+'&pid='+esc(pid)+'&fid='+esc(fid)+'&mobile=2&inajax=1');\n  var hiddens='';\n  var re=\/<(input|textarea|select)[^>]+name=\"([^\"]+)\"[^>]*>\/gi,x;\n  while((x=re.exec(s))){\n    var tag=x[1].toLowerCase(),nm=x[2];\n    if(nm==='subject'||nm==='message'||nm==='formhash')continue;\n    var v=tag==='textarea'?'':(x[0].match(\/value=\"([^\"]*)\"\/i)?RegExp.$1:'');\n    hiddens+='<input type=\"hidden\" name=\"'+esc(dec(nm))+'\" value=\"'+esc(dec(v))+'\">';\n  }\n  hiddens+='<input type=\"hidden\" name=\"formhash\" value=\"'+esc(dec(formhash))+'\">';\n  return '<!DOCTYPE html><html><head><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"><title>编辑帖子<\/title><\/head>'+\n    '<body style=\"margin:0;padding:12px;background:#fff;color:#2B2D42;font-size:15px\">'+\n    '<div id=\"webrecon_edit\" data-tid=\"'+esc(tid)+'\" data-pid=\"'+esc(pid)+'\" data-fid=\"'+esc(fid)+'\" data-formhash=\"'+esc(dec(formhash))+'\" data-action=\"'+esc(dec(action))+'\" style=\"display:none\"><\/div>'+\n    '<h3 style=\"margin:0 0 10px;font-size:17px\">编辑帖子 <small style=\"color:#8A8FA8;font-weight:400\">· 书源编辑模式<\/small><\/h3>'+\n    '<label style=\"display:block;margin:8px 0 4px;color:#5A5F73;font-size:13px\">标题<\/label>'+\n    '<input id=\"et\" type=\"text\" value=\"'+esc(dec(subject))+'\" style=\"width:100%;padding:10px;border:1px solid #E4E7F0;border-radius:10px;font-size:15px;box-sizing:border-box\">'+\n    '<label style=\"display:block;margin:12px 0 4px;color:#5A5F73;font-size:13px\">正文<\/label>'+\n    '<textarea id=\"ei\" style=\"width:100%;height:52vh;padding:10px;border:1px solid #E4E7F0;border-radius:10px;font-size:15px;box-sizing:border-box;line-height:1.6\">'+esc(dec(message))+'<\/textarea>'+\n    hiddens+\n    '<div id=\"wr_tip\" style=\"margin:10px 0;min-height:18px;font-size:13px\"><\/div>'+\n    '<button id=\"wr_submit\" type=\"button\" style=\"width:100%;padding:12px;background:#F1F2F7;color:#3D4256;border:1px solid #E4E7F0;border-radius:10px;font-size:15px\">保存并发布<\/button>'+\n    '<\/body><\/html>';\n}\nif(isWebnoteUrl(baseUrl)){return webnotePage(result,baseUrl);}\nif(isEditPage(baseUrl)){return buildEditPage(result,baseUrl);}\nvar html=result;\nif(!html||String(html).indexOf('<')<0){try{html=java.ajax(baseUrl);}catch(e){html='';}}\nhtml=String(html).replace(\/&\/g,'&amp;').replace(\/<\/g,'&lt;').replace(\/>\/g,'&gt;');\nvar cur=String(baseUrl).replace(\/\\\"\/g,'&quot;');\nvar CSS=\"\\n*{margin:0;padding:0;box-sizing:border-box;-webkit-tap-highlight-color:transparent}\\n:root{\\n --postbg:#FFFFFF;--replybg:#FFFFFF;--posttx:#2B2D42;--replytx:#2B2D42;--metatx:#8A8FA8;\\n --gap:8px;--fs:15px;--lh:1.65;--fw:400;--ls:0px;--rd:14px;\\n --postbdw:1px;--postbdc:#E4E7F0;--postsh:none;\\n --replybdw:1px;--replybdc:#E4E7F0;--replysh:none;\\n --imgw:50%;--imgh:120px;--imgfit:cover;--imgrd:10px;--imggap:6px;--imgfx:50%;--imgfy:50%;\\n --btnbg:#F1F2F7;--btntx:#5A5F73;--btnbdw:1px;--btnbdc:#E4E7F0;--btnsh:none;--btnrd:10px;\\n --btnfs:13px;--btnpad:10px;\\n --qbg:#F1F2F7;--qtx:#5A5F73;--qbdw:1px;--qbdc:#E4E7F0;--qrd:10px;--qfs:13px;--qlh:1.6;--qpad:9px;--qsh:none;\\n --mbg:#FFFFFF;--mtx:#2B2D42;--catbg:#F1F2F7;--sechbg:#F1F2F7;--lbtx:#5A5F73;--hdtx:#3D4256;\\n --posttxsh:none;--replytxsh:none;\\n --ttfs:20px;--ttfw:700;--ttlh:1.35;--ttls:0px;--tttx:#1F2430;\\n --hintfs:11px;--hinttx:#8A8FA8;--hintls:0px;--hintlh:1.55;--hintsh:none;\\n --fabbdw:1px;--fabbdc:#E4E7F0;--fabsh:0 3px 10px rgba(0,0,0,.18);--fabr:50px;--fabsz:48px;--fabx:14px;--faby:68px;\\n--fabbgimg:none;--fabbgcol:#F1F2F7;--fabbgsz:cover;--fabbgpx:50%;--fabbgpy:50%;\\n--frm:50%;--avm:50%;\\n--opnfs:14px;--opnfw:600;--opnit:normal;--opntx:#2B2D42;--opnsh:none;--opnrb:none;\\n--rnfs:14px;--rnfw:600;--rnit:normal;--rntx:#2B2D42;--rnsh:none;--rnrb:none;\\n --rpt:12px;--rpr:12px;--rpb:12px;--rpl:12px;\\n \/* 底部分页栏(上一页\/页码\/下一页) + 页码选择格子: 独立于通用按钮配色 *\/\\n --pgbg:#F1F2F7;--pgtx:#5A5F73;--pgbdw:1px;--pgbdc:#E4E7F0;--pgrd:10px;--pgfs:13px;\\n --pgonbg:#FF6B9D;--pgontx:#FFFFFF;\\n --hdgap:8px;--qgapt:8px;--qgapb:10px;--msggapt:8px;--ttgap:8px;\\n --edbg:#7C6BD9;--edtx:#FFFFFF;--edbdw:0px;--edbdc:#E4E7F0;--edrd:8px;--edfs:12px;\\n --avscale:1;--avfx:0px;--avfy:0px;--frscale:1;--frfx:0px;--frfy:0px;\\n \/* 头像外框: 与「悬浮设置按钮 · 按钮背景图」同一套参数模型 *\/\\n --frsz:100%;--frbx:50%;--frby:50%;--frimg:none;\\n --bd:#E4E7F0;--bg:#F4F5F9;--pk:#FF6B9D;--pu:#7C6BD9;--chip:#F1F2F7;--sub:#8A8FA8;\\n}\\n\/* color-scheme: light only 告知 WebView 本页自带浅色主题,\\n   阻止 Android 算法反色把黑字反成白字(而白底不变黑) 导致的白底白字。*\/\\n:root{color-scheme:light only;supported-color-schemes:light only}\\nhtml{background:var(--bg)}\\nbody{background:transparent;color:var(--posttx);font:var(--fw) var(--fs)\/var(--lh) -apple-system,BlinkMacSystemFont,\\\"Segoe UI\\\",Roboto,sans-serif;letter-spacing:var(--ls);padding:10px;min-height:100vh}\\n#bgimg{position:fixed;left:0;top:0;width:100%;height:100%;z-index:0;display:none}\\n.wrap{position:relative;z-index:1;max-width:640px;margin:0 auto}\\n\/* ★ 首屏提速: 屏幕外的帖子卡片跳过渲染(滚动到时才渲染)。\\n   帖子常含 60 层楼, 全量布局会显著拖慢首次打开。\\n   contain-intrinsic-size 提供占位高度, 避免未渲染区域高度为 0 导致滚动条跳动。\\n   不支持的 WebView 会忽略这两条, 自动退化成全量渲染(无副作用)。 *\/\\n.card{background:var(--postbg);border:var(--postbdw) solid var(--postbdc);border-radius:var(--rd);padding:14px;margin-bottom:10px;box-shadow:var(--postsh);\\n content-visibility:auto;contain-intrinsic-size:auto 260px}\\n.card.post{color:var(--posttx);text-shadow:var(--posttxsh)}\\n.card.reply{background:var(--replybg);color:var(--replytx);text-shadow:var(--replytxsh);\\n padding:var(--rpt) var(--rpr) var(--rpb) var(--rpl);margin-bottom:var(--gap);position:relative;border:var(--replybdw) solid var(--replybdc);box-shadow:var(--replysh)}\\n.hd{display:flex;align-items:center;gap:10px;margin-bottom:var(--hdgap)}\\n.avw{position:relative;flex:none;display:flex;align-items:center;justify-content:center;isolation:isolate}\\n\/* 外框图层遮罩: border-radius 限制该图层的可见形状。\\n   --frm:50% = 圆形遮罩(与圆形头像同形); 0 = 方形; 中间值 = 圆角方形。\\n   配合背景尺寸 var(--frsz) 让图片填满遮罩区域而不留空。*\/\\n\/* ★ 头像外框图改用【背景绘制】(与「悬浮设置按钮 · 按钮背景图」同构):\\n     --frsz  = cover 填充裁切 \/ contain 完整显示 \/ 手动缩放百分比\\n     --frbx, --frby = 手动缩放模式下的焦点 X \/ Y\\n   为什么不用 <img>+object-fit:\\n     ① object-fit 只有 cover\/contain\/fill 等固定行为, 无法表达\\n        \\\"按百分比自由缩放 + 自由指定焦点\\\" —— 那是 background-size \/ background-position 的能力;\\n     ② 背景的尺寸与位置变化【不改变元素自身占位】, 因此 .avw 容器尺寸恒定不变,\\n        外框图只在容器内部缩放与平移, 超出容器的部分被自然裁掉;\\n        若用 <img> 缩放, 一放大就会撑开或溢出容器, 带动整行布局变化。 *\/\\n.avf{position:absolute;left:50%;top:50%;width:100%;height:100%;pointer-events:none;\\n border-radius:var(--frm);\\n background-image:var(--frimg);background-repeat:no-repeat;\\n background-size:var(--frsz);background-position:var(--frbx) var(--frby);\\n transform:translate(calc(-50% + var(--frfx)),calc(-50% + var(--frfy))) scale(var(--frscale))}\\n.avf.under{z-index:0}\\n.avf.over{z-index:2}\\n\/* 头像图层遮罩: --avm:50% = 圆形(默认) *\/\\n.avi{position:relative;z-index:1;border-radius:var(--avm);object-fit:cover;background:var(--chip);border:none;\\n transform:translate(var(--avfx),var(--avfy)) scale(var(--avscale))}\\n.who{flex:1;min-width:0}\\n\/* 用户名独立字体样式: 与正文\/回复内容解耦(不再用 calc(--fs) \/ color:inherit) *\/\\n.un{display:inline-block;max-width:100%;transform:translate(var(--unx),var(--uny))}\\n\/* v55 头像旁元素 XY 坐标位移: 用 transform 位移而不改 position, 原占位保留, 下方正文不会被顶动。\\n   ★ transform 对 display:inline 元素无效, 故这几类必须改成 inline-block。*\/\\n.fl{display:inline-block;transform:translate(var(--flx),var(--fly))}\\n.tm{display:inline-block;transform:translate(var(--tmx),var(--tmy))}\\n.vw{display:inline-block;transform:translate(var(--vwx),var(--vwy))}\\n.rp{display:inline-block;transform:translate(var(--rpx),var(--rpy))}\\n.post .un{font-size:var(--opnfs);font-weight:var(--opnfw);font-style:var(--opnit);\\n color:var(--opntx);text-shadow:var(--opnsh)}\\n.reply .un{font-size:var(--rnfs);font-weight:var(--rnfw);font-style:var(--rnit);\\n color:var(--rntx);text-shadow:var(--rnsh)}\\n\/* 彩虹多层次渐变: background-clip:text 实现文字渐变 *\/\\n.post .un.rb{background-image:var(--opnrb);-webkit-background-clip:text;background-clip:text;\\n color:transparent!important;-webkit-text-fill-color:transparent;text-shadow:none}\\n.reply .un.rb{background-image:var(--rnrb);-webkit-background-clip:text;background-clip:text;\\n color:transparent!important;-webkit-text-fill-color:transparent;text-shadow:none}\\n\/* 彩虹模式下父元素 -webkit-text-fill-color 会被子元素继承, 徽章需恢复实色 *\/\\n.un.rb .tag{-webkit-text-fill-color:#fff;color:#fff!important}\\n.who b{font-size:calc(var(--fs) - 1px);color:inherit}\\n.tag{display:inline-block;padding:0 7px;border-radius:9px;font-size:10px;font-weight:600;margin-left:5px;color:#fff;background:var(--pk);vertical-align:1px}\\n.sub{font-size:11px;color:var(--sub)}\\n.meta{color:var(--metatx)!important}\\n.hdbtns{display:flex;gap:6px;flex:none}\\n\/* 外观设置: 绝对定位悬浮按钮, 下滑跟随 *\/\\n.fab{position:fixed;right:var(--fabx);bottom:var(--faby);z-index:70;width:var(--fabsz);height:var(--fabsz);\\n border-radius:var(--fabr);border:var(--fabbdw) solid var(--fabbdc);\\n background-color:var(--fabbgcol);background-image:var(--fabbgimg);\\n background-size:var(--fabbgsz);background-position:var(--fabbgpx) var(--fabbgpy);\\n background-repeat:no-repeat;\\n color:var(--btntx);font-size:21px;cursor:pointer;display:flex;align-items:center;justify-content:center;\\n box-shadow:var(--fabsh);touch-action:none;overflow:hidden}\\n.fab:active{transform:scale(.92)}\\n\/* 长按进入拖动模式: 放大并高亮, 提示用户可拖动 *\/\\n.fab.drag{transform:scale(1.18);opacity:.9;border-color:var(--pk)!important;\\n box-shadow:0 0 0 3px rgba(255,107,157,.35),var(--fabsh)}\\n.ib{width:30px;height:30px;border:1px solid var(--bd);border-radius:9px;background:var(--chip);color:#5A5F73;font-size:14px;cursor:pointer;flex:none;display:flex;align-items:center;justify-content:center}\\n.ib:active{opacity:.6}\\n.profrow{display:flex;align-items:center;gap:8px;margin-top:7px}\\n.profrow .bt{flex:1;min-width:0}\\n.stat{font-size:11px;margin-top:8px}\\n.tt{font-size:var(--ttfs);font-weight:var(--ttfw);color:var(--tttx);margin:6px 0 var(--ttgap);line-height:var(--ttlh);letter-spacing:var(--ttls)}\\n.msg{font-size:var(--fs);color:inherit;word-wrap:break-word;overflow-wrap:break-word;margin-top:var(--msggapt)}\\n\/* 兜底: 无论图片带 inline style \/ width 属性 \/ 布局脚本是否执行, 都强制受控不溢出 *\/\\n.msg img{max-width:100%!important;height:auto!important;max-height:var(--imgh)!important;\\n object-fit:var(--imgfit);border-radius:var(--imgrd);display:block;margin:5px 0}\\n.msg img[src*=\\\"smiley\\\"]{max-height:24px!important;width:auto!important;display:inline!important;vertical-align:-4px;margin:0 1px;border-radius:0}\\n\/* 图片网格: 宽度决定一行几列(优先级高于兜底) *\/\\n.imgrid{display:flex;flex-wrap:wrap;gap:var(--imggap);margin:8px 0;width:100%}\\n.imgrid img.zoom{flex:0 0 auto;width:calc(var(--imgw) - var(--imggap))!important;height:var(--imgh)!important;\\n object-fit:var(--imgfit)!important;object-position:var(--imgfx) var(--imgfy);border-radius:var(--imgrd);display:block;cursor:zoom-in;margin:0}\\n.imgrid.one img.zoom{width:100%!important;height:auto!important;max-height:var(--imgh)!important}\\n\/* v46: 图片去底色(取色变透明) + .json 书源\/订阅源一键导入按钮 *\/\\n.decbox{position:relative;display:block;max-width:100%;margin:5px 0}\\n.decbox img{display:block!important;margin:0!important;max-width:100%!important}\\n\/* v47: .imgrid 是 flex 网格, 图片被 .decbox 包裹后尺寸规则要转移到包裹层, 否则网格错位 *\/\\n.imgrid .decbox{flex:0 0 auto;width:calc(var(--imgw) - var(--imggap))!important;position:relative;display:block;margin:0}\\n.imgrid.one .decbox{width:100%!important}\\n.imgrid .decbox img{width:100%!important;height:var(--imgh)!important}\\n.imgrid.one .decbox img{height:auto!important;max-height:var(--imgh)!important}\\n.dec-ic{position:absolute;right:3px;bottom:3px;width:24px;height:24px;line-height:24px;text-align:center;font-size:12px;border-radius:50%;background:rgba(0,0,0,.55);color:#fff;cursor:pointer;z-index:5;-webkit-user-select:none;user-select:none}\\n.dec-hint{font-size:12px;color:var(--metatx);margin-bottom:8px}\\n\/* v48: 棋盘格背景 —— 透明区域直接显示为灰白格子, 否则纯色背景看不出哪里透明了 *\/\\n.dec-prev{border:1px solid var(--bd);border-radius:10px;overflow:hidden;text-align:center;min-height:100px;display:flex;align-items:center;justify-content:center;background-image:linear-gradient(45deg,#D8DBE3 25%,transparent 25%,transparent 75%,#D8DBE3 75%),linear-gradient(45deg,#D8DBE3 25%,transparent 25%,transparent 75%,#D8DBE3 75%);background-size:16px 16px;background-position:0 0,8px 8px;background-color:#fff}\\n.dec-prev img{max-width:100%;max-height:42vh;display:block;margin:0 auto;cursor:crosshair}\\n\/* v58 去底色: 模式按钮 \/ 覆盖层(框选与涂抹的画布) \/ 连续开关 *\/\\n.dec-modes{display:flex;gap:6px;margin:8px 0}\\n.dec-modes .bt{flex:1;padding:8px 4px;font-size:12px;white-space:nowrap}\\n.dec-modes .bt.on{background:var(--pk);color:#fff;border-color:var(--pk)}\\n.dec-ov{position:absolute;left:0;top:0;pointer-events:none;touch-action:none}\\n.dec-sw{display:flex;gap:6px;flex:1}\\n.dec-sw .msw{flex:1}\\n\/* v49: 预览区作为「视口」—— touch-action:none 交给 JS 处理手势, 否则 WebView\\n   会抢走双指做页面缩放; -webkit-user-drag 防原生图片拖拽干扰单指平移。 *\/\\n.dec-prev,.frdec-prev{position:relative;touch-action:none;-webkit-user-select:none;user-select:none}\\n.dec-prev img,.frdec-prev img{transform-origin:50% 50%;-webkit-user-drag:none;will-change:transform}\\n.zbar{display:flex;align-items:center;gap:8px;margin:10px 0 2px;font-size:12px;color:var(--metatx)}\\n.zbar input[type=range]{flex:1;min-width:0}\\n.zbar b{min-width:40px;text-align:right;color:#4A6CF7}\\n.zbar button{padding:3px 9px;font-size:12px;border:1px solid var(--bd);border-radius:6px;background:var(--chip);color:var(--btntx);cursor:pointer;flex:none}\\n.zbar button:active{opacity:.7}\\n.dec-tol{display:flex;align-items:center;gap:8px;margin:12px 0 6px;font-size:13px}\\n.dec-tol input[type=range]{flex:1}\\n.dec-tol b{min-width:28px;text-align:right;color:#4A6CF7}\\n.dec-btns{display:flex;flex-wrap:wrap;gap:8px;margin-top:10px}\\n.dec-btns .bt{flex:1;min-width:78px}\\n.imp-ic{display:inline-block;margin-left:8px;padding:3px 10px;font-size:12px;font-weight:600;color:#fff;background:#4A6CF7;border-radius:20px;cursor:pointer;vertical-align:middle;-webkit-user-select:none;user-select:none}\\n.imp-link{word-break:break-all}\\n.jmp-tx{word-break:break-all}\\n.jmp-ic{display:inline-block;margin-left:6px;padding:2px 9px;font-size:12px;font-weight:600;color:#fff;background:#4A6CF7;border-radius:20px;cursor:pointer;vertical-align:middle;-webkit-user-select:none;user-select:none}\\n.jmp-ic:active{opacity:.75}\\n\\n\/* 长按图片 = 复制链接(见 imgCopyInit), 需屏蔽系统\\\"保存图片\/识别\\\"菜单以免两者冲突 *\/\\n.msg img,.atico,.avi,.lbox img{-webkit-touch-callout:none}\\nblockquote,.quote{padding:var(--qpad) 12px;margin:var(--qgapt) 0 var(--qgapb);border:var(--qbdw) solid var(--qbdc);\\n border-radius:var(--qrd);font-size:var(--qfs);line-height:var(--qlh);color:var(--qtx);background:var(--qbg);\\n text-shadow:var(--qsh)}\\n.quote blockquote{padding:0;margin:0;border:none;background:transparent;border-radius:0;font-size:inherit;line-height:inherit;color:inherit}\\n\/* 论坛引用内常含 <font color=.. size=..> 与 <a>, 这些表现属性的优先级高于继承值,\\n   使 --qfs\/--qtx 传不进去(表现为: 仅部分引用碰巧受控, 其余不受控)。\\n   强制改为 inherit, 让任意来源的引用文本(含\\\"XX 发表于\\\"元信息行)全部受引用样式控制。 *\/\\nblockquote font,.quote font{font-size:inherit!important;color:inherit!important}\\nblockquote a,.quote a,blockquote a font,.quote a font{color:inherit!important;font-size:inherit!important}\\n\/* ★ 按钮行布局: v12 原文, 逐字未改。\\n   .row2 是 v24 新增的类名, v12 完全没有(计数 0); v36 已把全部 class=\\\"row2\\\" 改回 class=\\\"row\\\",\\n   使 HTML 结构与 v12 完全一致。教训: 已知可用的基线不要自作聪明重写。 *\/\\n\/* v12 原文(逐字未改) *\/\\n\/* ★ 按钮行布局: 用 table 布局(CSS2, Android 2 起全支持)。\\n   为什么不用 flex\/grid: 实测本 App 的 WebView 对 grid 完全无效\\n   (v37 把 .acts 回退成 grid 后立刻变成 3 行、按钮间距 0、边框重叠),\\n   而 flex 容器虽生效, gap 与 flex:1 的实测结果不稳定(表现为按钮按内容宽度收缩、\\n   「完成」很窄且换行)。table 布局不依赖 flex \/ grid \/ gap \/ flex:1 \/ calc() \/\\n   :nth-child \/ :first-child 中的任何一个。\\n   ★ table-layout:fixed + 不设子项宽度: 浏览器会把所有单元格【自动均分】,\\n     任意个数(2\/3\/8 个)都天然等宽, 因此完全不需要 :nth-child 之类去按数量设宽度。\\n   ★ display 用 !important: .bt{display:flex} 与本选择器同为 (0,1,0) 优先级,\\n     且它在文件更靠后, 不加 !important 会被它覆盖(按钮变回块级各占一行)。\\n   ★ 间隙用 border-spacing(表格原生属性, 支持极好) 而非 gap。 *\/\\n\/* ★ 按钮行布局: 用 float(CSS1)。\\n   为什么: 实测本 App 的 WebView ① grid 完全无效(v37 把 .acts 改回 grid 后立即\\n   变成 3 行、按钮间距 0、边框重叠); ② 更关键的是【button 元素的布局支持有缺陷】——\\n   试 table 布局时 .row>*{display:table-cell!important} 居然不生效, computed 仍是\\n   inline-block(实测 88 vs 36 不等宽)。旧 WebKit 对 button 作为 flex\/table 子项\\n   的支持都不完整, 按钮会退回内容宽度而非参与分配。\\n   故改用最古老的 float, 只依赖 float \/ width \/ margin \/ overflow, 支持到 CSS1:\\n   ★ float:left 保证横排(不依赖 flex\/grid\/inline-block 的空白间隙问题);\\n   ★ width:47% 保证等宽(不依赖 flex:1);\\n   ★ margin:0 1% 提供间隙(不依赖 gap);\\n   ★ 父容器 overflow:hidden 形成 BFC 清除浮动(不用 ::after 伪元素, 兼容性更稳)。\\n   ★ 总宽刻意留 2%~4% 余量: 2 列 = (47+2)x2 = 98%, 3 列 = (30+2)x3 = 96%,\\n     避免亚像素舍入导致最后一个被挤到下一行。 *\/\\n\/* v39: 面板 .mbox 是 overflow:auto(滚动条约 15px), 而按钮总宽若占满 98% 则滚动条\\n   一来就超宽换行 —— 实测容器 343px x 98% = 336px, 仅剩 7px 余量, 故被挤成两行;\\n   正文 .acts 容器 610px、总宽 96%、余量 24px, 所以不受影响(与用户观察一致)。\\n   v12 用的是 flex, 子项 flex:1 会【自动收缩】吸收滚动条占用的宽度, 因此不受影响 ——\\n   这正是 v12 在本 App 上正常的根本原因。故 .row 恢复 v12 的 flex 写法。 *\/\\n.row,.row2{display:flex;gap:8px;margin-top:9px}\\n.row .bt,.row2 .bt{flex:1;min-width:0}\\n\/* 正文 3 按钮: 30%+2% = 32%, 三个 96% *\/\\n.acts{display:block;overflow:visible;margin-top:12px}\\n.acts:after{content:'';display:block;clear:both}\\n.acts>*{float:left;width:32%;margin:0 1% 0 0;-webkit-box-sizing:border-box;box-sizing:border-box}\\n\\n\/* v40 兜底: 本 App 会往【可见】的按钮行注入 <font color=\\\"\\\" size=\\\"\\\"> 包裹层\\n   (诊断 [C] 实测: <font color=\\\"\\\" size=\\\"\\\"><button>恢复全部默认<\/button><button>完成<\/button><\/font>)。\\n   后果: font 成为 .row 的 flex item -> 被 blockify 成 block, 且自身不是 flex 容器,\\n   按钮的 flex:1(.row .bt 是后代选择器, 照样命中)无处生效 -> 退回内容宽度(实测 36px)。\\n   为何只有一行异常: 注入只作用于可见元素, 折叠分区(display:none)内的 15 个 .row 均未受影响,\\n   唯独底部这行在 endsec() 之后、始终可见 -> 中招。\\n   对策: 让 font 自身成为 flex 容器并 flex:1 撑满整行, 内部按钮继续按 .row .bt{flex:1} 等分。\\n   font 不存在时本规则不匹配, 行为与之前完全一致。 *\/\\n.row>font,.row2>font{display:flex;gap:8px;flex:1;min-width:0}\\n.acts>font{float:left;width:96%;overflow:visible}\\n.acts>font:after{content:'';display:block;clear:both}\\n.acts>font>*{float:left;width:32%;margin:0 1% 0 0;-webkit-box-sizing:border-box;box-sizing:border-box}\\n.bt{display:flex;align-items:center;justify-content:center;gap:4px;line-height:1;padding:var(--btnpad) 4px;\\n border:var(--btnbdw) solid var(--btnbdc);border-radius:var(--btnrd);background:var(--btnbg);\\n color:var(--btntx);font-size:var(--btnfs);font-weight:600;cursor:pointer;box-shadow:var(--btnsh);overflow:hidden}\\n.bt.pri{background-color:var(--pk);color:#fff}\\n\/* v48: 「还原\/清除」类操作要一眼可见 —— .bt 默认底色太淡, 实测看不出是个按钮 *\/\\n.bt.warn{background:#FFF1F0;color:#D4380D;border-color:#FFA39E}\\n.bt.warn:active{opacity:.7}\\n.bt:active{opacity:.7}\\n.tools{display:flex;gap:7px;margin-top:9px;flex-wrap:wrap;align-items:center}\\n.tb{padding:6px 12px;border:var(--btnbdw) solid var(--btnbdc);border-radius:calc(var(--btnrd) - 1px);\\n background:var(--btnbg);\\n color:var(--btntx);font-size:calc(var(--btnfs) - 1px);cursor:pointer;box-shadow:var(--btnsh)}\\n.tb:active{opacity:.6}\\n.tb.off{opacity:.4}\\n\/* 激活态: 「正序\/倒序」与「看全部」时高亮, 提示当前处于该视图且可再点一次切回 *\/\\n.tb.on{background:var(--pk);color:#fff;border-color:var(--pk)}\\n.ed{padding:5px 13px;border:var(--edbdw) solid var(--edbdc);border-radius:var(--edrd);\\n background:var(--edbg);color:var(--edtx);font-size:var(--edfs);font-weight:600;cursor:pointer}\\n.ed:active{opacity:.7}\\n.rtt{font-size:13px;font-weight:600;padding:4px 4px 8px}\\n\/* v54 点评框: 底色\/不透明度\/边框\/圆角\/内边距\/阴影 与 点评者名·时间·内容 三段字体 全部由外观设置下发 *\/\\n.cmt{margin-top:var(--cmtgap);padding:var(--cmtpad);border:var(--cmtbdw) solid var(--cmtbdc);\\n border-radius:var(--cmtrd);background:var(--cmtbg);color:var(--cmttx);\\n font-size:var(--cmtfs);line-height:var(--cmtlh);box-shadow:var(--cmtsh)}\\n.cmt b{color:var(--cmtntx);margin-right:5px;font-weight:600}\\n.cmt i{font-style:normal;font-size:calc(var(--cmtfs) - 1px);color:var(--cmtttx);margin-right:5px}\\n.cmt .ct{margin-top:3px;color:var(--cmtctx);font-size:var(--cmtcfs);line-height:var(--cmtclh)}\\n.pgbar{display:flex;align-items:center;justify-content:center;gap:9px;margin:12px 0 8px}\\n\/* ★ 分页栏内的「上一页\/下一页」用 .pgbar .tb 作用域覆盖, 不改全局 .tb,\\n     否则会连带改掉工具栏的「倒序\/只看楼主\/重载」三个按钮。 *\/\\n.pgbar .tb{background:var(--pgbg);color:var(--pgtx);\\n border:var(--pgbdw) solid var(--pgbdc);border-radius:var(--pgrd);font-size:var(--pgfs)}\\n\/* 页码: 中间页数文本可点击 -> 弹出下拉选择页码\\n   ★ color 必须 !important: 该按钮带 .meta 类, 而 .meta 用 !important 强制了颜色。 *\/\\n.pnum{display:inline-flex;align-items:center;gap:4px;padding:6px 11px;margin:0;\\n border:var(--pgbdw) solid var(--pgbdc);border-radius:var(--pgrd);\\n background:var(--pgbg);color:var(--pgtx)!important;font-size:var(--pgfs);font-weight:600;\\n cursor:pointer;box-shadow:var(--btnsh)}\\n.pnum:active{opacity:.6}\\n.pcar{font-style:normal;font-size:10px;opacity:.65}\\n\/* 页码下拉选择框 *\/\\n\/* 页码格子: 同样不依赖 flex(.pw 是 div, flex 失效时会退化成各占一整行) *\/\\n\/* 页码格子: 5 列。v12 的 .pregrid 即 grid 且实测正常, 故同样用 grid, 不再自创 inline-block *\/\\n.pggrid{display:grid;grid-template-columns:repeat(5,1fr);gap:7px;margin:10px 0 4px}\\n.pgn{box-sizing:border-box;padding:9px 0;border:var(--pgbdw) solid var(--pgbdc);border-radius:var(--pgrd);\\n background:var(--pgbg);color:var(--pgtx);font-size:var(--pgfs);font-weight:600;\\n cursor:pointer;box-shadow:var(--btnsh)}\\n.pgn.on{background:var(--pgonbg);color:var(--pgontx);border-color:var(--pgonbg)}\\n.pgn:active{opacity:.6}\\n.pginput{width:100%!important;margin-top:6px!important;padding:11px!important;font-size:15px!important}\\n.dock{position:sticky;bottom:0;z-index:60;display:flex;gap:8px;align-items:center;padding:9px 10px;\\n margin:10px -10px -10px;background:var(--dbg);border-top:var(--dbdw) solid var(--dbdc);border-radius:var(--drd) var(--drd) 0 0}\\n.slot{flex:1;padding:9px 14px;border:1px solid var(--bd);border-radius:18px;background:var(--chip);font-size:13px;color:#2B2D42;outline:none}\\n.slot:focus{border-color:var(--pk)}\\n.send{padding:9px 16px;border:none;border-radius:18px;background:var(--pk);color:#fff;font-size:13px;font-weight:600;cursor:pointer}\\n.send:active{opacity:.7}\\n.menu{position:absolute;right:10px;top:44px;background:#fff;border:1px solid var(--bd);border-radius:10px;padding:4px 0;z-index:20;min-width:120px}\\n.menu button{display:block;width:100%;text-align:left;padding:9px 14px;background:none;border:none;font-size:13px;color:#4E5364;cursor:pointer}\\n.menu button:active{background:var(--chip)}\\n.modal{display:none;position:fixed;left:0;top:0;right:0;bottom:0;background:rgba(43,45,66,.45);z-index:99;align-items:center;justify-content:center;padding:16px}\\n.modal.on{display:flex}\\n.mbox{width:100%;max-width:390px;max-height:90vh;overflow:auto;padding:16px;border-radius:14px;background:var(--mbg);color:var(--mtx)}\\n.mbox h3{font-size:16px;margin-bottom:10px;color:#2B2D42}\\n.mbox h4{font-size:12px;font-weight:600;color:#5A5F73;margin:12px 0 6px}\\n.mbox input[type=text]{width:100%;padding:9px 11px;border:1px solid var(--bd);border-radius:10px;background:var(--chip);font-size:13px;color:#2B2D42;outline:none;margin-top:6px}\\n.mbox textarea{width:100%;padding:10px;border:1px solid var(--bd);border-radius:10px;background:var(--chip);font-size:13px;resize:vertical;outline:none;color:#2B2D42}\\n.hint{font-size:var(--hintfs);color:var(--hinttx);margin:7px 0;line-height:var(--hintlh);letter-spacing:var(--hintls);text-shadow:var(--hintsh)}\\n\/* ★ 按钮行一律用 flex-wrap(不用 grid): \\n   1) 兼容性: 部分阅读 App(尤其修改版\/旧版)的 WebView 不支持 display:grid,\\n      一旦失效容器退化成 block, 配合 .bt{width:100%} 会让每个按钮各占满一整行 -> 上下堆叠。\\n   2) 自动流动: flex:1 1 auto 让按钮按内容宽度比例分配同一行剩余空间,\\n      短按钮(如\\\"完成\\\")不会被强行拉成半行而在右侧留出大片空白;\\n      一行挤不下时自动换行, 不会溢出行宽。 *\/\\n\/* 折叠分区 *\/\\n.sec{border:1px solid var(--bd);border-radius:11px;margin-bottom:9px;overflow:hidden}\\n.sech{display:flex;align-items:center;justify-content:space-between;padding:10px 12px;background:var(--sechbg);cursor:pointer}\\n.sech b{font-size:13px;color:var(--hdtx)}\\n.sech span{font-size:13px;color:var(--sub)}\\n.secb{padding:10px 12px}\\n\/* 附件(非图片: txt\/pdf\/epub\/json\/zip…): 图标+文件名+大小\/下载次数, 点击下载 *\/\\n.atts{display:flex;flex-direction:column;gap:7px;margin:10px 0 2px}\\n.att{display:flex;align-items:center;gap:10px;padding:9px 11px;\\n border:var(--btnbdw) solid var(--btnbdc);border-radius:var(--rd);\\n background:var(--chip);color:var(--btntx);text-decoration:none;box-shadow:var(--btnsh)}\\n.att:active{opacity:.7}\\n.atico{width:26px;height:26px;flex:none;object-fit:contain;border-radius:5px;\\n background:var(--mbg);display:flex;align-items:center;justify-content:center;font-size:16px}\\n.atinfo{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}\\n.atnm{font-size:13px;font-weight:600;color:var(--mtx);\\n overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\\n.atmeta{font-size:11px;color:var(--sub)}\\n.atdl{flex:none;font-size:15px;color:var(--pk);opacity:.85}\\n\/* 分类 *\/\\n.catadd{display:flex;gap:6px;margin:6px 0}\\n.catadd input{flex:1;margin-top:0!important}\\n.cat{margin:8px 0;border:1px solid var(--bd);border-radius:9px;overflow:hidden}\\n.cath{display:flex;align-items:center;gap:7px;padding:7px 10px;background:var(--catbg);cursor:pointer}\\n.cath b{font-size:12px;color:var(--hdtx);flex:1}\\n.cnt{font-size:11px;color:var(--sub)}\\n.cdel{margin-left:6px;padding:2px 8px;border:1px solid var(--bd);border-radius:6px;background:#fff;color:#E5484D;font-size:11px;cursor:pointer}\\n.arw{cursor:pointer;font-size:12px}\\n\/* v12 原样 *\/\\n.pregrid{display:grid;grid-template-columns:repeat(4,1fr);gap:7px;padding:8px}\\n.pw{position:relative;aspect-ratio:1;box-sizing:border-box;border:2px solid var(--bd);border-radius:9px;overflow:hidden;background:var(--chip)}\\n.pw.sel{border-color:var(--pk)}\\n.pv{width:100%;height:100%;object-fit:cover;cursor:pointer;display:block;-webkit-touch-callout:none}\\n.del{position:absolute;right:0;top:0;width:20px;height:20px;border:none;background:var(--pk);color:#fff;font-size:13px;line-height:1;cursor:pointer;border-radius:0 0 0 6px}\\n.fprev{display:flex;align-items:center;gap:10px;margin:9px 0;padding:9px;border:1px dashed var(--bd);border-radius:10px;background:var(--chip)}\\n.fprev span{font-size:11px;color:var(--sub);flex:none}\\n#fabPrev{background-repeat:no-repeat;display:flex;align-items:center;justify-content:center;font-size:19px;flex:none;overflow:hidden;border:1px solid var(--bd)}\\n#fabPrevEmo{font-weight:400}\\n.msw{padding:6px 11px;border:1px solid var(--bd);border-radius:9px;background:#fff;color:#5A5F73;font-size:12px;cursor:pointer;flex:1}\\n.msw.on{background:var(--pk);color:#fff;border-color:var(--pk)}\\n\/* v58 选中问 AI *\/\\n.aisel{position:absolute;z-index:9999;padding:7px 12px;font-size:13px;cursor:pointer;\\n border:1px solid var(--dbdc);border-radius:16px;background:var(--mbg);color:var(--tx);\\n box-shadow:0 2px 10px rgba(0,0,0,.25)}\\n.aiq{max-height:22vh;overflow:auto;padding:8px 10px;margin-bottom:8px;\\n border-left:3px solid var(--pk);background:var(--sechbg);color:var(--sub);font-size:13px}\\n.aia{max-height:46vh;overflow:auto;font-size:14px;line-height:1.7}\\n.aia.wait{color:var(--sub)}\\n.aia.err{color:#e33}\\n.aia pre{overflow:auto;padding:8px;border-radius:6px;background:var(--sechbg)}\\n.aia code{padding:1px 4px;border-radius:4px;background:var(--sechbg);font-size:13px}\\n.aia h3,.aia h4{margin:8px 0 4px}\\n.aia li{margin-left:16px}\\n.srow{display:flex;align-items:center;gap:8px;margin:8px 0}\\n.srow label{font-size:12px;color:var(--lbtx);width:78px;flex:none}\\n.srow input[type=range]{flex:1;min-width:0}\\n.srow input[type=color]{width:36px;height:26px;border:1px solid var(--bd);border-radius:7px;padding:0;background:none;cursor:pointer}\\n\/* PS 风格取色器 *\/\\n.cpk{display:flex;align-items:center;gap:8px;padding:5px 10px;border:1px solid var(--bd);border-radius:9px;background:#fff;cursor:pointer;flex:1;min-width:0}\\n.cpk:active{opacity:.7}\\n.csw{width:24px;height:24px;border-radius:6px;border:1px solid var(--bd);flex:none;display:block;background:#fff}\\n.chex{font-size:11px;color:var(--lbtx);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\\n#cp{z-index:150}\\n.cprev{display:flex;gap:12px;margin-bottom:12px}\\n.cpv{flex:1;text-align:center}\\n.cpv i{display:block;height:42px;border-radius:10px;border:1px solid var(--bd)}\\n.cpv span{font-size:11px;color:var(--sub)}\\n.svbox{position:relative;width:100%;height:175px;border-radius:11px;border:1px solid var(--bd);cursor:crosshair;margin-bottom:12px;touch-action:none;overflow:hidden}\\n.svcur{position:absolute;width:17px;height:17px;border-radius:50%;border:2px solid #fff;box-shadow:0 0 0 1px rgba(0,0,0,.5);transform:translate(-50%,-50%);pointer-events:none}\\n.huebar{position:relative;width:100%;height:20px;border-radius:10px;border:1px solid var(--bd);margin-bottom:12px;cursor:pointer;touch-action:none;\\n background:linear-gradient(to right,#f00 0%,#ff0 17%,#0f0 33%,#0ff 50%,#00f 67%,#f0f 83%,#f00 100%)}\\n.huecur{position:absolute;top:50%;width:15px;height:24px;border-radius:5px;border:2px solid #fff;box-shadow:0 0 0 1px rgba(0,0,0,.5);transform:translate(-50%,-50%);pointer-events:none}\\n.rgbrow{display:flex;align-items:center;gap:6px;margin:7px 0}\\n.rgbrow label{font-size:12px;color:var(--lbtx);width:28px;flex:none}\\n.rgbrow input{flex:1;min-width:0;padding:7px 9px;border:1px solid var(--bd);border-radius:8px;background:#fff;font-size:12px;color:#2B2D42;outline:none}\\n\/* 颜色预设: 8 列, 与 v12 的 grid 风格一致 *\/\\n.preset{display:grid;grid-template-columns:repeat(8,1fr);gap:6px;margin:12px 0}\\n.psw{aspect-ratio:1;box-sizing:border-box;border-radius:6px;border:1px solid var(--bd);cursor:pointer;padding:0}\\n.psw:active{transform:scale(.9)}\\n.srow input[type=text]{flex:1;margin-top:0!important}\\n.srow select{flex:1;padding:6px 8px;border:1px solid var(--bd);border-radius:8px;background:#fff;font-size:12px;color:#2B2D42}\\n.sval{font-size:11px;color:var(--sub);width:38px;text-align:right;flex:none}\\n\/* v55 XY 双滑块行: 一行内两个 range 各占剩余宽度一半(继承 .srow input[type=range] 的 flex:1),\\n   右侧 .sxy 显示 (x,y) 坐标, 比 .sval 宽因而单独定宽 *\/\\n.sxy{font-size:11px;color:var(--sub);width:66px;text-align:right;flex:none;white-space:nowrap}\\n\/* v58 XY 分组: 一组一个卡片, 横 \/ 纵各占一行 —— 滑块不再与另一个对半分宽度 *\/\\n.xyg{margin:10px 0 12px;padding:8px 10px 6px;border:1px solid var(--bd);border-radius:10px;background:var(--sechbg)}\\n.xyh{display:flex;align-items:center;gap:8px;margin-bottom:2px}\\n.xyh b{flex:1;min-width:0;font-size:12px;font-weight:600;color:var(--lbtx)}\\n.srow.xr{margin:5px 0}\\n.srow.xr>label{width:26px;flex:0 0 26px}\\n.srow.xr input[type=range]{flex:1;min-width:0}\\n.lbox{display:none;position:fixed;left:0;top:0;right:0;bottom:0;background:rgba(0,0,0,.92);z-index:400;\\n align-items:center;justify-content:center;padding:12px;overflow:hidden;touch-action:none}\\n.lbox.on{display:flex}\\n.lbox img{max-width:100%;max-height:100%;width:auto;height:auto;object-fit:contain;border-radius:6px;\\n transform-origin:center center;will-change:transform;cursor:grab}\\n.tip{position:fixed;left:50%;bottom:76px;transform:translateX(-50%);padding:9px 15px;border-radius:10px;background:#2B2D42;color:#fff;font-size:13px;z-index:500;max-width:86%;line-height:1.5;white-space:pre-line}\\n.tip.ok{background:#16A34A}.tip.no{background:#E5484D}.tip.wait{background:#7C6BD9}\\n\\n\/* v48: 外框去底色面板 *\/\\n.frdec-prev{border:1px solid var(--bd);border-radius:10px;overflow:hidden;text-align:center;min-height:110px;display:flex;align-items:center;justify-content:center;background-image:linear-gradient(45deg,#D8DBE3 25%,transparent 25%,transparent 75%,#D8DBE3 75%),linear-gradient(45deg,#D8DBE3 25%,transparent 25%,transparent 75%,#D8DBE3 75%);background-size:16px 16px;background-position:0 0,8px 8px;background-color:#fff}\\n.frdec-prev img{max-width:100%;max-height:36vh;display:block;margin:0 auto;cursor:crosshair}\\n\/* v58b: AI 编辑弹窗 *\/\\n#aim .srow label{width:66px}\\n#aim select{width:100%;padding:7px 9px;border:1px solid var(--bd);border-radius:9px;\\n background:var(--chip);font-size:12px;color:#2B2D42;margin-top:6px}\\n.prow{display:flex;gap:6px;align-items:stretch;margin-top:8px}\\n.prow textarea{flex:1;min-width:0;margin-top:0}\\n.prow .bt{flex:none;width:62px;min-width:62px;padding:0;display:flex;align-items:center;\\n justify-content:center;font-size:12px;white-space:nowrap}\\n#aiq{min-height:96px;max-height:34vh;margin-top:8px}\\n#aiqq{max-height:16vh;margin:0 0 8px}\\n.aihint{font-size:11px;color:var(--sub);margin:4px 0 2px;line-height:1.5}\\n\\n\/* v58c: 一键测试结果框 *\/\\n.aitest{display:block;margin-top:8px;padding:8px 10px;border-radius:8px;\\n background:var(--sechbg);font:11px\/1.6 monospace;color:var(--sub);\\n white-space:pre-wrap;word-break:break-all;max-height:30vh;overflow:auto}\\n.aitest.wait{color:var(--sub)}\\n.aitest.ok{background:rgba(46,160,67,.10);color:#1a7f37}\\n.aitest.err{background:rgba(207,34,46,.10);color:#cf222e}\\n\\n\/* v59b: 模型列表(多提供商 \/ 多选 \/ 序号 \/ 拖动) *\/\\n.mlist{max-height:32vh;overflow:auto;margin-top:6px;border:1px solid var(--bd);border-radius:9px}\\n.mrow{display:flex;align-items:center;gap:6px;padding:7px 8px;font-size:12px;\\n border-bottom:1px solid var(--bd);background:transparent}\\n.mrow:last-child{border-bottom:none}\\n.mrow.on{background:rgba(74,108,247,.10)}\\n.mrow.dragging{opacity:.55;background:rgba(74,108,247,.22)}\\n.mno{flex:none;width:18px;text-align:center;font-weight:700;color:var(--sub)}\\n.mrow.on .mno{color:var(--pk)}\\n.mrow input[type=checkbox]{flex:none;width:15px;height:15px;margin:0}\\n.mname{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;cursor:pointer}\\n.mhandle{flex:none;color:var(--sub);padding:0 2px;font-size:14px;cursor:grab}\\n\\n\/* v59c: 返回上一级按钮(加大, 与密钥同排靠右) *\/\\n.ib.back{width:auto;min-width:64px;padding:0 14px;font-size:14px;flex:none}\\n\/* v59d: 悬浮按钮长按拖动 —— 禁止选中内部文字\/图案、禁止长按菜单 *\/\\n.fab,.fab *{-webkit-user-select:none;-moz-user-select:none;user-select:none;-webkit-touch-callout:none;-webkit-user-drag:none}\\n.fab{touch-action:none}\";\nreturn '<!DOCTYPE html><html><head><meta charset=\\\"UTF-8\\\">'+'<meta name=\\\"color-scheme\\\" content=\\\"light only\\\">'+'<meta name=\\\"supported-color-schemes\\\" content=\\\"light only\\\">'+'<meta name=\\\"viewport\\\" content=\\\"width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no\\\">'+'<base href=\\\"https:\/\/bbs.xiaoxiaoshuo8.com\/\\\">'+'<title>加载中<\/title>'+'<style>'+CSS+'<\/style><\/head><body>'+'<img id=\\\"bgimg\\\" referrerpolicy=\\\"no-referrer\\\" alt=\\\"\\\">'+'<div class=\\\"wrap\\\">'+'<textarea id=\\\"SRC\\\" style=\\\"display:none\\\">'+html+'<\/textarea>'+'<input type=\\\"hidden\\\" id=\\\"CURURL\\\" value=\\\"'+cur+'\\\">'+'<div id=\\\"app\\\"><\/div>'+'<div class=\"modal\" id=\"mm\" onclick=\"if(event.target===this)closeCmt()\"><div class=\"mbox\"><h3>💭 点评<\/h3>'+'<textarea id=\"ci\" rows=\"3\" placeholder=\"输入点评内容…\"><\/textarea>'+'<div class=\"row2\"><button class=\"bt\" onclick=\"closeCmt()\">取消<\/button>'+'<button class=\"bt pri\" onclick=\"submitCmt()\">提交<\/button><\/div><\/div><\/div>'+'<div class=\"modal\" id=\"em\" onclick=\"if(event.target===this)closeEditM()\"><div class=\"mbox\"><h3>✏️ 编辑内容<\/h3>'+'<input type=\"text\" id=\"et\" placeholder=\"标题（可留空）\">'+'<textarea id=\"ei\" rows=\"9\" placeholder=\"编辑内容…\"><\/textarea>'+'<div class=\"row2\"><button class=\"bt\" onclick=\"closeEditM()\">取消<\/button>'+'<button class=\"bt pri\" onclick=\"submitEdit()\">保存并发布<\/button><\/div><\/div><\/div>'+'<div class=\"modal\" id=\"am\" onclick=\"if(event.target===this)closeAtt()\"><div class=\"mbox\"><h3>📎 插入图片<\/h3>'+'<div class=\"hint\">⚠ 阅读内置浏览器不支持上传本地文件，只能发送文字。<br>'+'需要发图片\/附件请点右上角菜单用浏览器打开原帖上传。<br>'+'此处可粘贴图片网址，仅支持 jpg\/png\/gif\/webp\/bmp\/svg 后缀,<br>'+'非图片后缀的网址论坛无法显示成图片，故已限制。<\/div>'+'<input type=\"text\" id=\"au\" placeholder=\"https:\/\/...\/photo.jpg\">'+'<div class=\"row2\"><button class=\"bt\" onclick=\"closeAtt()\">取消<\/button>'+'<button class=\"bt pri\" onclick=\"insAtt()\">插入到回复框<\/button><\/div>'+'<\/div><\/div>'+'<div class=\"modal\" id=\"bp\" onclick=\"if(event.target===this)closeBG()\"><div class=\"mbox\" id=\"bpb\"><\/div><\/div>'+'<div class=\"lbox\" id=\"lb\" onclick=\"closeLB()\"><img id=\"lbi\" referrerpolicy=\"no-referrer\" alt=\"\"><\/div>'+'<div class=\"modal\" id=\"cp\" onclick=\"if(event.target===this)closePicker()\"><div class=\"mbox\"><h3>🎨 选择颜色<\/h3>'+'<div class=\"cprev\"><div class=\"cpv\"><i id=\"cpOld\"><\/i><span>原色<\/span><\/div>'+'<div class=\"cpv\"><i id=\"cpNew\"><\/i><span>新色<\/span><\/div><\/div>'+'<div class=\"svbox\" id=\"cpSv\"><i class=\"svcur\" id=\"cpSvC\"><\/i><\/div>'+'<div class=\"huebar\" id=\"cpHue\"><i class=\"huecur\" id=\"cpHueC\"><\/i><\/div>'+'<div class=\"rgbrow\"><label>R<\/label><input type=\"number\" id=\"cpR\" min=\"0\" max=\"255\"><label>G<\/label>'+'<input type=\"number\" id=\"cpG\" min=\"0\" max=\"255\"><label>B<\/label>'+'<input type=\"number\" id=\"cpB\" min=\"0\" max=\"255\"><\/div>'+'<div class=\"rgbrow\"><label>HEX<\/label><input type=\"text\" id=\"cpHex\" maxlength=\"7\" placeholder=\"#RRGGBB\"><\/div>'+'<div class=\"preset\" id=\"cpPreset\"><\/div>'+'<div class=\"row2\"><button class=\"bt\" onclick=\"closePicker()\">取消<\/button>'+'<button class=\"bt pri\" onclick=\"applyPicker()\">确定<\/button><\/div><\/div><\/div>'+'<button class=\"fab\" id=\"fab\" onclick=\"bgPanel()\" title=\"外观设置\">🎨<\/button>'+'<div class=\"modal\" id=\"io\" onclick=\"if(event.target===this)closeIO()\"><div class=\"mbox\"><h3>📋 配置备份 \/ 恢复<\/h3>'+'<div class=\"hint\">导出：下方文本即当前全部配置（颜色\/间距\/背景\/头像框\/分类），长按全选复制保存。<br>'+'导入：把之前保存的文本粘贴到下方，点「导入并应用」。<\/div>'+'<textarea id=\"ioTa\" rows=\"8\" placeholder=\"点导出生成配置文本，或粘贴配置文本后点导入\"><\/textarea>'+'<div class=\"row2\"><button class=\"bt\" onclick=\"exportCfg()\">导出<\/button>'+'<button class=\"bt\" onclick=\"copyCfg()\">复制<\/button>'+'<button class=\"bt pri\" style=\"grid-column:1\/-1\" onclick=\"importCfg()\">导入并应用<\/button><\/div>'+'<div class=\"row2\"><button class=\"bt\" onclick=\"saveCfgLocal()\">存为本机备份<\/button>'+'<button class=\"bt\" onclick=\"loadCfgLocal()\">读取本机备份<\/button><\/div>'+'<div class=\"row2\"><button class=\"bt\" onclick=\"darkPreset()\">深色配色<\/button>'+'<button class=\"bt\" onclick=\"lightPreset()\">浅色默认<\/button><\/div>'+'<div class=\"row2\"><button class=\"bt\" onclick=\"resetAll()\">恢复出厂设置<\/button>'+'<button class=\"bt\" onclick=\"closeIO()\">关闭<\/button><\/div><\/div><\/div>'+'<\/div>'+'<script>'+\"try{if(typeof window.__p8page==='function'){window.__p8page();}else{var _a=document.getElementById('app');if(_a)_a.innerHTML='<div style=\\\"padding:20px;color:#c00\\\">脚本未加载：preloadJs 未生效<\\\/div>';}}catch(e){var _b=document.getElementById('app');if(_b)_b.innerHTML='<pre style=\\\"padding:12px;color:#c00;white-space:pre-wrap;word-break:break-all\\\">'+(e&&e.stack?e.stack:e)+'<\\\/pre>';}\"+'<\\\/script>'+'<script>'+\"setTimeout(function(){try{if(typeof window.__p8page==='function')return;var ap=document.getElementById('app');if(!ap)return;if((ap.textContent||'').trim())return;ap.innerHTML='<div style=\\\"padding:16px;color:#c00;font-size:13px;line-height:1.7;background:#fff\\\">'+'<b>页面脚本未加载<\\\/b><br>'+'preloadJs 未生效（可能体积过大或被拦截），因此内容无法渲染。<br>'+'<span style=\\\"color:#666\\\">可尝试：设置 → 图片样式 → 加载方式改“立即加载”；或在书源编辑里确认 preloadJs 字段完整。<\\\/span>'+'<\\\/div>';}catch(e){}},3000);\"+'<\\\/script>'+'<\/body><\/html>';\n}catch(err){\nreturn '<!DOCTYPE html><html><head><meta charset=\\\"UTF-8\\\">'+'<meta name=\\\"viewport\\\" content=\\\"width=device-width,initial-scale=1\\\">'+'<title>出错<\/title><\/head>'+'<body style=\\\"margin:0;padding:16px;font-family:monospace;background:#fff;color:#c00\\\">'+'<h3>ruleContent 执行出错<\/h3>'+'<pre style=\\\"white-space:pre-wrap;word-break:break-all;font-size:12px\\\">'+String(err&&err.stack?err.stack:err)+'<\/pre><\/body><\/html>';\n}\n})()","ruleImage":"@js:\n(function(){\n  var s='';\n  try{s=String(result.outerHtml?result.outerHtml():String(result));}catch(e){s=String(result);}\n  var m=s.match(\/<div class=\"[^\"]*threadlist_imgs\\d*[^\"]*\"[^>]*>[\\s\\S]*?<img src=\"([^\"]*)\"\/);\n  var u=m?m[1]:'';\n  if(!u){var a=s.match(\/class=\"mimg\"><img src=\"([^\"]*)\"\/);if(a)u=a[1];}\n  u=String(u||'').replace(\/&amp;\/g,'&').trim();\n  if(!u)return '';\n  return \/^https?:\\\/\\\/\/i.test(u)?u:('https:\/\/bbs.xiaoxiaoshuo8.com\/'+u.replace(\/^\\\/+\/,''));\n})()","ruleLink":"@js:\n(function(){\n  var e=result,s='';\n  try{\n    if(e&&e.attr){var h=e.attr('href');if(h)s=h;}\n    if(!s&&e&&e.select){\n      var a=e.select('a');\n      for(var i=0;i<a.size();i++){\n        var u=a.get(i).attr('href');\n        if(u&&u.indexOf('mod=viewthread')>=0){s=u;break;}\n      }\n      if(!s){var b=e.select('a.murl');if(b.size()>0)s=b.get(0).attr('href');}\n    }\n  }catch(err){}\n  return s;\n})()","ruleNextPage":"@js:\n(function(){\n  try{\n    var s=String(result||'');\n    var m=s.match(\/<a href=\"([^\"]*page=\\d+[^\"]*)\"[^>]*class=\"[^\"]*nxt\/);\n    if(m)return m[1].replace(\/&amp;\/g,'&');\n    \/* 没有分页条的页面(如搜索结果页)退化为 {{page}} 自增 *\/\n    var hasPg=\/<div class=\"pg\"\/.test(s)||\/class=\"[^\"]*nxt\/.test(s);\n    var b=String(baseUrl||'');\n    if(!hasPg&&b.indexOf('{{page}}')>=0)return b;\n  }catch(e){}\n  return '';\n})()","rulePubDate":"@js:\n(function(){\n  var s='';\n  try{s=String(result.outerHtml?result.outerHtml():String(result));}catch(e){s=String(result);}\n  s=s.replace(\/&nbsp;\/g,' ');\n  var bu=String(baseUrl||'');\n  if(bu.indexOf('x8new')>=0&&s.indexOf('class=\"murl\"')>=0)return '\\u70b9\\u51fb\\u8fdb\\u5165\\u65b0\\u7248\\u7f51\\u9875\\u5217\\u8868';\n  if(s.indexOf('class=\"murl\"')>=0){\n    var n=s.match(\/<span class=\"mnum\">([^<]*)<\\\/span>\/);\n    if(n)return n[1].replace(\/<[^>]*>\/g,'').trim();\n    var d=s.match(\/<p class=\"mtxt\">([\\s\\S]*?)<\\\/p>\/);\n    return d?d[1].replace(\/<[^>]*>\/g,'').trim():'';\n  }\n  var o=[];\n  var u=s.match(\/class=\"mmc\"[^>]*>([\\s\\S]*?)<\\\/a>\/);\n  if(u)o.push(u[1].replace(\/<[^>]*>\/g,'').trim());\n  var m=s.match(\/<span class=\"mtime\">([\\s\\S]*?)<\\\/span>\/);\n  if(m)o.push(m[1].replace(\/<[^>]*>\/g,'').trim());\n  var f=s.match(\/<div class=\"threadlist_foot cl\">([\\s\\S]*?)<\\\/div>\/);\n  if(f){\n    var r=\/<\\\/i>(\\d+)<\\\/li>\/g,x,v=[];\n    while((x=r.exec(f[1])))v.push(x[1]);\n    if(v[0])o.push('\\ud83d\\udc41'+v[0]);\n    if(v[1])o.push('\\ud83d\\udcac'+v[1]);\n  }\n  \/* v52: 最后发表作者+时间(电脑版独有, 由 ruleArticles 预先合并进 data-last) *\/\n  var lp=s.match(\/data-last=\"([^\"]*)\"\/);\n  if(lp){var lv=lp[1].replace(\/<[^>]*>\/g,'').trim();if(lv)o.push('\\u21a9'+lv);}\n  return o.join(' \\u00b7 ');\n})()","ruleTitle":"@js:\n(function(){\n  var s='';\n  try{s=String(result.outerHtml?result.outerHtml():String(result));}catch(e){s=String(result);}\n  s=s.replace(\/&nbsp;\/g,' ');\n  var bu=String(baseUrl||'');\n  \/* v52: 第14个分类「新版列表入口」下面的 13 条, 重命名为「<板块名> · 新版列表页」 *\/\n  if(bu.indexOf('x8new')>=0&&s.indexOf('class=\"murl\"')>=0){\n    var bt=s.match(\/<p class=\"mtit\">([\\s\\S]*?)<\\\/p>\/);\n    var bn=bt?bt[1].replace(\/<span[\\s\\S]*?<\\\/span>\/g,'').replace(\/<[^>]*>\/g,'').trim():'';\n    return bn?bn+' \\u00b7 \\u65b0\\u7248\\u5217\\u8868\\u9875':'\\u65b0\\u7248\\u5217\\u8868\\u9875';\n  }\n  var G={'2':'书友交流','3':'书友交流','6':'书友交流','12':'小说','13':'小说','14':'小说',\n         '16':'鉴赏区','17':'鉴赏区','18':'鉴赏区','11':'网站导航','10':'资源分享','9':'资源分享','8':'资源分享'};\n  var fid=s.match(\/fid=(\\d+)\/);\n  if(fid&&s.indexOf('class=\"murl\"')>=0){\n    var t=s.match(\/<p class=\"mtit\">([\\s\\S]*?)<\\\/p>\/);\n    var n=t?t[1].replace(\/<span[\\s\\S]*?<\\\/span>\/g,'').replace(\/<[^>]*>\/g,'').trim():'';\n    return (G[fid[1]]?G[fid[1]]+' \\u00b7 ':'')+n;\n  }\n  var em=s.match(\/<div class=\"threadlist_tit cl\">[\\s\\S]*?<em[^>]*>([\\s\\S]*?)<\\\/em>\/)\n      || s.match(\/<em[^>]*>([\\s\\S]*?)<\\\/em>\/);\n  var P=s.indexOf('class=\"list_top\"')>=0?'\\ud83d\\udccc':'';\n  return em?P+em[1].replace(\/<[^>]*>\/g,'').trim():'';\n})()","searchUrl":"search.php?mod=forum&srchtxt={{key}}&searchsubmit=yes&mobile=2&page={{page}}","shouldOverrideUrlLoading":"(function(){\n  try{\n    var u=String(url||'');\n    var m1=u.indexOf('mod=viewthread')>=0,m2=u.indexOf('mod=forumdisplay')>=0;\n    \/* 双保险：接管原生 Discuz 编辑页，自建可提交编辑 UI，避免标题缺失触发“请输入标题或内容” *\/\n    if(u.indexOf('mod=post')>=0 && u.indexOf('action=edit')>=0){\n      if(typeof java!=='undefined'&&java&&typeof java.open==='function'){ java.open('rss',u); return true; }\n      return false;\n    }\n    \/* webnote.cc 加密便签(\/p\/<id>@<pwd>) -> 走书源详情页渲染, 由 ruleContent 特判取正文进主楼层 *\/\n    if(\/webnote\\.cc\\\/p\\\/[A-Za-z0-9]+\/i.test(u)){\n      if(typeof java!=='undefined'&&java&&typeof java.open==='function'){ java.open('rss',u); return true; }\n      return false;\n    }\n    if(m1||m2){\n      \/* RssJsExtensions.open() 内部有多个【静默失败】分支:\n         activityRef.get() 为 null \/ getSource() 为 null(弱引用被回收) \/\n         source 不是 RssSource —— 都会直接 return@launch, 不提示也不跳转。\n         若这里仍无条件 return true 拦截掉导航, 点卡片就完全没反应。\n         所以先确认 java.open 可用; 不可用则放行, 让 WebView 裸跳原网页,\n         至少还能看到内容, 而不是点了毫无动静。 *\/\n      if(typeof java!=='undefined'&&java&&typeof java.open==='function'){\n        java.open('rss',u);\n        return true;\n      }\n      return false;\n    }\n    \/* v53: 附件图片链接(mod=attachment) -> 用内置图片查看器打开, 不再裸跳原网页 *\/\n    if(u.indexOf('mod=attachment')>=0){\n      if(typeof java!=='undefined'&&java&&typeof java.showPhoto==='function'){\n        java.showPhoto(u);\n        return true;\n      }\n      return false;\n    }\n  }catch(e){}\n  return false;\n})()","showWebLog":true,"singleUrl":false,"sortUrl":"书友交流 · 小说讨论::forum.php?mod=forumdisplay&fid=2&mobile=2&page={{page}}\n书友交流 · 求书::forum.php?mod=forumdisplay&fid=3&mobile=2&page={{page}}\n书友交流 · 催更::forum.php?mod=forumdisplay&fid=6&mobile=2&page={{page}}\n小说 · 慎入::forum.php?mod=forumdisplay&fid=14&mobile=2&page={{page}}\n小说 · nsfw::forum.php?mod=forumdisplay&fid=13&mobile=2&page={{page}}\n小说 · sfw::forum.php?mod=forumdisplay&fid=12&mobile=2&page={{page}}\n鉴赏区 · 小说::forum.php?mod=forumdisplay&fid=16&mobile=2&page={{page}}\n鉴赏区 · 图片::forum.php?mod=forumdisplay&fid=17&mobile=2&page={{page}}\n鉴赏区 · 网站::forum.php?mod=forumdisplay&fid=18&mobile=2&page={{page}}\n网站导航 · 千百羽官方站::forum.php?mod=forumdisplay&fid=11&mobile=2&page={{page}}\n资源分享 · 应用::forum.php?mod=forumdisplay&fid=10&mobile=2&page={{page}}\n资源分享 · 网盘::forum.php?mod=forumdisplay&fid=9&mobile=2&page={{page}}\n资源分享 · 链接::forum.php?mod=forumdisplay&fid=8&mobile=2&page={{page}}","sourceComment":"v51 - 板块页网页视图(ruleContent 板块分支)补上 dhnav 分类导航条与置顶帖分组, 并修复 v50 @js 列表规则的 Java String replace 重载歧义报错。① 报错根因: ruleTitle\/rulePubDate 改 @js 后, 列表项 result 是 jsoup Element, result.outerHtml() 返回 Java String, 对它 .replace(\/&nbsp;\/g,' ') 触发 Rhino 对 String.replace(char,char) 与 replace(CharSequence,CharSequence) 的重载歧义(<Unknown Source>#4)。修复: String(...) 包一层, outerHtml() 结果先转 JS 字符串再做正则替换, 语义不变。② 分类导航: 板块页 HTML 顶部有 .dhnav_box(全部\/最新\/热门\/热帖\/精华 5 个过滤 tab), v50 未渲染; v51 解析 dhnav_box, 按各 tab href 的 filter\/digest 参数与当前 URL 比对高亮激活项(.nav a.on), 渲染为横向滚动胶囊导航, 点击经 shouldOverrideUrlLoading 回本源按 filter 重解析(最新=filter=lastpost, 热门=filter=heat, 热帖=filter=hot, 精华=filter=digest&digest=1)。③ 置顶帖: list_top 原与普通帖同卡片仅加红 tag; v51 将 list_top\/list 分流 —— 置顶帖独立成组(.tpb)置于「📌 置顶」标题下(米黄底\/虚线框, 取真实 micon 文本作 tag), 普通帖保持头像大卡片(.tlb); 原生列表规则 ruleTitle 对置顶帖标题前缀 📌 便于列表辨识。④ 验证: 真实 fid=2(1置顶+20普通) 与 fid=13(2置顶+1普通) HTML 端到端渲染, 5-tab 激活高亮\/置顶普通分组数量正确, 分页与深色适配保留; 帖子页(viewthread)不误触发板块分支。\n\nv50 - 订阅源入口改为首页(index.php?mobile=2), 打通「首页→板块→帖子」三层导航。起因: 首页新增到 5 个分组 \/ 13 个板块, 而入口一直是 fid=2「小说讨论」单个板块, 只能看到一个区。① 列表: ruleArticles 改 class.murl||class.list —— 首页命中 13 个板块(.murl), 板块页无 .murl 自动回退 class.list 取帖子(getElements 支持 || 取首个非空即 break), 故 sortUrl 的 13 个板块分类与首页共用同一套列表规则, 互不冲突。② 标题: ruleTitle 用 @js 兼容两种结构 —— 首页按 fid 查分组映射表输出「分组 · 板块名」, 板块页仍取 threadlist_tit\/em。注意 @js 里 result 是【jsoup Element】, 须 outerHtml() 取 HTML。③ 链接: ruleLink 用 @js 取 href —— a.murl 取自身, li.list 则在其子 a 中挑含 mod=viewthread 的(li 内第一个 a 是用户空间 home.php?mod=space, 直接取会串到用户主页); isUrl=true 时 AnalyzeRule 末尾会无条件 NetworkUtils.getAbsoluteURL 转绝对, 故返回相对 href 即可。④ 正文: ruleContent 最前面插入板块页分支 —— 判断 baseUrl 含 mod=forumdisplay 即渲染帖子列表(板块名+统计 \/ 头像+标题+摘要+作者·时间·浏览·回复 \/ 置顶标记 \/ 上一页下一页 \/ 深色适配), 帖子项用前瞻正则 (?=<li class=\"list|<\/ul>) 切分以避开 threadlist_foot 内的嵌套 <li>。⑤ 跳转: 新增 shouldOverrideUrlLoading —— ReadRssActivity 对 http\/https 链接默认 return false(WebView 裸加载原网页, 不会用 ruleContent 二次解析), 必须在此拦截: 命中 mod=viewthread|mod=forumdisplay 则 java.open('rss',url) 用本订阅源重新解析, 返回 true。注意 evalJS 不处理 @js: 前缀且用 Rhino(ES5), 故该字段写纯 JS + IIFE 返回值, 全部 ES5 语法。⑥ sortUrl 由 10 项补到 13 项: 补齐鉴赏区 16\/17\/18, 并修正 fid=12 被错标为 nsfw(应为 sfw, 13 才是 nsfw), 全部按「分组 · 板块名」重新命名排序。⑦ ruleNextPage 保持 page(URL 参数翻页): 首页 URL 无 page 参数故不翻页, 板块页正常翻页。\nv49 - 取色预览支持放大以便精确取色: 双指捏合缩放 \/ 单指拖动移动 \/ 缩放滑块(1~8x) \/ 双击复位, 去底色与外框去底色两个面板共用一套 z* 逻辑(按 id 前缀 dec \/ frdec 区分)。实现: 预览容器作为视口(overflow:hidden + touch-action:none 以防 WebView 抢走双指做页面缩放), 图片用 transform:translate(x,y) scale(s), transform-origin 50% 50%。★取色换算无需改动: 取色走 getBoundingClientRect(), 该矩形已包含 transform, 故 (clientX-rect.left)\/rect.width 在任意缩放\/平移下都直接给出原图比例(实测 1x\/2x\/5x\/8x 全精确)。★双指捏合以两指中点为锚点(zAnchor), 手指下的像素保持不动(实测漂移 0px); 当锚点接近图片边缘且平移已达边界时由 zClampView 限制 —— 与图片查看器一致, 宁可锚点略偏也不露容器空白。细节: 位移超 3px 才判定为拖动以避免手抖误判; 拖动\/缩放后置 moved 标志并延迟 80ms 清除, 使紧随的 click 被跳过而不会误触发取色; 放大 >=3x 时切 image-rendering:pixelated 以看清像素边界; 平移边界保证图片始终覆盖容器; 图片 draggable=false 并拦截 dragstart, 防止原生拖拽干扰单指平移; 容器内 touch 事件均 preventDefault, 并在每次事件入口检查容器仍在文档中(window 级 mousemove 不会泄漏)。\nv48 - 头像外框去底色(全局生效): JPG 外框素材常带纯色背景, 铺满 .avf 图层后会把头像整块挡住, 需要吸取背景色变透明。关键: 所有楼层的 .avf 共用 CSS 变量 --frimg(applyStyle 下发), 故新增全局 FRDEC(去底色结果 dataURL)并让 applyStyle 取 FRDEC||FRAME, 全部头像即同时生效, 无需逐元素处理。新增 frDec* 函数组: 面板 \/ 点图取色 \/ 自动去底色 \/ 还原。自动去底色用【四角取样定背景色 + 从四角洪水填充】, 只透明化与边缘连通的背景, 不会误伤图案内部同色像素(实测: 背景 3520 像素全透明, 而图案内白色高光 64 像素完整保留; 若用全图颜色匹配则会误伤这 64 像素); 边缘几乎不扩散时(渐变\/四角异色)自动退回全图匹配。处理尺寸限 320px(外框实际仅显示 ~62px), 显著减小 dataURL 体积; 结果只存 localStorage, 不写进书源变量(书源变量会被导出\/同步, 不适放大段 base64)。换外框图(useFrame\/clearFrame\/addFrame)时自动丢弃旧的去底色结果, 避免新外框套用上一张的去底色图。另修: 「还原」按钮原用 .bt 默认淡色底, 实测看不出是个按钮 —— 新增 .bt.warn 警示配色(浅红底+深红字+红边框)用于所有还原\/清除类操作; 去底色预览区改棋盘格背景, 透明区域直接显示为灰白格子。\nv47 - ①三按钮(收藏\/点评\/回复)上下边框的阴影被遮挡: 根因是 .acts{overflow:hidden} 裁掉了子元素 .bt 的 box-shadow(阴影画在盒外), 与 <button>\/<span> 无关, 故 v46 改 span 无效。修复: .acts 与 .acts>font 改 overflow:visible, 改用 ::after clearfix 清除浮动(float 布局保持不变)。②.json 书源链接的一键导入按钮不显示, 三个原因: (a) decInit\/impSrcInit 原先只在脚本末尾跑一次, 而正文 5 处渲染入口都会 APP.innerHTML= 全量重建 DOM, 重建后角标与按钮全部丢失 —— 新增 postRender() 并挂到全部渲染入口; (b) 只扫第一个 .msg —— 改为扫全部楼层; (c) 只认 <a href>, 而论坛正文里粘贴的 .json URL 常是纯文本 —— 新增文本节点识别, URL 主体限定 ASCII 合法字符并剥离尾部中文标点(实测 15\/15), 补 .imp-link{word-break:break-all} 防长 URL 撑破窄屏。③看不到去底色入口: layoutImgs() 会把正文【所有】大图分组进 .imgrid 并打上 class=\"zoom\", 而 isDecImg 恰好排除了这两者, 等于把去底色整个禁用。修复: 不再排除, 改为 .imgrid .decbox 继承 flex item 尺寸以保持网格布局。\nv46 - ①收藏\/点评\/回复按钮行边框被透明内容遮挡: 旧 WebKit 对 <button> 的 flex 布局支持有缺陷(项目 CSS 注释早有记载), 按钮内 emoji+文字行高溢出 padding 区, 盖住上下边框。修复: render() 中该行三个 <button class=\"bt\"> 改为 <span class=\"bt\" role=\"button\">(无 UA 样式, display:flex 可靠), 并在 .bt 主规则补 line-height:1(内容行高=字号不溢出)。其余 .bt(设置面板等) 不受影响。 ②新增图片去底色(取色变透明): 正文 .msg 图片(排除表情\/头像\/附件图标\/图片网格) 右下角叠 🎨 角标, 点击打开取色面板, 点图上某色即把该色像素透明化(canvas getImageData 遍历+容差滑块 0~128 默认24, toDataURL('image\/png') 替换, 可还原); 跨域图(无 CORS 头) 会 taint canvas, 已 try\/catch 提示。 ③正文 .json 书源\/订阅源链接自动挂「⤓ 一键导入」按钮: 点击 location.href='legado:\/\/import\/any?src='+encodeURIComponent(url), WebView 拦截 legado:\/\/ scheme 交给 OnLineImportActivity, 未知类型 path 走 determineType 自动识别书源或订阅源后弹窗导入。 v45 - 修复方案列表行布局: 自定义一键切换方案的每行 切换按钮\/重命名\/删除 原先不在同一行 —— .profrow 无任何 CSS(普通 block), 块级 .bt 独占一行, 两个 .ib(30x30) 挤到下一行左侧且紧贴无间距(该规则 v36 曾存在, 后续 CSS 重构时丢失)。新增 .profrow{display:flex;align-items:center;gap:8px;margin-top:7px} 与 .profrow .bt{flex:1;min-width:0}: 切换按钮占满剩余宽度(长方案名可压缩), ✏️\/🗑 固定 30x30(.ib 自带 flex:none 不压缩) 与切换按钮同一行, 行内 8px 间距, 多方案行间 7px。实测: 三按钮同一行、间距 8px、无 JS 报错。 v44 - 头像外框: 「显示模式」改名「裁切模式」并默认 manual, 新增小标题「外框裁切与缩放」, 选项顺序改为 完整显示\/填充裁切\/手动缩放(默认)。v42 时该下拉藏在「头像外框」折叠分区底部, 且上方「背景图片」分区已有一个同名「显示模式」, 用户在实机找不到 —— 改名后两个下拉不再混淆, 并补小标题提升可见性。注意: 面板所有分区默认折叠, 需点「头像外框」标题条展开才能看到。原有「头像 \/ 外框 对位」分区的 外框放大\/左右\/上下(frScale\/frFx\/frFy) 按要求原样保留, 与新增的 外框图缩放\/焦点X\/焦点Y(frZoom\/frBX\/frBY) 正交: 前者 transform 移动整个外框图层, 后者 background-size\/position 只改外框图内部显示范围, 互不影响; 已在 hint 中向用户说明。滑块标签由「外框缩放 %」改为「外框图缩放 %」以与对位分区的「外框放大 %」区分。CSS 变量 --frsz 默认值同步 cover -> 100%(与 manual 默认一致)。实测: 展开分区后「裁切模式」下拉可见(184x30)、值=manual、三滑块默认全部显示; 切 contain\/cover 三滑块隐藏、切回 manual 再出现; 对位六个滑块原样保留; 容器恒定 62x62、行高 62; 60% 缩放粉色区 37px、焦点 0\/0 黑点左上角、100\/100 右下角; 无 JS 报错。- 「悬浮设置按钮 \/ 图标文字」出厂默认改为空(纯图按钮)。DEFST.fabEmo 由 emoji 改为空字符串; 输入框 placeholder 同步改为「留空 = 纯图按钮（默认）」。关键点: 老用户缓存(xss8_st)里存的是旧默认值, 改 DEFST 不会生效, 故加一次性迁移 —— 新增标记键 xss8_mig_fabemo, 仅当缓存值【等于旧出厂默认】时才清空, 用户自己填过的字一律不动; 标记保证只跑一次, 之后用户再填回 emoji 也不会被清。踩坑记录: 迁移判断原写成 JS 转义序列, 但书源 JSON 需经多层转义, 转义符被逐层翻倍成字面反斜杠, 比较永远为假(等于迁移静默失效, 且这类失效不会报错)。最终改用 charCodeAt 码点比较, 全 ASCII 无转义。实测五场景: 全新用户->空; 旧默认->被清空; 自定义\"A\"->保留; 已迁移后填回 emoji->保留; 已空->保持空。默认背景图(duitang gif)仍在, 按钮 48x48 可见, 不会出现空白按钮。- 头像外框新增显示模式\/缩放\/焦点三参数, 与「悬浮设置按钮 · 按钮背景图」同一套模型。旧版外框图是 <img>+object-fit:cover, 只能 cover\/contain, 无法自由缩放与指定焦点; 现改为 div 图层 + background-image\/background-size\/background-position, 由 --frimg\/--frsz\/--frbx\/--frby 四个变量下发。关键收益: 背景的尺寸与位置变化不改变元素占位, 故 .avw 容器尺寸恒定(实测 zoom 20%~400% 时 .avw 恒为 62x62、宿主行高恒为 62), 外框图只在容器内部缩放平移, 超出部分被裁掉, 不会撑动整行布局 —— 这正是「容器大小不变」的要求; 若沿用 <img> 缩放, 一放大就会撑开容器并带动布局。面板: 「显示模式」下拉(填充裁切\/完整显示\/手动缩放), 「外框缩放 %」20~400 步长5, 「焦点X %」「焦点Y %」0~100 步长1; 后三项仅在「手动缩放」模式下显示(frFitUI() 整行显隐, rrow 新增可选 wid 行 id 参数)。DEFST 新增 frFit:cover\/frZoom:100\/frBX:50\/frBY:50, 老配置导入自动回退默认(已实测)。useFrame\/clearFrame\/addFrame\/delPre 均补 applyStyle(), 保证切换外框时 --frimg 立即更新。bindAv 移除 .avf 的 onerror 兜底(改背景绘制后无裂图风险)。实测: 60% 缩放粉色区 37px(=62x0.6)、100% 撑满 62px、400% 撑满且只见中心部位; 焦点 0\/0 黑点在左上(0.17,0.17)、100\/100 在右下(0.83,0.83)。\n\nv52(已废弃) - 曾把分类切换做成 java.open('sort') 打开原生列表页、并把板块列表塞进 ruleContent 板块分支。废弃原因: ① startHtml 页面里 java 对象由 JS_INJECTION 以 const 声明且被包在 IIFE 内, startJs 取不到, 故分类\/新版入口\/帖子点击全部静默失效(表现为\"点了没反应\"); ② 板块分支加在 ruleContent 最前面, 与正文渲染抢职责, 维护成本高。\n\nv53 - 门户首页(startHtml+startStyle+startJs)全功能化, 舍弃原生分类列表页与 ruleContent 板块分支。① 根因: ReadRssActivity.initJavascriptInterface() 里有 if(!hasPreloadJs) return, 而 hasPreloadJs 取决于 preloadJs 非空; 更关键的是注入脚本为 (()=>{JS_INJECTION;preloadJs})(); —— java\/ajaxAwait 是 IIFE 内的 const, 门户页 startJs 访问不到, 所以 v52 里所有 java.open() 全部失效; 而搜索用 fetch 属浏览器原生 API 故仍可用(与\"搜索能出结果、点击无反应\"现象吻合)。② 修复: preloadJs 改为 var _x8=1;try{window.java=java;window.ajaxAwait=ajaxAwait;}catch(e){} —— preloadJs 同样拼在 IIFE 内, 可把 java\/ajaxAwait 挂到 window 供门户页使用; 同时主导航一律走\"真实 URL 跳转 + shouldOverrideUrlLoading 拦截\", 该回调在 Kotlin 侧执行(put(\"java\", rssJsExtensions)), 与页面注入无关, 最可靠。③ ruleContent 回退: 删除 v50 起的板块分支(含 v51 的 dhnav\/置顶分组), 恢复为纯帖子正文渲染(已用真实 tid=139 页面验证, 输出 15 万字符完整楼层页)。注意 java.open('rss',url) 走的是 ReadRssActivity.start(...,openUrl) 分支, link 为空时 RssArticle 不存在也会新建并 loadContent, 不依赖数据库。④ 门户页: 搜索框 + 单行横向滑动的 13 个分类(精简名, 去掉\"分组 · \"前缀), 点击在当前页 fetch 板块页并渲染 —— 含置顶分区、作者、时间、观看、回复、最后发表(电脑版 mobile=no 取)、帖子列表图片、头像; 滚动到底或点\"加载更多\"自动续页; 帖子为真实 URL 超链接, 由 shouldOverrideUrlLoading 拦截进渲染后正文页。⑤ 图片跳转修复: 新增 mod=attachment 拦截, 用 java.showPhoto() 打开, 避免正文内嵌附件图点击后裸跳原网页。⑥ sortUrl 去掉\"新版列表入口\"(门户页已集成), 保留 13 分类仅作回退。\nv54 - 门户首页(startHtml\/startStyle\/startJs)版面重做 + 帖子页新增「点评框」分区。\n① 多图: 手机版列表用 <div class=\"threadlist_imgs\">(多图) 与 <div class=\"threadlist_imgs1\">(单图), 后者是前者加数字后缀, 必须用同一条 \/threadlist_imgs\/ 正则才能都匹配。一行张数 = round(100 \/ 单图宽%), 再受「最多显示张数」与实际张数限制; 实际图宽 = (行宽 - 间距×(n-1)) \/ n 撑满整行, 高度恒为「行高」+ object-fit, 即图片缩放自适应高度。图片不够铺满一行时回退到「单图宽度」左对齐, 避免 1 张图被拉成整行宽。\n② 综合信息栏(作者\/时间\/观看\/回复\/最后发表)常驻卡片底部: .mt 改 position:absolute;left\/right=卡片左右内边距;bottom=「距卡片底部」, 因而天然横跨整行(覆盖头像与图片的左右留白)且恒占一行; 卡片 padding-bottom 由 JS 算出 --itpb = 上间距 + 下间距 + 字号×1.5 预留。放不下时 fitOne() 先逐 0.5px 缩字距到 -1、再逐 0.5px 缩字号到「最小字号」, 仍放不下交给 text-overflow:ellipsis 尾部省略 —— 块级 + white-space:nowrap + overflow:hidden 三件套缺一不可。\n③ 二级导航(全部\/最新\/热门\/热帖\/精华): 从页面 <div class=\"dhnav_box\"> 解析, 当前项带 class=\"flex mon\"; 筛选页的「下一页」链接自带 filter 参数, 直接沿用即可, 无需手工拼接。\n④ 发帖: 从页面取 href 含 mod=post&action=newthread&fid= 的链接, 天然指向当前分区(取不到时按 fid 兜底拼)。该链接不带 mod=viewthread\/forumdisplay, shouldOverrideUrlLoading 不拦截, 由 WebView 正常跳转。\n⑤ 置顶帖 <li class=\"list_top\"> 只有标题(micon + em), 没有作者\/时间\/观看, 故改为「标题 + 最后发表」同一行(.it.tp 用 flex, 内部 .mt 改回 static), 并删除单独的「📌 置顶」分区标题, 不再分两行。\n⑥ 最后发表: 每页只发 1 次请求 —— 取列表 URL 把 mobile=2 换成 mobile=no 拿电脑版(必须同一筛选条件, 否则精华\/热门等筛选后 tid 集合对不上), 按 URL 缓存(LMC), 翻回来不重复请求。\n⑦ 门户配置持久化: 页面里 window.java 是 WebJsExtensions, 它继承 RssJsExtensions, 因此有 @JavascriptInterface 的 put\/get —— 直接 java.put(k,v) 写进订阅源变量(随源导出\/同步), 比 localStorage 可靠; 代码里保留 localStorage 兜底。\n⑧ 帖子页新增「点评框」折叠分区(p18): .cmt 原先硬编码 background:var(--chip)、opacity:.92、font-size:calc(var(--fs) - 3px), 现全部改为 --cmt* 变量; 新增 17 个键(cmtBg\/cmtA\/cmtBdW\/cmtBdC\/cmtRd\/cmtPad\/cmtGap\/cmtSh\/cmtShC\/cmtFs\/cmtLh\/cmtTx\/cmtNTx\/cmtTTx\/cmtCTx\/cmtCFs\/cmtCLh), 已同步登记 syncStyle 的 nums\/cols 与 darkPreset(深底上浅灰点评框非常刺眼)。\n⑨ 门户面板一律用 flex-wrap 而非 grid(见 v25 实测: 部分阅读 App 的 WebView 不支持 grid); -webkit-line-clamp 先写固定值再写 var(), 给老 WebView 兜底。\nv55 - 帖子页: 头像旁元素新增 XY 坐标滑块(用户名\/时间\/楼层号\/观看数\/回复数)。\n① 拆分 DOM: 楼层号(沙发\/板凳\/N楼)与时间原本同在 .sub 里、观看数与回复数同在 .stat 里,\n   无法各自移动, 故各包一层 span —— .fl(楼层号) .tm(时间) .vw(观看) .rp(回复);\n   用户名 .un 原本就有独立节点。分隔符 \" · \" 并入后一个元素(时间 \/ 回复数), 跟着它一起移动。\n② 位移用 transform:translate(var(--unx),var(--uny)) 而非改 position —— 不脱离文档流,\n   原占位仍在, 下面的正文不会被顶动; 这是「微调坐标」而不是「重排布局」。\n   ★ transform 对 display:inline 元素无效, 所以 .un 从 display:inline 改为 inline-block\n     (补 max-width:100% 防止长用户名撑破容器), .fl\/.tm\/.vw\/.rp 同样必须 inline-block。\n③ 范围: 横向 ±400 \/ 纵向 ±300, 足以覆盖手机到平板的整个卡片范围(用户要求「整个 xy 坐标范围」)。\n   卡片开了 content-visibility:auto 做长列表性能优化, 它隐含 paint containment,\n   所以挪到卡片边界外的部分会被裁掉 —— 这是预期行为而非 bug。\n④ 面板新增折叠分区 p19「头像旁元素 XY 坐标」: 每类元素一行两个 range(横 \/ 纵),\n   右侧实时显示 (x,y); 底部有「全部复位到 (0,0)」。\n   ★ 新 range 的 id 必须登记进 syncStyle 的 nums 数组, 否则打开面板时滑块不回显当前值。\n⑤ ★ 转义层级陷阱: PAGE 是双层转义字符串(ruleContent 源码 -> JS 解析 -> PAGE 脚本 -> eval)。\n   在 PAGE 里写 \\uXXXX 会被转义两次, 最终变成字面文本 \"\\ud83d\" 而不是 emoji。\n   因此 PAGE 里一律写真实字符(👁 💬 ·), 只有单层转义的 startJs 才可以用 \\uXXXX。\nv56 - 门户首页性能优化(首屏 5.5s -> 1.5s) + 修复切分类误触发自动翻页。\n① ★ 根因: loadUrl 里写的是 getHtml(u).then(h => fetchLast(u)...), 两个请求完全串行。\n   实测手机版列表 1.54s \/ 25.5KB, 电脑版取「最后发表」3.93s \/ 46.7KB, 串行合计 5.47s。\n   改为同时发出(pList \/ pLast), 并行后 3.14s; 且首屏不再等电脑版, 降到 1.54s。\n② 渐进渲染: 列表页一到就先渲染 20 个卡片(「最后发表」留空), 电脑版那个慢请求回来后\n   fillLast() 按 data-tid 回填。故给每个 .mt 加 data-tid, 并用 META[tid] 存下\n   作者\/时间\/观看\/回复以便回填时重建整条综合信息; 置顶帖只有最后发表(data-fit=\"0\"), 直接 innerHTML。\n   回填后调 fitMeta() 重算挤压(内容变长了)。\n③ ★ 修复「切分类会自动翻到下一页」: loadCat \/ loadSub 替换内容后没有回顶部,\n   若在页面深处切换 -> 内容变短、页面骤降 -> 滚动位置仍很深 -> 立刻命中\n   「距底部 <300」的判定 -> 自动加载新分类第 2 页。现两处都加 window.scrollTo(0,0)。\n   同时 autoNext 默认改为关闭(需手动点「加载更多」), 并加 1.2s 保护期(lastLoadAt)。\n④ 快速连点分类用 loadSeq 序号丢弃过期响应, 避免旧内容盖掉新内容。\n⑤ 布局 layout thrashing: layoutImgs 改为「先批量读 clientWidth, 再批量写」(原读写交替);\n   fitOne 压缩字距\/字号由每 0.5px 一档线性递减(最坏 ~20 轮, 每轮强制重排, 20 条目上百次)\n   改为二分(每阶段最多 4 轮), 实测读取 scrollWidth 次数 20 -> 7。\n⑥ 图片加 decoding=\"async\", 避免解码阻塞渲染。\nv57 - 标题框自定义背景\/文字 + 「最后发表」空闲回填 + 帖子页楼层分批渲染。\n① 顶部标题框(startHtml\/startStyle\/startJs): 新增自定义背景图(heroBi, 网址或本地路径)\n   与显示模式(heroBFit, 含平铺)、背景图不透明度(heroBA)、最小高度(heroBH)、\n   遮罩(heroOv\/heroOvC, 保证文字在亮\/暗背景上都读得清)、上下\/左右内边距(heroPV\/heroPH);\n   文字改为可编辑(heroTxt 主标题 \/ heroSub 副标题)。\n   ★ 文字是 textContent 不是 CSS 变量, 故新增 syncHero() 在 applyStyle 里同步;\n     没设背景图时隐藏遮罩层(.heroov), 免得白压一层暗色。\n   CSS 上 .hero 改 position:relative + overflow:hidden, 内部再分 .herobg(背景图)\n   .heroov(遮罩) .heroin(文字容器, position:relative 压在两者之上)。\n② 「最后发表」为什么拖慢(澄清 v56): 确实用户说得对 —— 每页只请求 1 次, 一次拿满\n   当前页 20 条。慢的原因是「这 1 次请求本身慢」: 实测电脑版 forumdisplay\n   TTFB 1.36~1.66s(服务端渲染)、总量 46.7KB(手机版 25.5KB 的 1.8 倍), 而手机版\n   列表 TTFB 0.688s 就收完了。旧代码让 0.69s 就能显示的列表干等 1.7~2.3s。\n   v57 进一步: 回填从「请求返回即执行」改为 defer() 让位给首屏(优先 requestIdleCallback,\n   老 WebView 退化 setTimeout 120ms), 避免与首屏图片解码抢主线程;\n   并新增开关 lpOn(默认开), 关掉则一个请求都不发, 省下 46.7KB + 1.7s。\n   已验证没有更轻量的数据源: Discuz RSS(mod=rss, 仅 8KB)只有 pubDate 发布时间,\n   没有最后回复; Archiver(mod=archiver \/ archiver\/?fid-2.html)需登录, 不可用。\n③ 帖子页楼层分批渲染: 实测 150 楼的帖子, render() 字符串拼接只要 1ms —— 不是瓶颈,\n   真正的大头是 innerHTML 要一次性构建 1960 个 DOM 节点(解析 + 布局)。\n   把 render 拆成 renderHead(楼主帖) \/ renderItem(单楼层) \/ renderTail(分页栏+回复栏),\n   render() 保留为全量包装; renderLazy 只渲染前 ST.firstN 楼(默认 12)并插入\n   <div id=\"more\" data-next=\"N\"> 占位, 剩余由 renderRest() 每批补 60 楼,\n   触发时机为 requestIdleCallback(首屏后趁空闲补) + 滚动距底部一屏内(moreCheck)。\n   ★ 与已有的 content-visibility:auto 互补而非重复: 后者只跳过屏幕外的「布局\/绘制」,\n     跳不过「DOM 构建」; 分批渲染恰恰减少 DOM 构建。\n   实测: 首屏 HTML 占全量 9.6%, 节点 1960 -> 189(9.6%); 分 3 批补全 137 楼,\n   合并后与全量渲染逐字符完全一致(已加断言)。firstN=0 可恢复旧行为。\n\n\nv59 - ①「最后发表」改为异步回填, 不再拖慢首屏。② 默认图片(头像外框\/背景)支持「忽略」。\n③ 整理订阅源字段用法(据 Legado 源码)。\n\n① 最后发表: 之前 v57 的做法有两个问题 —— 首屏就并发请求电脑版列表(46.7KB \/ TTFB 1.4s)\n   与手机版抢带宽; 回填时对每一行重建整条 .mt 的 innerHTML(作者\/时间\/观看\/回复全部重拼)\n   并重跑 fitMeta 挤压。现在:\n   - 首屏【只请求手机版】, 渲染完立即出所有卡片, 与「最后发表」开关无关\n   - 渲染完成后用 defer()(requestIdleCallback) 等到主线程【空闲】才发电脑版请求\n     (实测: 手机版 16ms -> 电脑版 37ms, 明显滞后, 说明确实是渲染完才发)\n   - 回填时只写 .lp 这一个节点的 textContent, 不重建整行; fitMeta 只在确实填入后跑一次\n   - 布局: .lp 是 <i>(inline), 在 nowrap 的 .mt 里自然流动, 自动贴近前一个元素\n     (观看数\/回复数)的尾部, 无需定位。初始为空时由 CSS :empty 隐藏(不占空间、\n     不显示分隔符), 回填后自动出现, 分隔符用 ::before(与「分隔符」设置同步)\n   - 关掉「获取最后发表」则完全不发电脑版请求, 也不生成占位元素(实测请求数 1 -> 0)\n\n② 默认图片忽略: 默认图(头像外框 DFRAMES \/ 背景 DBGS)写在代码里删不掉,\n   现在每张都有 × 按钮, 点了加入「忽略列表」(localStorage, 两页共用键名 x8_hidebg \/\n   x8_hidefr, 两页同步), 渲染时跳过。「恢复默认设置」(帖子页 resetStyle) 或\n   「恢复出厂设置」(门户页 resetAll) 会清空忽略列表, 让它们回来 —— 实测\n   11 张 -> 忽略 1 张 -> 10 张 -> 恢复 -> 11 张。\n   注: 门户页的浅色配色预设(lightPreset)【不】清空忽略列表, 换配色不该把忽略的图弄回来。\n   另: 门户页背景 BGL 初始即 DBGS.slice(), 本来就能删, 未改动。\n   顺带给帖子页 resetStyle 补了 refreshPanel(), 否则恢复后面板不刷新(原来就没刷新)。\n\n③ 订阅源字段用法(据 Legado 源码确认, 便于后续维护):\n   - preloadJs : 由 ReadRssActivity.shouldInterceptRequest 通过 <script src> 注入,\n                 位置在 <head> 之后 —— 此时【DOM 未就绪】, 所以只能定义函数,\n                 不能操作元素。本源用它承载 148KB 详情页主脚本(window.__p8page),\n                 由 WebView 的 JS 引擎执行(不是 Rhino, 快很多)。\n   - injectJs  : 在 onPageFinished 里用 evaluateJavascript 执行 —— 此时【DOM 已就绪】,\n                 适合做初始化\/兜底\/后处理。本源用它做三件兜底:\n                 __p8page 缺失时给可见提示(不白屏)、#app 为空时提示解析失败、\n                 清理残留的全屏加载遮罩。\n   - preload   : 【不是 WebView 缓存开关】, 而是控制文章列表「进入即自动加载 +\n                 滚动到底自动加载更多」。当前 false。\n   - cacheFirst: 才是【优先加载缓存】的开关。ReadRssActivity 里\n                 cacheMode = if (cacheFirst) LOAD_CACHE_ELSE_NETWORK else LOAD_DEFAULT。\n                 当前 false(论坛需要看新帖, 开缓存可能看到旧内容)。\n   - enableJs \/ loadWithBaseUrl: 均为 true。\r\n[v59d] 首页门户页「外观设置」悬浮按钮(FAB)长按拖动不再选中按钮里的图案:\r\n       1) startStyle 追加 .fab,.fab *{-webkit-user-select:none;user-select:none;\r\n          -webkit-touch-callout:none;-webkit-user-drag:none} 与 .fab{touch-action:none};\r\n       2) fabInit 里再兜一层: 内联同款样式 + draggable=\"false\" + unselectable=\"on\",\r\n          并拦截 contextmenu \/ selectstart \/ dragstart;\r\n       3) down() 里先清空已有选区, mousedown 阻止默认(防止鼠标拖选字);\r\n       4) 长按判定前的抖动容差 8px -> 12px, 拖动过程中持续清选区。\r\n       短按仍正常打开外观设置面板(拖动后吞掉 click 的逻辑不变)。\r\n\r\n\r\n========== [v60] 修复「点列表卡片跳转后黑屏」 ==========\r\n根因(源码级, 见 ReadRssActivity \/ ReadRssViewModel):\r\n 1) initJavascriptInterface 里有一行 `if (!viewModel.hasPreloadJs) return` ——\r\n    preloadJs 必须非空, java\/source\/cache 三个桥接对象才会被 addJavascriptInterface 注入。\r\n 2) 但 hasPreloadJs=true 时, clHtml 会在 <head> 后插入\r\n    <script src=\"https:\/\/<uuid>.com\/<uuid>.js\"><\/script>  (JS_URL)\r\n    它靠 CustomWebViewClient#shouldInterceptRequest 用随机 nameUrl 拦截返回 preloadJs。\r\n 3) 详情页是 loadDataWithBaseURL(...) 加载的, 主框架是 data: URL。Android WebView\r\n    不一定为 data: URL 主文档触发 shouldInterceptRequest, 于是 jsInjected 标志复位不了;\r\n    第二次及以后打开详情页, nameUrl 不再被拦截 -> 去请求真实网络 -> 阻塞解析\/失败\r\n    -> window.__p8page 未定义 -> 页面空白\/黑屏。\r\n 4) 门户页走 htmlLiveData, 且 clHtml(processedHtml, startStyle ?: style) 取的是\r\n    startStyle(非空), 又完全不依赖 preloadJs 的内容 -> 所以门户页一直正常, 只有详情页黑。\r\n\r\n改法: 详情页主脚本(PAGE, 约 200KB) 从 preloadJs 迁到 style 字段内联。\r\n  * clHtml: htmlBuilder.insert(styleEndIndex+8, \"<style>$style<\/style>\"),\r\n    纯字符串拼接、不进 JS 引擎、零转义膨胀; 用 <\/style>...<style> 闭合技巧让 <script> 落在顶层。\r\n  * 门户页因为 startStyle 非空, clHtml 取 startStyle 而不是 style —— PAGE 只作用于详情页。\r\n  * preloadJs 只留 1 行桥接(109B), 保证 hasPreloadJs=true, 桥接对象才会被注入。\r\n  * style 的 <script> 开头 + injectJs 各有一段「桥接探测」: 即使 JS_URL 拦截失败,\r\n    也会遍历 window 把随机名注入的 java\/source\/cache 找回来。\r\n\r\n当前字段分工(详情页):\r\n  ruleContent 36KB  : CSS + 页面骨架 HTML + 末尾调用 window.__p8page()\r\n  style      202KB  : 详情页主脚本(PAGE) 内联 —— 真正干活的地方\r\n  preloadJs  109B   : 仅桥接行, 非空只为触发 addJavascriptInterface\r\n  injectJs   2.7KB  : DOM 就绪后的第二道保险(桥接兜底 \/ 补救调用 \/ 可见报错 \/ 清遮罩)\r\n\r\n⚠ 维护提醒: style 字段现在是详情页主脚本, 不要在书源编辑界面里手动改动它,\r\n   也不要把它当成普通 CSS 用。改详情页脚本请改 style 字段, 改门户页请改 startJs\/startStyle。\r\n\n========== [v61] 详情页 HTML 瘦身: 首屏用不到的子系统迁到 injectJs ==========\n背景: v60 把主脚本从 preloadJs 迁到 style 内联后, 详情页 HTML 变成\n      ruleContent(46KB) + style(203KB) ≈ 249KB, 手机端仍然黑屏\/白屏无字。\n      对照历史版本: 46KB HTML + 149KB preloadJs 正常, 195KB 开始黑 ——\n      瓶颈在「单次交给 WebView 的 HTML 体积」, 不在拦截机制。\n\n做法(两步):\n 1) 迁移: ai*(AI 子系统, 71个) + buildPanel(外观设置面板) + cp*(取色器)\n          + z*(图片缩放手势) 共 88 个函数、24 个专属状态量 -> injectJs。\n    injectJs 在 onPageFinished 用 evaluateJavascript 执行, 不计入 HTML 体积。\n    留下首屏渲染链 parse\/renderItem\/layoutImgs\/postRender\/decInit\/frDec* 等。\n 2) 压缩: esbuild --minify --charset=utf8(用 utf8 免得中文被转成 \\uXXXX 反而变大)。\n\n跨作用域方案(关键):\n  · 函数: injectJs 里写成 window.f = function f(...){...}; 包在 with(window){ } 内。\n    函数表达式的闭包作用域含 with 对象, 函数体内的裸名字会沿作用域链动态解析到\n    window 上的同名成员 —— 不用改写任何调用点。\n  · 共享状态量(APP\/BGC\/CP\/FRC\/FRDEC\/ST): PAGE 挂载块里 defineProperty 暴露。\n    ★ 必须写成 (function(){var _v=X; ... get:function(){return _v;}})(); 的形式:\n      getter 里若按名字回查 X, 一旦压缩器认为 X 在 PAGE 中已无人使用而删掉声明,\n      getter 就会读到 window.X 自身 -> 无限递归(Maximum call stack)。\n      先取值再闭包捕获, 既杜绝递归, 也强制压缩器保留声明。\n    ★ 顶层 var 要用逗号连写感知的解析器(var A=1,B=2 只取首名会漏掉 B)。\n    ★ 有些声明夹在两个被迁走的函数之间, 会随函数区间一起被切掉 ——\n      此时它在剩余 PAGE 里找不到声明, 必须从原始 PAGE 取回并一起迁走。\n\n体积变化:\n  style(PAGE)   202803 ->  95251 字符 (-53%)\n  injectJs        2731 ->  50455 字符 (经 evaluateJavascript, 不进 HTML)\n  详情页 HTML     ~249KB -> ~141KB\n\n\n========== [v62] 修复详情页黑屏\/白屏无字 —— ruleContent 丢了 @js: 前缀 ==========\n症状: 点列表卡片进详情页, 完全无字; 手机深色模式下黑屏、浅色模式下白屏, 多个 App 一致。\n      (不是脚本报错 —— 连 injectJs 里\"脚本未加载\"的兜底提示都出不来。)\n\n根因: ruleContent 字段必须以 @js: 开头, Legado 才会把它当 JS 执行\n     (见 BaseSource.evalJS \/ Rss.getContent 对 @js: \/ <js> 前缀的判断)。\n     v59c(e15e860) 的改动里这个前缀被弄丢了, 变成以 \"\\n(function(){\" 开头。\n     没有 @js: 前缀 -> 整个字段被当成【普通规则】(选择器\/JSONPath)去解析 ->\n     脚本一行都不执行 -> WebView 拿到的是空页面 -> 只剩 App 主题底色(黑\/白)。\n\n     对照定位过程(用线上导出的两个版本精确比对字段内容哈希):\n       1274072 (最后一个正常)  ruleContent = '@js:\\n(function(){'\n       e15e860 (第一个黑屏)    ruleContent = '\\n(function(){'   <-- 前缀丢失\n     之后 91443cd \/ c060e69 \/ c0d93aa \/ 02c5cad 全部继承了这个 bug。\n\n     这也解释了为什么之前几轮排查都落空:\n       · 不是 preloadJs 拦截失败(v60 已把主脚本迁到 style, 但仍黑屏)\n       · 不是 HTML 体积(v61 从 249KB 瘦到 141KB, 仍黑屏)\n       · 症状\"完全无字\"本就是强线索: 脚本压根没跑, 而不是跑出错。\n\n修复: ruleContent 补回 @js: 前缀(4 个字符)。\n\n⚠ 防回归: 任何改动 ruleContent 的脚本\/手工编辑, 都必须保证字段以 '@js:' 开头。\n   书源编辑界面里保存时也可能被去掉 —— 改完记得检查开头 4 个字符。\n\n\n=== BUGFIX 2026-09 ===\n修复启动页🎨外观设置与详情页🎨外观设置函数同名冲突。\n- 详情页原 \"window.buildPanel\" 改为 \"window.detailBuildPanel\"\n- \"style.Hi()\" 改为调用 \"window.detailBuildPanel()\"\n- 启动页 \"startJs\" 的 \"buildPanel()\" 保持原样\n- 已验证：首页和详情页外观设置均可正常打开\n- 本次只做函数命名隔离，没有修改正文、AI、小说弹窗等其他功能\n [fixed23: 详情回复后跳新楼层\/悬浮回顶⬆\/首页今日徽标] [fixed24: 卡片双击折叠3行\/下载HTML按钮]","sourceGroup":"论坛RSS","sourceIcon":"https:\/\/bbs.xiaoxiaoshuo8.com\/data\/attachment\/forum\/202609\/07\/041808zlw9am99ldm9moao.png","sourceName":"千白羽论坛","sourceUrl":"https:\/\/bbs.xiaoxiaoshuo8.com\/index.php?mobile=2","startHtml":"<!DOCTYPE html><html><head><meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no\">\n<title>千白羽论坛<\/title><style><\/style><\/head><body>\n<img id=\"bgimg\" alt=\"\">\n<div class=\"wrap\">\n  <div class=\"hero\" id=\"hero\"><div class=\"herobg\" id=\"herobg\"><\/div><div class=\"heroov\" id=\"heroov\"><\/div><div class=\"heroin\"><div class=\"hlg\" id=\"hlg\">千白羽论坛<\/div><div class=\"hsb\" id=\"hsb\">选分类浏览帖子，或直接全站搜索<\/div><\/div><\/div>\n  <div class=\"sbox\"><input id=\"q\" type=\"search\" placeholder=\"搜索帖子标题 \/ 内容…\" autocomplete=\"off\"><button type=\"button\" onclick=\"doSearch()\">搜索<\/button><\/div>\n  <div class=\"tabsrow\"><div class=\"tabs\" id=\"tabs\"><\/div><div class=\"xstab\" id=\"xstab\" onclick=\"xsEnter()\">小说站<\/div><\/div>\n  <div class=\"subbar\">\n    <div class=\"subs\" id=\"subs\"><\/div>\n    <a class=\"pst\" id=\"pst\" href=\"javascript:;\">✏️ 发帖<\/a>\n  <\/div>\n  <div id=\"res\"><div class=\"emp\">请选择一个分类<\/div><\/div>\n<\/div>\n<div class=\"x8top\" id=\"x8top\"><div class=\"x8cats\" id=\"x8tsc\"><div class=\"x8cat\" id=\"x8c0\" onclick=\"x8NavToggle(0)\">推荐阅读<\/div><div class=\"x8cat\" id=\"x8c1\" onclick=\"x8NavToggle(1)\">网址导航<\/div><div class=\"x8cat\" id=\"x8c2\" onclick=\"x8NavToggle(2)\">我的<\/div><\/div><div class=\"x8cls\" id=\"x8cls\" onclick=\"x8NavClose()\" title=\"关闭\">✕<\/div><\/div>\n<div class=\"x8nav\" id=\"x8nav\"><div class=\"x8side\" id=\"x8side\"><\/div><div class=\"x8pane\" id=\"x8pane\"><div class=\"x8phd\" id=\"x8phd\"><\/div><div class=\"x8pbd\" id=\"x8pbd\"><\/div><\/div><\/div>\n<button class=\"fab\" id=\"fab\" onclick=\"bgPanel()\">🎨<\/button>\n<button class=\"fab bell\" id=\"bellFab\" onclick=\"bellPanel()\">🔔<i class=\"bellDot\" id=\"bellDot\">0<\/i><\/button>\n<div class=\"modal\" id=\"bp\" onclick=\"if(event.target===this)closeBG()\"><div class=\"mbox\" id=\"bpb\"><\/div><\/div>\n<div class=\"modal\" id=\"cp\" onclick=\"if(event.target===this)closePicker()\"><div class=\"mbox\">\n  <h3>🎨 选择颜色<\/h3>\n  <div class=\"cprev\"><div class=\"cpv\"><i id=\"cpOld\"><\/i><span>原色<\/span><\/div><div class=\"cpv\"><i id=\"cpNew\"><\/i><span>新色<\/span><\/div><\/div>\n  <div class=\"svbox\" id=\"cpSv\"><i class=\"svcur\" id=\"cpSvC\"><\/i><\/div>\n  <div class=\"huebar\" id=\"cpHue\"><i class=\"huecur\" id=\"cpHueC\"><\/i><\/div>\n  <div class=\"rgbrow\"><label>R<\/label><input type=\"number\" id=\"cpR\" min=\"0\" max=\"255\" oninput=\"cpRgbIn()\"><label>G<\/label><input type=\"number\" id=\"cpG\" min=\"0\" max=\"255\" oninput=\"cpRgbIn()\"><label>B<\/label><input type=\"number\" id=\"cpB\" min=\"0\" max=\"255\" oninput=\"cpRgbIn()\"><\/div>\n  <div class=\"rgbrow\"><label>HEX<\/label><input type=\"text\" id=\"cpHex\" maxlength=\"7\" placeholder=\"#RRGGBB\" oninput=\"cpHexIn()\"><\/div>\n  <div class=\"preset\" id=\"cpPreset\"><\/div>\n  <div class=\"row2\"><button class=\"bt\" onclick=\"clearPicker()\">清除(继承)<\/button><button class=\"bt\" onclick=\"closePicker()\">取消<\/button><\/div>\n  <div class=\"row\"><button class=\"bt pri\" style=\"flex:1\" onclick=\"applyPicker()\">确定<\/button><\/div>\n<\/div><\/div>\n<div class=\"modal\" id=\"io\" onclick=\"if(event.target===this)closeIO()\"><div class=\"mbox\">\n  <h3>📋 配置备份 \/ 恢复<\/h3>\n  <div class=\"hint\">导出：下方文本即当前全部配置 —— 外观设置 + 「我的」分类里的自定义按钮及其容器内容，长按全选复制保存。<br>导入：粘贴文本后点「导入并应用」（「我的」那组按钮会整体换成配置里的那一份）。<\/div>\n  <textarea id=\"ioTa\" rows=\"7\" placeholder=\"点导出生成配置文本，或粘贴配置文本后点导入\"><\/textarea>\n  <div class=\"row2\"><button class=\"bt\" onclick=\"exportCfg()\">导出<\/button><button class=\"bt\" onclick=\"copyCfg()\">复制<\/button><\/div>\n  <div class=\"row\"><button class=\"bt pri\" style=\"flex:1\" onclick=\"importCfg()\">导入并应用<\/button><\/div>\n  <div class=\"row2\"><button class=\"bt\" onclick=\"saveCfgLocal()\">存为本机备份<\/button><button class=\"bt\" onclick=\"loadCfgLocal()\">读取本机备份<\/button><\/div>\n  <div class=\"row2\"><button class=\"bt\" onclick=\"darkPreset()\">深色配色<\/button><button class=\"bt\" onclick=\"lightPreset()\">浅色默认<\/button><\/div>\n  <div class=\"row2\"><button class=\"bt warn\" onclick=\"resetAll()\">恢复出厂设置<\/button><button class=\"bt\" onclick=\"closeIO()\">关闭<\/button><\/div>\n<\/div><\/div>\n<div class=\"modal\" id=\"nb\" onclick=\"if(event.target===this)closeBell()\"><div class=\"mbox\" id=\"nbb\"><div class=\"phd\"><b>🔔 通知<\/b><span style=\"flex:1\"><\/span><button class=\"bt\" onclick=\"closeBell()\">关闭<\/button><\/div><div id=\"nbc\"><div class=\"nb-empty\">加载中…<\/div><\/div><\/div><\/div>\n<div class=\"modal\" id=\"x8ann\" onclick=\"if(event.target===this)closeAnn()\"><div class=\"mbox\" id=\"x8annb\"><\/div><\/div>\n<div class=\"x8lb\" id=\"x8lb\" onclick=\"x8ZoomClose()\"><img id=\"x8lbi\" alt=\"\"><\/div>\n<div class=\"tip\" id=\"tip\"><\/div>\n<\/body><\/html>\n","startJs":"\/* ================= v54 门户首页 =================\n   1) 列表多图: 一行固定高度, 按「行宽 \/ 图宽 \/ 间距」决定一行放几张, 图片自适应行高\n   2) 综合信息栏: 绝对定位在卡片底部, 横跨整行(挤进头像与图片的留白), 单行;\n      放不下时先缩间距、再缩字号, 仍放不下才尾部省略\n   3) 正文摘要: 独占整行, 自动挤入前后留白并换行\n   4) 分类内二级导航(全部\/最新\/热门\/热帖\/精华) + 指向当前分区的发帖按钮\n   5) 置顶帖: 取消「置顶」分区标题, 标题与最后发表同一行\n   6) 最后发表: 每页只请求 1 次并按 URL 缓存(翻回不重复请求)\n   7) 外观设置: 各类容器底色\/透明度\/边框粗细颜色 + 各字段字体独立参数 +\n      页面背景图(填写\/保存\/分类) + 模板新建保存删除 + 配置导入导出 + 悬浮按钮自定义 *\/\nvar ORI='https:\/\/bbs.xiaoxiaoshuo8.com\/';\nvar CATS=[{\"n\": \"小说讨论\", \"fid\": \"2\", \"u\": \"forum.php?mod=forumdisplay&fid=2&mobile=2&page={{page}}\"}, {\"n\": \"求书\", \"fid\": \"3\", \"u\": \"forum.php?mod=forumdisplay&fid=3&mobile=2&page={{page}}\"}, {\"n\": \"催更\", \"fid\": \"6\", \"u\": \"forum.php?mod=forumdisplay&fid=6&mobile=2&page={{page}}\"}, {\"n\": \"慎入\", \"fid\": \"14\", \"u\": \"forum.php?mod=forumdisplay&fid=14&mobile=2&page={{page}}\"}, {\"n\": \"nsfw\", \"fid\": \"13\", \"u\": \"forum.php?mod=forumdisplay&fid=13&mobile=2&page={{page}}\"}, {\"n\": \"sfw\", \"fid\": \"12\", \"u\": \"forum.php?mod=forumdisplay&fid=12&mobile=2&page={{page}}\"}, {\"n\": \"小说\", \"fid\": \"16\", \"u\": \"forum.php?mod=forumdisplay&fid=16&mobile=2&page={{page}}\"}, {\"n\": \"图片\", \"fid\": \"17\", \"u\": \"forum.php?mod=forumdisplay&fid=17&mobile=2&page={{page}}\"}, {\"n\": \"网站\", \"fid\": \"18\", \"u\": \"forum.php?mod=forumdisplay&fid=18&mobile=2&page={{page}}\"}, {\"n\": \"千百羽官方站\", \"fid\": \"11\", \"u\": \"forum.php?mod=forumdisplay&fid=11&mobile=2&page={{page}}\"}, {\"n\": \"应用\", \"fid\": \"10\", \"u\": \"forum.php?mod=forumdisplay&fid=10&mobile=2&page={{page}}\"}, {\"n\": \"网盘\", \"fid\": \"9\", \"u\": \"forum.php?mod=forumdisplay&fid=9&mobile=2&page={{page}}\"}, {\"n\": \"链接\", \"fid\": \"8\", \"u\": \"forum.php?mod=forumdisplay&fid=8&mobile=2&page={{page}}\"}];\n\/* v58: 内置默认头像框, 与帖子正文页的 DFRAMES 完全一致 *\/\n\/* ===== fixed20: 分类栏排序 ===== *\/\nvar CATS_M=CATS;                 \/* 不可变原始顺序(恢复默认用) *\/\nvar KCATS='x8_cats_order_v1';   \/* 自定义顺序持久化键(存 fid 数组 JSON) *\/\nvar CATWORK=null;                \/* 面板里正在编辑的顺序(working copy, fid 数组) *\/\n\/* 按保存的 fid 顺序重排; 列表里没有的新分类追加到末尾 *\/\nfunction catOrderByFids(base,fids){\n  var byFid={},i;\n  for(i=0;i<base.length;i++)byFid[base[i].fid]=base[i];\n  var out=[],seen={};\n  for(i=0;i<fids.length;i++){var f=fids[i];if(byFid[f]&&!seen[f]){out.push(byFid[f]);seen[f]=1;}}\n  for(i=0;i<base.length;i++){if(!seen[base[i].fid])out.push(base[i]);}\n  return out;\n}\n\/* 默认顺序: 应用(fid=10) 紧挨在 求书(fid=3) 之后 *\/\nfunction catDefaultOrderOf(base){\n  var list=base.slice(),iq=-1,ia=-1,i;\n  for(i=0;i<list.length;i++){if(list[i].fid==='3')iq=i;if(list[i].fid==='10')ia=i;}\n  if(iq<0||ia<0)return list;\n  if(ia===iq+1)return list;\n  var app=list.splice(ia,1)[0];\n  var q=iq;if(ia<iq)q=iq-1;     \/* 若应用原在求书之前, 移除后求书下标-1 *\/\n  list.splice(q+1,0,app);\n  return list;\n}\n\/* 启动时解析: 有保存顺序用保存, 否则用默认(应用在求书后) *\/\nfunction catResolve(){\n  CATS=CATS_M.slice();\n  var s=pget(KCATS);\n  if(s){try{var a=JSON.parse(s);if(Array.isArray(a)&&a.length)CATS=catOrderByFids(CATS_M.slice(),a);}catch(e){}}\n  else CATS=catDefaultOrderOf(CATS_M.slice());\n  CATWORK=catFidOrder();\n}\nfunction catFidOrder(){var a=[],i;for(i=0;i<CATS.length;i++)a.push(CATS[i].fid);return a;}\n\/* 生成 #catord 内部 HTML(字符串, 不依赖 DOM 时机) *\/\nfunction catOrdHtml(){\n  if(!CATWORK)CATWORK=catFidOrder();\n  var byFid={},i;\n  for(i=0;i<CATS.length;i++)byFid[CATS[i].fid]=CATS[i].n;\n  var h='',dis1,dis2;\n  for(i=0;i<CATWORK.length;i++){\n    var f=CATWORK[i];\n    dis1=i===0?' disabled':'';dis2=i===CATWORK.length-1?' disabled':'';\n    h+='<div class=\"corow\"><span class=\"con\">'+esc(byFid[f]||f)+'<\/span>'\n      +'<span class=\"cob\">'\n      +'<button class=\"bt sm\" type=\"button\" onclick=\"catOrdMove('+i+',-1)\"'+dis1+'>↑<\/button>'\n      +'<button class=\"bt sm\" type=\"button\" onclick=\"catOrdMove('+i+',1)\"'+dis2+'>↓<\/button>'\n      +'<\/span><\/div>';\n  }\n  return h;\n}\nfunction renderCatOrd(){var el=document.getElementById('catord');if(el)el.innerHTML=catOrdHtml();}\nfunction catOrdMove(k,dir){\n  if(!CATWORK)CATWORK=catFidOrder();\n  var j=k+dir;if(j<0||j>=CATWORK.length)return;\n  var t=CATWORK[k];CATWORK[k]=CATWORK[j];CATWORK[j]=t;\n  renderCatOrd();\n}\nfunction catOrdSave(){\n  if(!CATWORK)CATWORK=catFidOrder();\n  pput(KCATS,JSON.stringify(CATWORK));\n  var curFid=(CATS[cur]&&CATS[cur].fid)||'';\n  CATS=catOrderByFids(CATS_M.slice(),CATWORK);\n  renderTabs();\n  if(curFid){for(var i=0;i<CATS.length;i++){if(CATS[i].fid===curFid){cur=i;break;}}}\n  markTab();renderCatOrd();\n  tip('✔ 已保存分类顺序','ok');\n}\nfunction catOrdReset(){\n  pput(KCATS,'');\n  var curFid=(CATS[cur]&&CATS[cur].fid)||'';\n  CATS=catDefaultOrderOf(CATS_M.slice());\n  CATWORK=catFidOrder();\n  renderTabs();\n  if(curFid){for(var i=0;i<CATS.length;i++){if(CATS[i].fid===curFid){cur=i;break;}}}\n  markTab();renderCatOrd();\n  tip('✔ 已恢复默认顺序','ok');\n}\n\nvar DFRAMES=[{\"u\": \"https:\/\/gd-hbimg.huaban.com\/d847f2d95ab73b0eac98d25b4cae9ff3c050ef361f28e-1codrS_fw658\", \"c\": \"默认\"}, {\"u\": \"https:\/\/gd-hbimg.huaban.com\/160f1aa414759bbe63d45c5169187d9864dd73b3be5b6-5X3G63_fw658\", \"c\": \"默认\"}, {\"u\": \"https:\/\/gd-hbimg.huaban.com\/78faf4a366ea6c34a70f721e89c652dab1df52d313700e-x8Aud7_fw658\", \"c\": \"默认\"}, {\"u\": \"https:\/\/gd-hbimg.huaban.com\/78fe50de5affe6da7e0d8f0f776cd074843bf3eb7137ce-oUtWr7_fw658\", \"c\": \"默认\"}, {\"u\": \"https:\/\/gd-hbimg.huaban.com\/853f39b95dbc7785577cd78ccfb0a75ff2eca9d4492c1-vDp7AS_fw658\", \"c\": \"默认\"}];\nvar DBGS=[{\"u\": \"https:\/\/c-ssl.dtstatic.com\/uploads\/blog\/202406\/08\/GgSbN770Sd4QMWy.thumb.1000_0.png\", \"c\": \"默认\"}, {\"u\": \"https:\/\/c-ssl.duitang.com\/uploads\/blog\/202404\/24\/GgSZdaw3CdXwn3X.jpeg\", \"c\": \"默认\"}, {\"u\": \"https:\/\/pic1.zhimg.com\/v2-7bad831d3495c510e0949cdaeac23fee_1440w.jpg\", \"c\": \"默认\"}, {\"u\": \"https:\/\/picx.zhimg.com\/v2-b27197bcb7d8079c6260542508f14c6f_1440w.jpg\", \"c\": \"默认\"}, {\"u\": \"https:\/\/pic1.zhimg.com\/v2-6fc07084f4c4972d8d2873f2023c5172_1440w.jpg\", \"c\": \"默认\"}];\n\nvar cur=-1,curSub=0,curPage=1,curNext='',loading=false;\n\/* loadSeq: 快速连点分类时, 用序号丢弃已过期的旧响应, 避免旧内容盖掉新内容\n   lastLoadAt: 上次加载完成时间, 供滚动加载的保护期判断 *\/\nvar loadSeq=0,lastLoadAt=0;\nvar SUBS=[],POSTURL='';\n\n\/* ---------------- 工具 ---------------- *\/\nfunction esc(s){return String(s==null?'':s).replace(\/&\/g,'&amp;').replace(\/<\/g,'&lt;').replace(\/>\/g,'&gt;').replace(\/\"\/g,'&quot;');}\nfunction tx(s){return String(s==null?'':s).replace(\/<[^>]*>\/g,'').replace(\/&nbsp;\/g,' ').replace(\/&amp;\/g,'&').replace(\/&quot;\/g,'\"').replace(\/\\s+\/g,' ').trim();}\nfunction ee(s){return String(s==null?'':s).replace(\/&amp;\/g,'&');}\nfunction abs(u){u=ee(String(u||''));return \/^https?:\\\/\\\/\/i.test(u)?u:(ORI+u.replace(\/^\\\/+\/,''));}\nfunction hex2rgba(h,a){\n  h=String(h||'').replace('#','');\n  if(h.length===3)h=h.split('').map(function(c){return c+c;}).join('');\n  var n=parseInt(h,16);if(isNaN(n))return 'transparent';\n  return 'rgba('+((n>>16)&255)+','+((n>>8)&255)+','+(n&255)+','+a+')';\n}\nfunction shadow(v,c){var n=parseFloat(v)||0;return n>0?('0 '+n+'px '+(n*2)+'px '+c):'none';}\nfunction toFile(p){p=String(p||'').trim();if(!p)return '';return \/^(file:|https?:|data:)\/i.test(p)?p:('file:\/\/'+(p.charAt(0)==='\/'?p:('\/'+p)));}\n\n\/* ---------------- 存储: java.put 优先(随书源导出), localStorage 兜底 ---------------- *\/\nvar MEM={};\nfunction pput(k,v){v=String(v);\n  \/* 两层都写: java.put 仅随书源导出用, localStorage 才是跨重进真正持久的层 *\/\n  try{if(window.java&&window.java.put){window.java.put(k,v);}}catch(e){}\n  try{localStorage.setItem(k,v);}catch(e2){}\n  MEM[k]=v;}\nfunction pget(k){\n  \/* 优先读 localStorage(跨重进持久); 其次 java(导出); 最后内存兜底 *\/\n  try{var v2=localStorage.getItem(k);if(v2)return v2;}catch(e2){}\n  try{if(window.java&&window.java.get){var v=window.java.get(k);if(v)return v;}}catch(e){}\n  return MEM[k]||'';}\nfunction jload(k,d){try{var s=pget(k);return s?JSON.parse(s):d;}catch(e){return d;}}\nfunction jsave(k,o){try{pput(k,JSON.stringify(o));}catch(e){}}\n\n\/* ---------------- 配置定义 ----------------\n   每个键: [类型, 默认值, ...]\n     类型 c=颜色(空串=继承)  r=滑块[min,max,step]  t=文本  b=开关[0\/1]  s=下拉[选项] *\/\nvar PDEF={\n \/* 页面 *\/\n pageBg:['c','#F2F3F7'],pageA:['r',100,0,100,1],bgA:['r',100,0,100,1],\n bgFit:['s','cover',[['cover','填充裁切'],['contain','完整显示'],['fill','拉伸铺满'],['repeat','平铺']]],\n \/* 列表卡片 *\/\n cardBg:['c','#FFFFFF'],cardA:['r',100,0,100,1],cardBdW:['r',0,0,8,1],cardBdC:['c','#E4E7F0'],\n cardRd:['r',12,0,30,1],cardSh:['r',0,0,20,1],cardShC:['c','#000000'],\n cardPT:['r',10,0,30,1],cardPR:['r',12,0,30,1],cardPL:['r',12,0,30,1],cardPB:['r',10,0,30,1],cardGap:['r',8,0,24,1],\n \/* 顶部横幅 *\/\n heroOn:['b',1],heroBg:['c','#4A6CF7'],heroA:['r',100,0,100,1],heroBdW:['r',0,0,8,1],heroBdC:['c','#E4E7F0'],\n heroRd:['r',14,0,30,1],heroTx:['c','#FFFFFF'],heroFs:['r',20,12,34,1],heroSubFs:['r',12,9,20,1],\n \/* v57 标题框: 自定义背景图 + 自定义文字 *\/\n heroTxt:['t','千白羽论坛'],heroSub:['t','选分类浏览帖子，或直接全站搜索'],\n heroBi:['t',''],heroBA:['r',100,0,100,1],heroBFit:['s','cover',[['cover','填充裁切'],['contain','完整显示'],['fill','拉伸铺满'],['repeat','平铺']]],\n heroBH:['r',64,32,240,2],heroOv:['r',20,0,100,1],heroOvC:['c','#000000'],\n heroPV:['r',14,0,40,1],heroPH:['r',16,0,40,1],\n \/* 搜索框 *\/\n srchOn:['b',1],sBg:['c','#FFFFFF'],sA:['r',100,0,100,1],sBdW:['r',0,0,8,1],sBdC:['c','#E4E7F0'],\n sRd:['r',10,0,24,1],sTx:['c','#222222'],sFs:['r',14,10,22,1],\n sBtnBg:['c','#4A6CF7'],sBtnTx:['c','#FFFFFF'],sBtnRd:['r',10,0,24,1],sBtnBdW:['r',0,0,8,1],sBtnBdC:['c','#E4E7F0'],sBtnFs:['r',14,10,22,1],\n \/* 分类标签(一级) *\/\n tabBg:['c','#FFFFFF'],tabA:['r',100,0,100,1],tabBdW:['r',0,0,8,1],tabBdC:['c','#E4E7F0'],\n tabRd:['r',999,0,999,1],tabTx:['c','#3A3F52'],tabFs:['r',13,9,22,1],tabPV:['r',8,0,24,1],tabPH:['r',14,0,32,1],tabGap:['r',8,0,24,1],\n tabOnBg:['c','#4A6CF7'],tabOnTx:['c','#FFFFFF'],\n \/* 二级导航(全部\/最新\/热门\/热帖\/精华) *\/\n subOn:['b',1],subBg:['c','#FFFFFF'],subA:['r',100,0,100,1],subBdW:['r',0,0,8,1],subBdC:['c','#E4E7F0'],\n subRd:['r',999,0,999,1],subTx:['c','#3A3F52'],subFs:['r',13,9,22,1],subPV:['r',7,0,24,1],subPH:['r',13,0,32,1],subGap:['r',8,0,24,1],\n subOnBg:['c','#FF6B9D'],subOnTx:['c','#FFFFFF'],\n \/* 发帖按钮 *\/\n pstOn:['b',1],pstBg:['c','#4A6CF7'],pstA:['r',100,0,100,1],pstTx:['c','#FFFFFF'],pstBdW:['r',0,0,8,1],pstBdC:['c','#E4E7F0'],\n pstRd:['r',10,0,24,1],pstFs:['r',13,9,22,1],pstPV:['r',8,0,24,1],pstPH:['r',12,0,32,1],\n \/* 头像 *\/\n avOn:['b',1],avSz:['r',38,0,80,1],avRd:['r',50,0,50,1],avBdW:['r',0,0,8,1],avBdC:['c','#E4E7F0'],avBg:['c','#E8EAF0'],avGap:['r',9,0,20,1],\n \/* v58 头像外框(移植自帖子页): 铺在头像上的一层装饰图。\n    当前用的外框图地址不进 ST, 单独存 KFR(与背景图 BG 的做法一致)。 *\/\n frOn:['b',0],frSz:['r',52,24,120,2],frOffX:['r',0,-40,40,1],frOffY:['r',0,-40,40,1],\n frMode:['s','over',[['over','外框在上'],['under','外框在下']]],\n frA:['r',100,0,100,5],\n \/* 列表图片 *\/\n igOn:['b',1],igRowH:['r',74,30,260,2],igW:['r',33,15,100,1],igGap:['r',6,0,24,1],igRd:['r',8,0,24,1],\n igFit:['s','cover',[['cover','填充裁切'],['contain','完整显示'],['fill','拉伸']]],\n igBdW:['r',0,0,8,1],igBdC:['c','#E4E7F0'],igMax:['r',9,1,20,1],igA:['r',100,0,100,1],igTop:['r',8,0,24,1],\n \/* 标题 *\/\n ttFs:['r',15,10,30,1],ttFw:['r',600,300,900,100],ttLh:['r',145,100,220,5],ttLs:['r',0,-2,8,1],\n ttTx:['c','#222222'],ttIt:['b',0],ttSh:['r',0,0,12,1],ttShC:['c','#000000'],ttLines:['r',2,1,6,1],\n \/* 正文摘要 *\/\n msOn:['b',1],msFs:['r',13,9,24,1],msFw:['r',400,300,900,100],msLh:['r',160,100,220,5],msLs:['r',0,-2,8,1],\n msTx:['c','#666666'],msIt:['b',0],msSh:['r',0,0,12,1],msShC:['c','#000000'],msLines:['r',2,1,8,1],msTop:['r',4,0,20,1],\n \/* 综合信息(作者\/时间\/观看\/回复\/最后发表) *\/\n mtOn:['b',1],mtFs:['r',11,7,22,1],mtFw:['r',400,300,900,100],mtLs:['r',0,-2,8,1],mtTx:['c','#9AA0AE'],\n mtIt:['b',0],mtSh:['r',0,0,12,1],mtShC:['c','#000000'],mtAuto:['b',1],mtMinFs:['r',8,6,22,1],\n mtSep:['t',' · '],mtTop:['r',6,0,24,1],mtBott:['r',8,0,30,1],\n \/* v58: 自动下一页默认开 —— 但只在用户【向下滚动】后才触发(见下方 scroll),\n     切分类\/二级导航导致的页面骤降不会误触发。 *\/\n autoNext:['b',1],\n \/* v59 最后发表: 需要额外请求一次电脑版列表页。已改为首屏渲染完后的空闲时段异步取,\n    不影响其它元素的显示速度; 不需要可以关掉, 能省掉这次请求。 *\/\n lpOn:['b',1],\n auTx:['c',''],tmTx:['c',''],vwTx:['c',''],rpTx:['c',''],lpTx:['c',''],\n \/* 置顶帖 *\/\n tpBg:['c','#FFF8E6'],tpA:['r',100,0,100,1],tpBdW:['r',1,0,8,1],tpBdC:['c','#E8C77A'],tpTx:['c','#8A6D1F'],\n \/* 公告卡片 *\/\n annBg:['c','#E8F0FF'],annA:['r',100,0,100,1],annBdW:['r',1,0,8,1],annBdC:['c','#9DBEF7'],annTx:['c','#2A5BD7'],\n \/* 分区标题 \/ 空态 \/ 加载更多 *\/\n secFs:['r',12,9,22,1],secTx:['c','#8A90A0'],\n empBg:['c','#FFFFFF'],empA:['r',100,0,100,1],empTx:['c','#999999'],empFs:['r',14,10,22,1],empRd:['r',12,0,30,1],\n pgBg:['c','#FFFFFF'],pgA:['r',100,0,100,1],pgTx:['c','#4A6CF7'],pgFs:['r',13,10,22,1],pgRd:['r',10,0,24,1],pgBdW:['r',0,0,8,1],pgBdC:['c','#E4E7F0'],\n \/* 设置弹窗 *\/\n mBg:['c','#FFFFFF'],mA:['r',100,0,100,1],mTx:['c','#2B2D42'],\n dBg:['c','#FAFBFD'],dA:['r',100,0,100,1],dBdC:['c','#E4E7F0'],dRd:['r',10,0,24,1],\n sechBg:['c','#F1F2F7'],sechA:['r',100,0,100,1],hdTx:['c','#3D4256'],lbTx:['c','#5A5F73'],hintTx:['c','#8A8FA8'],\n pk:['c','#4A6CF7'],btnBg:['c','#F1F2F7'],btnTx:['c','#5A5F73'],\n \/* 悬浮设置按钮 *\/\n fabOn:['b',1],fabSz:['r',48,28,88,2],fabRd:['r',50,0,50,1],fabBg:['c','#F1F2F7'],fabA:['r',100,0,100,1],\n fabBdW:['r',1,0,8,1],fabBdC:['c','#E4E7F0'],fabSh:['r',3,0,20,1],fabShC:['c','#000000'],\n fabX:['r',14,0,320,1],fabY:['r',68,0,640,1],fabFs:['r',22,10,40,1],fabTx:['c','#5A5F73'],\n  \/* B批: 铃铛悬浮按钮位置(左上角, 独立于 fab 的 right\/bottom) *\/\n  bellX:['r',14,0,320,1],bellY:['r',14,0,640,1],\n fabEmo:['t','\\ud83c\\udf58'],fabBi:['t',''],\n fabFit:['s','cover',[['cover','填充裁切'],['contain','完整显示'],['manual','手动缩放']]],fabScl:['r',100,20,400,5],\n \/* 章节正文(小说站阅读页) *\/xsFs:['r',17,12,28,1],xsFw:['r',400,100,900,100],xsLh:['r',185,100,300,5],xsLs:['r',0,0,4,1],xsTx:['c','#222'],\n \/* fixed35 正文容器 *\/x8Opa:['r',92,0,100,1],x8DocBg:['c','#FFFFFF'],\n x8Mode:['s','scroll',[['scroll','上下滑动'],['page','左右翻页']]],x8DocH:['r',76,25,100,1]\n};\nvar ST={};\nfor(var _k in PDEF)ST[_k]=PDEF[_k][1];\n(function(){var o=jload('x8p_st',null);if(o&&typeof o==='object'){for(var k in PDEF){if(o[k]!==undefined&&o[k]!==null)ST[k]=o[k];}}})();\nfunction saveST(){jsave('x8p_st',ST);}\n\/* fixed37 一次性迁移: 正文容器默认高度 60vh -> 76vh(「再高一点, 多显示点内容」)。\n   老配置里存着 60 的话不迁移就看不到新高度; 只在没迁移过时执行一次, 之后用户怎么改都尊重。 *\/\n(function(){\n  try{\n    if(pget('x8p_v37doch')==='1')return;\n    if(ST.x8DocH==null||ST.x8DocH===60||ST.x8DocH==='60')ST.x8DocH=76;\n    saveST();pput('x8p_v37doch','1');\n  }catch(e){}\n})();\n\/* v58 一次性迁移: 「下拉到底自动加载下一页」改为默认开启。\n   老配置里存着 0(关闭), 若不迁移, 升级后仍然是关的, 看不到新行为。\n   只在没迁移过时执行一次, 之后用户怎么改都尊重。 *\/\n(function(){\n  try{\n    if(pget('x8p_v58next')==='1')return;\n    ST.autoNext=1;saveST();pput('x8p_v58next','1');\n  }catch(e){}\n})();\n\nvar KBG='x8p_bg',KBGL='x8p_bgl',KBGC='x8p_bgc',KPROF='x8p_prof';\nvar BG=pget(KBG)||'';\nvar BGL=jload(KBGL,null);if(!BGL)BGL=DBGS.slice();\nvar BGC=jload(KBGC,['默认']);\nif(BGC.indexOf('默认')<0)BGC.unshift('默认');\nvar PROF=jload(KPROF,[]);\ntry{var _mr=document.createElement(\"meta\");_mr.setAttribute(\"name\",\"referrer\");_mr.setAttribute(\"content\",\"no-referrer\");var _dh=document.head||document.documentElement;if(_dh)_dh.appendChild(_mr);}catch(e){}\n\/* v58 头像外框: 当前外框(KFR) \/ 自定义外框图列表(KFRD) \/ 分类(KFRC) *\/\nvar KFR='x8p_fr',KFRD='x8p_frd',KFRC='x8p_frc';\nvar FR=pget(KFR)||'';\nvar FRD=jload(KFRD,[]);if(!FRD||typeof FRD.length!=='number')FRD=[];\nvar FRC=jload(KFRC,['默认']);if(FRC.indexOf('默认')<0)FRC.unshift('默认');\n\n\/* ---------------- 样式下发 ---------------- *\/\nfunction applyStyle(){\n  var r=document.documentElement.style;\n  r.setProperty('--pagebg',hex2rgba(ST.pageBg,ST.pageA\/100));\n  r.setProperty('--bga',ST.bgA\/100);\n  r.setProperty('--ttx',ST.ttTx);\n  r.setProperty('--cardbg',hex2rgba(ST.cardBg,ST.cardA\/100));\n  r.setProperty('--cardbdw',ST.cardBdW+'px');\n  r.setProperty('--cardbdc',ST.cardBdC);\n  r.setProperty('--cardrd',ST.cardRd+'px');\n  r.setProperty('--cardsh',shadow(ST.cardSh,ST.cardShC));\n  r.setProperty('--cardpt',ST.cardPT+'px');\n  r.setProperty('--cardpr',ST.cardPR+'px');\n  r.setProperty('--cardpl',ST.cardPL+'px');\n  r.setProperty('--cardgap',ST.cardGap+'px');\n  \/* 综合信息栏常驻底部: 卡片底部预留 = 上间距 + 下间距 + 一行高 *\/\n  r.setProperty('--itpb',ST.mtOn?Math.round(ST.mtTop+ST.mtBott+ST.mtFs*1.5)+'px':ST.cardPB+'px');\n\n  r.setProperty('--herobg',hex2rgba(ST.heroBg,ST.heroA\/100));\n  r.setProperty('--herobdw',ST.heroBdW+'px');\n  r.setProperty('--herobdc',ST.heroBdC);\n  r.setProperty('--herord',ST.heroRd+'px');\n  r.setProperty('--herotx',ST.heroTx);\n  r.setProperty('--herofs',ST.heroFs+'px');\n  r.setProperty('--herosubfs',ST.heroSubFs+'px');\n  \/* v57 标题框背景图 \/ 遮罩 \/ 内边距 *\/\n  r.setProperty('--herobi',ST.heroBi?('url(\"'+String(ST.heroBi).replace(\/[\"\\\\\\n\\r]\/g,'')+'\")'):'none');\n  r.setProperty('--heroba',ST.heroBA);\n  r.setProperty('--herobfit',ST.heroBFit==='repeat'?'auto':ST.heroBFit);\n  r.setProperty('--herobh',ST.heroBH+'px');\n  r.setProperty('--heroov',ST.heroOv);\n  r.setProperty('--heroovc',ST.heroOvC);\n  r.setProperty('--heropv',ST.heroPV+'px');\n  r.setProperty('--heroph',ST.heroPH+'px');\n  syncHero();\n\n  r.setProperty('--sbg',hex2rgba(ST.sBg,ST.sA\/100));\n  r.setProperty('--sbdw',ST.sBdW+'px');\n  r.setProperty('--sbdc',ST.sBdC);\n  r.setProperty('--srd',ST.sRd+'px');\n  r.setProperty('--stx',ST.sTx);\n  r.setProperty('--sfs',ST.sFs+'px');\n  r.setProperty('--sbtnbg',hex2rgba(ST.sBtnBg,ST.sA\/100));\n  r.setProperty('--sbtntx',ST.sBtnTx);\n  r.setProperty('--sbtnrd',ST.sBtnRd+'px');\n  r.setProperty('--sbtnbdw',ST.sBtnBdW+'px');\n  r.setProperty('--sbtnbdc',ST.sBtnBdC);\n  r.setProperty('--sbtnfs',ST.sBtnFs+'px');\n\n  r.setProperty('--tabbg',hex2rgba(ST.tabBg,ST.tabA\/100));\n  r.setProperty('--tabbdw',ST.tabBdW+'px');\n  r.setProperty('--tabbdc',ST.tabBdC);\n  r.setProperty('--tabrd',(ST.tabRd>=999?'999px':ST.tabRd+'px'));\n  r.setProperty('--tabtx',ST.tabTx);\n  r.setProperty('--tabfs',ST.tabFs+'px');\n  r.setProperty('--tabpv',ST.tabPV+'px');\n  r.setProperty('--tabph',ST.tabPH+'px');\n  r.setProperty('--tabgap',ST.tabGap+'px');\n  r.setProperty('--tabonbg',ST.tabOnBg);\n  r.setProperty('--tabontx',ST.tabOnTx);\n\n  r.setProperty('--subbg',hex2rgba(ST.subBg,ST.subA\/100));\n  r.setProperty('--subbdw',ST.subBdW+'px');\n  r.setProperty('--subbdc',ST.subBdC);\n  r.setProperty('--subrd',(ST.subRd>=999?'999px':ST.subRd+'px'));\n  r.setProperty('--subtx',ST.subTx);\n  r.setProperty('--subfs',ST.subFs+'px');\n  r.setProperty('--subpv',ST.subPV+'px');\n  r.setProperty('--subph',ST.subPH+'px');\n  r.setProperty('--subgap',ST.subGap+'px');\n  r.setProperty('--subonbg',ST.subOnBg);\n  r.setProperty('--subontx',ST.subOnTx);\n\n  r.setProperty('--pstbg',hex2rgba(ST.pstBg,ST.pstA\/100));\n  r.setProperty('--pstbdw',ST.pstBdW+'px');\n  r.setProperty('--pstbdc',ST.pstBdC);\n  r.setProperty('--pstrd',ST.pstRd+'px');\n  r.setProperty('--psttx',ST.pstTx);\n  r.setProperty('--pstfs',ST.pstFs+'px');\n  r.setProperty('--pstpv',ST.pstPV+'px');\n  r.setProperty('--pstph',ST.pstPH+'px');\n\n  r.setProperty('--avsz',ST.avOn?ST.avSz+'px':'0px');\n  r.setProperty('--avrd',(ST.avRd>=50?'50%':ST.avRd+'px'));\n  r.setProperty('--avbdw',ST.avBdW+'px');\n  r.setProperty('--avbdc',ST.avBdC);\n  r.setProperty('--avbg',ST.avBg);\n  r.setProperty('--avgap',ST.avOn?ST.avGap+'px':'0px');\n  \/* v58 头像外框: 外框层默认与头像同大, 再靠 scale 放大到 frSz\n     (不用 calc, 老 WebView 对 transform 里的 calc 支持不稳) *\/\n  var _fru=(ST.frOn&&FR)?(String(FR).split('\"').join('').split('\\\\').join('')):'';\n  r.setProperty('--frimg',_fru?('url(\"'+_fru+'\")'):'none');\n  r.setProperty('--frscale',(ST.avSz>0?(ST.frSz\/ST.avSz):1));\n  r.setProperty('--frx',ST.frOffX+'px');\n  r.setProperty('--fry',ST.frOffY+'px');\n  r.setProperty('--fra',ST.frA\/100);\n\n  r.setProperty('--iggap',ST.igGap+'px');\n  r.setProperty('--igrd',ST.igRd+'px');\n  r.setProperty('--igbdw',ST.igBdW+'px');\n  r.setProperty('--igbdc',ST.igBdC);\n  r.setProperty('--igfit',ST.igFit);\n  r.setProperty('--iga',ST.igA);\n  r.setProperty('--igtop',ST.igTop+'px');\n\n  r.setProperty('--ttfs',ST.ttFs+'px');\n  r.setProperty('--ttfw',ST.ttFw);\n  r.setProperty('--ttlh',(ST.ttLh\/100));\n  r.setProperty('--ttls',ST.ttLs+'px');\n  r.setProperty('--tttx',ST.ttTx);\n  r.setProperty('--ttit',ST.ttIt?'italic':'normal');\n  r.setProperty('--ttsh',ST.ttSh?('0 1px '+ST.ttSh+'px '+ST.ttShC):'none');\n  r.setProperty('--ttlines',ST.ttLines);\n  r.setProperty('--xsfs',ST.xsFs+'px');\n  r.setProperty('--xsfw',ST.xsFw);\n  r.setProperty('--xslh',(ST.xsLh\/100));\n  r.setProperty('--xsls',ST.xsLs+'px');\n  r.setProperty('--xstx',ST.xsTx);\n  \/* fixed35 正文容器底色(hex + 可调透明度) \/ 高度 *\/\n  r.setProperty('--x8docbg',hex2rgba(ST.x8DocBg||'#FFFFFF',(ST.x8Opa==null?92:ST.x8Opa)\/100));\n  r.setProperty('--x8doch',(ST.x8DocH==null?76:ST.x8DocH)+'vh');\n\n  r.setProperty('--msfs',ST.msFs+'px');\n  r.setProperty('--msfw',ST.msFw);\n  r.setProperty('--mslh',(ST.msLh\/100));\n  r.setProperty('--msls',ST.msLs+'px');\n  r.setProperty('--mstx',ST.msTx);\n  r.setProperty('--msit',ST.msIt?'italic':'normal');\n  r.setProperty('--mssh',ST.msSh?('0 1px '+ST.msSh+'px '+ST.msShC):'none');\n  r.setProperty('--mslines',ST.msLines);\n  r.setProperty('--mstop',ST.msTop+'px');\n\n  r.setProperty('--mtfs',ST.mtFs+'px');\n  r.setProperty('--mtfw',ST.mtFw);\n  r.setProperty('--mtls',ST.mtLs+'px');\n  r.setProperty('--mttx',ST.mtTx);\n  r.setProperty('--mtit',ST.mtIt?'italic':'normal');\n  r.setProperty('--mtsh',ST.mtSh?('0 1px '+ST.mtSh+'px '+ST.mtShC):'none');\n  r.setProperty('--mtbott',ST.mtBott+'px');\n  r.setProperty('--autx',ST.auTx||'inherit');\n  r.setProperty('--lptx',ST.lpTx||ST.mtTx);   \/* v59: 最后发表, 空则跟随综合信息 *\/\n  \/* 供 .lp 的 ::before 分隔符使用(与「分隔符」设置保持一致) *\/\n  r.setProperty('--mtsep','\"'+String(ST.mtSep||' · ').replace(\/\"\/g,'\\\\\"')+'\"');\n  r.setProperty('--tmtx',ST.tmTx||'inherit');\n  r.setProperty('--vwtx',ST.vwTx||'inherit');\n  r.setProperty('--rptx',ST.rpTx||'inherit');\n\n  r.setProperty('--tpbg',hex2rgba(ST.tpBg,ST.tpA\/100));\n  r.setProperty('--tpbdw',ST.tpBdW+'px');\n  r.setProperty('--tpbdc',ST.tpBdC);\n  r.setProperty('--tptx',ST.tpTx||ST.ttTx);\n  r.setProperty('--annbg',hex2rgba(ST.annBg,ST.annA\/100));\n  r.setProperty('--annbdw',ST.annBdW+'px');\n  r.setProperty('--annabdc',ST.annBdC);\n  r.setProperty('--anntx',ST.annTx||ST.ttTx);\n\n  r.setProperty('--secfs',ST.secFs+'px');\n  r.setProperty('--sectx',ST.secTx);\n  r.setProperty('--empbg',hex2rgba(ST.empBg,ST.empA\/100));\n  r.setProperty('--emptx',ST.empTx);\n  r.setProperty('--empfs',ST.empFs+'px');\n  r.setProperty('--emprd',ST.empRd+'px');\n  r.setProperty('--pgbg',hex2rgba(ST.pgBg,ST.pgA\/100));\n  r.setProperty('--pgtx',ST.pgTx);\n  r.setProperty('--pgfs',ST.pgFs+'px');\n  r.setProperty('--pgrd',ST.pgRd+'px');\n  r.setProperty('--pgbdw',ST.pgBdW+'px');\n  r.setProperty('--pgbdc',ST.pgBdC);\n\n  r.setProperty('--mbg',hex2rgba(ST.mBg,ST.mA\/100));\n  r.setProperty('--mtx',ST.mTx);\n  r.setProperty('--dbg',hex2rgba(ST.dBg,ST.dA\/100));\n  r.setProperty('--dbdc',ST.dBdC);\n  r.setProperty('--drd',ST.dRd+'px');\n  r.setProperty('--sechbg',hex2rgba(ST.sechBg,ST.sechA\/100));\n  r.setProperty('--hdtx',ST.hdTx);\n  r.setProperty('--lbtx',ST.lbTx);\n  r.setProperty('--hintx',ST.hintTx);\n  r.setProperty('--pk',ST.pk);\n  r.setProperty('--btnbg',ST.btnBg);\n  r.setProperty('--btntx',ST.btnTx);\n\n  r.setProperty('--fabsz',ST.fabSz+'px');\n  r.setProperty('--fabr',(ST.fabRd>=50?'50%':ST.fabRd+'px'));\n  r.setProperty('--fabbgcol',hex2rgba(ST.fabBg,ST.fabA\/100));\n  r.setProperty('--fabbgimg',ST.fabBi?('url(\"'+String(ST.fabBi).replace(\/[\"\\\\\\n\\r]\/g,'')+'\")'):'none');\n  r.setProperty('--fabbgsz',(ST.fabFit==='manual')?(ST.fabScl+'%'):ST.fabFit);\n  r.setProperty('--fabbdw',ST.fabBdW+'px');\n  r.setProperty('--fabbdc',ST.fabBdC);\n  r.setProperty('--fabsh',shadow(ST.fabSh,ST.fabShC));\n  r.setProperty('--fabx',ST.fabX+'px');\n  r.setProperty('--faby',ST.fabY+'px');\n  r.setProperty('--bellx',ST.bellX+'px');\n  r.setProperty('--bella',ST.bellY+'px');\n  r.setProperty('--fabfs',ST.fabFs+'px');\n  r.setProperty('--fabtx',ST.fabTx);\n  try{\n    var fb=document.getElementById('fab');\n    if(fb){fb.textContent=ST.fabEmo||'';fb.style.display=ST.fabOn?'flex':'none';}\n  }catch(e){}\n  try{\n    var he=document.getElementById('hero');if(he)he.style.display=ST.heroOn?'':'none';\n    var sb=document.querySelector('.sbox');if(sb)sb.style.display=ST.srchOn?'flex':'none';\n    var sbb=document.querySelector('.subbar');if(sbb)sbb.style.display=ST.subOn?'flex':'none';\n    var ps=document.getElementById('pst');if(ps)ps.style.display=ST.pstOn?'':'none';\n    \/* 布尔开关回显(构建面板前这些控件可能不存在, 故逐个判空) *\/\n    var ln=document.getElementById('slpOn0'),ln1=document.getElementById('slpOn1');\n    if(ln)ln.className='msw'+(ST.lpOn?'':' on');\n    if(ln1)ln1.className='msw'+(ST.lpOn?' on':'');\n    var an=document.getElementById('san0'),an1=document.getElementById('san1');\n    if(an)an.className='msw'+(ST.autoNext?'':' on');\n    if(an1)an1.className='msw'+(ST.autoNext?' on':'');\n  }catch(e2){}\n}\n\/* v57 标题框文字与背景图同步(文字是 textContent, 不能走 CSS 变量) *\/\nfunction syncHero(){\n  try{\n    var a=document.getElementById('hlg'),b=document.getElementById('hsb');\n    if(a)a.textContent=ST.heroTxt;\n    if(b)b.textContent=ST.heroSub;\n    var ov=document.getElementById('heroov');\n    if(ov)ov.style.display=ST.heroBi?'':'none';  \/* 没背景图就不需要遮罩 *\/\n  }catch(e){}\n}\nfunction applyBG(){\n  var im=document.getElementById('bgimg');\n  if(!im)return;\n  if(!BG){im.style.display='none';document.body.style.backgroundImage='';return;}\n  if(ST.bgFit==='repeat'){\n    im.style.display='none';\n    document.body.style.backgroundImage='url(\"'+BG+'\")';\n    document.body.style.backgroundRepeat='repeat';\n    document.body.style.backgroundSize='auto';\n  }else{\n    document.body.style.backgroundImage='';\n    im.style.display='block';\n    im.src=BG;\n    im.style.objectFit=ST.bgFit;\n  }\n}\n\n\/* ---------------- 取值器 ---------------- *\/\n\/* v58: 半截 HTML 校验 + 自动重试。\n   ★ 根因: 请求偶尔被中断(网络抖动 \/ CDN \/ WebView 超时), 拿到【半截】HTML。\n     列表页里置顶帖永远排在最前面, 所以半截 HTML 解析出来往往只剩一个置顶帖 ——\n     表现就是「不管点哪个分类或筛选, 都只显示同一个帖子」, 而且不报错。\n     实测把正常页面截断到 15% 解析, 得到的正是 1 张卡片(置顶帖「给网站取名」)。\n   ★ 判据: 正常页面一定以 <\/html> 收尾; 没有就是被截断了。\n     >512 字符才判, 避免把 404\/错误短页面也算成截断而白重试。 *\/\n\/* 半截判据(放宽松): 只要出现 <\/html> 或 <\/body> 任一闭标签就认为完整。\n   只认 <\/html> 太严: 有些响应只到 <\/body>(或末尾被 CDN 截断一点点),\n   会被误判成半截 -> 白白重试 3 次, 列表反而卡在「加载中」更久。 *\/\nfunction isTrunc(t){\n  if(!t||t.length<=512)return false;\n  if(\/<\\\/html\\s*>\/i.test(t))return false;\n  if(\/<\\\/body\\s*>\/i.test(t))return false;\n  return true;\n}\nfunction fb(u,res,rej){\n  fetch(u,{credentials:'include'}).then(function(r){return r.text();}).then(function(t){res(String(t||''));},rej);\n}\nfunction fetchOnce(u){\n  return new Promise(function(res,rej){\n    if(window.ajaxAwait){\n      try{window.ajaxAwait(u).then(function(t){res(String(t||''));},function(){fb(u,res,rej);});return;}catch(e){}\n    }\n    \/* 门户页是 loadDataWithBaseURL 加载的, 主框架 URL 形如 data:text\/html;,\n       而 ReadRssActivity.shouldInterceptRequest 对 data:text\/html; 直接放行、\n       不注入 JS_INJECTION —— 所以门户页里【没有 ajaxAwait】, 只能退回 fetch。\n       但 addJavascriptInterface 注入的 java 一直可用, java.ajax 比 fetch 可靠:\n       它走 APP 自己的网络栈(带 Cookie \/ UA), 不受页面 CORS 限制。 *\/\n    if(typeof java!=='undefined'&&java&&typeof java.ajax==='function'){\n      try{\n        var jt=java.ajax(u);\n        if(jt&&String(jt).length>0){res(String(jt));return;}\n      }catch(e){}\n    }\n    fb(u,res,rej);   \/* 最后才用 fetch *\/\n  });\n}\n\/* 最多尝试 3 次: 半截 或 直接失败 都重试; 仍不行才交回上层报错,\n   不再静默把半截页面显示成「只有一帖」。 *\/\nfunction getHtml(u){\n  return new Promise(function(res,rej){\n    var n=0;\n    function go(){\n      fetchOnce(u).then(function(t){\n        if(isTrunc(t)&&n<2){n++;go();return;}\n        res(t);\n      },function(e){\n        if(n<2){n++;go();return;}\n        rej(e);\n      });\n    }\n    go();\n  });\n}\n\n\/* ---------------- v59 最后发表: 每页只请求一次, 按 URL 缓存 ---------------- *\/\nvar LMC={};\n\/* ===== v63 置顶帖详情: Discuz 移动接口 JSON 透传 =====\n   接口: api\/mobile\/index.php?version=4&module=forumdisplay&fid=X&page=N\n   Variables.forum_threadlist[] 里每个主题自带:\n     author \/ views \/ replies \/ lastposter \/ lastpost \/ message(楼主正文) \/ reply[](最后几条回复)\n   一次请求就能补齐置顶帖需要的全部字段, 同时替代原来那次「电脑版 mobile=no」HTML 请求。 *\/\nvar TPM={},LASTPC='';\nfunction apiUrl(u){\n  u=ee(String(u||''));\n  if(u.indexOf('mod=forumdisplay')<0)return '';\n  var fid=(u.match(\/fid=(\\d+)\/)||[])[1]||'';\n  if(!fid)return '';\n  var pg=(u.match(\/[?&]page=(\\d+)\/)||[])[1]||'1';\n  return ORI+'api\/mobile\/index.php?version=4&module=forumdisplay&fid='+fid+'&page='+pg;\n}\nfunction parseApi(t){\n  var lm={},tp={};\n  try{\n    var j=JSON.parse(String(t||'{}'));\n    var tl=(((j||{}).Variables||{}).forum_threadlist)||[];\n    for(var i=0;i<tl.length;i++){\n      var o=tl[i]||{},id=String(o.tid||'');\n      if(!id)continue;\n      var dd={au:tx(o.author||''),at:tx(o.dateline||''),vw:tx(o.views||''),rp:tx(o.replies||''),\n              lpA:tx(o.lastposter||''),lpT:tx(o.lastpost||''),sum:tx(o.message||''),\n              lastAu:'',lastTx:''};\n      var r=o.reply;\n      if(r&&r.length){var Lz=r[r.length-1]||{};dd.lastAu=tx(Lz.author||'');dd.lastTx=tx(Lz.message||'');}\n      if(!dd.lastAu)dd.lastAu=dd.lpA;\n      if(!dd.lastTx)dd.lastTx=dd.sum;\n      tp[id]=dd;\n      if(dd.lpA)lm[id]=dd.lpA+(dd.lpT?(' '+dd.lpT):'');\n    }\n  }catch(e){}\n  return {lm:lm,tp:tp};\n}\n\/* 优先走移动接口 JSON; 不是板块列表(如搜索页)或接口失败时, 退回原来的电脑版 HTML 解析 *\/\nfunction fetchDesk(u){\n  var pc=String(u).replace(\/mobile=2\/,'mobile=no');LASTPC=pc;\n  if(LMC[pc]&&TPM[pc])return Promise.resolve(LMC[pc]);\n  var au=apiUrl(u);\n  if(au){\n    \/* JSON 里没有 <\/html>, 不能用 getHtml(会被 isTrunc 误判成半截而重试 3 次) *\/\n    return fetchOnce(au).then(function(t){\n      var r=parseApi(t),n=0,k;\n      for(k in r.tp){if(r.tp.hasOwnProperty(k))n++;}\n      if(!n)throw new Error('emptyApi');\n      LMC[pc]=r.lm;TPM[pc]=r.tp;return r.lm;\n    })['catch'](function(){return fetchDeskOld(u,pc);});\n  }\n  return fetchDeskOld(u,pc);\n}\nfunction fetchDeskOld(u,pc){\n  return getHtml(pc).then(function(h){\n    var m=parseLast(h);LMC[pc]=m;try{TPM[pc]=parseTop(h);}catch(e){TPM[pc]={};}return m;\n  })['catch'](function(){return {};});\n}\nfunction parseTop(h){\n  var map={},re=\/<tbody id=\"(?:normalthread|stickthread)_(\\d+)\"[\\s\\S]*?<\\\/tbody>\/g,m;\n  while((m=re.exec(h))!==null){\n    var blk=m[0],dd={},pr=blk.split(\/<td class=\"by\">\/);\n    if(pr.length>=2){\n      var au=pr[1].match(\/<cite>[\\s\\S]*?<a[^>]*>([\\s\\S]*?)<\\\/a>\/);\n      if(au)dd.au=tx(au[1]);\n      var at=pr[1].match(\/<em>[\\s\\S]*?>([\\s\\S]*?)<\\\/em>\/)||pr[1].match(\/<em>([\\s\\S]*?)<\\\/em>\/);\n      if(at)dd.at=tx(at[1]);\n    }\n    if(pr.length>=3){\n      var lz=pr[pr.length-1];\n      var la=lz.match(\/<cite>[\\s\\S]*?<a[^>]*>([\\s\\S]*?)<\\\/a>\/);\n      var lt=lz.match(\/<em>[\\s\\S]*?>([\\s\\S]*?)<\\\/em>\/)||lz.match(\/<em>([\\s\\S]*?)<\\\/em>\/);\n      if(la)dd.lpA=tx(la[1]);\n      if(lt)dd.lpT=tx(lt[1]);\n    }\n    var nm=blk.match(\/<td class=\"num\">[\\s\\S]*?<\\\/td>\/);\n    if(nm){\n      var rp=nm[0].match(\/<a[^>]*>(\\d+)<\\\/a>\/),vw=nm[0].match(\/<em>(\\d+)<\\\/em>\/);\n      if(rp)dd.rp=rp[1];if(vw)dd.vw=vw[1];\n    }\n    dd.lastAu=dd.lpA||'';dd.lastTx='';\n    if(dd.au||dd.rp||dd.lpA)map[m[1]]=dd;\n  }\n  return map;\n}\nfunction tpFmtLpT(s){\n  s=String(s||'').trim();\n  if(!s)return '';\n  var m=s.match(\/(\\d{4})[-\/.年](\\d{1,2})[-\/.月](\\d{1,2})\\D*(\\d{1,2}:\\d{2})?\/);\n  if(m)return m[2]+'-'+m[3]+(m[4]?(' '+m[4]):'');\n  var m2=s.match(\/(\\d{1,2})[-\/.](\\d{1,2})(?:\\D+(\\d{1,2}:\\d{2}))?\/);\n  if(m2)return m2[1]+'-'+m2[2]+(m2[3]?(' '+m2[3]):'');\n  return s;\n}\nfunction tpMeta(dd){\n  var p=[];\n  if(dd.lpA)p.push('\\u21a9 '+esc(dd.lpA));\n  var t=tpFmtLpT(dd.lpT);\n  if(t)p.push(t);\n  return p.join(' · ');\n}\nfunction tpFull(dd){\n  var s='<div class=\"tpfl\">';\n  if(dd.au)s+='<span class=\"tpi\">\\ud83d\\udc64 作者 <b>'+esc(dd.au)+'<\/b><\/span>';\n  if(dd.at)s+='<span class=\"tpi\">\\ud83d\\udd52 '+esc(dd.at)+'<\/span>';\n  if(dd.vw)s+='<span class=\"tpi\">\\ud83d\\udc41 观看 <b>'+esc(dd.vw)+'<\/b><\/span>';\n  if(dd.rp)s+='<span class=\"tpi\">\\ud83d\\udcac 回复 <b>'+esc(dd.rp)+'<\/b><\/span>';\n  if(dd.lpA||dd.lpT)s+='<span class=\"tpi lp\">\\u21a9 最后发表 <b>'+esc(dd.lpA||'')+'<\/b>'+(dd.lpT?(' '+esc(dd.lpT)):'')+'<\/span>';\n  return s+'<\/div>';\n}\nfunction fillTop(){\n  var m=TPM[LASTPC]||{};\n  var ns=document.querySelectorAll('#res .tpc[data-tid]'),i;\n  for(i=0;i<ns.length;i++){\n    var t=ns[i].getAttribute('data-tid');if(!t)continue;\n    var dd=m[t];if(!dd)continue;\n    var c=ns[i].querySelector('.tpmeta');if(c)c.innerHTML=tpMeta(dd);\n    var f=ns[i].querySelector('.tpfull');if(f)f.innerHTML=tpFull(dd);\n    var x=ns[i].querySelector('.tpext');if(x)x.innerHTML=tpExt(dd);\n  }\n}\nfunction tpExt(dd){\n  var s='';\n  if(dd.sum)s+='<div class=\"tpsum\"><i>摘要<\/i>'+esc(dd.sum)+'<\/div>';\n  if(dd.lastTx)s+='<div class=\"tplast\"><i>最后回复<\/i>'+(dd.lastAu?('<b>'+esc(dd.lastAu)+'<\/b> '):'')+esc(dd.lastTx)+'<\/div>';\n  return s||'<div class=\"tpld\">暂无内容<\/div>';\n}\n\/* ---- 展开 \/ 折叠 ---- *\/\nfunction tpStop(e){try{if(e&&e.stopPropagation)e.stopPropagation();}catch(_){}}\nfunction tpToggle(row){\n  try{\n    var c=row&&row.parentNode;if(!c||c.className.indexOf('tpc')<0)return;\n    if(c.className.indexOf('open')>=0)c.className=c.className.replace(\/\\s*open\/g,'');\n    else c.className+=' open';\n  }catch(e){}\n}\nfunction tpToggleAll(hd){\n  try{\n    var box=hd&&hd.parentNode;if(!box)return;\n    var ls=box.querySelectorAll('.tpc'),i;\n    var st=parseInt(box.getAttribute('data-tpst')||'0',10)%3;  \/* 0=仅标题(B) 1=全展开(A) 2=各卡单行(C) *\/\n    st=(st+1)%3;\n    box.setAttribute('data-tpst',st);\n    if(st===0){            \/* B: 折叠为仅容器标题 *\/\n      box.className=box.className.replace(\/\\s*open\/g,'');\n      for(i=0;i<ls.length;i++)ls[i].className=ls[i].className.replace(\/\\s*open\/g,'');\n    }else if(st===1){     \/* A: 全部展开 *\/\n      if(box.className.indexOf('open')<0)box.className+=' open';\n      for(i=0;i<ls.length;i++)if(ls[i].className.indexOf('open')<0)ls[i].className+=' open';\n    }else{                 \/* C: 容器展开, 各卡单行折叠 *\/\n      if(box.className.indexOf('open')<0)box.className+=' open';\n      for(i=0;i<ls.length;i++)ls[i].className=ls[i].className.replace(\/\\s*open\/g,'');\n    }\n  }catch(e){}\n}\nfunction tpBoxHtml(cards){\n  return '<div class=\"tpbox\" data-tpst=\"0\">'\n    +'<div class=\"tphd\" onclick=\"tpToggleAll(this)\">'\n      +'<span class=\"tphn\">\\ud83d\\udccc 置顶 · '+cards.length+' 条<\/span>'\n      +'<span class=\"tphr\">\\u25be<\/span>'\n    +'<\/div>'\n    +'<div class=\"tplst\">'+cards.join('')+'<\/div>'\n  +'<\/div>';\n}\nfunction parseLast(h){\n  var map={},re=\/<tbody id=\"(?:normalthread|stickthread)_(\\d+)\"[\\s\\S]*?<\\\/tbody>\/g,m;\n  while((m=re.exec(h))!==null){\n    var pr=m[0].split(\/<td class=\"by\">\/);\n    if(pr.length>=3){\n      var lz=pr[pr.length-1];\n      var la=lz.match(\/<cite>[\\s\\S]*?<a[^>]*>([\\s\\S]*?)<\\\/a>\/);\n      var lt=lz.match(\/<em>[\\s\\S]*?>([\\s\\S]*?)<\\\/em>\/)||lz.match(\/<em>([\\s\\S]*?)<\\\/em>\/);\n      if(la){\n        var nm=tx(la[1]),tm=lt?tx(lt[1]):'';\n        if(nm)map[m[1]]=nm+(tm?' '+tm:'');\n      }\n    }\n  }\n  return map;\n}\n\/* 用与列表完全相同的筛选条件取电脑版, 保证 tid 集合一致 *\/\nfunction fetchLast(u){\n  if(!ST.lpOn)return Promise.reject(new Error('lpOff'));   \/* 关掉就一个请求都不发 *\/\n  var pc=String(u).replace(\/mobile=2\/,'mobile=no');\n  if(LMC[pc])return Promise.resolve(LMC[pc]);\n  return getHtml(pc).then(function(h){\n    var m=parseLast(h);LMC[pc]=m;return m;\n  })['catch'](function(){return {};});\n}\n\/* v59 回填: 只写 .lp 这一个节点的 textContent。\n   ★ 不再重建整条 .mt 的 innerHTML(那是 v57 卡顿的主因);\n   fitMeta 只在确实填入内容后统一跑一次。 *\/\nfunction fillLast(lm){\n  var ns=document.querySelectorAll('#res .lp[data-tid]'),i,ch=0;\n  for(i=0;i<ns.length;i++){\n    var t=ns[i].getAttribute('data-tid');\n    if(!t)continue;\n    var v=lm[t]||'';\n    if(v){ns[i].textContent='\\u21a9 '+v;ch=1;}\n  }\n  if(ch)fitMeta();\n}\n\/* ★ 关键: 首屏渲染完 + 空闲后, 才去取「最后发表」。\n   这样既不占用首屏带宽, 也不阻塞任何已有元素的渲染与图片解码。 *\/\nfunction scheduleLast(u,seq){\n  \/* v63: 这唯一一次请求现在同时供「最后发表」和「置顶帖详情」使用。\n     关掉「最后发表」时, 只有页面上确实存在置顶卡才发, 避免白白多一个请求。 *\/\n  if(!ST.lpOn){\n    try{ if(!document.querySelector('#res .tpc'))return; }catch(e){}\n  }\n  defer(function(){\n    if(seq!==loadSeq)return;                 \/* 已被更新的请求取代 *\/\n    fetchDesk(u).then(function(lm){\n      if(seq!==loadSeq)return;\n      defer(function(){\n        try{if(ST.lpOn)fillLast(lm||{});}catch(e){}\n        try{fillTop();}catch(e){}\n      });                                    \/* 回填同样让位给主线程 *\/\n    })['catch'](function(){});\n  });\n}\n\n\/* ---------------- 列表解析 ---------------- *\/\n\/* 解析论坛列表页里的站点公告(<th><strong class=\"xst\">公告: <a ...>...<\/a><\/strong><\/th>) *\/\nfunction parseAnnounce(h){\n  try{\n    var m=String(h||'').match(\/<li[^>]*class=\"[^\"]*list_top[^\"]*\"[^>]*>\\s*<a[^>]*href=\"([^\"]*announcement[^\"]*)\"[^>]*>([\\s\\S]*?)<\\\/a>\/i);\n    if(!m)return '';\n    \/* 源码里的 href 已是 HTML 转义(&amp;), 先解码再 esc, 避免双重转义成 &amp;amp; *\/\n    var href=esc(abs(m[1].replace(\/&amp;\/g,'&')));\n    var txt=tx(m[2]).replace(\/^公告\\s*\/,'')||'公告';\n    \/* href 已在上面 esc 过, 这里直接拼接, 不要再 esc 一次 *\/\n    return '<a class=\"it ann\" href=\"'+href+'\">'\n      +'<span class=\"tt\">\\ud83d\\udce2 公告: '+esc(txt)+'<\/span><\/a>';\n  }catch(e){return '';}\n}\n\nfunction splitItems(h){\n  var out=[],re=\/<li class=\"(list_top|list)\"\/g,m,st=[];\n  while((m=re.exec(h))!==null)st.push({i:m.index,cls:m[1]});\n  for(var k=0;k<st.length;k++){\n    var end=(k+1<st.length)?st[k+1].i:h.length;\n    var s=h.slice(st[k].i,end);\n    var li=s.lastIndexOf('<\/li>');\n    if(li>0)s=s.slice(0,li+5);\n    out.push({cls:st[k].cls,h:s});\n  }\n  return out;\n}\nfunction itemImgs(b){\n  var m=b.match(\/<div class=\"[^\"]*threadlist_imgs[^\"]*\"[^>]*>([\\s\\S]*?)<\\\/div>\/);\n  if(!m)return [];\n  var out=[],re=\/<img[^>]+src=\"([^\"]+)\"\/g,x;\n  while((x=re.exec(m[1]))!==null)out.push(abs(x[1]));\n  return out;\n}\n\/* 综合信息: 作者 \/ 时间 \/ 观看 \/ 回复 + 最后发表(异步回填)。\n   ★ v59: 「最后发表」以【预留占位】的方式挂在末尾 —— 它是 <i>(inline),\n     会在这行 nowrap 的 .mt 里自然流动、自动贴近前一个元素(观看数\/回复数)的尾部。\n     初始为空时由 CSS 的 :empty 隐藏, 既不占空间也不显示分隔符;\n     异步拿到数据后只写它的 textContent, 不重建整行。 *\/\nfunction metaHtml(o,tidv){\n  var p=[];\n  function cell(c,t){return t?('<i class=\"mc\" style=\"color:var(--'+c+')\">'+esc(t)+'<\/i>'):'';}\n  var a=cell('autx',o.au),b=cell('tmtx',o.tm),c=cell('vwtx',o.vw),d=cell('rptx',o.rp);\n  if(a)p.push(a);if(b)p.push(b);if(c)p.push(c);if(d)p.push(d);\n  var sep='<i class=\"mc sep\" style=\"color:var(--mttx)\">'+esc(ST.mtSep)+'<\/i>';\n  var s=p.join(sep);\n  if(ST.lpOn&&tidv)s+='<i class=\"mc lp\" data-tid=\"'+esc(tidv)+'\"><\/i>';\n  return s;\n}\nfunction itemHtml(it,lm){\n  var b=it.h;\n  var a=b.match(\/href=\"(forum\\.php\\?mod=viewthread[^\"]*)\"\/);\n  if(!a)return '';\n  var url=abs(a[1]);\n  var tid=b.match(\/tid=(\\d+)\/);\n  var tidv=tid?tid[1]:'';\n  var t=b.match(\/<em[^>]*>([\\s\\S]*?)<\\\/em>\/);\n  var title=tx(t?t[1]:'')||'(无标题)';\n\n  \/* --- v63 置顶帖: 折叠时一行(标题+紧凑信息), 点开展开全部信息 --- *\/\n  if(it.cls==='list_top'){\n    return '<div class=\"it tp tpc\" data-tid=\"'+esc(tidv)+'\">'\n      +'<div class=\"tprow\" onclick=\"tpToggle(this)\">'\n        +'<i class=\"tparw\">▸<\/i>'\n        +'<a class=\"tt\" href=\"'+esc(url)+'\" onclick=\"tpStop(event)\">\\ud83d\\udccc '+esc(title)+'<\/a>'\n        +'<span class=\"tpmeta\"><\/span>'\n      +'<\/div>'\n      +'<div class=\"tpbd\"><div class=\"tpfull\"><\/div><div class=\"tpext\"><\/div><\/div>'\n      +'<\/div>';\n  }\n\n  var me=b.match(\/<div class=\"threadlist_mes cl\">([\\s\\S]*?)<\\\/div>\/);\n  var av=b.match(\/class=\"mimg\"><img src=\"([^\"]*)\"\/);\n  var u=b.match(\/class=\"mmc\"[^>]*>([\\s\\S]*?)<\\\/a>\/);\n  var tm=b.match(\/<span class=\"mtime\">([\\s\\S]*?)<\\\/span>\/);\n  var ft=b.match(\/<div class=\"threadlist_foot cl\">([\\s\\S]*)$\/);\n  var v=[];\n  if(ft){var rr=\/<\\\/i>(\\d+)<\\\/li>\/g,x2;while((x2=rr.exec(ft[1]))!==null)v.push(x2[1]);}\n\n  var h='<div class=\"itw\" data-tid=\"'+esc(tidv)+'\">'\n    +'<button class=\"lpb\" type=\"button\" title=\"最近回复\" onclick=\"lpBtn(event,this)\">\\u25be<\/button>'\n    +'<a class=\"it\" href=\"'+esc(url)+'\">';\n  h+='<div class=\"row1\">';\n  \/* v58: 头像外包一层 .avw 作定位容器, 外框 .avf 是同尺寸的绝对定位图层 *\/\n  if(ST.avOn){\n    h+='<span class=\"avw\"><img class=\"av\" src=\"'+esc(abs(av?av[1]:''))+'\" loading=\"lazy\" onerror=\"this.style.visibility=\\'hidden\\'\">'\n      +((ST.frOn&&FR)?('<i class=\"avf'+(ST.frMode==='under'?' under':'')+'\"><\/i>'):'')\n      +'<\/span>';\n  }\n  h+='<div class=\"tt\">'+esc(title)+'<\/div><\/div>';\n  if(ST.msOn&&me)h+='<div class=\"ms\">'+esc(tx(me[1]))+'<\/div>';\n  var imgs=ST.igOn?itemImgs(b):[];\n  if(imgs.length){\n    h+='<div class=\"igs\" data-n=\"'+imgs.length+'\">';\n    \/* v56 图片是首屏最大开销(实测电脑版 46.7KB、手机 25.5KB, 图片占比最高)。\n       loading=\"lazy\" 只加载进入视口附近的图; 再加 decoding=\"async\" 避免解码卡住渲染。 *\/\n    for(var i=0;i<imgs.length;i++)h+='<img class=\"ig\" src=\"'+esc(imgs[i])+'\" loading=\"lazy\" decoding=\"async\" onerror=\"this.style.display=\\'none\\'\">';\n    h+='<\/div>';\n  }\n  if(ST.mtOn){\n    var mo={au:u?tx(u[1]):'',tm:tm?tx(tm[1]):'',\n      vw:v[0]?('\\ud83d\\udc41'+v[0]):'',rp:v[1]?('\\ud83d\\udcac'+v[1]):''};\n    h+='<div class=\"mt\" data-fit=\"1\" data-tid=\"'+esc(tidv)+'\">'+metaHtml(mo,tidv)+'<\/div>';\n  }\n  h+='<\/a><\/div>';\n  return h;\n}\nfunction parseSub(h){\n  var m=h.match(\/<div class=\"dhnav_box\">([\\s\\S]*?)<div class=\"threadlist_box\/);\n  if(!m)return [];\n  var out=[],re=\/<li class=\"flex([^\"]*)\"><a href=\"([^\"]+)\"[^>]*>([\\s\\S]*?)<\\\/a>\/g,x;\n  while((x=re.exec(m[1]))!==null)out.push({n:tx(x[3]),u:abs(x[2]),on:\/mon\/.test(x[1])});\n  return out;\n}\nfunction parsePost(h,fid){\n  var m=h.match(\/href=\"(forum\\.php\\?mod=post&amp;action=newthread&amp;fid=\\d+[^\"]*)\"\/);\n  if(m)return abs(m[1]);\n  return ORI+'forum.php?mod=post&action=newthread&fid='+fid+'&mobile=2';\n}\nfunction nextUrl(h){\n  var m=h.match(\/<a href=\"([^\"]*page=\\d+[^\"]*)\"[^>]*class=\"[^\"]*nxt\/);\n  return m?abs(m[1]):'';\n}\nfunction parseList(h,lm){\n  var items=splitItems(h),out=[],k,html,tp=[],cnt=0;\n  \/* v63: 连续的置顶帖收进同一个容器(容器头可一键折叠\/展开全部) *\/\n  function flush(){ if(!tp.length)return; out.push(tpBoxHtml(tp)); tp=[]; }\n  for(k=0;k<items.length;k++){\n    html=itemHtml(items[k],lm);\n    if(!html)continue;\n    cnt++;\n    if(items[k].cls==='list_top'){tp.push(html);continue;}\n    flush();\n    out.push(html);\n  }\n  flush();\n  return {html:out.join(''),count:cnt};\n}\n\n\/* ---------------- 图片行布局: 行宽\/图宽\/间距 -> 一行几张 ---------------- *\/\nfunction layoutImgs(){\n  var gs=document.querySelectorAll('.igs');\n  var ws=[],i;\n  \/* v56 先批量读再批量写: 原来「读-写-读-写」交替, 每个元素都触发一次强制重排 *\/\n  for(i=0;i<gs.length;i++)ws.push(gs[i].clientWidth);\n  for(i=0;i<gs.length;i++)layoutOne(gs[i],ws[i]);\n}\nfunction layoutOne(g,cw){\n    if(!cw)return;\n    var gap=ST.igGap,maxN=ST.igMax||9;\n    var n=parseInt(g.getAttribute('data-n'),10)||0;\n    if(n>maxN)n=maxN;\n    \/* 一行几张 = 100 ÷ 单图宽度%(33% -> 3 张, 25% -> 4 张); 再受「最多显示张数」与实际图片数限制 *\/\n    var n0=Math.max(1,Math.round(100\/(ST.igW||100)));\n    var cnt=Math.min(n0,n,maxN);\n    if(cnt<1)cnt=1;\n    var iw=Math.floor((cw-gap*(cnt-1))\/cnt);\n    \/* 图片不够铺满一行时按「单图宽度」左对齐, 不把少数几张拉伸成超大图 *\/\n    var want=Math.max(20,Math.round(cw*(ST.igW||100)\/100));\n    if(n<n0)iw=Math.min(iw,want);\n    g.style.height=ST.igRowH+'px';\n    var its=g.children;\n    for(var j=0;j<its.length;j++){\n      if(j<cnt){its[j].style.display='';its[j].style.width=iw+'px';its[j].style.height=ST.igRowH+'px';}\n      else its[j].style.display='none';\n  }\n}\n\/* ---------------- 综合信息自适应: 先缩间距, 再缩字号, 最后省略 ---------------- *\/\nfunction fitOne(el){\n  el.style.letterSpacing='';el.style.fontSize='';\n  var avail=el.clientWidth;\n  if(!avail)return;\n  var base=ST.mtFs,ls=ST.mtLs,minFs=Math.min(ST.mtMinFs,base);\n  el.style.fontSize=base+'px';el.style.letterSpacing=ls+'px';\n  if(el.scrollWidth<=avail+1)return;\n  if(!ST.mtAuto){el.style.letterSpacing='0px';return;}\n  \/* v56 二分代替线性递减: 原来每 0.5px 一档最坏 ~20 轮「写样式->读scrollWidth」,\n     每轮都强制重排; 20 个条目就是上百次。二分后每阶段最多 4 轮。 *\/\n  var lo,hi,mid;\n  \/* 阶段一: 压缩字距 *\/\n  lo=ls;hi=-1;                       \/* 假定 hi 一定放不下 *\/\n  if(binFit(el,hi,'ls')){el.style.letterSpacing=hi+'px';return;}\n  for(var k=0;k<4&&(hi-lo)>0.4;k++){\n    mid=Math.round((lo+hi)\/2*2)\/2;   \/* 取到 0.5 的倍数 *\/\n    if(binFit(el,mid,'ls'))lo=mid; else hi=mid;\n  }\n  el.style.letterSpacing=lo+'px';\n  if(binFit(el,lo,'ls'))return;\n  \/* 阶段二: 字距已到极限仍放不下, 再缩字号 *\/\n  el.style.letterSpacing='-1px';\n  lo=minFs;hi=base;                  \/* 假定 hi 一定放不下 *\/\n  for(var k2=0;k2<4&&(hi-lo)>0.4;k2++){\n    var fm=Math.round((lo+hi)\/2*2)\/2;\n    if(binFit(el,fm,'fs'))lo=fm; else hi=fm;\n  }\n  el.style.fontSize=lo+'px';\n}\nfunction binFit(el,v,mode){\n  if(mode==='ls')el.style.letterSpacing=v+'px';\n  else el.style.fontSize=v+'px';\n  return el.scrollWidth<=el.clientWidth+1;\n}\nfunction fitMeta(){\n  var ms=document.querySelectorAll('.mt[data-fit=\"1\"]');\n  for(var i=0;i<ms.length;i++)fitOne(ms[i]);\n}\n\/* v58: 外框层是在渲染列表时插进 .avw 的, 但切换「启用 \/ 换图 \/ 叠放次序」时\n   不该为了看效果再去重新拉一次列表 —— 直接在现有 DOM 上补齐或移除。 *\/\nfunction syncFrames(){\n  var ws=document.querySelectorAll('#res .avw'),i;\n  for(i=0;i<ws.length;i++){\n    var f=ws[i].querySelector('.avf');\n    if(ST.frOn&&FR){\n      if(!f){f=document.createElement('i');ws[i].appendChild(f);}\n      f.className='avf'+(ST.frMode==='under'?' under':'');\n    }else if(f&&f.parentNode){f.parentNode.removeChild(f);}\n  }\n}\nfunction relayout(){try{layoutImgs();fitMeta();syncFrames();}catch(e){}}\n\n\/* ---------------- 渲染 ---------------- *\/\nfunction pageUrl(u,p){\n  u=ee(String(u));\n  if(u.indexOf('{{page}}')>=0)return abs(u.replace('{{page}}',p));\n  if(\/[?&]page=\\d+\/.test(u))return abs(u.replace(\/([?&])page=\\d+\/,'$1page='+p));\n  return abs(u+(u.indexOf('?')>=0?'&':'?')+'page='+p);\n}\nfunction fidOf(u){var m=String(u).match(\/fid=(\\d+)\/);return m?m[1]:'';}\n\n\/* ===== v66 首页分类标签「今日更新」徽标 ===== *\/\nvar TODAY_MAP={};\nfunction parseToday(h){\n  var map={}, fids=[], re=\/fid=(\\d+)\/g, m;\n  while((m=re.exec(h))!==null) fids.push({fid:m[1], pos:m.index});\n  var pats=[\n    \/<em[^>]*title=\"\\u4eca\\u65e5\"[^>]*>\\s*\\((\\d+)\\)\\s*<\\\/em>\/i,\n    \/<span[^>]*class=\"mnum\"[^>]*>\\u4eca\\u65e5\\s*(\\d+)\/i,\n    \/\\u4eca\\u65e5:\\s*<strong[^>]*>(\\d+)<\\\/strong>\/i,\n    \/\\u4eca\\u65e5:\\s*<span[^>]*>(\\d+)<\\\/span>\/i,\n    \/\\u4eca\\u65e5\\s*(\\d+)\/\n  ];\n  for(var i=0;i<fids.length;i++){\n    var fpos=fids[i].pos;\n    var end=(i+1<fids.length)?fids[i+1].pos:fpos+700;\n    var seg=h.slice(fpos,end);\n    for(var p=0;p<pats.length;p++){\n      var mm=pats[p].exec(seg);\n      if(mm){var n=parseInt(mm[1],10);if(n>0)map[fids[i].fid]=n;break;}\n    }\n  }\n  return map;\n}\nfunction badgeTabs(map){\n  try{\n    for(var i=0;i<CATS.length;i++){\n      var el=document.getElementById('tb'+i); if(!el)continue;\n      var n=map[CATS[i].fid];\n      var b=el.querySelector('.tpcnt');\n      if(n>0){\n        if(!b){b=document.createElement('span');b.className='tpcnt';el.appendChild(b);}\n        b.textContent=(n>99?'99+':(''+n));\n      } else if(b){ b.parentNode.removeChild(b); }\n    }\n  }catch(e){}\n}\nfunction fetchToday(){\n  try{\n    var u=abs('forum.php?mod=index&mobile=2');\n    getHtml(u).then(function(h){try{TODAY_MAP=parseToday(h);badgeTabs(TODAY_MAP);}catch(e){}}).catch(function(){});\n  }catch(e){}\n}\nfunction renderTabs(){\n  var h='',el=document.getElementById('tabs');\n  for(var i=0;i<CATS.length;i++)h+='<div class=\"tab\" id=\"tb'+i+'\" onclick=\"loadCat('+i+')\">'+esc(CATS[i].n)+'<\/div>';\n  el.innerHTML=h;\n\n  if(typeof TODAY_MAP!=='undefined'&&TODAY_MAP)badgeTabs(TODAY_MAP);\n}\nfunction markTab(){\n  for(var i=0;i<CATS.length;i++){\n    var el=document.getElementById('tb'+i);\n    if(el)el.className=(i===cur)?'tab on':'tab';\n  }\n}\nfunction renderSubs(){\n  var box=document.getElementById('subs'),h='';\n  if(!SUBS.length){box.innerHTML='';box.style.display='none';}\n  else{\n    box.style.display='flex';\n    for(var i=0;i<SUBS.length;i++)h+='<div class=\"sub'+(i===curSub?' on':'')+'\" onclick=\"loadSub('+i+')\">'+esc(SUBS[i].n)+'<\/div>';\n    box.innerHTML=h;\n  }\n  var ps=document.getElementById('pst');\n  if(ps)ps.setAttribute('href',POSTURL||'javascript:;');\n}\nfunction showLoading(t){\n  var el=document.getElementById('res');\n  el.setAttribute('data-append','0');\n  el.innerHTML='<div class=\"emp\">'+esc(t)+'<\/div>';\n}\nfunction loadUrl(u,append){\n  loading=true;\n  var el=document.getElementById('res');\n  if(!append)showLoading('加载中…');\n  else el.setAttribute('data-append','1');\n  var fid=fidOf(u);\n  var seq=++loadSeq;\n  \/* v59: 首屏只发列表这一个请求(手机版)。\n     「最后发表」需要的电脑版请求推迟到本页渲染完、主线程空闲之后再发(见 scheduleLast),\n     因此既不占用首屏带宽, 也不会拖慢任何已有元素的显示。 *\/\n  var pList=getHtml(u);\n  pList.then(function(h){\n    if(seq!==loadSeq)return;   \/* 已被更新的请求取代, 丢弃旧结果 *\/\n    SUBS=parseSub(h);\n    POSTURL=parsePost(h,fid);\n    \/* 二级导航当前项: 优先用页面自带的 mon 标记, 否则沿用当前索引 *\/\n    var ai=-1;\n    for(var i=0;i<SUBS.length;i++){if(SUBS[i].on){ai=i;break;}}\n    if(ai>=0)curSub=ai;\n    renderSubs();\n    var r=parseList(h,{});\n    var ann=append?'':parseAnnounce(h);\n    var body=(r.count?r.html:'<div class=\"emp\">该分类暂无帖子<\/div>');\n    if(ann)body=ann+body;\n    if(append)el.innerHTML+=body; else el.innerHTML=body;\n    curNext=nextUrl(h);\n    if(curNext)el.innerHTML+='<div class=\"pg\"><a href=\"javascript:loadMore()\">加载更多<\/a><\/div>';\n    el.setAttribute('data-append','0');\n    loading=false;\n    lastLoadAt=(new Date()).getTime();\n    relayout();\n    scheduleLast(u,seq);   \/* v59: 渲染完 + 空闲后, 才异步补「最后发表」 *\/\n  })['catch'](function(e){\n    if(seq!==loadSeq)return;\n    loading=false;\n    lastLoadAt=(new Date()).getTime();\n    el.setAttribute('data-append','0');\n    el.innerHTML='<div class=\"emp\">加载失败：'+esc(e)+'<\/div>';\n  });\n}\n\/* 让位给首屏: 优先 requestIdleCallback; 老 WebView 没有就退化为两帧后执行 *\/\nfunction defer(fn){\n  try{\n    if(typeof window.requestIdleCallback==='function'){window.requestIdleCallback(fn,{timeout:1500});return;}\n  }catch(e){}\n  setTimeout(fn,120);\n}\n\/* ===== fixed22: 长按首页帖子卡片(.itw)展开最近 3 条回复 ===== *\/\nvar LP3C={};                       \/* 按 tid 缓存已加载的回复, 避免重复请求 *\/\nfunction lpPt(e){if(e.touches&&e.touches[0])return{x:e.touches[0].clientX,y:e.touches[0].clientY};return{x:e.clientX||0,y:e.clientY||0};}\nfunction lpFindCard(t){\n  while(t&&t!==document){\n    if(t.classList&&t.classList.contains('itw')&&t.getAttribute('data-tid'))return t;\n    t=t.parentNode;\n  }\n  return null;\n}\nfunction lpDown(e){\n  var c=lpFindCard(e.target);\n  lpCard=c;lpMoved=false;\n  if(!c){if(lpTimer){clearTimeout(lpTimer);lpTimer=null;}return;}\n  var p=lpPt(e);lpSX=p.x;lpSY=p.y;\n  if(lpTimer)clearTimeout(lpTimer);\n  lpTimer=setTimeout(function(){lpFire(c);},480);\n}\nfunction lpMove(e){\n  if(!lpTimer)return;\n  var p=lpPt(e);\n  if(Math.abs(p.x-lpSX)>10||Math.abs(p.y-lpSY)>10){clearTimeout(lpTimer);lpTimer=null;}\n}\nfunction lpUp(){if(lpTimer){clearTimeout(lpTimer);lpTimer=null;}}\nfunction lpFire(c){\n  lpTimer=null;\n  c._lp=1;                                  \/* 武装: 抑制随后冒出的 click 导航 *\/\n  setTimeout(function(){if(c._lp===1)c._lp=0;},420);\n  lpToggle(c);\n}\nfunction lpClick(e){\n  var c=lpFindCard(e.target);\n  if(c&&c._lp){e.preventDefault();e.stopPropagation();c._lp=0;}\n}\nfunction lpBtn(e,btn){\n  \/* 卡片右上角 ▾ 按钮: 展开\/折叠最近3条回复。\n     按钮在 <a class=\"it\"> 之外, 但仍要拦住默认与冒泡, 避免误触卡片导航。 *\/\n  if(e){if(e.preventDefault)e.preventDefault();if(e.stopPropagation)e.stopPropagation();}\n  var w=btn&&btn.parentNode;\n  while(w&&!(w.classList&&w.classList.contains('itw')))w=w.parentNode;\n  if(!w)return;\n  var on=lpToggle(w);\n  if(btn)btn.className=on?'lpb on':'lpb';\n}\nfunction lpToggle(c){\n  var tid=c.getAttribute('data-tid');if(!tid)return false;\n  \/* fixed26: 回复区挂到卡片容器 .it 内部(而非外层 .itw), 使其真正显示在卡片里 *\/\n  var host=c.querySelector('.it')||c;\n  var box=c.querySelector('.lp3');\n  if(box&&box.classList.contains('open')){box.classList.remove('open');box.innerHTML='';return false;}\n  if(!box){\n    box=document.createElement('div');box.className='lp3';\n    \/* box 在 <a> 内: 点它不能触发帖子导航 *\/\n    box.onclick=function(e){if(e){if(e.preventDefault)e.preventDefault();if(e.stopPropagation)e.stopPropagation();}};\n    host.appendChild(box);\n  }\n  box.classList.add('open');\n  if(LP3C[tid]){box.innerHTML=lp3Html(LP3C[tid]);return true;}\n  box.innerHTML='<div class=\"lp3ld\">加载最近回复…<\/div>';\n  fetchReplies(tid).then(function(arr){\n    LP3C[tid]=arr;\n    if(box.classList.contains('open'))box.innerHTML=lp3Html(arr);\n  })['catch'](function(){\n    if(box.classList.contains('open'))box.innerHTML='<div class=\"lp3ld\">加载失败<\/div>';\n  });\n  return true;\n}\nfunction lp3Html(arr){\n  if(!arr||!arr.length)return '<div class=\"lp3ld\">暂无回复<\/div>';\n  var h='<div class=\"lp3hd\">最近回复<\/div>',i;\n  for(i=0;i<arr.length;i++){\n    var r=arr[i];\n    h+='<div class=\"lp3it\">'\n      +'<div class=\"lp3au\">'+esc(r.au||'')+'<span class=\"lp3tm\">'+esc(r.tm||'')+'<\/span><\/div>'\n      +'<div class=\"lp3tx\">'+esc(r.tx||'')+'<\/div>'\n      +'<\/div>';\n  }\n  return h;\n}\nfunction lp3Take(arr){return arr.length>3?arr.slice(0,3):arr;}\nfunction stripQuote(s){\n  return String(s||'')\n    .replace(\/<div class=\"quote\">[\\s\\S]*?<\\\/div>\/g,'')\n    .replace(\/<blockquote[\\s\\S]*?<\\\/blockquote>\/g,'')\n    .replace(\/<ignore_js_op>[\\s\\S]*?<\\\/ignore_js_op>\/g,'');\n}\nfunction snip(s,n){s=String(s||'');return s.length>n?s.slice(0,n)+'…':s;}\nfunction balDivMatch(p,mi){\n  \/* 从 <div class=\"message\"> 起, 按 <div \/ <\/div> 配平, 取到消息块的闭合 <\/div>\n     (消息体内含 <div class=\"quote\"> 等嵌套, 非贪婪正则会提前截止) *\/\n  var depth=0,i=mi,n=p.length;\n  while(i<n){\n    if(p.substr(i,4)==='<div'){depth++;i+=4;continue;}\n    if(p.substr(i,6)==='<\/div>'){depth--;i+=6;if(depth===0)return p.slice(mi,i);continue;}\n    i++;\n  }\n  return p.slice(mi);\n}\nfunction parseReplies(h){\n  var arr=[];\n  try{\n    var seg=String(h||'');\n    var parts=seg.split(\/<div class=\"plc cl\" id=\"pid\\d+\">\/),i;\n    for(i=1;i<parts.length;i++){\n      var p=parts[i];\n      var cut=p.indexOf('<div class=\"threadlist_foot');\n      if(cut>=0)p=p.slice(0,cut);\n      var mt=p.match(\/<li class=\"mtit\">([\\s\\S]*?)<\\\/li>\/);\n      if(mt&&\/楼主\/.test(mt[1]))continue;          \/* 跳过楼主主楼 *\/\n      var au=p.match(\/<li class=\"mtit\">[\\s\\S]*?<a[^>]*>([\\s\\S]*?)<\\\/a>\/);\n      var tm=p.match(\/<li class=\"mtime\">([\\s\\S]*?)<\\\/li>\/);\n      var mi=p.indexOf('<div class=\"message\">');\n      var author=au?tx(au[1]):'';\n      var time=tm?tx(tm[1]):'';\n      var content=mi>=0?tx(stripQuote(balDivMatch(p,mi))):'';\n      content=snip(content,80);\n      arr.push({au:author,tm:time,tx:content});\n    }\n  }catch(e){}\n  return arr;\n}\nfunction fetchReplies(tid){\n  var u=ORI+'forum.php?mod=viewthread&tid='+encodeURIComponent(tid)+'&ordertype=1&mobile=2';\n  return getHtml(u).then(function(h){return lp3Take(parseReplies(h));});\n}\nvar lpTimer=null,lpCard=null,lpSX=0,lpSY=0,lpMoved=false;\nfunction lpAttach(){\n  var res=document.getElementById('res');\n  if(!res||res._lpB)return;res._lpB=1;\n  \/* fixed26: 长按在 WebView 里必定弹出系统级菜单(原生行为, contextmenu 拦截不可靠),\n     故不再绑定长按手势; 展开「最近3条回复」改由卡片右上角 ▾ 按钮(lpBtn)触发。 *\/\n  var lpNo=function(e){if(e&&e.preventDefault)e.preventDefault();return false;};\n  res.addEventListener('contextmenu',lpNo,false);\n  res.addEventListener('selectstart',lpNo,false);\n  res.addEventListener('dragstart',lpNo,false);\n}\n\nfunction loadCat(i){\n  \/* 进入任何论坛分类时, 先恢复论坛视图并隐藏小说站覆盖层(隔离两者状态) *\/\n  if(typeof showForum==='function')showForum();\n  \/* 点论坛分类: 清除小说站固定入口高亮 *\/\n  var xst=document.getElementById('xstab');if(xst)xst.className='xstab';\n  if(loading)return;\n  cur=i;curSub=0;curPage=1;curNext='';markTab();\n  resetNext();\n  \/* v58: 最后发表已独立成 .lp, 不再需要按 tid 缓存整行字段(原 META) *\/\n  SUBS=[];renderSubs();\n  \/* ★ v56 关键: 不回顶部的话, 上一页滚到深处时点分类 -> 内容被替换、页面骤降,\n     滚动位置仍很深 -> 立刻命中「到底部」判定 -> 自动把新分类的第 2 页也加载了。 *\/\n  try{window.scrollTo(0,0);}catch(e){}\n  loadUrl(pageUrl(CATS[i].u,1),false);\n}\nfunction loadSub(k){\n  if(loading||!SUBS[k])return;\n  curSub=k;curPage=1;curNext='';\n  renderSubs();\n  resetNext();\n  try{window.scrollTo(0,0);}catch(e){}   \/* 同上 *\/\n\n  loadUrl(pageUrl(SUBS[k].u,1),false);\n}\nfunction loadMore(){\n  if(loading||!curNext)return;\n  var el=document.getElementById('res'),pg=el.querySelector('.pg');\n  if(pg)pg.parentNode.removeChild(pg);\n  curPage++;\n  loadUrl(curNext,true);\n}\nfunction doSearch(){\n  var q=String((document.getElementById('q')||{}).value||'').trim();\n  var xsr=document.getElementById('xsres');\n  if(xsr&&xsr.style.display!=='none'&&xsr.style.display!==''){xsSearch(q);return;}\n  var el=document.getElementById('res');\n  if(!q){el.setAttribute('data-append','0');el.innerHTML='<div class=\"emp\">请输入搜索关键词<\/div>';return;}\n  cur=-1;curNext='';curSub=0;markTab();SUBS=[];renderSubs();\n  resetNext();\n  el.setAttribute('data-append','0');\n  el.innerHTML='<div class=\"emp\">搜索中…<\/div>';\n  var u=abs('search.php?mod=forum&srchtxt='+encodeURIComponent(q)+'&searchsubmit=yes&mobile=2');\n  getHtml(u).then(function(h){\n    var r=parseList(h,{});\n    el.innerHTML=(r.count?'<div class=\"cnt\">搜索到 '+r.count+' 条帖子<\/div>'+r.html:'<div class=\"emp\">没有找到相关帖子<\/div>');\n    curNext=nextUrl(h);\n    if(curNext)el.innerHTML+='<div class=\"pg\"><a href=\"javascript:loadMore()\">加载更多<\/a><\/div>';\n    relayout();\n  })['catch'](function(e){el.innerHTML='<div class=\"emp\">搜索失败：'+esc(e)+'<\/div>';});\n}\n\/* v58 下拉到底自动加载下一页。\n   ★ 难点: 切分类\/二级导航时内容被整块替换, 页面高度骤降, 若此时滚动位置仍很深,\n     会立刻命中「到底部」判定, 把新分类的第 2 页也自动加载掉。\n     已有的 scrollTo(0,0) 是异步生效的, 单靠它拦不住。\n   ★ 做法: 只有检测到【用户向下滑动】才解除封锁(nextArmed)。\n     页面骤降只会让 scrollY 变小, 不会让它变大, 因此不会误解锁。 *\/\nvar nextArmed=false,lastY=0,nextMute=0;\nfunction resetNext(){                            \/* 切换分类\/导航\/搜索后调用 *\/\n  nextArmed=false;lastY=0;nextMute=(new Date()).getTime();\n}\nwindow.addEventListener('scroll',function(){\n  if(!ST.autoNext)return;                        \/* 关掉则只能手动点「加载更多」 *\/\n  if(loading||!curNext)return;\n  var now=(new Date()).getTime();\n  if(now-lastLoadAt<1200)return;                 \/* 刚加载完的保护期, 防止连环触发 *\/\n  if(now-nextMute<600)return;                    \/* 等 scrollTo(0,0) 真正生效 *\/\n  var y=window.pageYOffset;\n  if(y>lastY+4)nextArmed=true;                   \/* 只认向下滑动 *\/\n  lastY=y;\n  if(!nextArmed)return;\n  var d=document.documentElement;\n  if(d.scrollHeight-(y+d.clientHeight)<300)loadMore();\n});\nwindow.addEventListener('resize',function(){relayout();});\ndocument.addEventListener('keydown',function(e){\n  if(e.keyCode===13&&document.activeElement&&document.activeElement.id==='q')doSearch();\n});\n\n\/* ================= 外观设置面板 ================= *\/\nvar _tipT=null;\nfunction tip(m){\n  var el=document.getElementById('tip');\n  if(!el)return;\n  el.textContent=m;el.className='tip on';\n  if(_tipT)clearTimeout(_tipT);\n  _tipT=setTimeout(function(){el.className='tip';},1600);\n}\nfunction sv(id,v){var e=document.getElementById(id+'v');if(e)e.textContent=v;}\nfunction setV(id,v){var e=document.getElementById(id);if(e&&String(e.value)!==String(v))e.value=v;}\nfunction setSw(id,hex){\n  var sw=document.getElementById(id+'s');if(sw)sw.style.background=hex||'transparent';\n  var lb=document.getElementById(id+'v');if(lb)lb.textContent=hex?String(hex).toUpperCase():'继承';\n}\nfunction upd(k,v){ST[k]=v;saveST();applyStyle();relayout();if(k==='aiOn'){try{aiEcho()}catch(q){}}}\nfunction updT(k,v){ST[k]=v;saveST();applyStyle();relayout();}\nfunction updB(k,v){\n  ST[k]=v?1:0;saveST();applyStyle();relayout();\n  var a=document.getElementById('s'+k+'0'),b=document.getElementById('s'+k+'1');\n  if(a)a.className='msw'+(ST[k]?'':' on');\n  if(b)b.className='msw'+(ST[k]?' on':'');\n}\nfunction sec(id,title,open){\n  return '<div class=\"sec\"><div class=\"sech\" onclick=\"tog(\\''+id+'\\')\"><b>'+title+'<\/b><span id=\"'+id+'a\">'+(open?'▾':'▸')+'<\/span><\/div>'\n    +'<div class=\"secb\" id=\"'+id+'\" style=\"display:'+(open?'block':'none')+'\">';\n}\nfunction endsec(){return '<\/div><\/div>';}\nfunction tog(id){\n  var b=document.getElementById(id),a=document.getElementById(id+'a');\n  if(!b)return;\n  var on=b.style.display!=='none';\n  b.style.display=on?'none':'block';\n  if(a)a.textContent=on?'▸':'▾';\n}\nfunction prow(r){\n  var t=r[0];\n  if(t==='h')return '<div class=\"hint\">'+r[1]+'<\/div>';\n  if(t==='x')return r[1];\n  var k=r[1],lb=r[2],d=PDEF[k],id='s'+k;\n  if(!d)return '';\n  if(t==='c')return '<div class=\"srow\"><label>'+esc(lb)+'<\/label><button class=\"cpk\" id=\"'+id+'\" onclick=\"openPicker(\\''+k+'\\')\"><i class=\"csw\" id=\"'+id+'s\"><\/i><span class=\"chex\" id=\"'+id+'v\"><\/span><\/button><\/div>';\n  if(t==='r')return '<div class=\"srow\"><label>'+esc(lb)+'<\/label><input type=\"range\" id=\"'+id+'\" min=\"'+d[2]+'\" max=\"'+d[3]+'\" step=\"'+d[4]+'\" oninput=\"upd(\\''+k+'\\',parseFloat(this.value));sv(\\''+id+'\\',this.value)\"><span class=\"sval\" id=\"'+id+'v\"><\/span><\/div>';\n  if(t==='t')return '<div class=\"srow\"><label>'+esc(lb)+'<\/label><input type=\"text\" id=\"'+id+'\" placeholder=\"'+esc(r[3]||'')+'\" oninput=\"updT(\\''+k+'\\',this.value)\"><\/div>';\n  if(t==='s'){\n    var o='';\n    for(var i=0;i<d[2].length;i++)o+='<option value=\"'+esc(d[2][i][0])+'\">'+esc(d[2][i][1])+'<\/option>';\n    return '<div class=\"srow\"><label>'+esc(lb)+'<\/label><select id=\"'+id+'\" onchange=\"upd(\\''+k+'\\',this.value)\">'+o+'<\/select><\/div>';\n  }\n  if(t==='b')return '<div class=\"srow\"><label>'+esc(lb)+'<\/label><span class=\"sw\"><button class=\"msw\" id=\"'+id+'0\" onclick=\"updB(\\''+k+'\\',0)\">关<\/button><button class=\"msw\" id=\"'+id+'1\" onclick=\"updB(\\''+k+'\\',1)\">开<\/button><\/span><\/div>';\n  return '';\n}\nvar SCHEMA=[\n ['q1','页面背景',[\n   ['x','<div id=\"pbg\"><\/div>'],\n   ['x','<div class=\"row\"><input type=\"text\" id=\"bgsel\" readonly placeholder=\"点上面的图片选中，再点复制\" onclick=\"this.select()\" style=\"flex:1;min-width:0\"><button class=\"bt\" onclick=\"pvCopyH(\\'bg\\')\">📋复制链接<\/button><\/div>'],\n   ['x','<div class=\"srow\"><label>保存到分类<\/label><select id=\"bcat\"><\/select><\/div>'],\n   ['x','<input type=\"text\" id=\"bi\" placeholder=\"图片网址 或 \/sdcard\/Pictures\/bg.jpg\">'],\n   ['x','<div class=\"row\"><button class=\"bt\" onclick=\"addBG()\">保存并应用<\/button><button class=\"bt\" onclick=\"clearBG()\">清除背景<\/button><\/div>'],\n   ['x','<div class=\"row\"><button class=\"bt\" onclick=\"wnUp(\\'bg\\')\">上传到背景图片云<\/button><button class=\"bt\" onclick=\"wnDown(\\'bg\\')\">从背景图片云下载<\/button><\/div>'],\n   ['s','bgFit','显示模式'],['r','bgA','背景不透明度 %'],\n   ['c','pageBg','页面底色'],['r','pageA','底色不透明度 %']\n ]],\n ['q2','列表卡片',[\n   ['c','cardBg','底色'],['r','cardA','不透明度 %'],\n   ['r','cardBdW','边框粗细'],['c','cardBdC','边框色'],\n   ['r','cardRd','圆角'],['r','cardSh','阴影大小'],['c','cardShC','阴影色'],\n   ['r','cardPT','上内边距'],['r','cardPR','右内边距'],['r','cardPL','左内边距'],['r','cardPB','下内边距(无综合信息时)'],\n   ['r','cardGap','卡片间距']\n ]],\n ['q3','顶部横幅 \/ 搜索框',[\n   ['b','heroOn','显示横幅'],\n   ['h','<b>文字内容<\/b>'],\n   ['t','heroTxt','主标题文字','千白羽论坛'],['t','heroSub','副标题文字','选分类浏览帖子…'],\n   ['h','<b>背景图<\/b>（留空则用下面的纯色底色）'],\n   ['t','heroBi','背景图网址','https:\/\/... 或 \/sdcard\/Pictures\/bg.jpg'],\n   ['x','<div class=\"row\"><button class=\"bt\" onclick=\"updT(\\'heroBi\\',(document.getElementById(\\'sheroBi\\')||{}).value||\\'\\')\">应用背景图<\/button><button class=\"bt\" onclick=\"clearHeroBi()\">清除背景图<\/button><\/div>'],\n   ['s','heroBFit','显示模式'],['r','heroBA','背景图不透明度 %'],['r','heroBH','标题框最小高度'],\n   ['r','heroOv','遮罩不透明度 %'],['c','heroOvC','遮罩颜色'],\n   ['h','<b>底色 \/ 边框 \/ 字体<\/b>'],\n   ['c','heroBg','底色'],['r','heroA','不透明度 %'],['r','heroBdW','边框'],['c','heroBdC','边框色'],\n   ['r','heroRd','圆角'],['r','heroPV','上下内边距'],['r','heroPH','左右内边距'],\n   ['c','heroTx','文字色'],['r','heroFs','主标题字号'],['r','heroSubFs','副标题字号'],\n   ['h','<b>搜索框<\/b>'],\n   ['b','srchOn','显示搜索框'],\n   ['c','sBg','输入框底色'],['r','sA','不透明度 %'],['r','sBdW','输入框边框'],['c','sBdC','输入框边框色'],\n   ['r','sRd','输入框圆角'],['c','sTx','输入文字色'],['r','sFs','输入字号'],\n   ['c','sBtnBg','按钮底色'],['c','sBtnTx','按钮文字色'],['r','sBtnRd','按钮圆角'],\n   ['r','sBtnBdW','按钮边框'],['c','sBtnBdC','按钮边框色'],['r','sBtnFs','按钮字号']\n ]],\n ['q4','分类标签 \/ 二级导航 \/ 发帖按钮',[\n   ['h','<b>一级分类标签<\/b>'],\n   ['c','tabBg','底色'],['r','tabA','不透明度 %'],['r','tabBdW','边框'],['c','tabBdC','边框色'],['r','tabRd','圆角'],\n   ['c','tabTx','文字色'],['r','tabFs','字号'],['r','tabPV','上下内边距'],['r','tabPH','左右内边距'],['r','tabGap','间距'],\n   ['c','tabOnBg','选中底色'],['c','tabOnTx','选中文字色'],\n   ['h','<b>二级导航（全部 \/ 最新 \/ 热门 \/ 热帖 \/ 精华）<\/b>'],\n   ['b','subOn','显示二级导航'],\n   ['c','subBg','底色'],['r','subA','不透明度 %'],['r','subBdW','边框'],['c','subBdC','边框色'],['r','subRd','圆角'],\n   ['c','subTx','文字色'],['r','subFs','字号'],['r','subPV','上下内边距'],['r','subPH','左右内边距'],['r','subGap','间距'],\n   ['c','subOnBg','选中底色'],['c','subOnTx','选中文字色'],\n   ['h','<b>发帖按钮<\/b>（自动指向当前分区）<\/b>'],\n   ['b','pstOn','显示发帖按钮'],\n   ['c','pstBg','底色'],['r','pstA','不透明度 %'],['c','pstTx','文字色'],['r','pstBdW','边框'],['c','pstBdC','边框色'],\n   ['r','pstRd','圆角'],['r','pstFs','字号'],['r','pstPV','上下内边距'],['r','pstPH','左右内边距']\n ]],\n ['q5','头像',[\n   ['b','avOn','显示头像'],\n   ['r','avSz','尺寸'],['r','avRd','圆角(50=圆)'],['r','avBdW','边框'],['c','avBdC','边框色'],['c','avBg','占位底色'],\n   ['r','avGap','与标题间距']\n ]],\n ['q5b','头像外框',[\n   ['h','给列表头像套一层装饰图。外框默认与头像同大，调「外框尺寸」可放大到头像外面。<br>'\n       +'「外框在下」适合四周有留白的完整相框图；「外框在上」适合中间镂空的贴纸型边框。'],\n   ['b','frOn','启用头像外框'],\n   ['x','<div id=\"pfr\"><\/div>'],\n   ['x','<div class=\"row\"><input type=\"text\" id=\"frsel\" readonly placeholder=\"点上面的图片选中，再点复制\" onclick=\"this.select()\" style=\"flex:1;min-width:0\"><button class=\"bt\" onclick=\"pvCopyH(\\'fr\\')\">📋复制链接<\/button><\/div>'],\n   ['x','<div class=\"srow\"><label>保存到分类<\/label><select id=\"frcat\"><\/select><\/div>'],\n   ['h','<b>直链怎么拿<\/b>：网上找到头像框下载 → 浏览器进论坛图片区上传 → '\n       +'订阅源里打开该帖详情页长按图片复制直链（弹窗报错就先点图片放大再长按复制）。'\n       +'不支持复制就换张图。粘贴进来保存即可，再配合去底色清掉水印。'],\n   ['x','<input type=\"text\" id=\"fri\" placeholder=\"外框图片网址 或 \/sdcard\/Pictures\/frame.png\">'],\n   ['x','<div class=\"row\"><button class=\"bt\" onclick=\"addFr()\">保存并应用<\/button><button class=\"bt\" onclick=\"clearFr()\">清除外框<\/button><\/div>'],\n   ['x','<div class=\"row\"><button class=\"bt\" onclick=\"wnUp(\\'fr\\')\">上传到头像框云<\/button><button class=\"bt\" onclick=\"wnDown(\\'fr\\')\">从头像框云下载<\/button><\/div>'],\n   ['r','frSz','外框尺寸'],['s','frMode','叠放次序'],\n   ['r','frOffX','横向偏移'],['r','frOffY','纵向偏移'],['r','frA','不透明度 %']\n ]],\n ['q6','列表图片',[\n   ['h','一行几张 = 100 ÷ 单图宽度 %（33% → 3 张，25% → 4 张），再受「最多显示张数」限制。<br>'\n       +'图片高度统一为「行高」，宽度自动撑满整行（行越宽图越宽、间距越大图越窄）；'\n       +'图片不够铺满一行时按「单图宽度」左对齐，不会把少数几张拉伸成超大图。'],\n   ['b','igOn','显示列表图片'],\n   ['r','igRowH','行高 px'],['r','igW','单图宽度 %'],['r','igGap','图片间距'],\n   ['r','igMax','最多显示张数'],['r','igTop','上方间距'],\n   ['s','igFit','裁切模式'],['r','igRd','圆角'],['r','igBdW','边框'],['c','igBdC','边框色'],['r','igA','不透明度 %']\n ]],\n ['q7','标题字体',[\n   ['r','ttFs','字号'],['r','ttFw','字重'],['r','ttLh','行高 %'],['r','ttLs','字距'],\n   ['c','ttTx','颜色'],['b','ttIt','斜体'],['r','ttSh','阴影'],['c','ttShC','阴影色'],['r','ttLines','最多行数']\n ]],\n ['q8','正文摘要字体',[\n   ['h','摘要独占整行，会自动挤进头像与图片的留白，并按「最多行数」换行截断。'],\n   ['b','msOn','显示摘要'],\n   ['r','msFs','字号'],['r','msFw','字重'],['r','msLh','行高 %'],['r','msLs','字距'],\n   ['c','msTx','颜色'],['b','msIt','斜体'],['r','msSh','阴影'],['c','msShC','阴影色'],\n   ['r','msLines','最多行数'],['r','msTop','上方间距']\n ]],\n ['q9','综合信息字体',[\n   ['h','综合信息（作者 \/ 时间 \/ 观看 \/ 回复）常驻卡片底部，横跨整行，固定一行。放不下时会先压缩间距、再缩小字号，仍放不下才在尾部省略。'],\n   ['b','mtOn','显示综合信息'],\n   ['h','<b>最后发表<\/b>：需要额外请求一次电脑版列表（46.7KB）。已改为首屏渲染完、'\n       +'主线程空闲后再异步取并回填，<b>不影响其它元素的显示速度<\/b>；'\n       +'它流动排列在观看数\/回复数后面。不需要可关掉，能省掉这次请求。'],\n   ['b','lpOn','获取「最后发表」'],\n   ['r','mtFs','字号'],['r','mtFw','字重'],['r','mtLs','字距'],['c','mtTx','颜色'],\n   ['b','mtIt','斜体'],['r','mtSh','阴影'],['c','mtShC','阴影色'],\n   ['t','mtSep','分隔符',' · '],['b','mtAuto','挤不下时自动压缩'],['r','mtMinFs','最小字号'],\n   ['r','mtTop','与上方内容间距'],['r','mtBott','距卡片底部'],\n   ['h','<b>下拉到底部自动加载下一页<\/b>：默认开启，但要等你<b>向下滑动<\/b>后才会触发，'\n       +'切换分类\/二级导航导致的页面骤降不会误触发连续翻页。'\n       +'不想自动加载就关掉，改为手动点下方「加载更多」。'],\n   ['b','autoNext','下拉到底自动加载'],\n   ['h','<b>各字段独立颜色<\/b>（留空 = 跟随综合信息）'],\n   ['c','auTx','作者'],['c','tmTx','时间'],['c','vwTx','观看数'],['c','rpTx','回复数'],['c','lpTx','最后发表']\n ]],\n ['q10','置顶帖',[\n   ['c','tpBg','底色'],['r','tpA','不透明度 %'],['r','tpBdW','边框'],['c','tpBdC','边框色'],['c','tpTx','标题文字色'],\n   ['h','置顶帖信息很少，只有标题一行。'],\n ]],\n ['qAnn','公告卡片',[\n   ['c','annBg','底色'],['r','annA','不透明度 %'],['r','annBdW','边框'],['c','annBdC','边框色'],['c','annTx','文字色'],\n   ['h','首页置顶帖上方显示的网站公告。'],\n ]],\n ['q12','设置弹窗外观',[\n   ['c','mBg','弹窗底色'],['r','mA','不透明度 %'],['c','mTx','弹窗文字色'],\n   ['c','dBg','分区底色'],['r','dA','不透明度 %'],['c','dBdC','分区边框色'],['r','dRd','分区圆角'],\n   ['c','sechBg','折叠标题底色'],['r','sechA','不透明度 %'],['c','hdTx','小标题色'],\n   ['c','lbTx','控件标签色'],['c','hintTx','提示文字色'],\n   ['c','pk','主题色(选中\/主按钮)'],['c','btnBg','普通按钮底色'],['c','btnTx','普通按钮文字色']\n ]],\n ['q13','悬浮设置按钮',[\n   ['h','长按按钮约 0.5 秒进入拖动模式，拖到合适位置松手即自动保存。'],\n   ['b','fabOn','显示悬浮按钮'],\n   ['r','fabSz','按钮大小'],['r','fabRd','圆角(50=正圆)'],\n   ['c','fabBg','底色'],['r','fabA','不透明度 %'],\n   ['t','fabEmo','图标文字','留空 = 纯色按钮'],['t','fabBi','按钮背景图网址','https:\/\/... 或 \/sdcard\/xx.gif'],\n   ['x','<div class=\"row\"><button class=\"bt\" onclick=\"applyFabBi()\">应用背景图<\/button><button class=\"bt\" onclick=\"clearFabBi()\">清除背景图<\/button><\/div>'],\n   ['s','fabFit','裁切模式'],['r','fabScl','背景图缩放 %'],\n   ['r','fabBdW','边框'],['c','fabBdC','边框色'],['r','fabSh','阴影'],['c','fabShC','阴影色'],\n   ['c','fabTx','图标颜色'],['r','fabFs','图标字号'],\n   ['r','fabX','位置·距右'],['r','fabY','位置·距底']\n ]],\n ['q14','我的模板',[\n   ['x','<input type=\"text\" id=\"profName\" placeholder=\"输入模板名称\">'],\n   ['x','<div class=\"row\"><button class=\"bt pri\" id=\"profBtn\" onclick=\"saveProfile()\">💾 保存方案<\/button><button class=\"bt\" onclick=\"cancelRen()\">取消重命名<\/button><\/div>'],\n   ['x','<div class=\"hint\">模板 \/ 导出 \/ 本机备份都会一起带上「我的」分类里的自定义按钮及其容器内容，换设备粘一次就能还原。<\/div>'],\n   ['x','<div id=\"profList\"><\/div>']\n ]],\n ['q15','配置备份 \/ 恢复',[\n   ['x','<div class=\"hint\">导出：下方文本即当前全部配置，长按全选复制保存。<br>导入：粘贴文本后点「导入并应用」。<\/div>'],\n   ['x','<textarea id=\"ioTa\" rows=\"7\" placeholder=\"点导出生成配置文本，或粘贴配置文本后点导入\"><\/textarea>'],\n   ['x','<div class=\"row2\"><button class=\"bt\" onclick=\"exportCfg()\">导出<\/button><button class=\"bt\" onclick=\"copyCfg()\">复制<\/button><\/div>'],\n   ['x','<div class=\"row\"><button class=\"bt pri\" style=\"flex:1\" onclick=\"importCfg()\">导入并应用<\/button><\/div>'],\n   ['x','<div class=\"row2\"><button class=\"bt\" onclick=\"saveCfgLocal()\">存为本机备份<\/button><button class=\"bt\" onclick=\"loadCfgLocal()\">读取本机备份<\/button><\/div>'],\n   ['x','<div class=\"row2\"><button class=\"bt\" onclick=\"darkPreset()\">深色配色<\/button><button class=\"bt\" onclick=\"lightPreset()\">浅色默认<\/button><\/div>'],\n   ['x','<div class=\"row2\"><button class=\"bt warn\" onclick=\"resetAll()\">恢复出厂设置<\/button><button class=\"bt\" onclick=\"closeIO()\">关闭<\/button><\/div>']\n ]],\n ['q16','章节正文',[\n   ['h','章节阅读页正文（小说站）的字体外观。'],\n   ['r','xsFs','字号'],['r','xsFw','字重'],['r','xsLh','行高 %'],['r','xsLs','字距'],\n   ['c','xsTx','颜色'],\n   ['h','fixed35：正文在「正文容器」内渲染。滑动 \/ 翻页过程中容器会临时变成完全透明，不遮挡背景图。'],\n   ['r','x8Opa','容器底色透明度 %'],['r','x8DocH','容器高度 vh'],\n   ['c','x8DocBg','容器底色'],['s','x8Mode','阅读模式']\n ]]\n];\nfunction buildPanel(){\n  \/* v58: 原来只有点遮罩才能退出, 面板一长就很难点到遮罩,\n     现在头部给 ✕、底部给常驻「完成」(sticky, 滚到哪都点得到)。 *\/\n  var h='<div class=\"phd\"><h3>\\ud83c\\udfa8 外观设置<\/h3>'\n    +'<button class=\"x\" type=\"button\" onclick=\"closeBG()\" aria-label=\"关闭\">\\u2715<\/button><\/div>'\n    +'<div class=\"hint\">点标题展开 \/ 折叠分区。<\/div>';\n  for(var i=0;i<SCHEMA.length;i++){\n    h+=sec(SCHEMA[i][0],SCHEMA[i][1],false);\n    for(var j=0;j<SCHEMA[i][2].length;j++)h+=prow(SCHEMA[i][2][j]);\n    h+=endsec();\n  }\n\n  \/* C批: 首页外观设置面板加入「问AI设置」入口 (style 参考详情页 detailBuildPanel 的 AI 区块) *\/\n  h+=sec(\"pAI\",\"AI 问答\",!1),h+='<div class=\"hint ck\" onclick=\"aiHintT(this)\">📌 免费模型怎么配置更稳？（点开）<div class=\"ckb\" style=\"display:none;font-size:12px\">为了减少免费模型的延迟高出错率高的问题，可在外观设置按钮打开ai问答设置，点新建，再点击申请免费密钥（来自站点<b>https:\/\/platform.aitools.cfd\/<\/b>）简单命个序号名，然后就会自动保存新配置。<br>同一IP过一个小时又能申请一个免费密钥，WIFI和移动数据IP是不同的，所以一个小时能申请2个免费密钥。回到问ai面板，选新配置，点击拉取，选择一个就够了，因为一个key每3-5秒只能请求1次，再选新申请密钥的配置，又拉取一个，循环。然后你就能有足够多并发模式可用的免费模型了，然后并发模式下哪个请求快就显示哪个结果。<br>为了更好的体验，还是建议去智谱、硅基流动、agens等平台，都有免费版模型，登录注册一个apikey，在外观设置按钮中ai问答设置里添加新配置填入正确的baseurl和key即可，不会注册和填写就问豆包元宝ds<\/div><\/div>',h+=`<div class=\"srow\"><label>开关<\/label><span class=\"dec-sw\"><button class=\"msw\" id=\"ai0\" onclick=\"upd('aiOn',0)\">关<\/button><button class=\"msw\" id=\"ai1\" onclick=\"upd('aiOn',1)\">开<\/button><\/span><\/div>`,h+='<div class=\"srow\"><label>配置<\/label><select id=\"aicfg\" onchange=\"aiPickCfg(this.value)\"><\/select><\/div>',h+='<div class=\"row\"><button class=\"bt\" onclick=\"aiAddCfg()\">＋ 新建<\/button><button class=\"bt\" onclick=\"aiDupCfg()\">复制<\/button><button class=\"bt warn\" onclick=\"aiDelCfg()\">删除<\/button><\/div>',h+=`<div class=\"srow\"><label>名称<\/label><input type=\"text\" id=\"ainame\" onchange=\"aiSet('n',this.value)\"><\/div>`,h+=`<div class=\"srow\"><label>Base<\/label><input type=\"text\" id=\"aibase\" placeholder=\"https:\/\/...\/v1\" onchange=\"aiSet('base',this.value)\"><\/div>`,h+=`<div class=\"srow\"><label>密钥<\/label><input type=\"text\" id=\"aikey\" placeholder=\"sk-...\" onchange=\"aiSet('key',this.value)\"><\/div>`,h+='<div class=\"row\"><button class=\"bt\" onclick=\"aiGenKey()\">↻ 申请免费密钥<\/button><button class=\"bt\" onclick=\"aiFetchModels()\">拉取模型<\/button><\/div>',h+=`<div class=\"srow\"><label>模型<\/label><input type=\"text\" id=\"aimodel\" placeholder=\"模型 ID，可手填\" onchange=\"aiSet('model',this.value)\"><\/div>`,h+=`<select id=\"aimpick\" onchange=\"aiSet('model',this.value)\"><\/select>`,h+=`<div class=\"srow\"><label>自动续期<\/label><span class=\"dec-sw\"><button class=\"msw\" id=\"aiauto0\" onclick=\"aiSet('auto',0)\">关<\/button><button class=\"msw\" id=\"aiauto1\" onclick=\"aiSet('auto',1)\">开<\/button><\/span><\/div>`,h+='<div class=\"hint\">密钥失效（401）时自动去免费站申请新密钥并覆盖。该站每小时限申请 1 个，且实测密钥约 1 小时过期，开着更省心。<\/div>',h+='<div class=\"srow\"><label>提示词<\/label><select id=\"aipro\" onchange=\"aiPickPro(this.value)\"><\/select><\/div>',h+=`<textarea id=\"aisys\" rows=\"4\" placeholder=\"系统提示词（选中文字会作为用户消息一起发送）\" onchange=\"aiSet('sys',this.value)\"><\/textarea>`,h+='<div class=\"row\"><button class=\"bt\" onclick=\"aiAddPro()\">＋ 存为模板<\/button><button class=\"bt warn\" onclick=\"aiDelPro()\">删提示词<\/button><\/div>',h+='<div class=\"hint\">预设：翻译 \/ 词语含义（含网络用语、常见用法、出现场景）\/ 润色改写 \/ 续写。改完点「存为模板」即可新增，也可在下拉里切换。<\/div>',\n  \nh+=endsec()\n\n  \/* fixed20: 分类栏排序 section (顶层, 与 AI 问答 平级, 不在 AI 内) *\/\n  h+=sec(\"pCats\",\"分类栏排序\",!1);\n  h+='<div class=\"hint\">调整首页顶部「分类」按钮的先后顺序。默认顺序：应用 在 求书 之后。<\/div>';\n  h+='<div class=\"catord\" id=\"catord\">'+catOrdHtml()+'<\/div>';\n  h+='<div class=\"row2\"><button class=\"bt\" type=\"button\" onclick=\"catOrdSave()\">保存顺序<\/button><button class=\"bt\" type=\"button\" onclick=\"catOrdReset()\">恢复默认<\/button><\/div>';\n  h+=endsec()\nh+=endsec()\n  h+='<div class=\"row\"><button class=\"bt\" type=\"button\" onclick=\"annOpen()\">📢 更新公告<\/button><\/div>';\n  h+='<div class=\"row done\"><button class=\"bt pri\" style=\"flex:1\" onclick=\"closeBG()\">\\u5b8c\\u6210<\/button><\/div>';\n  return h;\n}\nfunction syncStyle(){\n  for(var k in PDEF){\n    var d=PDEF[k],t=d[0],id='s'+k;\n    if(t==='r'){setV(id,ST[k]);sv(id,ST[k]);}\n    else if(t==='c')setSw(id,ST[k]);\n    else if(t==='t')setV(id,ST[k]);\n    else if(t==='s')setV(id,ST[k]);\n    else if(t==='b'){\n      var a=document.getElementById(id+'0'),b=document.getElementById(id+'1');\n      if(a)a.className='msw'+(ST[k]?'':' on');\n      if(b)b.className='msw'+(ST[k]?' on':'');\n    }\n  }\n}\n\/* ---- 背景图分类列表 ---- *\/\nfunction catOpts(list){\n  var o='';\n  for(var i=0;i<list.length;i++)o+='<option value=\"'+esc(list[i])+'\">'+esc(list[i])+'<\/option>';\n  return o;\n}\nfunction bgBlock(){\n  var o='';\n  for(var i=0;i<BGL.length;i++){\n    o+='<span class=\"pvwrap'+((typeof PVS!=\"undefined\"&&PVS.bg===BGL[i].u)?' pick':'')+'\"><img class=\"pv\" src=\"'+esc(BGL[i].u)+'\" data-k=\"bg\" onclick=\"try{pvSelEl(this)}catch(e){};useBG(\\''+i+'\\')\" onerror=\"this.style.opacity=.25\" ontouchstart=\"pvLP(event,this)\" ontouchend=\"pvClr()\" ontouchcancel=\"pvClr()\" onmousedown=\"pvLP(event,this)\" onmouseup=\"pvClr()\" onmouseleave=\"pvClr()\" oncontextmenu=\"pvCpImg(this);return false;\">'\n      +'<b class=\"pvx\" onclick=\"delBG('+i+')\">×<\/b><\/span>';\n  }\n  if(!o)o='<div class=\"hint\">还没有保存过背景图。<\/div>';\n  o+='<div class=\"row\"><button class=\"bt\" onclick=\"restoreDef(\\'bg\\')\">↺ 恢复默认背景图<\/button><\/div>';\n  return o;\n}\nfunction useBG(i){var it=BGL[i];if(!it)return;BG=it.u;pput(KBG,BG);applyBG();refreshPanel();tip('✔ 已应用背景图','ok');}\nfunction delBG(i){\n  if(!BGL[i])return;\n  if(!confirm('确定删除这张背景图？'))return;\n  if(BG===BGL[i].u){BG='';pput(KBG,'');applyBG();}\n  BGL.splice(i,1);jsave(KBGL,BGL);refreshPanel();tip('✔ 已删除');\n}\nfunction addBG(){\n  var v=(document.getElementById('bi')||{}).value||'';\n  v=v.trim();\n  if(!v){tip('✘ 请输入背景图片地址');return;}\n  var u=toFile(v),sel=document.getElementById('bcat');\n  var cat=sel?sel.value:'默认';\n  var ex=null;\n  for(var i=0;i<BGL.length;i++){if(BGL[i].u===u)ex=BGL[i];}\n  if(ex)ex.c=cat;else BGL.push({u:u,c:cat});\n  jsave(KBGL,BGL);BG=u;pput(KBG,u);applyBG();\n  document.getElementById('bi').value='';refreshPanel();tip('✔ 已保存到「'+cat+'」并应用');\n}\nfunction clearBG(){BG='';pput(KBG,'');applyBG();refreshPanel();tip('✔ 已清除背景');}\n\n\n\/* ===== v61 头像框\/背景图 云同步(webnote.cc「按名称」剪贴板) =====\n   读取: POST \/netcut\/note\/info\/  note_name=<名称>\n   保存: POST \/netcut\/note\/save\/  note_name & note_id & note_token & note_content\n   ★ 每次保存都会生成新的 note_id\/token, 追加前必须先 info 取最新 id\/token。\n   ★★ 通道顺序(实测结论, 别再调回去):\n     1) fetch —— 接口校验 TLS 指纹, OkHttp\/Java 原生指纹会被判「服务器负载过高」;\n        而它 CORS 头回声 Origin(Origin:xxx -> ACAO:xxx + ACAC:true), WebView 内 fetch 可用。\n     2) postAwait \/ ajaxAwait(url,{\"method\":\"POST\"...}) \/ java.ajax —— 仅作兜底。\n        注意 ajaxAwait 只收 1 个参数(url), POST 要走 postAwait 或 AnalyzeUrl 的 url,{} 选项串。\n     每条通道都必须返回 JSON 且 status===1 才算成功, 否则换下一条, 并透出服务端 error。 *\/\nvar WNAPI='https:\/\/api-webnote.txttool.cn\/netcut\/note\/';\nvar WNNM={fr:'头像框',bg:'背景图片'};\nfunction wnOk(t){try{var o=JSON.parse(t);return !!(o&&o.status===1&&o.data);}catch(e){return false;}}\nfunction wnErr(t){\n  try{var o=JSON.parse(t);if(o&&o.status!==1)return String(o.error||('status='+o.status));}catch(e){}\n  t=String(t||'');\n  return t?('响应异常: '+t.slice(0,50)):'空响应';\n}\nfunction wnChan(u,body,h){\n  var c=[];\n  \/* 1) 浏览器内核 fetch(推荐通道) *\/\n  c.push(function(){return new Promise(function(res,rej){\n    try{fetch(u,{method:'POST',body:body,headers:h,mode:'cors',credentials:'omit'})\n          .then(function(r){return r.text();})\n          .then(function(t){res(String(t||''));},rej);}\n    catch(e){rej(e);}\n  });});\n  \/* 2) postAwait(url, body, headersJSON) *\/\n  c.push(function(){return Promise.resolve(postAwait(u,body,JSON.stringify(h)))\n    .then(function(a){return String(a==null?'':a);});});\n  \/* 3) ajaxAwait 走 Legado AnalyzeUrl 的 url,{选项} 语法做原生 POST *\/\n  c.push(function(){return Promise.resolve(ajaxAwait(u+','+JSON.stringify({method:'POST',body:body,headers:h})))\n    .then(function(a){return String(a==null?'':a);});});\n  \/* 4) java.ajax(url, 选项JSON) \/ java.ajax(url) 兜底 *\/\n  c.push(function(){return Promise.resolve(java.ajax(u,JSON.stringify({method:'POST',body:body,headers:h})))\n    .then(function(a){return String(a==null?'':a);});});\n  return c;\n}\nfunction wnRun(c,i,last){\n  if(i>=c.length)return Promise.reject(new Error(last||('无可用网络通道')));\n  return Promise.resolve().then(function(){return c[i]();}).then(function(t){\n    t=String(t==null?'':t);\n    if(wnOk(t))return t;\n    return wnRun(c,i+1,wnErr(t));\n  },function(e){\n    var m=(e&&e.message)?String(e.message).slice(0,50):'异常';\n    \/* 通道不可用(java\/postAwait 未定义)时不要覆盖上一次的真实错误(如\"服务器负载过高\") *\/\n    if(last&&\/is not defined|not a function\/.test(m))return wnRun(c,i+1,last);\n    return wnRun(c,i+1,m);\n  });\n}\nfunction wnReq(p,body){\n  var u=WNAPI+p+'\/';\n  var h={'Content-Type':'application\/x-www-form-urlencoded; charset=UTF-8',\n         'X-Requested-With':'XMLHttpRequest',\n         'Accept':'application\/json, text\/javascript, *\/*; q=0.01'};\n  return new Promise(function(res,rej){\n    var done=false,tm=null;\n    try{tm=setTimeout(function(){if(done)return;done=true;rej(new Error('请求超时(20秒)'));},20000);}catch(e){}\n    function fin(f,a){if(done)return;done=true;try{tm&&clearTimeout(tm);}catch(e){}f(a);}\n    wnRun(wnChan(u,body,h),0,'').then(function(t){fin(res,t);},function(e){fin(rej,e);});\n  });\n}\nfunction wnData(txt){\n  var o=null;\n  try{o=JSON.parse(txt);}catch(e){throw new Error('响应不是JSON: '+String(txt||'').slice(0,40));}\n  if(o&&o.status===1&&o.data)return o.data;\n  throw new Error(String((o&&o.error)||('status='+(o&&o.status))));\n}\n\/* note_content 是 JSON 数组字符串: [{\"title\":..,\"content\":..}] -> 拼成纯文本 *\/\nfunction wnText(nc){\n  if(!nc)return '';\n  try{\n    var a=JSON.parse(nc);\n    if(a&&a.length){\n      var s='';\n      for(var i=0;i<a.length;i++)s+=(a[i].title||'')+(a[i].content||'');\n      return s;\n    }\n  }catch(e){}\n  return String(nc);\n}\nfunction wnPack(txt){return JSON.stringify([{title:'',content:txt}]);}\n\/* ===== fixed34 首页更新公告 =====\n   正文来源: https:\/\/webnote.cc\/p\/1d15ae33c97d0276  (note_id=1d15ae33c97d0276, 无密码)\n   接口: POST https:\/\/api-webnote.txttool.cn\/netcut\/note\/info\/  (note_id & note_pwd)\n   逻辑: 进入首页懒加载便签, 与上次内容比对 -> 有变化则弹窗; 无变化则 24h 内不再弹窗也不再检测。\n   正文渲染: 同帖子详情页 v46 —— 自动识别 .json 链接并附加「⤓ 一键导入」。 *\/\nvar ANURL='https:\/\/webnote.cc\/p\/1d15ae33c97d0276';\nvar ANID='1d15ae33c97d0276';\nvar KANH='x8_ann_hash',KANT='x8_ann_ts';\nvar ANDAY=24*60*60*1000;\nvar _annCache=null;\nfunction annEsc(t){return String(t==null?'':t).replace(\/&\/g,'&amp;').replace(\/<\/g,'&lt;').replace(\/>\/g,'&gt;').replace(\/\"\/g,'&quot;');}\nfunction annHash(s){s=String(s||'');var h=5381,i;for(i=0;i<s.length;i++){h=(((h<<5)+h)^s.charCodeAt(i))>>>0;}return h.toString(36)+'_'+s.length;}\nfunction annIsJson(u){return \/^https?:\\\/\\\/[^\\s\"'<>]+\\.json(\\?[^#\\s]*)?(#\\S*)?$\/i.test(u);}\nfunction annLink(u){\n  var e=String(u||'');if(!e)return '';\n  var o='<a class=\"anlink\" href=\"'+annEsc(e)+'\">'+annEsc(e)+'<\/a>';\n  if(annIsJson(e))o+='<span class=\"animp\" data-u=\"'+annEsc(e)+'\" onclick=\"annImp(this)\">\\u2913 一键导入<\/span>';\n  return o;\n}\nfunction annRender(txt){\n  var raw=String(txt==null?'':txt),re=\/https?:\\\/\\\/[A-Za-z0-9\\-._~:\\\/?#\\[\\]@!$&'()*+,;=%]+\/gi,out='',last=0,m;\n  while((m=re.exec(raw))){\n    var u=m[0],tail='',mt=u.match(\/[.,;:!?)\\]}'\"]+$\/);\n    if(mt){tail=mt[0];u=u.slice(0,u.length-tail.length);}\n    out+=annEsc(raw.slice(last,m.index))+annLink(u)+annEsc(tail);\n    last=m.index+m[0].length;\n  }\n  return out+annEsc(raw.slice(last));\n}\nfunction annReq(){\n  var u=WNAPI+'info\/';\n  var h={'Content-Type':'application\/x-www-form-urlencoded; charset=UTF-8',\n         'Origin':'https:\/\/webnote.cc','Referer':ANURL,\n         'X-Requested-With':'XMLHttpRequest',\n         'Accept':'application\/json, text\/javascript, *\/*; q=0.01'};\n  var body='note_id='+ANID+'&note_pwd=';\n  return new Promise(function(res,rej){\n    var done=false,tm=null;\n    try{tm=setTimeout(function(){if(done)return;done=true;rej(new Error('请求超时(20秒)'));},20000);}catch(e){}\n    function fin(f,a){if(done)return;done=true;try{tm&&clearTimeout(tm);}catch(e){}f(a);}\n    wnRun(wnChan(u,body,h),0,'').then(function(t){fin(res,t);},function(e){fin(rej,e);});\n  });\n}\nfunction annParse(txt){\n  var d=wnData(txt),raw=String((d&&d.note_content)||''),arr=[];\n  try{arr=JSON.parse(raw);}catch(e){arr=[];}\n  if(!(arr&&arr.length&&arr[0]&&(arr[0].title||arr[0].content)))return {title:'',text:wnText(raw),raw:raw};\n  var tt='',cc='',i;\n  for(i=0;i<arr.length;i++){if(i===0)tt=String(arr[i].title||'');if(arr[i].content)cc+=(cc?'\\n\\n':'')+String(arr[i].content);}\n  return {title:tt,text:cc,raw:raw};\n}\nfunction annLoad(){\n  if(_annCache)return Promise.resolve(_annCache);\n  return annReq().then(function(t){var o=annParse(t);_annCache=o;return o;});\n}\nfunction annBody(html){var b=document.getElementById('x8annbd');if(b)b.innerHTML=html;}\nfunction annFill(o){\n  annBody((o&&o.title?'<div class=\"antt\">'+annEsc(o.title)+'<\/div>':'')\n    +'<div class=\"antx\">'+annRender(o?o.text:'')+'<\/div>');\n}\nfunction annErr(e){annBody('<div class=\"anhint\">✘ 获取失败：'+annEsc((e&&e.message)||'网络异常')+'<\/div>');}\nfunction annShow(){\n  var m=document.getElementById('x8ann');if(!m)return;\n  var b=document.getElementById('x8annb');\n  if(b&&!b.getAttribute('data-a')){\n    b.innerHTML='<div class=\"phd\"><b>📢 更新公告<\/b><span style=\"flex:1\"><\/span>'\n      +'<button class=\"bt\" type=\"button\" onclick=\"closeAnn()\">关闭<\/button><\/div>'\n      +'<div id=\"x8annbd\"><div class=\"anhint\">正在获取更新公告…<\/div><\/div>'\n      +'<div class=\"anhint\">关闭后可从首页外观设置按钮中点击更新公告按钮进入<\/div>';\n    b.setAttribute('data-a','1');\n  }\n  m.className='modal on';\n}\nfunction closeAnn(){var m=document.getElementById('x8ann');if(m)m.className='modal';}\nfunction annOpen(){annShow();annLoad().then(function(o){annFill(o);},annErr);}\nfunction annAuto(){\n  var now=Date.now(),lt=0;\n  try{lt=parseInt(pget(KANT)||'0',10)||0;}catch(e){}\n  if(lt&&(now-lt)<ANDAY)return;\n  annLoad().then(function(o){\n    var h=annHash(o.raw),last='';\n    try{last=pget(KANH)||'';}catch(e){}\n    try{pput(KANT,String(now));}catch(e){}\n    if(h!==last){try{pput(KANH,h);}catch(e){}annShow();annFill(o);}\n  },function(){});\n}\nfunction annImp(el){\n  var u=el&&el.getAttribute?el.getAttribute('data-u'):'';\n  if(!u)return;\n  try{el.textContent='已跳转导入…';}catch(e){}\n  try{location.href='legado:\/\/import\/any?src='+encodeURIComponent(u);return;}catch(e){}\n  try{if(typeof java!='undefined'&&java&&typeof java.open=='function'){java.open('rss',u);return;}}catch(e){}\n  try{location.href=u;}catch(e){}\n}\n\nfunction wnGet(nm){\n  return wnReq('info','note_name='+encodeURIComponent(nm)).then(function(t){\n    return wnData(t);});\n}\nfunction wnPut(nm,id,tk,content){\n  return wnReq('save','note_name='+encodeURIComponent(nm)\n    +'&note_id='+encodeURIComponent(id||'')\n    +'&note_token='+encodeURIComponent(tk||'')\n    +'&note_content='+encodeURIComponent(content)\n    +'&expire_time=2592000').then(function(t){return wnData(t);});\n}\n\/* 保存失败重试: 服务端偶发 {\"status\":2,\"error\":\"业务处理失败\"}(token 刚轮换\/抖动),\n   重取一次最新 id\/token 再写一次 *\/\nfunction wnRetry(nm,txt){\n  return wnGet(nm).then(function(d2){return wnPut(nm,d2.note_id,d2.note_token,wnPack(txt));});\n}\n\/* 正文 -> 图片链接数组: 从任意文本里提取 http(s)\/file 链接(支持紧跟中文无分隔符的情况), 并去重 *\/\nfunction wnUrls(txt){\n  var out=[],seen={};\n  var re=\/(?:https?:\\\/\\\/|file:\\\/\\\/)[^\\s,，;；|、<>\"'）)】\\]。]+\/gi;\n  var m;\n  while((m=re.exec(String(txt||'')))!==null){\n    var u=m[0].replace(\/[,，;；|、.。]+$\/,'');\n    if(!u)continue;\n    if(seen[u])continue;\n    seen[u]=1;out.push(u);\n  }\n  return out;\n}\n\/* 复制文本: execCommand('copy') 优先, navigator.clipboard 兜底 *\/\nfunction cpTxt(t){\n  t=String(t==null?'':t);\n  if(!t)return;\n  try{\n    var ta=document.createElement('textarea');\n    ta.value=t;ta.setAttribute('readonly','');\n    ta.style.position='fixed';ta.style.left='-9999px';ta.style.opacity='0';\n    document.body.appendChild(ta);\n    ta.focus();ta.select();\n    try{ta.setSelectionRange(0,999999);}catch(e){}\n    var ok=false;try{ok=document.execCommand('copy');}catch(e){}\n    try{document.body.removeChild(ta);}catch(e){}\n    if(ok)return;\n  }catch(e){}\n  try{if(navigator.clipboard&&navigator.clipboard.writeText){navigator.clipboard.writeText(t);}}catch(e){}\n}\n\/* ===== v61 预览图「点选中 -> 点复制按钮」 =====\n   长按复制在部分 WebView\/机型上触发不稳定(有时要点一下图片才能长按), 所以改成显式交互:\n   点图片 = 选中(高亮 + 链接填入下方输入框) 并沿用原来的「应用」行为; 点「📋复制链接」= 复制。*\/\nvar PVS={};\nfunction pvCss(){\n  try{\n    if(document.getElementById('x8pk'))return;\n    var st=document.createElement('style');st.id='x8pk';\n    st.textContent='.pw.pick{outline:2px solid #ff9800;outline-offset:1px}'\n      +'.pvwrap.pick{outline:2px solid #ff9800;outline-offset:1px;border-radius:6px}'\n      +'#bgsel,#frsel,#bgsel2,#frsel2{opacity:.9}';\n    (document.head||document.documentElement).appendChild(st);\n  }catch(e){}\n}\nfunction pvBox(el){\n  try{\n    var b=el;\n    while(b&&b!==document){\n      var c=String(b.className||'');\n      if(c.indexOf('pvwrap')>=0||\/(^|\\s)pw(\\s|$)\/.test(c))return b;\n      b=b.parentNode;\n    }\n  }catch(e){}\n  return null;\n}\n\/* 从元素自身读 data-k(避免在内联 onclick 里写单引号把外层 JS 字符串截断) *\/\nfunction pvSelEl(el){\n  var k='';\n  try{k=el.getAttribute('data-k')||'';}catch(e){}\n  pvSel(k||'',el);\n}\nfunction pvSel(kind,el){\n  try{\n    pvCss();\n    var u='';\n    try{u=el.getAttribute('src')||el.src||'';}catch(e){}\n    u=String(u||'').trim();\n    if(u)PVS[kind]=u;\n    var inp=document.getElementById(kind+'sel');\n    if(inp&&u)inp.value=u;\n    try{\n      var all=document.querySelectorAll('.pw.pick,.pvwrap.pick'),i;\n      for(i=0;i<all.length;i++)all[i].className=String(all[i].className).replace(\/\\s*pick\\b\/g,'');\n    }catch(e){}\n    var b=pvBox(el);\n    if(b)b.className=String(b.className||'')+' pick';\n  }catch(e){}\n}\n\/* 返回实际复制的链接; 没选中返回空串 *\/\nfunction pvDo(kind){\n  var u=String(PVS[kind]||'').trim();\n  if(!u){\n    try{var inp=document.getElementById(kind+'sel');u=String((inp&&inp.value)||'').trim();}catch(e){}\n  }\n  if(!u)return '';\n  cpTxt(u);\n  return u;\n}\nvar _lpT=null;\nfunction pvCpImg(img){\n  try{if(img&&img.getAttribute)cpTxt(img.getAttribute('src')||img.src||'');}catch(e){}\n}\n\/* 长按预览图 600ms -> 复制该图链接(保留, 作为复制按钮之外的补充)\n   ★★ 绝对不要在这里 preventDefault(): ontouchstart 里 preventDefault 会让 WebView\n      不再合成 click 事件, 结果就是\"点一下应用\/选中\"彻底失效(首页 fixed13~14 正是踩了这个坑)。 *\/\nvar DBGSX=[\"https:\/\/c-ssl.dtstatic.com\/uploads\/blog\/202406\/08\/GgSbN770Sd4QMWy.thumb.1000_0.png\",\"https:\/\/c-ssl.duitang.com\/uploads\/blog\/202404\/24\/GgSZdaw3CdXwn3X.jpeg\",\"https:\/\/pic1.zhimg.com\/v2-7bad831d3495c510e0949cdaeac23fee_1440w.jpg\",\"https:\/\/picx.zhimg.com\/v2-b27197bcb7d8079c6260542508f14c6f_1440w.jpg\",\"https:\/\/pic1.zhimg.com\/v2-6fc07084f4c4972d8d2873f2023c5172_1440w.jpg\"];\nfunction restoreDef(kind){\n  try{\n    \/* 同时兼容字符串 'bg'\/'fr' 与布尔; 调用点均传 'bg'\/'fr' *\/\n    var isFr=(kind==='fr'||kind===true||kind==='true');\n    \/* 清除被忽略的默认图:\n       首页隐藏列表 KBGH\/KFRH 由 jsave\/pput 管理 -> 用 jsave 清空;\n       详情隐藏列表 _n\/zn 由 g(M\/yt) 管理 -> 用 g 清空;\n       两套存储互不相通, 必须用对机制(此前详情恢复失效的根因) *\/\n    if(typeof jsave==='function'){try{jsave(KBGH,[]);}catch(e){}try{jsave(KFRH,[]);}catch(e){}}\n    if(typeof g==='function'){try{if(typeof _n!=='undefined')g(_n,[]);}catch(e){}try{if(typeof zn!=='undefined')g(zn,[]);}catch(e){}}\n    \/* 背景: 把内置默认图补齐进本地库(首页 BGL \/ 详情 Z) *\/\n    if(!isFr){\n      var defs=(typeof DBGS!=='undefined'&&DBGS)?DBGS.slice():(typeof DBGSX!=='undefined'?DBGSX.slice():[]);\n      var bl=wnList('bg'),kk,xx,jj,hdup;\n      for(kk=0;kk<defs.length;kk++){xx=defs[kk].u||defs[kk];hdup=false;\n        for(jj=0;jj<bl.length;jj++){if(((bl[jj]&&bl[jj].u)||bl[jj])===xx){hdup=true;break;}}\n        if(!hdup)bl.push({u:xx,c:'默认'});}\n      try{g(wnKey('bg'),bl);}catch(e){}\n    }\n    try{if(typeof refreshPanel==='function')refreshPanel();}catch(e){}\n    try{if(typeof A==='function')A();}catch(e){}\n    try{if(typeof s==='function'){s('✔ 已恢复默认'+(isFr?'外框（被忽略的已显示）':'背景图（缺失的已补回）'),'ok');}else if(typeof tip==='function'){tip('✔ 已恢复默认'+(isFr?'外框（被忽略的已显示）':'背景图（缺失的已补回）'),'ok');}}catch(e){}\n  }catch(e){try{if(typeof s==='function')s('✘ 恢复失败：'+(e&&e.message||e),'no');else if(typeof tip==='function')tip('✘ 恢复失败：'+(e&&e.message||e),'no');}catch(_){}}\n}\nfunction pvLP(ev,img){\n  try{_lpT&&clearTimeout(_lpT);}catch(e){}\n  _lpT=setTimeout(function(){_lpT=null;pvCpImg(img);},600);\n}\nfunction pvClr(){try{_lpT&&clearTimeout(_lpT);}catch(e){}_lpT=null;}\n\/* ★ 抗系统深色反色: color-scheme:light only 告知 WebView 本页自带浅色主题,\n   阻止 Android force dark 把黑字反成白字(而底色不变) 造成的「白底白字」。 *\/\n(function(){\n  function addCS(){\n    try{\n      if(document.getElementById('x8cs'))return;\n      var st=document.createElement('style');st.id='x8cs';\n      st.textContent=':root{color-scheme:light only;supported-color-schemes:light only}html{color-scheme:light only}';\n      (document.head||document.documentElement).appendChild(st);\n    }catch(e){}\n  }\n  if(document.readyState==='loading'){\n    try{document.addEventListener('DOMContentLoaded',addCS);}catch(e){setTimeout(addCS,0);}\n  }else addCS();\n})();\n\/* ---- 首页: 本地库适配 (BGL=背景列表, FRD=外框列表) ---- *\/\n\nfunction pvCopyH(k){var u=pvDo(k);tip(u?('✔ 已复制链接: '+u.slice(0,28)+(u.length>28?'…':'')):'✘ 先点一张图片选中',u?'ok':'no');}\n\nfunction wnList(kind){return kind==='fr'?FRD:BGL;}\nfunction wnKey(kind){return kind==='fr'?KFRD:KBGL;}\nfunction wnUp(kind){\n  var nm=WNNM[kind]||kind,list=wnList(kind),add=[],i;\n  for(i=0;i<list.length;i++){var u=(list[i]&&list[i].u)||list[i];if(u)add.push(u);}\n  if(!add.length){tip('✘ 本地还没有保存过'+(kind==='fr'?'头像框':'背景图'));return;}\n  tip('正在上传到'+(kind==='fr'?'头像框':'背景图片')+'云…','wait');\n  wnGet(nm).then(function(d){\n    var cur=wnText(d.note_content)||'';\n    var have={};wnUrls(cur).forEach(function(u){have[u]=1;});\n    var neu=[];add.forEach(function(u){if(!have[u]){have[u]=1;neu.push(u);}});\n    if(!neu.length){tip('✔ 云端已包含全部本地链接');return null;}\n    var s=cur;\n    if(s&&!\/[,，]$\/.test(s))s+=',';   \/* 与已有内容分隔 *\/\n    s+=neu.join(',')+',';            \/* 末尾带逗号, 方便下次追加 *\/\n    var okf=function(){tip('✔ 已上传 '+neu.length+' 个链接到'+(kind==='fr'?'头像框':'背景图片')+'云','ok');};\n    return wnPut(nm,d.note_id,d.note_token,wnPack(s)).then(okf,function(){return wnRetry(nm,s).then(okf);});\n  })['catch'](function(e){tip('✘ 上传失败：'+(e&&e.message?e.message:e),'no');});\n}\nfunction wnDown(kind){\n  var nm=WNNM[kind]||kind,list=wnList(kind);\n  var wcat=(function(){try{var s=document.getElementById(kind==='fr'?'frcat':'bcat');return s&&s.value?s.value:'';}catch(e){return '';}})()||'默认';\n  tip('正在从'+(kind==='fr'?'头像框':'背景图片')+'云下载…','wait');\n  wnGet(nm).then(function(d){\n    var urls=wnUrls(wnText(d.note_content)),added=0,chg=false,i,j;\n    for(i=0;i<urls.length;i++){\n      var u=urls[i],ex=-1;\n      for(j=0;j<list.length;j++){if(((list[j]&&list[j].u)||list[j])===u){ex=j;break;}}\n      if(ex>=0){var oc=(list[ex]&&list[ex].c)||'默认';if(oc!==wcat){list[ex].c=wcat;added++;}continue;}\n      \/* 内置默认图(ha\/va)仅详情页存在且直接显示在预览框: 跳过避免重复下载; 但被忽略(隐藏)的仍下载以恢复 *\/\n      if(typeof g==='function'){var _defs=((kind==='fr')?(typeof va!=='undefined'?va:[]):(typeof ha!=='undefined'?ha:[])),_dx=-1;\n      for(var _dj=0;_dj<_defs.length;_dj++){var _du=(_defs[_dj]&&_defs[_dj].u)||_defs[_dj];if(_du===u&&!((typeof Yn==='function')&&Yn(kind,u))){_dx=_dj;break;}}\n      if(_dx>=0){continue;}}\n      list.push({u:u,c:wcat});added++;\n    }\n    if(added){try{jsave(wnKey(kind),list);}catch(e){}}\n    try{if(typeof refreshPanel==='function')refreshPanel();}catch(e){}\n    tip(added?('✔ 已新增\/恢复 '+added+' 个链接到「'+wcat+'」'):'✔ 云端的链接本地都有了');\n  })['catch'](function(e){tip('✘ 下载失败：'+(e&&e.message?e.message:e),'no');});\n}\n\n\/* ---- v58 头像外框: 与背景图同一套交互(缩略图列表 + 分类 + 增删) ---- *\/\n\/* v58: 内置默认(删不掉) 排前面, 用户自己存的 排后面(可删)。\n   与帖子正文页头像框面板的排法保持一致。 *\/\n\/* v59: 默认图片的「忽略」列表(与帖子页共用键名, 两页同步)。\n   默认图写在代码里删不掉, 但可以「忽略」隐藏; 「恢复出厂设置」会清空, 让它们回来。 *\/\nvar KBGH='x8_hidebg',KFRH='x8_hidefr';\nfunction hideList(kind){var a=[];try{a=jload(kind==='bg'?KBGH:KFRH,null);}catch(e){}\n  return (a&&typeof a.length==='number')?a:[];}\nfunction isHidden(kind,u){var a=hideList(kind),i;\n  for(i=0;i<a.length;i++){if(a[i]===u)return true;}return false;}\nfunction hidePre(kind,u){\n  var a=hideList(kind),i;\n  for(i=0;i<a.length;i++){if(a[i]===u)break;}\n  if(i>=a.length)a.push(u);\n  jsave(kind==='bg'?KBGH:KFRH,a);\n  if(kind==='bg'){if(BG===u){BG='';pput(KBG,'');applyBG();}}\n  else{if(FR===u){FR='';pput(KFR,'');applyStyle();relayout();}}\n  refreshPanel();tip('✔ 已忽略该默认图（恢复出厂设置可找回）','ok');\n}\n\/* 用索引调用, 避免在 onclick 里拼接 URL 带来的转义麻烦 *\/\nfunction hideDefFr(i){var d=DFRAMES[i];if(!d)return;hidePre('fr',d.u||d);}\nfunction frBlock(){\n  var o='',i;\n  for(i=0;i<DFRAMES.length;i++){\n    var du=DFRAMES[i].u||DFRAMES[i];\n    if(isHidden('fr',du))continue;            \/* v59: 被忽略的默认图不显示 *\/\n    \/* v59: 默认图也能「忽略」(×); 点 × 调 hideDefFr, 走忽略列表而不是真删除 *\/\n    o+='<span class=\"pvwrap'+((typeof PVS!=\"undefined\"&&PVS.fr===du)?' pick':'')+'\"><img class=\"pv\" src=\"'+esc(du)+'\" data-k=\"fr\" onclick=\"try{pvSelEl(this)}catch(e){};useDef('+i+')\" onerror=\"this.style.opacity=.25\" ontouchstart=\"pvLP(event,this)\" ontouchend=\"pvClr()\" ontouchcancel=\"pvClr()\" onmousedown=\"pvLP(event,this)\" onmouseup=\"pvClr()\" onmouseleave=\"pvClr()\" oncontextmenu=\"pvCpImg(this);return false;\">'\n      +'<b class=\"pvx\" onclick=\"hideDefFr('+i+')\">×<\/b><\/span>';\n  }\n  for(i=0;i<FRD.length;i++){\n    o+='<span class=\"pvwrap'+((typeof PVS!=\"undefined\"&&PVS.fr===FRD[i].u)?' pick':'')+'\"><img class=\"pv\" src=\"'+esc(FRD[i].u)+'\" data-k=\"fr\" onclick=\"try{pvSelEl(this)}catch(e){};useCus('+i+')\" onerror=\"this.style.opacity=.25\" ontouchstart=\"pvLP(event,this)\" ontouchend=\"pvClr()\" ontouchcancel=\"pvClr()\" onmousedown=\"pvLP(event,this)\" onmouseup=\"pvClr()\" onmouseleave=\"pvClr()\" oncontextmenu=\"pvCpImg(this);return false;\">'\n      +'<b class=\"pvx\" onclick=\"delFr('+i+')\">×<\/b><\/span>';\n  }\n  if(!o)o='<div class=\"hint\">还没有保存过头像外框。<\/div>';\n  o+='<div class=\"row\"><button class=\"bt\" onclick=\"restoreDef(\\'fr\\')\">↺ 恢复默认外框<\/button><\/div>';\n  return o;\n}\n\/* 头像外框直链的获取方法(照着做一遍就会了):\n   ① 网上找到喜欢的头像框图片, 下载下来 —— 有没有水印、是不是透明 PNG 都可以;\n   ② 用浏览器进论坛的「图片区」, 把这张头像框上传上去;\n   ③ 在订阅源里打开相关帖子的详情页, 长按刚上传的那张图, 选「复制链接」;\n   ④ 如果长按弹窗报错, 就先点一下图片放大, 再长按复制图片直链;\n   ⑤ 还是不成功, 那就是这个链接本身不支持复制(换张图或换个图床再试)。\n   拿到直链后粘贴到下面的输入框, 点「保存并应用」即可。\n   之后配合去底色的 4 种模式(取色 \/ 只去连续的 \/ 框选 \/ 涂抹),\n   就能把水印和不想要的部分清掉, 得到干净的头像框。 *\/\nfunction useFrUrl(u){if(!u)return;FR=u;pput(KFR,FR);ST.frOn=1;saveST();applyStyle();relayout();refreshPanel();tip('✔ 已应用头像外框','ok');}\nfunction useDef(i){var d=DFRAMES[i];if(!d)return;useFrUrl(d.u||d);}\nfunction useCus(i){var d=FRD[i];if(!d)return;useFrUrl(d.u);}\nfunction delFr(i){\n  if(!FRD[i])return;\n  if(!confirm('确定删除这张外框图？'))return;\n  if(FR===FRD[i].u){FR='';pput(KFR,'');applyStyle();}\n  FRD.splice(i,1);jsave(KFRD,FRD);refreshPanel();tip('✔ 已删除');\n}\nfunction addFr(){\n  var v=(document.getElementById('fri')||{}).value||'';\n  v=v.trim();\n  if(!v){tip('✘ 请输入外框图片地址');return;}\n  var u=toFile(v),sel=document.getElementById('frcat');\n  var cat=sel?sel.value:'默认';\n  var ex=null;\n  for(var i=0;i<FRD.length;i++){if(FRD[i].u===u)ex=FRD[i];}\n  if(ex)ex.c=cat;else FRD.push({u:u,c:cat});\n  jsave(KFRD,FRD);useFrUrl(u);\n  document.getElementById('fri').value='';refreshPanel();tip('✔ 已保存到「'+cat+'」并启用');\n}\nfunction clearFr(){FR='';pput(KFR,'');applyStyle();relayout();refreshPanel();tip('✔ 已清除外框');}\nfunction clearHeroBi(){ST.heroBi='';saveST();applyStyle();setV('sheroBi','');tip('✔ 已清除标题框背景图');}\nfunction applyFabBi(){ST.fabBi=(document.getElementById('sfabBi')||{}).value||'';saveST();applyStyle();tip('✔ 已应用按钮背景图');}\nfunction clearFabBi(){ST.fabBi='';saveST();applyStyle();setV('sfabBi','');tip('✔ 已清除按钮背景图');}\n\/* ---- 模板 ---- *\/\nvar _ren=-1;\nfunction profBlock(){\n  var o='';\n  for(var i=0;i<PROF.length;i++){\n    var p=PROF[i]||{};\n    o+='<div class=\"profrow\">'\n      +'<button class=\"bt\" style=\"flex:1\" onclick=\"applyProfile('+i+')\">\\ud83c\\udfa8 '+esc(p.n||('方案'+(i+1)))+'<\/button>'\n      +'<button class=\"ib\" title=\"重命名\" onclick=\"renProfile('+i+')\">✏️<\/button>'\n      +'<button class=\"ib\" title=\"删除\" onclick=\"delProfile('+i+')\">\\ud83d\\uddd1<\/button><\/div>';\n  }\n  if(!o)o='<div class=\"hint\">还没有保存过模板，输入名称后点「保存方案」。<br>模板会连「我的」分类里的自定义按钮及其容器内容一起存下来。<\/div>';\n  return o;\n}\nfunction saveProfile(){\n  var inp=document.getElementById('profName');\n  var n=inp?(inp.value||'').trim():'';\n  if(!n){tip('✘ 请先输入模板名称');return;}\n  if(_ren>=0){\n    var p=PROF[_ren];\n    if(p){p.n=n;jsave(KPROF,PROF);_ren=-1;if(inp)inp.value='';tip('✔ 已重命名');}\n  }else{\n    var dup=-1;\n    for(var i=0;i<PROF.length;i++){if(PROF[i].n===n){dup=i;break;}}\n    var snap={n:n,s:snapCfg()};\n    if(dup>=0)PROF[dup]=snap;else PROF.push(snap);\n    jsave(KPROF,PROF);tip('✔ 已保存模板「'+n+'」');\n  }\n  refreshPanel();\n}\nfunction applyProfile(i){var p=PROF[i];if(!p)return;applyCfg(p.s,'模板「'+(p.n||'')+'」');}\nfunction cancelRen(){if(_ren<0)return;_ren=-1;var inp=document.getElementById('profName');if(inp)inp.value='';refreshPanel();}\nfunction renProfile(i){\n  var p=PROF[i];if(!p)return;_ren=i;\n  var inp=document.getElementById('profName');\n  if(inp){inp.value=p.n||'';inp.focus();inp.select();}\n  refreshPanel();tip('修改名称后点击「保存方案」');\n}\nfunction delProfile(i){\n  var p=PROF[i];if(!p)return;\n  if(!confirm('确定删除模板「'+(p.n||'')+'」？'))return;\n  PROF.splice(i,1);jsave(KPROF,PROF);\n  if(_ren===i)_ren=-1;\n  refreshPanel();tip('✔ 已删除模板');\n}\n\/* ---- fixed40: 「我的」分类的自定义按钮 + 各自容器里的内容 ---- *\/\n\/* 打包: 保存模板 \/ 导出 \/ 复制 \/ 本机备份 都会带上这一份 *\/\nfunction minePack(){\n  var out=[],i;\n  for(i=0;i<X8M.length;i++){\n    var m=X8M[i]||{};\n    out.push({id:String(m.id||''),n:String(m.n||''),txt:String(m.txt==null?'':m.txt),\n      img:m.img?1:0,btn:m.btn?1:0});\n  }\n  return out;\n}\n\/* 解包: 脏数据一律过滤; id 缺失或重复的自动补一个, 保证侧边栏 \/ 容器不打架 *\/\nfunction mineUnpack(a){\n  var out=[],seen={},i;\n  for(i=0;i<(a&&a.length?a.length:0);i++){\n    var o=a[i];\n    if(!o||typeof o!=='object')continue;\n    var id=String(o.id||'')||('m'+Date.now()+'_'+i);\n    if(seen[id])continue;\n    seen[id]=1;\n    out.push({id:id,n:String(o.n||'')||'未命名',txt:String(o.txt==null?'':o.txt),\n      k:'mine',img:o.img?1:0,btn:o.btn?1:0});\n  }\n  return out;\n}\n\/* 换掉 X8M 之后把界面接上: 清掉「我的」容器的内容缓存 -> 侧边栏按钮 -> 正在看的那个容器 *\/\nfunction mineSync(){\n  var mk;\n  for(mk in X8PC){if(x8CatOf(mk)===2)delete X8PC[mk];}\n  x8Cur=null;x8MineCache=[];\n  if(x8Sel&&x8CatOf(x8Sel)<0)x8Sel='';\n  var cit=x8Sel?x8Find(x8Sel):null;\n  if(cit&&x8CatOf(cit.id)===2)x8PaneRender(cit,true);\n  if(x8Cat>=0)x8Stamp();\n}\n\/* ---- 导入导出 ---- *\/\nfunction snapCfg(){\n  var o={v:3,ST:ST,BG:BG,BGL:BGL,BGC:BGC,FR:FR,FRD:FRD,FRC:FRC,XS:jload(xsCfgKey,null),M:minePack()};\n  \/* fixed40: ST \/ BG \/ BGL … 是「活引用」, 直接放进快照会跟着后续修改一起变 ->\n     「保存模板」\/「存为本机备份」拿到的就不是真快照。这里做一次深拷贝。 *\/\n  try{return JSON.parse(JSON.stringify(o));}catch(e){return o;}\n}\nfunction exportCfg(){\n  var ta=document.getElementById('ioTa');\n  if(ta){ta.value=JSON.stringify(snapCfg());setTimeout(function(){try{ta.focus();ta.select();}catch(e){}},80);}\n  tip('已生成配置文本，可长按全选复制');\n}\nfunction copyCfg(){\n  var ta=document.getElementById('ioTa');if(!ta)return;\n  var okc=false;\n  try{ta.removeAttribute('readonly');ta.focus();ta.select();ta.setSelectionRange(0,999999);okc=document.execCommand('copy');}catch(e){}\n  if(okc)tip('✔ 已复制到剪贴板');\n  else if(navigator.clipboard&&navigator.clipboard.writeText){\n    navigator.clipboard.writeText(ta.value).then(function(){tip('✔ 已复制到剪贴板');},function(){tip('请长按文本手动复制');});\n  }else tip('请长按文本手动复制');\n}\nfunction applyCfg(o,tag){\n  if(!o||typeof o!=='object'){tip('✘ 数据无效');return;}\n  \/* fixed40: 深拷贝一份再用 —— 否则 BGL\/BGC\/… 会把调用方的引用挂进全局,\n     之后改全局会反过来改到已保存的模板快照。 *\/\n  try{o=JSON.parse(JSON.stringify(o));}catch(e){}\n  if(o.ST&&typeof o.ST==='object'){\n    ST={};for(var k in PDEF){ST[k]=(o.ST[k]!==undefined&&o.ST[k]!==null)?o.ST[k]:PDEF[k][1];}\n  }\n  if(typeof o.BG==='string'){BG=o.BG;pput(KBG,BG);}\n  if(o.BGL&&o.BGL.length!==undefined){BGL=o.BGL;jsave(KBGL,BGL);}\n  if(o.BGC&&o.BGC.length!==undefined){BGC=o.BGC;jsave(KBGC,BGC);}\n  if(typeof o.FR==='string'){FR=o.FR;pput(KFR,FR);}\n  if(o.FRD&&o.FRD.length!==undefined){FRD=o.FRD;jsave(KFRD,FRD);}\n  if(o.FRC&&o.FRC.length!==undefined){FRC=o.FRC;jsave(KFRC,FRC);}\n  if(o.XS&&o.XS.length!==undefined){var cur=jload(xsCfgKey,null);if(!(cur&&cur.length!==undefined))cur=[];for(var xi=0;xi<o.XS.length;xi++){var xo=o.XS[xi];if(!xo||!xo.u)continue;var xf=-1;for(var xj=0;xj<cur.length;xj++){if(cur[xj].u===xo.u){xf=xj;break;}}if(xf>=0)cur[xf]=xo;else cur.push(xo);}jsave(xsCfgKey,cur);}\n  if(o.M&&o.M.length!==undefined){X8M=mineUnpack(o.M);x8MineSave();mineSync();}\n  saveST();applyStyle();applyBG();syncStyle();refreshPanel();relayout();\n  tip('✔ 已'+(tag||'导入')+'配置');\n}\nfunction importCfg(){\n  var ta=document.getElementById('ioTa');\n  if(!ta||!ta.value.trim()){tip('✘ 请先粘贴配置文本');return;}\n  var o;\n  try{o=JSON.parse(ta.value.trim());}catch(e){tip('✘ 解析失败：不是有效的配置文本');return;}\n  applyCfg(o,'导入');\n}\nvar KCFGL='x8p_cfgbk';\nfunction saveCfgLocal(){jsave(KCFGL,snapCfg());tip('✔ 已存为本机备份（含我的按钮）');}\nfunction loadCfgLocal(){var s=pget(KCFGL);if(!s){tip('✘ 无本机备份');return;}try{applyCfg(JSON.parse(s),'本机备份');}catch(e){tip('✘ 备份损坏');}}\nfunction resetAll(){\n  if(!confirm('确定恢复全部出厂设置？\\n所有自定义颜色\/间距\/背景\/模板以外的配置将被清空。'))return;\n  ST={};for(var k in PDEF)ST[k]=PDEF[k][1];\n  try{jsave(KBGH,[]);jsave(KFRH,[]);}catch(e){}   \/* v59: 让被忽略的默认图回来 *\/\n  try{pput(KCATS,'');CATS=catDefaultOrderOf(CATS_M.slice());CATWORK=catFidOrder();var ce=document.getElementById('catord');if(ce)ce.innerHTML=catOrdHtml();renderTabs();markTab();}catch(e){}\n  saveST();applyStyle();applyBG();syncStyle();refreshPanel();relayout();\n  tip('✔ 已恢复出厂设置');\n}\nfunction darkPreset(){\n  ST.pageBg='#16171C';ST.pageA=100;\n  ST.cardBg='#21232B';ST.cardA=100;ST.cardBdC='#33363F';\n  ST.ttTx='#E8E9F0';ST.msTx='#9AA0AE';ST.mtTx='#8A90A0';\n  ST.heroBg='#2A2D37';ST.heroTx='#F2F3F8';\n  ST.sBg='#21232B';ST.sTx='#E8E9F0';ST.sBdC='#33363F';\n  ST.tabBg='#21232B';ST.tabTx='#E8E9F0';ST.tabBdC='#33363F';\n  ST.subBg='#21232B';ST.subTx='#E8E9F0';ST.subBdC='#33363F';\n  ST.empBg='#21232B';ST.empTx='#8A90A0';\n  ST.pgBg='#21232B';ST.pgTx='#8AB4FF';ST.pgBdC='#33363F';\n  ST.tpBg='#2E2A1C';ST.tpBdC='#5A4A20';ST.tpTx='#E8D9A8';\n  ST.mBg='#1B1C22';ST.mTx='#E8E9F0';ST.dBg='#21232B';ST.dBdC='#33363F';\n  ST.sechBg='#2A2D37';ST.hdTx='#F2F3F8';ST.lbTx='#C8CAD4';ST.hintTx='#8A90A0';\n  ST.btnBg='#2A2D37';ST.btnTx='#E8E9F0';\n  ST.annBg='#1E2740';ST.annBdC='#3A4A6A';ST.annTx='#A9C0FF';\n  saveST();applyStyle();syncStyle();relayout();tip('✔ 已应用深色配色');\n}\nfunction lightPreset(){\n  ST={};for(var k in PDEF)ST[k]=PDEF[k][1];\n  saveST();applyStyle();applyBG();syncStyle();refreshPanel();relayout();tip('✔ 已恢复浅色默认');\n}\nfunction refreshPanel(){\n  var p=document.getElementById('pbg');if(p)p.innerHTML=bgBlock();\n  var bc=document.getElementById('bcat');if(bc)bc.innerHTML=catOpts(BGC);\n  var pf=document.getElementById('pfr');if(pf)pf.innerHTML=frBlock();\n  var fc=document.getElementById('frcat');if(fc)fc.innerHTML=catOpts(FRC);\n  var pl=document.getElementById('profList');if(pl)pl.innerHTML=profBlock();\n  var pb=document.getElementById('profBtn');if(pb)pb.textContent=(_ren>=0?'✏️ 重命名':'\\ud83d\\udcbe 保存方案');\n}\nfunction bgPanel(){\n  var box=document.getElementById('bpb');\n  if(box&&!box.getAttribute('data-b')){box.innerHTML=buildPanel();box.setAttribute('data-b','1');}\n  var bs=document.querySelectorAll('.secb');\n  for(var i=0;i<bs.length;i++)bs[i].style.display='none';\n  var as=document.querySelectorAll('.sech span');\n  for(var j=0;j<as.length;j++)as[j].textContent='▸';\n  document.getElementById('bp').className='modal on';\n  refreshPanel();syncStyle();\n}\nfunction closeBG(){document.getElementById('bp').className='modal';}\nfunction closeIO(){document.getElementById('io').className='modal';}\n\n\/* ---- 取色器(HSV) ---- *\/\nvar CP={key:'',h:0,s:0,v:1,hex:'#FFFFFF'};\nvar CP_PRESET=['#FFFFFF','#F1F2F7','#E4E7F0','#8A8FA8','#5A5F73','#2B2D42','#000000','#FF6B9D','#E5484D','#F2A33C','#16A34A','#22A7C2','#7C6BD9','#A855F7','#FDF4DE','#C3A875'];\nfunction h2r(hex){\n  hex=String(hex||'').replace('#','');\n  if(hex.length===3)hex=hex.split('').map(function(c){return c+c;}).join('');\n  var n=parseInt(hex,16);\n  if(isNaN(n))return {r:255,g:255,b:255};\n  return {r:(n>>16)&255,g:(n>>8)&255,b:n&255};\n}\nfunction r2h(r,g,b){\n  function c(x){x=Math.round(Math.min(255,Math.max(0,x))).toString(16);return x.length<2?'0'+x:x;}\n  return '#'+c(r)+c(g)+c(b);\n}\nfunction rgb2hsv(r,g,b){\n  r\/=255;g\/=255;b\/=255;\n  var mx=Math.max(r,g,b),mn=Math.min(r,g,b),d=mx-mn,h=0;\n  if(d){\n    if(mx===r)h=((g-b)\/d+(g<b?6:0));\n    else if(mx===g)h=((b-r)\/d+2);\n    else h=((r-g)\/d+4);\n    h*=60;\n  }\n  return {h:h,s:(mx?d\/mx:0),v:mx};\n}\nfunction hsv2rgb(h,s,v){\n  h=((h%360)+360)%360;\n  var c=v*s,x=c*(1-Math.abs((h\/60)%2-1)),m=v-c,r=0,g=0,b=0;\n  if(h<60){r=c;g=x;}else if(h<120){r=x;g=c;}else if(h<180){g=c;b=x;}\n  else if(h<240){g=x;b=c;}else if(h<300){r=x;b=c;}else{r=c;b=x;}\n  return {r:(r+m)*255,g:(g+m)*255,b:(b+m)*255};\n}\nfunction cpSync(noHex){\n  var rgb=hsv2rgb(CP.h,CP.s,CP.v);\n  CP.hex=r2h(rgb.r,rgb.g,rgb.b);\n  var pu=hsv2rgb(CP.h,1,1);\n  var svb=document.getElementById('cpSv');\n  if(svb)svb.style.background='linear-gradient(to top,#000,rgba(0,0,0,0)),linear-gradient(to right,#fff,'+r2h(pu.r,pu.g,pu.b)+')';\n  var sc=document.getElementById('cpSvC');\n  if(sc){sc.style.left=(CP.s*100)+'%';sc.style.top=((1-CP.v)*100)+'%';sc.style.background=CP.hex;}\n  var hc=document.getElementById('cpHueC');\n  if(hc)hc.style.left=(CP.h\/360*100)+'%';\n  setV('cpR',Math.round(rgb.r));setV('cpG',Math.round(rgb.g));setV('cpB',Math.round(rgb.b));\n  if(!noHex)setV('cpHex',CP.hex.toUpperCase());\n  var nw=document.getElementById('cpNew');if(nw)nw.style.background=CP.hex;\n}\nfunction openPicker(key){\n  CP.key=key;\n  var c=h2r(ST[key]||'#FFFFFF'),h=rgb2hsv(c.r,c.g,c.b);\n  CP.h=h.h;CP.s=h.s;CP.v=h.v;\n  var old=document.getElementById('cpOld');if(old)old.style.background=ST[key]||'transparent';\n  cpSync();\n  document.getElementById('cp').className='modal on';\n}\nfunction closePicker(){document.getElementById('cp').className='modal';}\nfunction applyPicker(){\n  if(!CP.key)return;\n  ST[CP.key]=CP.hex;saveST();applyStyle();relayout();\n  setSw('s'+CP.key,CP.hex);\n  closePicker();\n}\nfunction clearPicker(){if(!CP.key)return;ST[CP.key]='';saveST();applyStyle();relayout();setSw('s'+CP.key,'');closePicker();}\nfunction cpUse(hex){\n  var c=h2r(hex),h=rgb2hsv(c.r,c.g,c.b);\n  CP.h=h.h;CP.s=h.s;CP.v=h.v;cpSync();\n}\nfunction cpRgbIn(){\n  var r=parseInt(cv('cpR'),10)||0,g=parseInt(cv('cpG'),10)||0,b=parseInt(cv('cpB'),10)||0;\n  var h=rgb2hsv(Math.min(255,Math.max(0,r)),Math.min(255,Math.max(0,g)),Math.min(255,Math.max(0,b)));\n  CP.h=h.h;CP.s=h.s;CP.v=h.v;cpSync();\n}\nfunction cpHexIn(){\n  var c=h2r(cv('cpHex'));\n  var h=rgb2hsv(c.r,c.g,c.b);\n  CP.h=h.h;CP.s=h.s;CP.v=h.v;cpSync(1);\n}\nfunction cv(id){var e=document.getElementById(id);return e?e.value:'';}\nfunction pt(e){return (e.touches&&e.touches[0])||e;}\nfunction cpSvGo(e){\n  var b=document.getElementById('cpSv');if(!b)return;\n  var r=b.getBoundingClientRect(),p=pt(e);\n  CP.s=Math.min(1,Math.max(0,(p.clientX-r.left)\/r.width));\n  CP.v=1-Math.min(1,Math.max(0,(p.clientY-r.top)\/r.height));\n  cpSync();if(e.preventDefault)e.preventDefault();\n}\nfunction cpHueGo(e){\n  var b=document.getElementById('cpHue');if(!b)return;\n  var r=b.getBoundingClientRect(),p=pt(e);\n  CP.h=Math.min(360,Math.max(0,(p.clientX-r.left)\/r.width*360));\n  cpSync();if(e.preventDefault)e.preventDefault();\n}\nfunction cpInit(){\n  var sv=document.getElementById('cpSv'),hb=document.getElementById('cpHue');\n  function bind(el,fn){\n    if(!el)return;\n    el.addEventListener('touchstart',fn,false);\n    el.addEventListener('touchmove',fn,false);\n    el.addEventListener('mousedown',fn,false);\n  }\n  var mv=false;\n  bind(sv,function(e){mv=true;cpSvGo(e);});\n  bind(hb,function(e){mv=true;cpHueGo(e);});\n  document.addEventListener('touchmove',function(e){if(mv)cpSvGo(e);},false);\n  document.addEventListener('mousemove',function(e){if(mv){var t=e.target;if(t&&t.id==='cpHue')cpHueGo(e);else cpSvGo(e);}},false);\n  document.addEventListener('touchend',function(){mv=false;},false);\n  document.addEventListener('mouseup',function(){mv=false;},false);\n  var pr=document.getElementById('cpPreset');\n  if(pr){\n    var o='';\n    for(var i=0;i<CP_PRESET.length;i++)o+='<i class=\"cpi\" style=\"background:'+CP_PRESET[i]+'\" onclick=\"cpUse(\\''+CP_PRESET[i]+'\\')\"><\/i>';\n    pr.innerHTML=o;\n  }\n  lpAttach();\n}\n\/* ---- 悬浮按钮拖动 ---- *\/\nvar _fb=null,_fx=0,_fy=0,_fblk=0,_fmov=0;\nfunction fabInit(){\n  var f=document.getElementById('fab');\n  if(!f)return;\n  \/* 长按拖动前先关掉一切\"选中\/菜单\/原生拖拽\", 否则会选中按钮里的图案 *\/\n  try{\n    f.style.webkitUserSelect='none';f.style.webkitTouchCallout='none';\n    f.style.touchAction='none';f.style.webkitUserDrag='none';\n    f.setAttribute('unselectable','on');f.setAttribute('draggable','false');\n  }catch(_e){}\n  function noSel(e){if(e&&e.preventDefault)e.preventDefault();return false;}\n  f.addEventListener('contextmenu',noSel,false);\n  f.addEventListener('selectstart',noSel,false);\n  f.addEventListener('dragstart',noSel,false);\n  function down(e){\n    try{var _s=window.getSelection();if(_s&&_s.removeAllRanges)_s.removeAllRanges();}catch(_e){}\n    var p=pt(e);_fx=p.clientX;_fy=p.clientY;_fblk=0;_fmov=0;\n    if(e&&e.type==='mousedown'&&e.preventDefault)e.preventDefault();\n    _fb=setTimeout(function(){_fb=null;_fblk=1;tip('拖动中，松手保存位置');},500);\n  }\n  function move(e){\n    if(_fb){if(Math.abs(pt(e).clientX-_fx)>12||Math.abs(pt(e).clientY-_fy)>12){clearTimeout(_fb);_fb=null;}return;}\n    if(!_fblk)return;\n    try{var _g=window.getSelection();if(_g&&!_g.isCollapsed&&_g.removeAllRanges)_g.removeAllRanges();}catch(_e){}\n    var p=pt(e);\n    _fmov=1;\n    ST.fabX=Math.max(0,Math.min(320,ST.fabX-(p.clientX-_fx)));\n    ST.fabY=Math.max(0,Math.min(640,ST.fabY-(p.clientY-_fy)));\n    _fx=p.clientX;_fy=p.clientY;\n    var r=document.documentElement.style;\n    r.setProperty('--fabx',Math.round(ST.fabX)+'px');\n    r.setProperty('--faby',Math.round(ST.fabY)+'px');\n    if(e.preventDefault)e.preventDefault();\n  }\n  function up(){\n    if(_fb){clearTimeout(_fb);_fb=null;}\n    if(_fblk&&_fmov){saveST();tip('✔ 位置已保存');}\n    _fblk=0;_fmov=0;\n  }\n  f.addEventListener('touchstart',down,false);\n  f.addEventListener('touchmove',move,false);\n  f.addEventListener('touchend',up,false);\n  f.addEventListener('mousedown',down,false);\n  document.addEventListener('mousemove',move,false);\n  document.addEventListener('mouseup',up,false);\n  \/* 拖动后吞掉 click, 避免松手就打开面板 *\/\n  f.addEventListener('click',function(e){\n    if(_fblk||_fmov){if(e.preventDefault)e.preventDefault();if(e.stopPropagation)e.stopPropagation();_fmov=0;}\n  },true);\n}\n\napplyStyle();applyBG();catResolve();renderTabs();renderSubs();cpInit();fabInit();bellInit();bellAutoRefresh();bellStartPoll(60000);loadCat(0);try{fetchToday()}catch(e){}try{annAuto()}catch(e){}\n\n\/* ===== 小说站模块注入 ===== *\/\n\/* ================= 小说站模块 (千白羽小说站 www.xiaoxiaoshuo8.com, GBK) ================= *\/\n\/* ================= 小说站模块 (千白羽小说站 www.xiaoxiaoshuo8.com, GBK) ================= *\/\nvar XS_ORI='https:\/\/www.xiaoxiaoshuo8.com';\n\/* 9 个入口: 索引0=书架, 1..8=分类 *\/\nvar XS_M='https:\/\/m.xiaoxiaoshuo8.com';\nvar xsNext='',xsLoading=false,xsLoadCur=-1;\nXS_CATS=[\n  {n:'\\u4e66\\u67b6',  k:'shelf'},\n  {n:'\\u5168\\u90e8',  u:'\/xclass\/0\/1.html'},\n  {n:'\\u7384\\u5e7b',  u:'\/xclass\/1\/1.html'},\n  {n:'\\u4fee\\u771f',  u:'\/xclass\/2\/1.html'},\n  {n:'\\u90fd\\u5e02',  u:'\/xclass\/3\/1.html'},\n  {n:'\\u7a7f\\u8d8a',  u:'\/xclass\/4\/1.html'},\n  {n:'\\u7f51\\u6e38',  u:'\/xclass\/5\/1.html'},\n  {n:'\\u79d1\\u5e7b',  u:'\/xclass\/6\/1.html'},\n  {n:'\\u5176\\u4ed6',  u:'\/xclass\/7\/1.html'},\n  {n:'\\u6392\\u884c',  u:'\/ph\/week.html'}\n];\nvar xsCur=1;             \/* 当前选中的分类索引 *\/\nvar beforeXSCur=-1;          \/* 进入小说站前所在论坛分类, 返回时恢复高亮 *\/\nvar xsCfgKey='XSHELF';   \/* 书架 存 jload\/jsave *\/\nvar xsReadKey='XSREAD';  \/* 章节进度记忆 *\/\n\/* 最近阅读独立存储: 以书牌URL为键的 map, 兼容旧版单条记录 *\/\nfunction xsReadRec(k){var rd=null;try{rd=jload(xsReadKey,null);}catch(e){}if(!rd)return null;if(rd.cat!==undefined){return rd.cat===k?rd:null;}return rd[k]||null;}\nfunction xsSaveRec(k,r){var rd=null;try{rd=jload(xsReadKey,null);}catch(e){}if(!rd||rd.cat!==undefined)rd={};rd[k]=r;jsave(xsReadKey,rd);}\n\n\n\/* GBK 页面由 legado 网络栈按 content-type 解码, java.ajax 返回已是 UTF-8 字符串 *\/\nfunction xsD(s){return s;}\n\n\/* 论坛<->小说站 视图切换 *\/\nfunction hideForum(){\n  var res=document.getElementById('res');\n  if(res)res.style.display='none';\n  var sub=document.getElementById('subs');\n  if(sub)sub.style.display='none';\n  var pst=document.getElementById('pst');\n  if(pst)pst.style.display='none';\n}\nfunction showForum(){\n  \/* 隐藏小说站覆盖层, 恢复论坛三件套显示(切回论坛分类时确保不再被 hideForum 残留的 display:none 遮住) *\/\n  var xs=document.getElementById('xsres');\n  if(xs)xs.style.display='none';\n  var res=document.getElementById('res');\n  if(res)res.style.display='';\n  var sub=document.getElementById('subs');\n  if(sub&&typeof SUBS!=='undefined'&&SUBS.length)sub.style.display='flex';\n  xsRestoreSubs();\n  var pst=document.getElementById('pst');\n  if(pst)pst.style.display='';\n  \/* 清空搜索框 placeholder 回论坛态 *\/\n  var q=document.getElementById('q');\n  if(q){q.setAttribute('placeholder','搜索帖子标题 \/ 内容…');}\n  var _sqb=document.querySelector('.sbox button');if(_sqb)_sqb.textContent='搜索';\n}\nfunction xsRestoreSubs(){\n  \/* 由 renderSubs 依据 SUBS 重新渲染二级导航 *\/\n  if(typeof renderSubs==='function')renderSubs();\n}\n\n\/* 进入小说站 *\/\nfunction xsEnter(){\n  hideForum();\n  \/* 小说站为独立固定入口: 高亮 xstab, 清除当前论坛 tab 高亮 *\/\n  beforeXSCur=(typeof cur!=='undefined'&&cur>=0)?cur:-1;\n  cur=-1;if(typeof markTab==='function')markTab();\n  var xst=document.getElementById('xstab');if(xst)xst.className='xstab on';\n  var box=document.getElementById('xsres');\n  if(!box){\n    box=document.createElement('div');box.id='xsres';box.className='xsres';\n    var res=document.getElementById('res');\n    res.parentNode.insertBefore(box,res.nextSibling);\n  }\n  box.style.display='block';\n  var tb='<div class=\"xsbar\">';\n  for(var i=0;i<XS_CATS.length;i++){\n    tb+='<div class=\"xsbt'+(i===xsCur?' on':'')+'\" onclick=\"xsCat('+i+')\">'+esc(XS_CATS[i].n)+'<\/div>';\n  }\n  tb+='<\/div><div id=\"xsbody\" class=\"xsbody\"><\/div>';\n  box.innerHTML=tb;\n  xsLoad(xsCur);\n  \/* 小说站激活: 搜索按钮\/占位符切换为小说站文案 *\/\n  var _sqb=document.querySelector('.sbox button');if(_sqb)_sqb.textContent='小说搜索';\n  var _sq=document.getElementById('q');if(_sq)_sq.setAttribute('placeholder','填写正确的书名关键字，宁少勿错');\n}\nfunction xsJump(){\n  var box=document.getElementById('xsres');\n  if(box)box.style.display='none';\n  \/* 从小说站返回: 恢复之前论坛分类高亮, 清除 xstab 高亮 *\/\n  if(typeof beforeXSCur!=='undefined'&&beforeXSCur>=0){cur=beforeXSCur;beforeXSCur=-1;if(typeof markTab==='function')markTab();}\n  var xst=document.getElementById('xstab');if(xst)xst.className='xstab';\n  showForum();\n}\nfunction xsCat(i){xsCur=i;xsLoad(i);}\nfunction xsLoad(i){\n  var body=document.getElementById('xsbody');\n  body.innerHTML='<div class=\"emp\">\\u52a0\\u8f7d\\u4e2d\\u2026<\/div>';\n  xsLoadCur=i;xsNext='';xsLoading=false;\n  var bs=document.querySelectorAll('.xsres .xsbt');\n  for(var j=0;j<bs.length;j++)bs[j].className='xsbt'+(j===i?' on':'');\n  if(i===0){xsShelf();return;}\n  var c=XS_CATS[i];\n  var mo=c.k==='shelf'?XS_ORI:XS_M;\n  xsGet(mo+c.u).then(function(h){\n    if(i!==xsCur||i!==xsLoadCur)return;\n    var books=xsParseList(h);\n    if(!books.length){body.innerHTML='<div class=\"emp\">\\u65e0\\u6570\\u636e<\/div>';return;}\n    xsNext=(\/<a[^>]*href=\"([^\"]*)\"[^>]*>\\s*\\[\\u4e0b\\u9875\\]\\s*<\\\/a>\/i.exec(h)||[])[1]||'';\n    body.innerHTML='<div class=\"xslist\">'+books.map(xsCard).join('')+'<\/div>'+(xsNext?'<div class=\"xsloadind\" id=\"xsloadind\">\\u4e0a\\u62c9\\u52a0\\u8f7d\\u66f4\\u591a<\/div>':'')+'';\n    xsBindScroll();\n  },function(){body.innerHTML='<div class=\"emp\">\\u52a0\\u8f7d\\u5931\\u8d25<\/div>';});\n}\nfunction xsBindScroll(){\n  if(window.__xsScroll)return;window.__xsScroll=true;\n  window.addEventListener('scroll',function(){\n    var sr=document.getElementById('xsres');\n    if(!sr||sr.style.display==='none')return;\n    if(window.innerHeight+window.scrollY>=document.body.scrollHeight-220)xsNextPage();\n  });\n}\nfunction xsNextPage(){\n  if(xsLoading||!xsNext)return;\n  xsLoading=true;\n  var ind=document.getElementById('xsloadind');if(ind)ind.textContent='\\u52a0\\u8f7d\\u4e2d\\u2026';\n  var i=xsCur;\n  xsGet(XS_M+xsNext).then(function(h){\n    xsLoading=false;\n    if(i!==xsCur)return;\n    var books=xsParseList(h);\n    xsNext=(\/<a[^>]*href=\"([^\"]*)\"[^>]*>\\s*\\[\\u4e0b\\u9875\\]\\s*<\\\/a>\/i.exec(h)||[])[1]||'';\n    if(books.length&&i===xsLoadCur){\n      var lst=document.querySelector('#xsbody .xslist');\n      if(lst)lst.insertAdjacentHTML('beforeend',books.map(xsCard).join(''));\n    }\n    var e=document.getElementById('xsloadind');if(e)e.textContent=xsNext?'\\u4e0a\\u62c9\\u52a0\\u8f7d\\u66f4\\u591a':'\\u2014 \\u5df2\\u52a0\\u8f7d\\u5168\\u90e8 \\u2014';\n  },function(){xsLoading=false;var e=document.getElementById('xsloadind');if(e)e.textContent='\\u52a0\\u8f7d\\u5931\\u8d25';});\n}\nfunction xsGet(u){\n  u=xsD(String(u));\n  return new Promise(function(res,rej){getHtml(u).then(function(h){res(xsD(h));},rej);});\n}\n\/* 解析分类页 .item 卡片列表 *\/\nfunction xsParseList(h){\n  var books=[],parts=h.split('<div class=\"hot_sale\">');\n  for(var k=1;k<parts.length;k++){\n    var s=parts[k];\n    var url=(\/<a[^>]*href=\"([^\"]*)\"\/.exec(s)||[])[1]||'';\n    var cover=(\/data-original=\"([^\"]*)\"\/.exec(s)||[])[1]||'';\n    var ttl=(\/<p class=\"title\">\\s*([\\s\\S]*?)\\s*<\\\/p>\/.exec(s)||[])[1]||'';\n    var auth=(\/<p class=\"author\">\\s*(?:\\u4f5c\\u8005[:\\uff1a])?\\s*([\\s\\S]*?)\\s*<\\\/p>\/.exec(s)||[])[1]||'';\n    var intro=(\/<p class=\"review\">\\s*<span class=\"longview\"><\\\/span>\\s*\\u7b80\\u4ecb[:\\uff1a]\\s*([\\s\\S]*?)\\s*<\\\/p>\/.exec(s)||[])[1]||'';\n    if(url)books.push({url:url,cover:cover,ttl:tx(ttl),auth:tx(auth),intro:tx(intro)});\n  }\n  return books;\n}\nfunction xsCard(b){\n  var cv=b.cover?'<img class=\"xscv\" src=\"'+esc(b.cover)+'\" onerror=\"this.style.display=\\'none\\'\">':'';\n  return '<div class=\"xsitem\" onclick=\"xsDetail(\\''+b.url+'\\')\"><div class=\"xsimg\">'+cv+'<\/div><div class=\"xsinfo\"><div class=\"xsttl\">'+esc(b.ttl)+'<\/div><div class=\"xsauth\">'+esc(b.auth)+'<\/div><div class=\"xsintro\">'+esc(b.intro)+'<\/div><\/div><\/div>';\n}\n\/* 详情页渲染 *\/\nfunction xsDetail(url){\n  var body=document.getElementById('xsbody');\n  body.innerHTML='<div class=\"emp\">\\u52a0\\u8f7d\\u4e2d\\u2026<\/div>';\n  var u=\/^https?:\\\/\\\/\/i.test(url)?url:XS_ORI+url;\n  var mm=(\/(\\d+)_(\\d+)\\\/?$\/.exec(u||'')||[]);\n  var A=mm[1]||'',B=mm[2]||'',id=B;\n  var norm='';if(A&&B)norm='\/'+A+'_'+B+'\/';\n  xsGet(u).then(function(h){\n    body.innerHTML=xsRenderDetail(h,norm||url);\n    try{x8SlideInit();}catch(_x8s){}\n    var el=document.getElementById('xscoverimg');\n    if(el&&B){el.src=XS_ORI+'\/files\/article\/image\/'+A+'\/'+B+'\/'+B+'s.jpg';}\n    var um=\/<script[^>]*src=\"([^\"]*52mb_uptime[^\"]*type=lastupdate[^\"]*)\"[^>]*>\/i.exec(h);\n    if(um&&um[1]){xsGet(XS_ORI+um[1]).then(function(s){var d=(\/\"([^\"]*)\"\/.exec(s)||[])[1]||'';var ue=document.getElementById('xsupd');if(ue&&d)ue.textContent='\\u6700\\u540e\\u66f4\\u65b0\\uff1a'+d;},function(){});}\n    if(id){xsGet(XS_ORI+'\/modules\/article\/52mb_uptime.php?id='+id+'&type=img').then(function(s){var cv=(\/<img[^>]*src=['\"]([^'\"]+)['\"]\/i.exec(s)||[])[1]||'';var im=document.getElementById('xscoverimg');if(im&&cv)im.src=cv;},function(){});}\n  },function(){body.innerHTML='<div class=\"emp\">\\u52a0\\u8f7d\\u5931\\u8d25<\/div>';});\n}function xsRenderDetail(h,url){\n  var t=(\/<h1[^>]*>([\\s\\S]*?)<\\\/h1>\/.exec(h)||[])[1]||'未知书名';\n  var a=(\/<p[^>]*>\\s*作者[^<]*：\\s*([^<]*)<\\\/p>\/.exec(h)||[])[1]||'';\n  var im=\/<div[^>]*id=\"intro\"[^>]*>([\\s\\S]*?)<\\\/div>\/.exec(h);\n  var intro=im?tx(im[1]):'';\n  var idx=url;\n  var chaps=dds(h);\n  var rows=chaps.map(function(c){return '<div class=\"xschap\" data-u=\"'+c.u+'\" onclick=\"xsChapter(\\''+c.u+'\\',\\''+idx+'\\')\">'+esc(c.t)+'<\/div>';}).join('');\n  try{x8SlideNames=chaps.map(function(c){return c.t;});}catch(_x8nm){}\n  var readj='';\n  try{\n    var rd=xsReadRec(idx);\n    if(rd&&rd.url){\n      readj='<div class=\"xsreadjump\" onclick=\"xsJumpRead(\\''+idx+'\\')\"><span class=\"xsrj-label\">继续阅读<\/span><span class=\"xsrj-ch\">'+esc(rd.nm||'定位到章节')+'<\/span><span class=\"xsrj-arw\">⌄<\/span><\/div>';\n    }\n  }catch(e){}\n  var head='<div class=\"xshead\"><div class=\"xscover\"><img id=\"xscoverimg\" class=\"xscv\" alt=\"\"><\/div><div class=\"xsttl big\">'+esc(t)+'<\/div>'+(a?'<div class=\"xsauth\">作者：'+esc(a)+'<\/div>':'')+'<div class=\"xsupd\" id=\"xsupd\"><\/div><div class=\"xsintro\" onclick=\"xsToggleIntro(this)\">'+intro+'<\/div><\/div>';\n  return '<div class=\"xsdet\">'+head+'<div class=\"xsdetbar\"><div class=\"xsbt2 pri\" onclick=\"xsAddShelf(\\''+idx+'\\')\">加入书架<\/div><div class=\"xsbt2\" onclick=\"xsBack()\">返回<\/div><\/div>'+readj+'<div class=\"x8srw\"><div class=\"xsrules\" id=\"xsrules\">'+rows+'<\/div>'+'<div class=\"x8ssl\" id=\"x8ssl\"><div class=\"x8sst\" id=\"x8sst\"><div class=\"x8sstip\" id=\"x8sstip\"><\/div><\/div><\/div><\/div><\/div>';\n}\nfunction xsToggleIntro(el){if(!el)return;el.classList.toggle('exp');}function xsBack(){\n  var body=document.getElementById('xsbody');\n  body.innerHTML='<div class=\"emp\">\\u52a0\\u8f7d\\u4e2d\\u2026<\/div>';\n  xsLoad(xsCur);\n}\n\/* 从详情页 html 提取章节目录 dd (注意可能倒序) *\/\nfunction dds(h){\n  var out=[],re=\/<dd><a[^>]*href=['\"]([^'\"]*)['\"]\\s*>([\\s\\S]*?)<\\\/a><\\\/dd>\/g,m;\n  while((m=re.exec(h))!==null)out.push({u:m[1],t:tx(m[2])});\n  return out;\n}\n\/* 章节读取-占位 *\/\nfunction xsChapter(u,cat){\n  var url=\/^https?:\\\/\\\/\/i.test(u)?u:XS_ORI+u;\n  xsGet(url).then(function(h){\n    try{var nm=(\/<h1[^>]*>([\\s\\S]*?)<\\\/h1>\/.exec(h)||[])[1]||'';xsSaveRec(cat,{url:url,cat:cat,nm:tx(nm||''),time:+new Date()});}catch(e){}\n    xsRenderChapter(h,u,cat);\n  },function(){var b=document.getElementById('xsbody');b.innerHTML='<div class=\"emp\">加载失败<\/div>';});\n}\nfunction xsRenderChapter(h,u,cat){\n  cat=cat||'';\n  var b=document.getElementById('xsbody');\n  var t=(\/<h1[^>]*>([\\s\\S]*?)<\\\/h1>\/.exec(h)||[])[1]||'';\n  var cm=\/<div id=\"content\"[^>]*>([\\s\\S]*?)<\\\/div>\/.exec(h);\n  var cnt=cm&&cm[1]&&cm[1].length>100?cm[1]:'';\n  \/* 上一章\/下一章 *\/\n  var prev=(\/<a[^>]*href=\"([^\"]*)\"[^>]*>\\s*上一章\\s*<\\\/a>\/.exec(h)||[])[1]||'';\n  var nx=(\/上一章\\s*<\\\/a>[\\s\\S]*?<a[^>]*href=\"([^\"]*)\"[^>]*>\\s*章节目录\\s*<\\\/a>[\\s\\S]*?<a[^>]*href=\"([^\"]*)\"[^>]*>\\s*下一章\/.exec(h)||[])[2]||'';\n  var catL=cat?(\/^https?:\\\/\\\/\/i.test(cat)?cat:XS_ORI+cat):'';\n  var nav='<div class=\"xsnav\">';\n  if(prev)nav+='<div class=\"xsbt2\" onclick=\"xsChapter(\\''+prev+'\\',\\''+cat+'\\')\">上一页<\/div>';\n  nav+='<div class=\"xsbt2\"'+(catL?' onclick=\"xsDetail(\\''+catL+'\\')\"':' onclick=\"xsBack()\"')+'>章节目录<\/div>';\n  if(nx)nav+='<div class=\"xsbt2\" onclick=\"xsChapter(\\''+nx+'\\',\\''+cat+'\\')\">下一页<\/div>';\n  nav+='<\/div>';\n  var _op=(ST.x8Opa==null?92:ST.x8Opa);\n  b.innerHTML='<div class=\"xsdet\"><div class=\"xsttl big\">'+esc(t)+'<\/div>'\n    +'<div class=\"x8bar\">'\n    +'<button class=\"x8bb\" id=\"x8m0\" onclick=\"x8DocMode(0)\">上下滑动<\/button>'\n    +'<button class=\"x8bb\" id=\"x8m1\" onclick=\"x8DocMode(1)\">左右翻页<\/button>'\n    +'<span class=\"x8opa\"><i>容器底色<\/i>'\n    +'<input type=\"range\" min=\"0\" max=\"100\" step=\"1\" value=\"'+_op+'\" oninput=\"x8DocOpa(this.value)\">'\n    +'<b id=\"x8opav\">'+_op+'%<\/b><\/span>'\n    +'<\/div>'\n    +'<div class=\"x8doc\" id=\"x8doc\"><div class=\"x8docbd\" id=\"x8docbd\">'\n    +'<div class=\"x8pgs\" id=\"x8pgs\"><div class=\"x8pgin\" id=\"x8pgin\"><div class=\"xstext\">'+cnt+'<\/div><\/div><\/div>'\n    +'<\/div><\/div>'\n    +'<div class=\"x8pgbar\" id=\"x8pgbar\"><\/div>'\n    +nav+'<\/div>';\n  \/* 章节进度记录 *\/\n  try{x8DocInit();}catch(_x8e){}\n\n}\nfunction xsShelf(){\n  var b=document.getElementById('xsbody');\n  var arr=jload(xsCfgKey,null)||[];\n  if(!arr.length){b.innerHTML='<div class=\"emp\">书架暂无书籍，去详情页点击加入书架<\/div>';return;}\n  var rows=arr.map(function(it,idx){\n    var last='';\n    var rd=xsReadRec(it.u);\n    if(rd&&rd.url)last='<div class=\"xsread\">最近阅读：'+(rd.nm?esc(rd.nm):'')+'<\/div>';\n    var init=it.upd?('更新时间：'+esc(it.upd)):'更新时间：加载中…';\n    return '<div class=\"xsitem\" onclick=\"xsDetail(\\''+it.u+'\\')\"><div class=\"xsimg\">'+(it.cover?'<img class=\"xscv\" src=\"'+esc(it.cover)+'\" onerror=\"this.style.display=\\'none\\'\">':'')+'<\/div><div class=\"xsinfo\"><div class=\"xsttl\">'+esc(it.t)+'<\/div>'+(it.a?'<div class=\"xsauth\">作者：'+esc(it.a)+'<\/div>':'')+'<div class=\"xsupd\" id=\"xsupd_'+idx+'\">'+init+'<\/div>'+last+'<div class=\"xsrm\" onclick=\"event.stopPropagation();xsRmShelf(\\''+it.u+'\\')\">删除<\/div><\/div><\/div>';\n  }).join('');\n  b.innerHTML='<div class=\"xslist\">'+rows+'<\/div>';\n  xsShelfRefresh(arr);\n}\n\/* 书架卡片动态更新：从书籍详情页拉取更新时间 + id.list 下首个 dd>a 文本 *\/\nvar xsShelfCache={};\nfunction xsShelfRefresh(arr){\n  arr.forEach(function(it,idx){\n    var el=document.getElementById('xsupd_'+idx);\n    if(!el)return;\n    var key=it.u||'';\n    if(xsShelfCache[key]){xsShelfApply(el,xsShelfCache[key]);return;}\n    xsShelfUpd(it,el);\n  });\n}\nfunction xsShelfUpd(it,el){\n  var u=\/^https?:\\\/\\\/\/i.test(it.u)?it.u:XS_ORI+it.u;\n  xsGet(u).then(function(h){\n    \/* id.list@tag.dd.0@tag.a@text : #list 下首个 <dd> 内的 <a> 文本 *\/\n    var ddM=\/<div id=\"list\"[\\s\\S]*?<dd>\\s*<a[^>]*>([\\s\\S]*?)<\\\/a>\/i.exec(h);\n    var ddTxt=ddM?tx(ddM[1]):'';\n    \/* 封面\/信息区附近的更新时间（52mb_uptime 脚本，等效“更新时间：2026-”字段） *\/\n    var um=\/<script[^>]*src=\"([^\"]*52mb_uptime[^\"]*type=lastupdate[^\"]*)\"\/i.exec(h);\n    var done=function(d){\n      var o={ut:d,dd:ddTxt};\n      xsShelfCache[it.u||'']=o;\n      xsShelfApply(el,o);\n    };\n    if(um&&um[1]){\n      xsGet(XS_ORI+um[1]).then(function(s){var d=(\/\"([^\"]*)\"\/.exec(s)||[])[1]||'';done(d);},function(){done('');});\n    }else{done('');}\n  },function(){\/* 加载失败：保留原有显示（it.upd 兜底） *\/});\n}\nfunction xsShelfApply(el,o){\n  if(!el)return;\n  var parts=[];\n  if(o.ut)parts.push('更新时间：'+o.ut);\n  if(o.dd)parts.push(o.dd);\n  if(!parts.length)return; \/* 无数据时不覆盖原有内容 *\/\n  el.innerHTML=esc(parts.join('　'));\n}\nfunction xsRmShelf(u){\n  var arr=jload(xsCfgKey,null)||[];\n  var narr=[];\n  for(var i=0;i<arr.length;i++){if(arr[i].u!==u)narr.push(arr[i]);}\n  jsave(xsCfgKey,narr);tip('已删除');\n  xsShelf();\n}\nfunction xsAddShelf(u){\n  var t='',a='',cov='',upd='';\n  var tt=document.querySelector('.xsttl.big');if(tt)t=tt.textContent;\n  var aa=document.querySelector('.xsauth');if(aa)a=aa.textContent.replace(\/^\\u4f5c\\u8005\\uff1a\/,'');\n  var cv=document.querySelector('.xscover #xscoverimg');if(cv)cov=cv.src;\n  var ue=document.getElementById('xsupd');if(ue)upd=ue.textContent.replace(\/^\\u6700\\u540e\\u66f4\\u65b0[:\\uff1a]\/,'').trim();\n  var arr=jload(xsCfgKey,null)||[];\n  for(var i=0;i<arr.length;i++){if(arr[i].u===u){tip('\\u5df2\\u5728\\u4e66\\u67b6');return;}}\n  arr.push({u:u,t:t,a:a,cover:cov,upd:upd,time:+new Date()});\n  jsave(xsCfgKey,arr);tip('\\u2714 \\u5df2\\u52a0\\u5165\\u4e66\\u67b6');\n}\n\/* ===== A批新增: s.php 小说搜索 + 封面拼接 + 最近阅读定位 ===== *\/\nfunction xsParseSearch(h){\n  var books=[];\n  if(!\/<div class=\"hot_sale\/.test(h))return books;\n  var parts=h.split(\/<div class=\"hot_sale[^\"]*\">\/);\n  for(var k=1;k<parts.length;k++){\n    var s=parts[k];\n    var url=(\/<a[^>]*href=\"([^\"]*)\"\/.exec(s)||[])[1]||'';\n    if(!url)continue;\n    var ttl=(\/<p class=\"title\">\\s*([\\s\\S]*?)\\s*<\\\/p>\/.exec(s)||[])[1]||'';\n    var auth=(\/<p class=\"author\">\\s*(?:作者[:：])?\\s*([\\s\\S]*?)\\s*<\\\/p>\/.exec(s)||[])[1]||'';\n    var mm=(\/^\\\/?(\\d+)_(\\d+)\\\/?$\/.exec(url)||[]),cover='';\n    if(mm[1]&&mm[2])cover=XS_ORI+'\/files\/article\/image\/'+mm[1]+'\/'+mm[2]+'\/'+mm[2]+'s.jpg';\n    books.push({url:url,cover:cover,ttl:tx(ttl),auth:tx(auth),intro:''});\n  }\n  return books;\n}\nfunction xsSearch(q){\n  var body=document.getElementById('xsbody');\n  body.innerHTML='<div class=\"emp\">搜索中…<\/div>';\n  var kw=(q||'').trim();\n  if(!kw){body.innerHTML='<div class=\"emp\">请输入搜索关键词<\/div>';return;}\n  xsGet(XS_M+'\/s.php?keyword='+encodeURIComponent(kw)).then(function(h){\n    var books=xsParseSearch(h);\n    if(!books.length){body.innerHTML='<div class=\"emp\">没有找到相关小说<\/div>';return;}\n    body.innerHTML='<div class=\"xslist\">'+books.map(xsCard).join('')+'<\/div>';\n  },function(){body.innerHTML='<div class=\"emp\">搜索失败<\/div>';});\n}\nfunction xsJumpRead(bookurl){\n  var rd=xsReadRec(bookurl);\n  if(!rd||!rd.url)return;\n  var items=document.querySelectorAll('.xschap');\n  for(var i=0;i<items.length;i++){\n    var u=items[i].getAttribute('data-u');\n    if(u&&(XS_ORI+u)===rd.url){\n      try{items[i].scrollIntoView({behavior:'smooth',block:'center'});}catch(e){items[i].scrollIntoView();}\n      items[i].classList.add('xs-cur');\n      (function(el){setTimeout(function(){el.classList.remove('xs-cur');},2500);})(items[i]);\n      return;\n    }\n  }\n\n}\n\n\/* ================= B批: 铃铛通知 + 刷新红点 ================= *\/\nvar BELL_NOTICE_URL='home.php?mod=space&do=notice&mobile=2';\nvar bellReadKey='bellRd';\nvar BELL_PROMPT_URL='';\n\/* 红点计数直接取自 bbs 头部 #myprompt 元素状态(用户指定的权威来源):\n   有提醒 -> <a id=\"myprompt\" class=\"... new ...\">提醒(N)<\/a>  (N=未读数)\n   无提醒 -> <a id=\"myprompt\" class=\"... \">提醒<\/a>            (无红点) *\/\nfunction parseBellCount(h){\n  var am=\/<a\\s[^>]*id=\"myprompt\"[^>]*>([\\s\\S]*?)<\\\/a>\/i.exec(h||'');\n  if(!am)return 0;\n  var hasNew=\/\\bnew\\b\/i.test(am[0]);\n  var cm=\/提醒\\s*\\((\\d+)\\)\/i.exec(am[1]||'');\n  if(cm)return parseInt(cm[1],10)||0;\n  return hasNew?1:0;\n}\nfunction getBellCount(){\n  return getHtml(abs(BELL_PROMPT_URL)).then(function(h){return parseBellCount(h);},function(){return 0;});\n}\nfunction bellRefreshDotCount(n){\n  var dot=document.getElementById('bellDot');\n  if(!dot)return;\n  n=parseInt(n,10)||0;\n  dot.textContent=n>99?'99+':String(n);\n  dot.className='bellDot'+(n>0?' on':'');\n}\n\nfunction nidMax(arr){var m=0;for(var i=0;i<arr.length;i++){if(arr[i].id>m)m=arr[i].id;}return m;}\nfunction bellRead(){var v='';try{v=pget(bellReadKey)||'';}catch(e){}return parseInt(v,10)||0;}\nfunction bellMarkRead(arr){var m=nidMax(arr);if(m>0){try{pput(bellReadKey,String(m));}catch(e){}}}\nfunction bellRefreshDot(arr){\n  var rd=bellRead();\n  var un=0;for(var i=0;i<arr.length;i++){if(arr[i].id>rd)un++;}\n  var dot=document.getElementById('bellDot');\n  if(!dot)return;\n  dot.textContent=un>99?'99+':String(un);\n  dot.className='bellDot'+(un>0?' on':'');\n}\nfunction bellAutoRefresh(){\n  try{getBellCount().then(function(n){bellRefreshDotCount(n);},function(){});}catch(e){}\n}\n\/* ---- 红点周期轮询 + 回到前台即刷(仿 Discuz 消息红点持续刷新) ---- *\/\nvar _bellTimer=null,_bellBusy=0,_bellBound=0;\nfunction bellTick(){\n  if(_bellBusy)return;\n  try{if(typeof document!=='undefined'&&document.hidden)return;}catch(_e){}\n  var dot=document.getElementById('bellDot');\n  if(!dot)return;\n  _bellBusy=1;\n  try{getBellCount().then(function(n){_bellBusy=0;bellRefreshDotCount(n);},function(){_bellBusy=0;});}\n  catch(_e){_bellBusy=0;}\n}\nfunction bellStartPoll(ms){\n  if(_bellTimer){clearInterval(_bellTimer);_bellTimer=null;}\n  _bellTimer=setInterval(bellTick, ms||60000);\n  if(_bellBound)return;\n  _bellBound=1;\n  function onShow(){try{bellAutoRefresh();}catch(_e){}}\n  if(typeof document!=='undefined'&&document.addEventListener){\n    document.addEventListener('visibilitychange',function(){\n      if(!document.hidden)onShow();\n    },false);\n    window.addEventListener('focus',onShow,false);\n  }\n}\n\nfunction bs(html){var d=document.createElement('div');d.innerHTML=html;return d;}\nfunction bt(q,d){var e=d.querySelector(q);return e?e.textContent:'';}\nfunction bellHref(){try{return abs(BELL_NOTICE_URL);}catch(e){return ORI+BELL_NOTICE_URL;}}\nfunction getNotices(){\n  return getHtml(bellHref()).then(function(h){\n    return parseNotices(h);\n  });\n}\nfunction parseNotices(h){\n  var out=[],re=\/<li\\s+class=\"cl\"\\s+notice=\"(\\d+)\"[\\s\\S]*?<\\\/li>\/gi,m;\n  while((m=re.exec(h))!==null){\n    var id=parseInt(m[1],10)||0;\n    var d=bs(m[0]);\n    var isSys=\/alt=\"systempm\"\/i.test(m[0]);\n    var time=bt('p.mtit span',d);\n    var opA=d.querySelector('p.mbody a[href*=\"mod=space&uid=\"]');\n    var opName=opA?(opA.textContent||''):'';\n    var postA=d.querySelector('p.mbody a[href*=\"goto=findpost\"]');\n    var ptid='';\n    if(postA){var qm=String(postA.getAttribute('href')||'').match(\/ptid=(\\d+)\/);if(qm)ptid=qm[1];}\n    var body='';try{var bd=d.querySelector('p.mbody');if(bd)body=(bd.textContent||'').replace(\/\\s+\/g,' ').trim();}catch(e){}\n    if(body&&opName&&body.indexOf(opName)===0){body=body.substring(opName.length).replace(\/^\\s+\/,'');}\n    out.push({id:id,isSys:isSys,time:time,op:opName,ptid:ptid,body:body});\n  }\n  return out;\n}\nfunction nbTopicUrl(ptid){try{return abs('forum.php?mod=viewthread&tid='+ptid+'&mobile=2');}catch(e){return ORI+'forum.php?mod=viewthread&tid='+ptid+'&mobile=2';}}\nfunction renderNotices(arr){\n  var el=document.getElementById('nbc');\n  if(!el)return;\n  if(!arr||!arr.length){el.innerHTML='<div class=\"nb-empty\">暂未收取通知<\/div>';return;}\n  var h='';\n  for(var i=0;i<arr.length;i++){\n    var it=arr[i];\n    var type=it.isSys?'<span class=\"nb-type sys\">系统<\/span>':'<span class=\"nb-type reply\">回复<\/span>';\n    var top='<div class=\"nb-top\">'+type+'<span>'+esc(it.time||'')+'<\/span><span style=\"flex:1\"><\/span><\/div>';\n    var txt;\n    if(it.isSys){\n      txt=esc(it.body||'系统通知');\n    }else{\n      var nm=it.op?('<b>'+esc(it.op)+'<\/b> '):'';\n      txt=nm+esc(it.body||'');\n    }\n    if(it.ptid){\n      h+='<a class=\"nb-item\" href=\"'+nbTopicUrl(it.ptid)+'\">'+top+'<div class=\"nb-text\">'+txt+'<\/div>'\n        +'<div class=\"nb-act\">查看帖子 ›<\/div><\/a>';\n    }else{\n      h+='<div class=\"nb-item\">'+top+'<div class=\"nb-text\">'+txt+'<\/div><\/div>';\n    }\n  }\n  el.innerHTML=h;\n}\nfunction bellPanel(){\n  var m=document.getElementById('nb');\n  var el=document.getElementById('nbc');\n  if(!m)return;\n  m.className='modal on';\n  if(el)el.innerHTML='<div class=\"nb-empty\">加载中…<\/div>';\n  getNotices().then(function(arr){\n    renderNotices(arr);\n    getBellCount().then(bellRefreshDotCount);\n  },function(e){\n    if(el)el.innerHTML='<div class=\"nb-empty\">通知加载失败，请确认已登录<\/div>';\n  });\n}\nfunction closeBell(){\n  var m=document.getElementById('nb');\n  if(m)m.className='modal';\n}\n\/* ---- 铃铛长按拖动定位(左上角, left\/top) ---- *\/\nvar _bb=null,_bx=0,_by=0,_bblk=0,_bmov=0;\nfunction bellInit(){\n  var b=document.getElementById('bellFab');\n  if(!b)return;\n  try{\n    b.style.webkitUserSelect='none';b.style.webkitTouchCallout='none';\n    b.style.touchAction='none';b.style.webkitUserDrag='none';\n    b.setAttribute('unselectable','on');b.setAttribute('draggable','false');\n  }catch(_e){}\n  function noSel(e){if(e&&e.preventDefault)e.preventDefault();return false;}\n  b.addEventListener('contextmenu',noSel,false);\n  b.addEventListener('selectstart',noSel,false);\n  b.addEventListener('dragstart',noSel,false);\n  function down(e){\n    try{var _s=window.getSelection();if(_s&&_s.removeAllRanges)_s.removeAllRanges();}catch(_e){}\n    var p=pt(e);_bx=p.clientX;_by=p.clientY;_bblk=0;_bmov=0;\n    if(e&&e.type==='mousedown'&&e.preventDefault)e.preventDefault();\n    _bb=setTimeout(function(){_bb=null;_bblk=1;tip('拖动中，松手保存位置');},500);\n  }\n  function move(e){\n    if(_bb){if(Math.abs(pt(e).clientX-_bx)>12||Math.abs(pt(e).clientY-_by)>12){clearTimeout(_bb);_bb=null;}return;}\n    if(!_bblk)return;\n    try{var _g=window.getSelection();if(_g&&!_g.isCollapsed&&_g.removeAllRanges)_g.removeAllRanges();}catch(_e){}\n    var p=pt(e);\n    _bmov=1;\n    \/* 铃铛是 left\/top 定位: 向右拖 => bellX 增大(+), 向下拖 => bellY 增大(+) *\/\n    ST.bellX=Math.max(0,Math.min(320,ST.bellX+(p.clientX-_bx)));\n    ST.bellY=Math.max(0,Math.min(640,ST.bellY+(p.clientY-_by)));\n    _bx=p.clientX;_by=p.clientY;\n    var r=document.documentElement.style;\n    r.setProperty('--bellx',Math.round(ST.bellX)+'px');\n    r.setProperty('--bella',Math.round(ST.bellY)+'px');\n    if(e.preventDefault)e.preventDefault();\n  }\n  function up(){\n    if(_bb){clearTimeout(_bb);_bb=null;}\n    if(_bblk&&_bmov){saveST();tip('✔ 位置已保存');}\n    _bblk=0;_bmov=0;\n  }\n  b.addEventListener('touchstart',down,false);\n  b.addEventListener('touchmove',move,false);\n  b.addEventListener('touchend',up,false);\n  b.addEventListener('mousedown',down,false);\n  document.addEventListener('mousemove',move,false);\n  document.addEventListener('mouseup',up,false);\n  \/* 拖动后吞掉 click, 避免松手就打开通知面板 *\/\n  b.addEventListener('click',function(e){\n    if(_bblk||_bmov){if(e.preventDefault)e.preventDefault();if(e.stopPropagation)e.stopPropagation();_bmov=0;}\n  },true);\n}\n\n\/* ===== C批: 全局复用 injectJs AI 子系统 兼容层 =====\n   首页(startJs)无 injectJs(data协议不注入), 现内联复刻 injectJs 全文以启用问AI功能。\n   补充 injectJs 依赖但首页缺失的 4 个全局符号(load\/save\/store\/killEv)。\n   注: jload\/jsave -> pget\/pput -> window.java 持久化, 首页与详情页共享同一AI配置键空间。\n*\/\nfunction load(k,d){return jload(k,d);}\nfunction save(k,v){jsave(k,v);}\nfunction store(k,v){jsave(k,v);}\nfunction killEv(t){try{var e=t||window.event;if(e){e.preventDefault&&e.preventDefault();e.stopPropagation&&e.stopPropagation();}}catch(x){}}\n\/* AI开关默认值: 首页ST无aiOn键, 默认置1开启问AI按钮(不动injectJs任何代码) *\/\ntry{ST.aiOn!==undefined||(ST.aiOn=1);}catch(e){}\n(function(){function B(a){try{var t=Object.keys(window),e,n;for(e=0;e<t.length;e++){try{n=window[t[e]]}catch(i){continue}if(n&&typeof n==\"object\"&&a(n))return n}}catch(i){}return null}window.java||(window.java=B(function(a){return typeof a.ajaxAwait==\"function\"})),window.source||(window.source=B(function(a){return typeof a.getSource==\"function\"})),window.cache||(window.cache=B(function(a){return typeof a.get==\"function\"&&typeof a.put==\"function\"})),window.java&&(window.ajaxAwait||(window.ajaxAwait=function(a){return window.java.ajaxAwait(a)}),window.postAwait||(window.postAwait=function(a,t,e,n){return window.java.postAwait(a,t,e,n)}));try{with(window){window.AIDEFBASE=\"https:\/\/platform.aitools.cfd\/api\/v1\",window.AIFALLBACK=[[\"zhipu\/glm-4.7-flash\",\"GLM-4.7-Flash\"],[\"zhipu\/glm-4.6v-flash\",\"GLM-4.6V-Flash\"],[\"zhipu\/glm-4-flash\",\"GLM-4-Flash\"],[\"openai\/gpt-oss-20b\",\"GPT-OSS-20B\"],[\"google\/gemma-4-31b\",\"Gemma-4-31B\"]],window.AIKEYURL=\"https:\/\/platform.aitools.cfd\/api\/key\/generate\",window.AILMAX=60,window.CP_PRESET=[\"#FFFFFF\",\"#F1F2F7\",\"#E4E7F0\",\"#8A8FA8\",\"#5A5F73\",\"#2B2D42\",\"#000000\",\"#FF6B9D\",\"#E5484D\",\"#F2A33C\",\"#16A34A\",\"#22A7C2\",\"#7C6BD9\",\"#A855F7\",\"#FDF4DE\",\"#C3A875\"],window.DPROMS=[{n:\"深度翻译\",s:`你是精通双语的翻译与跨文化解读专家。\n请对选中的内容做「翻译 + 扩展解读」，严格按以下结构输出：\n\n## 一、译文\n给出自然、通顺、符合中文表达习惯的译文（若是中译英则给地道英文）。\n\n## 二、关键措辞\n挑出 3～6 个值得留意的词句，逐一说明：原意、你的译法、为什么这样译、还有哪些可选译法。\n\n## 三、背景与知识扩展\n补充与内容相关的背景知识、文化典故、专业术语或领域常识，帮助读者真正读懂。\n\n## 四、语言点赏析\n从语法、修辞、语气、风格等角度做简要赏析，指出原文的精妙或难点。\n\n要求：条理清晰、用小标题分段；信息密度高但不啰嗦；不确定之处明确标注，不要编造。`},{n:\"词语全景解读\",s:`你是网络文化与语言学研究者。\n请对选中的词句做「全景式解读」，严格按以下结构输出：\n\n## 一、基本释义\n字面含义、词性、读音\/写法变体。\n\n## 二、网络与口语含义\n在当前网络语境下的真实含义，与字面义的差异。\n\n## 三、来源与演变\n出处（梗\/事件\/平台）、传播路径、含义的流变过程。\n\n## 四、常见用法与搭配\n给出 4～8 个真实例句，覆盖不同语境。\n\n## 五、典型场景\n说明它常出现在哪些平台\/人群\/话题中（弹幕、评论区、贴吧、游戏、职场等）。\n\n## 六、感情色彩与避雷\n褒贬、亲疏、正式程度；哪些场合能用、哪些场合慎用或易冒犯。\n\n## 七、近义与对照\n列出 3～5 个近义表达并比较细微差别。\n\n要求：要点化、每条一行；不确定的来源标注\"待考\"，不要臆断。`},{n:\"润色与改写\",s:`你是资深文字编辑。\n请在【完全保留原意】的前提下优化选中的文字，按以下结构输出：\n\n## 一、润色稿\n直接给出优化后的成稿（这是主要输出，要能直接复制使用）。\n\n## 二、主要改动\n分条说明改了什么、为什么改（语病、啰嗦、逻辑、用词、节奏等）。\n\n## 三、风格备选\n再给 2 个不同风格的版本（如：简洁版 \/ 正式版 \/ 更有感染力版），并注明各自适用场景。\n\n## 四、提升建议\n指出原文最值得改进的一两个根本问题，给出可操作的写作建议。\n\n要求：只润色不篡改事实；不要无谓堆砌辞藻；保持作者原有语气除非明显不妥。`},{n:\"深度分析与思辨\",s:`你是跨学科的思考伙伴。\n请对选中的内容做有纵深的分析，严格按以下结构输出：\n\n## 一、核心观点\n用一两句话概括它真正在说什么。\n\n## 二、多层解读\n从不同角度拆解（至少 3 个角度：如逻辑层面、心理层面、社会\/历史层面、实用层面）。\n\n## 三、支撑与反驳\n它成立的前提是什么？有哪些有力的支持理由？又有哪些合理的质疑或反例？\n\n## 四、关联与延伸\n把它和更广阔的知识领域连起来（可涉历史、经济、心理、科学、哲学、艺术等），打开视野。\n\n## 五、启发与行动\n读者能从中带走什么？给出 2～3 条可落地的启发或行动建议。\n\n## 六、反过来想\n如果站在完全相反的立场，会怎么看？\n\n要求：观点明确、论据具体；区分\"事实\"与\"推测\"；不要和稀泥，也不要武断。`},{n:\"续写与创作\",s:`你是小说创作者。\n请接着选中的内容往下写，严格按以下要求：\n\n## 一、续写正文\n直接接着写，保持原有文风、人称、叙事节奏与世界观；长度适中，有推进不要原地打转。\n\n## 二、创作说明\n简要说明你为什么这样接（埋了什么伏笔、想营造什么情绪、后续可能走向）。\n\n## 三、可选分支\n再给 2 个不同走向的开头片段（如：温情向 \/ 悬疑向 \/ 冲突向），供作者选择。\n\n要求：不重复原文；人物行为符合已展现的性格；结尾留有余味，不要把所有话说尽。`},{n:\"一键优化提示词\",s:`你是提示词工程专家，擅长把粗糙的想法打磨成高质量的系统提示词。\n用户接下来给你的，是他准备拿去当提示词的一段文字。请你【不要回答这段文字本身的内容】，而是把它【扩展、改写、优化成一条成熟的提示词】。\n\n优化时按以下方向发力（突出一个\"多\"）：\n1. 角色更专业：为它设定一个最合适的专家身份，并点明该身份的知识范围与判断标准。\n2. 任务更多维：不只做一件事，而是拆成若干互相补充的维度（释义\/分析\/举例\/对比\/延伸\/启发等）。\n3. 结构更清晰：用小标题或编号规定输出结构，让回答层次分明、便于扫读。\n4. 知识更广：主动要求它调动跨领域知识（历史、社会、心理、科学、文化、实用场景等）。\n5. 深度更足：要求给出理由、依据、前提、反例与边界，而不是只给结论。\n6. 更有启发：要求补充别人容易忽略的角度、可迁移的方法、可落地的建议。\n7. 排版更好：明确要求分段、要点化、适当留白，必要时用表格。\n8. 约束更明确：说明长度、语气、禁止编造、不确定要标注等。\n\n请直接输出优化后的提示词全文（不要解释你的优化思路，不要加前后缀），要求可直接复制使用。`}],window.KAIL=\"x8t_ailog\",window.KCFG=\"x8t_aicfg\",window.KCIDX=\"x8t_aicfgidx\",window.KEN=\"x8t_aien\",window.KMODE=\"x8t_aimode\",window.KPOOL=\"x8t_aipool\",window.KPRO=\"x8t_aipro\",window.KRR=\"x8t_airr\",window.KTO=\"x8t_aito\",window._Z={},window._aiBtn=null,window._aiBusy=0,window._aiDrag=null,window._aiQ=\"\",window._aiRaw=\"\",window._aiSysTmp=\"\",window._aiT=0,window._aiTimer=0,window._aiSel=[],window.aiAddCfg=function(){var t=aiCfgs();t.push({n:\"新配置\",base:AIDEFBASE,key:\"\",model:AIFALLBACK[0][0],sys:\"\",auto:1}),aiSaveCfgs(t),aiSetIdx(t.length-1),aiEcho(),tip(\"✔ 已新建，填密钥即可用\",\"ok\")},window.aiAddPro=function(){var t=document.getElementById(\"aisys\"),e=t?String(t.value||\"\").trim():\"\";if(!e){tip(\"✘ 提示词是空的\",\"no\");return}var n=prompt(\"给这个提示词起个名字\",\"我的提示词\");if(n!==null){var i=aiPro();i.push({n:String(n||\"\").trim()||\"我的提示词\",s:e}),aiSavePro(i),aiEcho(),tip(\"✔ 已保存提示词\",\"ok\")}},window.aiAsk=function(t){if(t=String(t||\"\").trim(),!!t){var e=document.getElementById(\"aim\");e||(e=document.createElement(\"div\"),e.id=\"aim\",e.className=\"modal\",e.innerHTML='<div class=\"mbox\"><div class=\"phd\"><h3>✨ 问 AI<\/h3><button class=\"x\" type=\"button\" onclick=\"aiClose()\">✕<\/button><\/div><div id=\"aiedit\"><div class=\"aifold\"><button class=\"bt\" id=\"aifoldbtn\" type=\"button\" onclick=\"aiFoldToggle()\">⚙ 收起设置<\/button><\/div><div class=\"aifold-body\" id=\"aifoldbody\"><div class=\"srow\"><label>提供商<\/label><select id=\"aicfg2\" onchange=\"aiPickAskCfg(this.value)\"><\/select><button class=\"bt\" type=\"button\" style=\"flex:none;min-width:52px\" onclick=\"aiPullIntoPool(aiIdx())\">拉取<\/button><\/div><div class=\"srow\"><label>调用模式<\/label><select id=\"aimode2\" onchange=\"aiSetMode(this.value)\"><option value=\"single\">单一模型（只用 1 号）<\/option><option value=\"rr\">轮流调用<\/option><option value=\"cc\">并发调用<\/option><\/select><\/div><div class=\"srow\"><label>轮流数量<\/label><input type=\"number\" id=\"airrn2\" min=\"1\" max=\"20\" style=\"flex:none;width:64px\" onchange=\"aiSetRR(this.value)\"><label style=\"width:auto;flex:none\">超时(秒)<\/label><input type=\"number\" id=\"aito2\" min=\"5\" max=\"300\" style=\"flex:none;width:64px\" onchange=\"aiSetTO(this.value)\"><\/div><div class=\"aihint\">可在外观设置界面的问ai设置里，改变模型密钥和新增自定义模型。<\/div><\/div><div class=\"mlist\" id=\"aimlist\"><\/div><div class=\"mlist-btns\" id=\"aimlistbtns\"><\/div><div class=\"srow\"><label>提示词模板<\/label><select id=\"aipro2\" onchange=\"aiPickAskPro(this.value)\"><\/select><\/div><div class=\"prow\"><textarea id=\"aisys2\" rows=\"3\" placeholder=\"临时提示词：只对这一次生效，留空则用模板\/默认\"><\/textarea><button class=\"bt\" type=\"button\" title=\"保存为提示词模板\" onclick=\"aiSaveTmpPro()\">存为模板<\/button><button class=\"bt warn\" type=\"button\" title=\"删除当前选中的模板\" onclick=\"aiDelAskPro()\">删模板<\/button><\/div><div class=\"aihint ck\" onclick=\"aiHintT(this)\">📌 免费模型怎么配置更稳？（点开）<div class=\"ckb\" style=\"display:none;font-size:12px\">为了减少免费模型的延迟高出错率高的问题，可在外观设置按钮打开ai问答设置，点新建，再点击申请免费密钥（来自站点<b>https:\/\/platform.aitools.cfd\/<\/b>）简单命个序号名，然后就会自动保存新配置。<br>同一IP过一个小时又能申请一个免费密钥，WIFI和移动数据IP是不同的，所以一个小时能申请2个免费密钥。回到问ai面板，选新配置，点击拉取，选择一个就够了，因为一个key每3-5秒只能请求1次，再选新申请密钥的配置，又拉取一个，循环。然后你就能有足够多并发模式可用的免费模型了，然后并发模式下哪个请求快就显示哪个结果。<br>为了更好的体验，还是建议去智谱、硅基流动、agens等平台，都有免费版模型，登录注册一个apikey，在外观设置按钮中ai问答设置里添加新配置填入正确的baseurl和key即可，不会注册和填写就问豆包元宝ds<\/div><\/div><textarea id=\"aiq\" rows=\"6\" placeholder=\"要发送给 AI 的文字（可编辑）\"><\/textarea><div class=\"row\"><button class=\"bt pri\" style=\"flex:1\" onclick=\"aiSend()\">✨ 问一下<\/button><button class=\"bt\" style=\"flex:none;min-width:72px\" onclick=\"aiClose()\">取消<\/button><\/div><div class=\"row\"><button class=\"bt\" style=\"flex:1\" onclick=\"aiTest()\">⚡ 一键测试<\/button><button class=\"bt\" style=\"flex:none;min-width:56px\" onclick=\"aiTestClear()\">清除<\/button><button class=\"bt\" style=\"flex:none;min-width:56px\" onclick=\"aiViewLog()\">日志<\/button><\/div><pre class=\"aitest\" id=\"aitest\" style=\"display:none\"><\/pre><\/div><div id=\"aians\" style=\"display:none\"><div class=\"aiq\" id=\"aiqq\"><\/div><div class=\"aia\" id=\"aia\"><\/div><div class=\"aipick\" id=\"aipickwrap\" style=\"display:none\"><label>答案来源<\/label><select id=\"aipick\" onchange=\"aiConcPick(this.value)\"><option value=\"\">（暂无并发缓存）<\/option><\/select><\/div><div class=\"row\"><button class=\"bt\" onclick=\"aiBackEdit()\">改一下<\/button><button class=\"bt\" onclick=\"aiCopy()\">复制<\/button><button class=\"bt\" onclick=\"aiSend()\">重试<\/button><button class=\"bt pri\" onclick=\"aiClose()\">关闭<\/button><\/div><\/div><\/div>',document.body.appendChild(e)),e.className=\"modal on\",aiEchoAsk();var n=document.getElementById(\"aiq\");n&&(n.value=t),aiBackEdit()}},window.aiAskFetchModels=function(){aiModels(function(t){if(!(!t||!t.length)){var e=document.getElementById(\"aimpick2\");if(e){var n=\"\",i;for(i=0;i<t.length;i++)n+='<option value=\"'+esc(t[i][0])+'\">'+esc(t[i][1])+\"<\/option>\";e.innerHTML=n,tip(\"✔ 拉到 \"+t.length+\" 个模型，可在下拉里选\",\"ok\")}}})},window.aiBackEdit=function(){var t=document.getElementById(\"aiedit\"),e=document.getElementById(\"aians\");t&&(t.style.display=\"\"),e&&(e.style.display=\"none\")},window.aiBase=function(){var t=aiCfg();return String(t&&t.base||AIDEFBASE).replace(\/[\/]+$\/,\"\")},window.aiCall=function a(t,e,n,i,o){var r={method:\"POST\",headers:{\"Content-Type\":\"application\/json\",Authorization:\"Bearer \"+t.key},body:JSON.stringify({model:t.model,messages:e})},s=\"\";try{e&&e[0]&&e[0].role===\"system\"&&(s=e[0].content)}catch(c){}function d(c,u,l){try{aiLog({kind:\"问AI\",ok:!!c,model:t.model,sys:s,q:i,a:l||\"\",err:u||\"\",ms:_aiT0?new Date().getTime()-_aiT0:0})}catch(f){}}fetch(aiBase()+\"\/chat\/completions\",r).then(function(c){if((c.status===401||c.status===403)&&aiIsFree()&&t.auto!==0&&o<1)return n.className=\"aia wait\",n.textContent=\"密钥失效，正在自动申请新密钥…\",aiNewKey().then(function(l){if(!l)return n.className=\"aia err\",n.textContent=\"密钥失效，自动申请也没成功（每小时限 1 个），请稍后重试或手动填密钥。\",_aiBusy=0,d(!1,\"密钥失效且自动申请失败\"),null;var f=aiCfgs(),m=aiIdx();f[m]&&(f[m].key=l,aiSaveCfgs(f));var g=document.getElementById(\"aikey\");return g&&(g.value=l),t.key=l,tip(\"✔ 已自动换新密钥\",\"ok\"),a(t,e,n,i,o+1)});if(c.status===401||c.status===403)return _aiBusy=0,d(!1,\"HTTP \"+c.status+\" 密钥无效\"),n.className=\"aia err\",n.textContent=\"密钥无效（401），请重填或开启自动续期。\",null;if(c.status===429){var u=3;try{u=parseInt(c.headers.get(\"Retry-After\")||\"3\",10)||3}catch(l){}return _aiBusy=0,d(!1,\"HTTP 429 请求太频繁\"),n.className=\"aia err\",n.textContent=\"请求太频繁（每密钥 3 秒 1 次），请 \"+u+\" 秒后重试。\",null}return c.ok?c.text():(_aiBusy=0,d(!1,\"HTTP \"+c.status),n.className=\"aia err\",n.textContent=\"请求失败：HTTP \"+c.status,null)}).then(function(c){if(!(c===null||c===undefined)){_aiBusy=0;var u=\"\";try{var l=JSON.parse(c);u=((((l||{}).choices||[])[0]||{}).message||{}).content||\"\"}catch(f){u=\"\"}if(!u){d(!1,\"空回答: \"+String(c||\"\").slice(0,60)),n.className=\"aia err\",n.textContent=\"没拿到回答：\"+String(c||\"\").slice(0,200);return}_aiRaw=u,n.className=\"aia\",aiType(n,aiMd(u)),d(!0,\"\",u)}}).catch(function(c){_aiBusy=0,d(!1,String(c&&c.message?c.message:c)),n.className=\"aia err\",n.textContent=\"请求出错：\"+(c&&c.message?c.message:c)})},window.aiCfg=function(){var t=aiCfgs(),e=aiIdx();return t[e]||t[0]},window.aiCfgs=function(){var t=null;try{t=jload(KCFG,null)}catch(e){}return(!t||typeof t.length!=\"number\"||!t.length)&&(t=[{n:\"免费站\",base:AIDEFBASE,key:\"\",model:AIFALLBACK[0][0],sys:\"\",auto:1}]),t},window.aiClearLog=function(){try{jsave(KAIL,[])}catch(t){}tip(\"✔ 日志已清空\",\"ok\")},window.aiClose=function(){var t=document.getElementById(\"aim\");t&&(t.className=\"modal\")},window.aiCopy=function(){if(!_aiRaw){tip(\"✘ 还没有内容\",\"no\");return}try{if(window.java&&window.java.setClipboard){window.java.setClipboard(_aiRaw),tip(\"✔ 已复制\",\"ok\");return}}catch(t){}tip(\"✘ 复制失败，请长按选择文字\",\"no\")},window.aiDelCfg=function(){var t=aiCfgs(),e=aiIdx();if(t.length<=1){tip(\"✘ 至少保留一套配置\",\"no\");return}confirm(\"删除当前配置「\"+(t[e].n||\"\")+\"」？\")&&(t.splice(e,1),aiSaveCfgs(t),aiSetIdx(Math.max(0,e-1)),aiEcho(),tip(\"✔ 已删除\",\"ok\"))},window.aiDelPro=function(){var t=document.getElementById(\"aipro\"),e=t?parseInt(t.value,10):-1,n=aiPro();if(e<0||!n[e]){tip(\"✘ 先在下拉里选一条\",\"no\");return}confirm(\"删除提示词「\"+(n[e].n||\"\")+\"」？\")&&(n.splice(e,1),aiSavePro(n),aiEcho(),tip(\"✔ 已删除\",\"ok\"))},window.aiDupCfg=function(){var t=aiCfgs(),e=aiIdx();if(t[e]){var n={};for(var i in t[e])n[i]=t[e][i];n.n=(t[e].n||\"\")+\" 副本\",t.push(n),aiSaveCfgs(t),aiSetIdx(t.length-1),aiEcho(),tip(\"✔ 已复制\",\"ok\")}},window.aiEcho=function(){var t=aiCfg(),e,n=document.getElementById(\"aicfg\");n&&(n.innerHTML=aiOptsCfgs(),n.value=String(aiIdx()));var i=document.getElementById(\"ainame\");i&&(i.value=t.n||\"\");var o=document.getElementById(\"aibase\");o&&(o.value=t.base||\"\");var r=document.getElementById(\"aikey\");r&&(r.value=t.key||\"\");var s=document.getElementById(\"aimodel\");s&&(s.value=t.model||\"\");var d=document.getElementById(\"aisys\");d&&(d.value=t.sys||\"\");var c=document.getElementById(\"aimpick\");if(c&&!c.innerHTML){var u=\"\";for(e=0;e<AIFALLBACK.length;e++)u+='<option value=\"'+esc(AIFALLBACK[e][0])+'\">'+esc(AIFALLBACK[e][1])+\"<\/option>\";c.innerHTML=u}c&&t.model&&(c.value=t.model);var l=document.getElementById(\"aipro\");if(l){l.innerHTML=aiOptsPro();var f=aiPro();for(e=0;e<f.length;e++)if(f[e].s===(t.sys||\"\")){l.value=String(e);break}}var m=document.getElementById(\"ai0\");m&&(m.className=\"msw\"+(ST.aiOn?\"\":\" on\"));var g=document.getElementById(\"ai1\");g&&(g.className=\"msw\"+(ST.aiOn?\" on\":\"\"));var h=document.getElementById(\"aiauto0\");h&&(h.className=\"msw\"+(t.auto===0?\" on\":\"\"));var w=document.getElementById(\"aiauto1\");w&&(w.className=\"msw\"+(t.auto!==0?\" on\":\"\"))};var KAIL=\"x8t_ailog\",AILMAX=60;window.aiEchoAsk=function(){var t=aiCfg(),e,n;if(e=document.getElementById(\"aicfg2\"),e&&(e.innerHTML=aiOptsCfgs(),e.value=String(aiIdx())))e=document.getElementById(\"aipro2\"),e&&(e.innerHTML=aiOptsPro()),e=document.getElementById(\"aisys2\"),e&&(e.value=t.sys||\"\"),aiRenderModels(),e=document.getElementById(\"aimode2\"),e&&(e.value=aiMode()),e=document.getElementById(\"airrn2\"),e&&(e.value=String(aiRRN())),e=document.getElementById(\"aito2\"),e&&(e.value=String(Math.round(aiTimeout()\/1e3))),aiSyncModeUI()},window.aiEn=function(){var t=[];try{t=jload(KEN,null)}catch(e){}return t&&typeof t.length==\"number\"?t:[]},window.aiEnList=function(){var t=aiPool(),e=aiEn(),n=[],i,o;for(i=0;i<e.length;i++)for(o=0;o<t.length;o++)if(aiKeyOf(t[o])===e[i]){n.push(t[o]);break}return n},window.aiFetchModels=function(){aiModels(function(t){if(!(!t||!t.length)){var e=document.getElementById(\"aimpick\");if(e){var n=\"\",i;for(i=0;i<t.length;i++)n+='<option value=\"'+esc(t[i][0])+'\">'+esc(t[i][1])+\"<\/option>\";e.innerHTML=n}}})},window.aiGenKey=function(){tip(\"… 正在申请\"),aiNewKey().then(function(t){if(!t){tip(\"✘ 申请失败（该站每小时限 1 个），可稍后再试或手动填\",\"no\");return}aiSet(\"key\",t),tip(\"✔ 新密钥已填入\",\"ok\")})},window.aiIdx=function(){var t=0;try{t=parseInt(load(KCIDX)||\"0\",10)||0}catch(n){}var e=aiCfgs();return t<0&&(t=0),t>=e.length&&(t=e.length-1),t},window.aiInitBtn=function(){_aiBtn||(_aiBtn=document.createElement(\"button\"),_aiBtn.type=\"button\",_aiBtn.className=\"aisel\",_aiBtn.innerHTML=\"✨ 问 AI\",_aiBtn.onclick=function(t){killEv(t);var e=aiSelText();e&&aiAsk(e)},_aiBtn.style.display=\"none\",_aiBtn.style.position=\"fixed\",_aiBtn.style.zIndex=\"2147483647\",document.body.appendChild(_aiBtn),document.addEventListener(\"selectionchange\",function(){try{clearTimeout(_aiT)}catch(t){}_aiT=setTimeout(aiShowBtn,260)},!1))},window.aiIsFree=function(){return aiBase().indexOf(\"aitools.cfd\")>=0},window.aiKeyOf=function(t){return t.cfg+\"|\"+t.id},window.aiLog=function(t){try{t.t=new Date().getTime(),t.ts=aiTs(t.t);var e=[];try{e=jload(KAIL,null)}catch(n){}for((!e||typeof e.length!=\"number\")&&(e=[]),e.push(t);e.length>AILMAX;)e.shift();jsave(KAIL,e)}catch(n){}try{java.log(\"[AI] \"+String(t.kind||\"\")+\" \"+String(t.ok?\"OK\":\"FAIL\")+\" \"+String(t.msg||\"\"))}catch(n){}},window.aiLogText=function(){var t=[];try{t=jload(KAIL,null)}catch(r){}if(!t||!t.length)return\"（暂无日志）\";var e=[],n;for(n=t.length-1;n>=0;n--){var i=t[n],o=\"[\"+String(i.ts||\"\")+\"] \"+String(i.kind||\"\");i.kind===\"问AI\"?(o+=\" #\"+String(i.no||1)+\" | \"+String(i.pn||\"\")+\" \/ \"+String(i.model||\"\")+\" | \"+(i.ms||0)+\"ms | \"+(i.ok?\"成功\":\"失败 \"+String(i.err||\"\")),i.sys&&(o+=`\n  提示词: `+String(i.sys).slice(0,80)),o+=`\n  发送: `+String(i.q||\"\").slice(0,120),o+=`\n  返回: `+String(i.a||\"\").slice(0,200)):i.kind===\"测试\"&&(o+=\" | \"+String(i.name||\"\")+\" | 延迟 \"+(i.ms||0)+\"ms | \"+(i.ok?\"成功\":\"失败 \"+String(i.err||\"\")),i.a&&(o+=`\n  返回: `+String(i.a).slice(0,80))),e.push(o)}return e.join(`\n`)},window.aiMd=function(t){return t=String(t||\"\"),t=t.replace(\/&\/g,\"&amp;\").replace(\/<\/g,\"&lt;\").replace(\/>\/g,\"&gt;\"),t=t.replace(\/```[\\w]*\\n?([\\s\\S]*?)```\/g,function(e,n){return\"<pre><code>\"+n.replace(\/\\n$\/,\"\")+\"<\/code><\/pre>\"}),t=t.replace(\/`([^`\\n]+)`\/g,\"<code>$1<\/code>\"),t=t.replace(\/\\*\\*([^*\\n]+)\\*\\*\/g,\"<b>$1<\/b>\"),t=t.replace(\/^###[ \\t]+(.*)$\/gm,\"<h4>$1<\/h4>\"),t=t.replace(\/^##[ \\t]+(.*)$\/gm,\"<h3>$1<\/h3>\"),t=t.replace(\/^[-*][ \\t]+(.*)$\/gm,\"<li>$1<\/li>\"),t=t.replace(\/\\n\/g,\"<br>\"),t},window.aiMode=function(){var t=\"single\";try{t=String(load(KMODE)||\"single\")}catch(e){}return t===\"rr\"?\"rr\":(t===\"cc\"?\"cc\":\"single\")},window.aiModels=function(t){var e=aiCfg().key||\"\";if(!e){tip(\"✘ 先填 API 密钥再拉模型\",\"no\"),t&&t(null);return}fetch(aiBase()+\"\/models\",{headers:{Authorization:\"Bearer \"+e}}).then(function(n){return n.ok?n.text():null}).then(function(n){if(!n){tip(\"✘ 拉取失败, 请检查 Base URL 与密钥\",\"no\"),t&&t(null);return}var i=[];try{var o=JSON.parse(n);i=o&&o.data||[]}catch(c){i=[]}if(!i.length){tip(\"✘ 没拉到模型, 可手动填模型 ID\",\"no\"),t&&t(null);return}var r=[],s;for(s=0;s<i.length;s++){var d=i[s]&&i[s].id;d&&r.push([d,d])}if(!r.length){t&&t(null);return}tip(\"✔ 拉到 \"+r.length+\" 个模型\",\"ok\"),t&&t(r)}).catch(function(n){tip(\"✘ 拉取出错: \"+(n&&n.message?n.message:n),\"no\"),t&&t(null)})},window.aiNewKey=function(){return fetch(AIKEYURL,{method:\"POST\",headers:{\"Content-Type\":\"application\/json\"},body:\"{}\"}).then(function(t){return t.ok?t.text():null}).then(function(t){if(!t)return\"\";try{var e=JSON.parse(t);return e&&e.key?String(e.key):\"\"}catch(n){return\"\"}}).catch(function(){return\"\"})},window.aiOnce=function(t,e,n,i,o){return new Promise(function(r){var s=!1,d=new Date().getTime(),c=setTimeout(function(){s||(s=!0,r({ok:!1,err:\"超时 \"+Math.round(o\/1e3)+\" 秒\",ms:o}))},o),u={method:\"POST\",headers:{\"Content-Type\":\"application\/json\",Authorization:\"Bearer \"+e},body:JSON.stringify({model:n,messages:i})};fetch(t+\"\/chat\/completions\",u).then(function(l){if(!s){s=!0,clearTimeout(c);var f=new Date().getTime()-d;if(!l.ok){var m=\"HTTP \"+l.status;return l.status===429&&(m=\"HTTP 429 请求太频繁(每密钥3秒1次)\"),(l.status===401||l.status===403)&&(m=\"HTTP \"+l.status+\" 密钥无效\"),r({ok:!1,err:m,ms:f})}return l.text().then(function(g){var h=\"\";try{var w=JSON.parse(g);h=((((w||{}).choices||[])[0]||{}).message||{}).content||\"\"}catch(v){}if(!h)return r({ok:!1,err:\"空回答: \"+String(g||\"\").slice(0,60),ms:f});r({ok:!0,ans:h,ms:f})})}}).catch(function(l){s||(s=!0,clearTimeout(c),r({ok:!1,err:String(l&&l.message?l.message:l),ms:new Date().getTime()-d}))})})},window.aiOptsCfgs=function(){var t=aiCfgs(),e=\"\",n;for(n=0;n<t.length;n++)e+='<option value=\"'+n+'\">'+esc(t[n].n||\"配置\"+(n+1))+\"<\/option>\";return e},window.aiOptsPro=function(){var t=aiPro(),e='<option value=\"-1\">（不用提示词）<\/option>',n;for(n=0;n<t.length;n++)e+='<option value=\"'+n+'\">'+esc(t[n].n||\"提示词\"+(n+1))+\"<\/option>\";return e},window.aiPickAskCfg=function(t){aiSetIdx(parseInt(t,10)||0);var e=aiCfg(),n;n=document.getElementById(\"aisys2\"),n&&(n.value=e.sys||\"\")},window.aiPickAskPro=function(t){var e=parseInt(t,10),n=document.getElementById(\"aisys2\");if(e<0){n&&(n.value=\"\");return}var i=aiPro();i[e]&&n&&(n.value=i[e].s||\"\")},window.aiPickCfg=function(t){var e=parseInt(t,10)||0;aiSetIdx(e),aiEcho()},window.aiPickPro=function(t){var e=parseInt(t,10),n=aiPro();e<0||!n[e]||(aiSet(\"sys\",n[e].s),tip(\"✔ 已套用「\"+(n[e].n||\"\")+\"」\",\"ok\"))},window.aiPool=function(){var t=[];try{t=jload(KPOOL,null)}catch(e){}return t&&typeof t.length==\"number\"?t:[]},window.aiPro=function(){var t=null;try{t=jload(KPRO,null)}catch(e){}return(!t||typeof t.length!=\"number\"||!t.length)&&(t=DPROMS.slice(0)),t},window.aiPullIntoPool=function(t,e){var n=aiCfgs(),i=n[t];if(!i){e&&e(0);return}if(!i.key){tip(\"✘ 该提供商还没填密钥\",\"no\"),e&&e(0);return}var o=String(i.base||AIDEFBASE).replace(\/[\/]+$\/,\"\");fetch(o+\"\/models\",{headers:{Authorization:\"Bearer \"+i.key}}).then(function(r){return r.ok?r.text():null}).then(function(r){var s=[];try{s=JSON.parse(r||\"{}\").data||[]}catch(g){s=[]}var d=aiPool(),avail=[],u,l;for(u=0;u<s.length;u++){var f=s[u]&&s[u].id;if(f){var m=!1;for(l=0;l<d.length;l++)if(d[l].cfg===t&&d[l].id===f){m=!0;break}if(!m)avail.push(f)}}if(!avail.length){tip(\"没有新模型（都已添加）\",\"ok\"),e&&e(0);return}aiShowPicker(avail,function(sel){if(!sel||!sel.length){e&&e(0);return}var pp=aiPool(),c=0,k;for(k=0;k<sel.length;k++){var fid=sel[k],ex=!1;for(l=0;l<pp.length;l++)if(pp[l].cfg===t&&pp[l].id===fid){ex=!0;break}if(!ex)pp.push({cfg:t,id:fid,pn:i.n||\"配置\"+(t+1),mn:fid}),c++}c&&aiSavePool(pp),aiRenderModels(),tip(c?\"✔ 新增 \"+c+\" 个模型\":\"没有新模型\",\"ok\"),e&&e(c)})}).catch(function(r){tip(\"✘ 拉取失败: \"+(r&&r.message?r.message:r),\"no\"),e&&e(0)})},window.aiRRN=function(){var t=2;try{t=parseInt(load(KRR)||\"2\",10)||2}catch(e){t=2}return t<1&&(t=1),t>20&&(t=20),t},window.aiRenderModels=function(){var t=document.getElementById(\"aimlist\"),b=document.getElementById(\"aimlistbtns\");if(t){var e=aiPool(),n=aiEn(),i,o,r=[],s={};for(i=0;i<n.length;i++)for(o=0;o<e.length;o++)if(aiKeyOf(e[o])===n[i]){r.push(o),s[o]=1;break}for(o=0;o<e.length;o++)s[o]||r.push(o);var bt='<div class=\"mlist-btns\"><button class=\"bt\" type=\"button\" onclick=\"aiMoveUp()\">▲ 上移<\/button><button class=\"bt\" type=\"button\" onclick=\"aiMoveDown()\">▼ 下移<\/button><button class=\"bt\" type=\"button\" onclick=\"aiDel()\">✕ 删除<\/button><\/div>';if(!r.length){t.innerHTML='<div class=\"aihint\">还没有模型。选好提供商后点上面的「拉取」。<\/div>';if(b)b.innerHTML=bt;return}var d=0,c=\"\";for(i=0;i<r.length;i++){var u=r[i],l=e[u],f=n.indexOf(aiKeyOf(l))>=0;f&&d++;var sel=_aiSel.indexOf(u)>=0?\" selected\":\"\";c+='<div class=\"mrow'+(f?\" on\":\"\")+sel+'\" data-pi=\"'+u+'\" onclick=\"aiSelToggle('+u+')\"><span class=\"mno\">'+(f?d:\"·\")+'<\/span><input type=\"checkbox\"'+(f?\" checked\":\"\")+' onclick=\"event.stopPropagation()\" onchange=\"aiToggleEn('+u+')\"><span class=\"mname\">'+esc(l.pn)+\" \/ \"+esc(l.mn)+'<\/span><\/div>'}t.innerHTML=c;if(b)b.innerHTML=bt}};window.aiRetry=function(){aiSend()},window.aiRun=function(t,e){if(_aiBusy){tip(\"… 正在请求中\");return}var n=document.getElementById(\"aia\");if(n){n.className=\"aia wait\",n.textContent=\"思考中…\",_aiRaw=\"\";var i=aiEnList();if(!i.length){n.className=\"aia err\",n.textContent=\"没有启用的模型。请在模型列表里勾选，或先点「拉取」把模型加进来。\";return}var o=aiMode(),r=o===\"rr\"?Math.min(aiRRN(),i.length):1,s=typeof e==\"string\"?String(e).trim():\"\";_aiBusy=1;if(o===\"cc\"){aiRunConc(t,s,i,Math.min(aiRRN(),i.length),n);return}aiRunSeq(t,s,i,0,r,n)}},\nwindow._aiConcC=[];window._aiConcCur=\"\";window.buildConcPick=function(){var p=document.getElementById(\"aipick\"),w=document.getElementById(\"aipickwrap\");if(!p)return;if(_aiConcC.length<2){p.style.display=\"none\";if(w)w.style.display=\"none\";return}p.innerHTML=\"\";for(var i=0;i<_aiConcC.length;i++){var o=document.createElement(\"option\");var lab=_aiConcC[i].pn+\" \/ \"+_aiConcC[i].mn;o.value=String(i);o.textContent=lab;if(lab===_aiConcCur)o.selected=true;p.appendChild(o)}p.style.display=\"\";if(w)w.style.display=\"\"},window.aiConcPick=function(i){var idx=parseInt(i,10);if(isNaN(idx)||idx<0||idx>=_aiConcC.length)return;var c=_aiConcC[idx];_aiConcCur=c.pn+\" \/ \"+c.mn;_aiRaw=c.ans;var r=document.getElementById(\"aia\");if(r){r.className=\"aia\";r.textContent=aiMd(c.ans)}buildConcPick()},window.aiRunConc=function(t,e,list,n,r){var fired=Math.min(n,list.length);_aiConcC=[];_aiConcCur=\"\";var pick=document.getElementById(\"aipick\"),wr=document.getElementById(\"aipickwrap\");if(pick){pick.style.display=\"none\";pick.innerHTML=\"\"}if(wr)wr.style.display=\"none\";r.className=\"aia wait\";r.textContent=\"并发请求 \"+fired+\" 个模型（\"+list[0].pn+\" \/ \"+list[0].mn+\" 等）…\";var done=0,shown=false,cfgs=aiCfgs();if(!cfgs||typeof cfgs.length!==\"number\")cfgs=[cfgs];var fire=function(idx){var mod=list[idx],d=cfgs[mod.cfg]||cfgs[0]||{},u=String(d.base||AIDEFBASE).replace(\/[\/]+$\/,\"\"),msgs=[];e&&msgs.push({role:\"system\",content:e});msgs.push({role:\"user\",content:t});aiOnce(u,d.key,mod.id,msgs,aiTimeout()).then(function(f){aiLog({kind:\"问AI\",ok:f.ok,no:idx+1,pn:mod.pn,model:mod.mn,sys:e,q:t,a:f.ans||\"\",err:f.err||\"\",ms:f.ms||0});done++;if(f.ok){_aiConcC.push({pn:mod.pn,mn:mod.mn,ans:f.ans});if(!shown){shown=true;_aiBusy=0;_aiConcCur=mod.pn+\" \/ \"+mod.mn;_aiRaw=f.ans;r.className=\"aia\";aiType(r,aiMd(f.ans));tip(\"✔ 最快：\"+mod.pn+\" \/ \"+mod.mn+\" 已返回\",\"ok\")}buildConcPick()}if(done>=fired&&!shown){_aiBusy=0;r.className=\"aia err\";r.textContent=\"全部 \"+fired+\" 个模型请求都失败了。\"}}) };for(var k=0;k<fired;k++){fire(k)}},window.aiRunSeq=function a(t,e,n,i,o,r){if(i>=o||i>=n.length){_aiBusy=0,r.className=\"aia err\",r.textContent=\"已尝试 \"+Math.min(i,o)+\" 个模型，都失败了。\";return}var s=n[i],d=aiCfgs(),c=d[s.cfg]||d[0]||{},u=String(c.base||AIDEFBASE).replace(\/[\/]+$\/,\"\"),l=[];e&&l.push({role:\"system\",content:e}),l.push({role:\"user\",content:t}),r.className=\"aia wait\",r.textContent=\"[\"+(i+1)+\"\/\"+o+\"] \"+s.pn+\" \/ \"+s.mn+\" 请求中…\",aiOnce(u,c.key,s.id,l,aiTimeout()).then(function(f){if(aiLog({kind:\"问AI\",ok:f.ok,no:i+1,pn:s.pn,model:s.mn,sys:e,q:t,a:f.ans||\"\",err:f.err||\"\",ms:f.ms||0}),f.ok){_aiBusy=0,_aiRaw=f.ans,r.className=\"aia\",aiType(r,aiMd(f.ans)),i>0&&tip(\"✔ 1 号失败，已由序号 \"+(i+1)+\"（\"+s.mn+\"）返回\",\"ok\");return}a(t,e,n,i+1,o,r)})},window.aiSaveCfgs=function(t){try{jsave(KCFG,t)}catch(e){}},window.aiSaveEn=function(t){try{jsave(KEN,t)}catch(e){}},window.aiSavePool=function(t){try{jsave(KPOOL,t)}catch(e){}},window.aiSavePro=function(t){try{jsave(KPRO,t)}catch(e){}},window.aiSaveTmpPro=function(){var t=document.getElementById(\"aisys2\"),e=t?String(t.value||\"\").trim():\"\";if(!e){tip(\"✘ 提示词是空的\",\"no\");return}var n=prompt(\"给这个提示词起个名字\",\"我的提示词\");if(n!==null){var i=aiPro();i.push({n:String(n||\"\").trim()||\"我的提示词\",s:e}),aiSavePro(i),aiEchoAsk();var o=document.getElementById(\"aipro2\");o&&(o.value=String(i.length-1)),tip(\"✔ 已保存为提示词模板\",\"ok\")}},window.aiSelText=function(){try{var t=window.getSelection();return t?String(t.toString()||\"\").trim():\"\"}catch(e){return\"\"}},window.aiSend=function(){var t=document.getElementById(\"aiq\");if(t=t?String(t.value||\"\").trim():\"\",!t){tip(\"✘ 要说点什么吧\",\"no\");return}var e=aiCfg();if(!e.key){tip(\"✘ 还没填 API 密钥：外观设置 → AI 问答\",\"no\");return}var i=document.getElementById(\"aisys2\");i=i?String(i.value||\"\").trim():\"\",_aiSysTmp=i,_aiQ=t;var o=document.getElementById(\"aiedit\"),r=document.getElementById(\"aians\");o&&(o.style.display=\"none\"),r&&(r.style.display=\"\");var s=document.getElementById(\"aiqq\");s&&(s.textContent=t),aiRun(t,i)},window.aiSet=function(t,e){var n=aiCfgs(),i=aiIdx();n[i]&&(n[i][t]=e,aiSaveCfgs(n),tip(\"✔ 已保存\",\"ok\"),aiEcho())},window.aiSetAskModel=function(t){var e=document.getElementById(\"aimodel2\");e&&(e.value=String(t||\"\")),aiSet(\"model\",String(t||\"\"))},window.aiSetIdx=function(t){try{store(KCIDX,String(t))}catch(e){}},window.aiSetMode=function(t){var m=t===\"rr\"?\"rr\":(t===\"cc\"?\"cc\":\"single\");try{store(KMODE,m)}catch(e){}aiSyncModeUI(),tip(\"✔ 已切换为\"+(m===\"rr\"?\"轮流调用\":(m===\"cc\"?\"并发调用\":\"单一模型\")),\"ok\")},window.aiSetRR=function(t){var e=parseInt(t,10)||2;e<1&&(e=1),e>20&&(e=20);try{store(KRR,String(e))}catch(n){}tip(\"✔ 轮流数量 \"+e,\"ok\")},window.aiSetTO=function(t){var e=parseInt(t,10)||45;e<5&&(e=5),e>300&&(e=300);try{store(KTO,String(e))}catch(n){}tip(\"✔ 超时 \"+e+\" 秒\",\"ok\")},window.aiShowBtn=function(){if(ST.aiOn){var t=aiSelText();if(_aiBtn){if(t.length<2){_aiBtn.style.display=\"none\";return}try{var e=window.getSelection(),g=e.rangeCount?e.getRangeAt(0):null,i=document.documentElement.clientWidth||window.innerWidth||320,o=window.innerHeight||document.documentElement.clientHeight||480,r=_aiBtn.offsetWidth||72,s=_aiBtn.offsetHeight||32,d,c;try{var r0=document.createRange();r0.setStart(g.startContainer,g.startOffset);r0.collapse(true);var n=r0.getBoundingClientRect();d=n.left+8;c=n.bottom+36}catch(f){var n=e.getRangeAt(0).getBoundingClientRect();d=n.right+8;c=n.bottom+8}n.right+8+r>i&&(d=Math.max(4,i-r-8)),c+s>o&&(c=Math.max(4,n.top-s-8));try{var u=document.querySelector(\".fab\");if(u){var l=u.getBoundingClientRect();d<l.right+8&&d+r>l.left-8&&c<l.bottom+8&&c+s>l.top-8&&(c=Math.max(4,l.top-s-10))}}catch(f){}_aiBtn.style.left=Math.max(4,d)+\"px\",_aiBtn.style.top=c+\"px\"}catch(f){}_aiBtn.style.display=\"\"}}},window.aiSelToggle=function(u){var s=_aiSel,i=s.indexOf(u);i>=0?s.splice(i,1):s.push(u);aiRenderModels()},\nwindow.aiRenderOrder=function(){var e=aiPool(),n=aiEn(),i,o,r=[],s={};for(i=0;i<n.length;i++)for(o=0;o<e.length;o++)if(aiKeyOf(e[o])===n[i]){r.push(o),s[o]=1;break}for(o=0;o<e.length;o++)s[o]||r.push(o);return r},\nwindow.aiSelIdxInOrder=function(){var r=aiRenderOrder(),a=[],i;for(i=0;i<r.length;i++)if(_aiSel.indexOf(r[i])>=0)a.push(i);a.sort(function(x,y){return x-y});return a},\nwindow.aiReorder=function(nr){var e=aiPool(),n=aiEn(),i,key,ne=[],seen={};for(i=0;i<nr.length;i++){key=aiKeyOf(e[nr[i]]);if(n.indexOf(key)>=0)ne.push(key)}aiSaveEn(ne);var np=[];seen={};for(i=0;i<nr.length;i++){key=aiKeyOf(e[nr[i]]);if(!seen[key]){seen[key]=1;np.push(e[nr[i]])}}aiSavePool(np)},window.aiMoveUp=function(){var a=aiSelIdxInOrder();if(!a.length){tip(\"请先点选要上移的模型\",\"no\");return}var r=aiRenderOrder(),first=a[0];if(first<=0)return;var last=a[a.length-1],moved=r[first-1],nr=r.slice(0,first-1).concat(r.slice(first,last+1)).concat([moved]).concat(r.slice(last+1));aiReorder(nr),aiReselAfterMove(nr),aiRenderModels()},window.aiMoveDown=function(){var a=aiSelIdxInOrder();if(!a.length){tip(\"请先点选要下移的模型\",\"no\");return}var r=aiRenderOrder(),last=a[a.length-1];if(last>=r.length-1)return;var first=a[0],moved=r[last+1],nr=r.slice(0,first).concat([moved]).concat(r.slice(first,last+1)).concat(r.slice(last+2));aiReorder(nr),aiReselAfterMove(nr),aiRenderModels()},window.aiReselAfterMove=function(nr){for(var i=0;i<_aiSel.length;i++){var x=_aiSel[i];_aiSel[i]=x>=0&&x<nr.length?nr.indexOf(x):x}},\nwindow.aiDel=function(){var a=aiSelIdxInOrder();if(!a.length){tip(\"请先点选要删除的模型\",\"no\");return}if(!confirm(\"确定删除选中的模型吗？\"))return;var r=aiRenderOrder(),e=aiPool(),n=aiEn(),rm={},i,key,ne=[],np=[];for(i=0;i<a.length;i++){var pi=r[a[i]];rm[pi]=1}for(i=0;i<n.length;i++){key=aiKeyOf(e[i]);if(!rm[i]&&n.indexOf(key)>=0)ne.push(key)}var kept=[];for(i=0;i<e.length;i++){if(!rm[i])kept.push(e[i])}aiSaveEn(ne),aiSavePool(kept),_aiSel=[];aiRenderModels()},\nwindow.aiFoldToggle=function(){var b=document.getElementById(\"aifoldbody\"),m=document.getElementById(\"aimlist\"),k=document.getElementById(\"aimlistbtns\");if(!b)return;var on=b.style.display!==\"none\";b.style.display=on?\"none\":\"\";m&&(m.style.display=on?\"none\":\"\");k&&(k.style.display=on?\"none\":\"\");var btn=document.getElementById(\"aifoldbtn\");btn&&(btn.textContent=on?\"⚙ 展开设置\":\"⚙ 收起设置\")},\nwindow.aiShowPicker=function(list,cb){var ov=document.createElement(\"div\");ov.className=\"mpicker-overlay\";var html='<div class=\"mpicker\"><div class=\"mpicker-hd\">选择要添加的模型<\/div><div class=\"mpicker-list\">';for(var i=0;i<list.length;i++)html+='<label class=\"mpick\"><input type=\"checkbox\" value=\"'+esc(list[i])+'\"><span>'+esc(list[i])+'<\/span><\/label>';html+='<\/div><div class=\"mpicker-ft\"><button class=\"bt\" type=\"button\" id=\"mpickcancel\">取消<\/button><button class=\"bt pri\" type=\"button\" id=\"mpickok\">确认<\/button><\/div><\/div>';ov.innerHTML=html;document.body.appendChild(ov);function close(){ov.parentNode&&ov.parentNode.removeChild(ov)}ov.querySelector(\"#mpickcancel\").onclick=function(){close();cb([])};ov.querySelector(\"#mpickok\").onclick=function(){var sel=[],cks=ov.querySelectorAll(\"input[type=checkbox]:checked\");for(var k=0;k<cks.length;k++)sel.push(cks[k].value);close();cb(sel)}},window.aiSyncModeUI=function(){var t=aiMode(),e=document.getElementById(\"airrn2\"),l=null,p=e&&e.closest?e.closest(\"div\"):null;if(p){var lab=p.querySelector(\"label\");if(lab){try{while(lab.firstChild)lab.removeChild(lab.firstChild)}catch(x){}var span=document.createElement(\"span\");span.textContent=(t===\"cc\"?\"并发数量\":\"轮流数量\");lab.appendChild(span)}}e&&(e.disabled=(t!==\"rr\"&&t!==\"cc\"),e.style.opacity=(t!==\"rr\"&&t!==\"cc\")?\".45\":\"1\")},window.aiTest=function(){var t=aiEnList();if(!t.length){tip(\"✘ 没有启用的模型，先在列表里勾选\",\"no\");return}var e=document.getElementById(\"aitest\");if(!e)return;e.style.display=\"\",e.className=\"aitest wait\",e.textContent=\"测试中…\";var n=document.getElementById(\"aiq\"),i=n?String(n.value||\"\").trim():\"\";i||(i=\"只回复：OK\");var o=document.getElementById(\"aisys2\"),r=o?String(o.value||\"\").trim():\"\",s=[];r&&s.push({role:\"system\",content:r}),s.push({role:\"user\",content:i});var d=[],c=0,u=0;function l(){if(c>=t.length){e.className=\"aitest \"+(u===t.length?\"err\":\"ok\"),e.textContent=d.join(`\n`),tip(\"✔ 测试完成：\"+(t.length-u)+\"\/\"+t.length+\" 个成功\",\"ok\");return}var f=t[c],m=c+1,g=aiCfgs(),h=g[f.cfg]||g[0]||{},w=String(h.base||AIDEFBASE).replace(\/[\/]+$\/,\"\");e.className=\"aitest wait\",e.textContent=d.join(`\n`)+(d.length?`\n`:\"\")+\"[\"+m+\"\/\"+t.length+\"] \"+f.pn+\" \/ \"+f.mn+\" 测试中…\",aiOnce(w,h.key,f.id,s,aiTimeout()).then(function(v){aiLog({kind:\"测试\",ok:v.ok,name:\"#\"+m+\" \"+f.pn+\" \/ \"+f.mn,pn:f.pn,model:f.mn,ms:v.ms||0,err:v.err||\"\",a:v.ans||\"\",q:i,sys:r}),v.ok||u++,d.push(\"[\"+m+\"] \"+(v.ok?\"成功  延迟 \"+v.ms+\"ms\":\"失败  \"+String(v.err||\"\")+\"  (\"+(v.ms||0)+\"ms)\")+\"  \"+f.pn+\" \/ \"+f.mn+(v.ok&&v.ans?`\n     答: `+String(v.ans).slice(0,50):\"\")),c++,l()})}l()},window.aiTestClear=function(){var t=document.getElementById(\"aitest\");t&&(t.style.display=\"none\",t.textContent=\"\");try{jsave(KAIL,[])}catch(e){}};var _aiBtn=null,_aiT=0,_aiTimer=0,_aiQ=\"\",_aiRaw=\"\",_aiBusy=0,_aiSysTmp=\"\";window.aiTimeout=function(){var t=45;try{t=parseInt(load(KTO)||\"45\",10)||45}catch(e){t=45}return t<5&&(t=5),t>300&&(t=300),t*1e3},window.aiToggleEn=function(t){var e=aiPool();if(e[t]){var n=aiKeyOf(e[t]),i=aiEn(),o=i.indexOf(n);o>=0?i.splice(o,1):i.push(n),aiSaveEn(i),aiRenderModels(),tip(o>=0?\"已取消勾选\":\"已勾选，序号 \"+i.length,\"ok\")}},window.aiTs=function(t){try{var e=new Date(t),n=function(i){return(i<10?\"0\":\"\")+i};return n(e.getMonth()+1)+\"-\"+n(e.getDate())+\" \"+n(e.getHours())+\":\"+n(e.getMinutes())+\":\"+n(e.getSeconds())}catch(i){return\"\"}},window.aiType=function(t,e){var n=document.createElement(\"div\");n.innerHTML=e;var i=n.textContent||\"\";t.textContent=\"\";var o=0,r=Math.max(1,Math.ceil(i.length\/200));try{_aiTimer&&clearInterval(_aiTimer)}catch(s){}_aiTimer=setInterval(function(){o+=r,t.textContent=i.slice(0,o),o>=i.length&&(clearInterval(_aiTimer),_aiTimer=0,t.innerHTML=e)},16)},window.aiViewLog=function(){alert(aiLogText())},\/\/ BUGFIX 2026-09：详情页外观面板专用桥接函数。\n\/\/ 必须使用 window.detailBuildPanel，避免与启动页 startJs 的 buildPanel() 全局同名冲突。\nwindow.detailBuildPanel=function(){var t=\"<h3>🎨 外观设置<\/h3>\";return t+=sec(\"p1\",\"背景图片\",!1),t+='<div id=\"pbg\"><\/div>',t+='<div class=\"srow\"><label>保存到分类<\/label><select id=\"bcat\">'+catOpts(BGC)+\"<\/select><\/div>\",t+='<input type=\"text\" id=\"bi\" placeholder=\"图片网址 或 \/sdcard\/Pictures\/bg.jpg\">',t+='<div class=\"row\"><button class=\"bt\" onclick=\"addBG()\">保存并应用<\/button><button class=\"bt\" onclick=\"clearBG()\">清除背景<\/button><\/div>',t+='<div class=\"row\"><button class=\"bt\" onclick=\"wnUp(\\'bg\\')\">上传到背景图片云<\/button><button class=\"bt\" onclick=\"wnDown(\\'bg\\')\">从背景图片云下载<\/button><\/div>',t+=selrow(\"显示模式\",\"sbgFitO\",[[\"cover\",\"填充裁切\"],[\"contain\",\"完整显示\"],[\"fill\",\"拉伸\"]],\"upd('bgFit',this.value);applyBG()\"),t+=endsec(),t+=sec(\"p2\",\"头像外框\",!1),t+=`<div class=\"row\" style=\"margin-bottom:4px\"><button class=\"msw\" id=\"m1\" onclick=\"setFMode('under')\">衬于头像下方<\/button><button class=\"msw\" id=\"m2\" onclick=\"setFMode('over')\">浮于头像上方<\/button><\/div>`,t+='<div id=\"pfr\"><\/div>',t+='<div class=\"srow\"><label>保存到分类<\/label><select id=\"fcat\">'+catOpts(FRC)+\"<\/select><\/div>\",t+='<input type=\"text\" id=\"fi\" placeholder=\"外框网址（建议正方形透明 PNG）\">',t+='<div class=\"row\"><button class=\"bt\" onclick=\"addFrame()\">保存并应用<\/button><button class=\"bt\" onclick=\"clearFrame()\">清除外框<\/button><\/div>',t+='<div class=\"row\"><button class=\"bt\" onclick=\"wnUp(\\'fr\\')\">上传到头像框云<\/button><button class=\"bt\" onclick=\"wnDown(\\'fr\\')\">从头像框云下载<\/button><\/div>',t+='<div class=\"row\"><button class=\"bt\" onclick=\"frDecOpen()\">🎨 外框去底色<\/button>'+(FRDEC?'<button class=\"bt warn\" onclick=\"frDecClear()\">↺ 还原原图<\/button>':\"\")+\"<\/div>\",t+='<div class=\"hint\">JPG 外框常带纯色背景，套在头像上会挡住头像。去底色只处理<b>外框图<\/b>，结果对所有楼层头像生效并存在本机。<\/div>',t+=\"<h4>外框裁切与缩放<\/h4>\",t+=selrow(\"裁切模式\",\"sfrFitO\",[[\"contain\",\"完整显示\"],[\"cover\",\"填充裁切\"],[\"manual\",\"手动缩放（默认）\"]],\"upd('frFit',this.value);frFitUI()\"),t+=rrow(\"外框图缩放 %\",\"sfrZoom\",20,400,5,\"wfrZoom\"),t+=rrow(\"焦点X %\",\"sfrBX\",0,100,1,\"wfrBX\"),t+=rrow(\"焦点Y %\",\"sfrBY\",0,100,1,\"wfrBY\"),t+='<div class=\"hint\">选「手动缩放」才会出现下面三个滑块：缩放决定外框图在<b>大小固定<\/b>的遮罩容器里的放大倍数，焦点 X \/ Y 决定放大后显示它的哪个部位；<b>容器尺寸始终不变<\/b>，超出部分自动裁掉。<br>注意：这三个滑块只改变外框图<b>内部<\/b>的显示范围；「头像 \/ 外框 对位」分区里的「外框放大 \/ 左右 \/ 上下」移动的是<b>整个外框图层<\/b>，两者互不干扰。<\/div>',t+=\"<h4>外框遮罩形状<\/h4>\",t+='<div class=\"row\" style=\"margin-bottom:2px\"><button class=\"msw\" id=\"fmk1\" onclick=\"setFMask(1)\">圆形<\/button><button class=\"msw\" id=\"fmk0\" onclick=\"setFMask(0)\">方形<\/button><\/div>',t+=rrow(\"遮罩圆角(0~50)\",\"sfrMask\",0,50,1),t+='<div class=\"hint\">图层遮罩限制外框图层的可见形状（类似 PS 图层蒙版）。<br>· 圆形：遮罩成圆形，贴合圆形头像，适合纯色\/满铺的外框图。<br>· 方形：完整保留原图，适合中间透明的 PNG —— 透明部分会自然形成任意形状（花瓣、星星、边框等），此时方形遮罩才能完整显示它的设计。<\/div>',t+=endsec(),t+=sec(\"p3\",\"头像 \/ 外框 对位\",!1),t+=rrow(\"头像放大 %\",\"savScale\",50,200,5),t+=rrow(\"头像 左右\",\"savFx\",-20,20,1),t+=rrow(\"头像 上下\",\"savFy\",-20,20,1),t+=rrow(\"外框放大 %\",\"sfrScale\",50,200,5),t+=rrow(\"外框 左右\",\"sfrFx\",-20,20,1),t+=rrow(\"外框 上下\",\"sfrFy\",-20,20,1),t+=\"<h4>头像遮罩形状<\/h4>\",t+='<div class=\"row\" style=\"margin-bottom:2px\"><button class=\"msw\" id=\"amk1\" onclick=\"setAMask(1)\">圆形<\/button><button class=\"msw\" id=\"amk0\" onclick=\"setAMask(0)\">方形<\/button><\/div>',t+=rrow(\"遮罩圆角(0~50)\",\"savMask\",0,50,1),t+=endsec(),t+=sec(\"p4\",\"图片样式\",!1),t+='<div class=\"hint\">「单图宽度」决定一行显示几列：50%→2列，33%→3列，25%→4列，100%→单列大图。<\/div>',t+=rrow(\"单图宽度 %\",\"simgw\",20,100,1),t+=rrow(\"图片高度 px\",\"simgh\",60,400,10),t+=selrow(\"裁切模式\",\"simgfitO\",[[\"contain\",\"完整显示\"],[\"cover\",\"填充裁切\"],[\"fill\",\"拉伸\"]],\"upd('imgfit',this.value)\"),t+=rrow(\"焦点X %\",\"simgfx\",0,100,1),t+=rrow(\"焦点Y %\",\"simgfy\",0,100,1),t+=rrow(\"圆角\",\"simgrd\",0,24,1),t+=rrow(\"间距\",\"simggap\",0,20,1),t+='<div class=\"row\" style=\"margin-bottom:4px\"><button class=\"msw'+(ST.imgLazy?\"\":\" on\")+'\" id=\"ilz0\" onclick=\"setImgLazy(0)\">立即加载<\/button><button class=\"msw'+(ST.imgLazy?\" on\":\"\")+'\" id=\"ilz1\" onclick=\"setImgLazy(1)\">滚动加载<\/button><\/div>',t+='<div class=\"hint\">默认「滚动加载」：图片滚到附近才加载，省流量、首屏快。<br>若某些阅读 App 里正文图片<b>完全不显示<\/b>（老 WebView 不触发懒加载），改成「立即加载」即可。<\/div>',t+=endsec(),t+=sec(\"p5\",\"正文框 \/ 楼层框 边框与阴影\",!1),t+=rrow(\"正文框 边框\",\"spostBdW\",0,8,1),t+=crow(\"　颜色\",\"spostBdC\"),t+=rrow(\"正文框 阴影\",\"spostSh\",0,12,1),t+=crow(\"　阴影色\",\"spostShC\"),t+=rrow(\"楼层框 边框\",\"sreplyBdW\",0,8,1),t+=crow(\"　颜色\",\"sreplyBdC\"),t+=rrow(\"楼层框 阴影\",\"sreplySh\",0,12,1),t+=crow(\"　阴影色\",\"sreplyShC\"),t+=rrow(\"卡片圆角\",\"srd\",0,26,1),t+=endsec(),t+=sec(\"p6\",\"底色与文字\",!1),t+=crow(\"正文框底色\",\"spostBg\"),t+=rrow(\"　不透明度\",\"spostA\",0,100,1),t+=crow(\"正文字色\",\"spostTx\"),t+=crow(\"楼层框底色\",\"sreplyBg\"),t+=rrow(\"　不透明度\",\"sreplyA\",0,100,1),t+=crow(\"楼层字色\",\"sreplyTx\"),t+=crow(\"元信息色\",\"smetaTx\"),t+=rrow(\"正文字·阴影\",\"spostTxSh\",0,12,1),t+=crow(\"　阴影色\",\"spostTxShC\"),t+=rrow(\"楼层字·阴影\",\"sreplyTxSh\",0,12,1),t+=crow(\"　阴影色\",\"sreplyTxShC\"),t+='<div class=\"hint\">「正文\/楼层字·阴影」作用于帖子正文与楼层回复的文字本身（提升可读性），与「正文框 \/ 楼层框 边框与阴影」分区里的卡片外阴影是两回事。<\/div>',t+='<div class=\"hint\">元信息色：沙发\/时间\/观看数\/回复数\/全部回复\/分页 等字段。<\/div>',t+=rrow(\"楼层间距\",\"sgap\",0,30,1),t+=rrow(\"标题·字号\",\"sttFs\",14,30,1),t+=rrow(\"标题·字重\",\"sttFw\",300,900,100),t+=rrow(\"标题·行高\",\"sttLh\",120,220,5),t+=rrow(\"标题·字间距\",\"sttLs\",0,4,.5),t+='<div class=\"hint\">标题·字号\/字重\/行高\/字间距：帖子大标题的字体独立控制，不再跟随正文。<\/div>',t+=rrow(\"字号\",\"sfs\",12,22,1),t+=rrow(\"行高\",\"slh\",120,220,5),t+=rrow(\"字重\",\"sfw\",300,700,100),t+=rrow(\"字间距\",\"sls\",0,4,.5),t+=endsec(),t+=sec(\"p10\",\"引用框（楼层内嵌套）\",!1),t+=crow(\"底色\",\"sqBg\"),t+=rrow(\"　不透明度\",\"sqA\",0,100,1),t+=crow(\"文字色\",\"sqTx\"),t+=rrow(\"边框\",\"sqBdW\",0,8,1),t+=crow(\"　边框色\",\"sqBdC\"),t+=rrow(\"圆角\",\"sqRd\",0,20,1),t+=rrow(\"字号\",\"sqFs\",10,20,1),t+=rrow(\"行高\",\"sqLh\",120,220,5),t+=rrow(\"内边距\",\"sqPad\",0,24,1),t+=rrow(\"文字·阴影\",\"sqSh\",0,12,1),t+=crow(\"　阴影色\",\"sqShC\"),t+='<div class=\"hint\">引用文字的字号\/颜色现已对全部引用生效：论坛引用里的 &lt;font color\/size&gt; 表现属性会被强制覆盖，因此引用自楼主或任意楼层用户的文本都统一受上面几项控制。<\/div>',t+=endsec(),t+=sec(\"p11\",\"标题、正文、引用、回复\",!1),t+=rrow(\"标题→正文\",\"sttgap\",0,40,1),t+=rrow(\"楼层 上\",\"srpt\",0,32,1),t+=rrow(\"楼层 下\",\"srpb\",0,32,1),t+=rrow(\"楼层 左\",\"srpl\",0,32,1),t+=rrow(\"楼层 右\",\"srpr\",0,32,1),t+=rrow(\"沙发→下方\",\"shdgap\",0,40,1),t+=rrow(\"引用→沙发\",\"sqgapt\",0,40,1),t+=rrow(\"引用→正文\",\"sqgapb\",0,40,1),t+=rrow(\"正文→上方\",\"smsggapt\",0,40,1),t+='<div class=\"hint\">标题→正文：帖子大标题到正文的距离。<br>楼层 上\/下\/左\/右：文本块整体到楼层框四边的距离。<br>后四项为楼层内三类文本（沙发信息 \/ 引用 \/ 回复内容）之间的独立间距。<\/div>',t+=endsec(),t+=sec(\"p7\",\"按钮样式\",!1),t+=crow(\"按钮底色\",\"sbtnBg\"),t+=rrow(\"　不透明度\",\"sbtnA\",0,100,1),t+=crow(\"按钮字色\",\"sbtnTx\"),t+=rrow(\"边框粗细\",\"sbtnBdW\",0,8,1),t+=crow(\"　边框色\",\"sbtnBdC\"),t+=rrow(\"阴影\",\"sbtnSh\",0,12,1),t+=crow(\"　阴影色\",\"sbtnShC\"),t+=rrow(\"圆角\",\"sbtnRd\",0,24,1),t+=rrow(\"字号\",\"sbtnFs\",10,20,1),t+=rrow(\"大小\",\"sbtnPad\",4,20,1),t+=endsec(),t+=sec(\"p8\",\"按钮文字 \/ 图案\",!1),t+=trow(\"收藏\",\"sbtnLfav\",\"⭐ 收藏\"),t+=trow(\"点评\",\"sbtnLcmt\",\"💬 点评\"),t+=trow(\"回复\",\"sbtnLrep\",\"✏️ 回复\"),t+=trow(\"倒序\",\"sbtnLord\",\"🔃 倒序\"),t+=trow(\"正序\",\"sbtnLasc\",\"🔄 正序\"),t+=trow(\"只看楼主\",\"sbtnLop\",\"👤 只看楼主\"),t+=trow(\"重载\",\"sbtnLrl\",\"🔄 重载\"),t+=trow(\"发送\",\"sbtnLsend\",\"发送\"),t+=endsec(),t+=sec(\"p12\",\"设置弹窗外观\",!1),t+='<div class=\"hint\">以下各项只影响「设置弹窗」自身的外观，不影响帖子内容。<\/div>',t+=crow(\"弹窗·底色\",\"smBg\"),t+=rrow(\"弹窗·不透明度\",\"smA\",0,100,1),t+=crow(\"弹窗·文字色\",\"smTx\"),t+=crow(\"折叠分区·标题底色\",\"ssechBg\"),t+=rrow(\"折叠分区·标题不透明度\",\"ssechA\",0,100,1),t+='<div class=\"hint\">折叠分区标题 = 本弹窗中每个折叠项的标题条（如「背景图片」「图片样式」）。<br>半透明时会透出下方弹窗底色，建议把弹窗底色调深色更容易看出效果。<\/div>',t+=crow(\"预设分类·标题底色\",\"scatBg\"),t+=rrow(\"预设分类·标题不透明度\",\"scatA\",0,100,1),t+='<div class=\"hint\">预设分类标题 = 背景\/头像框预设列表里，每个分类（如「默认」）的标题条。<\/div>',t+=crow(\"滑块文字·颜色\",\"slbTx\"),t+='<div class=\"hint\">滑块文字 = 本面板所有设置项左侧的标签文字（如「弹窗·底色」）。<\/div>',t+=crow(\"标题文字·颜色\",\"shdTx\"),t+='<div class=\"hint\">标题文字 = 两类标题的字体颜色，由本项统一控制：<br>① 折叠分区标题（如「背景图片」「图片样式」）<br>② 预设分类标题（背景\/头像框列表中的「默认」等）<\/div>',t+=\"<h4>参数说明文字<\/h4>\",t+=rrow(\"字号\",\"shintFs\",8,20,1),t+=crow(\"颜色\",\"shintTx\"),t+=rrow(\"行高\",\"shintLh\",120,220,5),t+=rrow(\"字间距\",\"shintLs\",-2,8,.5),t+=rrow(\"阴影\",\"shintSh\",0,12,1),t+=crow(\"　阴影色\",\"shintShC\"),t+='<div class=\"hint\">参数说明文字 = 各类弹窗（外观设置、图片上传、图片网址等）内灰色的补充说明文本，由以上六项统一控制其字号、颜色、行高、字距与阴影。<\/div>',t+=endsec(),t+=sec(\"p13\",\"底部回复框\",!1),t+=crow(\"框底色\",\"sdBg\"),t+=rrow(\"　不透明度\",\"sdA\",0,100,1),t+=rrow(\"上边框\",\"sdBdW\",0,8,1),t+=crow(\"　边框色\",\"sdBdC\"),t+=rrow(\"圆角\",\"sdRd\",0,20,1),t+=endsec(),t+=sec(\"p14\",\"底部分页栏\",!1),t+='<div class=\"hint\">控制帖子底部的「‹ 上一页 \/ 第 N 页 \/ 下一页 ›」三个按钮，以及点中间页码弹出的选择框里的页码格子。与工具栏按钮（倒序\/只看楼主\/重载）互不干扰。<\/div>',t+=crow(\"底色\",\"spgBg\"),t+=rrow(\"　不透明度\",\"spgA\",0,100,1),t+=crow(\"文字色\",\"spgTx\"),t+=rrow(\"边框粗细\",\"spgBdW\",0,8,1),t+=crow(\"　边框色\",\"spgBdC\"),t+=rrow(\"圆角\",\"spgRd\",0,20,1),t+=rrow(\"字号\",\"spgFs\",10,20,1),t+=\"<h4>当前页码高亮<\/h4>\",t+=crow(\"底色\",\"spgOnBg\"),t+=crow(\"文字色\",\"spgOnTx\"),t+=endsec(),t+=sec(\"p9\",\"编辑按钮\",!1),t+=crow(\"底色\",\"sedBg\"),t+=rrow(\"　不透明度\",\"sedA\",0,100,1),t+=crow(\"文字色\",\"sedTx\"),t+=rrow(\"边框\",\"sedBdW\",0,8,1),t+=crow(\"　边框色\",\"sedBdC\"),t+=rrow(\"圆角\",\"sedRd\",0,20,1),t+=rrow(\"字号\",\"sedFs\",10,20,1),t+='<div class=\"hint\">「编辑」只会在你自己的主题帖与回复上出现（依据页面 discuz_uid 判定）。<\/div>',t+=endsec(),t+=sec(\"p16\",\"悬浮设置按钮\",!1),t+='<div class=\"hint\">长按该按钮约 0.6 秒可进入拖动模式，拖到合适位置松手即自动保存位置。<\/div>',t+='<div class=\"row\" style=\"margin-bottom:6px\"><button class=\"msw\" id=\"sh1\" onclick=\"setShape(1)\">圆形<\/button><button class=\"msw\" id=\"sh0\" onclick=\"setShape(0)\">方形<\/button><\/div>',t+=rrow(\"圆角(50=正圆)\",\"sfabRd\",0,50,1),t+=rrow(\"按钮大小\",\"sfabSz\",32,72,2),t+=\"<h4>按钮背景图<\/h4>\",t+='<div class=\"fprev\"><span>预览<\/span><div id=\"fabPrev\"><b id=\"fabPrevEmo\"><\/b><\/div><\/div>',t+='<div id=\"fabiList\"><\/div>',t+='<input type=\"text\" id=\"fabin\" placeholder=\"图片网址（支持动图）或 \/sdcard\/xx.gif\">',t+='<div class=\"row\"><button class=\"bt\" onclick=\"addFabBi()\">保存并应用<\/button><button class=\"bt\" onclick=\"clearFabBi()\">清除背景图<\/button><\/div>',t+=crow(\"背景底色\",\"sfabBg\"),t+=selrow(\"裁切模式\",\"sfabFitO\",[[\"manual\",\"手动缩放\"],[\"cover\",\"填充裁切\"],[\"contain\",\"完整显示\"]],\"upd('fabFit',this.value)\"),t+=rrow(\"缩放 %\",\"sfabScale\",100,500,10),t+=rrow(\"焦点 X %\",\"sfabBX\",0,100,1),t+=rrow(\"焦点 Y %\",\"sfabBY\",0,100,1),t+='<div class=\"hint\">只有「手动缩放」模式下支持焦点移动与缩放滑块。动图链接会自动播放。<\/div>',t+=trow(\"图标文字\",\"sfabEmo\",\"留空 = 纯图按钮（默认 🎨）\"),t+=\"<h4>边框 \/ 阴影 \/ 位置<\/h4>\",t+=rrow(\"边框粗细\",\"sfabBdW\",0,8,1),t+=crow(\"　边框色\",\"sfabBdC\"),t+=rrow(\"阴影大小\",\"sfabSh\",0,20,1),t+=crow(\"　阴影色\",\"sfabShC\"),t+=rrow(\"位置·距右\",\"sfabX\",0,320,1),t+=rrow(\"位置·距底\",\"sfabY\",0,640,1),t+=endsec(),t+=sec(\"p17\",\"用户名字体样式\",!1),t+='<div class=\"hint\">用户名（楼主名 \/ 楼层作者名）的字体独立设置，不再跟随正文。<br>彩虹渐变需开启开关，多色用英文逗号分隔，支持任意多层次。<\/div>',t+=\"<h4>帖子正文的用户名<\/h4>\",t+='<div class=\"row\" style=\"margin-bottom:4px\"><button class=\"msw\" id=\"oi0\" onclick=\"setOpnIt(0)\">正常<\/button><button class=\"msw\" id=\"oi1\" onclick=\"setOpnIt(1)\">斜体<\/button><\/div>',t+=rrow(\"字号\",\"sopnFs\",10,26,1),t+=rrow(\"字重\",\"sopnFw\",300,900,100),t+=crow(\"颜色\",\"sopnTx\"),t+=rrow(\"阴影\",\"sopnSh\",0,12,1),t+=crow(\"　阴影色\",\"sopnShC\"),t+='<div class=\"row\" style=\"margin:6px 0 2px\"><button class=\"msw\" id=\"or0\" onclick=\"setOpnRb(0)\">纯色<\/button><button class=\"msw\" id=\"or1\" onclick=\"setOpnRb(1)\">彩虹渐变<\/button><\/div>',t+=trow(\"彩虹色(逗号分隔)\",\"sopnRbC\",\"#FF6B9D,#7C6BD9,#22A7C2\"),t+=rrow(\"渐变角度\",\"sopnRbD\",0,360,5),t+=\"<h4>回复楼层的用户名<\/h4>\",t+='<div class=\"row\" style=\"margin-bottom:4px\"><button class=\"msw\" id=\"ri0\" onclick=\"setRnIt(0)\">正常<\/button><button class=\"msw\" id=\"ri1\" onclick=\"setRnIt(1)\">斜体<\/button><\/div>',t+=rrow(\"字号\",\"srnFs\",10,26,1),t+=rrow(\"字重\",\"srnFw\",300,900,100),t+=crow(\"颜色\",\"srnTx\"),t+=rrow(\"阴影\",\"srnSh\",0,12,1),t+=crow(\"　阴影色\",\"srnShC\"),t+='<div class=\"row\" style=\"margin:6px 0 2px\"><button class=\"msw\" id=\"rr0\" onclick=\"setRnRb(0)\">纯色<\/button><button class=\"msw\" id=\"rr1\" onclick=\"setRnRb(1)\">彩虹渐变<\/button><\/div>',t+=trow(\"彩虹色(逗号分隔)\",\"srnRbC\",\"#FF6B9D,#7C6BD9,#22A7C2\"),t+=rrow(\"渐变角度\",\"srnRbD\",0,360,5),t+=endsec(),t+=sec(\"p18\",\"点评框（楼层内的点评）\",!1),t+='<div class=\"hint\">楼层正文下方的「点评」区块。底色与边框作用于整个点评框，点评者名 \/ 时间 \/ 点评内容三段文字各有独立字号与颜色。<\/div>',t+=\"<h4>点评框<\/h4>\",t+=crow(\"底色\",\"scmtBg\"),t+=rrow(\"　不透明度\",\"scmtA\",0,100,1),t+=rrow(\"边框\",\"scmtBdW\",0,8,1),t+=crow(\"　边框色\",\"scmtBdC\"),t+=rrow(\"圆角\",\"scmtRd\",0,24,1),t+=rrow(\"内边距\",\"scmtPad\",0,24,1),t+=rrow(\"上方间距\",\"scmtGap\",0,24,1),t+=rrow(\"阴影\",\"scmtSh\",0,12,1),t+=crow(\"　阴影色\",\"scmtShC\"),t+=rrow(\"框内基准字号\",\"scmtFs\",8,22,1),t+=rrow(\"框内行高 %\",\"scmtLh\",100,220,5),t+=crow(\"框内文字色\",\"scmtTx\"),t+=\"<h4>点评者名（🌸 之后）<\/h4>\",t+=crow(\"颜色\",\"scmtNTx\"),t+=\"<h4>点评时间<\/h4>\",t+=crow(\"颜色\",\"scmtTTx\"),t+=\"<h4>点评内容<\/h4>\",t+=crow(\"颜色\",\"scmtCTx\"),t+=rrow(\"字号\",\"scmtCFs\",8,24,1),t+=rrow(\"行高 %\",\"scmtCLh\",100,220,5),t+=endsec(),t+=sec(\"p19\",\"头像旁元素 XY 坐标\",!1),t+='<div class=\"hint\">把「用户名 \/ 时间 \/ 沙发等楼层号 \/ 观看数 \/ 回复数」相对所在容器挪位：横向 ±120、纵向 ±80；横 \/ 纵各占一行，滑块更长、更好对准。<br>位移用 transform，<b>原位置仍会占位<\/b>，所以下面的正文不会被顶动。<br>注意：卡片开了长列表性能优化（content-visibility），挪到卡片边界外的部分会被裁掉，这是预期行为。<\/div>',t+=xyrow(\"用户名\",\"un\"),t+=xyrow(\"时间\",\"tm\"),t+=xyrow(\"楼层号（沙发类）\",\"fl\"),t+=xyrow(\"观看数\",\"vw\"),t+=xyrow(\"回复数\",\"rp\"),t+=endsec(),t+=sec(\"p20\",\"首屏性能（楼层分批渲染）\",!1),t+='<div class=\"hint\">实测 150 楼的帖子：JS 拼接只要 1ms，真正的大头是浏览器要一次性构建约 2000 个 DOM 节点。<br>开启分批后，首屏只渲染前 N 楼（节点降至约 10%），剩余楼层滚动到接近底部时自动补上（每次补 60 楼）。<br>★ 与已有的 content-visibility 是<b>互补<\/b>的：后者只跳过屏幕外的布局\/绘制，跳不过 DOM 构建。<br>设为 <b>0<\/b> 则恢复「一次渲染全部」（旧行为，首屏较慢但滚动不会有任何停顿）。<\/div>',t+=rrow(\"首屏楼层数（0=不分批）\",\"sfirstN\",0,60,1),t+=`<div class=\"row\"><button class=\"bt\" onclick=\"upd('firstN',0);sv('sfirstN',0);setV('sfirstN',0);tip('已设为不分批，下次加载生效')\">恢复不分批<\/button><button class=\"bt\" onclick=\"upd('firstN',12);sv('sfirstN',12);setV('sfirstN',12);tip('已设为首屏 12 楼')\">默认 12 楼<\/button><\/div>`,t+=\"<h4>批量<\/h4>\",t+='<div class=\"row\"><button class=\"bt\" onclick=\"resetXY()\">全部复位到 (0,0)<\/button><\/div>',t+=endsec(),t+=sec(\"p15\",\"配置备份 \/ 恢复\",!1),t+='<div class=\"hint\">把全部自定义（颜色、间距、背景、头像框、分类）导出成文本保存；换机或缓存被清理后粘贴回来即可一键还原。<\/div>',t+='<div class=\"row\"><button class=\"bt\" onclick=\"exportCfg()\">📤 导出配置<\/button><button class=\"bt\" onclick=\"importCfgPanel()\">📥 导入配置<\/button><\/div>',t+='<div class=\"row\"><button class=\"bt\" onclick=\"saveCfgLocal()\">💾 存本机备份<\/button><button class=\"bt\" onclick=\"loadCfgLocal()\">📂 读本机备份<\/button><\/div>',t+='<div class=\"row\"><button class=\"bt\" onclick=\"darkPreset()\">🌙 深色配色<\/button><button class=\"bt\" onclick=\"lightPreset()\">☀️ 浅色默认<\/button><\/div>',t+='<h4 style=\"margin-top:14px\">我的配置方案<\/h4>',t+='<div class=\"hint\">把当前全部外观配置保存为命名方案，可一键切换、重命名或删除；「深色配色 \/ 浅色默认」为内置预设。<\/div>',t+='<div class=\"catadd\"><input type=\"text\" id=\"profName\" placeholder=\"方案名称，如：护眼绿\"><\/div>',t+='<div class=\"row\"><button class=\"bt\" onclick=\"cancelRen()\">✖ 取消<\/button><button class=\"bt pri\" id=\"profBtn\" onclick=\"saveProfile()\">💾 保存方案<\/button><\/div>',t+='<div id=\"profList\"><\/div>',t+=endsec(),t+=sec(\"pAI\",\"AI 问答\",!1),t+='<div class=\"hint ck\" onclick=\"aiHintT(this)\">📌 免费模型怎么配置更稳？（点开）<div class=\"ckb\" style=\"display:none;font-size:12px\">为了减少免费模型的延迟高出错率高的问题，可在外观设置按钮打开ai问答设置，点新建，再点击申请免费密钥（来自站点<b>https:\/\/platform.aitools.cfd\/<\/b>）简单命个序号名，然后就会自动保存新配置。<br>同一IP过一个小时又能申请一个免费密钥，WIFI和移动数据IP是不同的，所以一个小时能申请2个免费密钥。回到问ai面板，选新配置，点击拉取，选择一个就够了，因为一个key每3-5秒只能请求1次，再选新申请密钥的配置，又拉取一个，循环。然后你就能有足够多并发模式可用的免费模型了，然后并发模式下哪个请求快就显示哪个结果。<br>为了更好的体验，还是建议去智谱、硅基流动、agens等平台，都有免费版模型，登录注册一个apikey，在外观设置按钮中ai问答设置里添加新配置填入正确的baseurl和key即可，不会注册和填写就问豆包元宝ds<\/div><\/div>',t+=`<div class=\"srow\"><label>开关<\/label><span class=\"dec-sw\"><button class=\"msw\" id=\"ai0\" onclick=\"upd('aiOn',0)\">关<\/button><button class=\"msw\" id=\"ai1\" onclick=\"upd('aiOn',1)\">开<\/button><\/span><\/div>`,t+='<div class=\"srow\"><label>配置<\/label><select id=\"aicfg\" onchange=\"aiPickCfg(this.value)\"><\/select><\/div>',t+='<div class=\"row\"><button class=\"bt\" onclick=\"aiAddCfg()\">＋ 新建<\/button><button class=\"bt\" onclick=\"aiDupCfg()\">复制<\/button><button class=\"bt warn\" onclick=\"aiDelCfg()\">删除<\/button><\/div>',t+=`<div class=\"srow\"><label>名称<\/label><input type=\"text\" id=\"ainame\" onchange=\"aiSet('n',this.value)\"><\/div>`,t+=`<div class=\"srow\"><label>Base<\/label><input type=\"text\" id=\"aibase\" placeholder=\"https:\/\/...\/v1\" onchange=\"aiSet('base',this.value)\"><\/div>`,t+=`<div class=\"srow\"><label>密钥<\/label><input type=\"text\" id=\"aikey\" placeholder=\"sk-...\" onchange=\"aiSet('key',this.value)\"><\/div>`,t+='<div class=\"row\"><button class=\"bt\" onclick=\"aiGenKey()\">↻ 申请免费密钥<\/button><button class=\"bt\" onclick=\"aiFetchModels()\">拉取模型<\/button><\/div>',t+=`<div class=\"srow\"><label>模型<\/label><input type=\"text\" id=\"aimodel\" placeholder=\"模型 ID，可手填\" onchange=\"aiSet('model',this.value)\"><\/div>`,t+=`<select id=\"aimpick\" onchange=\"aiSet('model',this.value)\"><\/select>`,t+=`<div class=\"srow\"><label>自动续期<\/label><span class=\"dec-sw\"><button class=\"msw\" id=\"aiauto0\" onclick=\"aiSet('auto',0)\">关<\/button><button class=\"msw\" id=\"aiauto1\" onclick=\"aiSet('auto',1)\">开<\/button><\/span><\/div>`,t+='<div class=\"hint\">密钥失效（401）时自动去免费站申请新密钥并覆盖。该站每小时限申请 1 个，且实测密钥约 1 小时过期，开着更省心。<\/div>',t+='<div class=\"srow\"><label>提示词<\/label><select id=\"aipro\" onchange=\"aiPickPro(this.value)\"><\/select><\/div>',t+=`<textarea id=\"aisys\" rows=\"4\" placeholder=\"系统提示词（选中文字会作为用户消息一起发送）\" onchange=\"aiSet('sys',this.value)\"><\/textarea>`,t+='<div class=\"row\"><button class=\"bt\" onclick=\"aiAddPro()\">＋ 存为模板<\/button><button class=\"bt warn\" onclick=\"aiDelPro()\">删提示词<\/button><\/div>',t+='<div class=\"hint\">预设：翻译 \/ 词语含义（含网络用语、常见用法、出现场景）\/ 润色改写 \/ 续写。改完点「存为模板」即可新增，也可在下拉里切换。<\/div>',t+=endsec(),t+='<div class=\"row\"><button class=\"bt\" onclick=\"resetStyle()\">恢复全部默认<\/button><button class=\"bt pri\" onclick=\"closeBG()\">完成<\/button><\/div>',t},window.cpDrag=function(t,e){function n(i){i.touches&&i.preventDefault&&i.preventDefault();var o=i.touches&&i.touches[0]||i,r=t.getBoundingClientRect();e(Math.min(1,Math.max(0,(o.clientX-r.left)\/r.width)),Math.min(1,Math.max(0,(o.clientY-r.top)\/r.height)))}t.addEventListener(\"touchstart\",n,{passive:!1}),t.addEventListener(\"touchmove\",n,{passive:!1}),t.addEventListener(\"mousedown\",function(i){n(i);var o=function(s){n(s)},r=function(){document.removeEventListener(\"mousemove\",o),document.removeEventListener(\"mouseup\",r)};document.addEventListener(\"mousemove\",o),document.addEventListener(\"mouseup\",r)})},window.cpHexIn=function(){var t=h2r(cv(\"cpHex\")),e=rgb2hsv(t.r,t.g,t.b);CP.h=e.h,CP.s=e.s,CP.v=e.v,cpSync(1)},window.cpInit=function(){var t=document.getElementById(\"cpSv\");t&&cpDrag(t,function(u,l){CP.s=u,CP.v=1-l,cpSync()});var e=document.getElementById(\"cpHue\");e&&cpDrag(e,function(u){CP.h=u*360,cpSync()});for(var n=[\"cpR\",\"cpG\",\"cpB\"],i=0;i<n.length;i++){var o=document.getElementById(n[i]);o&&(o.oninput=cpRgbIn)}var r=document.getElementById(\"cpHex\");r&&(r.oninput=cpHexIn);var s=document.getElementById(\"cpPreset\");if(s){for(var d=\"\",c=0;c<CP_PRESET.length;c++)d+='<button class=\"psw\" style=\"background:'+CP_PRESET[c]+`\" onclick=\"cpUse('`+CP_PRESET[c]+`')\" title=\"`+CP_PRESET[c]+'\"><\/button>';s.innerHTML=d}},window.cpRgbIn=function(){var t=parseInt(cv(\"cpR\"),10)||0,e=parseInt(cv(\"cpG\"),10)||0,n=parseInt(cv(\"cpB\"),10)||0,i=rgb2hsv(Math.min(255,Math.max(0,t)),Math.min(255,Math.max(0,e)),Math.min(255,Math.max(0,n)));CP.h=i.h,CP.s=i.s,CP.v=i.v,cpSync()},window.cpSync=function(t){var e=hsv2rgb(CP.h,CP.s,CP.v);CP.hex=r2h(e.r,e.g,e.b);var n=hsv2rgb(CP.h,1,1),i=document.getElementById(\"cpSv\");i&&(i.style.background=\"linear-gradient(to top,#000,rgba(0,0,0,0)),linear-gradient(to right,#fff,\"+r2h(n.r,n.g,n.b)+\")\");var o=document.getElementById(\"cpSvC\");o&&(o.style.left=CP.s*100+\"%\",o.style.top=(1-CP.v)*100+\"%\",o.style.background=CP.hex);var r=document.getElementById(\"cpHueC\");r&&(r.style.left=CP.h\/360*100+\"%\"),setV(\"cpR\",Math.round(e.r)),setV(\"cpG\",Math.round(e.g)),setV(\"cpB\",Math.round(e.b)),t||setV(\"cpHex\",CP.hex.toUpperCase());var s=document.getElementById(\"cpNew\");s&&(s.style.background=CP.hex)},window.cpUse=function(t){var e=h2r(t),n=rgb2hsv(e.r,e.g,e.b);CP.h=n.h,CP.s=n.s,CP.v=n.v,cpSync()},window.zAnchor=function(t,e,n,i){var o=zGet(t),r=document.getElementById(t+\"Prev\");if(!(!r||!e||!o.s)){var s=r.clientWidth||0,d=r.clientHeight||0,c=(n-(s\/2+o.x))\/o.s,u=(i-(d\/2+o.y))\/o.s,l=o.s*e;l<1&&(l=1),l>8&&(l=8),o.s=l,o.x=n-c*l-s\/2,o.y=i-u*l-d\/2,zClampView(t),zApply(t)}},window.zApply=function(t){var e=zGet(t),n=document.getElementById(t+\"Img\");n&&(n.style.transform=\"translate(\"+e.x+\"px,\"+e.y+\"px) scale(\"+e.s+\")\",n.style.imageRendering=e.s>=3?\"pixelated\":\"auto\");var i=document.getElementById(t+\"ZoomV\");i&&(i.textContent=e.s.toFixed(1)+\"x\");var o=document.getElementById(t+\"Zoom\");if(o){var r=Math.round(e.s*10);+o.value!==r&&(o.value=r)}},window.zBind=function(t){var e=document.getElementById(t+\"Prev\");if(!e||e._zb)return;e._zb=1;var n=zGet(t),i=null,o=0;function r(w,v){var p=e.getBoundingClientRect();return{x:w-p.left,y:v-p.top}}function s(w){for(var v=[],p=0;p<w.touches.length;p++)v.push({x:w.touches[p].clientX,y:w.touches[p].clientY});return v}function d(w,v){var p=w.x-v.x,S=w.y-v.y;return Math.sqrt(p*p+S*S)}function c(w,v){return{x:(w.x+v.x)\/2,y:(w.y+v.y)\/2}}function u(){return document.body&&document.body.contains(e)}function l(w){if(u()){n.moved=0,zMeasure(t);var v=w.touches;if(v&&v.length>=2){var p=s(w);o=d(p[0],p[1]),i=null}else v&&v.length===1?i={x:v[0].clientX,y:v[0].clientY}:i={x:w.clientX,y:w.clientY}}}function f(w){if(u()){var v=w.touches;if(v&&v.length>=2){var p=s(w),S=d(p[0],p[1]),x=c(p[0],p[1]);if(o>0&&S>0){var C=r(x.x,x.y);zAnchor(t,S\/o,C.x,C.y)}o=S,n.moved=1,w.cancelable&&w.preventDefault();return}if(i){var I=v?v[0].clientX:w.clientX,E=v?v[0].clientY:w.clientY,A=I-i.x,T=E-i.y;(Math.abs(A)>3||Math.abs(T)>3)&&(n.moved=1),n.x+=A,n.y+=T,zClampView(t),zApply(t),i={x:I,y:E},w.cancelable&&w.preventDefault()}}}function m(w){w&&w.touches&&w.touches.length||(i=null,o=0,setTimeout(function(){n.moved=0},80))}function g(){zReset(t)}e.addEventListener(\"touchstart\",l,!1),e.addEventListener(\"touchmove\",f,!1),e.addEventListener(\"touchend\",m,!1),e.addEventListener(\"touchcancel\",m,!1),e.addEventListener(\"mousedown\",l,!1),e.addEventListener(\"dblclick\",g,!1),window.addEventListener(\"mousemove\",f,!1),window.addEventListener(\"mouseup\",m,!1);try{var h=document.getElementById(t+\"Img\");h&&(h.draggable=!1,h.addEventListener(\"dragstart\",function(w){w.cancelable&&w.preventDefault()},!1))}catch(w){}},window.zClampView=function(t){var e=zGet(t),n=document.getElementById(t+\"Prev\");if(n){var i=n.clientWidth||0,o=n.clientHeight||0,r=((e.bw||0)*e.s-i)\/2;r<0&&(r=0);var s=((e.bh||0)*e.s-o)\/2;s<0&&(s=0),e.x>r&&(e.x=r),e.x<-r&&(e.x=-r),e.y>s&&(e.y=s),e.y<-s&&(e.y=-s)}},window.zGet=function(t){return _Z[t]||(_Z[t]={s:1,x:0,y:0,bw:0,bh:0,moved:0}),_Z[t]},window.zMeasure=function(t){var e=zGet(t),n=document.getElementById(t+\"Img\");n&&(e.bw=n.offsetWidth||0,e.bh=n.offsetHeight||0)},window.zOpen=function(t){var e=zGet(t);e.s=1,e.x=0,e.y=0,e.moved=0,zBind(t),zApply(t)},window.zReset=function(t){var e=zGet(t);e.s=1,e.x=0,e.y=0,zMeasure(t),zApply(t)},window.zSet=function(t,e){var n=document.getElementById(t+\"Prev\");if(n){var i=zGet(t);i.s&&zAnchor(t,(+e||1)\/i.s,(n.clientWidth||0)\/2,(n.clientHeight||0)\/2)}},window.zSlider=function(t,e){zSet(t,(+e.value||10)\/10)}}}catch(a){}window.aiDelAskPro=function(){var t=document.getElementById(\"aipro2\"),e=t?parseInt(t.value,10):-1,n=aiPro();if(e<0||!n[e]){tip(\"✘ 先在下拉里选一条\",\"no\");return}confirm(\"删除提示词「\"+(n[e].n||\"\")+\"」？\")&&(n.splice(e,1),aiSavePro(n),aiEchoAsk(),tip(\"✔ 已删除\",\"ok\"))},window.aiHintT=function(t){if(!t)return;var b=t.querySelector(\".ckb\");if(b)b.style.display=(b.style.display!==\"none\")?\"none\":\"block\"};try{typeof window.cpInit==\"function\"&&window.cpInit()}catch(a){}try{typeof window.aiInitBtn==\"function\"&&window.aiInitBtn()}catch(a){}var b=document.getElementById(\"app\");if(b){if(typeof window.__p8page!=\"function\"){(b.textContent||\"\").trim()||(b.innerHTML='<div style=\"padding:16px;color:#c00;font-size:13px;line-height:1.7\">页面脚本未加载。<br>请检查订阅源的 style 字段(详情页主脚本)是否完整。<\/div>');return}if(!b.firstChild||(b.textContent||\"\").trim()===\"\")try{window.__p8page()}catch(a){try{b.innerHTML='<pre style=\"padding:12px;color:#c00;white-space:pre-wrap;word-break:break-all;font-size:12px\">'+(a&&a.stack?a.stack:a)+\"<\/pre>\"}catch(t){}return}(!b.firstChild||(b.textContent||\"\").trim()===\"\")&&(b.innerHTML='<div style=\"padding:16px;color:#c00;font-size:13px;line-height:1.7\">页面脚本已执行，但没有渲染出内容。<br>可能是正文解析失败。<\/div>');try{for(var k=document.querySelectorAll(\".loading,.spinner,.mask-loading\"),y=0;y<k.length;y++)k[y]&&k[y].parentNode&&k[y].parentNode.removeChild(k[y])}catch(a){}}})();\n\n;(function(){\nvar NS=document.createElement('style');\nNS.textContent='.novel-read-btn{display:inline-block;padding:6px 16px;margin:4px 0;background:#1890ff;color:#fff!important;border-radius:4px;font-size:14px;text-decoration:none!important;cursor:pointer;border:none;line-height:1.5}.novel-read-btn:active{background:#096dd9}.novel-modal-overlay{position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,.6);z-index:1;display:flex;align-items:center;justify-content:center}.novel-modal{background:#fff;width:90%;max-width:600px;max-height:80vh;border-radius:8px;overflow:hidden;display:flex;flex-direction:column}.novel-modal-header{padding:12px 16px;border-bottom:1px solid #eee;display:flex;justify-content:space-between;align-items:center;font-weight:bold;font-size:16px}.novel-modal-close{cursor:pointer;font-size:20px;color:#999}.novel-modal-body{padding:16px;overflow-y:auto;flex:1;font-size:16px;line-height:1.8;white-space:pre-wrap;word-break:break-word;color:#333}.novel-loading{text-align:center;color:#999;padding:40px}';\ndocument.head.appendChild(NS);\n;(function(){var NS=document.createElement('style');NS.textContent=\".mrow.selected{background:var(--pkbg,#e8f0fe)!important;outline:2px solid var(--pk,#4285f4);outline-offset:-2px;border-radius:6px}\\n.mlist-btns{display:flex;gap:6px;margin-top:8px;justify-content:center;flex-wrap:wrap}\\n.mlist-btns .bt{flex:1;min-width:72px;max-width:120px}\\n.mlist-btns .bt:disabled{opacity:.4;cursor:not-allowed}\\n#aimlist{max-height:42vh;overflow-y:auto;overflow-x:hidden}\\n.mpicker-overlay{position:absolute;inset:0;background:rgba(0,0,0,.5);display:flex;align-items:center;justify-content:center;z-index:9999}\\n.mpicker{background:var(--bg);border-radius:12px;width:90%;max-width:400px;max-height:70vh;display:flex;flex-direction:column;box-shadow:0 8px 32px rgba(0,0,0,.3)}\\n.mpicker-hd{padding:12px 16px;font-weight:700;border-bottom:1px solid var(--bd);flex:none}\\n.mpicker-list{flex:1;overflow:auto;padding:8px 12px}\\n.mpicker-list label.mpick{display:flex;align-items:center;gap:8px;padding:8px;border-radius:6px;cursor:pointer}\\n.mpicker-list label.mpick:hover{background:var(--hbg)}\\n.mpicker-ft{padding:10px 16px;border-top:1px solid var(--bd);display:flex;gap:8px;justify-content:flex-end;flex:none}\\n.aifold{font-size:13px;text-align:center;margin:6px 0}\\n.aifold .bt{min-width:96px}\\n.aifold-body{overflow:visible}\\n#aim .phd{display:flex;align-items:center;justify-content:space-between;padding:12px 14px;border-bottom:1px solid rgba(0,0,0,.08)}\\n#aim .phd h3{margin:0;font-size:16px;color:#333;padding-left:2px}\\n#aim .phd .x{width:30px;height:30px;border:none;border-radius:50%;background:var(--pk,#4285f4);color:#fff;font-size:17px;font-weight:bold;line-height:1;cursor:pointer;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:opacity .15s}\\n#aim .phd .x:hover{opacity:.8}\\n\";document.head.appendChild(NS);})();\n\nfunction fetchNovelGbk(url){\n    return new Promise(function(resolve){\n        try{\n            var p=ajaxAwait(url);\n\n            if(p&&typeof p.then===\"function\"){\n                p.then(function(html){\n                    if(typeof html===\"string\"){\n                        resolve(html);\n                    }else{\n                        resolve(String(html||\"\"));\n                    }\n                }).catch(function(err){\n                    console.log(\"千白羽论坛LOG: ajaxAwait error: \"+err);\n                    resolve(\"\");\n                });\n            }else{\n                resolve(typeof p===\"string\"?p:String(p||\"\"));\n            }\n        }catch(e){\n            console.log(\"千白羽论坛LOG: ajaxAwait exception: \"+e);\n            resolve(\"\");\n        }\n    });\n}\nfunction cleanNovelHtml(html){\n  var m=html.match(\/<div[^>]*id=[\"']content[\"'][^>]*>([\\s\\S]*?)<\\\/div>\/i);\n  if(!m)return '未能提取正文内容';\n  var t=m[1]\n    .replace(\/<br\\s*\\\/?>\/gi,'\\n')\n    .replace(\/<[^>]+>\/g,'')\n    .replace(\/&nbsp;\/g,' ')\n    .replace(\/&lt;\/g,'<').replace(\/&gt;\/g,'>').replace(\/&amp;\/g,'&')\n    .replace(\/\\n\\s*\\n\/g,'\\n\\n')\n    .trim();\n  return t||'正文为空';\n}\nfunction showNovelModal(title,content){\n  var ov=document.createElement('div');\n  ov.className='novel-modal-overlay';\n  ov.innerHTML='<div class=\"novel-modal\"><div class=\"novel-modal-header\"><span>'+title.replace(\/<\/g,'&lt;')+'<\/span><span class=\"novel-modal-close\">&times;<\/span><\/div><div class=\"novel-modal-body\">'+content+'<\/div><\/div>';\n  document.body.appendChild(ov);\n  ov.querySelector('.novel-modal-close').onclick=function(){ov.remove();};\n  ov.onclick=function(e){if(e.target===ov)ov.remove();};\n}\nfunction initNovelButtons(){\n  var processed={};\n\n  function addButton(href,title,parent,oldNode){\n    if(!href||!title)return;\n\n    href=String(href).trim();\n    title=String(title).replace(\/^\\s+|\\s+$\/g,'');\n\n    if(!\/xiaoxiaoshuo8\/i.test(href))return;\n    if(!\/\\.html(?:[?#].*)?$\/i.test(href))return;\n\n    var key=href+'|'+title;\n    if(processed[key])return;\n    processed[key]=1;\n\n    var btn=document.createElement('button');\n    btn.className='novel-read-btn';\n    btn.textContent='\\uD83D\\uDCD6 '+title;\n    btn.setAttribute('data-novel-url',href);\n\n    btn.onclick=(function(h,t){\n      return function(e){\n        if(e){\n          if(e.preventDefault)e.preventDefault();\n          if(e.stopPropagation)e.stopPropagation();\n        }\n\n        showNovelModal(t,'<div class=\"novel-loading\">加载中...<\/div>');\n\n        fetchNovelGbk(h).then(function(raw){\n          var text=cleanNovelHtml(raw);\n          var body=document.querySelector('.novel-modal-body');\n          if(body)body.textContent=text;\n        });\n      };\n    })(href,title);\n\n    if(oldNode&&oldNode.parentNode){\n      oldNode.parentNode.replaceChild(btn,oldNode);\n    }else if(parent){\n      parent.appendChild(btn);\n    }\n  }\n\n  \/* ① 处理页面中真正存在的 <a> *\/\n  var links=document.querySelectorAll('a[href]');\n  for(var i=0;i<links.length;i++){\n    var a=links[i];\n    var href=a.getAttribute('href')||a.href||'';\n    var title=(a.textContent||'').trim();\n\n    addButton(href,title,a.parentNode,a);\n  }\n\n  \/* ② 处理正文文本里被转义\/嵌套的 <a> *\/\n  var walker=document.createTreeWalker(\n    document.body,\n    NodeFilter.SHOW_TEXT,\n    null,\n    false\n  );\n\n  var nodes=[];\n  var node;\n\n  while(node=walker.nextNode()){\n    if(node.parentNode&&node.parentNode.closest&&\n       node.parentNode.closest('.novel-read-btn'))continue;\n\n    var txt=node.nodeValue||'';\n\n    if(!\/xiaoxiaoshuo8\/i.test(txt))continue;\n    if(!\/\\.html\/i.test(txt))continue;\n    if(!\/<a\\b\/i.test(txt)&&!\/&lt;\\s*a\\b\/i.test(txt))continue;\n\n    nodes.push(node);\n  }\n\n  for(var ni=0;ni<nodes.length;ni++){\n    var textNode=nodes[ni];\n    var raw=textNode.nodeValue||'';\n\n    \/*\n     * 同时支持：\n     * <a href=\"...\">章节<\/a>\n     * &lt;a href=\"...\"&gt;章节&lt;\/a&gt;\n     *\/\n    var decoded=raw\n      .replace(\/&lt;\/gi,'<')\n      .replace(\/&gt;\/gi,'>')\n      .replace(\/&quot;\/gi,'\"')\n      .replace(\/&#39;\/gi,\"'\")\n      .replace(\/&amp;\/gi,'&');\n\n    var re=\/<a\\b[^>]*\\bhref\\s*=\\s*[\"']([^\"']+)[\"'][^>]*>([\\s\\S]*?)<\\\/a>\/gi;\n    var matches=[];\n    var m;\n\n    while(m=re.exec(decoded)){\n      var href=m[1];\n      var title=m[2]\n        .replace(\/<[^>]+>\/g,'')\n        .replace(\/&nbsp;\/gi,' ')\n        .trim();\n\n      if(!\/xiaoxiaoshuo8\/i.test(href))continue;\n      if(!\/\\.html(?:[?#].*)?$\/i.test(href))continue;\n      if(!title)continue;\n\n      matches.push({\n        href:href,\n        title:title\n      });\n    }\n\n    if(!matches.length)continue;\n\n    var frag=document.createDocumentFragment();\n\n    for(var mi=0;mi<matches.length;mi++){\n      var item=matches[mi];\n\n      var btn=document.createElement('button');\n      btn.className='novel-read-btn';\n      btn.textContent='\\uD83D\\uDCD6 '+item.title;\n      btn.setAttribute('data-novel-url',item.href);\n\n      btn.onclick=(function(h,t){\n        return function(e){\n          if(e){\n            if(e.preventDefault)e.preventDefault();\n            if(e.stopPropagation)e.stopPropagation();\n          }\n\n          showNovelModal(t,'<div class=\"novel-loading\">加载中...<\/div>');\n\n          fetchNovelGbk(h).then(function(raw){\n            var content=cleanNovelHtml(raw);\n            var body=document.querySelector('.novel-modal-body');\n            if(body)body.textContent=content;\n          });\n        };\n      })(item.href,item.title);\n\n      frag.appendChild(btn);\n      frag.appendChild(document.createElement('br'));\n    }\n\n    if(textNode.parentNode){\n      textNode.parentNode.replaceChild(frag,textNode);\n    }\n  }\n}\n\nif(document.readyState==='complete'){\n  setTimeout(initNovelButtons,600);\n}else{\n  window.addEventListener('load',function(){\n    setTimeout(initNovelButtons,600);\n  });\n}\nif(document.readyState==='complete'){setTimeout(initNovelButtons,600);}\nelse{window.addEventListener('load',function(){setTimeout(initNovelButtons,600);});}\n})();\n\/* ================= fixed35: 顶部固定栏 \/ 侧边栏 \/ 文章容器 ================= *\/\nvar X8WVD='3500';\nvar X8ITEMS=[\n  [ {id:'r52',n:'52破解软件区',k:'rss',\n     u:'https:\/\/www.52pojie.cn\/forum.php?mod=rss&fid=16&auth=0',ref:'https:\/\/www.52pojie.cn\/'},\n    \/* fixed38: 正文都来自 webnote 云便签, 渲染进同一个文章容器 *\/\n    {id:'nfree',n:'免费资讯',k:'note',u:'https:\/\/webnote.cc\/p\/e17d64cd356df1c6',nid:'e17d64cd356df1c6'},\n    {id:'nmsg',n:'留言',k:'msg',u:'https:\/\/webnote.cc\/%E7%95%99%E8%A8%80',nm:'留言'},\n    \/* fixed39: 纯文本容器 k='text' —— 正文只在容器里显示, 链接一律「一键跳转」走内置浏览器 *\/\n    {id:'ur1',n:'全网资讯站1',k:'text',txt:'跟大富翁-AI同一个网站，https:\/\/ttkit.cn\/'},\n    {id:'oe',n:'不死鸟资讯',k:'text',txt:'不死鸟官网，https:\/\/oe.do\/'},\n    {id:'flo',n:'folo订阅',k:'text',txt:'folo订阅源管理器，github trending排名靠前，作者是b站视频播放器编写程序员Diygod，免费用户可订阅150条普通订阅和30条rsshub订阅，rsshub订阅可以订阅B站up主、YouTube主等。不用它的ai服务，可以用浏览器的扩展的免费ai总结服务，或者直接复制正文或链接交给自己的免费ai总结，workbuddy也有网页划线总结技能，网站好像要魔法：https:\/\/folo.is\/'},\n    \/* fixed42: 纯文本容器 *\/\n    {id:'dse',n:'ds工程师发文称',k:'text',txt:'deepseek算子工程师在微信发文的结语引人深思：“少数科技公司控制着大部分资源，只有极少数人能够使用最先进的 AI 和各式科技，获得接近“机械飞升”的效果，大部分人则只能用上很孱弱的 AI。阶层跨越将越来越难实现：你得先有最强的 AI，才能跨越阶层，形成了一种死循环。你猜猜如果 Anthropic 公司永远掌握着这个世界上最先进的 AI，未来社会是会变成共产主义还是 2077 呢？你猜？所以，我还是相信，最前沿的智能应该以一种开放、廉价的方式，供应给所有人。我不信任 Anthropic 或者 OpenAI 能这样做，特别是不希望 Anthropic 掌握最先进的人工智能或 AGI，夸张点说其严重性不亚于让希特勒先于盟军掌握原子弹技术。这也是为什么我选择并坚持留在了 DeepSeek：我们研究强大、快速、普惠的人工智能并将其开源，或许能把世界从 2077 那端拉回来一些。”'},\n    \/* fixed46: 纯文本容器 *\/\n    {id:'ldo',n:'学AI到L站',k:'text',txt:'日活跃近十万，日发帖数也上万的围绕ai模型学习交流的社区，从以前的公开注册→50字非ai写作的申请缘由→站内3级号每日的邀请码注册→3年github账号注册→现今是5年github才有注册资格，即使如此每日注册量好像也上千了，用api链接《api.github.com\/users\/你的GitHub用户名》查询自己的账号注册日期，还差6个月，有大佬用L站商城积分兑换一个邀请码分享到论坛里吗https:\/\/linux.do'} ],\n  [ {id:'g1',n:'线下聚会游戏',k:'nav',u:'https:\/\/game.hullqin.cn\/'},\n    {id:'g2',n:'大富翁-AI',k:'nav',u:'https:\/\/ttkit.cn\/game\/monopoly'},\n    {id:'g3',n:'红色警戒网页版',k:'nav',u:'https:\/\/ra2.games\/'},\n    \/* fixed39: 纯文本容器 *\/\n    {id:'mpy',n:'殁漂遥软件',k:'text',txt:'老殁软件推荐，https:\/\/www.mpyit.com\/'},\n    {id:'pmt',n:'生图提示词',k:'text',txt:'5000多条分类好的生图提示词，有图片展示，https:\/\/prompt.qqsrc.com\/classic\/。预览图：https:\/\/r2.qqsrc.com\/images\/twitter\/2082722430049735087.jpg'},\n    \/* fixed41: 纯文本容器 *\/\n    {id:'gpt',n:'GPT-Astra制作的游戏',k:'text',txt:'大佬搜集的上百款网友用GPT-Astra制作的游戏，附上源码和试玩链接，多数可手机浏览器直接游玩:https:\/\/astragames.aigccreative.com\/zh-CN'},\n    {id:'ima',n:'腾讯ima知识库skill库',k:'text',txt:'ima最高100G免费个人库和不限量订阅公开库，有大量公开知识库和skill，可以收藏办公文档、网页链接正文和公众号文章到个人库中，复制文章知识到笔记中，然后问内置ai总结或检索需要的内容。https:\/\/ima.qq.com\/invitation\/storage-assistant\/V_5sR_uFk73_V0gf9KuYzA'},\n    \/* fixed43: 纯文本容器 *\/\n    {id:'tea',n:'企鹅教师助手',k:'text',txt:'企鹅教师助手网页端，包含全年级作业设计，课堂设计，理化生实验html等众多功能，记得每日签到https:\/\/aiteach.qq.com\/points'},\n    \/* fixed44: 纯文本容器（fixed45 起网址写全 https:\/\/，于是会带「一键跳转」按钮） *\/\n    {id:'fjp',n:'小飞机网盘',k:'text',txt:'蓝奏云和123网盘都开始收费了。小飞机网盘目前可上传app，下载方免登录不限速。https:\/\/www.feijipan.com'} ],\n  []\n];\nvar KX8S='x8_nav_state_v1',KX8M='x8_mine_v1';\nvar X8M=jload(KX8M,[]);\nif(!X8M||typeof X8M.length!=='number')X8M=[];\nfor(var _x8i=0;_x8i<X8M.length;_x8i++){X8M[_x8i].k='mine';}\nvar x8Cat=-1,x8Sel='',x8Cur=null,x8NavCache=[],x8List=[],x8MineCache=[],X8NBS=[];\n\nfunction x8Ajax(u){\n  try{if(typeof java==='undefined'||!java||typeof java.ajax!=='function')return '';}catch(e){return '';}\n  try{var s=java.ajax(u);return s==null?'':String(s);}catch(e2){return '';}\n}\n\/* fixed36: 所有外链一律走「内置浏览器」------------------------------------------------\n   java.startBrowser(url,title) = Legado 内置浏览器(WebViewActivity): 对 http\/https 的\n   shouldOverrideUrlLoading 返回 false, 就地加载, 不会被当成书源内链接管, 也不会阻塞等待。\n   ★绝对禁止回退到 window.open \/ location.href: 书源首页本身就是一个 WebView, 一旦发生\n   页面级导航, Legado 会把该 URL 当书源内链去渲染详情页(用户实测的 bug 根因)。\n   注: java.open('rss'|'web',url) 在 JsExtensions 里并不存在(只有 RssJsExtensions 的\n   searchBook\/addBook), 调用必抛异常, 已移除。 *\/\nvar X8BT='小小说8';\nfunction x8Open(u,t){\n  u=String(u==null?'':u).replace(\/^\\s+|\\s+$\/g,'');\n  if(!u)return;\n  var ti=String(t==null?'':t).replace(\/[\\r\\n\\t]+\/g,' ').replace(\/^\\s+|\\s+$\/g,'').slice(0,40)||X8BT;\n  try{if(typeof java!=='undefined'&&java&&typeof java.startBrowser==='function'){java.startBrowser(u,ti);return;}}catch(e){}\n  try{if(typeof java!=='undefined'&&java&&typeof java.openUrl==='function'){java.openUrl(u);return;}}catch(e){}\n  try{if(typeof java!=='undefined'&&java&&typeof java.toast==='function'){java.toast('无法打开链接: '+u);}}catch(e){}\n  try{console.log('[x8] 无法打开链接',u);}catch(e2){}\n}\nfunction x8Short(u){var s=String(u==null?'':u).replace(\/^https?:\\\/\\\/\/i,'');return s.length>72?s.slice(0,72)+'…':s;}\nfunction x8Find(id){\n  if(!id)return null;\n  for(var c=0;c<2;c++){var a=X8ITEMS[c];for(var i=0;i<a.length;i++){if(a[i].id===id)return a[i];}}\n  for(var j=0;j<X8M.length;j++){if(X8M[j].id===id)return X8M[j];}\n  return null;\n}\nfunction x8SaveState(){try{pput(KX8S,JSON.stringify({cat:x8Cat,id:x8Sel}));}catch(e){}}\n\n\/* ---------------- 顶栏 \/ 侧边栏 ---------------- *\/\nfunction x8NavToggle(i){\n  x8Cat=(x8Cat===i)?-1:i;\n  x8SaveState();x8Stamp();\n}\n\/* fixed37: 顶栏最右「✕」-> 收起侧边栏 + 文章容器(只隐藏, 内容保留, 不重新加载) *\/\nfunction x8NavClose(){x8Cat=-1;x8SaveState();x8Stamp();}\n\/* 某个按钮属于哪个顶栏分类(-1 = 找不到) *\/\nfunction x8CatOf(id){\n  if(!id)return -1;\n  for(var c=0;c<2;c++){var a=X8ITEMS[c];for(var i=0;i<a.length;i++){if(a[i].id===id)return c;}}\n  for(var j=0;j<X8M.length;j++){if(X8M[j].id===id)return 2;}\n  return -1;\n}\nfunction x8Stamp(){\n  for(var i=0;i<3;i++){\n    var el=document.getElementById('x8c'+i);\n    if(el)el.className='x8cat'+(x8Cat===i?' on':'');\n  }\n  var nv=document.getElementById('x8nav');\n  if(!nv)return;\n  nv.className='x8nav'+(x8Cat>=0?' on':'');\n  if(x8Cat<0){x8PaneClose();return;}\n  x8SideRender();\n  \/* ★ fixed37: 切换分类**只做显示 \/ 隐藏**, 绝不重新渲染文章容器\n     (否则每次切分类都会重新发请求刷新一遍)。容器内容还留着(只是 display:none):\n     属于本分类就直接露出来, 不属于本分类就收起, 两边都不动内容。 *\/\n  if(x8PaneId&&x8CatOf(x8PaneId)===x8Cat){\n    var p=document.getElementById('x8pane');\n    if(p)p.className='x8pane on';\n  }else{\n    x8PaneClose();\n  }\n}\nfunction x8PaneClose(){var p=document.getElementById('x8pane');if(p)p.className='x8pane';}\nfunction x8SideRender(){\n  var el=document.getElementById('x8side');\n  if(!el)return;\n  el.innerHTML='';\n  X8NBS=[];\n  var items=[],i;\n  if(x8Cat===2){\n    items.push({id:'__add',n:'＋ 添加',add:1});\n    for(i=0;i<X8M.length;i++)items.push({id:X8M[i].id,n:X8M[i].n||'未命名'});\n  }else{\n    var arr=X8ITEMS[x8Cat]||[];\n    for(i=0;i<arr.length;i++)items.push({id:arr[i].id,n:arr[i].n});\n  }\n  for(i=0;i<items.length;i++){\n    var it=items[i];\n    var b=document.createElement('button');\n    b.className='x8nb'+(it.add?' add':'')+(x8Sel===it.id?' on':'');\n    b.id=it.add?'x8addb':('x8sb_'+it.id);\n    if(it.add)b.setAttribute('data-add','1');\n    b.onclick=(function(id,isAdd){\n      return function(){if(isAdd){x8MineAdd();}else{x8NavPick(id);}};\n    })(it.id,it.add);\n    var sp=document.createElement('span');\n    sp.className='x8nbt';\n    sp.textContent=it.n;\n    b.appendChild(sp);\n    el.appendChild(b);\n    if(!it.add)X8NBS.push({id:it.id,btn:b,span:sp});\n  }\n  x8Marquee();\n}\n\/* 文本超过一行宽 -> 加上 .mv 让 CSS 动画左右滚动显示 *\/\nfunction x8Marquee(){\n  for(var i=0;i<X8NBS.length;i++){\n    var o=X8NBS[i],b=o.btn,s=o.span;\n    if(!b||!s)continue;\n    try{\n      var cs=(typeof getComputedStyle==='function')?getComputedStyle(b):null;\n      var pl=cs?parseFloat(cs.paddingLeft):0,pr=cs?parseFloat(cs.paddingRight):0;\n      if(!pl&&!pr){pl=10;pr=10;}\n      var avail=(b.clientWidth||0)-pl-pr;\n      var w=s.offsetWidth||0;\n      if(avail>0&&w>avail+2){\n        try{s.style.setProperty('--x8mvx','-'+(w-avail+8)+'px');}catch(e1){}\n        s.className='x8nbt mv';\n      }else{\n        s.className='x8nbt';\n      }\n    }catch(e){}\n  }\n}\nfunction x8MarkSide(){\n  for(var i=0;i<X8NBS.length;i++){\n    X8NBS[i].btn.className='x8nb'+(x8Sel===X8NBS[i].id?' on':'');\n  }\n  var a=document.getElementById('x8addb');\n  if(a)a.className='x8nb add';\n}\nfunction x8RenameBtn(id,name){\n  for(var i=0;i<X8NBS.length;i++){\n    if(X8NBS[i].id===id){X8NBS[i].span.textContent=name;x8Marquee();return;}\n  }\n}\nfunction x8NavPick(id){\n  x8Sel=id;x8SaveState();x8MarkSide();\n  var it=x8Find(id);\n  if(it)x8PaneRender(it);\n}\n\n\/* ---------------- 文章容器 ---------------- *\/\nfunction x8PaneHd(it,right){\n  var hd=document.getElementById('x8phd');\n  if(!hd)return;\n  hd.innerHTML='<span class=\"x8pt\" id=\"x8pt\">'+esc(it.n||'')+'<\/span>'\n    +'<span class=\"x8pl\">'+esc(x8Short(it.u||''))+'<\/span>'\n    +'<button class=\"x8pb\" onclick=\"x8PaneReload()\">↻<\/button>'\n    +(right||'<button class=\"x8pb\" onclick=\"x8OpenCur()\">↗ 打开<\/button>');\n}\nfunction x8OpenCur(){x8Open(x8Cur&&x8Cur.u,x8Cur&&x8Cur.n);}\nfunction x8PaneReload(){if(x8Cur)x8PaneRender(x8Cur,true);}\nvar X8PC={};      \/* 内容缓存: id -> {kind:'rss',list} \/ {kind:'nav',links} \/ {kind:'note',title,text} \/ {kind:'msg',text} \/ {kind:'text',text} *\/\nvar x8PaneId='';  \/* 当前容器里装着哪个按钮的内容 *\/\nfunction x8PaneRender(it,force){\n  if(!it)return;\n  x8Cur=it;\n  var pane=document.getElementById('x8pane');\n  if(pane)pane.className='x8pane on';\n  if(!force&&x8PaneId===it.id)return;          \/* 就是它 -> 直接露出, 什么也不做 *\/\n  var c=force?null:X8PC[it.id];\n  if(c&&c.kind==='rss'&&c.list&&c.list.length){\n    x8List=c.list.slice();x8PaneId=it.id;x8PaneHd(it);x8RssPaint();return;\n  }\n  if(c&&c.kind==='nav'&&c.links&&c.links.length){\n    x8NavCache=c.links.slice();x8PaneId=it.id;x8PaneHd(it);x8NavPaint();return;\n  }\n  \/* fixed38: 便签类(免费资讯\/留言)也吃同一套缓存 —— 切分类再回来不重新请求 *\/\n  if(c&&c.kind==='note'){x8PaneId=it.id;x8PaneHd(it);x8NotePaint(it);return;}\n  if(c&&c.kind==='msg'){x8PaneId=it.id;x8PaneHd(it);x8MsgPaint(it);return;}\n  \/* fixed39: 纯文本容器(k='text')也吃同一套缓存 —— 切分类再回来不重新渲染 *\/\n  if(c&&c.kind==='text'){x8PaneId=it.id;x8PaneHd(it);x8TextPaint(it);return;}\n  if(force)delete X8PC[it.id];\n  x8PaneId=it.id;\n  if(it.k==='rss')x8RssGo(it);\n  else if(it.k==='nav')x8NavGo(it);\n  else if(it.k==='note')x8NoteGo(it);\n  else if(it.k==='msg')x8MsgGo(it);\n  else if(it.k==='text')x8TextGo(it);\n  else x8MineRender(it);\n}\nfunction x8PaneBody(html){\n  var bd=document.getElementById('x8pbd');\n  if(bd)bd.innerHTML=html;\n}\n\n\/* ---------------- 推荐阅读: 52破解 RSS ---------------- *\/\n\/* GBK: ① 显式 charset 让 legado 网络栈解码 ② 取 hex 原始字节 + bytesToStr(gbk) 兜底 *\/\nfunction x8Gbk(u){\n  var s='';\n  try{s=x8Ajax(u+',{\"charset\":\"gbk\"}');}catch(e){s='';}\n  if(s&&s.indexOf('<item')>=0&&s.indexOf(String.fromCharCode(65533))<0)return s;\n  try{\n    var hex=x8Ajax(u+',{\"type\":\"hex\"}');\n    if(hex&&\/^[0-9a-fA-F]{16,}$\/.test(hex.slice(0,32))){\n      var t=String(java.bytesToStr(java.hexDecodeToByteArray(hex),'gbk'));\n      if(t&&t.indexOf('<item')>=0)return t;\n    }\n  }catch(e2){}\n  return s;\n}\nfunction x8RssParse(x){\n  var out=[],re=\/<item[\\s>][\\s\\S]*?<\\\/item>\/gi,m;\n  while((m=re.exec(String(x==null?'':x)))!==null){\n    var s=m[0];\n    var g=function(tag){\n      var r=new RegExp('<'+tag+'(?:\\\\s[^>]*)?>([\\\\s\\\\S]*?)<\\\\\/'+tag+'>','i');\n      var mm=r.exec(s);\n      return mm?mm[1]:'';\n    };\n    var enc=\/<enclosure[^>]*\\burl\\s*=\\s*[\"']([^\"']+)[\"']\/i.exec(s);\n    out.push({\n      title:tx(g('title')),\n      link:tx(g('link')),\n      desc:tx(String(g('description')).replace(\/^\\s*<!\\[CDATA\\[\/,'').replace(\/\\]\\]>\\s*$\/,'')),\n      cat:tx(g('category')),\n      auth:tx(g('author')),\n      pd:tx(g('pubDate')),\n      img:enc?String(enc[1]).replace(\/^\\s+|\\s+$\/g,''):''\n    });\n  }\n  return out;\n}\nfunction x8RssGo(it){\n  x8PaneHd(it);\n  x8PaneBody('<div class=\"x8load\">正在加载五二破解 RSS…<\/div>');\n  setTimeout(function(){\n    if(x8PaneId!==it.id)return;   \/* fixed37: 已切走 -> 丢弃这次结果 *\/\n    var raw='';\n    try{raw=x8Gbk(it.u);}catch(e){raw='';}\n    if(!raw){x8PaneBody('<div class=\"x8err\">RSS 加载失败，请检查网络后重试。<\/div>');return;}\n    x8List=x8RssParse(raw);\n    if(!x8List.length){x8PaneBody('<div class=\"x8err\">未能解析到条目（可能被拦截）。<\/div>');return;}\n    \/* 每条带上 Referer: 52pojie 附件图片防盗链, 无 Referer 一律 403 *\/\n    for(var z=0;z<x8List.length;z++)x8List[z].ref=it.ref||'';\n    X8PC[it.id]={kind:'rss',list:x8List};   \/* fixed37: 缓存, 再进这个按钮不再重新请求 *\/\n    x8RssPaint();\n  },40);\n}\n\/* 渲染已解析的 x8List(首次 \/ 缓存命中都走这里): 已取过的图片直接用条目里的 dataURI *\/\nfunction x8RssPaint(){\n  var h='<div class=\"x8rss\">';\n  for(var i=0;i<x8List.length;i++)h+=x8RssItem(x8List[i],i);\n  h+='<\/div>';\n  x8PaneBody(h);\n  \/* 图片防盗链: 逐条异步取字节转 dataURI(先把列表显示出来); 已有 src 的不再取 *\/\n  for(var k=0;k<x8List.length;k++){\n    var o=x8List[k];\n    if(!o||!o.img||o.src)continue;\n    (function(n){setTimeout(function(){x8RssImg(n);},120*n);})(k);\n  }\n}\nfunction x8RssItem(o,i){\n  var meta=[o.auth,o.cat,o.pd];\n  var mm='';\n  for(var j=0;j<meta.length;j++){if(meta[j])mm+=(mm?' · ':'')+esc(meta[j]);}\n  return '<div class=\"x8rssi\">'\n    +(o.img?(o.src?'<div class=\"x8rssph\" id=\"x8ph'+i+'\"><img class=\"x8rssimg\" src=\"'+o.src+'\" alt=\"\" onclick=\"x8RssOpenImg('+i+')\"><\/div>':'<div class=\"x8ph\" id=\"x8ph'+i+'\" onclick=\"x8RssImg('+i+')\">图片<br>加载<\/div>'):'')\n    +'<div class=\"x8rssb\">'\n    +'<div class=\"x8rsst\" onclick=\"x8RssOpen('+i+')\">'+esc(o.title)+'<\/div>'\n    +(mm?'<div class=\"x8rssm\">'+mm+'<\/div>':'')\n    +(o.desc?'<div class=\"x8rssd\">'+esc(o.desc)+'<\/div>':'')\n    +'<div class=\"x8rssa\"><button class=\"x8bb\" onclick=\"x8RssOpen('+i+')\">↗ 新窗口打开原帖<\/button>'\n    \/* fixed39: 去掉「图片原图」按钮 —— 卡片本来就出了缩略图(x8rssimg), 点缩略图即可看原图 *\/\n    +'<\/div><\/div><\/div>';\n}\nfunction x8RssOpen(i){var o=x8List[i];if(o)x8Open(o.link,o.title);}\nfunction x8RssOpenImg(i){var o=x8List[i];if(o)x8Open(o.img||o.link,o.title?o.title+' 图片':'图片');}\nvar X8B64='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+\/';\nfunction x8HexB64(hex){\n  var n=hex.length>>1,out=[],i=0;\n  while(i<n){\n    var b0=parseInt(hex.substr(i*2,2),16);if(isNaN(b0))b0=0;\n    var b1=(i+1<n)?parseInt(hex.substr((i+1)*2,2),16):-1;if(isNaN(b1))b1=-1;\n    var b2=(i+2<n)?parseInt(hex.substr((i+2)*2,2),16):-1;if(isNaN(b2))b2=-1;\n    out.push(X8B64.charAt(b0>>2));\n    out.push(X8B64.charAt(((b0&3)<<4)|((b1<0?0:b1)>>4)));\n    out.push(b1<0?'=':X8B64.charAt((((b1&15)<<2)|((b2<0?0:b2)>>6))));\n    out.push(b2<0?'=':X8B64.charAt(b2&63));\n    i+=3;\n  }\n  return out.join('');\n}\nfunction x8ImgMime(u){\n  var m=\/\\.(png|jpe?g|gif|webp|bmp|svg|avif|ico)(?:[?#]|$)\/i.exec(String(u||''));\n  if(!m)return 'image\/jpeg';\n  var e=m[1].toLowerCase();\n  if(e==='jpg')e='jpeg';\n  if(e==='svg')return 'image\/svg+xml';\n  return 'image\/'+e;\n}\n\/* 52pojie 图片有防盗链(无 Referer -> 403), 页面又是 no-referrer, <img src> 必然 403。\n   所以走 java.ajax 带 Referer 取 hex 原始字节, 再用纯 JS 转 base64 内联。 *\/\nfunction x8RssImg(i){\n  var o=x8List[i];\n  if(!o||!o.img)return;\n  var ph=document.getElementById('x8ph'+i);\n  if(ph&&ph.getAttribute('data-busy')==='1')return;\n  if(ph){ph.setAttribute('data-busy','1');ph.innerHTML='加载中…';}\n  setTimeout(function(){\n    var hex='';\n    try{\n      var opt=',{\"type\":\"hex\",\"headers\":{\"Referer\":\"'+String(o.ref||'').replace(\/\"\/g,'')+'\"}}';\n      hex=x8Ajax(o.img+opt);\n    }catch(e){hex='';}\n    var ok=hex&&\/^[0-9a-fA-F]{16,}$\/.test(hex.slice(0,32));\n    if(!ph)return;\n    if(!ok){\n      ph.setAttribute('data-busy','0');\n      ph.innerHTML='图片加载失败<br>点此重试';\n      return;\n    }\n    var src='data:'+x8ImgMime(o.img)+';base64,'+x8HexB64(hex);\n    try{o.src=src;}catch(_e){}   \/* fixed37: 存回条目, 重进容器不用再取一次字节 *\/\n    ph.setAttribute('data-busy','0');\n    ph.className='x8rssph';\n    ph.innerHTML='<img class=\"x8rssimg\" src=\"'+src+'\" alt=\"\" onclick=\"x8RssOpenImg('+i+')\">';\n  },30);\n}\n\n\/* ---------------- 网址导航: webview 渲染取 DOM -> 链接列表 ---------------- *\/\nfunction x8Abs(h,b){\n  h=String(h==null?'':h).replace(\/^\\s+|\\s+$\/g,'');\n  if(\/^https?:\\\/\\\/\/i.test(h))return h;\n  if(\/^\\\/\\\/\/.test(h))return 'https:'+h;\n  var m=\/^(https?:\\\/\\\/[^\\\/]+)\/i.exec(String(b||''));\n  var org=m?m[1]:'';\n  if(!org)return '';\n  if(h.charAt(0)==='\/')return org+h;\n  h=h.replace(\/^\\.\\\/\/,'').replace(\/^(\\.\\.\\\/)+\/,'');\n  return org+'\/'+h;\n}\nfunction x8NavLinks(html){\n  var out=[],seen={},re=\/<a\\b[^>]*\\bhref\\s*=\\s*[\"']([^\"']*)[\"'][^>]*>([\\s\\S]*?)<\\\/a>\/gi,m;\n  while((m=re.exec(String(html==null?'':html)))!==null){\n    var href=m[1],t=tx(m[2]);\n    if(!href||\/^(javascript:|#|mailto:|tel:|data:)\/i.test(href))continue;\n    if(seen[href])continue;\n    seen[href]=1;\n    out.push({u:href,t:t||href});\n  }\n  return out;\n}\nfunction x8NavList(links){\n  var h='<div class=\"x8nlist\">';\n  for(var i=0;i<links.length;i++){\n    h+='<div class=\"x8nrow\">'\n      +'<div class=\"x8nrt\" onclick=\"x8LaOpen('+i+')\"><b>'+esc(links[i].t)+'<\/b><i>'+esc(x8Short(links[i].u))+'<\/i><\/div>'\n      +'<button class=\"x8bb x8jump\" onclick=\"x8LaOpen('+i+')\">一键跳转<\/button>'\n      +'<\/div>';\n  }\n  h+='<\/div>';\n  return h;\n}\nfunction x8LaOpen(i){var l=x8NavCache[i];if(l)x8Open(l.u,l.t);}\n\/* 显式点「内嵌浏览」才挂 iframe; sandbox 不带 allow-top-navigation, 内嵌页无法导航顶层页面,\n   也就不会被书源接管去渲染详情页 *\/\nfunction x8NavEmbed(){\n  var w=document.getElementById('x8ifw');\n  if(!w||!x8Cur)return;\n  w.innerHTML='<iframe class=\"x8if\" sandbox=\"allow-scripts allow-same-origin allow-forms\" '\n    +'referrerpolicy=\"no-referrer\" src=\"'+esc(x8Cur.u)+'\"><\/iframe>';\n  try{java.toast('已在容器内内嵌：内部链接只在该区域内跳转');}catch(e){}\n}\nfunction x8NavGo(it){\n  x8PaneHd(it);\n  x8PaneBody('<div class=\"x8load\">正在渲染 '+esc(x8Short(it.u))+' …<br>'\n    +'<span class=\"x8sub\">首次渲染需要几秒<\/span><\/div>');\n  setTimeout(function(){\n    if(x8PaneId!==it.id)return;   \/* fixed37: 已切走 -> 丢弃这次结果 *\/\n    var html='';\n    \/* ① 后台 webview 渲染后再取 DOM: SPA 站点只有渲染后才有真实链接 *\/\n    try{\n      html=x8Ajax(it.u+',{\"useWebView\":true,\"webJs\":\"document.documentElement.outerHTML\",\"webViewDelayTime\":\"'+X8WVD+'\"}');\n    }catch(e){html='';}\n    if(!html||html.length<200){try{html=x8Ajax(it.u+',{\"charset\":\"utf-8\"}');}catch(e2){html='';}}\n    if(!html){try{html=x8Ajax(it.u);}catch(e3){html='';}}\n    if(!html){x8PaneBody('<div class=\"x8err\">加载失败，请重试或点右上角↗打开。<\/div>');return;}\n    x8NavCache=x8NavLinks(html);\n    if(x8NavCache.length>=2)X8PC[it.id]={kind:'nav',links:x8NavCache};   \/* fixed37: 缓存链接列表 *\/\n    x8NavPaint();\n  },40);\n}\n\/* 渲染已解析的链接列表(首次 \/ 缓存命中都走这里, 不再请求) *\/\nfunction x8NavPaint(){\n  var head='';\n  if(x8NavCache.length>=2){\n    head='<div class=\"x8hint\">已解析到 '+x8NavCache.length+' 条链接，每条右侧「一键跳转」直接用浏览器打开。<\/div>';\n    x8PaneBody(head+x8NavList(x8NavCache));\n    return;\n  }\n  \/* 解析不到链接(纯脚本渲染) -> 默认不内嵌: 内嵌页里的点击同样可能被书源内链接管,\n     直接把出口收口到内置浏览器 *\/\n  var cu=x8Cur||{};\n  x8PaneBody('<div class=\"x8hint\">该站为脚本渲染，未能解析到链接列表。'\n    +'为避免容器内的链接被书源接管去渲染详情页，这里默认不内嵌，请用下面按钮在内置浏览器浏览。<\/div>'\n    +'<div class=\"x8nrow\"><div class=\"x8nrt\"><b>'+esc(cu.n||'')+'<\/b><i>'+esc(x8Short(cu.u||''))+'<\/i><\/div>'\n    +'<button class=\"x8bb x8jump\" onclick=\"x8OpenCur()\">↗ 在内置浏览器打开<\/button><\/div>'\n    +'<div class=\"x8hint x8ifhint\"><span>需要就地浏览时可内嵌；内嵌页中的链接只在该区域内跳转，不会跳到详情页。<\/span>'\n    +'<button class=\"x8bb\" onclick=\"x8NavEmbed()\">内嵌浏览<\/button><\/div>'\n    +'<div id=\"x8ifw\"><\/div>');\n}\n\n\/* ---------------- 我的: 自定义按钮 ---------------- *\/\nfunction x8MineSave(){try{jsave(KX8M,X8M);}catch(e){}}\nfunction x8MineCur(){return x8Cur&&x8Cur.k==='mine'?x8Cur:null;}\nfunction x8MineAdd(){\n  var it={id:'m'+Date.now()+Math.floor(Math.random()*1000),n:'未命名',txt:'',k:'mine',img:0,btn:0};\n  X8M.push(it);\n  x8MineSave();\n  x8Cat=2;x8Sel=it.id;x8SaveState();\n  var nv=document.getElementById('x8nav');\n  if(nv)nv.className='x8nav on';\n  x8Stamp();\n  x8PaneRender(it);   \/* 新按钮 -> 直接把它的容器渲染出来 *\/\n}\nfunction x8MineDel(){\n  var it=x8MineCur();\n  if(!it)return;\n  var nx=[];\n  for(var i=0;i<X8M.length;i++){if(X8M[i].id!==it.id)nx.push(X8M[i]);}\n  X8M=nx;\n  x8MineSave();\n  x8Sel='';x8SaveState();x8Cur=null;x8PaneId='';delete X8PC[it.id];\n  x8PaneClose();x8SideRender();\n}\nfunction x8MineRender(it){\n  x8PaneHd(it);\n  x8PaneBody('<div class=\"x8me\">'\n    +'<div class=\"x8mttl\"><input type=\"text\" id=\"x8mttl\" value=\"'+esc(it.n||'')+'\" placeholder=\"标题栏：改名会同步左侧按钮\" oninput=\"x8MineRename(this.value)\"><\/div>'\n    +'<div class=\"x8mtb\">'\n    +'<button class=\"x8bb'+(it.img?' on':'')+'\" id=\"x8mimg\" onclick=\"x8MineImg()\">url显示为图片<\/button>'\n    +'<span style=\"flex:1\"><\/span>'\n    +'<button class=\"x8bb'+(it.btn?' on':'')+'\" id=\"x8mbtn\" onclick=\"x8MineBtn()\">url显示为按钮<\/button>'\n    +'<button class=\"x8bb x8del\" onclick=\"x8MineDel()\">删除<\/button>'\n    +'<\/div>'\n    +'<textarea class=\"x8mta\" id=\"x8mta\" placeholder=\"在这里编辑文本：每行一个图片链接或网页网址\" '\n    +'oninput=\"x8MineTxt(this.value)\">'+esc(it.txt||'')+'<\/textarea>'\n    +'<div class=\"x8mpv\" id=\"x8mpv\"><\/div>'\n    +'<\/div>');\n  x8MinePrev();\n}\nfunction x8MineRename(v){\n  var it=x8MineCur();\n  if(!it)return;\n  var s=String(v==null?'':v).replace(\/[\\r\\n]+\/g,' ').slice(0,40);\n  it.n=s||'未命名';\n  x8MineSave();\n  x8RenameBtn(it.id,it.n);\n  try{\n    var tt=document.getElementById('x8pt');\n    if(tt)tt.textContent=it.n;\n  }catch(e2){}\n}\nfunction x8MineTxt(v){var it=x8MineCur();if(!it)return;it.txt=String(v==null?'':v);x8MineSave();x8MinePrev();}\nfunction x8MineImg(){var it=x8MineCur();if(!it)return;it.img=it.img?0:1;x8MineSave();x8MineFlags();x8MinePrev();}\nfunction x8MineBtn(){var it=x8MineCur();if(!it)return;it.btn=it.btn?0:1;x8MineSave();x8MineFlags();x8MinePrev();}\nfunction x8MineFlags(){\n  var it=x8MineCur();\n  if(!it)return;\n  var a=document.getElementById('x8mimg'),c=document.getElementById('x8mbtn');\n  if(a)a.className='x8bb'+(it.img?' on':'');\n  if(c)c.className='x8bb'+(it.btn?' on':'');\n}\n\/* fixed45: 「我的」容器的两个开关（url显示为图片 \/ url显示为按钮）原来只认带协议前缀的\n   https?:\/\/… ，于是 www.foo.com、foo.com\/a.png 这类没写前缀的网址既显示不了图片也出不了按钮。\n   现在：① 先把原文里已有的 https?:\/\/… 抠出来（保持原样，记下位置）；\n        ② 把它们抹成空格，再补扫一遍「裸域名」（www.* 或已知 TLD）；\n        ③ 命中后统一补上 https:\/\/；最后按出现位置排序（保持原文顺序）。\n   两个开关都吃 x8MineCache，而 x8MineCache 只由本函数产出 —— 所以改这一处就同时覆盖两个功能。\n   ★裸域名扫描要防「误吞片段」：ftp:\/\/x.cn\/f 里的 x.cn、mailto:a@b.com 里的 b.com\n     都不是独立网址。用「前一个字符守卫」处理（前字符是 [A-Za-z0-9._%+-@\/] 就跳过），\n     这样 scheme:\/\/… 内部与邮箱内部都不会被切出来，而 www.qq.com 这类正常裸域名前面总是\n     空格\/中文\/（\/：等分隔符，不受影响。 *\/\nfunction x8MineAbs(u){\n  u=String(u==null?'':u).replace(\/^\\s+|\\s+$\/g,'');\n  if(!u)return '';\n  return \/^[a-z][a-z0-9+.\\-]*:\\\/\\\/\/i.test(u)?u:'https:\/\/'+u;\n}\nfunction x8Urls(t){\n  var s=String(t==null?'':t),acc=[],seen={},out=[],m,i,u,\n      re=\/https?:\\\/\\\/[A-Za-z0-9\\-._~:\\\/?#\\[\\]@!$&'()*+,;=%]+\/g,\n      re2=\/(?:[A-Za-z0-9](?:[A-Za-z0-9\\-]*[A-Za-z0-9])?\\.)+(?:com|cn|net|org|io|me|tv|cc|xyz|top|info|biz|app|dev|pro|site|online|club|fun|shop|wang|xin|ltd|vip|art|edu|gov|mil|int|co|ai|im|fm|gg|la|us|uk|jp|kr|hk|tw|mo|link|cloud|tech|store|life|live|world|space|press|wiki|blog|news|media|design|group|one|run|red|work|plus|tools|page|games|game)(?![A-Za-z0-9\\-])(?::\\d+)?(?:[\\\/?#][A-Za-z0-9\\-._~:\\\/?#\\[\\]@!$&'()*+,;=%]*)?\/gi,\n      pre=\/[A-Za-z0-9._%+\\-@\\\/]\/;\n  function clean(x){\n    x=String(x==null?'':x).replace(\/[.,;:!?)\\]}'\"]+$\/,'');\n    return x?x8MineAbs(x):'';\n  }\n  re.lastIndex=0;\n  while((m=re.exec(s))!==null){u=clean(m[0]);if(u)acc.push([m.index,u]);}\n  var rest=s.replace(re,function(x){return x.replace(\/[^\\s]\/g,' ');});\n  re2.lastIndex=0;\n  while((m=re2.exec(rest))!==null){\n    if(m.index>0&&pre.test(rest.charAt(m.index-1)))continue;\n    u=clean(m[0]);if(u)acc.push([m.index,u]);\n  }\n  acc.sort(function(a,b){return a[0]-b[0];});\n  for(i=0;i<acc.length;i++){u=acc[i][1];if(seen[u])continue;seen[u]=1;out.push(u);}\n  return out;\n}\nfunction x8IsImg(u){return \/\\.(png|jpe?g|gif|webp|bmp|svg|avif|ico)(?:[?#]|$)\/i.test(u)||\/^data:image\\\/\/i.test(u);}\nfunction x8MinePrev(){\n  var el=document.getElementById('x8mpv');\n  if(!el)return;\n  var it=x8MineCur();\n  if(!it){el.innerHTML='';return;}\n  x8MineCache=x8Urls(it.txt);\n  if(!x8MineCache.length){\n    el.innerHTML='<div class=\"x8mhint\">文本区里填图片链接或网页网址，再用上方按钮渲染。<\/div>';\n    return;\n  }\n  var h='';\n  for(var i=0;i<x8MineCache.length;i++){\n    var u=x8MineCache[i];\n    if(x8IsImg(u)){\n      \/* fixed39: 缩略图点击 -> 就地放大(不再直接甩到浏览器) *\/\n      if(it.img)h+='<img class=\"x8mpi\" src=\"'+esc(u)+'\" data-u=\"'+esc(u)+'\" referrerpolicy=\"no-referrer\" onclick=\"x8ZoomEl(this)\">';\n      else h+='<div class=\"x8mpu\"><span>'+esc(u)+'<\/span><button class=\"x8bb x8jump\" onclick=\"x8MineOpen('+i+')\">打开<\/button><\/div>';\n    }else{\n      h+='<div class=\"x8mpu\"><span>'+esc(u)+'<\/span>'\n        +(it.btn?'<button class=\"x8bb x8jump\" onclick=\"x8MineOpen('+i+')\">点击跳转<\/button>':'')\n        +'<\/div>';\n    }\n  }\n  el.innerHTML=h;\n}\nfunction x8MineOpen(i){var u=x8MineCache[i];if(u)x8Open(u,u);}\n\n\/* ---------------- 小说正文容器: 双阅读模式 + 临时全透明 ---------------- *\/\nvar X8DOC={mode:'scroll',pg:0,pgn:1,h:0,timer:0,lh:0,bound:0};\nvar X8DPAD=6;   \/* 翻页模式上下留白(放在 wrap 的 padding 上, 保证正文网格与页网格从 0 对齐) *\/\nfunction x8Mode(){return ST.x8Mode==='page'?'page':'scroll';}\n\/* 容器基础高度: 由面板的 x8DocH(vh) 换算成像素 *\/\nfunction x8DocBase(){\n  var vh=0;\n  try{vh=(window&&window.innerHeight)||0;}catch(e){}\n  if(!vh){try{vh=document.documentElement.clientHeight||0;}catch(e1){}}\n  if(!vh)vh=600;\n  var pct=(ST.x8DocH==null?76:ST.x8DocH);\n  if(!(pct>0))pct=76;\n  return Math.max(160,Math.round(vh*pct\/100));\n}\n\/* 量一行有多高(拿正文实际字体\/行高量, 量完即删) *\/\nfunction x8LineH(cg){\n  var host=(cg&&cg.firstChild&&cg.firstChild.appendChild)?cg.firstChild:cg;\n  if(!host||!host.appendChild)return 0;\n  var d=null,h=0;\n  try{\n    d=document.createElement('div');\n    d.style.cssText='position:absolute;left:0;top:0;visibility:hidden;white-space:nowrap;line-height:inherit;font:inherit;margin:0;padding:0;border:0;';\n    d.textContent='M';\n    host.appendChild(d);\n    h=d.offsetHeight||0;\n  }catch(e){h=0;}\n  try{if(d&&d.parentNode&&d.parentNode.removeChild)d.parentNode.removeChild(d);}catch(e2){}\n  return h>0?h:0;\n}\nfunction x8DocTrans(on){\n  var d=document.getElementById('x8doc');\n  if(!d)return;\n  if(on)d.classList.add('t');else d.classList.remove('t');\n}\nfunction x8DocOpa(v){\n  ST.x8Opa=parseFloat(v);if(isNaN(ST.x8Opa))ST.x8Opa=92;\n  try{saveST();applyStyle();}catch(e){}\n  var b=document.getElementById('x8opav');\n  if(b)b.textContent=ST.x8Opa+'%';\n}\nfunction x8DocMode(m){\n  ST.x8Mode=(m===1||m==='page')?'page':'scroll';\n  try{saveST();applyStyle();}catch(e){}\n  x8DocInit();\n}\nfunction x8PgBar(){\n  var el=document.getElementById('x8pgbar');\n  if(!el)return;\n  if(X8DOC.mode!=='page'||X8DOC.pgn<=1){el.className='x8pgbar';el.innerHTML='';return;}\n  el.className='x8pgbar on';\n  el.innerHTML='<button class=\"x8bb\" onclick=\"x8PgStep(-1)\">‹ 上一页<\/button>'\n    +'<span class=\"x8pgn\">'+(X8DOC.pg+1)+' \/ '+X8DOC.pgn+'<\/span>'\n    +'<button class=\"x8bb\" onclick=\"x8PgStep(1)\">下一页 ›<\/button>';\n}\nfunction x8PgGo(){\n  var inner=document.getElementById('x8pgs');\n  if(!inner)return;\n  inner.style.transform='translateY(-'+(X8DOC.pg*X8DOC.h)+'px)';\n  x8DocTrans(true);\n  if(X8DOC.timer)clearTimeout(X8DOC.timer);\n  X8DOC.timer=setTimeout(function(){x8DocTrans(false);},320);\n  x8PgBar();\n}\nfunction x8PgStep(d){\n  var n=X8DOC.pgn;\n  if(n<=1)return;\n  var i=X8DOC.pg+d;\n  if(i<0)i=0;\n  if(i>n-1)i=n-1;\n  if(i===X8DOC.pg)return;\n  X8DOC.pg=i;\n  x8PgGo();\n}\nfunction x8DocInit(){\n  var wrap=document.getElementById('x8docbd'),inner=document.getElementById('x8pgs'),cg=document.getElementById('x8pgin');\n  if(!wrap||!inner||!cg)return;\n  var isNew=wrap.getAttribute('data-x8b')!=='1';\n  var pg=x8Mode()==='page';\n  var wasPg=X8DOC.mode==='page';\n  var oldH=X8DOC.h||0,oldPg=X8DOC.pg||0;\n  \/* ★ fixed37: 先记下滑动模式下用户滚了多远。容器由 overflow-y:auto 改成 overflow:hidden 后,\n     scrollTop 会被浏览器保留 -> 页面等于整体上移且再也滚不回顶部(「无法翻页回正文顶部」的根因)。 *\/\n  var S=0;\n  try{S=wrap.scrollTop||0;}catch(e0){}\n  X8DOC.mode=pg?'page':'scroll';\n  wrap.className='x8docbd'+(pg?' pg':'');\n  try{wrap.scrollTop=0;wrap.scrollLeft=0;}catch(e1){}\n  if(pg){\n    \/* ★ 页高取「行高的整数倍」, 并且把上下留白放到 wrap 的 padding 上(内层 padding 顶部为 0),\n       这样正文的行网格与页网格都从 0 开始, 每页正好装整数行, 不会出现半行被容器切掉。 *\/\n    var base=x8DocBase();\n    var lh=x8LineH(cg);\n    X8DOC.lh=lh;\n    var h=base;\n    if(lh>1){\n      var lines=Math.floor(base\/lh);\n      if(lines<1)lines=1;\n      h=lines*lh;\n    }\n    X8DOC.h=h;\n    try{wrap.style.height=(h+X8DPAD*2)+'px';}catch(e2){}\n    X8DOC.pgn=Math.max(1,Math.ceil((cg.scrollHeight||0)\/h));\n  }else{\n    X8DOC.h=0;X8DOC.pgn=1;\n    try{wrap.style.height='';}catch(e3){}\n  }\n  if(isNew)X8DOC.pg=0;\n  else if(pg&&!wasPg&&S>0){X8DOC.pg=Math.floor(S\/Math.max(1,X8DOC.h));}\n  if(X8DOC.pg>X8DOC.pgn-1)X8DOC.pg=X8DOC.pgn-1;\n  if(X8DOC.pg<0)X8DOC.pg=0;\n  if(pg)inner.style.transform='translateY(-'+(X8DOC.pg*X8DOC.h)+'px)';\n  else inner.style.transform='';\n  if(!pg&&wasPg&&oldH>0&&oldPg>0){try{wrap.scrollTop=oldPg*oldH;}catch(e4){}}   \/* fixed37: 位置衔接 *\/\n  var m0=document.getElementById('x8m0'),m1=document.getElementById('x8m1');\n  if(m0)m0.className='x8bb'+(pg?'':' on');\n  if(m1)m1.className='x8bb'+(pg?' on':'');\n  x8PgBar();\n  if(!isNew)return;\n  wrap.setAttribute('data-x8b','1');\n  if(X8DOC.bound!==1){\n    X8DOC.bound=1;\n    try{if(window&&window.addEventListener)window.addEventListener('resize',function(){\n      try{if(x8Mode()==='page')x8DocInit();}catch(_r){}\n    },false);}catch(_b){}\n  }\n  \/* 滑动阅读: 滚动过程中容器临时全透明(松手 220ms 后恢复) *\/\n  wrap.addEventListener('scroll',function(){\n    x8DocTrans(true);\n    if(X8DOC.timer)clearTimeout(X8DOC.timer);\n    X8DOC.timer=setTimeout(function(){x8DocTrans(false);},220);\n  },false);\n  \/* 翻页模式: 左右滑动翻页, 翻页过程中容器临时全透明 *\/\n  var sx=0,sy=0,st=0;\n  function pt(e){\n    var t=(e.touches&&e.touches[0])||(e.changedTouches&&e.changedTouches[0])||e||{};\n    return {x:t.clientX||0,y:t.clientY||0};\n  }\n  wrap.addEventListener('touchstart',function(e){var q=pt(e);sx=q.x;sy=q.y;st=Date.now();},false);\n  wrap.addEventListener('touchmove',function(e){\n    if(X8DOC.mode!=='page')return;\n    var q=pt(e);\n    if(Math.abs(q.x-sx)>Math.abs(q.y-sy)&&Math.abs(q.x-sx)>8){\n      if(e.cancelable&&e.preventDefault)e.preventDefault();\n    }\n  },false);\n  wrap.addEventListener('touchend',function(e){\n    if(X8DOC.mode!=='page')return;\n    var q=pt(e),dx=q.x-sx;\n    if(Math.abs(dx)>36)x8PgStep(dx<0?1:-1);\n  },false);\n}\n\n\/* ---------------- fixed36: 容器内链接\/点击一律走内置浏览器 ----------------\n   书源首页自身是 WebView: 点 <a> \/ window.open \/ location.href 造成的页面级导航会被 Legado\n   当书源内链接管 -> 渲染详情页。这里在捕获阶段拦掉容器内所有 <a> 的默认导航, 统一转 x8Open。 *\/\nvar X8TRAP=0,X8TROOT='x8side,x8pane,x8nav,x8pbd,x8phd,x8doc,x8docbd,x8ifw,x8mpv,x8ann,x8annb';\nfunction x8InScope(n){\n  var d=0,ids=','+X8TROOT.split(',').join(',')+',';\n  while(n&&d<20){\n    try{\n      var id=String(n.id==null?'':n.id),cn=String(n.className==null?'':n.className);\n      if(id&&ids.indexOf(','+id+',')>=0)return true;\n      if(cn&&(cn.indexOf('x8side')>=0||cn.indexOf('x8pane')>=0||cn.indexOf('x8nav')>=0\n        ||cn.indexOf('x8doc')>=0||cn.indexOf('x8me')>=0||cn.indexOf('x8rss')>=0\n        ||cn.indexOf('x8nlist')>=0||cn.indexOf('x8mpv')>=0))return true;\n    }catch(e){}\n    n=n.parentNode;d++;\n  }\n  return false;\n}\nfunction x8AnchorOf(n){\n  var d=0;\n  while(n&&d<20){\n    try{if(n.tagName&&String(n.tagName).toUpperCase()==='A')return n;}catch(e){}\n    n=n.parentNode;d++;\n  }\n  return null;\n}\nfunction x8Base(){\n  if(x8Cur&&x8Cur.u)return String(x8Cur.u);\n  try{if(typeof location!=='undefined'&&location.href)return String(location.href);}catch(e){}\n  return '';\n}\nfunction x8TrapClick(e){\n  var t=e&&(e.target||e.srcElement);\n  if(!t)return true;\n  var a=x8AnchorOf(t);\n  if(!a)return true;\n  if(!x8InScope(a))return true;              \/* 容器外(如书源自己的列表)不动 *\/\n  var href='';\n  try{href=String(a.getAttribute('href')||a.href||'');}catch(e1){href='';}\n  try{if(e.preventDefault)e.preventDefault();}catch(e2){}\n  try{if(e.stopPropagation)e.stopPropagation();}catch(e3){}\n  try{if(e.returnValue!==undefined)e.returnValue=false;}catch(e4){}\n  href=href.replace(\/^\\s+|\\s+$\/g,'');\n  if(!href||\/^(javascript:|#|mailto:|tel:|sms:|data:|blob:|about:)\/i.test(href))return false;\n  var ti='';\n  try{ti=String(a.textContent==null?'':a.textContent).replace(\/\\s+\/g,' ');}catch(e5){ti='';}\n  x8Open(x8Abs(href,x8Base()),ti);\n  return false;\n}\nfunction x8TrapInit(){\n  if(X8TRAP)return;\n  X8TRAP=1;\n  try{document.addEventListener('click',x8TrapClick,true);}catch(e){}\n  \/* 覆盖 window.open: 第三方脚本的 window.open 也收口到内置浏览器, 不让首页 WebView 导航 *\/\n  try{\n    if(typeof window!=='undefined'&&window&&typeof window.open==='function'){\n      window.__x8open=window.open;\n      window.open=function(u){try{x8Open(u,'');}catch(e){}return null;};\n    }\n  }catch(e2){}\n}\n\n\/* ---------------- fixed37: 详情页章节目录右侧「大滑块」快速定位 ----------------\n   按住滑块(或点轨道)上下拖动 -> 目录列表跟着滚; 拖动时在滑块左侧显示当前章节名气泡。\n   只用 touch 事件(touch-action:none 保证拖动不会连带滚动页面), 顺带支持鼠标拖动。 *\/\nvar X8SS={list:null,track:null,thumb:null,tip:null,rows:[],drag:0,off:0,mouse:0};\nvar x8SlideNames=[];\nfunction x8SlideRows(){\n  X8SS.rows=[];\n  var list=X8SS.list;\n  if(!list)return;\n  var ns=null;\n  try{ns=list.getElementsByClassName?list.getElementsByClassName('xschap'):null;}catch(e){ns=null;}\n  if(ns&&ns.length){\n    for(var i=0;i<ns.length;i++)X8SS.rows.push({t:String(ns[i].textContent==null?'':ns[i].textContent)});\n    return;\n  }\n  var nm=x8SlideNames||[];\n  for(var j=0;j<nm.length;j++)X8SS.rows.push({t:String(nm[j]==null?'':nm[j])});\n}\nfunction x8SlideSync(){\n  var list=X8SS.list,track=X8SS.track,thumb=X8SS.thumb;\n  if(!list||!track||!thumb)return;\n  var viewH=list.clientHeight||0,allH=list.scrollHeight||0,trH=track.clientHeight||0;\n  if(trH<=0)return;\n  var th=trH;\n  if(allH>viewH&&viewH>0)th=Math.round(trH*viewH\/allH);\n  if(th<34)th=34;\n  if(th>trH)th=trH;\n  thumb.style.height=th+'px';\n  var maxPos=trH-th,maxScr=Math.max(0,allH-viewH);\n  var ratio=maxScr>0?(list.scrollTop||0)\/maxScr:0;\n  if(ratio<0)ratio=0;\n  if(ratio>1)ratio=1;\n  thumb.style.top=Math.round(ratio*(maxPos>0?maxPos:0))+'px';\n  track.className=(allH<=viewH+2)?'x8ssl off':'x8ssl';\n}\nfunction x8SlideTip(ratio){\n  var tip=X8SS.tip;\n  if(!tip)return;\n  var rows=X8SS.rows||[];\n  if(!rows.length){tip.textContent='';return;}\n  var i=Math.round(ratio*(rows.length-1));\n  if(i<0)i=0;\n  if(i>rows.length-1)i=rows.length-1;\n  tip.textContent=rows[i].t||'';\n}\nfunction x8SlideTo(y){\n  var list=X8SS.list,track=X8SS.track,thumb=X8SS.thumb;\n  if(!list||!track||!thumb)return;\n  var tr=null;\n  try{tr=track.getBoundingClientRect();}catch(e){tr=null;}\n  if(!tr)return;\n  var trH=tr.height||track.clientHeight||0;\n  var thumbH=thumb.offsetHeight||0;\n  var maxPos=trH-thumbH;\n  if(maxPos<1)maxPos=1;\n  var pos=(y||0)-(tr.top||0)-X8SS.off;\n  if(pos<0)pos=0;\n  if(pos>maxPos)pos=maxPos;\n  var ratio=pos\/maxPos;\n  var maxScr=Math.max(0,(list.scrollHeight||0)-(list.clientHeight||0));\n  list.scrollTop=Math.round(ratio*maxScr);\n  x8SlideTip(ratio);\n}\nfunction x8SlidePoint(e){\n  var t=(e&&e.touches&&e.touches[0])||(e&&e.changedTouches&&e.changedTouches[0])||e||{};\n  return {y:(t.clientY==null?0:t.clientY)};\n}\nfunction x8SlideDown(e){\n  var track=X8SS.track,thumb=X8SS.thumb;\n  if(!track||!thumb)return;\n  var q=x8SlidePoint(e);\n  var tr=null,thr=null;\n  try{tr=track.getBoundingClientRect();}catch(e1){}\n  try{thr=thumb.getBoundingClientRect();}catch(e2){}\n  X8SS.drag=1;\n  if(tr&&thr&&q.y>=(thr.top||0)&&q.y<=(thr.bottom||0)){\n    X8SS.off=q.y-(thr.top||0);          \/* 按在滑块身上 -> 保持抓握点, 不跳 *\/\n  }else{\n    X8SS.off=Math.round((thumb.offsetHeight||0)\/2);   \/* 按在轨道上 -> 滑块中心跟过来 *\/\n  }\n  if(thumb.className.indexOf('on')<0)thumb.className='x8sst on';\n  if(e&&e.cancelable&&e.preventDefault)e.preventDefault();\n  x8SlideTo(q.y);\n}\nfunction x8SlideMove(e){\n  if(!X8SS.drag)return;\n  if(e&&e.cancelable&&e.preventDefault)e.preventDefault();\n  x8SlideTo(x8SlidePoint(e).y);\n}\nfunction x8SlideUp(){\n  X8SS.drag=0;\n  var thumb=X8SS.thumb;\n  if(thumb)thumb.className='x8sst';\n}\nfunction x8SlideInit(){\n  var list=document.getElementById('xsrules'),track=document.getElementById('x8ssl'),\n      thumb=document.getElementById('x8sst'),tip=document.getElementById('x8sstip');\n  if(!list||!track||!thumb)return;\n  X8SS.list=list;X8SS.track=track;X8SS.thumb=thumb;X8SS.tip=tip;\n  X8SS.drag=0;X8SS.off=0;X8SS.mouse=0;\n  x8SlideRows();\n  try{\n    track.addEventListener('touchstart',x8SlideDown,{passive:false});\n    track.addEventListener('touchmove',x8SlideMove,{passive:false});\n    track.addEventListener('touchend',x8SlideUp,false);\n    track.addEventListener('touchcancel',x8SlideUp,false);\n    track.addEventListener('mousedown',function(e){\n      X8SS.mouse=1;x8SlideDown(e);\n      if(e&&e.preventDefault)e.preventDefault();\n    },false);\n    list.addEventListener('scroll',function(){try{x8SlideSync();}catch(e){}},false);\n    if(window&&window.addEventListener){\n      window.addEventListener('mousemove',function(e){if(X8SS.mouse)x8SlideMove(e);},false);\n      window.addEventListener('mouseup',function(){if(X8SS.mouse){X8SS.mouse=0;x8SlideUp();}},false);\n      window.addEventListener('resize',function(){try{x8SlideSync();}catch(e){}},false);\n    }\n  }catch(_sb){}\n  setTimeout(function(){try{x8SlideSync();}catch(e){}},40);\n  try{x8SlideSync();}catch(e2){}\n}\n\n\/* ===== fixed38: 推荐阅读里的「免费资讯 \/ 留言」(webnote 云便签) =====\n   免费资讯: 只读。https:\/\/webnote.cc\/p\/e17d64cd356df1c6 (note_id=e17d64cd356df1c6, 无密码)\n             取法与「更新公告」完全一致: POST WNAPI+'info\/'  body=note_id&note_pwd=\n             头带 Origin:https:\/\/webnote.cc + Referer。正文用 x8Rich() 渲染(转义 + 链接转「一键跳转」+ 图片缩略图 + .json 一键导入)。\n   留言:     可读可写。https:\/\/webnote.cc\/留言 按 **note_name** 存取:\n             读 wnGet('留言'); 写 wnPut('留言',note_id,note_token,wnPack(文本));\n             失败再 wnRetry('留言',文本)。与「上传到背景图片云」同一套接口。\n   ★两者都进文章容器, 沿用 fixed37 的「缓存命中直接渲染 + 迟到结果作废」。 *\/\nvar X8NFID='e17d64cd356df1c6';\nvar X8NMSG='\\u7559\\u8a00';                 \/* 留言便签的 note_name *\/\nvar X8NMSU='https:\/\/webnote.cc\/%E7%95%99%E8%A8%80';\n\/* 按 note_id 取便签(与 annReq 同通道, 只是 id \/ Referer 可变) *\/\nfunction x8nReq(id){\n  var u=WNAPI+'info\/';\n  var h={'Content-Type':'application\/x-www-form-urlencoded; charset=UTF-8',\n         'Origin':'https:\/\/webnote.cc','Referer':'https:\/\/webnote.cc\/p\/'+id,\n         'X-Requested-With':'XMLHttpRequest',\n         'Accept':'application\/json, text\/javascript, *\/*; q=0.01'};\n  var body='note_id='+encodeURIComponent(id)+'&note_pwd=';\n  return new Promise(function(res,rej){\n    var done=false,tm=null;\n    try{tm=setTimeout(function(){if(done)return;done=true;rej(new Error('请求超时(20秒)'));},20000);}catch(e){}\n    function fin(f,a){if(done)return;done=true;try{tm&&clearTimeout(tm);}catch(e){}f(a);}\n    wnRun(wnChan(u,body,h),0,'').then(function(t){fin(res,t);},function(e){fin(rej,e);});\n  });\n}\nfunction x8Nid(it){return String((it&&it.nid)||X8NFID);}\nfunction x8Nnm(it){return String((it&&it.nm)||X8NMSG);}\nfunction x8NoteLoad(it){return x8nReq(x8Nid(it)).then(function(t){return annParse(t);});}\n\n\/* ---------------- 免费资讯(只读) ---------------- *\/\nfunction x8NoteGo(it){\n  x8PaneHd(it);\n  x8PaneBody('<div class=\"x8load\">正在加载免费资讯…<\/div>');\n  setTimeout(function(){\n    if(x8PaneId!==it.id)return;\n    x8NoteLoad(it).then(function(o){\n      if(x8PaneId!==it.id)return;\n      X8PC[it.id]={kind:'note',title:o.title,text:o.text,raw:o.raw};\n      x8NotePaint(it);\n    },function(e){\n      if(x8PaneId!==it.id)return;\n      x8PaneBody('<div class=\"x8err\">资讯加载失败：'+annEsc((e&&e.message)||'网络异常')+'<\/div>');\n    });\n  },40);\n}\nfunction x8NotePaint(it){\n  var c=(it&&X8PC[it.id])||{};\n  var h='<div class=\"x8note\">';\n  if(c.title)h+='<div class=\"x8ntt\">'+annEsc(c.title)+'<\/div>';\n  h+='<div class=\"x8ntx\">'+x8Rich(c.text||'')+'<\/div>';\n  h+='<div class=\"x8ntip\">内容来自 webnote 云便签（'+annEsc(X8NFID)+'）；点右上角 ↻ 可重新拉取，'\n    +'.json 链接右侧可一键导入书源。<\/div>';\n  x8PaneBody(h+'<\/div>');\n}\n\n\/* ---------------- 留言(可编辑 + 保存) ---------------- *\/\nfunction x8MsgLoad(it){\n  return wnGet(x8Nnm(it)).then(function(d){\n    return {text:wnText(d&&d.note_content),id:(d&&d.note_id)||'',token:(d&&d.note_token)||'',miss:false,err:''};\n  },function(e){\n    \/* 云端还没有这条便签 -> 当作空白, 让用户写完直接保存(保存前会再 wnGet 一次取真实 id\/token) *\/\n    return {text:'',id:'',token:'',miss:true,err:(e&&e.message)||''};\n  });\n}\nfunction x8MsgGo(it){\n  x8PaneHd(it);\n  x8PaneBody('<div class=\"x8load\">正在加载留言…<\/div>');\n  setTimeout(function(){\n    if(x8PaneId!==it.id)return;\n    x8MsgLoad(it).then(function(d){\n      if(x8PaneId!==it.id)return;\n      d.kind='msg';\n      X8PC[it.id]=d;\n      x8MsgPaint(it);\n    },function(e){\n      if(x8PaneId!==it.id)return;\n      x8PaneBody('<div class=\"x8err\">留言加载失败：'+annEsc((e&&e.message)||'网络异常')+'<\/div>');\n    });\n  },40);\n}\nfunction x8MsgPaint(it){\n  var c=(it&&X8PC[it.id])||{};\n  var warn=c.miss?('<span class=\"x8mwn\">未能读到云端内容'+(c.err?'（'+annEsc(c.err)+'）':'')\n      +'——可直接编辑后保存，会尝试新建<\/span>'):'';\n  var h='<div class=\"x8msg\">'\n    +'<div class=\"x8mrd\">留言内容（可直接编辑，改完点「保存到留言云」）<\/div>'\n    +'<textarea class=\"x8mtxa\" id=\"x8mtxa\" spellcheck=\"false\" placeholder=\"在这里写留言…\"'\n    +' oninput=\"x8MsgDirty(this.value)\">'+annEsc(c.text||'')+'<\/textarea>'\n    +'<div class=\"x8mrow\">'\n    +'<button class=\"x8bb x8mp\" onclick=\"x8MsgSave()\">保存到留言云<\/button>'\n    +'<button class=\"x8bb\" onclick=\"x8MsgReload()\">\\u21bb 重新加载<\/button>'\n    +'<button class=\"x8bb\" onclick=\"x8MsgOpen()\">\\u2197 浏览器打开<\/button>'\n    +'<\/div>'\n    +'<div class=\"x8mst\" id=\"x8mst\">'+warn+'<\/div>'\n    +'<div class=\"x8mtip\">读 \/ 写都走 note_name=<b>'+annEsc(X8NMSG)+'<\/b> 的云便签，'\n    +'与「上传到背景图片云」是同一套接口（api-webnote.txttool.cn\/netcut\/note\/）。<\/div>'\n    +'<\/div>';\n  x8PaneBody(h);\n}\nfunction x8MsgSt(m,cls){\n  var s=document.getElementById('x8mst');\n  if(!s)return;\n  s.className='x8mst'+(cls?' '+cls:'');\n  s.textContent=String(m==null?'':m);\n}\n\/* 输入内容同步进缓存 -> 切分类走一圈回来草稿还在(保存时以文本框为准) *\/\nfunction x8MsgDirty(v){\n  var it=x8Cur;if(!it)return;\n  var c=X8PC[it.id];if(c&&c.kind==='msg')c.text=String(v==null?'':v);\n}\nfunction x8MsgTxt(){\n  var ta=document.getElementById('x8mtxa');\n  return ta&&ta.value!=null?String(ta.value):'';\n}\n\/* 保存: 先 wnGet 拿最新 id\/token 再 wnPut(与 wnUp 同款); 失败再 wnRetry 一次 *\/\nfunction x8MsgSave(){\n  var it=x8Cur;if(!it||it.k!=='msg')return;\n  var nm=x8Nnm(it),txt=x8MsgTxt();\n  x8MsgSt('正在保存到留言云…','wait');\n  var done=function(){\n    var c=X8PC[it.id]||{};c.kind='msg';c.text=txt;c.miss=false;c.err='';\n    X8PC[it.id]=c;\n    x8MsgSt('\\u2714 已保存到留言云','ok');\n  };\n  var first=wnGet(nm).then(function(d){return wnPut(nm,d.note_id,d.note_token,wnPack(txt));},\n                         function(){return wnPut(nm,'','',wnPack(txt));});\n  first.then(done,function(){return wnRetry(nm,txt).then(done);})\n       ['catch'](function(e){x8MsgSt('\\u2718 保存失败：'+((e&&e.message)||e),'no');});\n}\nfunction x8MsgReload(){\n  var it=x8Cur;if(!it||it.k!=='msg')return;\n  x8MsgSt('正在重新加载…','wait');\n  x8MsgLoad(it).then(function(d){\n    if(!x8Cur||x8Cur.id!==it.id)return;\n    d.kind='msg';\n    X8PC[it.id]=d;\n    x8MsgPaint(it);\n    x8MsgSt(d.miss?'云端还没有这条便签（已清空）':'已从云端重新加载','ok');\n  },function(e){x8MsgSt('\\u2718 重新加载失败：'+((e&&e.message)||e),'no');});\n}\nfunction x8MsgOpen(){var it=x8Cur;if(it)x8Open(it.u||X8NMSU,it.n||X8NMSG);}\n\n\/* ===== fixed39: 文章容器统一文本渲染 =====\n   ★核心约定(用户要求): 侧边栏文章容器里的链接**一律不渲染成 <a>**。\n   在 WebView 里点 <a> 就是一次页面级导航, 会被书源当内链去渲染详情页 —— 所以改成\n   「纯文本 + 一键跳转按钮」, 出口统一收口到内置浏览器(java.startBrowser)。\n   · 图片链接 -> 缩略图, 点缩略图就地放大(全屏遮罩 #x8lb)\n   · .json 链接 -> 额外附「⤓ 一键导入」\n   仅供 note(免费资讯) 与 text(纯文本容器) 使用; 导航列表另有 x8NavList, RSS 另有 x8RssItem。 *\/\nfunction x8Rich(txt){\n  var raw=String(txt==null?'':txt),re=\/https?:\\\/\\\/[A-Za-z0-9\\-._~:\\\/?#\\[\\]@!$&'()*+,;=%]+\/gi,out='',last=0,m;\n  while((m=re.exec(raw))!==null){\n    var u=m[0],tail='',mt=u.match(\/[.,;:!?)\\]}'\"]+$\/);\n    if(mt){tail=mt[0];u=u.slice(0,u.length-tail.length);}\n    out+=annEsc(raw.slice(last,m.index))+x8Link(u)+annEsc(tail);\n    last=m.index+m[0].length;\n  }\n  return out+annEsc(raw.slice(last));\n}\n\/* 单条链接 -> 「纯文本 \/ 缩略图」 + 一键跳转按钮 (+ .json 一键导入)。\n   URL 只放进 data-u(HTML 转义), onclick 用 this 取 —— 不用把它拼进 JS 字符串字面量。 *\/\nfunction x8Link(u){\n  var e=String(u||'');if(!e)return '';\n  var o='';\n  if(x8IsImg(e))o+='<span class=\"x8iw\"><img class=\"x8th\" src=\"'+annEsc(e)+'\" data-u=\"'+annEsc(e)\n    +'\" alt=\"预览图\" onclick=\"x8ZoomEl(this)\"><\/span>';\n  else o+='<span class=\"x8lt\">'+annEsc(e)+'<\/span>';\n  o+='<button class=\"x8bb x8jump\" data-u=\"'+annEsc(e)+'\" onclick=\"x8LnkOpen(this)\">一键跳转<\/button>';\n  if(annIsJson(e))o+='<span class=\"animp\" data-u=\"'+annEsc(e)+'\" onclick=\"annImp(this)\">\\u2913 一键导入<\/span>';\n  return o;\n}\nfunction x8LnkOpen(el){var u=el&&el.getAttribute?el.getAttribute('data-u'):'';if(u)x8Open(u,u);}\n\/* ---------- 图片就地放大 ---------- *\/\nfunction x8ZoomEl(el){var u=el&&el.getAttribute?el.getAttribute('data-u'):'';x8Zoom(u);}\nfunction x8Zoom(u){\n  u=String(u==null?'':u).replace(\/^\\s+|\\s+$\/g,'');\n  if(!u)return;\n  var b=document.getElementById('x8lb'),i=document.getElementById('x8lbi');\n  if(!b||!i)return;\n  try{i.setAttribute('src',u);}catch(e){}\n  b.className='x8lb on';\n}\nfunction x8ZoomClose(){var b=document.getElementById('x8lb');if(b)b.className='x8lb';}\n\/* ---------- 纯文本容器(k='text') ---------- *\/\nfunction x8TextGo(it){\n  x8PaneHd(it);\n  X8PC[it.id]={kind:'text',text:String(it.txt==null?'':it.txt)};\n  x8TextPaint(it);\n}\nfunction x8TextPaint(it){\n  var c=(it&&X8PC[it.id])||{};\n  var s=c.text!=null?c.text:String((it&&it.txt)||'');\n  x8PaneBody('<div class=\"x8txt\">'+x8Rich(s)+'<\/div>');\n}\n\n\/* ---------------- 启动 ---------------- *\/\nfunction x8NavInit(){\n  \/* fixed39: 重进首页**不再展开**顶栏分类 \/ 侧边栏 \/ 文章容器(用户要求: 一进来就占掉大半屏很碍事)。\n     以前从 KX8S 恢复上次展开的 cat -> 现在一律复位成收起; 状态照旧继续写(以后要用随时可恢复)。 *\/\n  x8Cat=-1;x8Sel='';\n  x8Stamp();\n}\ntry{x8NavInit();}catch(_x8n){}\ntry{x8TrapInit();}catch(_x8t){}\n\n","startStyle":"\/* v54 门户首页样式：所有可见容器的底色\/透明度\/边框\/圆角与各字段字体均由外观设置下发 *\/\n*{margin:0;padding:0;-webkit-box-sizing:border-box;box-sizing:border-box}\n:root{color-scheme:light only;supported-color-schemes:light only}\nhtml{-webkit-text-size-adjust:100%;color-scheme:light only}\nbody{font-size:15px;line-height:1.6;font-family:-apple-system,BlinkMacSystemFont,\"Helvetica Neue\",Helvetica,Arial,sans-serif;\n background:var(--pagebg);color:var(--ttx);padding:12px 12px 46px}\n#bgimg{position:fixed;left:0;top:0;width:100%;height:100%;object-fit:cover;opacity:var(--bga);z-index:0;pointer-events:none;display:none}\n.wrap{position:relative;z-index:1;max-width:720px;margin:0 auto}\n\/* v57 顶部标题框: 支持自定义背景图(网址或本地路径) + 自定义主\/副标题文字。\n   背景图铺满整个框, 上面盖一层可调不透明度的遮罩, 保证文字在亮\/暗背景上都读得清。 *\/\n.hero{position:relative;background:var(--herobg);border:var(--herobdw) solid var(--herobdc);\n border-radius:var(--herord);margin-bottom:10px;color:var(--herotx);overflow:hidden}\n.herobg{position:absolute;left:0;top:0;right:0;bottom:0;background-image:var(--herobi);\n background-size:var(--herobfit);background-position:center;background-repeat:no-repeat;\n opacity:calc(var(--heroba) \/ 100);pointer-events:none}\n.heroov{position:absolute;left:0;top:0;right:0;bottom:0;background:var(--heroovc);\n opacity:calc(var(--heroov) \/ 100);pointer-events:none}\n.heroin{position:relative;padding:var(--heropv) var(--heroph);min-height:var(--herobh);\n display:flex;flex-direction:column;justify-content:center}\n.hero .hlg{font-size:var(--herofs);font-weight:800;line-height:1.3;word-break:break-word}\n.hero .hsb{font-size:var(--herosubfs);opacity:.88;margin-top:4px;word-break:break-word}\n.sbox{display:flex;gap:8px;margin-bottom:2px}\n.sbox input{flex:1;min-width:0;padding:9px 13px;border:var(--sbdw) solid var(--sbdc);border-radius:var(--srd);\n background:var(--sbg);color:var(--stx);font-size:var(--sfs);outline:none;-webkit-appearance:none}\n.sbox button{flex:none;padding:9px 18px;border:var(--sbtnbdw) solid var(--sbtnbdc);border-radius:var(--sbtnrd);\n background:var(--sbtnbg);color:var(--sbtntx);font-size:var(--sbtnfs);font-weight:600}\n.tabs{display:flex;gap:var(--tabgap);overflow-x:auto;-webkit-overflow-scrolling:touch;padding:10px 0 10px}\n.tabs::-webkit-scrollbar{display:none}\n\/* fixed33: .tabs 是横向滚动容器(overflow-x:auto → 另一轴也被裁)，角标上溢 7px、右溢 9px，故上方留 10px 并在末尾垫 10px，避免被裁 *\/\n.tabs::after{content:'';flex:none;width:10px}\n.tab{flex:none;padding:var(--tabpv) var(--tabph);border:var(--tabbdw) solid var(--tabbdc);border-radius:var(--tabrd);\n background:var(--tabbg);color:var(--tabtx);font-size:var(--tabfs);white-space:nowrap;cursor:pointer}\n.tab:active{opacity:.7}\n.tab.on{background:var(--tabonbg);color:var(--tabontx);font-weight:600}\n.subbar{display:flex;gap:8px;align-items:center;margin-bottom:6px}\n.subs{display:flex;gap:var(--subgap);overflow-x:auto;-webkit-overflow-scrolling:touch;flex:1;min-width:0;padding:2px 0}\n.subs::-webkit-scrollbar{display:none}\n.sub{flex:none;padding:var(--subpv) var(--subph);border:var(--subbdw) solid var(--subbdc);border-radius:var(--subrd);\n background:var(--subbg);color:var(--subtx);font-size:var(--subfs);white-space:nowrap;cursor:pointer}\n.sub.on{background:var(--subonbg);color:var(--subontx);font-weight:600}\n.pst{flex:none;padding:var(--pstpv) var(--pstph);border:var(--pstbdw) solid var(--pstbdc);border-radius:var(--pstrd);\n background:var(--pstbg);color:var(--psttx);font-size:var(--pstfs);font-weight:600;text-decoration:none;white-space:nowrap}\n.pst:active{opacity:.75}\n\/* 列表卡片：position:relative 供综合信息栏绝对定位到底部 *\/\n.it{position:relative;display:block;background:var(--cardbg);border:var(--cardbdw) solid var(--cardbdc);\n border-radius:var(--cardrd);box-shadow:var(--cardsh);\n padding:var(--cardpt) var(--cardpr) var(--itpb) var(--cardpl);\n margin-top:var(--cardgap);text-decoration:none;color:inherit;overflow:hidden}\n.it:active{opacity:.75}\n.row1{display:flex;gap:var(--avgap);align-items:flex-start}\n.av{width:var(--avsz);height:var(--avsz);border-radius:var(--avrd);border:var(--avbdw) solid var(--avbdc);\n background:var(--avbg);-o-object-fit:cover;object-fit:cover;flex:none}\n\/* v58 头像外框: .avw 只作定位容器; .avf 是与头像同尺寸的绝对定位装饰层,\n   默认铺满头像, 再靠 scale 放大到「外框尺寸」(不用 calc, 老 WebView 更稳)。\n   变量都带 fallback, applyStyle 跑之前也不会炸。 *\/\n.avw{position:relative;flex:none;width:var(--avsz);height:var(--avsz)}\n.avw .av{display:block}\n.avf{position:absolute;left:0;top:0;right:0;bottom:0;pointer-events:none;z-index:1;\n transform:translate(var(--frx,0px),var(--fry,0px)) scale(var(--frscale,1));\n background-image:var(--frimg,none);background-size:100% 100%;\n background-position:center;background-repeat:no-repeat;opacity:var(--fra,1)}\n.avf.under{z-index:0}\n.tt{flex:1;min-width:0;font-size:var(--ttfs);font-weight:var(--ttfw);line-height:var(--ttlh);\n letter-spacing:var(--ttls);color:var(--tttx);font-style:var(--ttit);text-shadow:var(--ttsh);\n \/* 先写死 2 行做兜底, 再写 var(): 老 WebView 不支持 var() 取行数时会保持上一行的固定值 *\/\n display:-webkit-box;-webkit-line-clamp:2;-webkit-line-clamp:var(--ttlines);\n -webkit-box-orient:vertical;overflow:hidden;word-break:break-word}\n\/* 摘要：独占整行，挤进头像与图片的留白，按行数换行截断 *\/\n.ms{margin-top:var(--mstop);font-size:var(--msfs);font-weight:var(--msfw);line-height:var(--mslh);\n letter-spacing:var(--msls);color:var(--mstx);font-style:var(--msit);text-shadow:var(--mssh);\n display:-webkit-box;-webkit-line-clamp:2;-webkit-line-clamp:var(--mslines);\n -webkit-box-orient:vertical;overflow:hidden;word-break:break-word}\n\/* 图片行：高度固定，图片宽度由 JS 按行宽\/图宽\/间距算出后撑满整行 *\/\n.igs{display:flex;gap:var(--iggap);margin-top:var(--igtop);overflow:hidden}\n.ig{display:block;flex:none;border-radius:var(--igrd);border:var(--igbdw) solid var(--igbdc);\n -o-object-fit:var(--igfit);object-fit:var(--igfit);background:#E8EAF0;opacity:calc(var(--iga) \/ 100)}\n\/* 综合信息栏：常驻卡片底部，横跨整行（覆盖头像与图片的留白），固定一行 *\/\n.mt{position:absolute;left:var(--cardpl);right:var(--cardpr);bottom:var(--mtbott);\n font-size:var(--mtfs);font-weight:var(--mtfw);letter-spacing:var(--mtls);color:var(--mttx);\n font-style:var(--mtit);text-shadow:var(--mtsh);line-height:1.5;\n white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n.mt .mc{font-style:normal}\n\/* v59 最后发表: 内联(<i>)元素, 在这行 nowrap 的 .mt 里自然流动,\n   自动贴近前一个元素(观看数\/回复数)的尾部 —— 不需要额外的定位。\n   初始为空 -> :empty 完全隐藏(不占空间、不显示分隔符);\n   异步回填后自动出现, 分隔符用 ::before 补上(与「分隔符」设置同步)。 *\/\n.mt .lp:empty{display:none}\n.mt .lp{color:var(--lptx)}\n.mt .lp:not(:empty)::before{content:var(--mtsep,' · ');opacity:.5}\n.mt .sep{opacity:.5}\n\/* 置顶帖：只有标题一行 *\/\n.it.tp{display:flex;align-items:center;gap:8px;padding-top:var(--cardpt);padding-bottom:var(--cardpt);\n background:var(--tpbg);border:var(--tpbdw) solid var(--tpbdc)}\n.it.tp .tt{flex:1;min-width:0;color:var(--tptx);-webkit-line-clamp:1;-webkit-line-clamp:1}\n.it.ann{display:flex;align-items:center;gap:8px;padding-top:var(--cardpt);padding-bottom:var(--cardpt);\n background:var(--annbg);border:var(--annbdw) solid var(--annabdc)}\n.it.ann .tt{flex:1;min-width:0;color:var(--anntx)}\n.it.ann .tt a{color:var(--anntx);text-decoration:none}\n.emp{background:var(--empbg);border-radius:var(--emprd);padding:22px;text-align:center;color:var(--emptx);\n font-size:var(--empfs);margin-top:var(--cardgap)}\n.cnt{font-size:var(--secfs);color:var(--sectx);margin:10px 4px 0}\n.pg{margin-top:14px;display:flex}\n.pg a{flex:1;max-width:220px;margin:0 auto;text-align:center;padding:10px;border-radius:var(--pgrd);\n border:var(--pgbdw) solid var(--pgbdc);background:var(--pgbg);color:var(--pgtx);font-size:var(--pgfs);text-decoration:none}\n.fab{position:fixed;right:var(--fabx);bottom:var(--faby);width:var(--fabsz);height:var(--fabsz);\n border-radius:var(--fabr);border:var(--fabbdw) solid var(--fabbdc);background-color:var(--fabbgcol);\n background-image:var(--fabbgimg);background-size:var(--fabbgsz);background-position:center;background-repeat:no-repeat;\n box-shadow:var(--fabsh);color:var(--fabtx);font-size:var(--fabfs);z-index:60;cursor:pointer;padding:0;line-height:1;\n display:flex;align-items:center;justify-content:center;-webkit-tap-highlight-color:transparent}\n.modal{position:fixed;left:0;top:0;right:0;bottom:0;background:rgba(0,0,0,.45);z-index:80;display:none;\n align-items:flex-end;justify-content:center}\n.modal.on{display:flex}\n.mbox{width:100%;max-width:560px;max-height:86vh;overflow-y:auto;background:var(--mbg);color:var(--mtx);\n border-radius:16px 16px 0 0;padding:14px 14px 26px;-webkit-overflow-scrolling:touch}\n.mbox h3{margin:2px 0 8px;font-size:16px}\n\/* v58 面板头部: 标题 + 右上 ✕ 关闭 *\/\n.phd{display:flex;align-items:center;gap:8px}\n.phd h3{flex:1;min-width:0;margin:2px 0 8px}\n.phd .x{flex:none;width:30px;height:30px;padding:0;line-height:1;font-size:14px;cursor:pointer;\n border:1px solid var(--dbdc);border-radius:50%;background:var(--btnbg);color:var(--btntx)}\n.phd .x:active{opacity:.7}\n\/* v58 底部「完成」常驻: 面板可滚很长, sticky 保证滚到哪都点得到 *\/\n.row.done{position:-webkit-sticky;position:sticky;bottom:0;background:var(--mbg);\n padding:8px 0 10px;margin-top:10px}\n.mbox h4{margin:12px 0 6px;font-size:13px;color:var(--hdtx)}\n.sec{border:1px solid var(--dbdc);border-radius:var(--drd);margin-bottom:8px;background:var(--dbg);overflow:hidden}\n.sech{display:flex;align-items:center;justify-content:space-between;padding:9px 11px;background:var(--sechbg);\n font-size:13px;font-weight:700;color:var(--hdtx);cursor:pointer}\n.sech span{font-size:12px;opacity:.7}\n.secb{padding:6px 11px 10px}\n.srow{display:flex;align-items:center;gap:8px;margin:6px 0}\n.srow>label{flex:0 0 40%;font-size:12px;color:var(--lbtx);line-height:1.35}\n.srow input[type=range]{flex:1;min-width:0}\n.srow input[type=text],.srow select,.srow input[type=number]{flex:1;min-width:0;padding:6px 8px;border:1px solid var(--dbdc);\n border-radius:8px;background:var(--sbg);color:var(--stx);font-size:13px}\n.sval{flex:0 0 40px;text-align:right;font-size:12px;color:var(--lbtx)}\n.cpk{flex:1;display:flex;align-items:center;gap:8px;padding:5px 8px;border:1px solid var(--dbdc);border-radius:8px;\n background:var(--sbg);color:var(--stx)}\n.csw{width:22px;height:22px;border-radius:6px;border:1px solid var(--dbdc);display:block;background:#fff}\n.chex{font-size:12px}\n.sw{flex:1;display:flex;gap:6px}\n.dec-sw{flex:1;display:flex;gap:6px}\n.msw{flex:1;padding:10px 0;border:1px solid var(--dbdc);border-radius:8px;background:var(--sbg);color:var(--stx);font-size:14px}\n.msw.on{background:var(--pk);color:#fff;border-color:var(--pk)}\n\/* 一律用 flex-wrap 而非 grid：v25 已实测部分阅读 App 的 WebView 不支持 grid，\n   grid 规则被整条丢弃后按钮会各占满一行并露右侧空白。 *\/\n.row{display:flex;flex-wrap:wrap;gap:8px;margin:8px 0}\n.row>*{flex:1 1 auto;min-width:0}\n.row2{display:flex;flex-wrap:wrap;gap:8px;margin:8px 0}\n.row2>*{flex:1 1 45%;min-width:0}\n.bt{padding:9px 6px;border:1px solid var(--dbdc);border-radius:10px;background:var(--btnbg);color:var(--btntx);font-size:13px;white-space:nowrap}\n.bt.pri{background:var(--pk);color:#fff;border-color:var(--pk)}\n.bt.warn{background:#FFF1F0;color:#D4380D;border-color:#FFA39E}\n.bt:active{opacity:.7}\n.ib{padding:6px 10px;border:1px solid var(--dbdc);border-radius:8px;background:var(--sbg);color:var(--stx);font-size:13px}\n.hint{font-size:11px;line-height:1.7;color:var(--hintx);margin:6px 0}\ntextarea{width:100%;padding:8px;border:1px solid var(--dbdc);border-radius:10px;background:var(--sbg);color:var(--stx);font-size:12px}\n.pvwrap{position:relative;display:inline-block;margin:0 8px 8px 0}\n.pv{width:62px;height:44px;-o-object-fit:cover;object-fit:cover;border-radius:8px;border:1px solid var(--dbdc)}\n.pvx{position:absolute;right:-6px;top:-6px;width:20px;height:20px;line-height:18px;text-align:center;border-radius:50%;\n background:#E5484D;color:#fff;font-size:13px;font-weight:700}\n.profrow{display:flex;gap:6px;align-items:center;margin-bottom:6px}\n.cprev{display:flex;gap:10px;margin-bottom:8px}\n.cpv{flex:1;text-align:center;font-size:11px;color:var(--lbtx)}\n.cpv i{display:block;height:34px;border-radius:8px;border:1px solid var(--dbdc);background:#fff;margin-bottom:3px}\n.svbox{position:relative;height:150px;border-radius:10px;border:1px solid var(--dbdc);overflow:hidden;\n background:linear-gradient(to top,#000,rgba(0,0,0,0)),linear-gradient(to right,#fff,#f00);touch-action:none}\n.svcur{position:absolute;width:14px;height:14px;margin:-7px 0 0 -7px;border:2px solid #fff;border-radius:50%;\n box-shadow:0 0 0 1px rgba(0,0,0,.4)}\n.huebar{position:relative;height:18px;margin-top:8px;border-radius:9px;border:1px solid var(--dbdc);touch-action:none;\n background:linear-gradient(to right,#f00,#ff0,#0f0,#0ff,#00f,#f0f,#f00)}\n.huecur{position:absolute;top:-2px;width:12px;height:22px;margin-left:-6px;border:2px solid #fff;border-radius:4px;\n box-shadow:0 0 0 1px rgba(0,0,0,.4)}\n.rgbrow{display:flex;align-items:center;gap:6px;margin-top:8px;font-size:12px;color:var(--lbtx)}\n.rgbrow label{flex:none;width:26px}\n.rgbrow input{flex:1;min-width:0;padding:6px 8px;border:1px solid var(--dbdc);border-radius:8px;\n background:var(--sbg);color:var(--stx);font-size:13px}\n.preset{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px}\n.cpi{width:28px;height:28px;border-radius:6px;border:1px solid var(--dbdc);display:block}\n.tip{position:fixed;left:50%;bottom:88px;-webkit-transform:translateX(-50%);transform:translateX(-50%);\n background:rgba(0,0,0,.8);color:#fff;padding:8px 16px;border-radius:20px;font-size:13px;z-index:99;display:none;\n pointer-events:none;max-width:80%;text-align:center}\n.tip.on{display:block}\n\n\/* v59d: 悬浮按钮长按拖动 —— 禁止选中内部文字\/图案, 禁止长按弹出系统菜单 *\/\n.fab,.fab *{-webkit-user-select:none;-moz-user-select:none;user-select:none;-webkit-touch-callout:none;-webkit-user-drag:none}\n.fab{touch-action:none}\n\/* ================= B批: 铃铛悬浮按钮(左上角) + 通知弹窗 ================= *\/\n.fab.bell{left:var(--bellx,14px);top:var(--bella,14px);right:auto;bottom:auto;z-index:61}\n.bellDot{position:absolute;top:-4px;right:-4px;min-width:16px;height:16px;padding:0 4px;border-radius:9px;background:#F5222D;color:#fff;font-size:10px;font-weight:700;line-height:16px;text-align:center;display:none;box-shadow:0 0 0 2px var(--mbg,#fff)}\n.bellDot.on{display:inline-block}\n.nb-empty{padding:26px 10px;text-align:center;color:var(--hintx,#999);font-size:12px}\n.nb-item{display:block;padding:10px 11px;border-bottom:1px solid var(--dbdc,#eee);text-decoration:none;color:var(--mtx,#222)}\n.nb-item:last-child{border-bottom:0}\n.nb-item:active{background:rgba(0,0,0,.04)}\n.nb-top{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--hintx,#999)}\n.nb-type{flex:none;font-size:11px;padding:1px 6px;border-radius:8px;font-weight:600}\n.nb-type.reply{background:var(--pk,#4A6CF7);color:#fff}\n.nb-type.sys{background:#FFF1F0;color:#D4380D}\n.nb-text{font-size:13px;line-height:1.5;margin-top:4px}\n.nb-act{font-size:12px;color:var(--pk,#4A6CF7);margin-top:5px}\n\n\/* ===== 小说站 (千白羽小说站) ===== *\/\n.xsres{display:block;margin-top:10px}\n.xsbar{display:flex;gap:8px;overflow-x:auto;-webkit-overflow-scrolling:touch;padding:2px 0 8px;flex-wrap:nowrap}\n.xsbar::-webkit-scrollbar{display:none}\n.xsbt{flex:none;padding:8px 14px;border:1px solid var(--tabbdc,#E4E7F0);border-radius:10px;background:var(--tabbg,#fff);color:var(--tabtx,#333);font-size:14px;white-space:nowrap;cursor:pointer}\n.xsbt:active{opacity:.7}\n.xsbt.on{background:var(--pk,#4A6CF7);color:#fff;border-color:var(--pk,#4A6CF7);font-weight:600}\n.xsbody{min-height:100px}\n.xslist{display:block}\n.xsitem{display:flex;gap:10px;background:var(--cardbg,#fff);border:1px solid var(--cardbdc,#E4E7F0);border-radius:12px;padding:10px;margin-top:8px;box-shadow:var(--cardsh,none);cursor:pointer;overflow:hidden}\n.xsitem:active{opacity:.75}\n.xsimg{flex:none;width:64px;height:86px;border-radius:6px;overflow:hidden;background:#E8EAF0}\n.xscv{width:100%;height:100%;object-fit:cover;display:block}\n.xsinfo{flex:1;min-width:0;display:flex;flex-direction:column}\n.xsttl{font-size:15px;font-weight:600;color:var(--tttx,#222);line-height:1.4;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;word-break:break-word}\n.xsauth{font-size:12px;color:var(--lbtx,#888);margin-top:2px}\n.xsintro{font-size:12px;color:var(--mstx,#666);line-height:1.5;margin-top:4px;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}\n.xsdet{padding:2px 0}\n.xsttl.big{font-size:18px;font-weight:700;margin-bottom:6px;display:block}\n.xsintro{margin-bottom:8px}\n.xsdetbar{display:flex;gap:8px;margin:8px 0}\n.xsbt2{flex:none;padding:8px 16px;border:1px solid var(--dbdc,#E4E7F0);border-radius:10px;background:var(--btnbg,#f5f6fa);color:var(--btntx,#333);font-size:13px;white-space:nowrap;text-align:center;cursor:pointer}\n.xsbt2:active{opacity:.75}\n.xsbt2.pri{background:var(--pk,#4A6CF7);color:#fff;border-color:var(--pk,#4A6CF7)}\n.xsrules{margin-top:6px}\n.xschap{display:block;padding:10px 12px;border-bottom:1px solid var(--cardbdc,#F0F0F0);font-size:14px;color:var(--tttx,#333);cursor:pointer}\n.xschap:active{background:rgba(0,0,0,.04)}\n.xstext{font-size:var(--xsfs,17px);line-height:var(--xslh,1.85);color:var(--xstx,#222);font-weight:var(--xsfw,400);letter-spacing:var(--xsls,0);word-break:break-word}\n.xstext br{margin:2px 0}\n.xsnav{display:flex;gap:8px;margin-top:12px}\n\/* 小说站固定入口: 与论坛分类栏同行, 不参与水平滚动 *\/\n.tabsrow{display:flex;align-items:center;gap:8px}\n.tabs{flex:1;min-width:0}\n.xstab{flex:none;padding:var(--pstpv,8px) var(--pstph,14px);border:1px solid var(--pk,#4A6CF7);border-radius:var(--pstrd,10px);background:var(--pk,#4A6CF7);color:#fff;font-size:var(--pstfs,13px);font-weight:600;white-space:nowrap;cursor:pointer;box-shadow:0 2px 6px rgba(0,0,0,.18)}\n.xstab:active{opacity:.75}\n.xstab.on{background:#fff;color:var(--pk,#4A6CF7);border-color:var(--pk,#4A6CF7)}\n.xsupd{font-size:12px;color:var(--lbtx,#888);margin:2px 0;white-space:normal;overflow-wrap:anywhere;word-break:break-word;line-height:1.5}\n.xsrm{font-size:11px;color:#e33;margin-top:4px;cursor:pointer}\n.xsreadjump{display:flex;align-items:center;gap:8px;margin:8px 0;padding:11px 14px;border-radius:10px;background:var(--pk,#4A6CF7);color:#fff;cursor:pointer;box-shadow:0 2px 8px rgba(74,108,247,.28)}\n.xsreadjump:active{opacity:.82}\n.xsrj-label{flex:none;font-size:12px;opacity:.92;border:1px solid rgba(255,255,255,.6);border-radius:6px;padding:2px 7px;font-weight:600}\n.xsrj-ch{flex:1;min-width:0;font-size:14px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n.xsrj-arw{flex:none;font-size:15px;opacity:.9}\n.xs-cur{background:rgba(74,108,247,.14)!important;color:var(--pk,#4A6CF7)!important;font-weight:600}\n.xsread{font-size:12px;color:var(--pk,#4A6CF7);margin-top:3px;font-weight:600}\n\n.xshead{overflow:hidden;margin-bottom:10px}\n.xscover{float:left;width:96px;height:128px;border-radius:8px;overflow:hidden;background:#E8EAF0;border:1px solid var(--cardbdc,#E4E7F0);margin:0 12px 6px 0}\n.xsintro{cursor:pointer}\n.xsintro.exp{display:block;-webkit-line-clamp:unset;overflow:visible}\n.xsloadind{text-align:center;font-size:12px;color:var(--lbtx,#888);padding:12px 0}\n\/* ===== v63 置顶帖容器 \/ 展开折叠 ===== *\/\n.tpbox{margin-bottom:10px}\n.tphd{display:flex;align-items:center;gap:6px;padding:7px 10px;background:var(--tpbg);\n border:var(--tpbdw) solid var(--tpbdc);border-radius:10px 10px 0 0;cursor:pointer;-webkit-user-select:none;user-select:none}\n.tphd .tphn{flex:1;min-width:0;font-size:12px;font-weight:700;color:var(--tptx)}\n.tphd .tphr{font-size:11px;color:var(--tptx);transition:transform .15s}\n.tpbox.open .tphd .tphr{transform:rotate(180deg)}\n.tplst{border-radius:0 0 10px 10px;overflow:hidden}\n.tplst .it.tp.tpc{border-radius:0}\n.it.tp.tpc{display:block;padding:0}\n.tpc .tprow{display:flex;align-items:center;gap:8px;padding-top:var(--cardpt);padding-bottom:var(--cardpt);cursor:pointer}\n.tpc .tparw{font-style:normal;font-size:10px;color:var(--tptx);flex:0 0 auto;transition:transform .15s}\n.tpc.open .tparw{transform:rotate(90deg)}\n.tpc .tpmeta{flex:0 0 auto;max-width:48%;font-size:11px;color:var(--mttx);opacity:.9;\n overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.tpc .tpbd{display:none}\n.tpc.open .tpbd{display:block}\n.tpc .tpfull{padding:0 10px 4px}\n.tpc .tpfl{display:flex;flex-wrap:wrap;gap:3px 10px;font-size:11px;color:var(--mttx)}\n.tpc .tpi{font-style:normal}\n.tpc .tpi b{color:var(--tptx)}\n.tpc .tpi.lp{color:var(--lptx)}\n.tpc .tpext{padding:0 10px 9px;font-size:12px;line-height:1.65;color:var(--tptx)}\n.tpc .tpsum,.tpc .tplast{margin-top:5px;opacity:.92;word-break:break-word}\n.tpc .tpsum i,.tpc .tplast i{font-style:normal;display:inline-block;margin-right:6px;padding:0 5px;\n border-radius:8px;background:var(--tpbdc);color:var(--tptx);font-size:10px}\n.tpc .tpld{font-size:11px;color:var(--mttx);opacity:.7}\n\n\/* ===== fixed20: 分类栏排序 ===== *\/\n.catord{display:flex;flex-direction:column;gap:6px;margin:7px 0}\n.corow{display:flex;align-items:center;gap:8px;padding:7px 9px;border:1px solid var(--dbdc);border-radius:10px;background:var(--btnbg)}\n.corow .con{flex:1;min-width:0;font-size:13px;color:var(--btntx);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.corow .cob{display:flex;gap:5px;flex:0 0 auto}\n.bt.sm{padding:5px 11px;font-size:12px;flex:0 0 auto;white-space:nowrap}\n\n\/* ===== fixed21: 置顶帖 3 态折叠 ===== *\/\n.tpbox:not(.open) .tplst{display:none}\n.tpbox:not(.open) .tphr{transform:rotate(-90deg)}\n.tphr{transition:transform .15s}\n\n\/* fixed22: 长按展开最近3回复容器 *\/\n.itw{display:block;position:relative}\n.itw .lp3{display:none;margin-top:8px;padding-top:8px;border-top:1px solid var(--cardbdc);\n font-size:13px;line-height:1.55;color:var(--mttx)}\n.itw .lp3.open{display:block}\n.itw .lp3hd{font-size:12px;font-weight:700;opacity:.85;margin-bottom:4px}\n.itw .lp3it{padding:4px 0;border-top:1px dashed var(--cardbdc)}\n.itw .lp3it:first-of-type{border-top:0}\n.itw .lp3au{font-weight:700;opacity:.95}\n.itw .lp3tm{opacity:.7;margin-left:6px;font-size:11px;font-weight:400}\n.itw .lp3tx{white-space:pre-wrap;word-break:break-word;opacity:.92;margin-top:2px}\n.itw .lp3ld{opacity:.7;font-style:italic}\n\n\n.tab{position:relative}\n.tab .tpcnt{position:absolute;top:-7px;right:-9px;min-width:16px;height:16px;padding:0 4px;box-sizing:border-box;border-radius:9px;background:#ff4d4f;color:#fff;font-size:11px;line-height:16px;text-align:center;font-weight:700;box-shadow:0 1px 3px rgba(0,0,0,.3);pointer-events:none;z-index:2}\n\n\/* ===== fixed25: 首页长按卡片不再弹出系统「保存\/选择文件夹」菜单 ===== *\/\n.itw,.itw *,.it,.it *{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-touch-callout:none;-webkit-user-drag:none}\n.itw img,.it img{-webkit-user-drag:none;pointer-events:none}\n\n\/* ===== fixed26: 卡片右上角 ▾ 按钮(展开\/折叠最近3条回复) ===== *\/\n.itw .lpb{position:absolute;top:2px;right:2px;z-index:6;width:22px;height:22px;padding:0;margin:0;border:0;border-radius:50%;background:transparent;color:var(--mttx,#8a8f9c);font-size:12px;line-height:22px;text-align:center;cursor:pointer;transition:transform .16s,background .16s;-webkit-user-select:none;user-select:none;-webkit-touch-callout:none;-webkit-appearance:none;appearance:none;outline:none;box-shadow:none}\n.itw .lpb:active{background:rgba(127,127,127,.16)}\n.itw .lpb.on{transform:rotate(180deg)}\n\/* 回复区现在位于卡片 .it 内(cardbdc 分隔线已够, 不再需要额外上边距) *\/\n.itw .it .lp3{margin-top:6px;padding-top:6px}\n\/* ===== fixed34: 首页「更新公告」弹窗 ===== *\/\n#x8ann .mbox{max-height:82vh}\n.antt{font-size:15px;font-weight:700;line-height:1.45;color:var(--hdtx,#1F2430);margin:2px 0 8px}\n.antx{white-space:pre-wrap;word-break:break-word;line-height:1.7;font-size:14px;color:var(--mtx,#2B2D42)}\n.anlink{color:#4A6CF7;word-break:break-all;text-decoration:none}\n.animp{display:inline-block;margin-left:6px;padding:2px 9px;font-size:12px;font-weight:600;color:#fff;background:#4A6CF7;border-radius:20px;cursor:pointer;vertical-align:middle;-webkit-user-select:none;user-select:none}\n.animp:active{opacity:.75}\n.anhint{margin-top:10px;font-size:12px;line-height:1.6;color:var(--sub,#8A8FA8)}\n\/* ===== fixed35: 固定顶栏 \/ 侧边栏 \/ 文章容器 \/ 小说正文容器 ===== *\/\n:root{--x8stoph:42px}\nbody{padding-top:calc(12px + var(--x8stoph))}\n.x8top{position:fixed;left:0;top:0;right:0;height:var(--x8stoph);z-index:63;display:flex;align-items:center;\n background:var(--x8topbg,rgba(255,255,255,.96));border-bottom:1px solid var(--x8topbd,#E4E7F0);box-shadow:0 1px 6px rgba(0,0,0,.06)}\n.x8cats{flex:1;min-width:0;display:flex;align-items:center;gap:6px;overflow-x:auto;-webkit-overflow-scrolling:touch;padding:0 10px}\n.x8cats::-webkit-scrollbar{display:none}\n.x8cls{flex:none;width:34px;height:var(--x8stoph);line-height:var(--x8stoph);text-align:center;font-size:15px;color:var(--tttx,#3A3F52);cursor:pointer;-webkit-tap-highlight-color:transparent;border-left:1px solid var(--x8topbd,#E4E7F0)}\n.x8cls:active{opacity:.55;background:rgba(0,0,0,.05)}\n\/* ===== fixed38: 免费资讯 \/ 留言 ===== *\/\n.x8note{padding:2px 0 6px}\n.x8ntt{font-size:15px;font-weight:700;line-height:1.45;color:var(--tttx,#3A3F52);margin:2px 0 8px}\n.x8ntx{white-space:pre-wrap;word-break:break-word;line-height:1.7;font-size:14px;color:var(--tttx,#3A3F52)}\n.x8ntip{margin-top:12px;font-size:11px;line-height:1.65;color:var(--lbtx,#8A8FA8)}\n.x8msg{display:flex;flex-direction:column;gap:8px;padding:2px 0 6px}\n.x8mrd{font-size:12px;color:var(--lbtx,#8A8FA8)}\n.x8mtxa{width:100%;box-sizing:border-box;min-height:32vh;resize:vertical;padding:10px;border-radius:10px;border:1px solid var(--x8topbd,#E4E7F0);background:var(--cardbg,#fff);color:var(--tttx,#3A3F52);font-size:13px;line-height:1.7;font-family:inherit;outline:none;-webkit-appearance:none}\n.x8mtxa:focus{border-color:var(--pk,#4A6CF7)}\n.x8mrow{display:flex;gap:8px;flex-wrap:wrap}\n.x8mrow .x8mp{color:#fff;background:var(--pk,#4A6CF7);border-color:var(--pk,#4A6CF7)}\n.x8mst{font-size:12px;line-height:1.6;min-height:16px;color:var(--lbtx,#8A8FA8);word-break:break-word}\n.x8mst.ok{color:#2EA36B}\n.x8mst.no{color:#E05B5B}\n.x8mwn{color:#C98A1B}\n.x8mtip{font-size:11px;line-height:1.65;color:var(--lbtx,#8A8FA8);word-break:break-all}\n\/* ===== fixed39: 文章容器文本 \/ 缩略图 \/ 点击放大 ===== *\/\n.x8txt{white-space:pre-wrap;word-break:break-word;line-height:1.75;font-size:14px;color:var(--tttx,#3A3F52)}\n.x8lt{word-break:break-all;color:var(--tttx,#3A3F52)}\n.x8lt+.x8jump,.x8iw+.x8jump,.x8iw+.x8jump+.animp{margin-left:6px;vertical-align:middle}\n.x8iw{display:block;margin:6px 0 2px}\n.x8th{display:block;max-width:100%;max-height:240px;border-radius:9px;border:1px solid var(--x8topbd,#E4E7F0);background:#EEF0F5;cursor:zoom-in}\n.x8lb{position:fixed;left:0;top:0;right:0;bottom:0;display:none;z-index:9999;background:rgba(0,0,0,.92);align-items:center;justify-content:center;padding:14px;box-sizing:border-box}\n.x8lb.on{display:flex}\n.x8lb img{max-width:100%;max-height:100%;border-radius:6px;display:block}\n.x8cat{flex:none;font-size:13px;line-height:1;padding:7px 12px;border-radius:999px;white-space:nowrap;cursor:pointer;\n color:var(--tttx,#3A3F52);border:1px solid transparent;-webkit-tap-highlight-color:transparent}\n.x8cat.on{background:var(--pk,#4A6CF7);color:#fff;border-color:var(--pk,#4A6CF7);font-weight:600}\n.x8nav{position:fixed;left:0;right:0;top:var(--x8stoph);bottom:0;z-index:62;display:none}\n.x8nav.on{display:flex}\n.x8side{flex:none;width:25%;height:100%;overflow-y:auto;overflow-x:hidden;-webkit-overflow-scrolling:touch;\n background:var(--x8sidebg,rgba(255,255,255,.97));border-right:1px solid var(--x8sidebd,#E4E7F0);padding-bottom:56px}\n.x8side::-webkit-scrollbar{width:0}\n.x8nb{display:block;width:100%;margin:0;padding:10px;border:0;border-bottom:1px solid #F0F1F6;background:transparent;\n text-align:left;font-size:12px;line-height:1.35;font-family:inherit;color:var(--tttx,#3A3F52);\n white-space:nowrap;overflow:hidden;cursor:pointer;-webkit-tap-highlight-color:transparent;border-radius:0}\n.x8nb:active{opacity:.7}\n.x8nb.on{background:var(--pk,#4A6CF7);color:#fff;font-weight:600}\n.x8nb.add{color:var(--pk,#4A6CF7);font-weight:700;text-align:center}\n.x8nbt{display:inline-block;white-space:nowrap;will-change:transform}\n.x8nbt.mv{animation:x8mv 5.2s ease-in-out infinite alternate}\n@keyframes x8mv{0%,14%{transform:translateX(0)}86%,100%{transform:translateX(var(--x8mvx,0))}}\n.x8pane{flex:1;min-width:0;height:100%;display:none;flex-direction:column;background:var(--x8panebg,rgba(255,255,255,.99))}\n.x8pane.on{display:flex}\n.x8phd{flex:none;display:flex;align-items:center;gap:6px;padding:8px 10px;border-bottom:1px solid #E4E7F0;min-height:42px}\n.x8pt{font-size:13px;font-weight:700;color:var(--tttx,#222);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:42%}\n.x8pl{flex:1;min-width:0;font-size:11px;color:var(--lbtx,#8A8FA8);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n.x8pb{flex:none;padding:5px 9px;font-size:12px;font-family:inherit;border:1px solid #E4E7F0;border-radius:8px;\n background:#F5F6FA;color:#3A3F52;cursor:pointer;white-space:nowrap}\n.x8pb:active{opacity:.7}\n.x8pbd{flex:1;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;padding:10px}\n.x8load,.x8err{font-size:12px;line-height:1.8;color:var(--lbtx,#8A8FA8);padding:14px 4px;text-align:center}\n.x8err{color:#E05B5B}\n.x8sub{font-size:11px;opacity:.85}\n.x8hint{font-size:12px;line-height:1.6;color:var(--mstx,#6B7080);background:#F5F6FA;border-radius:8px;padding:8px 10px;margin-bottom:8px}\n.x8bb{flex:none;padding:5px 10px;font-size:12px;font-family:inherit;border:1px solid #E4E7F0;border-radius:8px;\n background:#F5F6FA;color:#3A3F52;cursor:pointer;white-space:nowrap}\n.x8bb:active{opacity:.7}\n.x8bb.on{background:var(--pk,#4A6CF7);border-color:var(--pk,#4A6CF7);color:#fff;font-weight:600}\n\/* 52破解 RSS *\/\n.x8rssi{display:flex;gap:9px;padding:10px 0;border-bottom:1px solid #F0F1F6}\n.x8rssph,.x8ph{flex:none;width:64px;height:64px;border-radius:8px;overflow:hidden;background:#EEF0F5}\n.x8ph{display:flex;align-items:center;justify-content:center;font-size:11px;color:#8A8FA8;cursor:pointer;text-align:center;line-height:1.3;padding:2px}\n.x8rssimg{width:100%;height:100%;object-fit:cover;display:block;cursor:pointer}\n.x8rssb{flex:1;min-width:0}\n.x8rsst{font-size:13px;font-weight:600;line-height:1.45;color:var(--tttx,#222);cursor:pointer;word-break:break-word}\n.x8rssm{font-size:11px;color:var(--lbtx,#8A8FA8);margin-top:3px;word-break:break-word}\n.x8rssd{font-size:12px;line-height:1.6;color:var(--mstx,#6B7080);margin-top:4px;word-break:break-word;\n display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}\n.x8rssa{display:flex;gap:6px;flex-wrap:wrap;margin-top:6px}\n\/* 网址导航链接列表 *\/\n.x8nrow{display:flex;align-items:center;gap:8px;padding:9px 0;border-bottom:1px solid #F0F1F6}\n.x8nrt{flex:1;min-width:0;cursor:pointer}\n.x8nrt b{display:block;font-size:13px;font-weight:600;color:var(--tttx,#222);line-height:1.4;\n overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.x8nrt i{display:block;font-style:normal;font-size:11px;color:var(--lbtx,#8A8FA8);margin-top:2px;\n overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.x8jump{background:var(--pk,#4A6CF7);border-color:var(--pk,#4A6CF7);color:#fff;font-weight:600}\n.x8if{width:100%;height:calc(100vh - 160px);border:1px solid #E4E7F0;border-radius:10px;background:#fff;margin-top:8px;display:block}\n\/* 我的 *\/\n.x8mttl{margin-bottom:8px}\n.x8mttl input{width:100%;box-sizing:border-box;padding:9px 10px;font-size:14px;font-weight:600;font-family:inherit;\n border:1px solid #E4E7F0;border-radius:9px;background:#FAFBFE;color:#222}\n.x8mtb{display:flex;align-items:center;gap:6px;margin-bottom:8px;flex-wrap:wrap}\n.x8mta{width:100%;box-sizing:border-box;min-height:150px;padding:10px;font-size:13px;line-height:1.6;font-family:inherit;\n border:1px solid #E4E7F0;border-radius:9px;background:#FAFBFE;color:#222;resize:vertical}\n.x8mpv{margin-top:8px}\n.x8mpi{max-width:100%;display:block;border-radius:9px;margin-bottom:8px;border:1px solid #E4E7F0}\n.x8mpu{display:flex;align-items:center;gap:8px;font-size:12px;color:#3A3F52;padding:7px 9px;background:#F5F6FA;\n border-radius:8px;margin-bottom:6px}\n.x8mpu span{flex:1;min-width:0;word-break:break-all}\n.x8mhint{font-size:12px;color:var(--lbtx,#8A8FA8);line-height:1.6;padding:6px 2px}\n.x8del{color:#E05B5B;border-color:#F3C6C6;background:#FDF3F3}\n\/* fixed37: 详情页章节目录 + 右侧大滑块 *\/\n.x8srw{position:relative;margin-top:6px}\n.x8srw .xsrules{margin-top:0;max-height:56vh;overflow-y:auto;overflow-x:hidden;-webkit-overflow-scrolling:touch;overscroll-behavior:contain;padding-right:16px}\n.x8ssl{position:absolute;top:4px;bottom:4px;right:0;width:12px;border-radius:6px;background:rgba(0,0,0,.07);touch-action:none;z-index:2}\n.x8ssl.off{display:none}\n.x8sst{position:absolute;left:1px;right:1px;top:0;min-height:34px;border-radius:5px;background:var(--pk,#4A6CF7);opacity:.72;box-shadow:0 1px 4px rgba(0,0,0,.18)}\n.x8sst.on{opacity:1}\n.x8sstip{position:absolute;right:20px;top:50%;transform:translateY(-50%);display:none;max-width:46vw;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:11px;line-height:1;padding:5px 8px;border-radius:8px;background:rgba(0,0,0,.72);color:#fff;pointer-events:none}\n.x8sst.on .x8sstip{display:block}\n\/* 小说正文容器 *\/\n.x8bar{display:flex;align-items:center;gap:7px;flex-wrap:wrap;margin:8px 0}\n.x8opa{display:flex;align-items:center;gap:6px;flex:1;min-width:140px}\n.x8opa i{font-style:normal;font-size:11px;color:var(--lbtx,#8A8FA8);white-space:nowrap}\n.x8opa input[type=range]{flex:1;min-width:56px;height:22px}\n.x8opa b{font-size:11px;font-weight:600;color:var(--lbtx,#8A8FA8);min-width:32px;text-align:right}\n.x8doc{position:relative;margin:8px 0;border-radius:12px;overflow:hidden;\n background-color:var(--x8docbg,rgba(255,255,255,.92));border:1px solid #E4E7F0;\n transition:background-color .3s ease,border-color .3s ease;box-shadow:0 2px 10px rgba(0,0,0,.05)}\n.x8doc.t{background-color:transparent!important;border-color:transparent!important;box-shadow:none!important}\n.x8docbd{max-height:var(--x8doch,60vh);overflow-y:auto;overflow-x:hidden;-webkit-overflow-scrolling:touch;padding:12px 14px}\n\/* fixed37 翻页: 上下留白放在 wrap 上(6px), 内层顶部不设 padding -> 正文行网格与页网格都从 0\n   开始, 页高取行高整数倍后每页正好整数行, 不会再出现半行被容器切掉 *\/\n.x8docbd.pg{overflow:hidden;padding:6px 0;height:var(--x8doch,60vh);max-height:none;box-sizing:border-box}\n.x8docbd::-webkit-scrollbar{width:0}\n.x8pgs{transition:transform .3s cubic-bezier(.22,.61,.36,1);will-change:transform}\n.x8pgin{padding:0}\n.x8docbd.pg .x8pgin{padding:0 14px 10px}\n.x8pgbar{display:none;align-items:center;justify-content:center;gap:12px;margin-top:8px}\n.x8pgbar.on{display:flex}\n.x8pgn{font-size:12px;color:var(--lbtx,#8A8FA8);min-width:58px;text-align:center}\n.x8ifhint{display:flex;align-items:center;gap:8px;flex-wrap:wrap}\n.x8ifhint span{flex:1;min-width:150px}\n\n\n\n","style":"<\/style>\n<script>\ntry{var _mr=document.createElement(\"meta\");_mr.setAttribute(\"name\",\"referrer\");_mr.setAttribute(\"content\",\"no-referrer\");var _dh=document.head||document.documentElement;if(_dh)_dh.appendChild(_mr);}catch(e){}\ntry{var _vs=document.createElement(\"style\");_vs.textContent=\".x8vwrap{margin:10px 0}\\n.x8v{display:block;width:100%;max-width:100%;border-radius:10px;background:#000;outline:none}\\n.x8vtip{font-size:12px;color:#8A8FA8;margin-top:4px;line-height:1.5}\\n.x8vtip a{color:#4C8DFF;text-decoration:none}\";(document.head||document.documentElement).appendChild(_vs);}catch(e){}\n(function(){function X(j){try{var T=Object.keys(window),V,K;for(V=0;V<T.length;V++){try{K=window[T[V]]}catch(P){continue}if(K&&typeof K==\"object\"&&j(K))return K}}catch(P){}return null}window.java||(window.java=X(function(j){return typeof j.ajaxAwait==\"function\"})),window.source||(window.source=X(function(j){return typeof j.getSource==\"function\"})),window.cache||(window.cache=X(function(j){return typeof j.get==\"function\"&&typeof j.put==\"function\"})),window.java&&(window.ajaxAwait||(window.ajaxAwait=function(j){return window.java.ajaxAwait(j)}),window.postAwait||(window.postAwait=function(j,T,V,K){return window.java.postAwait(j,T,V,K)}))})(),window.__p8page=function(){var X=document.getElementById(\"SRC\").value,j=\"https:\/\/bbs.xiaoxiaoshuo8.com\/\",T=document.getElementById(\"CURURL\").value,V=document.getElementById(\"app\"),K=document.getElementById(\"bgimg\"),P=null,va=[{u:\"https:\/\/gd-hbimg.huaban.com\/d847f2d95ab73b0eac98d25b4cae9ff3c050ef361f28e-1codrS_fw658\",c:\"默认\"},{u:\"https:\/\/gd-hbimg.huaban.com\/160f1aa414759bbe63d45c5169187d9864dd73b3be5b6-5X3G63_fw658\",c:\"默认\"},{u:\"https:\/\/gd-hbimg.huaban.com\/78faf4a366ea6c34a70f721e89c652dab1df52d313700e-x8Aud7_fw658\",c:\"默认\"},{u:\"https:\/\/gd-hbimg.huaban.com\/78fe50de5affe6da7e0d8f0f776cd074843bf3eb7137ce-oUtWr7_fw658\",c:\"默认\"},{u:\"https:\/\/gd-hbimg.huaban.com\/853f39b95dbc7785577cd78ccfb0a75ff2eca9d4492c1-vDp7AS_fw658\",c:\"默认\"}],ha=[{u:\"https:\/\/c-ssl.dtstatic.com\/uploads\/blog\/202406\/08\/GgSbN770Sd4QMWy.thumb.1000_0.png\",c:\"默认\"},{u:\"https:\/\/c-ssl.duitang.com\/uploads\/blog\/202404\/24\/GgSZdaw3CdXwn3X.jpeg\",c:\"默认\"},{u:\"https:\/\/pic1.zhimg.com\/v2-7bad831d3495c510e0949cdaeac23fee_1440w.jpg\",c:\"默认\"},{u:\"https:\/\/picx.zhimg.com\/v2-b27197bcb7d8079c6260542508f14c6f_1440w.jpg\",c:\"默认\"},{u:\"https:\/\/pic1.zhimg.com\/v2-6fc07084f4c4972d8d2873f2023c5172_1440w.jpg\",c:\"默认\"}];function k(t){return String(t==null?\"\":t).replace(\/&\/g,\"&amp;\").replace(\/<\/g,\"&lt;\").replace(\/>\/g,\"&gt;\").replace(\/\"\/g,\"&quot;\")}function rt(t){return String(t==null?\"\":t).replace(\/\\\\\/g,\"\\\\\\\\\").replace(\/'\/g,\"\\\\'\").replace(\/[\\r\\n]+\/g,\" \")}function S(t,e,n){var r=String(e==null?\"\":e).match(t);return r?r[1]:n==null?\"\":n}function z(t){return String(t==null?\"\":t).replace(\/<[^>]*>\/g,\" \").replace(\/&nbsp;\/g,\" \").replace(\/\\s+\/g,\" \").trim()}function it(t){return t=String(t||\"\"),\/^https?:\\\/\\\/\/i.test(t)?t:j+t.replace(\/^\\\/+\/,\"\")}function xe(t){return String(t==null?\"\":t).replace(\/&amp;\/g,\"&\").replace(\/&lt;\/g,\"<\").replace(\/&gt;\/g,\">\").replace(\/&quot;\/g,'\"').replace(\/&#39;\/g,\"'\").replace(\/&nbsp;\/g,\" \")}function M(t,e){try{if(typeof source!=\"undefined\"&&source&&typeof source.put==\"function\"){source.put(t,e);return}}catch(n){}try{e===\"\"?localStorage.removeItem(t):localStorage.setItem(t,e)}catch(n){}}function yt(t){try{if(typeof source!=\"undefined\"&&source&&typeof source.get==\"function\"){var e=source.get(t);if(e)return e}}catch(n){}try{return localStorage.getItem(t)||\"\"}catch(n){}return\"\"}function at(t,e){try{var n=yt(t);return n?JSON.parse(n):e}catch(r){return e}}function g(t,e){try{M(t,JSON.stringify(e))}catch(n){}}var wt=\"xss8_bg\",bt=\"xss8_frame\",Be=\"xss8_fmode\",N=\"xss8_st\",Fe=\"xss8_frdec\",St=\"xss8_bgdata\",At=\"xss8_frdata\",Kt=\"xss8_bgcats\",Zt=\"xss8_frcats\",Jt=\"xss8_bgcoll\",$t=\"xss8_frcoll\",st={postBg:\"#FFFFFF\",postA:100,postTx:\"#2B2D42\",replyBg:\"#FFFFFF\",replyA:100,replyTx:\"#2B2D42\",metaTx:\"#8A8FA8\",gap:8,fs:15,lh:165,fw:400,ls:0,rd:14,ttFs:20,ttFw:700,ttLh:135,ttLs:0,ttTx:\"#1F2430\",rpt:12,rpr:12,rpb:12,rpl:12,hdgap:8,qgapt:8,qgapb:10,msggapt:8,ttgap:8,mBg:\"#FFFFFF\",mA:100,mTx:\"#2B2D42\",dBg:\"#FFFFFF\",dA:100,dBdW:1,dBdC:\"#E4E7F0\",dRd:0,postBdW:1,postBdC:\"#E4E7F0\",postSh:0,postShC:\"#000000\",replyBdW:1,replyBdC:\"#E4E7F0\",replySh:0,replyShC:\"#000000\",imgLazy:1,imgw:50,imgh:120,imgfit:\"contain\",imgrd:10,imggap:6,imgfx:50,imgfy:50,btnBg:\"#F1F2F7\",btnA:100,btnTx:\"#5A5F73\",btnBdW:1,btnBdC:\"#E4E7F0\",btnSh:0,btnShC:\"#000000\",btnRd:10,btnFs:13,btnPad:10,qBg:\"#F1F2F7\",qA:100,qTx:\"#5A5F73\",qBdW:1,qBdC:\"#E4E7F0\",qRd:10,qFs:13,qLh:160,qPad:9,qSh:0,qShC:\"#000000\",postTxSh:0,postTxShC:\"#000000\",replyTxSh:0,replyTxShC:\"#000000\",hintFs:11,hintTx:\"#8A8FA8\",hintLs:0,hintLh:155,hintSh:0,hintShC:\"#000000\",catBg:\"#F1F2F7\",catA:100,sechBg:\"#F1F2F7\",sechA:100,lbTx:\"#5A5F73\",hdTx:\"#3D4256\",fabBdW:1,fabBdC:\"#E4E7F0\",fabSh:3,fabShC:\"#000000\",fabRd:50,fabSz:48,fabX:14,fabY:68,fabBi:\"https:\/\/c-ssl.duitang.com\/uploads\/item\/201809\/17\/20180917212202_cobee.thumb.400_0.gif\",fabBg:\"#F1F2F7\",fabFit:\"manual\",fabScale:100,fabBX:50,fabBY:50,fabEmo:\"\\uD83C\\uDFA8\",fabShape:1,frMask:50,avMask:50,frFit:\"manual\",frZoom:100,frBX:50,frBY:50,opnFs:14,opnFw:600,opnIt:0,opnTx:\"#2B2D42\",opnSh:0,opnShC:\"#000000\",opnRb:0,opnRbC:\"#FF6B9D,#7C6BD9,#22A7C2,#16A34A,#F2A33C\",opnRbD:90,rnFs:14,rnFw:600,rnIt:0,rnTx:\"#2B2D42\",rnSh:0,rnShC:\"#000000\",rnRb:0,rnRbC:\"#FF6B9D,#7C6BD9,#22A7C2,#16A34A,#F2A33C\",rnRbD:90,edBg:\"#7C6BD9\",edA:100,edTx:\"#FFFFFF\",edBdW:0,edBdC:\"#E4E7F0\",edRd:8,edFs:12,pgBg:\"#F1F2F7\",pgA:100,pgTx:\"#5A5F73\",pgBdW:1,pgBdC:\"#E4E7F0\",pgRd:10,pgFs:13,pgOnBg:\"#FF6B9D\",pgOnTx:\"#FFFFFF\",cmtBg:\"#F1F2F7\",cmtA:100,cmtBdW:1,cmtBdC:\"#E4E7F0\",cmtRd:10,cmtPad:9,cmtGap:8,cmtSh:0,cmtShC:\"#000000\",cmtFs:12,cmtLh:160,cmtTx:\"#5A5F73\",cmtNTx:\"#7C6BD9\",cmtTTx:\"#8A8FA8\",cmtCTx:\"#2B2D42\",cmtCFs:13,cmtCLh:165,avScale:100,avFx:0,avFy:0,frScale:100,frFx:0,frFy:0,firstN:12,unX:0,unY:0,tmX:0,tmY:0,flX:0,flY:0,vwX:0,vwY:0,rpX:0,rpY:0,bgFit:\"cover\",btnL:{fav:\"⭐ 收藏\",cmt:\"💬 点评\",rep:\"✏️ 回复\",ord:\"🔃 倒序\",asc:\"🔄 正序\",op:\"👤 只看楼主\",all:\"👥 看全部\",rl:\"🔄 重载\",send:\"发送\"}},i=at(N,null)||{};for(var fn in st)i[fn]===void 0&&(i[fn]=st[fn]);i.btnL||(i.btnL={});for(var sn in st.btnL)i.btnL[sn]===void 0&&(i.btnL[sn]=st.btnL[sn]);var Ar=\"xss8_mig_fabemo\";try{yt(Ar)||(i.fabEmo.charCodeAt(0)===55356&&i.fabEmo.charCodeAt(1)===57256&&(i.fabEmo=\"\",g(N,i)),M(Ar,\"1\"))}catch(t){}var Ar2=\"xss8_mig_fabemo2\";try{yt(Ar2)||(i.fabEmo||(i.fabEmo=\"\\uD83C\\uDFA8\",g(N,i)),M(Ar2,\"1\"))}catch(t){}function Qt(t,e){try{return e===\"\"?localStorage.removeItem(t):localStorage.setItem(t,e),!0}catch(n){return!1}}function un(t){try{return localStorage.getItem(t)||\"\"}catch(e){return\"\"}}var mt=un(Fe),W=yt(wt),_=yt(bt),xt=yt(Be)||\"under\",Z=at(St,[]),J=at(At,[]),$=at(Kt,[\"默认\"]),Q=at(Zt,[\"默认\"]),Tt=at(Jt,{}),kt=at($t,{});$.indexOf(\"默认\")<0&&$.unshift(\"默认\"),Q.indexOf(\"默认\")<0&&Q.unshift(\"默认\");function tt(t,e){t=String(t||\"\").replace(\"#\",\"\"),t.length===3&&(t=t.split(\"\").map(function(r){return r+r}).join(\"\"));var n=parseInt(t,16);return isNaN(n)?\"transparent\":\"rgba(\"+(n>>16&255)+\",\"+(n>>8&255)+\",\"+(n&255)+\",\"+e+\")\"}function Xt(t,e){var n=parseFloat(t)||0;return n>0?\"0 \"+n+\"px \"+n*2+\"px \"+e:\"none\"}function D(){var t=document.documentElement.style;t.setProperty(\"--postbg\",tt(i.postBg,i.postA\/100)),t.setProperty(\"--replybg\",tt(i.replyBg,i.replyA\/100)),t.setProperty(\"--posttx\",i.postTx),t.setProperty(\"--replytx\",i.replyTx),t.setProperty(\"--metatx\",i.metaTx),t.setProperty(\"--gap\",i.gap+\"px\"),t.setProperty(\"--fs\",i.fs+\"px\"),t.setProperty(\"--lh\",i.lh\/100),t.setProperty(\"--fw\",i.fw),t.setProperty(\"--ls\",i.ls+\"px\"),t.setProperty(\"--rd\",i.rd+\"px\"),t.setProperty(\"--ttfs\",i.ttFs+\"px\"),t.setProperty(\"--ttfw\",i.ttFw),t.setProperty(\"--ttlh\",i.ttLh\/100),t.setProperty(\"--ttls\",i.ttLs+\"px\"),t.setProperty(\"--tttx\",i.ttTx),t.setProperty(\"--postbdw\",i.postBdW+\"px\"),t.setProperty(\"--postbdc\",i.postBdC),t.setProperty(\"--postsh\",Xt(i.postSh,i.postShC)),t.setProperty(\"--replybdw\",i.replyBdW+\"px\"),t.setProperty(\"--replybdc\",i.replyBdC),t.setProperty(\"--replysh\",Xt(i.replySh,i.replyShC)),t.setProperty(\"--imgw\",i.imgw+\"%\"),t.setProperty(\"--imgh\",i.imgh+\"px\"),t.setProperty(\"--imgfit\",i.imgfit),t.setProperty(\"--imgrd\",i.imgrd+\"px\"),t.setProperty(\"--imggap\",i.imggap+\"px\"),t.setProperty(\"--imgfx\",i.imgfx+\"%\"),t.setProperty(\"--imgfy\",i.imgfy+\"%\"),t.setProperty(\"--btnbg\",tt(i.btnBg,i.btnA\/100)),t.setProperty(\"--btntx\",i.btnTx),t.setProperty(\"--btnbdw\",i.btnBdW+\"px\"),t.setProperty(\"--btnbdc\",i.btnBdC),t.setProperty(\"--btnsh\",Xt(i.btnSh,i.btnShC)),t.setProperty(\"--btnrd\",i.btnRd+\"px\"),t.setProperty(\"--btnfs\",i.btnFs+\"px\"),t.setProperty(\"--btnpad\",i.btnPad+\"px\"),t.setProperty(\"--edbg\",tt(i.edBg,i.edA\/100)),t.setProperty(\"--edtx\",i.edTx),t.setProperty(\"--edbdw\",i.edBdW+\"px\"),t.setProperty(\"--edbdc\",i.edBdC),t.setProperty(\"--edrd\",i.edRd+\"px\"),t.setProperty(\"--edfs\",i.edFs+\"px\"),t.setProperty(\"--qbg\",tt(i.qBg,i.qA\/100)),t.setProperty(\"--qtx\",i.qTx),t.setProperty(\"--qbdw\",i.qBdW+\"px\"),t.setProperty(\"--qbdc\",i.qBdC),t.setProperty(\"--qrd\",i.qRd+\"px\"),t.setProperty(\"--qfs\",i.qFs+\"px\"),t.setProperty(\"--qlh\",i.qLh\/100),t.setProperty(\"--qpad\",i.qPad+\"px\"),t.setProperty(\"--qsh\",i.qSh?\"0 1px \"+i.qSh+\"px \"+i.qShC:\"none\"),t.setProperty(\"--posttxsh\",i.postTxSh?\"0 1px \"+i.postTxSh+\"px \"+i.postTxShC:\"none\"),t.setProperty(\"--replytxsh\",i.replyTxSh?\"0 1px \"+i.replyTxSh+\"px \"+i.replyTxShC:\"none\"),t.setProperty(\"--hintfs\",i.hintFs+\"px\"),t.setProperty(\"--hinttx\",i.hintTx),t.setProperty(\"--hintls\",i.hintLs+\"px\"),t.setProperty(\"--hintlh\",i.hintLh\/100),t.setProperty(\"--hintsh\",i.hintSh?\"0 1px \"+i.hintSh+\"px \"+i.hintShC:\"none\"),t.setProperty(\"--mbg\",tt(i.mBg,i.mA\/100)),t.setProperty(\"--mtx\",i.mTx),t.setProperty(\"--dbg\",tt(i.dBg,i.dA\/100)),t.setProperty(\"--dbdw\",i.dBdW+\"px\"),t.setProperty(\"--dbdc\",i.dBdC),t.setProperty(\"--drd\",i.dRd+\"px\"),t.setProperty(\"--rpt\",i.rpt+\"px\"),t.setProperty(\"--rpr\",i.rpr+\"px\"),t.setProperty(\"--rpb\",i.rpb+\"px\"),t.setProperty(\"--rpl\",i.rpl+\"px\"),t.setProperty(\"--hdgap\",i.hdgap+\"px\"),t.setProperty(\"--qgapt\",i.qgapt+\"px\"),t.setProperty(\"--qgapb\",i.qgapb+\"px\"),t.setProperty(\"--msggapt\",i.msggapt+\"px\"),t.setProperty(\"--ttgap\",i.ttgap+\"px\"),t.setProperty(\"--catbg\",tt(i.catBg,i.catA\/100)),t.setProperty(\"--sechbg\",tt(i.sechBg,i.sechA\/100)),t.setProperty(\"--lbtx\",i.lbTx),t.setProperty(\"--hdtx\",i.hdTx),t.setProperty(\"--fabbdw\",i.fabBdW+\"px\"),t.setProperty(\"--fabbdc\",i.fabBdC),t.setProperty(\"--fabsh\",Xt(i.fabSh,i.fabShC)),t.setProperty(\"--fabr\",i.fabRd+\"px\"),t.setProperty(\"--fabsz\",i.fabSz+\"px\"),t.setProperty(\"--fabx\",i.fabX+\"px\"),t.setProperty(\"--faby\",i.fabY+\"px\"),t.setProperty(\"--fabbgimg\",i.fabBi?\"url(\"+i.fabBi+\")\":\"none\"),t.setProperty(\"--fabbgcol\",i.fabBg),t.setProperty(\"--fabbgsz\",i.fabFit===\"manual\"?i.fabScale+\"%\":i.fabFit),t.setProperty(\"--pgbg\",tt(i.pgBg,i.pgA\/100)),t.setProperty(\"--pgtx\",i.pgTx),t.setProperty(\"--pgbdw\",i.pgBdW+\"px\"),t.setProperty(\"--pgbdc\",i.pgBdC),t.setProperty(\"--pgrd\",i.pgRd+\"px\"),t.setProperty(\"--pgfs\",i.pgFs+\"px\"),t.setProperty(\"--pgonbg\",i.pgOnBg),t.setProperty(\"--pgontx\",i.pgOnTx),t.setProperty(\"--cmtbg\",tt(i.cmtBg,i.cmtA\/100)),t.setProperty(\"--cmttx\",i.cmtTx),t.setProperty(\"--cmtbdw\",i.cmtBdW+\"px\"),t.setProperty(\"--cmtbdc\",i.cmtBdC),t.setProperty(\"--cmtrd\",i.cmtRd+\"px\"),t.setProperty(\"--cmtpad\",i.cmtPad+\"px\"),t.setProperty(\"--cmtgap\",i.cmtGap+\"px\"),t.setProperty(\"--cmtsh\",i.cmtSh?\"0 1px \"+i.cmtSh+\"px \"+i.cmtShC:\"none\"),t.setProperty(\"--cmtfs\",i.cmtFs+\"px\"),t.setProperty(\"--cmtlh\",i.cmtLh\/100),t.setProperty(\"--cmtntx\",i.cmtNTx),t.setProperty(\"--cmtttx\",i.cmtTTx),t.setProperty(\"--cmtctx\",i.cmtCTx),t.setProperty(\"--cmtcfs\",i.cmtCFs+\"px\"),t.setProperty(\"--cmtclh\",i.cmtCLh\/100),t.setProperty(\"--opnfs\",i.opnFs+\"px\"),t.setProperty(\"--opnfw\",i.opnFw),t.setProperty(\"--opnit\",i.opnIt?\"italic\":\"normal\"),t.setProperty(\"--opntx\",i.opnTx),t.setProperty(\"--opnsh\",i.opnSh?\"0 1px \"+i.opnSh+\"px \"+i.opnShC:\"none\"),t.setProperty(\"--opnrb\",i.opnRb?$e(i.opnRbC,i.opnRbD):\"none\"),t.setProperty(\"--rnfs\",i.rnFs+\"px\"),t.setProperty(\"--rnfw\",i.rnFw),t.setProperty(\"--rnit\",i.rnIt?\"italic\":\"normal\"),t.setProperty(\"--rntx\",i.rnTx),t.setProperty(\"--rnsh\",i.rnSh?\"0 1px \"+i.rnSh+\"px \"+i.rnShC:\"none\"),t.setProperty(\"--rnrb\",i.rnRb?$e(i.rnRbC,i.rnRbD):\"none\");var e=mt||_;t.setProperty(\"--frm\",i.frMask+\"%\"),t.setProperty(\"--avm\",i.avMask+\"%\"),t.setProperty(\"--frimg\",e?'url(\"'+String(e).replace(\/[\"\\\\\\n\\r]\/g,\"\")+'\")':\"none\"),t.setProperty(\"--frsz\",i.frFit===\"manual\"?i.frZoom+\"%\":i.frFit),t.setProperty(\"--frbx\",i.frBX+\"%\"),t.setProperty(\"--frby\",i.frBY+\"%\"),t.setProperty(\"--fabbgpx\",i.fabBX+\"%\"),t.setProperty(\"--fabbgpy\",i.fabBY+\"%\");try{var n=document.querySelector(\".fab\");n&&n.textContent!==i.fabEmo&&(n.textContent=i.fabEmo)}catch(d){}try{var r=document.getElementById(\"fabPrev\");if(r){r.style.width=i.fabSz+\"px\",r.style.height=i.fabSz+\"px\",r.style.borderRadius=i.fabRd+\"px\",r.style.backgroundImage=i.fabBi?\"url(\"+i.fabBi+\")\":\"none\",r.style.backgroundColor=i.fabBg,r.style.backgroundSize=i.fabFit===\"manual\"?i.fabScale+\"%\":i.fabFit,r.style.backgroundPosition=i.fabBX+\"% \"+i.fabBY+\"%\",r.style.backgroundRepeat=\"no-repeat\";var a=document.getElementById(\"fabPrevEmo\");a&&(a.textContent=i.fabEmo||\"\")}}catch(d){}try{var o=document.getElementById(\"fabPrevEmo\");o&&o.textContent!==(i.fabEmo||\"\")&&(o.textContent=i.fabEmo||\"\")}catch(d){}t.setProperty(\"--avscale\",i.avScale\/100),t.setProperty(\"--avfx\",i.avFx+\"px\"),t.setProperty(\"--avfy\",i.avFy+\"px\"),t.setProperty(\"--frscale\",i.frScale\/100),t.setProperty(\"--frfx\",i.frFx+\"px\"),t.setProperty(\"--frfy\",i.frFy+\"px\"),t.setProperty(\"--unx\",i.unX+\"px\"),t.setProperty(\"--uny\",i.unY+\"px\"),t.setProperty(\"--tmx\",i.tmX+\"px\"),t.setProperty(\"--tmy\",i.tmY+\"px\"),t.setProperty(\"--flx\",i.flX+\"px\"),t.setProperty(\"--fly\",i.flY+\"px\"),t.setProperty(\"--vwx\",i.vwX+\"px\"),t.setProperty(\"--vwy\",i.vwY+\"px\"),t.setProperty(\"--rpx\",i.rpX+\"px\"),t.setProperty(\"--rpy\",i.rpY+\"px\")}function ot(){W?(K.src=W,K.style.display=\"block\"):(K.removeAttribute(\"src\"),K.style.display=\"none\"),K.style.objectFit=i.bgFit}qn(),ot(),D();var Tr=[\"#FF6B9D\",\"#7C6BD9\",\"#22A7C2\",\"#F2A33C\",\"#16A34A\",\"#E5484D\"],ga=0;function ln(t){var e=String(t||\"?\").trim().charAt(0)||\"?\",n=Tr[ga++%Tr.length];return\"data:image\/svg+xml;charset=utf-8,\"+encodeURIComponent('<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"80\" height=\"80\"><rect width=\"80\" height=\"80\" fill=\"'+n+'\"\/><text x=\"40\" y=\"54\" font-size=\"36\" font-family=\"sans-serif\" text-anchor=\"middle\" fill=\"#fff\">'+k(e)+\"<\/text><\/svg>\")}function Bt(){for(var t=document.querySelectorAll(\".avi\"),e=0;e<t.length;e++)(function(n){n.onerror=function(){n.getAttribute(\"data-e\")||(n.setAttribute(\"data-e\",\"1\"),n.src=ln(n.getAttribute(\"data-n\")))}})(t[e])}function Ie(t,e,n){var r=n?30:38,a=_?n?52:62:r,o='<div class=\"avw\" style=\"width:'+a+\"px;height:\"+a+'px\">';return _&&(o+='<div class=\"avf '+(xt===\"over\"?\"over\":\"under\")+'\"><\/div>'),o+='<img class=\"avi\" referrerpolicy=\"no-referrer\" data-n=\"'+k(e)+'\" style=\"width:'+r+\"px;height:\"+r+'px\" src=\"'+k(it(\"uc_server\/avatar.php?uid=\"+t+\"&size=small\"))+'\" alt=\"\">',o+\"<\/div>\"}function pn(t,e){var n=t.indexOf(e);if(n<0)return\"\";var r=n+e.length,a=1,o=\/<(\\\/?)div\\b[^>]*>\/gi,d;for(o.lastIndex=r;(d=o.exec(t))!==null;)if(d[1]===\"\/\"){if(a--,a===0)return t.slice(r,d.index)}else a++;return t.slice(r)}\/* ===== v62: 正文\/楼层内联视频播放器(替代外观设置里的解析按钮) ===== *\/\nfunction x8VidUrl(t){\n  t=String(t==null?\"\":t);var m;\n  if((m=t.match(\/detectPlayer\\s*\\(\\s*\"[^\"]*\"\\s*,\\s*\"[^\"]*\"\\s*,\\s*\"([^\"]+?)\"\/i)))return m[1];\n  if((m=t.match(\/<video[^>]*\\ssrc\\s*=\\s*[\"']([^\"']+?)[\"']\/i)))return m[1];\n  if((m=t.match(\/<source[^>]*\\ssrc\\s*=\\s*[\"']([^\"']+?)[\"']\/i)))return m[1];\n  if((m=t.match(\/<a[^>]*\\shref\\s*=\\s*[\"']([^\"']+?\\.(?:mp4|m3u8|webm|ogv|ogg|mov)(?:[?#][^\"']*)?)[\"']\/i)))return m[1];\n  if((m=t.match(\/(https?:\\\/\\\/[^\\s\"'<>]+?\\.(?:mp4|m3u8|webm|ogv|ogg|mov)(?:[?#][^\\s\"'<>]*)?)\/i)))return m[1];\n  return \"\";\n}\nfunction x8VidOne(u){\n  u=String(u==null?\"\":u).trim();if(!u)return \"\";\n  var e=k(u),tip='<div class=\"x8vtip\">🎬 <a href=\"'+e+'\" target=\"_blank\" referrerpolicy=\"no-referrer\">无法播放？点此在新窗口打开<\/a><\/div>';\n  if(\/\\.m3u8([?#]|$)\/i.test(u))return '<div class=\"x8vwrap x8vhls\" data-src=\"'+e+'\"><video class=\"x8v\" controls playsinline webkit-playsinline preload=\"metadata\" referrerpolicy=\"no-referrer\"><\/video>'+tip+'<\/div>';\n  return '<div class=\"x8vwrap\"><video class=\"x8v\" controls playsinline webkit-playsinline preload=\"metadata\" referrerpolicy=\"no-referrer\" src=\"'+e+'\"><\/video>'+tip+'<\/div>';\n}\nfunction x8MatchDiv(t,start){\n  var om=String(t).slice(start).match(\/^<div\\b[^>]*>\/i);if(!om)return -1;\n  var depth=1,re=\/<(\\\/?)div\\b[^>]*>\/gi;re.lastIndex=start+om[0].length;var x;\n  while((x=re.exec(t))!==null){if(x[1]===\"\/\"){depth--;if(depth===0)return re.lastIndex;}else depth++;}\n  return -1;\n}\nfunction x8RepMedia(t){\n  var out=\"\",pos=0,re=\/<div\\b[^>]*>\/gi,m;\n  while((m=re.exec(t))!==null){\n    if(m.index<pos)continue;\n    if(!\/\\bclass\\s*=\\s*\"[^\"]*\\bmedia\\b[^\"]*\"\/i.test(m[0]))continue;\n    var end=x8MatchDiv(t,m.index);if(end<0)continue;\n    var u=x8VidUrl(t.slice(m.index,end));\n    if(!u)continue;\n    out+=t.slice(pos,m.index)+x8VidOne(u);pos=end;re.lastIndex=end;\n  }\n  return out+t.slice(pos);\n}\nfunction x8vid(t){\n  t=String(t==null?\"\":t);if(!t)return t;\n  \/* 1) 正文里独立的视频直链\/链接 -> 播放器(排除附件卡 .att) *\/\n  t=t.replace(\/<a\\b([^>]*\\shref\\s*=\\s*[\"']([^\"']+?\\.(?:mp4|m3u8|webm|ogv|ogg|mov)(?:[?#][^\"']*)?)[\"'][^>]*)>[\\s\\S]*?<\\\/a>\/gi,function(mm,attrs,url){\n    if(\/\\bclass\\s*=\\s*\"[^\"]*\\batt\\b\/i.test(mm))return mm;\n    return x8VidOne(url);\n  });\n  \/* 2) <ignore_js_op> 包裹的 Discuz 媒体块(含 detectPlayer) *\/\n  t=t.replace(\/<ignore_js_op\\b[^>]*>[\\s\\S]*?<\\\/ignore_js_op>\/gi,function(blk){var u=x8VidUrl(blk);return u?x8VidOne(u):blk;});\n  \/* 3) 残留 script(detectPlayer) *\/\n  t=t.replace(\/<script\\b[^>]*>[\\s\\S]*?<\\\/script>\/gi,function(blk){var u=x8VidUrl(blk);return u?x8VidOne(u):\"\";});\n  \/* 4) 未被 ignore_js_op 包裹的 div.media 块 *\/\n  t=x8RepMedia(t);\n  \/* 5) 已存在的 <video> 规范化 *\/\n  t=t.replace(\/<video\\b([^>]*)>\/gi,function(mm,at){\n    var s='<video class=\"x8v\"'+String(at).replace(\/\\sclass\\s*=\\s*\"[^\"]*\"\/i,\"\");\n    if(!\/\\bcontrols\\b\/i.test(s))s+=\" controls\";\n    if(!\/\\bplaysinline\\b\/i.test(s))s+=\" playsinline webkit-playsinline\";\n    if(!\/\\bpreload\\b\/i.test(s))s+=' preload=\"metadata\"';\n    if(!\/\\breferrerpolicy\\b\/i.test(s))s+=' referrerpolicy=\"no-referrer\"';\n    return s+\">\";\n  });\n  return t;\n}\nfunction x8Hls(src,v){\n  function go(){try{var H=window.Hls;if(H&&H.isSupported()){var h=new H();h.loadSource(src);h.attachMedia(v);}else{v.src=src;}}catch(e){try{v.src=src;}catch(_){}}}\n  if(window.Hls)return go();\n  try{var s=document.createElement(\"script\");s.src=\"https:\/\/cdn.jsdelivr.net\/npm\/hls.js@1.5.17\/dist\/hls.min.js\";s.onload=go;s.onerror=function(){try{v.src=src;}catch(_){}};(document.head||document.documentElement).appendChild(s);}catch(e){try{v.src=src;}catch(_){}}\n}\nfunction x8BindVid(){\n  try{\n    var list=document.querySelectorAll(\".x8vhls\"),i;\n    for(i=0;i<list.length;i++){\n      var box=list[i];if(box.getAttribute(\"data-b\"))continue;box.setAttribute(\"data-b\",\"1\");\n      var src=box.getAttribute(\"data-src\"),v=box.querySelector(\"video\");\n      if(!src||!v)continue;\n      try{if(v.canPlayType(\"application\/vnd.apple.mpegurl\")){v.src=src;continue;}}catch(e){}\n      x8Hls(src,v);\n    }\n  }catch(e){}\n}\nfunction yn(t){var e=pn(t,'<div class=\"message\">');return e||(e=S(\/<div class=\"message\">([\\s\\S]*?)<\\\/div>\/,t,\"\")),e=e.replace(\/<i class=\"pstatus\">[\\s\\S]*?<\\\/i>(\\s*<br\\s*\\\/?>)*\/gi,\"\"),e=e.replace(\/(<\\\/div>)(\\s*<br\\s*\\\/?>)+\/gi,\"$1\"),e=e.replace(\/^(\\s*<br\\s*\\\/?>)+\/i,\"\"),e=e.replace(\/(\\s*<br\\s*\\\/?>)+$\/i,\"\"),e.trim()}function mn(t){for(var e=\"\",n=t.indexOf('<div class=\"message\">'),r=n<0?t:t.slice(n),a=\/<ul class=\"img_one\">([\\s\\S]*?)<\\\/ul>\/gi,o;(o=a.exec(r))!==null;){var d=o[1].match(\/<img[^>]*>\/gi);if(d)for(var f=0;f<d.length;f++)\/smiley|static\\\/image\\\/common\/i.test(d[f])||(e+=d[f])}if(!e)for(var l=\/<div class=\"quote\">([\\s\\S]*?)<\\\/div>\/gi,p;(p=l.exec(r))!==null;){var h=p[1];if(!(\/需要.*登录|您无权|attachment.*em>\/i.test(h)&&!\/<img\/i.test(h))){var w=h.match(\/<img[^>]*>\/gi);if(w)for(var b=0;b<w.length;b++)\/smiley|static\\\/image\\\/common\/i.test(w[b])||(e+=w[b])}}for(var x=\"\",I=\/<ul class=\"post_attlist\">([\\s\\S]*?)<\\\/ul>\/gi,m;(m=I.exec(r))!==null;)for(var v=\/<li[^>]*>([\\s\\S]*?)<\\\/li>\/gi,C;(C=v.exec(m[1]))!==null;){var y=C[1],B=xe(S(\/<a[^>]*href=\"([^\"]*)\"\/,y,\"\"));if(!(!B||\/^javascript\/i.test(B))){var R=it(xe(S(\/<img[^>]*src=\"([^\"]*)\"\/,y,\"\"))),L=z(S(\/<span class=\"link[^\"]*\">([\\s\\S]*?)<\\\/span>\/,y,\"\"))||z(S(\/<span[^>]*>([\\s\\S]*?)<\\\/span>\/,y,\"\"));L||(L=z(y.replace(\/<[^>]*>\/g,\" \")).slice(0,60)||\"附件\");var O=y.match(\/<p[^>]*>([\\s\\S]*?)<\\\/p>\/gi)||[],H=O[0]?z(O[0]):\"\",et=O[1]?z(O[1]):O[0]?z(O[0]):\"\",lt=S(\/([\\d.]+\\s*[KMGT]?B)\/i,et,\"\"),nt=S(\/下载次数:\\s*(\\d+)\/,et,\"\"),ft=\"\";lt&&(ft+=lt),nt&&(ft+=(ft?\" · \":\"\")+\"下载 \"+nt+\" 次\"),H&&\/上传\/.test(H)&&(ft+=(ft?\" · \":\"\")+H.replace(\/\\s*上传\\s*\/,\"\").trim());var pt=B;if(L){var Ot=encodeURIComponent(String(L).replace(\/[\\\/\\\\:*?\"<>|]+\/g,\"_\"));if(Ot){var Sr=B.search(\/[?#]\/);pt=Sr<0?B+\"\/\"+Ot:B.slice(0,Sr)+\"\/\"+Ot+B.slice(Sr)}}x+='<a class=\"att\" href=\"'+k(pt)+'\" download=\"'+k(L)+'\" title=\"'+k(L)+`\" onclick=\"attTip('`+rt(L)+`')\">`+(R?'<img class=\"atico\" src=\"'+k(R)+`\" alt=\"\" onerror=\"this.style.display='none'\">`:'<span class=\"atico atfx\">📄<\/span>')+'<span class=\"atinfo\"><b class=\"atnm\">'+k(L)+\"<\/b>\"+(ft?'<span class=\"atmeta\">'+k(ft)+\"<\/span>\":\"\")+'<\/span><span class=\"atdl\">⬇<\/span><\/a>'}}return x&&(e+='<div class=\"atts\">'+x+\"<\/div>\"),e}function kr(t){s(`⬇ 开始下载\n`+t+`\n\n保存位置：系统下载目录\n\/sdcard\/Download\/`,\"ok\")}function vn(t){var e=t.match(\/<div id=\"comment_\\d+\">([\\s\\S]*?)<div id=\"post_rate_div_\/);if(!e)return\"\";for(var n=\"\",r=\/id=\"commentdetail_\\d+\">([\\s\\S]*?)(?=id=\"commentdetail_\\d+|$)\/g,a;(a=r.exec(e[1]))!==null;){var o=S(\/<span class=\"z\">[\\s\\S]*?<a[^>]*>([^<]+)<\\\/a>\/,a[1],\"匿名\"),d=S(\/<li class=\"mtime\">([\\s\\S]*?)<\\\/li>\/,a[1],\"\"),f=S(\/<li class=\"mtxt[^\"]*\">([\\s\\S]*?)<\\\/li>\/,a[1],\"\");f&&(n+='<div class=\"cmt\"><b>🌸 '+k(o)+\"<\/b><i>\"+k(z(d))+'<\/i><div class=\"ct\">'+f+\"<\/div><\/div>\")}return n}function _t(t,e){t=String(t||\"\");var n={};n.tid=S(\/tid=(\\d+)\/,e||T,\"\"),P&&P.tid&&n.tid&&P.tid!==n.tid&&(P=null),n.fid=S(\/fid=(\\d+)\/,t,\"\")||S(\/fid=(\\d+)\/,e||T,\"\")||\"2\",n.title=z(S(\/<div class=\"view_tit\">([\\s\\S]*?)<\\\/div>\/,t,\"\"))||z(S(\/<title>([\\s\\S]*?)<\\\/title>\/,t,\"\"))||\"无标题\",n.formhash=S(\/formhash['\":]?\\s*[:=]\\s*['\"]?([a-f0-9]{8})\/,t,\"\"),n.total=S(\/全部回复<em>(\\d+)<\\\/em>\/,t,\"0\"),n.myuid=S(\/discuz_uid\\s*=\\s*'(-?\\d+)'\/,t,\"0\");for(var r=\/<div class=\"plc[^\"]*\" id=\"pid(\\d+)\">([\\s\\S]*?)(?=<div class=\"plc[^\"]*\" id=\"pid\\d+\"|<div class=\"txtlist|<div class=\"discuz_x|<div class=\"pg|<div class=\"threadlist_foot|$)\/g,a=[],o;(o=r.exec(t))!==null&&a.length<60;)a.push({pid:o[1],h:o[2]});n.empty=!a.length,a.length||(a=[{pid:\"0\",h:'<div class=\"message\">内容解析失败：可能未登录\/无权限，或页面结构不同。<\/div>'}]),n.items=[];for(var d=0;d<a.length;d++){var f=a[d],l=S(\/<span class=\"z\">\\s*<a[^>]*>([^<]+)<\\\/a>\/,f.h,\"\")||S(\/<li class=\"mtit\">[\\s\\S]*?<a[^>]*>([^<]+)<\\\/a>\/,f.h,\"匿名\"),p=S(\/<span class=\"y\">\\s*([^<]*?)\\s*<\\\/span>\/,f.h,\"\")||S(\/<span class=\"y\">([\\s\\S]*?)<\\\/span>\/,f.h,\"\"),h=S(\/<li class=\"mtime\">([\\s\\S]*?)<\\\/li>\/,f.h,\"\"),w=z(String(h).replace(\/<span class=\"y\">[\\s\\S]*?<\\\/span>\/g,\"\")),b=w.match(\/\\d{4}-\\d{1,2}-\\d{1,2}[^0-9]*\\d{1,2}:\\d{2}(:\\d{2})?\/);b&&(w=b[0]);var x=S(\/<span class=\"z\">\\s*<a href=\"[^\"]*uid=(\\d+)\/,f.h,\"\")||S(\/uid=(\\d+)\/,f.h,\"0\");n.items.push({pid:f.pid,uid:x,author:k(l||\"匿名\"),floor:k(z(p)||\"#\"+d),time:k(w),msg:x8vid(yn(f.h))+mn(f.h),cmts:vn(f.h)})}var I=(e||\"\").match(\/page=(\\d+)\/),m=parseInt(I?I[1]:S(\/<div class=\"pg\"><strong>(\\d+)<\\\/strong>\/,t,\"\"),10);m>0||(m=1);var v=m<=1;n.opLocal=v;var C=S(\/dm-eye\"><\\\/i><em>(\\d+)<\\\/em>\/,a[0].h,\"0\"),y=S(\/dm-chat-s\"><\\\/i><em>(\\d+)<\\\/em>\/,a[0].h,\"0\"),B=S(\/<span class=\"z\">\\s*<a href=\"[^\"]*uid=(\\d+)\/,a[0].h,\"0\");(v||!P)&&(P={op:n.items[0],viewCnt:C,replyCnt:y,uid:B,title:n.title,total:n.total,formhash:n.formhash,tid:n.tid,fid:n.fid,fromP1:v}),n.op=v?n.items[0]:P.op||n.items[0],n.viewCnt=v?C:P.viewCnt||C,n.replyCnt=v?y:P.replyCnt||y,n.uid=v?B:P.uid||B,!v&&P&&((!n.title||n.title===\"无标题\")&&(n.title=P.title),(!n.total||n.total===\"0\")&&(n.total=P.total),n.formhash||(n.formhash=P.formhash),n.tid||(n.tid=P.tid),n.fid||(n.fid=P.fid));var R=(e||\"\").match(\/page=(\\d+)\/),L=parseInt(R?R[1]:S(\/<div class=\"pg\"><strong>(\\d+)<\\\/strong>\/,t,\"\"),10);n.cur=L>0?L:1;var O=parseInt(S(\/共\\s*(\\d+)\\s*页\/,t,\"\"),10);if(!(O>0)){var H=0,et=t.match(\/<div class=\"pg\"[\\s\\S]*?<\\\/div>\/);if(et){var lt=et[0].match(\/page=(\\d+)\/g);if(lt)for(var nt=0;nt<lt.length;nt++){var ft=parseInt(lt[nt].replace(\"page=\",\"\"),10);ft>H&&(H=ft)}}O=H||1}return n.tp=O,n}function te(t){return F.myuid&&F.myuid!==\"0\"&&F.myuid!==\"-1\"&&t&&t.uid===F.myuid}var Rr=\"https:\/\/bbs.xiaoxiaoshuo8.com\/index.php?mobile=2\";function Mr(){try{if(history&&history.length>1){history.back();return}}catch(t){}try{if(typeof java!=\"undefined\"&&java&&typeof java.open==\"function\"){java.open(\"rss\",Rr);return}}catch(t){}try{location.href=Rr}catch(t){}}function Ee(t){var e=i.btnL,n=\"\";return n+='<div class=\"card post\">',n+='<div class=\"hd\">'+Ie(t.uid,t.op.author,!1)+'<div class=\"who\"><b class=\"un'+(i.opnRb?\" rb\":\"\")+'\">'+t.op.author+'<span class=\"tag\">楼主<\/span><\/b><div class=\"sub\"><span class=\"tm\">'+t.op.time+'<\/span><\/div><\/div><div class=\"hdbtns\"><button class=\"ib back\" onclick=\"goBack()\">‹ 返回<\/button><button class=\"ib\" onclick=\"downloadThread()\" title=\"下载HTML\">⬇️<\/button><\/div><\/div>',n+='<div class=\"stat meta\"><span class=\"vw\">👁 '+k(t.viewCnt)+'<\/span><span class=\"rp\"> &nbsp;·&nbsp; 💬 '+k(t.replyCnt)+\"<\/span><\/div>\",n+='<div class=\"tt\">'+t.title+\"<\/div>\",n+='<div class=\"msg\">'+t.op.msg+\"<\/div>\"+t.op.cmts,n+='<div class=\"acts\"><span class=\"bt\" role=\"button\" onclick=\"doFav()\">'+k(e.fav)+'<\/span><span class=\"bt\" role=\"button\" onclick=\"showCmt('+(t.opLocal===!1?-1:0)+')\">'+k(e.cmt)+'<\/span><span class=\"bt pri\" role=\"button\" onclick=\"focusReply()\">'+k(e.rep)+\"<\/span><\/div>\",n+='<div class=\"tools\">',n+='<button class=\"tb'+(zt?\" on\":\"\")+'\" onclick=\"goOrder()\">'+k(zt?e.asc:e.ord)+'<\/button><button class=\"tb'+(Yt?\" on\":\"\")+'\" onclick=\"goAuthor()\">'+k(Yt?e.all:e.op)+'<\/button><button class=\"tb\" onclick=\"nav(CUR)\">'+k(e.rl)+\"<\/button>\",te(t.op)&&(n+='<button class=\"ed\" onclick=\"editPost('+(t.opLocal===!1?-1:0)+')\">编辑<\/button>'),n+=\"<\/div><\/div>\",n+='<div class=\"rtt meta\">🍡 全部回复 · '+k(t.total||t.replyCnt)+\"<\/div>\",n}function Ce(t){return t.opLocal===!1?0:1}function ee(t,e){var n=t.items[e];return n?'<div class=\"card reply\"><div class=\"hd\">'+Ie(n.uid,n.author,!0)+'<div class=\"who\"><b class=\"un'+(i.rnRb?\" rb\":\"\")+'\">'+n.author+'<\/b><div class=\"sub meta\"><span class=\"fl\">'+n.floor+'<\/span><span class=\"tm\"> · '+n.time+'<\/span><\/div><\/div><div class=\"hdbtns\"><button class=\"ib\" onclick=\"replyTo('+e+')\" title=\"回复TA\">💬<\/button><button class=\"ib\" onclick=\"showCmt('+e+')\" title=\"点评\">💭<\/button><\/div><\/div><div class=\"msg\">'+n.msg+\"<\/div>\"+n.cmts+(te(n)?'<div class=\"tools\"><button class=\"ed\" onclick=\"editPost('+e+')\">编辑<\/button><\/div>':\"\")+\"<\/div>\":\"\"}function Pe(t){var e=i.btnL,n=\"\",r=parseInt(t.cur)||1,a=parseInt(t.tp)||1,o=\"\";return o+=r>1?'<button class=\"tb\" onclick=\"goPage('+(r-1)+')\">‹ 上一页<\/button>':'<button class=\"tb off\">‹ 上一页<\/button>',o+='<button class=\"pnum meta\" onclick=\"pickPage()\" title=\"点击选择页码\">'+(a>1?\"第 \"+r+\" \/ \"+a+\" 页\":\"第 \"+r+\" 页\")+(a>1?' <i class=\"pcar\">▾<\/i>':\"\")+\"<\/button>\",o+=r<a?'<button class=\"tb\" onclick=\"goPage('+(r+1)+')\">下一页 ›<\/button>':'<button class=\"tb off\">下一页 ›<\/button>',n+='<div class=\"pgbar\">'+o+\"<\/div>\",n+='<div class=\"dock\"><button class=\"ib\" onclick=\"attachDlg()\" title=\"插入图片\">📎<\/button><input class=\"slot\" type=\"text\" id=\"ri\" placeholder=\"说点什么…(◦˙▽˙◦)\" onkeydown=\"if(event.keyCode==13)sendReply()\"><button class=\"send\" onclick=\"sendReply()\">'+k(e.send)+\"<\/button><\/div>\",n}var hn=\/<img\\b(?![^>]*\\sloading=)\/gi;function gn(t){for(var e=Ee(t)||\"\",n=Ce(t),r=n;r<t.items.length;r++)e+=ee(t,r);return e+Pe(t)}var wn=\"more\";function Rt(t){var e=parseInt(i.firstN,10),n=Ce(t),r;if(!(e>0)||!t.items||t.items.length<=n+e)return gn(t).replace(hn,'<img loading=\"lazy\" decoding=\"async\"');r=n+e;for(var a=Ee(t)||\"\",o=n;o<r;o++)a+=ee(t,o);return a+='<div id=\"'+wn+'\" data-next=\"'+r+'\"><\/div>',a+=Pe(t),a.replace(hn,'<img loading=\"lazy\" decoding=\"async\"')}function Se(){try{var t=document.getElementById(wn);if(!t||!F||!F.items)return;var e=parseInt(t.getAttribute(\"data-next\"),10);if(!(e>=0))return;for(var n=\"\",r=Math.min(F.items.length,e+60),a=e;a<r;a++)n+=ee(F,a);if(n=n.replace(hn,'<img loading=\"lazy\" decoding=\"async\"'),r>=F.items.length?t.outerHTML=n:(t.insertAdjacentHTML(\"beforebegin\",n),t.setAttribute(\"data-next\",r),Ae=!0),r>=F.items.length){Ae=!1;try{It(),Bt()}catch(o){}}}catch(o){Ae=!1}}var Ae=!1;function bn(){if(Ae)try{var t=document.getElementById(wn);if(!t)return;var e=t.getBoundingClientRect();e.top-window.innerHeight<900&&Se()}catch(n){}}var wa=\/(smiley|static\\\/image\\\/common)\/i;function Ft(t){var e=t.getAttribute?String(t.getAttribute(\"src\")||\"\"):\"\";return wa.test(e)}var ba=\/mod=viewthread[^\"']*aid=\\d+\/i,Lr=\/\\.(jpe?g|png|gif|webp|bmp|svg)(\\?|#|$)\/i;function xn(t){if(!t||!t.getAttribute)return\"\";for(var e=[\"file\",\"zoomfile\",\"data-src\",\"data-original\",\"_src\"],n=\"\",r=0;r<e.length&&(n=String(t.getAttribute(e[r])||\"\").trim(),!n);r++);return n?\/^(https?:|data:|file:|blob:)\/i.test(n)?n:it(n):\"\"}function Bn(){for(var t=document.querySelectorAll(\".msg img\"),e=0;e<t.length;e++){var n=t[e];if(!Ft(n)){var r=String(n.className||\"\");if(!(r.indexOf(\"atico\")>=0||r.indexOf(\"avi\")>=0)){var a=xn(n);a&&n.setAttribute(\"data-src\",a);var o=n.getAttribute(\"src\");a&&o&&o!==a&&!Lr.test(o)&&ba.test(o)&&(n.setAttribute(\"data-osrc\",o),n.onerror=function(){var d=this,f=d.getAttribute(\"data-osrc\");f&&d.getAttribute(\"src\")!==f&&d.setAttribute(\"src\",f)},n.setAttribute(\"src\",a)),!Ft(n)&&r.indexOf(\"atico\")<0&&r.indexOf(\"zoom\")<0&&(n.className=(r?r+\" \":\"\").trim()===\"\"?\"zoom\":r+\" zoom\")}}}}var vt=null,ne=typeof IntersectionObserver!=\"undefined\",Mt=[],Fn=0,Dr=0;function Te(){if(Fn=0,!!Mt.length){var t=window.innerHeight||document.documentElement.clientHeight||600,e=[],n;for(n=0;n<Mt.length;n++){var r=Mt[n];if(r&&r.parentNode&&r.getAttribute(\"loading\")){try{var a=r.getBoundingClientRect();if(a.top<t+600&&a.bottom>-600){r.removeAttribute(\"loading\");continue}}catch(o){try{r.removeAttribute(\"loading\")}catch(d){}continue}e.push(r)}}Mt=e}}function re(){Fn||(Fn=setTimeout(Te,150))}function In(){if(!Dr){Dr=1;try{window.addEventListener(\"scroll\",re,!1)}catch(t){}try{window.addEventListener(\"resize\",re,!1)}catch(t){}}if(!(vt||!ne))try{vt=new IntersectionObserver(function(t){for(var e=0;e<t.length;e++){var n=t[e];if(!(!n||!n.isIntersecting)){var r=n.target;try{r.removeAttribute(\"loading\")}catch(a){}try{vt&&vt.unobserve(r)}catch(a){}}}Te()},{rootMargin:\"600px 0px\"})}catch(t){vt=null,ne=!1}}function En(t){if(t){var e=String(t.className||\"\");if(!(e.indexOf(\"atico\")>=0||e.indexOf(\"avi\")>=0)){try{if(Ft(t))return}catch(n){}try{if(t.complete&&t.naturalWidth>0){t.removeAttribute(\"loading\");return}}catch(n){}if(!i.imgLazy||!ne){try{t.removeAttribute(\"loading\")}catch(n){}return}if(t.getAttribute(\"loading\")||t.setAttribute(\"loading\",\"lazy\"),In(),Mt.push(t),vt)try{vt.observe(t)}catch(n){}re()}}}function Nr(t){_e(\"imgLazy\",t?1:0)}function It(){try{Bn()}catch(v){}for(var t=document.querySelectorAll(\".msg\"),e=0;e<t.length;e++){for(var n=t[e],r=[],a=n.firstChild;a;)r.push(a),a=a.nextSibling;for(var o=null,d=0;d<r.length;d++){var f=r[d],l=f&&f.nodeType===1&&f.tagName===\"IMG\"&&!Ft(f);if(l)o||(o=document.createElement(\"div\"),o.className=\"imgrid\",n.insertBefore(o,f)),o.appendChild(f);else{var p=f&&f.nodeType===3&&!\/[^\\s]\/.test(f.nodeValue)||f&&f.nodeType===1&&f.tagName===\"BR\";p||o&&(o.children.length===1&&(o.className=\"imgrid one\"),o=null)}}o&&o.children.length===1&&(o.className=\"imgrid one\");for(var h=n.querySelectorAll(\".imgrid\"),w=0;w<h.length;w++)for(var b=h[w].querySelectorAll(\"img\"),x=0;x<b.length;x++)b[x].className=\"zoom\",b[x].getAttribute(\"loading\")||b[x].setAttribute(\"loading\",\"lazy\"),b[x].setAttribute(\"decoding\",\"async\");for(var I=n.querySelectorAll(\"img\"),m=0;m<I.length;m++)En(I[m])}}function ie(){zt=\/[?&]ordertype=1(&|$)\/.test(T),Yt=\/[?&]authorid=\\d+\/.test(T)}var zt=!1,Yt=!1;ie();var F=_t(X,T);V.innerHTML=Rt(F),It(),Bt(),Pt(),document.title=F.title,!F.opLocal&&P&&!P.fromP1&&ke();var Lt=F.formhash,Gt=F.tid,xa=F.fid,Ba=F.uid,Ht=null,Cn=null;function ke(){var t=T;\/([?&])page=\\d+\/.test(t)?t=t.replace(\/([?&])page=\\d+\/,\"$1page=1\"):t+=(t.indexOf(\"?\")<0?\"?\":\"&\")+\"page=1\",Dt(t).then(function(e){e&&(_t(e,t),P&&(P.fromP1=!0),P&&(F.op=P.op,F.opLocal=!1,F.viewCnt=P.viewCnt,F.replyCnt=P.replyCnt,F.uid=P.uid,(!F.title||F.title===\"无标题\")&&(F.title=P.title),(!F.total||F.total===\"0\")&&(F.total=P.total),F.formhash||(F.formhash=P.formhash),V.innerHTML=Rt(F),It(),Bt(),Pt()))}).catch(function(){})}function Y(t,e){var n=_t(t,e);if(n.empty){s(\"✘ 内容为空，已保留原页面（可点🔄重载）\",\"no\");return}F=n,Lt=F.formhash,T=it(e||T),ie(),V.innerHTML=Rt(F),It(),Bt(),Pt(),window.scrollTo(0,0),!F.opLocal&&P&&!P.fromP1&&ke()}function Dt(t){return t=it(t),new Promise(function(e,n){if(typeof ajaxAwait==\"function\"){Promise.resolve(ajaxAwait(t)).then(function(r){e(String(r||\"\"))},function(){Re(t,e,n)});return}Re(t,e,n)})}function Re(t,e,n){fetch(t,{credentials:\"include\"}).then(function(r){return r.text()}).then(function(r){e(String(r||\"\"))},n)}function Wt(t,e){return t=it(t),t.indexOf(\"inajax=1\")<0&&(t+=(t.indexOf(\"?\")>-1?\"&\":\"?\")+\"inajax=1\"),new Promise(function(n,r){function fb(){try{if(typeof ajaxAwait==\"function\"){ajaxAwait(t,\"POST\",e,{\"Content-Type\":\"application\/x-www-form-urlencoded\"}).then(function(a){n(String(a==null?\"\":a))},function(){Me(t,e,n,r)});return}}catch(q){}Me(t,e,n,r)}try{if(typeof postAwait==\"function\"){Promise.resolve(postAwait(t,e,\"{}\")).then(function(a){n(String(a==null?\"\":a))},fb);return}}catch(q){}fb()})}function Me(t,e,n,r){fetch(t,{method:\"POST\",body:e,credentials:\"include\",headers:{\"Content-Type\":\"application\/x-www-form-urlencoded\"}}).then(function(a){return a.text()}).then(function(a){n(String(a||\"\"))},r)}function qt(t){var e=String(t||\"\"),n=e.match(\/<!\\[CDATA\\[([\\s\\S]*?)\\]\\]>\/),r=z(n?n[1]:e);if(\/请先登录|需要登录|您还未登录|登录后才能|mod=logging\/.test(e))return{ok:!1,msg:\"需要先登录（订阅源→登录）\"};if(\/System Error|非法字符|已经被系统拒绝\/.test(e))return{ok:!1,msg:\"服务器拒绝（站点防护）\"};if(\/抱歉[，,]\/.test(r)){var a=r.match(\/抱歉[，,]([^。！!]{0,60})\/);return{ok:!1,msg:a?\"抱歉，\"+a[1]:\"失败：\"+r.slice(0,60)}}return\/无权|没有权限|权限不足\/.test(r)?{ok:!1,msg:\"没有权限\"}:String(e||\"\").trim()?\/succeed|成功|succeedhandle\/i.test(e)?{ok:!0,msg:\"操作成功\"}:r?{ok:!0,msg:r.slice(0,60)}:{ok:!0,msg:\"已提交（站点未返回提示文字）\"}:{ok:!1,msg:\"服务器无响应（可能未登录或请求被拦截）\"}}function s(t,e){var n=document.querySelector(\".tip\");n&&n.remove();var r=document.createElement(\"div\");r.className=\"tip \"+(e||\"\"),r.textContent=t,document.body.appendChild(r),setTimeout(function(){r.remove()},3e3)}function Or(){if(!Lt){s(\"✘ 缺少 formhash：未登录或页面未就绪\",\"no\");return}s(\"发送中…\",\"wait\"),Wt(\"home.php?mod=spacecp&ac=favorite&type=thread&id=\"+Gt+\"&mobile=2\",\"favoritesubmit=true&formhash=\"+Lt).then(function(t){var e=qt(t);s(e.ok?\"✔ 收藏成功\":\"✘ \"+e.msg,e.ok?\"ok\":\"no\")}).catch(function(t){s(\"✘ 网络错误\",\"no\")})}function Pn(t){var e=t===-1?P&&P.op?P.op:F.op:null;Ht=t===-1?e?e.pid:null:F.items[t]?F.items[t].pid:null,document.getElementById(\"mm\").className=\"modal on\",document.getElementById(\"ci\").value=\"\"}function Sn(){document.getElementById(\"mm\").className=\"modal\"}function Xr(){var t=document.getElementById(\"ci\").value.trim();if(!t){s(\"✘ 请输入点评内容\",\"no\");return}s(\"发送中…\",\"wait\"),Wt(\"forum.php?mod=misc&action=comment&tid=\"+Gt+\"&pid=\"+(Ht||\"0\")+\"&mobile=2\",\"subject=\"+encodeURIComponent(document.getElementById(\"et\").value.trim())+\"&message=\"+encodeURIComponent(t)+\"&formhash=\"+Lt).then(function(e){var n=qt(e);n.ok?(s(\"✔ 点评成功\",\"ok\"),Sn(),ht(T)):s(\"✘ \"+n.msg,\"no\")}).catch(function(e){s(\"✘ 网络错误\",\"no\")})}\/* ===== fixed34: 回复成功后定位并高亮「刚发表的最新回复卡片」 ===== *\/\nvar NEWRP=null;\nfunction rpCss(){\n  if(document.getElementById('x8rpcss'))return;\n  var st=document.createElement('style');st.id='x8rpcss';\n  st.textContent='@keyframes x8rpk{0%{background:rgba(74,108,247,.22)}100%{background:transparent}}'\n    +'.card.newrp{animation:x8rpk 2.6s ease-out 1;border-color:#4A6CF7!important}';\n  (document.head||document.body).appendChild(st);\n}\nfunction rpHi(){\n  if(!NEWRP)return;\n  var want=String(NEWRP.t||'').replace(\/\\s+\/g,'');\n  NEWRP=null;\n  setTimeout(function(){\n    try{\n      var host=(typeof V!=='undefined'&&V)?V:document.body;\n      var cards=host.querySelectorAll('.card.reply'),n=cards.length;\n      if(!n)return;\n      var hit=null,i;\n      \/* 从「最新」一端开始比对: 倒序最新在首, 正序最新在尾 *\/\n      if(want){\n        for(i=0;i<n;i++){\n          var k=zt?i:(n-1-i);\n          var m=cards[k].querySelector('.msg');\n          var t=m?String(m.textContent||'').replace(\/\\s+\/g,''):'';\n          if(t&&t.indexOf(want)>=0){hit=cards[k];break;}\n        }\n      }\n      if(!hit)hit=zt?cards[0]:cards[n-1];\n      if(!hit)return;\n      rpCss();\n      try{hit.className+=' newrp';}catch(e){}\n      try{hit.scrollIntoView({block:'center'});}catch(e){try{hit.scrollIntoView();}catch(e2){}}\n    }catch(e){}\n  },60);\n}\nfunction _r(){var t=document.getElementById(\"ri\"),e=t.value.trim();if(!e){s(\"✘ 请输入内容\",\"no\");return}s(\"发送中…\",\"wait\");var n=\"forum.php?mod=post&action=reply&fid=\"+xa+\"&tid=\"+Gt+(Ht?\"&reppost=\"+Ht:\"\")+\"&mobile=2\";Wt(n,\"message=\"+encodeURIComponent(e)+\"&formhash=\"+Lt+\"&replysubmit=yes\").then(function(r){var a=qt(r);a.ok?(t.value=\"\",Ht=null,s(\"✔ 回复成功\",\"ok\"),NEWRP={t:e},ht(ae(zt?1:99999,!1,zt))):s(\"✘ \"+a.msg,\"no\")}).catch(function(r){s(\"✘ 网络错误\",\"no\")})}function An(){document.getElementById(\"em\").className=\"modal on\"}function Tn(){document.getElementById(\"em\").className=\"modal\"}function kn(t){var e=t===-1?P&&P.op?P.op:F.op:F.items[t];e&&(Cn=e.pid,window.Cn=Cn,s(\"读取原文…\",\"wait\"),Dt(\"forum.php?mod=post&action=edit&tid=\"+Gt+\"&pid=\"+e.pid+\"&mobile=2\").then(function(n){var r=String(n||\"\"),a=r.match(\/<textarea[^>]*name=\"message\"[^>]*>([\\s\\S]*?)<\\\/textarea>\/),s=r.match(\/<input[^>]*name=\"subject\"[^>]*value=\"([^\"]*)\"[^>]*>\/i)||r.match(\/<input[^>]*value=\"([^\"]*)\"[^>]*name=\"subject\"[^>]*>\/i)||r.match(\/<input[^>]*name=['\"]subject['\"][^>]*>\/i),o=a?a[1]:\"\";if(o=o.replace(\/&lt;\/g,\"<\").replace(\/&gt;\/g,\">\").replace(\/&quot;\/g,'\"').replace(\/&amp;\/g,\"&\"),o||(o=z(e.msg)),\/登录|logging\/.test(r)&&!a){s(\"✘ 读取失败，可能未登录\",\"no\");return}document.getElementById(\"ei\").value=o,s&&s[1]!=null?(document.getElementById(\"et\").value=s[1]):(t===-1&&F&&F.title&&(document.getElementById(\"et\").value=F.title)),An()}).catch(function(){s(\"✘ 读取原文失败\",\"no\")}))}function zr(){if(!Cn){s(\"✘ 无目标楼层\",\"no\");return}var t=document.getElementById(\"ei\").value.trim();if(!t){s(\"✘ 内容不能为空\",\"no\");return}s(\"保存中…\",\"wait\"),Wt(\"forum.php?mod=post&action=edit&tid=\"+Gt+\"&pid=\"+Cn+\"&mobile=2\",\"subject=\"+encodeURIComponent(document.getElementById(\"et\").value.trim())+\"&message=\"+encodeURIComponent(t)+\"&formhash=\"+Lt+\"&editsubmit=yes\").then(function(e){var n=qt(e);n.ok?(s(\"✔ 已保存\",\"ok\"),Tn(),ht(T)):s(\"✘ \"+n.msg,\"no\")}).catch(function(){s(\"✘ 保存失败\",\"no\")})}var Fa=\/\\.(jpe?g|png|gif|webp|bmp|svg)(\\?|#|$)\/i;function Yr(){try{s(\"⏳ 上传附件图片请到外置浏览器完成(已跳出)\",\"wait\");if(typeof java!=\"undefined\"&&java&&typeof java.open==\"function\"){java.open(\"rss\",Rr);return}}catch(t){}try{location.href=Rr}catch(t){}}function Rn(){document.getElementById(\"am\").className=\"modal\"}function Gr(){var t=document.getElementById(\"au\").value.trim();if(!t){s(\"✘ 请输入图片网址\",\"no\");return}if(!Fa.test(t)){s(\"✘ 仅支持图片后缀(jpg\/png\/gif\/webp\/bmp\/svg)\\\\n论坛不支持非图片网址显示为图片\",\"no\");return}var e=document.getElementById(\"ri\");e.value=(e.value?e.value+\" \":\"\")+\"[img]\"+t+\"[\/img]\",Rn(),document.getElementById(\"au\").value=\"\",s(\"✔ 已插入图片代码，发送后显示为图片\",\"ok\");try{e.focus()}catch(n){}}function ht(t){s(\"加载中…\",\"wait\"),Dt(t).then(function(e){var n=_t(e,t);if(n.empty){s(\"✘ 新页面无内容，已保留原页面\",\"no\");return}T=it(t),ie(),F=n,Lt=F.formhash,V.innerHTML=Rt(F),It(),Bt(),Pt(),window.scrollTo(0,0),s(\"✔ 已加载\",\"ok\")}).catch(function(e){s(\"✘ 加载失败，已保留原页面\",\"no\")})}function ae(t,e,n){var r=\"forum.php?mod=viewthread&tid=\"+Gt+\"&page=\"+(t||1);return e&&(r+=\"&authorid=\"+Ba),n&&(r+=\"&ordertype=1\"),r+\"&mobile=2\"}function Hr(){ht(ae(1,Yt,!zt))}function Wr(){ht(ae(1,!Yt,zt))}function Mn(t){ht(ae(t,Yt,zt))}function oe(){var t=document.getElementById(\"pk\");t&&t.parentNode&&t.parentNode.removeChild(t)}function Ln(t){oe(),Mn(t)}function Dn(t){var e=document.getElementById(\"pgin\"),n=parseInt(e?e.value:0,10);if(!(n>=1&&n<=t)){s(\"✘ 请输入 1 ~ \"+t+\" 之间的页码\",\"no\");return}Ln(n)}function qr(){oe();var t=parseInt(F.cur)||1,e=parseInt(F.tp)||1;if(e<=1){s(\"只有 1 页\",\"ok\");return}var n=document.createElement(\"div\");n.className=\"modal on\",n.id=\"pk\",n.onclick=function(f){f.target===n&&oe()};var r='<div class=\"mbox\"><h3>📄 跳转到第几页<\/h3>';if(e>120)r+='<div class=\"hint\">共 '+e+\" 页，页数较多，请输入要跳转的页码。<\/div>\",r+='<input class=\"slot pginput\" type=\"number\" id=\"pgin\" min=\"1\" max=\"'+e+'\" value=\"'+t+'\">',r+='<div class=\"row\"><button class=\"bt\" onclick=\"closePickPage()\">取消<\/button><button class=\"bt pri\" onclick=\"goPickInput('+e+')\">跳转<\/button><\/div>';else{r+='<div class=\"pggrid\">';for(var a=1;a<=e;a++)r+='<button class=\"pgn'+(a===t?\" on\":\"\")+'\" onclick=\"goPick('+a+')\">'+a+\"<\/button>\";r+='<\/div><div class=\"row\"><button class=\"bt\" onclick=\"closePickPage()\">取消<\/button><\/div>'}r+=\"<\/div>\",n.innerHTML=r,document.body.appendChild(n);var o=document.getElementById(\"pgin\");o&&(o.focus(),o.select(),o.onkeydown=function(f){f.keyCode===13&&Dn(e)});var d=n.querySelector(\".pgn.on\");d&&d.scrollIntoView&&d.scrollIntoView({block:\"center\"})}function Nt(){for(var t=document.querySelectorAll(\".menu\"),e=0;e<t.length;e++)t[e].remove()}function Ur(t,e){Nt();var n=e.closest(\".card\"),r=document.createElement(\"div\");r.className=\"menu\";var a=document.createElement(\"button\");a.textContent=\"💬 回复TA\",a.onclick=function(){Nn(t),Nt()},r.appendChild(a);var o=document.createElement(\"button\");if(o.textContent=\"💭 点评\",o.onclick=function(){Pn(t),Nt()},r.appendChild(o),te(F.items[t])){var d=document.createElement(\"button\");d.textContent=\"✏️ 编辑\",d.onclick=function(){kn(t),Nt()},r.appendChild(d)}n.appendChild(r),setTimeout(function(){document.addEventListener(\"click\",Nt,{once:!0})},0)}function Nn(t){var e=document.getElementById(\"ri\");e&&(e.value=\"回复 \"+F.items[t].author+\"：\",Ht=F.items[t].pid,e.focus())}function jr(){var t=document.getElementById(\"ri\");t&&t.focus()}function Vr(){s(\"检测中…\",\"wait\"),Dt(\"home.php?mod=spacecp&mobile=2\").then(function(t){var e=String(t||\"\"),n=z(S(\/<title>([\\s\\S]*?)<\\\/title>\/,e,\"\"));\/mod=logging|登录|login\/i.test(n)||\/name=\"username\"\/.test(e)?s(\"✘ 未登录 · 请到 订阅源→登录\",\"no\"):s(\"✔ 已登录\"+(n?\" · \"+n.slice(0,16):\"\"),\"ok\")}).catch(function(){s(\"✘ 检测失败\",\"no\")})}var u={sc:1,x:0,y:0,d0:0,sx:0,sy:0,mv:0,ox:0,oy:0};function Et(){var t=document.getElementById(\"lbi\");t&&(isFinite(u.x)||(u.x=0),isFinite(u.y)||(u.y=0),(!isFinite(u.sc)||u.sc<1)&&(u.sc=1),t.style.transform=\"translate(\"+u.x+\"px,\"+u.y+\"px) scale(\"+u.sc+\")\")}function ce(t){var e=document.getElementById(\"lbi\");e.src=t,u.sc=1,u.x=0,u.y=0,u.d0=0,u.mv=0,Et(),document.getElementById(\"lb\").className=\"lbox on\"}function Kr(){if(u.mv){u.mv=0;return}if(u.sc>1.05){u.sc=1,u.x=0,u.y=0,Et();return}document.getElementById(\"lb\").className=\"lbox\",document.getElementById(\"lbi\").removeAttribute(\"src\")}function On(){return document.getElementById(\"lbi\")}function Le(t){var e=t[0].clientX-t[1].clientX,n=t[0].clientY-t[1].clientY,r=Math.sqrt(e*e+n*n);return r>1?r:1}function Xn(){var t=document.getElementById(\"lb\");t&&(t.addEventListener(\"touchstart\",function(e){if(u.mv=0,e.touches.length===2){u.d0=Le(e.touches);var n=On();if(n){var r=n.getBoundingClientRect();u.ox=r.left+r.width\/2-u.x,u.oy=r.top+r.height\/2-u.y}}else e.touches.length===1&&(u.sx=e.touches[0].clientX-u.x,u.sy=e.touches[0].clientY-u.y)},{passive:!1}),t.addEventListener(\"touchmove\",function(e){if(e.touches.length===2&&u.d0){e.preventDefault(),u.mv=1;var n=Le(e.touches),r=(e.touches[0].clientX+e.touches[1].clientX)\/2,a=(e.touches[0].clientY+e.touches[1].clientY)\/2,o=Math.min(10,Math.max(1,u.sc*(n\/u.d0))),d=o\/u.sc;u.x=r-u.ox-(r-u.ox-u.x)*d,u.y=a-u.oy-(a-u.oy-u.y)*d,u.sc=o,u.d0=n,Et()}else e.touches.length===1&&u.sc>1.05?(e.preventDefault(),u.mv=1,u.x=e.touches[0].clientX-u.sx,u.y=e.touches[0].clientY-u.sy,Et()):e.touches.length===1&&(u.sx=e.touches[0].clientX-u.x,u.sy=e.touches[0].clientY-u.y)},{passive:!1}),t.addEventListener(\"touchend\",function(e){e.touches.length<2&&(u.d0=0),e.touches.length===1&&(u.sx=e.touches[0].clientX-u.x,u.sy=e.touches[0].clientY-u.y),e.touches.length===0&&u.sc<=1.05&&(u.sc=1,u.x=0,u.y=0,Et())}),t.addEventListener(\"dblclick\",function(e){e.preventDefault(),u.sc>1.05?(u.sc=1,u.x=0,u.y=0):u.sc=2.5,Et()}))}var _n=\"x8_hidebg\",zn=\"x8_hidefr\";function De(t){var e=[];try{e=at(t===\"bg\"?_n:zn,null)}catch(n){}return e&&typeof e.length==\"number\"?e:[]}function Yn(t,e){var n=De(t),r;for(r=0;r<n.length;r++)if(n[r]===e)return!0;return!1}function Zr(t,e){var n=De(t),r;for(r=0;r<n.length&&n[r]!==e;r++);r>=n.length&&n.push(e),g(t===\"bg\"?_n:zn,n),t===\"bg\"?W===e&&(W=\"\",M(wt,\"\"),ot()):_===e&&(_=\"\",M(bt,\"\"),D(),Y(X,T)),A(),s(\"✔ 已忽略该默认图（恢复默认设置可找回）\",\"ok\")}function Ne(t){\n  var e=t===\"bg\",lib=e?Z:J,defs=e?ha:va,d=e?W:_,cur=(typeof PVS!=\"undefined\"&&PVS[t])||\"\",f=\"\";\n  f+='<div class=\"catadd\"><input type=\"text\" id=\"'+t+'sel\" readonly value=\"'+k(cur||d||\"\")+'\" placeholder=\"点下面的图片选中，再点复制\" onclick=\"this.select()\"><button class=\"tb\" onclick=\"pvCopyBtn(this)\" data-k=\"'+t+'\">📋复制链接<\/button><\/div>';\n  f+='<div class=\"pregrid\">';\n  var x,b,y,inLib;\n  \/* 1) 库里的(用户下载\/同步) *\/\n  for(x=0;x<lib.length;x++){\n    b=(lib[x]&&lib[x].u)||lib[x];\n    f+='<div class=\"pw'+(d===b?\" sel\":\"\")+((cur===b)?\" pick\":\"\")+'\"><img class=\"pv\" referrerpolicy=\"no-referrer\" src=\"'+k(b)+'\" data-k=\"'+t+'\" data-u=\"'+k(b)+'\" data-def=\"0\" data-idx=\"'+x+'\" onclick=\"try{pvSelEl(this)}catch(e){};pvApply(this)\" onlongpress=\"pvDel(this)\" onmousedown=\"lpStart(event,this.dataset.k,this.dataset.u)\" onmouseup=\"lpEnd()\" onmouseleave=\"lpEnd()\" ontouchstart=\"lpStart(event,this.dataset.k,this.dataset.u)\" ontouchend=\"lpEnd()\" ontouchcancel=\"lpEnd()\"><button class=\"del\" onclick=\"pvDel(this)\">×<\/button><\/div>';\n  }\n  \/* 2) 内置默认图(ha\/va)中不在库里的, 合并显示, 天然去重(不再双份) *\/\n  for(x=0;x<defs.length;x++){\n    b=(defs[x]&&defs[x].u)||defs[x];inLib=false;\n    for(y=0;y<lib.length;y++){if(((lib[y]&&lib[y].u)||lib[y])===b){inLib=true;break;}}\n    if(inLib)continue;\n    f+='<div class=\"pw'+(d===b?\" sel\":\"\")+((cur===b)?\" pick\":\"\")+'\"><img class=\"pv\" referrerpolicy=\"no-referrer\" src=\"'+k(b)+'\" data-k=\"'+t+'\" data-u=\"'+k(b)+'\" data-def=\"1\" onclick=\"try{pvSelEl(this)}catch(e){};pvApply(this)\" onlongpress=\"pvDel(this)\" onmousedown=\"lpStart(event,this.dataset.k,this.dataset.u)\" onmouseup=\"lpEnd()\" onmouseleave=\"lpEnd()\" ontouchstart=\"lpStart(event,this.dataset.k,this.dataset.u)\" ontouchend=\"lpEnd()\" ontouchcancel=\"lpEnd()\"><button class=\"del\" onclick=\"pvDel(this)\">×<\/button><\/div>';\n  }\n  f+='<\/div>';\n  f+='<div class=\"row\"><button class=\"bt\" onclick=\"resetDef(this.dataset.k)\" data-k=\"'+t+'\">↺ 恢复默认'+(e?'背景图':'外框')+'<\/button><\/div>';\n  return f;\n}var Oe=null;function Jr(t,e,n){Gn(),Oe=setTimeout(function(){Hn(e,n)},600)}function Gn(){Oe&&(clearTimeout(Oe),Oe=null)}function $r(t,e){var n=t===\"bg\"?Tt:kt;n[e]=!n[e],g(t===\"bg\"?Jt:$t,n),A()}function Qr(t,e){if(e===\"默认\"){s(\"✘ 默认分类不可删除\",\"no\");return}if(confirm(\"删除分类「\"+e+`」？\n该分类下的自定义图片将移回「默认」。`)){var n=t===\"bg\"?$:Q,r=t===\"bg\"?Z:J,a=t===\"bg\"?Tt:kt,o=n.indexOf(e);o>=0&&n.splice(o,1);for(var d=0;d<r.length;d++)r[d].c===e&&(r[d].c=\"默认\");delete a[e],t===\"bg\"?(g(Kt,n),g(St,r),g(Jt,a)):(g(Zt,n),g(At,r),g($t,a)),A(),s(\"✔ 已删除分类「\"+e+\"」\",\"ok\")}}function ti(t){var e=document.getElementById(t+\"nc\"),n=e?e.value.trim():\"\";if(!n){s(\"✘ 请输入分类名\",\"no\");return}var r=t===\"bg\"?$:Q;if(r.indexOf(n)>=0){s(\"✘ 分类已存在\",\"no\");return}r.push(n),g(t===\"bg\"?Kt:Zt,r),e.value=\"\",A(),s(\"✔ 已新增分类\",\"ok\")}function Hn(t,e){for(var n=t===\"bg\"?$:Q,r=`移动到哪个分类？\n\n`,a=0;a<n.length;a++)r+=a+1+\". \"+n[a]+`\n`;r+=`\n输入序号或分类名：`;var o=prompt(r,\"\");if(!(o===null||!String(o).trim())){var d=String(o).trim(),f=\/^\\d+$\/.test(d)?n[parseInt(d)-1]:d;if(!f||n.indexOf(f)<0){s(\"✘ 分类无效\",\"no\");return}Wn(t,e,f)}}function Wn(t,e,n){for(var r=t===\"bg\"?Z:J,a=!1,o=0;o<r.length;o++)r[o].u===e&&(r[o].c=n,a=!0);a||r.push({u:e,c:n}),g(t===\"bg\"?St:At,r),A(),s(\"✔ 已移动到「\"+n+\"」\",\"ok\")}function ei(t,e){var n=t===\"bg\"?Z:J,r=t===\"bg\"?W:_,a=n[e];a&&(n.splice(e,1),t===\"bg\"?(g(St,n),W===a.u&&(W=\"\",M(wt,\"\"),ot())):(g(At,n),_===a.u&&(_=\"\",M(bt,\"\"),D(),Y(X,T))),A(),s(\"✔ 已删除\",\"ok\"))}function de(t,e){var n=new Image;n.referrerPolicy=\"no-referrer\",n.onload=function(){e(!0)},n.onerror=function(){e(!1)},n.src=t}function Xe(t){return t=String(t||\"\").trim(),t?\/^(file:|https?:)\/i.test(t)?t:\"file:\/\/\"+(t.charAt(0)===\"\/\"?t:\"\/\"+t):\"\"}function ni(t){be(),_=t,M(bt,t),D(),Y(X,T),A(),s(\"✔ 已切换头像外框\",\"ok\")}function ri(t){W=t,M(wt,t),ot(),A(),s(\"✔ 已切换背景\",\"ok\")}function ii(t){xt=t,M(Be,t),Y(X,T),A(),s(t===\"over\"?\"✔ 外框浮于头像上方\":\"✔ 外框衬于头像下方\",\"ok\")}function ai(){W=\"\",M(wt,\"\"),ot(),A(),s(\"✔ 已清除背景\",\"ok\")}function oi(){be(),_=\"\",M(bt,\"\"),D(),Y(X,T),A(),s(\"✔ 已清除头像外框\",\"ok\")}function ci(){var t=document.getElementById(\"fi\").value.trim();if(!t){s(\"✘ 请输入外框图片地址\",\"no\");return}var e=Xe(t),n=document.getElementById(\"fcat\")?document.getElementById(\"fcat\").value:\"默认\";s(\"验证中…\",\"wait\"),de(e,function(r){if(!r){s(\"✘ 图片无法加载（防盗链\/地址错误\/本地文件被拦截）\",\"no\");return}for(var a=null,o=0;o<J.length;o++)J[o].u===e&&(a=J[o]);a?a.c=n:J.push({u:e,c:n}),g(At,J),be(),_=e,M(bt,e),D(),Y(X,T),document.getElementById(\"fi\").value=\"\",A(),s(\"✔ 已保存到「\"+n+\"」并应用\",\"ok\")})}function di(){var t=document.getElementById(\"bi\").value.trim();if(!t){s(\"✘ 请输入背景图片地址\",\"no\");return}var e=Xe(t),n=document.getElementById(\"bcat\")?document.getElementById(\"bcat\").value:\"默认\";s(\"验证中…\",\"wait\"),de(e,function(r){if(!r){s(\"✘ 图片无法加载（防盗链\/地址错误\/本地文件被拦截）\",\"no\");return}for(var a=null,o=0;o<Z.length;o++)Z[o].u===e&&(a=Z[o]);a?a.c=n:Z.push({u:e,c:n}),g(St,Z),W=e,M(wt,e),ot(),document.getElementById(\"bi\").value=\"\",A(),s(\"✔ 已保存到「\"+n+\"」并应用\",\"ok\")})}function _e(t,e){i[t]=e,g(N,i),D();if(t==='aiOn'){try{window.aiEcho&&window.aiEcho()}catch(q){}}}function fi(t,e){i.btnL[t]=e,g(N,i),V.innerHTML=Rt(F),It(),Bt(),Pt()}function si(t,e,n){var r=`<div class=\"sec\"><div class=\"sech\" onclick=\"tog('`+t+`')\"><b>`+e+'<\/b><span id=\"'+t+'a\">'+(n?\"▾\":\"▸\")+'<\/span><\/div><div class=\"secb\" id=\"'+t+'\" style=\"display:'+(n?\"block\":\"none\")+'\">';return r}function ui(){return\"<\/div><\/div>\"}function li(t,e,n,r,a,o){return'<div class=\"srow\"'+(o?' id=\"'+o+'\"':\"\")+\"><label>\"+t+'<\/label><input type=\"range\" id=\"'+e+'\" min=\"'+n+'\" max=\"'+r+'\" step=\"'+a+`\" oninput=\"upd('`+e.slice(1)+\"',parseFloat(this.value));sv('\"+e+`',this.value)\"><span class=\"sval\" id=\"`+e+'v\"><\/span><\/div>'}function pi(t,e){var n=document.getElementById(t+\"v\");n&&(n.textContent=e)}function ze(){return 120}function Ye(){return 80}function Ge(t,e){return t=parseFloat(t)||0,t>e&&(t=e),t<-e&&(t=-e),Math.round(t)}function qn(){var t=[\"un\",\"tm\",\"fl\",\"vw\",\"rp\"],e=0,n;for(n=0;n<t.length;n++){var r=t[n],a=Ge(i[r+\"X\"],ze()),o=Ge(i[r+\"Y\"],Ye());(a!==i[r+\"X\"]||o!==i[r+\"Y\"])&&(i[r+\"X\"]=a,i[r+\"Y\"]=o,e=1)}e&&g(N,i)}function yi(t,e){var n=\"s\"+e+\"X\",r=\"s\"+e+\"Y\",a=ze(),o=Ye();return'<div class=\"xyg\"><div class=\"xyh\"><b>'+t+'<\/b><span class=\"sxy\" id=\"'+e+'v\"><\/span><\/div><div class=\"srow xr\"><label>横<\/label><input type=\"range\" id=\"'+n+'\" min=\"-'+a+'\" max=\"'+a+`\" step=\"1\" oninput=\"upd('`+e+\"X',parseFloat(this.value));sv('\"+n+\"',this.value);svx('\"+e+`')\"><span class=\"sval\" id=\"`+n+'v\"><\/span><\/div><div class=\"srow xr\"><label>纵<\/label><input type=\"range\" id=\"'+r+'\" min=\"-'+o+'\" max=\"'+o+`\" step=\"1\" oninput=\"upd('`+e+\"Y',parseFloat(this.value));sv('\"+r+\"',this.value);svx('\"+e+`')\"><span class=\"sval\" id=\"`+r+'v\"><\/span><\/div><\/div>;'}function Un(t){var e=document.getElementById(t+\"v\");e&&(e.textContent=\"(\"+i[t+\"X\"]+\",\"+i[t+\"Y\"]+\")\")}function mi(){i.unX=0,i.unY=0,i.tmX=0,i.tmY=0,i.flX=0,i.flY=0,i.vwX=0,i.vwY=0,i.rpX=0,i.rpY=0,g(N,i),D(),dt(),s(\"✔ 已复位到 (0,0)\")}function vi(t,e){var n=e.slice(1);return'<div class=\"srow\"><label>'+t+'<\/label><button class=\"cpk\" id=\"'+e+`\" onclick=\"openPicker('`+n+`')\"><i class=\"csw\" id=\"`+e+'s\"><\/i><span class=\"chex\" id=\"'+e+'v\"><\/span><\/button><\/div>'}function He(t,e){var n=document.getElementById(t+\"s\");n&&(n.style.background=e||\"#FFFFFF\");var r=document.getElementById(t+\"v\");r&&(r.textContent=String(e||\"\").toUpperCase())}function jn(t){t=String(t||\"\").replace(\"#\",\"\"),t.length===3&&(t=t.split(\"\").map(function(n){return n+n}).join(\"\"));var e=parseInt(t,16);return isNaN(e)?{r:255,g:255,b:255}:{r:e>>16&255,g:e>>8&255,b:e&255}}function hi(t,e,n){function r(a){return a=Math.round(Math.min(255,Math.max(0,a))).toString(16),a.length<2?\"0\"+a:a}return\"#\"+r(t)+r(e)+r(n)}function Vn(t,e,n){t\/=255,e\/=255,n\/=255;var r=Math.max(t,e,n),a=Math.min(t,e,n),o=r-a,d=0;return o&&(r===t?d=(e-n)\/o+(e<n?6:0):r===e?d=(n-t)\/o+2:d=(t-e)\/o+4,d*=60),{h:d,s:r?o\/r:0,v:r}}function gi(t,e,n){t=(t%360+360)%360;var r=n*e,a=r*(1-Math.abs(t\/60%2-1)),o=n-r,d=0,f=0,l=0;return t<60?(d=r,f=a):t<120?(d=a,f=r):t<180?(f=r,l=a):t<240?(f=a,l=r):t<300?(d=a,l=r):(d=r,l=a),{r:(d+o)*255,g:(f+o)*255,b:(l+o)*255}}var ct={key:\"\",h:0,s:0,v:1,hex:\"#FFFFFF\"};function wi(t){var e=document.getElementById(t);return e?e.value:\"\"}function bi(t,e){var n=document.getElementById(t);n&&String(n.value)!==String(e)&&(n.value=e)}function xi(t){ct.key=t;var e=jn(i[t]),n=Vn(e.r,e.g,e.b);ct.h=n.h,ct.s=n.s,ct.v=n.v;var r=document.getElementById(\"cpOld\");r&&(r.style.background=i[t]||\"#FFFFFF\"),cpSync(),document.getElementById(\"cp\").className=\"modal on\"}function Kn(){document.getElementById(\"cp\").className=\"modal\"}function Bi(){if(ct.key){_e(ct.key,ct.hex);var t=\"s\"+ct.key;He(t,ct.hex),Kn()}}function Fi(t,e,n){return'<div class=\"srow\"><label>'+t+'<\/label><input type=\"text\" id=\"'+e+'\" placeholder=\"'+n+'\" oninput=\"'+(e.charAt(1)===\"b\"&&\/^sbtnL\/.test(e)?\"updB('\"+e.slice(6)+\"',this.value)\":\"upd('\"+e.slice(1)+\"',this.value)\")+'\"><\/div>'}function Ii(t,e,n,r){for(var a=\"\",o=0;o<n.length;o++)a+='<option value=\"'+n[o][0]+'\">'+n[o][1]+\"<\/option>\";return'<div class=\"srow\"><label>'+t+'<\/label><select id=\"'+e+'\" onchange=\"'+r+'\">'+a+\"<\/select><\/div>\"}function Zn(){for(var t=i.frFit===\"manual\",e=[\"wfrZoom\",\"wfrBX\",\"wfrBY\"],n=0;n<e.length;n++){var r=document.getElementById(e[n]);r&&(r.style.display=t?\"\":\"none\")}}var fe={};function Ei(t){fe[t]=!fe[t];var e=document.getElementById(t),n=document.getElementById(t+\"a\");e&&(e.style.display=fe[t]?\"block\":\"none\"),n&&(n.textContent=fe[t]?\"▾\":\"▸\")}function We(t){for(var e=\"\",n=0;n<t.length;n++)e+='<option value=\"'+k(t[n])+'\">'+k(t[n])+\"<\/option>\";return e}function A(){var t=document.getElementById(\"pbg\");t&&(t.innerHTML=Ne(\"bg\"));var e=document.getElementById(\"pfr\");e&&(e.innerHTML=Ne(\"frame\"));var n=document.getElementById(\"m1\");n&&(n.className=\"msw\"+(xt===\"under\"?\" on\":\"\"));var r=document.getElementById(\"m2\");r&&(r.className=\"msw\"+(xt===\"over\"?\" on\":\"\"));var a=document.getElementById(\"bcat\");a&&(a.innerHTML=We($));var o=document.getElementById(\"fcat\");o&&(o.innerHTML=We(Q));var d=document.getElementById(\"fabiList\");d&&(d.innerHTML=fr());var f=document.getElementById(\"sh1\");f&&(f.className=\"msw\"+(i.fabShape?\" on\":\"\"));var l=document.getElementById(\"sh0\");l&&(l.className=\"msw\"+(i.fabShape?\"\":\" on\"));var p=document.getElementById(\"fmk1\");p&&(p.className=\"msw\"+(i.frMask>=50?\" on\":\"\"));var h=document.getElementById(\"fmk0\");h&&(h.className=\"msw\"+(i.frMask<=0?\" on\":\"\"));var w=document.getElementById(\"amk1\");w&&(w.className=\"msw\"+(i.avMask>=50?\" on\":\"\"));var b=document.getElementById(\"amk0\");b&&(b.className=\"msw\"+(i.avMask<=0?\" on\":\"\"));var x=document.getElementById(\"oi0\");x&&(x.className=\"msw\"+(i.opnIt?\"\":\" on\"));var I=document.getElementById(\"oi1\");I&&(I.className=\"msw\"+(i.opnIt?\" on\":\"\"));var m=document.getElementById(\"ri0\");m&&(m.className=\"msw\"+(i.rnIt?\"\":\" on\"));var v=document.getElementById(\"ri1\");v&&(v.className=\"msw\"+(i.rnIt?\" on\":\"\"));var C=document.getElementById(\"or0\");C&&(C.className=\"msw\"+(i.opnRb?\"\":\" on\"));var y=document.getElementById(\"or1\");y&&(y.className=\"msw\"+(i.opnRb?\" on\":\"\"));var B=document.getElementById(\"rr0\");B&&(B.className=\"msw\"+(i.rnRb?\"\":\" on\"));var R=document.getElementById(\"rr1\");R&&(R.className=\"msw\"+(i.rnRb?\" on\":\"\"));var L=document.getElementById(\"fabPrevEmo\");L&&(L.textContent=i.fabEmo||\"\");var O=document.getElementById(\"profList\");O&&(O.innerHTML=nr());var H=document.getElementById(\"profBtn\");H&&(H.textContent=gt>=0?\"✏️ 重命名\":\"💾 保存方案\");try{aiEcho()}catch(et){}}function Jn(){fe={};for(var t=document.querySelectorAll(\".secb\"),e=0;e<t.length;e++)t[e].style.display=\"none\";for(var n=document.querySelectorAll(\".sech span\"),r=0;r<n.length;r++)n[r].textContent=\"▸\"}var Ci=\"xss8_cfg\";function se(){return{v:2,ST:i,BG:W,BGD:Z,BGC:$,FRAME:_,FRD:J,FRC:Q,FM:xt,BGX:Tt,FRX:kt,FABI,ts:new Date().getTime()}}function Pi(){var t=se(),e=JSON.stringify(t),n=document.getElementById(\"ioTa\");n&&(n.value=e,setTimeout(function(){try{n.focus(),n.select()}catch(r){}},80)),document.getElementById(\"io\").className=\"modal on\",s(\"已生成配置文本，可长按全选复制\",\"ok\")}function Si(){var t=document.getElementById(\"ioTa\");if(t){var e=!1;try{t.removeAttribute(\"readonly\"),t.focus(),t.select(),t.setSelectionRange(0,999999),e=document.execCommand(\"copy\")}catch(n){}!e&&navigator.clipboard&&navigator.clipboard.writeText?navigator.clipboard.writeText(t.value).then(function(){s(\"✔ 已复制到剪贴板\",\"ok\")},function(){s(\"请长按文本手动复制\",\"no\")}):e&&s(\"✔ 已复制到剪贴板\",\"ok\")}}var Ut=null,Ia=null,Ai=0,Ti=0,qe=0;function $n(t){var e=String(t.getAttribute&&t.getAttribute(\"data-src\")||\"\");return e||(e=String(t.getAttribute&&t.getAttribute(\"src\")||\"\")),e?\/^(https?:|data:|file:|blob:)\/i.test(e)?e:it(e):\"\"}function Qn(t,e){var n=document.createElement(\"textarea\");n.value=t,n.setAttribute(\"readonly\",\"\"),n.style.position=\"fixed\",n.style.left=\"-9999px\",n.style.top=\"0\",n.style.opacity=\"0\",document.body.appendChild(n);var r=!1;try{n.focus(),n.select(),n.setSelectionRange(0,999999),r=document.execCommand(\"copy\")}catch(a){}try{document.body.removeChild(n)}catch(a){}if(r){s(e||\"✔ 已复制到剪贴板\",\"ok\");return}navigator.clipboard&&navigator.clipboard.writeText?navigator.clipboard.writeText(t).then(function(){s(e||\"✔ 已复制到剪贴板\",\"ok\")},function(){s(\"✘ 复制失败，请长按后手动记录\",\"no\")}):s(\"✘ 复制失败，请长按后手动记录\",\"no\")}function Ue(t){return t.touches&&t.touches[0]||t}function je(t){var e=t.target;if(!(!e||e.tagName!==\"IMG\")&&e.className!==\"pv\"){var n=Ue(t);Ia=e,Ai=n.clientX,Ti=n.clientY,qe=0,Ct(),Ut=setTimeout(function(){Ut=null,qe=1;var r=$n(e);r?Qn(r,\"✔ 图片链接已复制\"):s(\"✘ 该图片无有效链接\",\"no\")},550)}}function Ve(t){if(Ut){var e=Ue(t);(Math.abs(e.clientX-Ai)>10||Math.abs(e.clientY-Ti)>10)&&Ct()}}function Ct(){Ut&&(clearTimeout(Ut),Ut=null)}function tr(){var t=document;t.addEventListener(\"touchstart\",je,!0),t.addEventListener(\"touchmove\",Ve,!0),t.addEventListener(\"touchend\",Ct,!0),t.addEventListener(\"touchcancel\",Ct,!0),t.addEventListener(\"mousedown\",je,!0),t.addEventListener(\"mousemove\",Ve,!0),t.addEventListener(\"mouseup\",Ct,!0),t.addEventListener(\"mouseleave\",Ct,!0),t.addEventListener(\"click\",function(e){qe&&(qe=0,e.preventDefault&&e.preventDefault(),e.stopPropagation&&e.stopPropagation())},!0)}function er(){document.getElementById(\"io\").className=\"modal\"}function ki(){var t=document.getElementById(\"ioTa\");t&&(t.value=\"\"),document.getElementById(\"io\").className=\"modal on\",setTimeout(function(){try{t.focus()}catch(e){}},80)}function Ri(){try{M(Ci,JSON.stringify(se())),s(\"✔ 已存为本机备份\",\"ok\")}catch(t){s(\"✘ 保存失败\",\"no\")}}function Mi(){try{var t=yt(Ci);if(!t){s(\"✘ 无本机备份\",\"no\");return}ue(JSON.parse(t),\"本机备份\")}catch(e){s(\"✘ 备份损坏\",\"no\")}}function ue(t,e){if(!t||typeof t!=\"object\"){s(\"✘ 数据无效\",\"no\");return}if(t.ST&&typeof t.ST==\"object\"){i={};for(var n in st)t.ST[n]!==void 0?i[n]=t.ST[n]:i[n]=st[n];if(t.ST.btnL)for(var r in st.btnL)i.btnL[r]===void 0&&(i.btnL[r]=st.btnL[r])}typeof t.BG==\"string\"&&(W=t.BG,M(wt,W)),t.BGD&&t.BGD.length!==void 0&&(Z=t.BGD,g(St,Z)),t.BGC&&t.BGC.length!==void 0&&($=t.BGC,g(Kt,$)),typeof t.FRAME==\"string\"&&(_=t.FRAME,M(bt,_)),t.FRD&&t.FRD.length!==void 0&&(J=t.FRD,g(At,J)),t.FRC&&t.FRC.length!==void 0&&(Q=t.FRC,g(Zt,Q)),typeof t.FM==\"string\"&&(xt=t.FM,M(Be,xt)),t.FABI&&t.FABI.length!==void 0&&(FABI=t.FABI,le()),t.BGX&&typeof t.BGX==\"object\"&&(Tt=t.BGX,g(Jt,Tt)),t.FRX&&typeof t.FRX==\"object\"&&(kt=t.FRX,g($t,kt)),g(N,i),D(),ot(),Y(X,T),dt(),A(),s(\"✔ 已\"+(e||\"导入\")+\"配置\",\"ok\")}function Li(){var t=document.getElementById(\"ioTa\");if(!t||!t.value.trim()){s(\"✘ 请先粘贴配置文本\",\"no\");return}var e;try{e=JSON.parse(t.value.trim())}catch(n){s(\"✘ 解析失败：不是有效的配置文本\",\"no\");return}ue(e,\"导入\"),er()}function Di(){if(confirm(`确定恢复全部出厂设置？\n所有自定义颜色\/间距\/背景\/头像框将被清空。`)){try{M(wt,\"\"),M(bt,\"\"),M(Be,\"\"),M(St,\"\"),M(Kt,\"\"),M(At,\"\"),M(Zt,\"\"),M(Jt,\"\"),M($t,\"\"),M(or,\"\")}catch(t){}W=\"\",_=\"\",xt=\"under\",Z=[],$=[\"默认\"],J=[],Q=[\"默认\"],Tt={},kt={},FABI=[],rr()}}function Ni(){i.postBg=\"#1E1F26\",i.postTx=\"#E8E9F0\",i.replyBg=\"#25262E\",i.replyTx=\"#E8E9F0\",i.postBdC=\"#3A3B46\",i.replyBdC=\"#3A3B46\",i.btnBg=\"#2E2F38\",i.btnTx=\"#E8E9F0\",i.btnBdC=\"#3A3B46\",i.qBg=\"#2E2F38\",i.qBdC=\"#3A3B46\",i.mBg=\"#1E1F26\",i.mTx=\"#E8E9F0\",i.dBg=\"#1E1F26\",i.dBdC=\"#3A3B46\",i.catBg=\"#2E2F38\",i.sechBg=\"#2E2F38\",i.pgBg=\"#2E2F38\",i.pgTx=\"#E8E9F0\",i.pgBdC=\"#3A3B46\",i.hdTx=\"#F2F3F8\",i.lbTx=\"#E4E5EE\",i.ttTx=\"#F2F3F8\",i.metaTx=\"#B4B5C2\",i.qTx=\"#DCDDE8\",i.hintTx=\"#B4B5C2\",i.cmtBg=\"#2E2F38\",i.cmtBdC=\"#3A3B46\",i.cmtTx=\"#DCDDE8\",i.cmtCTx=\"#E8E9F0\",i.cmtNTx=\"#B9A6FF\",i.cmtTTx=\"#B4B5C2\",g(N,i),D(),dt(),Y(X,T),s(\"✔ 已应用深色配色预设\",\"ok\")}function Oi(){i=JSON.parse(JSON.stringify(st)),g(N,i),D(),ot(),dt(),Y(X,T),s(\"✔ 已恢复浅色默认\",\"ok\")}var Ke=\"xss8_profiles\",q=[];try{q=at(Ke,[])}catch(t){}var gt=-1;function nr(){for(var t=\"\",e=0;e<q.length;e++){var n=q[e]||{};t+='<div class=\"profrow\"><button class=\"bt\" onclick=\"applyProfile('+e+')\">🎨 '+k(n.n||\"方案\"+(e+1))+'<\/button><button class=\"ib\" title=\"重命名\" onclick=\"renProfile('+e+')\">✏️<\/button><button class=\"ib\" title=\"删除\" onclick=\"delProfile('+e+')\">🗑<\/button><\/div>'}return t||(t='<div class=\"hint\">还没有保存过方案，输入名称后点「保存方案」。<\/div>'),t}function Xi(){var t=document.getElementById(\"profName\"),e=t?(t.value||\"\").trim():\"\";if(!e){s(\"✘ 请先输入方案名称\",\"no\");return}if(gt>=0){var n=q[gt];n&&(n.n=e,g(Ke,q),gt=-1,t&&(t.value=\"\"),s(\"✔ 已重命名\",\"ok\"))}else{for(var r=-1,a=0;a<q.length;a++)if(q[a].n===e){r=a;break}var o={n:e,s:se()};r>=0?q[r]=o:q.push(o),g(Ke,q),s(\"✔ 已保存方案「\"+e+\"」\",\"ok\")}A()}function _i(t){var e=q[t];e&&ue(e.s,\"方案「\"+(e.n||\"\")+\"」\")}function zi(){if(!(gt<0)){gt=-1;var t=document.getElementById(\"profName\");t&&(t.value=\"\"),A()}}function Yi(t){var e=q[t];if(e){gt=t;var n=document.getElementById(\"profName\");n&&(n.value=e.n||\"\",n.focus(),n.select()),A(),s(\"修改名称后点击「重命名」\",\"ok\")}}function Gi(t){var e=q[t];e&&confirm(\"确定删除方案「\"+(e.n||\"\")+\"」？\")&&(q.splice(t,1),g(Ke,q),gt===t&&(gt=-1),A(),s(\"✔ 已删除方案\",\"ok\"))}function Hi(){var t=document.getElementById(\"bpb\");t&&!t.getAttribute(\"data-b\")&&(t.innerHTML=window.detailBuildPanel(),t.setAttribute(\"data-b\",\"1\")),Jn(),document.getElementById(\"bp\").className=\"modal on\",A(),dt()}function Wi(){document.getElementById(\"bp\").className=\"modal\"}function dt(){for(var t=[\"postA\",\"imgw\",\"imgh\",\"imgfx\",\"imgfy\",\"imgrd\",\"imggap\",\"gap\",\"fs\",\"lh\",\"fw\",\"ls\",\"rd\",\"postBdW\",\"postSh\",\"replyBdW\",\"replySh\",\"btnA\",\"btnBdW\",\"btnSh\",\"btnRd\",\"btnFs\",\"btnPad\",\"edA\",\"edBdW\",\"edRd\",\"edFs\",\"avScale\",\"avFx\",\"avFy\",\"frScale\",\"frFx\",\"frFy\",\"firstN\",\"qA\",\"qBdW\",\"qRd\",\"qFs\",\"qLh\",\"qPad\",\"qSh\",\"postTxSh\",\"replyTxSh\",\"hintFs\",\"hintLs\",\"hintLh\",\"hintSh\",\"mA\",\"dA\",\"dBdW\",\"dRd\",\"rpt\",\"rpr\",\"rpb\",\"rpl\",\"hdgap\",\"qgapt\",\"qgapb\",\"msggapt\",\"ttgap\",\"catA\",\"sechA\",\"ttFs\",\"ttFw\",\"ttLh\",\"ttLs\",\"fabBdW\",\"fabSh\",\"fabRd\",\"fabSz\",\"fabX\",\"fabY\",\"fabScale\",\"fabBX\",\"fabBY\",\"frMask\",\"avMask\",\"frZoom\",\"frBX\",\"frBY\",\"opnFs\",\"opnFw\",\"opnSh\",\"opnRbD\",\"rnFs\",\"rnFw\",\"rnSh\",\"rnRbD\",\"pgA\",\"pgBdW\",\"pgRd\",\"pgFs\",\"cmtA\",\"cmtBdW\",\"cmtRd\",\"cmtPad\",\"cmtGap\",\"cmtSh\",\"cmtFs\",\"cmtLh\",\"cmtCFs\",\"cmtCLh\",\"unX\",\"unY\",\"tmX\",\"tmY\",\"flX\",\"flY\",\"vwX\",\"vwY\",\"rpX\",\"rpY\"],e=0;e<t.length;e++){var n=t[e],r=\"s\"+n,a=document.getElementById(r);a&&(a.value=i[n]);var o=document.getElementById(r+\"v\");o&&(o.textContent=i[n])}for(var d=[\"un\",\"tm\",\"fl\",\"vw\",\"rp\"],f=0;f<d.length;f++)Un(d[f]);for(var l=[\"postBg\",\"postTx\",\"replyBg\",\"replyTx\",\"metaTx\",\"postBdC\",\"postShC\",\"replyBdC\",\"replyShC\",\"btnBg\",\"btnTx\",\"btnBdC\",\"btnShC\",\"edBg\",\"edTx\",\"edBdC\",\"qBg\",\"qTx\",\"qBdC\",\"mBg\",\"mTx\",\"dBg\",\"dBdC\",\"catBg\",\"sechBg\",\"lbTx\",\"hdTx\",\"fabBdC\",\"fabShC\",\"fabBg\",\"opnTx\",\"opnShC\",\"rnTx\",\"rnShC\",\"qShC\",\"postTxShC\",\"replyTxShC\",\"hintTx\",\"hintShC\",\"ttTx\",\"pgBg\",\"pgTx\",\"pgBdC\",\"pgOnBg\",\"pgOnTx\",\"cmtBg\",\"cmtTx\",\"cmtBdC\",\"cmtShC\",\"cmtNTx\",\"cmtTTx\",\"cmtCTx\"],f=0;f<l.length;f++){var p=l[f],h=\"s\"+p;He(h,i[p])}for(var w=[[\"sbgFitO\",\"bgFit\"],[\"simgfitO\",\"imgfit\"]],b=0;b<w.length;b++){var x=document.getElementById(w[b][0]);x&&(x.value=i[w[b][1]])}var I=document.getElementById(\"sfabEmo\");I&&(I.value=i.fabEmo);for(var m=[\"opnRbC\",\"rnRbC\"],v=0;v<m.length;v++){var C=document.getElementById(\"s\"+m[v]);C&&(C.value=i[m[v]])}var y=document.getElementById(\"sfabFitO\");y&&(y.value=i.fabFit);var B=document.getElementById(\"sfrFitO\");B&&(B.value=i.frFit);try{Zn()}catch(H){}for(var R=[\"fav\",\"cmt\",\"rep\",\"ord\",\"asc\",\"op\",\"all\",\"rl\",\"send\"],L=0;L<R.length;L++){var O=document.getElementById(\"sbtnL\"+R[L]);O&&(O.value=i.btnL[R[L]])}}function rr(){i=JSON.parse(JSON.stringify(st)),g(N,i);try{g(_n,[]),g(zn,[])}catch(t){}D(),ot(),Y(X,T),dt(),A(),s(\"✔ 已恢复默认样式\",\"ok\")}var ir={},Ea=\/(?:https?:\\\/\\\/[^\"'\\s<>]*)?data\\\/attachment\\\/[^\"'\\s<>]*?\\.(?:jpe?g|png|gif|webp|bmp)\/i,Ca=\/<img[^>]+src=[\"']([^\"']+\\.(?:jpe?g|png|gif|webp|bmp))[\"']\/i;function ar(t){var e=String(t||\"\"),n=e.match(Ea);if(n)return\/^https?:\/i.test(n[0])?n[0]:it(n[0].replace(\/^\\\/+\/,\"\"));var r=e.match(Ca);return r?it(r[1]):\"\"}function Ze(t){if(t){var e=t.getAttribute(\"data-src\")||t.getAttribute(\"src\")||\"\";if(!e){s(\"✘ 该图片无地址\",\"no\");return}if(Lr.test(e)||\/^data:\/i.test(e)){ce(e);return}if(ir[e]){ce(ir[e]);return}s(\"读取原图…\"),Dt(e).then(function(n){var r=ar(n);r?(ir[e]=r,ce(r)):s(\"✘ 未能取得原图地址\",\"no\")},function(){s(\"✘ 读取原图失败\",\"no\")})}}document.addEventListener(\"click\",function(t){var e=t.target;if(e&&e.tagName===\"IMG\"&&String(e.className||\"\").indexOf(\"zoom\")>=0){t.stopPropagation&&t.stopPropagation(),t.preventDefault&&t.preventDefault(),Ze(e);return}var n=e&&e.closest?e.closest(\"a\"):null;if(n){var r=n.querySelector(\"img\");if(r){var a=String(r.className||\"\");if(a.indexOf(\"atico\")<0&&a.indexOf(\"avi\")<0&&!Ft(r)){t.preventDefault&&t.preventDefault(),Ze(r);return}}var o=n.getAttribute(\"href\")||\"\";if(!(!o||\/^javascript\/i.test(o)||o.charAt(0)===\"#\")){var d=o.indexOf(\"bbs.xiaoxiaoshuo8.com\")>-1||!\/^[a-z]+:\/i.test(o);d&&\/mod=(viewthread|forumdisplay)\/.test(o)&&(t.preventDefault&&t.preventDefault(),ht(o))}}},!1);var or=\"xss8_fabi\";try{var qi=yt(or);FABI=qi?JSON.parse(qi):[]}catch(t){FABI=[]}(!FABI||typeof FABI.length!=\"number\")&&(FABI=[]);for(var cr=[\"https:\/\/c-ssl.duitang.com\/uploads\/item\/201809\/17\/20180917212202_cobee.thumb.400_0.gif\"],Je=0;Je<cr.length;Je++)FABI.indexOf(cr[Je])<0&&FABI.push(cr[Je]);function le(){g(or,FABI)}function dr(t){return t=String(t||\"\").trim(),t?\/^(file:|https?:)\/i.test(t)?t:\"file:\/\/\"+(t.charAt(0)===\"\/\"?t:\"\/\"+t):\"\"}function Ui(t){i.fabBi=t,g(N,i),D(),A(),s(\"✔ 已应用按钮背景图\",\"ok\")}function ji(t){var e=FABI[t];e&&(FABI.splice(t,1),le(),i.fabBi===e.u&&(i.fabBi=\"\",g(N,i),D()),A(),s(\"✔ 已删除\",\"ok\"))}function Vi(){var t=document.getElementById(\"fabin\").value.trim();if(!t){s(\"✘ 请输入图片网址\",\"no\");return}var e=dr(t);s(\"验证中…\",\"wait\"),de(e,function(n){if(!n){s(\"✘ 图片无法加载（防盗链\/地址错误\/本地文件被拦截）\",\"no\");return}FABI.indexOf(e)<0&&FABI.push(e),le(),i.fabBi=e,g(N,i),D(),document.getElementById(\"fabin\").value=\"\",A(),s(\"✔ 已保存并应用\",\"ok\")})}function Ki(){i.fabBi=\"\",g(N,i),D(),A(),s(\"✔ 已清除按钮背景图\",\"ok\")}function fr(){for(var t='<div class=\"pregrid\">',e=0;e<FABI.length;e++)t+='<div class=\"pw'+(i.fabBi===FABI[e]?\" sel\":\"\")+'\"><img class=\"pv\" referrerpolicy=\"no-referrer\" src=\"'+FABI[e]+`\" onclick=\"useFabBi('`+rt(FABI[e])+`')\"><button class=\"del\" onclick=\"delFabBi(`+e+')\">×<\/button><\/div>';return t+\"<\/div>\"}function $e(t,e){var n=String(t||\"\").split(\",\").map(function(d){return d.trim()}).filter(function(d){return d});n.length<2&&(n=[n[0]||\"#FF6B9D\",n[1]||n[0]||\"#7C6BD9\"]);for(var r=n.length,a=[],o=0;o<r;o++)a.push(n[o]+\" \"+Math.round(o\/(r-1)*100)+\"%\");return\"linear-gradient(\"+(e||90)+\"deg,\"+a.join(\",\")+\")\"}function Zi(t){i.opnIt=t?1:0,g(N,i),D(),Y(X,T),A(),s(t?\"✔ 帖子用户名：斜体\":\"✔ 帖子用户名：正常\",\"ok\")}function Ji(t){i.rnIt=t?1:0,g(N,i),D(),Y(X,T),A(),s(t?\"✔ 楼层用户名：斜体\":\"✔ 楼层用户名：正常\",\"ok\")}function $i(t){i.opnRb=t?1:0,g(N,i),D(),Y(X,T),A(),s(t?\"✔ 帖子用户名：彩虹渐变\":\"✔ 帖子用户名：纯色\",\"ok\")}function Qi(t){i.rnRb=t?1:0,g(N,i),D(),Y(X,T),A(),s(t?\"✔ 楼层用户名：彩虹渐变\":\"✔ 楼层用户名：纯色\",\"ok\")}function ta(t){i.frMask=t?50:0,g(N,i),D(),dt(),A(),s(t?\"✔ 外框遮罩：圆形\":\"✔ 外框遮罩：方形\",\"ok\")}function ea(t){i.avMask=t?50:0,g(N,i),D(),dt(),A(),s(t?\"✔ 头像遮罩：圆形\":\"✔ 头像遮罩：方形\",\"ok\")}function na(t){i.fabShape=t,i.fabRd=t?50:0,g(N,i),D(),dt(),A(),s(t?\"✔ 已切换为圆形\":\"✔ 已切换为方形\",\"ok\")}var G=null,ut=null,pe=0;function sr(){var t=document.querySelector(\".fab\");if(!t)return;try{t.style.webkitUserSelect=\"none\",t.style.webkitTouchCallout=\"none\",t.style.touchAction=\"none\",t.style.webkitUserDrag=\"none\",t.setAttribute(\"unselectable\",\"on\"),t.setAttribute(\"draggable\",\"false\")}catch(n){}function e(n){return n&&n.preventDefault&&n.preventDefault(),!1}t.addEventListener(\"contextmenu\",e,!1),t.addEventListener(\"selectstart\",e,!1),t.addEventListener(\"dragstart\",e,!1),t.addEventListener(\"touchstart\",function(n){try{var r=window.getSelection();r&&r.removeAllRanges&&r.removeAllRanges()}catch(o){}var a=n.touches[0];G={sx:a.clientX,sy:a.clientY,ox:i.fabX,oy:i.fabY,drag:0},ut=setTimeout(function(){if(G){G.drag=1,t.className=\"fab drag\";try{navigator.vibrate&&navigator.vibrate(30)}catch(o){}s(\"已进入拖动模式：拖到合适位置后松手\",\"ok\")}},600)},{passive:!1}),t.addEventListener(\"touchmove\",function(n){if(G){var r=n.touches[0],a=r.clientX-G.sx,o=r.clientY-G.sy;if(!G.drag&&(Math.abs(a)>12||Math.abs(o)>12)&&ut&&(clearTimeout(ut),ut=null),!!G.drag){n.preventDefault&&n.preventDefault(),n.stopPropagation&&n.stopPropagation();var d=window.innerWidth||360,f=window.innerHeight||640,l=i.fabSz||48;i.fabX=Math.round(Math.max(0,Math.min(d-l,G.ox-a))),i.fabY=Math.round(Math.max(0,Math.min(f-l,G.oy-o))),D()}}},{passive:!1}),t.addEventListener(\"touchend\",function(n){ut&&(clearTimeout(ut),ut=null),G&&G.drag&&(t.className=\"fab\",g(N,i),s(\"✔ 悬浮按钮位置已保存\",\"ok\"),pe=1,setTimeout(function(){pe=0},350)),G=null}),t.addEventListener(\"touchcancel\",function(){ut&&(clearTimeout(ut),ut=null),G&&G.drag&&(t.className=\"fab\",pe=1,setTimeout(function(){pe=0},350)),G=null}),t.addEventListener(\"click\",function(n){pe&&(n.preventDefault&&n.preventDefault(),n.stopPropagation&&n.stopPropagation())},!0)}function Qe(t){t&&(t.preventDefault&&t.preventDefault(),t.stopPropagation&&t.stopPropagation())}var ra=[\"dec-ic\",\"imp-ic\",\"jmp-ic\",\"pvx\",\"del\",\"cpk\",\"msw\",\"bt\",\"fab\",\"pgn\"];function ur(t){for(var e=0;t&&e<6;e++){for(var n=String(t.className||\"\").split(\" \"),r=0;r<n.length;r++)for(var a=0;a<ra.length;a++)if(n[r]===ra[a])return!0;t=t.parentNode}return!1}document.addEventListener(\"click\",function(t){ur(t.target)&&t.preventDefault&&t.preventDefault()},!0);function lr(t){if(!t||t.tagName!==\"IMG\"||Ft(t))return!1;var e=String(t.className||\"\");return!(e.indexOf(\"atico\")>=0||e.indexOf(\"avi\")>=0)}var E={im:null,src:\"\",tol:24,mode:0,cont:1,brush:28};function pr(){var t=document.body;if(t){if(!document.getElementById(\"dec\")){var e=document.createElement(\"div\");e.className=\"modal\",e.id=\"dec\",e.onclick=function(f){f&&f.target===this&&hr()},e.innerHTML=`<div class=\"mbox\"><h3>🎨 图片去底色<\/h3><div class=\"dec-hint\">三种用法：<b>取色<\/b>（点一下，清掉与该点相连的同色区域）、<b>框选<\/b>（拖一个框，框内全部清掉）、<b>涂抹<\/b>（按住划，划过的地方清掉）。<\/div><div class=\"dec-modes\"><button class=\"bt m on\" id=\"decM0\" type=\"button\" onclick=\"decMode(0)\">🎯 取色<\/button><button class=\"bt m\" id=\"decM1\" type=\"button\" onclick=\"decMode(1)\">▢ 框选<\/button><button class=\"bt m\" id=\"decM2\" type=\"button\" onclick=\"decMode(2)\">✎ 涂抹<\/button><\/div><div class=\"dec-prev\" id=\"decPrev\"><img id=\"decImg\" referrerpolicy=\"no-referrer\" draggable=\"false\" ondblclick=\"zReset('dec')\" onclick=\"decPick(event)\" alt=\"\"><canvas class=\"dec-ov\" id=\"decOv\"><\/canvas><\/div><div class=\"zbar\"><span>放大<\/span><input id=\"decZoom\" type=\"range\" min=\"10\" max=\"80\" value=\"10\" oninput=\"zSlider('dec',this)\"><b id=\"decZoomV\">1.0x<\/b><button type=\"button\" onclick=\"zReset('dec')\">复位<\/button><\/div><div class=\"dec-hint\">双指捏合或拖滑块可放大（1~8x），单指拖动移动画面，双击复位；放大后取色更精确。<\/div><div class=\"dec-tol\"><span>容差<\/span><input id=\"decTol\" type=\"range\" min=\"0\" max=\"128\" value=\"24\" oninput=\"decTol(this.value)\"><b id=\"decTolV\">24<\/b><\/div><div class=\"srow\"><label>只去连续的<\/label><span class=\"dec-sw\"><button class=\"msw\" id=\"decC0\" type=\"button\" onclick=\"decCont(0)\">关<\/button><button class=\"msw on\" id=\"decC1\" type=\"button\" onclick=\"decCont(1)\">开<\/button><\/span><\/div><div class=\"srow\"><label>笔刷<\/label><input type=\"range\" id=\"decBrush\" min=\"6\" max=\"120\" step=\"2\" value=\"28\" oninput=\"decBrush(this.value)\"><span class=\"sval\" id=\"decBrushV\">28<\/span><\/div><div class=\"dec-hint\">「只去连续的」只对<b>取色<\/b>生效：只清掉与落点<b>相连<\/b>的同色像素，画面里另一块同色但挨不着的地方会保留；关掉则全图同色一起清。框选 \/ 涂抹不受它影响。<\/div><div class=\"dec-btns\"><button class=\"bt warn\" id=\"decRest\" onclick=\"decRestore()\">↺ 还原<\/button><button class=\"bt pri\" onclick=\"decClose()\">完成<\/button><\/div><\/div>`,t.appendChild(e)}for(var n=document.querySelectorAll(\".msg img\"),r=0;r<n.length;r++){var a=n[r];if(lr(a)&&!(a.parentNode&&a.parentNode.className===\"decbox\")){var o=document.createElement(\"span\");o.className=\"decbox\",a.parentNode.insertBefore(o,a),o.appendChild(a);var d=document.createElement(\"span\");d.className=\"dec-ic\",d.textContent=\"🎨\",d._im=a,d.onclick=function(f){Qe(f),vr(this._im)},o.appendChild(d)}}}}function yr(t){E.mode=t|0;for(var e=0;e<3;e++){var n=document.getElementById(\"decM\"+e);n&&(n.className=\"bt m\"+(e===E.mode?\" on\":\"\"))}var r=document.getElementById(\"decOv\");r&&(r.style.pointerEvents=E.mode?\"auto\":\"none\"),s(E.mode===0?\"🎯 取色：点图片上要变透明的地方\":E.mode===1?\"▢ 框选：在图上拖一个框\":\"✎ 涂抹：按住划过要清掉的地方\")}function mr(t){E.cont=t?1:0;var e=document.getElementById(\"decC0\"),n=document.getElementById(\"decC1\");e&&(e.className=\"msw\"+(E.cont?\"\":\" on\")),n&&(n.className=\"msw\"+(E.cont?\" on\":\"\"))}function ia(t){E.brush=+t||28;var e=document.getElementById(\"decBrushV\");e&&(e.textContent=E.brush)}function vr(t){if(t){if(E.im=t,E.src=String(t.getAttribute(\"data-src\")||t.getAttribute(\"src\")||\"\"),!E.src){s(\"✘ 该图片无地址\",\"no\");return}var e=document.getElementById(\"decImg\");e.setAttribute(\"data-src\",E.src),e.onload=function(){zMeasure(\"dec\"),zApply(\"dec\")},e.src=E.src,zOpen(\"dec\");var n=document.getElementById(\"decTol\");n&&(n.value=E.tol);var r=document.getElementById(\"decTolV\");r&&(r.textContent=E.tol);var a=document.getElementById(\"decRest\");a&&(a.style.display=\"none\");var o=document.getElementById(\"decBrush\");o&&(o.value=E.brush);var d=document.getElementById(\"decBrushV\");d&&(d.textContent=E.brush),mr(E.cont),xr(),yr(E.mode);var f=document.getElementById(\"dec\");f.className=\"modal on\"}}function hr(){var t=document.getElementById(\"dec\");t&&(t.className=\"modal\")}function aa(t){E.tol=+t||0;var e=document.getElementById(\"decTolV\");e&&(e.textContent=E.tol)}function ye(t){var e=t.naturalWidth,n=t.naturalHeight,r=1600,a=1;Math.max(e,n)>r&&(a=r\/Math.max(e,n),e=Math.round(e*a),n=Math.round(n*a));var o=document.createElement(\"canvas\");o.width=e,o.height=n;var d=o.getContext(\"2d\");return d.drawImage(t,0,0,e,n),{cv:o,cx:d,W:e,H:n,dd:d.getImageData(0,0,e,n)}}function me(t){var e=\"\";try{e=t.toDataURL(\"image\/png\")}catch(o){s(\"✘ 跨域图片无法读取像素\",\"no\");return}if(!e||e.length<32){s(\"✘ 生成失败\",\"no\");return}var n=document.getElementById(\"decImg\");n&&(n.src=e);var r=document.getElementById(\"decRest\");r&&(r.style.display=\"inline-block\");var a=E.im;a&&(a.src=e,a.setAttribute(\"data-decbase\",E.src))}function gr(t,e,n,r,a,o,d,f,l){var p=new Uint8Array(e*n),h=new Int32Array(e*n),w=0,b=0,x=a*e+r;for(h[w++]=x,p[x]=1;w>0;){var I=h[--w],m=I*4;if(!(Math.abs(t[m]-o)>l||Math.abs(t[m+1]-d)>l||Math.abs(t[m+2]-f)>l)&&t[m+3]!==0){t[m+3]=0,b++;var v=I%e,C=I\/e|0,y;v>0&&(y=I-1,p[y]||(p[y]=1,h[w++]=y)),v<e-1&&(y=I+1,p[y]||(p[y]=1,h[w++]=y)),C>0&&(y=I-e,p[y]||(p[y]=1,h[w++]=y)),C<n-1&&(y=I+e,p[y]||(p[y]=1,h[w++]=y))}}return b}function oa(t){if(E.mode===0&&!zGet(\"dec\").moved){var e=document.getElementById(\"decImg\");if(!(!e||!e.naturalWidth)){var n;try{n=ye(e)}catch(v){s(\"✘ 跨域图片无法读取像素\",\"no\");return}var r=n.dd.data,a=n.W,o=n.H,d=e.getBoundingClientRect();if(!(!d.width||!d.height)){var f=Math.round((t.clientX-d.left)*a\/d.width),l=Math.round((t.clientY-d.top)*o\/d.height);f<0&&(f=0),l<0&&(l=0),f>=a&&(f=a-1),l>=o&&(l=o-1);var p=(l*a+f)*4,h=r[p],w=r[p+1],b=r[p+2],x=E.tol||0,I=0,m;if(E.cont)I=gr(r,a,o,f,l,h,w,b,x);else for(m=0;m<r.length;m+=4)Math.abs(r[m]-h)<=x&&Math.abs(r[m+1]-w)<=x&&Math.abs(r[m+2]-b)<=x&&(r[m+3]=0);n.cx.putImageData(n.dd,0,0),me(n.cv),s(E.cont?\"✔ 已清除相连区域 \"+I+\" px\":\"✔ 已清除全部同色像素\",\"ok\")}}}}function jt(){return document.getElementById(\"decOv\")}function Vt(){var t=jt();if(!t)return null;var e=document.getElementById(\"decPrev\");if(!e)return null;var n=e.clientWidth,r=e.clientHeight;return!n||!r?null:((t.width!==n||t.height!==r)&&(t.width=n,t.height=r),t)}function ve(t,e){var n=document.getElementById(\"decImg\");if(!n||!n.naturalWidth)return null;var r=document.getElementById(\"decPrev\");if(!r)return null;var a=n.getBoundingClientRect(),o=r.getBoundingClientRect();if(!a.width||!a.height)return null;var d=Math.round((o.left+t-a.left)*n.naturalWidth\/a.width),f=Math.round((o.top+e-a.top)*n.naturalHeight\/a.height);return d<0&&(d=0),f<0&&(f=0),d>=n.naturalWidth&&(d=n.naturalWidth-1),f>=n.naturalHeight&&(f=n.naturalHeight-1),{x:d,y:f}}var U=null,he=null;function tn(){var t=Vt();if(!(!t||!U)){var e=t.getContext(\"2d\");e.clearRect(0,0,t.width,t.height),e.strokeStyle=\"#FF6B9D\",e.lineWidth=2,e.setLineDash&&e.setLineDash([6,4]),e.strokeRect(Math.min(U.x0,U.x1),Math.min(U.y0,U.y1),Math.abs(U.x1-U.x0),Math.abs(U.y1-U.y0))}}function wr(){var t=U;U=null;var e=jt();if(e){var n=e.getContext(\"2d\");n.clearRect(0,0,e.width,e.height)}if(t){var r=ve(Math.min(t.x0,t.x1),Math.min(t.y0,t.y1)),a=ve(Math.max(t.x0,t.x1),Math.max(t.y0,t.y1));if(!(!r||!a)&&!(Math.abs(a.x-r.x)<3&&Math.abs(a.y-r.y)<3)){var o=document.getElementById(\"decImg\");if(!(!o||!o.naturalWidth)){var d;try{d=ye(o)}catch(R){s(\"✘ 跨域图片无法读取像素\",\"no\");return}var f=d.dd.data,l=d.W,p=d.H,h=l\/o.naturalWidth,w=p\/o.naturalHeight,b=Math.round(r.x*h),x=Math.round(a.x*h),I=Math.round(r.y*w),m=Math.round(a.y*w);b<0&&(b=0),I<0&&(I=0),x>=l&&(x=l-1),m>=p&&(m=p-1);var v=0,C,y;for(y=I;y<=m;y++)for(C=b;C<=x;C++){var B=(y*l+C)*4;f[B+3]!==0&&(f[B+3]=0,v++)}d.cx.putImageData(d.dd,0,0),me(d.cv),s(\"✔ 已清除框内 \"+v+\" px\",\"ok\")}}}}function en(t,e){if(he){var n=ve(t,e);n&&he.push(n);var r=Vt();if(r){var a=document.getElementById(\"decImg\");if(!(!a||!a.naturalWidth)){var o=a.getBoundingClientRect(),d=Math.max(3,Math.round(E.brush*o.width\/a.naturalWidth)),f=r.getContext(\"2d\");f.fillStyle=\"rgba(255,107,157,.45)\",f.beginPath(),f.arc(t,e,d,0,6.2832),f.fill()}}}}function br(){var t=he;he=null;var e=jt();if(e){var n=e.getContext(\"2d\");n.clearRect(0,0,e.width,e.height)}if(!(!t||!t.length)){var r=document.getElementById(\"decImg\");if(!(!r||!r.naturalWidth)){var a;try{a=ye(r)}catch(lt){s(\"✘ 跨域图片无法读取像素\",\"no\");return}var o=a.dd.data,d=a.W,f=a.H,l=d\/r.naturalWidth,p=f\/r.naturalHeight,h=Math.max(2,Math.round(E.brush*l)),w=h*h,b=0,x,I,m;for(x=0;x<t.length;x++){var v=Math.round(t[x].x*l),C=Math.round(t[x].y*p),y=C-h,B=C+h,R=v-h,L=v+h;for(y<0&&(y=0),R<0&&(R=0),B>=f&&(B=f-1),L>=d&&(L=d-1),m=y;m<=B;m++){var O=m-C;for(I=R;I<=L;I++){var H=I-v;if(!(H*H+O*O>w)){var et=(m*d+I)*4;o[et+3]!==0&&(o[et+3]=0,b++)}}}}a.cx.putImageData(a.dd,0,0),me(a.cv),s(\"✔ 已涂抹清除 \"+b+\" px\",\"ok\")}}}function xr(){var t=jt();if(!t||t._init)return;t._init=1;function e(d){var f=d.touches&&d.touches[0]||d,l=t.getBoundingClientRect();return{x:f.clientX-l.left,y:f.clientY-l.top}}function n(d){return!!(d.touches&&d.touches.length>1)}function r(d){if(!(!E.mode||n(d))){d.preventDefault&&d.preventDefault();var f=e(d);E.mode===1?(Vt(),U={x0:f.x,y0:f.y,x1:f.x,y1:f.y},tn()):(Vt(),he=[],en(f.x,f.y))}}function a(d){if(!(!E.mode||n(d))){d.preventDefault&&d.preventDefault();var f=e(d);if(E.mode===1){if(!U)return;U.x1=f.x,U.y1=f.y,tn()}else en(f.x,f.y)}}function o(d){E.mode&&(d.preventDefault&&d.preventDefault(),E.mode===1?wr():br())}t.addEventListener(\"touchstart\",r,!1),t.addEventListener(\"touchmove\",a,!1),t.addEventListener(\"touchend\",o,!1),t.addEventListener(\"touchcancel\",o,!1),t.addEventListener(\"mousedown\",function(d){r(d);var f=function(p){a(p)},l=function(p){o(p),document.removeEventListener(\"mousemove\",f),document.removeEventListener(\"mouseup\",l)};document.addEventListener(\"mousemove\",f),document.addEventListener(\"mouseup\",l)},!1)}function ca(){var t=document.getElementById(\"decImg\");t&&(t.src=E.src);var e=document.getElementById(\"decRest\");e&&(e.style.display=\"none\");var n=E.im;n&&(n.src=E.src,n.removeAttribute(\"data-decbase\")),s(\"✔ 已还原原图\",\"ok\")}var da=\/https?:\\\/\\\/[A-Za-z0-9\\-._~:\\\/?#\\[\\]@!$&'()*+,;=%]+\/gi,fa=\/[.,;:!?)\\]}'\"]+$\/;function nn(t){return\/^https?:\\\/\\\/[^\\s\"'<>]+\\.json(\\?.*)?(#.*)?$\/i.test(t)}function Br(t){for(var e=t;fa.test(e);)e=e.replace(fa,\"\");return e}function rn(t){var e=document.createElement(\"span\");return e.className=\"imp-ic\",e.textContent=\"⤓ 一键导入\",e.title=t,e.onclick=function(n){Qe(n);try{location.href=\"legado:\/\/import\/any?src=\"+encodeURIComponent(this.title)}catch(r){s(\"✘ 导入失败\",\"no\")}},e}function Fr(t,e){t.getAttribute&&t.getAttribute(\"data-imp\")||(t.setAttribute&&t.setAttribute(\"data-imp\",\"1\"),t.parentNode&&t.parentNode.insertBefore(rn(e),t.nextSibling))}function an(t,e){for(var n=t.childNodes,r=0;r<n.length;r++){var a=n[r];if(a.nodeType===3)e.push(a);else if(a.nodeType===1){var o=a.tagName;o!==\"A\"&&o!==\"SCRIPT\"&&o!==\"STYLE\"&&o!==\"BUTTON\"&&an(a,e)}}return e}\/* ===== fixed42: 详情页链接统一「一键跳转」(楼主正文 \/ 回复楼层 \/ 点评) =====\n   出口与首页侧边栏文章容器一致: 一律走内置浏览器 java.startBrowser。\n   · .json 订阅源链接 -> 维持原样(⤓ 一键导入)\n   · 站内链接(<a>)    -> 保留 <a>(阅读器内跳转) + 补「一键跳转」按钮\n   · 站外链接(<a>)    -> 去掉链接语义(避免整页被顶走), 纯文本 + 「一键跳转」按钮\n   · 裸文本 URL       -> 纯文本 + 「一键跳转」按钮\n   覆盖: .msg(楼主正文\/回复楼层正文) + .ct(点评正文) *\/\nfunction jHost(u){return String(u==null?'':u).replace(\/^[a-z][a-z0-9+.\\-]*:\\\/\\\/\/i,'').split(\/[\\\/?#]\/)[0].toLowerCase()}\nfunction jSelf(u){u=String(u==null?'':u).replace(\/^\\s+|\\s+$\/g,'');if(!u)return 1;\n  if(\/^(#|javascript:|mailto:|data:|blob:|about:)\/i.test(u))return 1;\n  if(!\/^[a-z][a-z0-9+.\\-]*:\\\/\\\/\/i.test(u))return 1;\n  var h=jHost(u);\n  try{if(h===jHost(j))return 1}catch(e){}\n  try{if(h===jHost(T))return 1}catch(e){}\n  return 0}\nfunction jOpen(u){u=String(u==null?'':u).replace(\/^\\s+|\\s+$\/g,'');if(!u)return;\n  try{if(typeof java!=='undefined'&&java&&typeof java.startBrowser==='function'){java.startBrowser(u,u.slice(0,40));return}}catch(e){}\n  try{if(typeof java!=='undefined'&&java&&typeof java.openUrl==='function'){java.openUrl(u);return}}catch(e){}\n  try{if(window&&window.java&&typeof window.java.startBrowser==='function'){window.java.startBrowser(u,u.slice(0,40))}}catch(e){}}\nfunction jBtn(u){var e=document.createElement('span');e.className='jmp-ic';e.textContent='一键跳转';e.title=String(u==null?'':u);\n  e.onclick=function(n){Qe(n);jOpen(this.title)};return e}\nfunction jTxt(u){var e=document.createElement('span');e.className='jmp-tx';e.textContent=String(u==null?'':u);return e}\nfunction jFlat(a,u){var sp=jTxt(u);try{sp.innerHTML=String(a.innerHTML==null?'':a.innerHTML)}catch(e){}try{a.removeAttribute('href')}catch(e){}\n  try{if(a.parentNode)a.parentNode.replaceChild(sp,a)}catch(e){}return sp}\nfunction jText(tn){var p=tn&&tn.nodeValue;if(!p||p.indexOf('http')<0)return;\n  try{if(tn.parentNode&&String(tn.parentNode.className||'').indexOf('jmp-tx')>=0)return}catch(e){}\n  da.lastIndex=0;\n  for(var h=[],w,g=0;(w=da.exec(p))&&g++<80;){var u=Br(w[0]);if(u)h.push({u:u,at:w.index,len:u.length,tail:w[0].slice(u.length)})}\n  if(!h.length)return;var m=document.createDocumentFragment(),v=0,C,y;\n  for(C=0;C<h.length;C++){y=h[C];if(y.at>v)m.appendChild(document.createTextNode(p.slice(v,y.at)));\n    if(nn(y.u)){var B=document.createElement('a');B.className='imp-link';B.href=y.u;B.textContent=y.u;B.setAttribute('data-imp','1');m.appendChild(B);m.appendChild(rn(y.u))}\n    else{m.appendChild(jTxt(y.u));m.appendChild(jBtn(y.u))}\n    if(y.tail)m.appendChild(document.createTextNode(y.tail));v=y.at+y.len+y.tail.length}\n  if(v<p.length)m.appendChild(document.createTextNode(p.slice(v)));\n  if(tn.parentNode)tn.parentNode.replaceChild(m,tn)}\nfunction Ir(){var cs=document.querySelectorAll('.msg,.ct');\n  for(var i=0;i<cs.length;i++){var c=cs[i],ext=[],k,a,u,aas=c.querySelectorAll('a[href]');\n    for(k=0;k<aas.length;k++){a=aas[k];u=String(a.getAttribute('href')||'').replace(\/^\\s+|\\s+$\/g,'');if(!u)continue;\n      if(nn(u)){if(a.getAttribute('data-imp'))continue;a.setAttribute('data-imp','1');if(a.parentNode)a.parentNode.insertBefore(rn(u),a.nextSibling);continue}\n      if(a.getAttribute('data-jmp'))continue;a.setAttribute('data-jmp','1');\n      if(jSelf(u)){if(a.parentNode)a.parentNode.insertBefore(jBtn(u),a.nextSibling)}else{ext.push({el:a,u:u})}}\n    var tns=an(c,[]);for(k=0;k<tns.length;k++)jText(tns[k]);\n    for(k=0;k<ext.length;k++){var sp=jFlat(ext[k].el,ext[k].u);if(sp&&sp.parentNode)sp.parentNode.insertBefore(jBtn(ext[k].u),sp.nextSibling)}}}\n\/* ===== v66 帖子详情页: 半透明悬浮回顶按钮 ⬆ (长按拖动, 点击回顶) ===== *\/\nfunction topInit(){\n  try{\n    var el=document.getElementById('fabtop');\n    if(!el){\n      el=document.createElement('div');\n      el.id='fabtop'; el.className='fabtop'; el.textContent='\\u2191';\n      document.body.appendChild(el);\n      if(!document.getElementById('fabtopcss')){\n        var st=document.createElement('style'); st.id='fabtopcss';\n        st.textContent='.fabtop{position:fixed;z-index:60;display:flex;align-items:center;justify-content:center;width:34px;height:34px;border-radius:50%;box-sizing:border-box;background:rgba(255,255,255,.55);color:#3C414B;border:1px solid rgba(0,0,0,.16);box-shadow:0 1px 6px rgba(0,0,0,.18);font-size:19px;font-weight:700;line-height:1;cursor:pointer;-webkit-user-select:none;user-select:none;touch-action:none;transition:background .15s,transform .15s} .fabtop.drag{background:rgba(255,255,255,.88);transform:scale(1.06)} .fabtop:active{background:rgba(255,255,255,.88)}';\n        document.head.appendChild(st);\n      }\n    }\n    var sz=34,d=window.innerWidth||360,f=window.innerHeight||640;\n    if(typeof i.topX!=='number'||i.topX==null||typeof i.topY!=='number'||i.topY==null){i.topX=d-sz-14;i.topY=f-sz-120;}\n    el.style.left=Math.max(0,Math.min(d-sz,i.topX))+'px';\n    el.style.top=Math.max(0,Math.min(f-sz,i.topY))+'px';\n    if(el._bound)return; el._bound=true;\n    var G=null,ut=null,pe=0;\n    function setPos(x,y){i.topX=x;i.topY=y;el.style.left=x+'px';el.style.top=y+'px';}\n    function start(x,y){G={sx:x,sy:y,ox:i.topX,oy:i.topY,drag:0};ut=setTimeout(function(){if(G){G.drag=1;el.className='fabtop drag';try{navigator.vibrate&&navigator.vibrate(30)}catch(e){}}},550);}\n    function move(x,y){if(!G)return;var dx=x-G.sx,dy=y-G.sy;if(!G.drag&&(Math.abs(dx)>10||Math.abs(dy)>10)&&ut){clearTimeout(ut);ut=null;}if(G.drag){var d2=window.innerWidth||360,f2=window.innerHeight||640;setPos(Math.round(Math.max(0,Math.min(d2-sz,G.ox+dx))),Math.round(Math.max(0,Math.min(f2-sz,G.oy+dy))));}}\n    function end(){if(ut){clearTimeout(ut);ut=null;}if(G&&G.drag){el.className='fabtop';try{g(N,i)}catch(e){}try{s&&s('✔ 悬浮按钮位置已保存','ok')}catch(e){}pe=1;setTimeout(function(){pe=0;},350);}G=null;}\n    el.addEventListener('touchstart',function(e){try{var r=window.getSelection();r&&r.removeAllRanges&&r.removeAllRanges()}catch(_){}var t=e.touches[0];start(t.clientX,t.clientY);},{passive:true});\n    el.addEventListener('touchmove',function(e){if(G&&G.drag){e.preventDefault&&e.preventDefault();e.stopPropagation&&e.stopPropagation();}var t=e.touches[0];move(t.clientX,t.clientY);},{passive:false});\n    el.addEventListener('touchend',end);\n    el.addEventListener('touchcancel',end);\n    el.addEventListener('mousedown',function(e){e.preventDefault&&e.preventDefault();start(e.clientX,e.clientY);});\n    el.addEventListener('mousemove',function(e){if(G){if(G.drag){e.preventDefault&&e.preventDefault();}move(e.clientX,e.clientY);}});\n    el.addEventListener('mouseup',end);\n    el.addEventListener('mouseleave',function(){if(G&&G.drag)end();});\n    el.addEventListener('click',function(e){if(pe){e.preventDefault&&e.preventDefault();e.stopPropagation&&e.stopPropagation();return;}try{window.scrollTo(0,0)}catch(_){}});\n  }catch(e){}\n}\n\n\/* ===== v67 详情页: 双击卡片折叠3行(再双击展开) + 下载HTML ===== *\/\nfunction dblInit(){\n  try{\n    if(!document.getElementById('x8d26css')){\n      var st=document.createElement('style'); st.id='x8d26css';\n      st.textContent='.card.post .hdbtns{flex-direction:column;align-items:flex-end}'\n        +'.card{touch-action:manipulation}'\n        +'.card.fold3>.msg{display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}'\n        +'.card.fold3{position:relative}'\n        +'.foldtip{display:block;width:max-content;max-width:92%;margin:6px auto 2px;padding:1px 10px;border-radius:10px;font-size:11px;line-height:17px;text-align:center;letter-spacing:.3px;color:#8a8f9c;background:rgba(138,143,156,.14);-webkit-user-select:none;user-select:none;-webkit-touch-callout:none}';\n      (document.head||document.documentElement).appendChild(st);\n    }\n  }catch(e){}\n  try{\n    if(document._x8dbl)return; document._x8dbl=1;\n    var lastT=0,lastCard=null;\n    function cardOf(el){var n=el;for(var i=0;n&&i<7;i++){if(n.classList&&n.classList.contains('card'))return n;n=n.parentNode;}return null;}\n    function skip(el){if(!el||!el.tagName)return true;var t=el.tagName;if(t==='IMG'||t==='VIDEO'||t==='A'||t==='BUTTON'||t==='INPUT'||t==='TEXTAREA'||t==='SELECT'||t==='OPTION')return true;var n=el;for(var i=0;n&&i<4;i++){var c=n.className?String(n.className):'';if(\/(^|\\s)(acts|hdbtns|cmt|lp3|dock|pgbar|menu)(\\s|$)\/.test(c))return true;n=n.parentNode;}return false;}\n    function tip(c,on){\n      try{\n        var t=c.querySelector('.foldtip');\n        if(!on){if(t&&t.parentNode)t.parentNode.removeChild(t);return;}\n        if(t)return;\n        var m=c.querySelector('.msg');if(!m)return;\n        t=document.createElement('div');t.className='foldtip';\n        t.textContent='\\u5df2\\u6298\\u53e0 \\u00b7 \\u53cc\\u51fb\\u5c55\\u5f00';\n        if(m.nextSibling)c.insertBefore(t,m.nextSibling);else c.appendChild(t);\n      }catch(e){}\n    }\n    function tg(c){if(!c)return;if(c.classList.contains('fold3')){c.classList.remove('fold3');tip(c,false);}else{c.classList.add('fold3');tip(c,true);}}\n    document.addEventListener('touchend',function(e){\n      var el=e.target;if(skip(el)){lastT=0;lastCard=null;return;}\n      var now=Date.now(),c=cardOf(el);\n      if(lastCard&&c&&lastCard===c&&now-lastT<330){tg(lastCard);lastT=0;lastCard=null;}\n      else{lastT=now;lastCard=c;}\n    },true);\n    document.addEventListener('dblclick',function(e){\n      if('ontouchstart' in window)return;\n      var el=e.target;if(skip(el))return;tg(cardOf(el));\n    },true);\n  }catch(e){}\n}\nfunction _dlEsc(t){return String(t==null?'':t).replace(\/&\/g,'&amp;').replace(\/<\/g,'&lt;').replace(\/>\/g,'&gt;').replace(\/\"\/g,'&quot;');}\n\/* ===== fixed25: 生成 HTML -> 真·本地文件（Legado java.downloadFile） ===== *\/\nvar _dlDoc='',_dlPath='';\n\/* 阅读 App 的 java.getFile 拿不到绝对路径（java.io.File 被 RhinoClassShutter 屏蔽），\n   这里直接拼外部缓存目录前缀，与 downloadFile 返回的文件名组合成完整路径。 *\/\n\/* 包名：阅读 App 的 js 沙箱没有任何接口能读到自身包名（Context\/File\/Intent 都被屏蔽），\n   这里作为兜底常量放在一处；换 App 版本只改这一行即可。 *\/\nvar DLPKG='io.legado.app.yuedu.release';\nvar DLPREFIX='\/storage\/emulated\/0\/Android\/data\/'+DLPKG+'\/cache\/';\nfunction dlRealAbs(rel){\n  \/* 万一某个版本允许取 File 的字符串形式，就优先用真实绝对路径（包名必然正确） *\/\n  try{\n    if(typeof java!=='undefined'&&java.getFile){\n      var f=java.getFile(rel);\n      if(f){\n        var p='';\n        try{p=String(f);}catch(e){}\n        if(!p||p==='undefined'||p==='null'||p==='[object Object]'){try{p=String(f.getAbsolutePath());}catch(e){}}\n        if(!p||p==='undefined'||p==='null'||p==='[object Object]'){try{p=String(f.getPath());}catch(e){}}\n        if(!p||p==='undefined'||p==='null'||p==='[object Object]'){try{p=String(f.getCanonicalPath());}catch(e){}}\n        if(p&&p.charAt(0)==='\/'&&p.indexOf('\/cache\/')>=0)return p;\n      }\n    }\n  }catch(e){}\n  return '';\n}\n\nfunction dlBase(p){var s=String(p==null?'':p),i=s.lastIndexOf('\/');return i>=0?s.substring(i+1):s;}\nfunction _dlBytes(s){\n  \/* UTF-8 编码为字节数组（Rhino 无 btoa\/TextEncoder，需自行实现） *\/\n  var b=[],i,c,c2,cp,n=s.length;\n  for(i=0;i<n;i++){\n    c=s.charCodeAt(i);\n    if(c<0x80){b.push(c);}\n    else if(c<0x800){b.push(0xC0|(c>>6),0x80|(c&0x3F));}\n    else if(c>=0xD800&&c<=0xDBFF&&i+1<n&&(c2=s.charCodeAt(i+1))>=0xDC00&&c2<=0xDFFF){\n      cp=0x10000+((c-0xD800)<<10)+(c2-0xDC00);\n      b.push(0xF0|(cp>>18),0x80|((cp>>12)&0x3F),0x80|((cp>>6)&0x3F),0x80|(cp&0x3F));i++;\n    }\n    else if(c>=0xD800&&c<=0xDFFF){b.push(0xEF,0xBF,0xBD);}\n    else {b.push(0xE0|(c>>12),0x80|((c>>6)&0x3F),0x80|(c&0x3F));}\n  }\n  return b;\n}\nfunction _dlHex(s){\n  var b=_dlBytes(s),h='',i,t;\n  for(i=0;i<b.length;i++){t=b[i].toString(16);h+=(t.length<2?'0':'')+t;}\n  return h;\n}\nfunction _dlB64(s){\n  var A='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+\/';\n  var b=_dlBytes(s),o='',i,n=b.length,c1,c2,c3;\n  for(i=0;i<n;i+=3){\n    c1=b[i];c2=(i+1<n)?b[i+1]:0;c3=(i+2<n)?b[i+2]:0;\n    o+=A.charAt(c1>>2)+A.charAt(((c1&3)<<4)|(c2>>4))\n      +((i+1<n)?A.charAt(((c2&15)<<2)|(c3>>6)):'=')\n      +((i+2<n)?A.charAt(c3&63):'=');\n  }\n  return o;\n}\nfunction dlSave(name,html,key){\n  var rel='',ok=false,err='',tag=String(key||name||'x8');\n  \/* ① 首选: java.downloadFile(内容十六进制, url) —— url 只用于推导缓存文件名\n     与后缀（{\"type\":\"html\"}），真正落盘的是第一个参数的十六进制内容。\n     带上 tid 让不同帖子落到不同文件，避免互相覆盖。 *\/\n  try{\n    if(typeof java!=='undefined'&&java.downloadFile){\n      rel=java.downloadFile(_dlHex(html),'https:\/\/bbs.xiaoxiaoshuo8.com\/_x8dl_'+encodeURIComponent(tag)+'.html,{\"type\":\"html\"}');\n      if(rel)ok=true;\n    }else{err='无 java.downloadFile';}\n  }catch(e){err=String((e&&(e.message||e))||e);}\n  \/* ② 兜底: data:base64 URI（Legado AnalyzeUrl 对 data: 走本地字节流，不联网） *\/\n  if(!ok){\n    try{\n      if(typeof java!=='undefined'&&java.downloadFile){\n        rel=java.downloadFile('data:text\/html;base64,'+_dlB64(html)+',{\"type\":\"html\"}');\n        if(rel)ok=true;\n      }\n    }catch(e){if(!err)err=String((e&&(e.message||e))||e);}\n  }\n  \/* ③ 最后兜底: 浏览器环境 Blob 下载（Legado 内置 WebView 不支持 blob:，\n     会报 Can only download HTTP\/HTTPS URIs，所以只在前两步都失败时才走） *\/\n  if(!ok){\n    try{\n      var blob=new Blob([html],{type:'text\/html;charset=utf-8'});\n      var u=(window.URL||window.webkitURL).createObjectURL(blob);\n      var a=document.createElement('a');a.href=u;a.download=name;a.rel='noopener';\n      a.style.display='none';document.body.appendChild(a);a.click();ok=true;\n      setTimeout(function(){try{(window.URL||window.webkitURL).revokeObjectURL(u);}catch(e){}try{a.parentNode&&a.parentNode.removeChild(a);}catch(e){}},6000);\n    }catch(e){if(!err)err=String((e&&(e.message||e))||e);}\n  }\n  if(!ok){s('✘ 保存失败：'+(err||'当前环境不支持'),'no');return false;}\n  _dlDoc=String(html||'');\n  dlResult(name,rel);\n  return true;\n}\nfunction dlResult(name,rel){\n  var kb=0,real=rel?dlRealAbs(rel):'',full=rel?(real||(DLPREFIX+dlBase(rel))):'',guess=!!(rel&&!real);\n  _dlPath=full;\n  try{kb=Math.round(_dlBytes(_dlDoc).length\/1024);}catch(e){}\n  var old=document.getElementById('x8dlbox');if(old&&old.parentNode)old.parentNode.removeChild(old);\n  var box=document.createElement('div');box.id='x8dlbox';\n  box.setAttribute('style','position:fixed;left:0;right:0;top:0;bottom:0;z-index:99999;background:rgba(0,0,0,.45);display:flex;align-items:center;justify-content:center;padding:16px;box-sizing:border-box');\n  var card=document.createElement('div');\n  card.setAttribute('style','width:100%;max-width:400px;background:#fff;color:#1c1c1e;border-radius:14px;padding:16px;box-shadow:0 10px 30px rgba(0,0,0,.35);font-size:14px;line-height:1.65');\n  var B='border:1px solid #d1d5db;background:#fff;color:#111827;border-radius:9px;padding:8px 12px;font-size:13px';\n  card.innerHTML='<div style=\"font-size:16px;font-weight:700;margin-bottom:6px\">\\u2714 已生成 HTML<\/div>'\n    +'<div style=\"color:#6b7280;font-size:13px;word-break:break-all;margin-bottom:10px\">'+_dlEsc(name)+(kb?('\\uff08\\u7ea6 '+kb+' KB\\uff09'):'')+'<\/div>'\n    +(full?'<div style=\"font-size:12px;color:#374151;background:#f3f4f6;border-radius:8px;padding:8px;word-break:break-all;margin-bottom:10px;-webkit-user-select:text;user-select:text\">'+_dlEsc(full)+(guess?'<div style=\"color:#9ca3af;font-size:11px;margin-top:4px\">\\u5305\\u540d\\u4ee5\\u5b9e\\u9645\\u5b89\\u88c5\\u7684 App \\u4e3a\\u51c6<\/div>':'')+'<\/div>':'')\n    +'<div style=\"font-size:12px;color:#6b7280;line-height:1.55;margin-bottom:10px\">\\u9605\\u8bfb App \\u7684 JS \\u63a5\\u53e3\\u6ca1\\u6709\\u7cfb\\u7edf\\u300c\\u5206\\u4eab\\u300d\\u9762\\u677f\\uff0c\\u6240\\u4ee5\\u8fd9\\u91cc\\u7528\\u300c\\u590d\\u5236HTML\\u6e90\\u7801\\u300d\\u4ee3\\u66ff\\u5206\\u4eab\\uff1a\\u590d\\u5236\\u540e\\u5230\\u5fae\\u4fe1\/\\u7b14\\u8bb0\/\\u7535\\u8111\\u4e0a\\u7c98\\u8d34\\u5373\\u53ef\\u4fdd\\u5b58\\u3002<\/div>'\n    +'<div style=\"display:flex;gap:8px;justify-content:flex-end;flex-wrap:wrap\">'\n      +'<button onclick=\"dlCopyHtml()\" style=\"border:0;background:#2563eb;color:#fff;border-radius:9px;padding:8px 14px;font-size:13px\">\\u590d\\u5236HTML\\u6e90\\u7801<\/button>'\n      +'<button onclick=\"dlPreview()\" style=\"'+B+'\">\\u9884\\u89c8<\/button>'\n      +'<button onclick=\"dlClose()\" style=\"'+B+'\">\\u5173\\u95ed<\/button>'\n    +'<\/div>';\n  box.appendChild(card);\n  box.onclick=function(e){if(e&&e.target===box)dlClose();};\n  document.body.appendChild(box);\n}\nfunction dlCopyHtml(){\n  try{\n    if(!_dlDoc){s('\\u2718 \\u6ca1\\u6709\\u53ef\\u590d\\u5236\\u7684\\u5185\\u5bb9','no');return;}\n    Qn(_dlDoc,'\\u2714 HTML \\u6e90\\u7801\\u5df2\\u590d\\u5236\\uff0c\\u53ef\\u7c98\\u8d34\\u5230\\u4efb\\u610f App');\n  }catch(e){s('\\u2718 \\u590d\\u5236\\u5931\\u8d25\\uff1a'+((e&&(e.message||e))||e),'no');}\n}\nfunction dlPreview(){\n  try{\n    if(!_dlDoc){s('\\u2718 \\u6ca1\\u6709\\u53ef\\u9884\\u89c8\\u7684\\u5185\\u5bb9','no');return;}\n    var old=document.getElementById('x8pvbox');if(old&&old.parentNode)old.parentNode.removeChild(old);\n    var box=document.createElement('div');box.id='x8pvbox';\n    box.setAttribute('style','position:fixed;left:0;right:0;top:0;bottom:0;z-index:100001;background:#fff;display:flex;flex-direction:column');\n    var bar=document.createElement('div');\n    bar.setAttribute('style','flex:none;display:flex;align-items:center;flex-wrap:wrap;gap:8px;padding:8px 12px;background:#f3f4f6;border-bottom:1px solid #e5e7eb;font-size:14px;color:#111827');\n    bar.innerHTML='<span style=\"flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap\">\\u5bfc\\u51fa\\u9884\\u89c8<\/span>'\n      +(_dlPath?'<button onclick=\"dlPreviewCopyPath()\" style=\"border:0;background:#2563eb;color:#fff;border-radius:8px;padding:5px 12px;font-size:13px\">\\u590d\\u5236\\u8def\\u5f84<\/button>':'')\n      +'<button onclick=\"dlPreviewClose()\" style=\"border:1px solid #d1d5db;background:#fff;color:#111827;border-radius:8px;padding:5px 12px;font-size:13px\">\\u5173\\u95ed<\/button>'\n      +(_dlPath?'<div style=\"flex:0 0 100%;font-size:11px;color:#6b7280;word-break:break-all;-webkit-user-select:text;user-select:text\">'+_dlEsc(_dlPath)+'<\/div>':'');\n    var fr=document.createElement('iframe');\n    fr.setAttribute('style','flex:1;width:100%;border:0;background:#fff');\n    box.appendChild(bar);box.appendChild(fr);\n    document.body.appendChild(box);\n    try{fr.srcdoc=_dlDoc;}catch(e){try{fr.src='data:text\/html;charset=utf-8,'+encodeURIComponent(_dlDoc);}catch(e2){fr.srcdoc=_dlDoc;}}\n  }catch(e){s('\\u2718 \\u9884\\u89c8\\u5931\\u8d25\\uff1a'+((e&&(e.message||e))||e),'no');}\n}\nfunction dlPreviewClose(){\n  var b=document.getElementById('x8pvbox');if(b&&b.parentNode)b.parentNode.removeChild(b);\n}\nfunction dlPreviewCopyPath(){\n  try{\n    if(!_dlPath){s('\\u2718 \\u6ca1\\u6709\\u53ef\\u590d\\u5236\\u7684\\u8def\\u5f84','no');return;}\n    Qn(_dlPath,'\\u2714 \\u8def\\u5f84\\u5df2\\u590d\\u5236');\n  }catch(e){s('\\u2718 \\u590d\\u5236\\u5931\\u8d25','no');}\n}\nfunction dlClose(){\n  var b=document.getElementById('x8dlbox');if(b&&b.parentNode)b.parentNode.removeChild(b);\n}\n\nfunction dlBuildDoc(title,items){\n  var css='body{font-family:-apple-system,\"PingFang SC\",\"Microsoft YaHei\",sans-serif;line-height:1.75;max-width:820px;margin:0 auto;padding:16px;color:#1c1c1e;background:#fff}'\n    +'h1{font-size:22px;margin:8px 0 16px}'\n    +'.card{border:1px solid #e6e6ea;border-radius:10px;padding:12px 14px;margin:14px 0}'\n    +'.hd{font-size:13px;color:#8a8f9c;margin-bottom:8px}.un{color:#333;font-weight:700;font-size:14px}.floor{margin-left:8px}'\n    +'.msg{word-wrap:break-word;overflow-wrap:anywhere}.msg img{max-width:100%;height:auto;border-radius:6px}'\n    +'.cmt{margin-top:8px;padding-top:6px;border-top:1px dashed #eee;font-size:13px;color:#777}';\n  var h='<!DOCTYPE html><html lang=\"zh-CN\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"><title>'+_dlEsc(title)+'<\/title><style>'+css+'<\/style><\/head><body>';\n  h+='<h1>'+_dlEsc(title)+'<\/h1>';\n  for(var i=0;i<items.length;i++){var it=items[i]||{};\n    h+='<div class=\"card\"><div class=\"hd\"><b class=\"un\">'+_dlEsc(it.author||'匿名')+'<\/b>'+(it.floor?'<span class=\"floor\">'+_dlEsc(it.floor)+'<\/span>':'')+' · <span class=\"tm\">'+_dlEsc(it.time||'')+'<\/span><\/div>';\n    h+='<div class=\"msg\">'+(it.msg||'')+'<\/div>'+(it.cmts||'')+'<\/div>';\n  }\n  h+='<\/body><\/html>';return h;\n}\nfunction downloadThread(){\n  try{\n    if(typeof Gt==='undefined'||!Gt){s('✘ 页面未就绪','no');return;}\n    s('正在抓取全部楼层…','wait');\n    var tid=Gt,items=[],seen={},title='',total=1,p=1,g=0;\n    function finish(){\n      if(!items.length){s('✘ 未获取到楼层内容','no');return;}\n      var name='帖子_'+tid+'.html';\n      try{var safe=String(title).replace(\/[\\\\\/:*?\"<>|\\r\\n\\t\\s]+\/g,'_').slice(0,40);if(safe)name='帖子_'+tid+'_'+safe+'.html';}catch(e){}\n      dlSave(name,dlBuildDoc(title,items),tid);\n    }\n    function next(){\n      var u=ae(p,false,false);\n      Dt(u).then(function(h){\n        var r=null;try{r=_t(h,u);}catch(e){r=null;}\n        if(r){\n          if(p===1){title=(r.title&&r.title!=='无标题')?r.title:('帖子 '+tid);total=parseInt(r.tp)||1;}\n          var it=r.items||[];\n          for(var i=0;i<it.length;i++){var pid=it[i]&&it[i].pid;if(pid&&pid!=='0'&&!seen[pid]){seen[pid]=1;items.push(it[i]);}}\n        }\n        p++;g++;\n        if(p<=total&&g<300){s('抓取中 '+Math.min(p,total)+'\/'+total+' …','wait');setTimeout(next,140);}\n        else finish();\n      })['catch'](function(){p++;g++;if(p<=total&&g<300)setTimeout(next,140);else finish();});\n    }\n    next();\n  }catch(e){s('✘ 下载出错：'+(e&&(e.message||e)),'no');}\n}\nfunction Pt(){try{pr()}catch(t){}try{Ir()}catch(t){}try{x8BindVid()}catch(t){}try{topInit()}catch(t){}try{dblInit()}catch(t){}try{rpHi()}catch(t){}}var ge={tol:24};function Er(){var t=document.getElementById(\"frdec\");return t||(t=document.createElement(\"div\"),t.className=\"modal\",t.id=\"frdec\",t.onclick=function(e){e&&e.target===this&&Cr()},t.innerHTML=`<div class=\"mbox\"><h3>🎨 外框去底色<\/h3><div class=\"dec-hint\">JPG 外框通常带纯色背景，套在头像上会挡住头像。点图片吸取背景色，或用「自动去底色」从四角自动识别。<\/div><div class=\"frdec-prev\" id=\"frdecPrev\"><img id=\"frdecImg\" referrerpolicy=\"no-referrer\" draggable=\"false\" ondblclick=\"zReset('frdec')\" onclick=\"frDecPick(event)\" alt=\"\"><\/div><div class=\"zbar\"><span>放大<\/span><input id=\"frdecZoom\" type=\"range\" min=\"10\" max=\"80\" value=\"10\" oninput=\"zSlider('frdec',this)\"><b id=\"frdecZoomV\">1.0x<\/b><button type=\"button\" onclick=\"zReset('frdec')\">复位<\/button><\/div><div class=\"dec-hint\">双指捏合或拖滑块可放大（1~8x），单指拖动移动画面，双击复位；放大后取色更精确。<\/div><div class=\"dec-tol\"><span>容差<\/span><input id=\"frdecTol\" type=\"range\" min=\"0\" max=\"128\" value=\"24\" oninput=\"frDecTol(this.value)\"><b id=\"frdecTolV\">24<\/b><\/div><div class=\"dec-btns\"><button class=\"bt\" onclick=\"frDecAuto()\">自动去底色<\/button><button class=\"bt warn\" id=\"frdecRest\" onclick=\"frDecRestore()\">↺ 还原<\/button><button class=\"bt pri\" onclick=\"frDecClose()\">完成<\/button><\/div><div class=\"hint\">灰白棋盘格处即已透明。去底色结果<b>对所有楼层头像生效<\/b>并保存在本机；容差越大，去掉的相近颜色越多。<\/div><\/div>`,document.body.appendChild(t),t)}function Cr(){var t=document.getElementById(\"frdec\");t&&(t.className=\"modal\")}function sa(t){ge.tol=+t||0;var e=document.getElementById(\"frdecTolV\");e&&(e.textContent=ge.tol)}function we(t){var e=document.getElementById(\"frdecRest\");e&&(e.style.display=t?\"inline-block\":\"none\")}function ua(){if(!_){s(\"✘ 请先设置头像外框图片\",\"no\");return}var t=Er(),e=document.getElementById(\"frdecImg\");e&&(e.onload=function(){zMeasure(\"frdec\"),zApply(\"frdec\")},e.src=mt||_),zOpen(\"frdec\");var n=document.getElementById(\"frdecTol\");n&&(n.value=24);var r=document.getElementById(\"frdecTolV\");r&&(r.textContent=24),ge.tol=24,we(!!mt),t.className=\"modal on\"}function be(){mt=\"\",Qt(Fe,\"\")}function on(t,e){var n=new Image;n.crossOrigin=\"anonymous\",n.onload=function(){e(n)},n.onerror=function(){e(null)},n.src=t}function cn(t){var e=t.naturalWidth,n=t.naturalHeight,r=320;if(Math.max(e,n)>r){var a=r\/Math.max(e,n);e=Math.round(e*a),n=Math.round(n*a)}var o=document.createElement(\"canvas\");o.width=e,o.height=n;var d=o.getContext(\"2d\");return d.drawImage(t,0,0,e,n),{cv:o,cx:d,W:e,H:n,dd:d.getImageData(0,0,e,n)}}function dn(t,e,n){var r=\"\";try{r=t.toDataURL(\"image\/png\")}catch(a){s(\"✘ 图片无法读取像素（跨域限制）\",\"no\");return}if(!r||r.length<32){s(\"✘ 生成失败\",\"no\");return}if(!Qt(Fe,r)){s(\"✘ 本机存储失败（图片过大？）\",\"no\");return}mt=r,D(),e&&(e.src=r),we(!0),s(\"✔ 已去底色，全部头像生效\",\"ok\")}function la(t){if(!zGet(\"frdec\").moved){var e=document.getElementById(\"frdecImg\");if(e){var n=String(e.getAttribute(\"src\")||\"\");if(!n){s(\"✘ 无图片\",\"no\");return}on(n,function(r){if(!r||!r.naturalWidth){s(\"✘ 跨域图片无法读取像素，请换用支持跨域的图床\",\"no\");return}try{var a=cn(r),o=a.dd.data,d=a.W,f=a.H,l=e.getBoundingClientRect(),p=Math.round((t.clientX-l.left)*d\/l.width),h=Math.round((t.clientY-l.top)*f\/l.height);p<0&&(p=0),h<0&&(h=0),p>=d&&(p=d-1),h>=f&&(h=f-1);for(var w=(h*d+p)*4,b=o[w],x=o[w+1],I=o[w+2],m=ge.tol||0,v=0;v<o.length;v+=4)Math.abs(o[v]-b)<=m&&Math.abs(o[v+1]-x)<=m&&Math.abs(o[v+2]-I)<=m&&(o[v+3]=0);a.cx.putImageData(a.dd,0,0),dn(a.cv,e,0)}catch(C){s(\"✘ 跨域图片无法读取像素\",\"no\")}})}}}function pa(){var t=document.getElementById(\"frdecImg\");if(t){var e=String(t.getAttribute(\"src\")||\"\");if(!e){s(\"✘ 无图片\",\"no\");return}s(\"处理中…\",\"wait\"),on(e,function(n){if(!n||!n.naturalWidth){s(\"✘ 跨域图片无法读取像素，请换用支持跨域的图床\",\"no\");return}try{let pt=function(Ot){return Math.abs(a[Ot]-I)<=f&&Math.abs(a[Ot+1]-m)<=f&&Math.abs(a[Ot+2]-v)<=f};var ft=pt,r=cn(n),a=r.dd.data,o=r.W,d=r.H,f=ge.tol||0,l=[[0,0],[o-1,0],[0,d-1],[o-1,d-1]],p=0,h=0,w=0,b;for(b=0;b<4;b++){var x=(l[b][1]*o+l[b][0])*4;p+=a[x],h+=a[x+1],w+=a[x+2]}var I=Math.round(p\/4),m=Math.round(h\/4),v=Math.round(w\/4),C=new Uint8Array(o*d),y=[],B,R;for(b=0;b<4;b++)R=l[b][1]*o+l[b][0],!C[R]&&pt(R*4)&&(C[R]=1,y.push(R));for(var L=0,O=o*d,H=0;y.length&&H++<O*4;){R=y.pop();var et=R\/o|0,lt=R-et*o;a[R*4+3]=0,L++,lt>0&&(B=R-1,!C[B]&&pt(B*4)&&(C[B]=1,y.push(B))),lt<o-1&&(B=R+1,!C[B]&&pt(B*4)&&(C[B]=1,y.push(B))),et>0&&(B=R-o,!C[B]&&pt(B*4)&&(C[B]=1,y.push(B))),et<d-1&&(B=R+o,!C[B]&&pt(B*4)&&(C[B]=1,y.push(B)))}if(L<o*d*.005){L=0;for(var nt=0;nt<a.length;nt+=4)Math.abs(a[nt]-I)<=f&&Math.abs(a[nt+1]-m)<=f&&Math.abs(a[nt+2]-v)<=f&&(a[nt+3]=0,L++)}r.cx.putImageData(r.dd,0,0),dn(r.cv,t,L)}catch(pt){s(\"✘ 跨域图片无法读取像素\",\"no\")}})}}function Pr(){if(!mt){s(\"当前已是原图\",\"ok\");return}mt=\"\",Qt(Fe,\"\"),D();var t=document.getElementById(\"frdecImg\");t&&(t.src=_),we(!1),s(\"✔ 已还原原图，全部头像生效\",\"ok\")}function ya(){Pr(),A()}try{Xn()}catch(t){}try{cpInit()}catch(t){}try{sr()}catch(t){}try{tr()}catch(t){}try{aiInitBtn()}catch(t){}try{window.addEventListener(\"scroll\",bn,!1)}catch(t){}Pt();try{var ma=function(){Se()};typeof window.requestIdleCallback==\"function\"?window.requestIdleCallback(ma,{timeout:2e3}):setTimeout(ma,300)}catch(t){}try{(function(){var t=V;Object.defineProperty(window,\"APP\",{get:function(){return t},set:function(e){t=e,V=e},configurable:!0})})()}catch(t){}try{(function(){var t=$;Object.defineProperty(window,\"BGC\",{get:function(){return t},set:function(e){t=e,$=e},configurable:!0})})()}catch(t){}try{(function(){var t=ct;Object.defineProperty(window,\"CP\",{get:function(){return t},set:function(e){t=e,ct=e},configurable:!0})})()}catch(t){}try{(function(){var t=Q;Object.defineProperty(window,\"FRC\",{get:function(){return t},set:function(e){t=e,Q=e},configurable:!0})})()}catch(t){}try{(function(){var t=mt;Object.defineProperty(window,\"FRDEC\",{get:function(){return t},set:function(e){t=e,mt=e},configurable:!0})})()}catch(t){}try{(function(){var t=i;Object.defineProperty(window,\"ST\",{get:function(){return t},set:function(e){t=e,i=e},configurable:!0})})()}catch(t){}try{typeof vt!=\"undefined\"&&(window.LZIO=vt)}catch(t){}try{typeof ne!=\"undefined\"&&(window.LZOK=ne)}catch(t){}try{typeof Mt!=\"undefined\"&&(window.LZQ=Mt)}catch(t){}try{typeof it!=\"undefined\"&&(window.absUrl=it)}catch(t){}try{typeof di!=\"undefined\"&&(window.addBG=di)}catch(t){}try{typeof ti!=\"undefined\"&&(window.addCat=ti)}catch(t){}try{typeof Vi!=\"undefined\"&&(window.addFabBi=Vi)}catch(t){}try{typeof ci!=\"undefined\"&&(window.addFrame=ci)}catch(t){}try{typeof alive!=\"undefined\"&&(window.alive=alive)}catch(t){}try{typeof ot!=\"undefined\"&&(window.applyBG=ot)}catch(t){}try{typeof ue!=\"undefined\"&&(window.applyCfg=ue)}catch(t){}try{typeof Et!=\"undefined\"&&(window.applyLB=Et)}catch(t){}try{typeof Bi!=\"undefined\"&&(window.applyPicker=Bi)}catch(t){}try{typeof _i!=\"undefined\"&&(window.applyProfile=_i)}catch(t){}try{typeof D!=\"undefined\"&&(window.applyStyle=D)}catch(t){}try{typeof arr!=\"undefined\"&&(window.arr=arr)}catch(t){}try{typeof kr!=\"undefined\"&&(window.attTip=kr)}catch(t){}try{typeof Yr!=\"undefined\"&&(window.attachDlg=Yr)}catch(t){}try{typeof Ie!=\"undefined\"&&(window.avHtml=Ie)}catch(t){}try{typeof Hi!=\"undefined\"&&(window.bgPanel=Hi)}catch(t){}try{typeof Bt!=\"undefined\"&&(window.bindAv=Bt)}catch(t){}try{typeof c!=\"undefined\"&&(window.c=c)}catch(t){}try{typeof zi!=\"undefined\"&&(window.cancelRen=zi)}catch(t){}try{typeof Ne!=\"undefined\"&&(window.catBlock=Ne)}catch(t){}try{typeof We!=\"undefined\"&&(window.catOpts=We)}catch(t){}try{typeof cen!=\"undefined\"&&(window.cen=cen)}catch(t){}try{typeof Vr!=\"undefined\"&&(window.checkLogin=Vr)}catch(t){}try{typeof downloadThread!=\"undefined\"&&(window.downloadThread=downloadThread)}catch(t){}try{typeof dlClose!=\"undefined\"&&(window.dlClose=dlClose)}catch(t){}try{typeof dlCopyHtml!=\"undefined\"&&(window.dlCopyHtml=dlCopyHtml)}catch(t){}try{typeof dlPreview!=\"undefined\"&&(window.dlPreview=dlPreview)}catch(t){}try{typeof dlPreviewClose!=\"undefined\"&&(window.dlPreviewClose=dlPreviewClose)}catch(t){}try{typeof dlPreviewCopyPath!=\"undefined\"&&(window.dlPreviewCopyPath=dlPreviewCopyPath)}catch(t){}try{typeof qn!=\"undefined\"&&(window.clampXY=qn)}catch(t){}try{typeof ai!=\"undefined\"&&(window.clearBG=ai)}catch(t){}try{typeof Ki!=\"undefined\"&&(window.clearFabBi=Ki)}catch(t){}try{typeof oi!=\"undefined\"&&(window.clearFrame=oi)}catch(t){}try{typeof Rn!=\"undefined\"&&(window.closeAtt=Rn)}catch(t){}try{typeof Wi!=\"undefined\"&&(window.closeBG=Wi)}catch(t){}try{typeof Sn!=\"undefined\"&&(window.closeCmt=Sn)}catch(t){}try{typeof Tn!=\"undefined\"&&(window.closeEditM=Tn)}catch(t){}try{typeof er!=\"undefined\"&&(window.closeIO=er)}catch(t){}try{typeof Kr!=\"undefined\"&&(window.closeLB=Kr)}catch(t){}try{typeof Nt!=\"undefined\"&&(window.closeMenu=Nt)}catch(t){}try{typeof oe!=\"undefined\"&&(window.closePickPage=oe)}catch(t){}try{typeof Kn!=\"undefined\"&&(window.closePicker=Kn)}catch(t){}try{typeof Si!=\"undefined\"&&(window.copyCfg=Si)}catch(t){}try{typeof Qn!=\"undefined\"&&(window.copyText=Qn)}catch(t){}try{typeof vi!=\"undefined\"&&(window.crow=vi)}catch(t){}try{typeof wi!=\"undefined\"&&(window.cv=wi)}catch(t){}try{typeof Ni!=\"undefined\"&&(window.darkPreset=Ni)}catch(t){}try{typeof dbl!=\"undefined\"&&(window.dbl=dbl)}catch(t){}try{typeof ia!=\"undefined\"&&(window.decBrush=ia)}catch(t){}try{typeof en!=\"undefined\"&&(window.decBrushAdd=en)}catch(t){}try{typeof br!=\"undefined\"&&(window.decBrushEnd=br)}catch(t){}try{typeof ye!=\"undefined\"&&(window.decCanvas=ye)}catch(t){}try{typeof hr!=\"undefined\"&&(window.decClose=hr)}catch(t){}try{typeof me!=\"undefined\"&&(window.decCommit=me)}catch(t){}try{typeof mr!=\"undefined\"&&(window.decCont=mr)}catch(t){}try{typeof gr!=\"undefined\"&&(window.decFlood=gr)}catch(t){}try{typeof pr!=\"undefined\"&&(window.decInit=pr)}catch(t){}try{typeof yr!=\"undefined\"&&(window.decMode=yr)}catch(t){}try{typeof vr!=\"undefined\"&&(window.decOpen=vr)}catch(t){}try{typeof jt!=\"undefined\"&&(window.decOv=jt)}catch(t){}try{typeof xr!=\"undefined\"&&(window.decOvInit=xr)}catch(t){}try{typeof Vt!=\"undefined\"&&(window.decOvSize=Vt)}catch(t){}try{typeof oa!=\"undefined\"&&(window.decPick=oa)}catch(t){}try{typeof ve!=\"undefined\"&&(window.decPt=ve)}catch(t){}try{typeof ca!=\"undefined\"&&(window.decRestore=ca)}catch(t){}try{typeof tn!=\"undefined\"&&(window.decSelDraw=tn)}catch(t){}try{typeof wr!=\"undefined\"&&(window.decSelEnd=wr)}catch(t){}try{typeof aa!=\"undefined\"&&(window.decTol=aa)}catch(t){}try{typeof xe!=\"undefined\"&&(window.decodeEnt=xe)}catch(t){}try{typeof Qr!=\"undefined\"&&(window.delCat=Qr)}catch(t){}try{typeof ji!=\"undefined\"&&(window.delFabBi=ji)}catch(t){}try{typeof ei!=\"undefined\"&&(window.delPre=ei)}catch(t){}try{typeof Gi!=\"undefined\"&&(window.delProfile=Gi)}catch(t){}try{typeof dist!=\"undefined\"&&(window.dist=dist)}catch(t){}try{typeof Or!=\"undefined\"&&(window.doFav=Or)}catch(t){}try{typeof kn!=\"undefined\"&&(window.editPost=kn)}catch(t){}try{typeof end!=\"undefined\"&&(window.end=end)}catch(t){}try{typeof ui!=\"undefined\"&&(window.endsec=ui)}catch(t){}try{typeof k!=\"undefined\"&&(window.esc=k)}catch(t){}try{typeof Pi!=\"undefined\"&&(window.exportCfg=Pi)}catch(t){}try{typeof pn!=\"undefined\"&&(window.extractDiv=pn)}catch(t){}try{typeof fr!=\"undefined\"&&(window.fabBlock=fr)}catch(t){}try{typeof sr!=\"undefined\"&&(window.fabInit=sr)}catch(t){}try{typeof Re!=\"undefined\"&&(window.fbGet=Re)}catch(t){}try{typeof Me!=\"undefined\"&&(window.fbPost=Me)}catch(t){}try{typeof ke!=\"undefined\"&&(window.fetchOp=ke)}catch(t){}try{typeof jr!=\"undefined\"&&(window.focusReply=jr)}catch(t){}try{typeof dn!=\"undefined\"&&(window.frDecApply=dn)}catch(t){}try{typeof pa!=\"undefined\"&&(window.frDecAuto=pa)}catch(t){}try{typeof cn!=\"undefined\"&&(window.frDecCanvas=cn)}catch(t){}try{typeof ya!=\"undefined\"&&(window.frDecClear=ya)}catch(t){}try{typeof Cr!=\"undefined\"&&(window.frDecClose=Cr)}catch(t){}try{typeof on!=\"undefined\"&&(window.frDecLoad=on)}catch(t){}try{typeof ua!=\"undefined\"&&(window.frDecOpen=ua)}catch(t){}try{typeof Er!=\"undefined\"&&(window.frDecPanel=Er)}catch(t){}try{typeof la!=\"undefined\"&&(window.frDecPick=la)}catch(t){}try{typeof be!=\"undefined\"&&(window.frDecReset=be)}catch(t){}try{typeof we!=\"undefined\"&&(window.frDecRestBtn=we)}catch(t){}try{typeof Pr!=\"undefined\"&&(window.frDecRestore=Pr)}catch(t){}try{typeof sa!=\"undefined\"&&(window.frDecTol=sa)}catch(t){}try{typeof Zn!=\"undefined\"&&(window.frFitUI=Zn)}catch(t){}try{typeof mn!=\"undefined\"&&(window.getAttaches=mn)}catch(t){}try{typeof vn!=\"undefined\"&&(window.getCmts=vn)}catch(t){}try{typeof Dt!=\"undefined\"&&(window.getHtml=Dt)}catch(t){}try{typeof yn!=\"undefined\"&&(window.getMsg=yn)}catch(t){}try{typeof go!=\"undefined\"&&(window.go=go)}catch(t){}try{typeof Wr!=\"undefined\"&&(window.goAuthor=Wr)}catch(t){}try{typeof Mr!=\"undefined\"&&(window.goBack=Mr)}catch(t){}try{typeof Hr!=\"undefined\"&&(window.goOrder=Hr)}catch(t){}try{typeof Mn!=\"undefined\"&&(window.goPage=Mn)}catch(t){}try{typeof Ln!=\"undefined\"&&(window.goPick=Ln)}catch(t){}try{typeof Dn!=\"undefined\"&&(window.goPickInput=Dn)}catch(t){}try{typeof jn!=\"undefined\"&&(window.h2r=jn)}catch(t){}try{typeof tt!=\"undefined\"&&(window.hex2rgba=tt)}catch(t){}try{typeof De!=\"undefined\"&&(window.hideList=De)}catch(t){}try{typeof Zr!=\"undefined\"&&(window.hidePre=Zr)}catch(t){}try{typeof gi!=\"undefined\"&&(window.hsv2rgb=gi)}catch(t){}try{typeof Ct!=\"undefined\"&&(window.icCancel=Ct)}catch(t){}try{typeof Ve!=\"undefined\"&&(window.icMove=Ve)}catch(t){}try{typeof Ue!=\"undefined\"&&(window.icPoint=Ue)}catch(t){}try{typeof je!=\"undefined\"&&(window.icStart=je)}catch(t){}try{typeof $n!=\"undefined\"&&(window.imgAbsSrc=$n)}catch(t){}try{typeof tr!=\"undefined\"&&(window.imgCopyInit=tr)}catch(t){}try{typeof rn!=\"undefined\"&&(window.impBtn=rn)}catch(t){}try{typeof Fr!=\"undefined\"&&(window.impBtnAfter=Fr)}catch(t){}try{typeof Br!=\"undefined\"&&(window.impClean=Br)}catch(t){}try{typeof Ir!=\"undefined\"&&(window.impSrcInit=Ir)}catch(t){}try{typeof an!=\"undefined\"&&(window.impTextNodes=an)}catch(t){}try{typeof nn!=\"undefined\"&&(window.impUrl=nn)}catch(t){}try{typeof Li!=\"undefined\"&&(window.importCfg=Li)}catch(t){}try{typeof ki!=\"undefined\"&&(window.importCfgPanel=ki)}catch(t){}try{typeof ln!=\"undefined\"&&(window.iniAv=ln)}catch(t){}try{typeof Gr!=\"undefined\"&&(window.insAtt=Gr)}catch(t){}try{typeof lr!=\"undefined\"&&(window.isDecImg=lr)}catch(t){}try{typeof Yn!=\"undefined\"&&(window.isHidden=Yn)}catch(t){}try{typeof te!=\"undefined\"&&(window.isMine=te)}catch(t){}try{typeof Ft!=\"undefined\"&&(window.isSm=Ft)}catch(t){}try{typeof at!=\"undefined\"&&(window.jload=at)}catch(t){}try{typeof rt!=\"undefined\"&&(window.jqt=rt)}catch(t){}try{typeof g!=\"undefined\"&&(window.jsave=g)}catch(t){}try{typeof Qe!=\"undefined\"&&(window.killEv=Qe)}catch(t){}try{typeof It!=\"undefined\"&&(window.layoutImgs=It)}catch(t){}try{typeof Le!=\"undefined\"&&(window.lbDist=Le)}catch(t){}try{typeof Xn!=\"undefined\"&&(window.lbInit=Xn)}catch(t){}try{typeof On!=\"undefined\"&&(window.li0=On)}catch(t){}try{typeof Oi!=\"undefined\"&&(window.lightPreset=Oi)}catch(t){}try{typeof yt!=\"undefined\"&&(window.load=yt)}catch(t){}try{typeof un!=\"undefined\"&&(window.loadBig=un)}catch(t){}try{typeof Mi!=\"undefined\"&&(window.loadCfgLocal=Mi)}catch(t){}try{typeof loc!=\"undefined\"&&(window.loc=loc)}catch(t){}try{typeof Gn!=\"undefined\"&&(window.lpEnd=Gn)}catch(t){}try{typeof Jr!=\"undefined\"&&(window.lpStart=Jr)}catch(t){}try{typeof In!=\"undefined\"&&(window.lzInit=In)}catch(t){}try{typeof re!=\"undefined\"&&(window.lzOnScroll=re)}catch(t){}try{typeof Te!=\"undefined\"&&(window.lzPump=Te)}catch(t){}try{typeof En!=\"undefined\"&&(window.lzWatch=En)}catch(t){}try{typeof mm!=\"undefined\"&&(window.mm=mm)}catch(t){}try{typeof bn!=\"undefined\"&&(window.moreCheck=bn)}catch(t){}try{typeof Y!=\"undefined\"&&(window.mount=Y)}catch(t){}try{typeof move!=\"undefined\"&&(window.move=move)}catch(t){}try{typeof Wn!=\"undefined\"&&(window.movePre=Wn)}catch(t){}try{typeof mu!=\"undefined\"&&(window.mu=mu)}catch(t){}try{typeof multi!=\"undefined\"&&(window.multi=multi)}catch(t){}try{typeof Hn!=\"undefined\"&&(window.mvPrompt=Hn)}catch(t){}try{typeof ht!=\"undefined\"&&(window.nav=ht)}catch(t){}try{typeof Bn!=\"undefined\"&&(window.normalizeImgs=Bn)}catch(t){}try{typeof An!=\"undefined\"&&(window.openEditM=An)}catch(t){}try{typeof ce!=\"undefined\"&&(window.openLB=ce)}catch(t){}try{typeof Ze!=\"undefined\"&&(window.openLBsrc=Ze)}catch(t){}try{typeof xi!=\"undefined\"&&(window.openPicker=xi)}catch(t){}try{typeof _t!=\"undefined\"&&(window.parse=_t)}catch(t){}try{typeof qt!=\"undefined\"&&(window.parseReply=qt)}catch(t){}try{typeof S!=\"undefined\"&&(window.pick=S)}catch(t){}try{typeof ar!=\"undefined\"&&(window.pickImgFromHtml=ar)}catch(t){}try{typeof qr!=\"undefined\"&&(window.pickPage=qr)}catch(t){}try{typeof Wt!=\"undefined\"&&(window.postHtml=Wt)}catch(t){}try{typeof Pt!=\"undefined\"&&(window.postRender=Pt)}catch(t){}try{typeof nr!=\"undefined\"&&(window.profBlock=nr)}catch(t){}try{typeof hi!=\"undefined\"&&(window.r2h=hi)}catch(t){}try{typeof Ur!=\"undefined\"&&(window.rMenu=Ur)}catch(t){}try{typeof $e!=\"undefined\"&&(window.rainbow=$e)}catch(t){}try{typeof xn!=\"undefined\"&&(window.realImgSrc=xn)}catch(t){}try{typeof A!=\"undefined\"&&(window.refreshPanel=A)}catch(t){}try{typeof Yi!=\"undefined\"&&(window.renProfile=Yi)}catch(t){}try{typeof gn!=\"undefined\"&&(window.render=gn)}catch(t){}try{typeof Ee!=\"undefined\"&&(window.renderHead=Ee)}catch(t){}try{typeof ee!=\"undefined\"&&(window.renderItem=ee)}catch(t){}try{typeof Rt!=\"undefined\"&&(window.renderLazy=Rt)}catch(t){}try{typeof Se!=\"undefined\"&&(window.renderRest=Se)}catch(t){}try{typeof Pe!=\"undefined\"&&(window.renderTail=Pe)}catch(t){}try{typeof Nn!=\"undefined\"&&(window.replyTo=Nn)}catch(t){}try{typeof Di!=\"undefined\"&&(window.resetAll=Di)}catch(t){}try{typeof Jn!=\"undefined\"&&(window.resetFold=Jn)}catch(t){}try{typeof rr!=\"undefined\"&&(window.resetStyle=rr)}catch(t){}try{typeof mi!=\"undefined\"&&(window.resetXY=mi)}catch(t){}try{typeof Vn!=\"undefined\"&&(window.rgb2hsv=Vn)}catch(t){}try{typeof li!=\"undefined\"&&(window.rrow=li)}catch(t){}try{typeof same!=\"undefined\"&&(window.same=same)}catch(t){}try{typeof Ri!=\"undefined\"&&(window.saveCfgLocal=Ri)}catch(t){}try{typeof le!=\"undefined\"&&(window.saveFABI=le)}catch(t){}try{typeof Xi!=\"undefined\"&&(window.saveProfile=Xi)}catch(t){}try{typeof si!=\"undefined\"&&(window.sec=si)}catch(t){}try{typeof Ii!=\"undefined\"&&(window.selrow=Ii)}catch(t){}try{typeof _r!=\"undefined\"&&(window.sendReply=_r)}catch(t){}try{typeof ea!=\"undefined\"&&(window.setAMask=ea)}catch(t){}try{typeof ta!=\"undefined\"&&(window.setFMask=ta)}catch(t){}try{typeof ii!=\"undefined\"&&(window.setFMode=ii)}catch(t){}try{typeof Nr!=\"undefined\"&&(window.setImgLazy=Nr)}catch(t){}try{typeof Zi!=\"undefined\"&&(window.setOpnIt=Zi)}catch(t){}try{typeof $i!=\"undefined\"&&(window.setOpnRb=$i)}catch(t){}try{typeof Ji!=\"undefined\"&&(window.setRnIt=Ji)}catch(t){}try{typeof Qi!=\"undefined\"&&(window.setRnRb=Qi)}catch(t){}try{typeof na!=\"undefined\"&&(window.setShape=na)}catch(t){}try{typeof He!=\"undefined\"&&(window.setSw=He)}catch(t){}try{typeof bi!=\"undefined\"&&(window.setV=bi)}catch(t){}try{typeof Xt!=\"undefined\"&&(window.shadow=Xt)}catch(t){}try{typeof Pn!=\"undefined\"&&(window.showCmt=Pn)}catch(t){}try{typeof se!=\"undefined\"&&(window.snapCfg=se)}catch(t){}try{typeof start!=\"undefined\"&&(window.start=start)}catch(t){}try{typeof Ce!=\"undefined\"&&(window.startIdx=Ce)}catch(t){}try{typeof step!=\"undefined\"&&(window.step=step)}catch(t){}try{typeof M!=\"undefined\"&&(window.store=M)}catch(t){}try{typeof Qt!=\"undefined\"&&(window.storeBig=Qt)}catch(t){}try{typeof z!=\"undefined\"&&(window.strip=z)}catch(t){}try{typeof Xr!=\"undefined\"&&(window.submitCmt=Xr)}catch(t){}try{typeof zr!=\"undefined\"&&(window.submitEdit=zr)}catch(t){}try{typeof pi!=\"undefined\"&&(window.sv=pi)}catch(t){}try{typeof Un!=\"undefined\"&&(window.svx=Un)}catch(t){}try{typeof ie!=\"undefined\"&&(window.syncFlags=ie)}catch(t){}try{typeof dt!=\"undefined\"&&(window.syncStyle=dt)}catch(t){}try{typeof de!=\"undefined\"&&(window.testImg=de)}catch(t){}try{typeof ae!=\"undefined\"&&(window.threadUrl=ae)}catch(t){}try{typeof s!=\"undefined\"&&(window.tip=s)}catch(t){}try{typeof Xe!=\"undefined\"&&(window.toFile=Xe)}catch(t){}try{typeof dr!=\"undefined\"&&(window.toFile2=dr)}catch(t){}try{typeof Ei!=\"undefined\"&&(window.tog=Ei)}catch(t){}try{typeof $r!=\"undefined\"&&(window.togCat=$r)}catch(t){}try{typeof Fi!=\"undefined\"&&(window.trow=Fi)}catch(t){}try{typeof ur!=\"undefined\"&&(window.uiHit=ur)}catch(t){}try{typeof _e!=\"undefined\"&&(window.upd=_e)}catch(t){}try{typeof fi!=\"undefined\"&&(window.updB=fi)}catch(t){}try{typeof ri!=\"undefined\"&&(window.useBG=ri)}catch(t){}try{typeof Ui!=\"undefined\"&&(window.useFabBi=Ui)}catch(t){}\n\n\/* ===== v61 头像框\/背景图 云同步(webnote.cc「按名称」剪贴板) =====\n   读取: POST \/netcut\/note\/info\/  note_name=<名称>\n   保存: POST \/netcut\/note\/save\/  note_name & note_id & note_token & note_content\n   ★ 每次保存都会生成新的 note_id\/token, 追加前必须先 info 取最新 id\/token。\n   ★★ 通道顺序(实测结论, 别再调回去):\n     1) fetch —— 接口校验 TLS 指纹, OkHttp\/Java 原生指纹会被判「服务器负载过高」;\n        而它 CORS 头回声 Origin(Origin:xxx -> ACAO:xxx + ACAC:true), WebView 内 fetch 可用。\n     2) postAwait \/ ajaxAwait(url,{\"method\":\"POST\"...}) \/ java.ajax —— 仅作兜底。\n        注意 ajaxAwait 只收 1 个参数(url), POST 要走 postAwait 或 AnalyzeUrl 的 url,{} 选项串。\n     每条通道都必须返回 JSON 且 status===1 才算成功, 否则换下一条, 并透出服务端 error。 *\/\nvar WNAPI='https:\/\/api-webnote.txttool.cn\/netcut\/note\/';\nvar WNNM={fr:'头像框',bg:'背景图片'};\nfunction wnOk(t){try{var o=JSON.parse(t);return !!(o&&o.status===1&&o.data);}catch(e){return false;}}\nfunction wnErr(t){\n  try{var o=JSON.parse(t);if(o&&o.status!==1)return String(o.error||('status='+o.status));}catch(e){}\n  t=String(t||'');\n  return t?('响应异常: '+t.slice(0,50)):'空响应';\n}\nfunction wnChan(u,body,h){\n  var c=[];\n  \/* 1) 浏览器内核 fetch(推荐通道) *\/\n  c.push(function(){return new Promise(function(res,rej){\n    try{fetch(u,{method:'POST',body:body,headers:h,mode:'cors',credentials:'omit'})\n          .then(function(r){return r.text();})\n          .then(function(t){res(String(t||''));},rej);}\n    catch(e){rej(e);}\n  });});\n  \/* 2) postAwait(url, body, headersJSON) *\/\n  c.push(function(){return Promise.resolve(postAwait(u,body,JSON.stringify(h)))\n    .then(function(a){return String(a==null?'':a);});});\n  \/* 3) ajaxAwait 走 Legado AnalyzeUrl 的 url,{选项} 语法做原生 POST *\/\n  c.push(function(){return Promise.resolve(ajaxAwait(u+','+JSON.stringify({method:'POST',body:body,headers:h})))\n    .then(function(a){return String(a==null?'':a);});});\n  \/* 4) java.ajax(url, 选项JSON) \/ java.ajax(url) 兜底 *\/\n  c.push(function(){return Promise.resolve(java.ajax(u,JSON.stringify({method:'POST',body:body,headers:h})))\n    .then(function(a){return String(a==null?'':a);});});\n  return c;\n}\nfunction wnRun(c,i,last){\n  if(i>=c.length)return Promise.reject(new Error(last||('无可用网络通道')));\n  return Promise.resolve().then(function(){return c[i]();}).then(function(t){\n    t=String(t==null?'':t);\n    if(wnOk(t))return t;\n    return wnRun(c,i+1,wnErr(t));\n  },function(e){\n    var m=(e&&e.message)?String(e.message).slice(0,50):'异常';\n    \/* 通道不可用(java\/postAwait 未定义)时不要覆盖上一次的真实错误(如\"服务器负载过高\") *\/\n    if(last&&\/is not defined|not a function\/.test(m))return wnRun(c,i+1,last);\n    return wnRun(c,i+1,m);\n  });\n}\nfunction wnReq(p,body){\n  var u=WNAPI+p+'\/';\n  var h={'Content-Type':'application\/x-www-form-urlencoded; charset=UTF-8',\n         'X-Requested-With':'XMLHttpRequest',\n         'Accept':'application\/json, text\/javascript, *\/*; q=0.01'};\n  return new Promise(function(res,rej){\n    var done=false,tm=null;\n    try{tm=setTimeout(function(){if(done)return;done=true;rej(new Error('请求超时(20秒)'));},20000);}catch(e){}\n    function fin(f,a){if(done)return;done=true;try{tm&&clearTimeout(tm);}catch(e){}f(a);}\n    wnRun(wnChan(u,body,h),0,'').then(function(t){fin(res,t);},function(e){fin(rej,e);});\n  });\n}\nfunction wnData(txt){\n  var o=null;\n  try{o=JSON.parse(txt);}catch(e){throw new Error('响应不是JSON: '+String(txt||'').slice(0,40));}\n  if(o&&o.status===1&&o.data)return o.data;\n  throw new Error(String((o&&o.error)||('status='+(o&&o.status))));\n}\n\/* note_content 是 JSON 数组字符串: [{\"title\":..,\"content\":..}] -> 拼成纯文本 *\/\nfunction wnText(nc){\n  if(!nc)return '';\n  try{\n    var a=JSON.parse(nc);\n    if(a&&a.length){\n      var s='';\n      for(var i=0;i<a.length;i++)s+=(a[i].title||'')+(a[i].content||'');\n      return s;\n    }\n  }catch(e){}\n  return String(nc);\n}\nfunction wnPack(txt){return JSON.stringify([{title:'',content:txt}]);}\nfunction wnGet(nm){\n  return wnReq('info','note_name='+encodeURIComponent(nm)).then(function(t){\n    return wnData(t);});\n}\nfunction wnPut(nm,id,tk,content){\n  return wnReq('save','note_name='+encodeURIComponent(nm)\n    +'&note_id='+encodeURIComponent(id||'')\n    +'&note_token='+encodeURIComponent(tk||'')\n    +'&note_content='+encodeURIComponent(content)\n    +'&expire_time=2592000').then(function(t){return wnData(t);});\n}\n\/* 保存失败重试: 服务端偶发 {\"status\":2,\"error\":\"业务处理失败\"}(token 刚轮换\/抖动),\n   重取一次最新 id\/token 再写一次 *\/\nfunction wnRetry(nm,txt){\n  return wnGet(nm).then(function(d2){return wnPut(nm,d2.note_id,d2.note_token,wnPack(txt));});\n}\n\/* 正文 -> 图片链接数组: 从任意文本里提取 http(s)\/file 链接(支持紧跟中文无分隔符的情况), 并去重 *\/\nfunction wnUrls(txt){\n  var out=[],seen={};\n  var re=\/(?:https?:\\\/\\\/|file:\\\/\\\/)[^\\s,，;；|、<>\"'）)】\\]。]+\/gi;\n  var m;\n  while((m=re.exec(String(txt||'')))!==null){\n    var u=m[0].replace(\/[,，;；|、.。]+$\/,'');\n    if(!u)continue;\n    if(seen[u])continue;\n    seen[u]=1;out.push(u);\n  }\n  return out;\n}\n\/* 复制文本: execCommand('copy') 优先, navigator.clipboard 兜底 *\/\nfunction cpTxt(t){\n  t=String(t==null?'':t);\n  if(!t)return;\n  try{\n    var ta=document.createElement('textarea');\n    ta.value=t;ta.setAttribute('readonly','');\n    ta.style.position='fixed';ta.style.left='-9999px';ta.style.opacity='0';\n    document.body.appendChild(ta);\n    ta.focus();ta.select();\n    try{ta.setSelectionRange(0,999999);}catch(e){}\n    var ok=false;try{ok=document.execCommand('copy');}catch(e){}\n    try{document.body.removeChild(ta);}catch(e){}\n    if(ok)return;\n  }catch(e){}\n  try{if(navigator.clipboard&&navigator.clipboard.writeText){navigator.clipboard.writeText(t);}}catch(e){}\n}\n\/* ===== v61 预览图「点选中 -> 点复制按钮」 =====\n   长按复制在部分 WebView\/机型上触发不稳定(有时要点一下图片才能长按), 所以改成显式交互:\n   点图片 = 选中(高亮 + 链接填入下方输入框) 并沿用原来的「应用」行为; 点「📋复制链接」= 复制。*\/\nvar PVS={};\nfunction pvCss(){\n  try{\n    if(document.getElementById('x8pk'))return;\n    var st=document.createElement('style');st.id='x8pk';\n    st.textContent='.pw.pick{outline:2px solid #ff9800;outline-offset:1px}'\n      +'.pvwrap.pick{outline:2px solid #ff9800;outline-offset:1px;border-radius:6px}'\n      +'#bgsel,#frsel,#bgsel2,#frsel2{opacity:.9}';\n    (document.head||document.documentElement).appendChild(st);\n  }catch(e){}\n}\nfunction pvBox(el){\n  try{\n    var b=el;\n    while(b&&b!==document){\n      var c=String(b.className||'');\n      if(c.indexOf('pvwrap')>=0||\/(^|\\s)pw(\\s|$)\/.test(c))return b;\n      b=b.parentNode;\n    }\n  }catch(e){}\n  return null;\n}\n\/* 从元素自身读 data-k(避免在内联 onclick 里写单引号把外层 JS 字符串截断) *\/\nfunction pvSelEl(el){\n  var k='';\n  try{k=el.getAttribute('data-k')||'';}catch(e){}\n  pvSel(k||'',el);\n}\nfunction pvSel(kind,el){\n  try{\n    pvCss();\n    var u='';\n    try{u=el.getAttribute('src')||el.src||'';}catch(e){}\n    u=String(u||'').trim();\n    if(u)PVS[kind]=u;\n    var inp=document.getElementById(kind+'sel');\n    if(inp&&u)inp.value=u;\n    try{\n      var all=document.querySelectorAll('.pw.pick,.pvwrap.pick'),i;\n      for(i=0;i<all.length;i++)all[i].className=String(all[i].className).replace(\/\\s*pick\\b\/g,'');\n    }catch(e){}\n    var b=pvBox(el);\n    if(b)b.className=String(b.className||'')+' pick';\n  }catch(e){}\n}\n\/* 返回实际复制的链接; 没选中返回空串 *\/\nfunction pvDo(kind){\n  var u=String(PVS[kind]||'').trim();\n  if(!u){\n    try{var inp=document.getElementById(kind+'sel');u=String((inp&&inp.value)||'').trim();}catch(e){}\n  }\n  if(!u)return '';\n  cpTxt(u);\n  return u;\n}\nvar _lpT=null;\nfunction pvCpImg(img){\n  try{if(img&&img.getAttribute)cpTxt(img.getAttribute('src')||img.src||'');}catch(e){}\n}\n\/* 长按预览图 600ms -> 复制该图链接(保留, 作为复制按钮之外的补充)\n   ★★ 绝对不要在这里 preventDefault(): ontouchstart 里 preventDefault 会让 WebView\n      不再合成 click 事件, 结果就是\"点一下应用\/选中\"彻底失效(首页 fixed13~14 正是踩了这个坑)。 *\/\nvar DBGSX=[\"https:\/\/c-ssl.dtstatic.com\/uploads\/blog\/202406\/08\/GgSbN770Sd4QMWy.thumb.1000_0.png\",\"https:\/\/c-ssl.duitang.com\/uploads\/blog\/202404\/24\/GgSZdaw3CdXwn3X.jpeg\",\"https:\/\/pic1.zhimg.com\/v2-7bad831d3495c510e0949cdaeac23fee_1440w.jpg\",\"https:\/\/picx.zhimg.com\/v2-b27197bcb7d8079c6260542508f14c6f_1440w.jpg\",\"https:\/\/pic1.zhimg.com\/v2-6fc07084f4c4972d8d2873f2023c5172_1440w.jpg\"];\nfunction restoreDef(kind){\n  try{\n    \/* 同时兼容字符串 'bg'\/'fr' 与布尔; 调用点均传 'bg'\/'fr' *\/\n    var isFr=(kind==='fr'||kind===true||kind==='true');\n    \/* 清除被忽略的默认图:\n       首页隐藏列表 KBGH\/KFRH 由 jsave\/pput 管理 -> 用 jsave 清空;\n       详情隐藏列表 _n\/zn 由 g(M\/yt) 管理 -> 用 g 清空;\n       两套存储互不相通, 必须用对机制(此前详情恢复失效的根因) *\/\n    if(typeof jsave==='function'){try{jsave(KBGH,[]);}catch(e){}try{jsave(KFRH,[]);}catch(e){}}\n    if(typeof g==='function'){try{if(typeof _n!=='undefined')g(_n,[]);}catch(e){}try{if(typeof zn!=='undefined')g(zn,[]);}catch(e){}}\n    \/* 背景: 把内置默认图补齐进本地库(首页 BGL \/ 详情 Z) *\/\n    if(!isFr){\n      var defs=(typeof DBGS!=='undefined'&&DBGS)?DBGS.slice():(typeof DBGSX!=='undefined'?DBGSX.slice():[]);\n      var bl=wnList('bg'),kk,xx,jj,hdup;\n      for(kk=0;kk<defs.length;kk++){xx=defs[kk].u||defs[kk];hdup=false;\n        for(jj=0;jj<bl.length;jj++){if(((bl[jj]&&bl[jj].u)||bl[jj])===xx){hdup=true;break;}}\n        if(!hdup)bl.push({u:xx,c:'默认'});}\n      try{g(wnKey('bg'),bl);}catch(e){}\n    }\n    try{if(typeof refreshPanel==='function')refreshPanel();}catch(e){}\n    try{if(typeof A==='function')A();}catch(e){}\n    try{if(typeof s==='function'){s('✔ 已恢复默认'+(isFr?'外框（被忽略的已显示）':'背景图（缺失的已补回）'),'ok');}else if(typeof tip==='function'){tip('✔ 已恢复默认'+(isFr?'外框（被忽略的已显示）':'背景图（缺失的已补回）'),'ok');}}catch(e){}\n  }catch(e){try{if(typeof s==='function')s('✘ 恢复失败：'+(e&&e.message||e),'no');else if(typeof tip==='function')tip('✘ 恢复失败：'+(e&&e.message||e),'no');}catch(_){}}\n}\nfunction pvLP(ev,img){\n  try{_lpT&&clearTimeout(_lpT);}catch(e){}\n  _lpT=setTimeout(function(){_lpT=null;pvCpImg(img);},600);\n}\nfunction pvClr(){try{_lpT&&clearTimeout(_lpT);}catch(e){}_lpT=null;}\n\/* ★ 抗系统深色反色: color-scheme:light only 告知 WebView 本页自带浅色主题,\n   阻止 Android force dark 把黑字反成白字(而底色不变) 造成的「白底白字」。 *\/\n(function(){\n  function addCS(){\n    try{\n      if(document.getElementById('x8cs'))return;\n      var st=document.createElement('style');st.id='x8cs';\n      st.textContent=':root{color-scheme:light only;supported-color-schemes:light only}html{color-scheme:light only}';\n      (document.head||document.documentElement).appendChild(st);\n    }catch(e){}\n  }\n  if(document.readyState==='loading'){\n    try{document.addEventListener('DOMContentLoaded',addCS);}catch(e){setTimeout(addCS,0);}\n  }else addCS();\n})();\n\/* ---- 详情页: 本地库适配 (Z=背景列表, J=外框列表) ---- *\/\nfunction wnList(kind){return kind==='fr'?J:Z;}\nfunction wnKey(kind){return kind==='fr'?At:St;}\nfunction wnUp(kind){\n  var nm=WNNM[kind]||kind,list=wnList(kind),add=[],i;\n  for(i=0;i<list.length;i++){var u=(list[i]&&list[i].u)||list[i];if(u)add.push(u);}\n  if(!add.length){s('✘ 本地还没有保存过'+(kind==='fr'?'头像框':'背景图'),'no');return;}\n  s('正在上传到'+(kind==='fr'?'头像框':'背景图片')+'云…','wait');\n  wnGet(nm).then(function(d){\n    var cur=wnText(d.note_content)||'';\n    var have={};wnUrls(cur).forEach(function(u){have[u]=1;});\n    var neu=[];add.forEach(function(u){if(!have[u]){have[u]=1;neu.push(u);}});\n    if(!neu.length){s('✔ 云端已包含全部本地链接','ok');return null;}\n    var x=cur;\n    if(x&&!\/[,，]$\/.test(x))x+=',';\n    x+=neu.join(',')+',';\n    var okf=function(){s('✔ 已上传 '+neu.length+' 个链接到'+(kind==='fr'?'头像框':'背景图片')+'云','ok');};\n    return wnPut(nm,d.note_id,d.note_token,wnPack(x)).then(okf,function(){return wnRetry(nm,x).then(okf);});\n  })['catch'](function(e){s('✘ 上传失败：'+(e&&e.message?e.message:e),'no');});\n}\nvar HA0=ha.slice(),VA0=va.slice();\nfunction pvApply(el){try{var k=el.dataset.k,u=el.dataset.u;if(k==='bg'){useBG(u);}else{useFrame(u);}}catch(e){}}\nfunction pvDel(el){try{var k=el.dataset.k,u=el.dataset.u;if(el.dataset.def==='1'){delDef(k,u);}else{delPre(k,parseInt(el.dataset.idx));}}catch(e){}}\nfunction pvCopyBtn(el){try{pvCopyD(el.dataset.k);}catch(e){}}\nfunction delDef(t,u){\n  var arr=t===\"bg\"?ha:va,i,b;\n  for(i=0;i<arr.length;i++){b=(arr[i]&&arr[i].u)||arr[i];if(b===u){arr.splice(i,1);break;}}\n  try{A();}catch(e){}\n  s('✔ 已删除该默认'+(t===\"bg\"?'背景图':'外框'),'ok');\n}\nfunction resetDef(t){\n  if(t===\"bg\"){ha=HA0.slice();}else{va=VA0.slice();}\n  try{A();}catch(e){}\n  s('✔ 已恢复默认'+(t===\"bg\"?'背景图':'外框'),'ok');\n}\nfunction wnDown(kind){\n  var nm=WNNM[kind]||kind,list=wnList(kind),defs=(kind==='fr'?va:ha);\n  s('正在从'+(kind==='fr'?'头像框':'背景图片')+'云下载…','wait');\n  return wnGet(nm).then(function(d){\n    var urls=wnUrls(wnText(d.note_content)),added=0,i,j,b;\n    for(i=0;i<urls.length;i++){\n      var u=urls[i];\n      var ex=-1;\n      for(j=0;j<list.length;j++){if(((list[j]&&list[j].u)||list[j])===u){ex=j;break;}}\n      if(ex>=0){continue;} \/* 已在库, 跳过 *\/\n      \/* 已是内置默认图(ha\/va)且预览框已显示, 跳过避免重复 *\/\n      var dupDef=false;\n      for(j=0;j<defs.length;j++){if(((defs[j]&&defs[j].u)||defs[j])===u){dupDef=true;break;}}\n      if(dupDef){continue;}\n      list.push({u:u});added++;\n    }\n    if(added){try{g(wnKey(kind),list);}catch(e){}}\n    try{A();}catch(e){}\n    s(added?('✔ 已新增 '+added+' 个链接'):'✔ 云端的链接本地都有了','ok');\n  })['catch'](function(e){s('✘ 下载失败：'+(e&&e.message?e.message:e),'no');});\n}\n\/* v61: 长按 = 移动到分类(恢复原逻辑); 复制链接改用「点图片选中 -> 📋复制链接 按钮」 *\/\ntry{window.wnUp=wnUp}catch(t){}\ntry{window.wnDown=wnDown}catch(t){}\ntry{window.cpTxt=cpTxt}catch(t){}\n\nfunction pvCopyD(k){var u=pvDo(k);s(u?('✔ 已复制链接: '+u.slice(0,28)+(u.length>28?'…':'')):'✘ 先点一张图片选中',u?'ok':'no');}\ntry{window.pvSel=pvSel}catch(t){}\ntry{window.pvSelEl=pvSelEl}catch(t){}\ntry{window.pvCopyD=pvCopyD}catch(t){}\ntry{window.pvDo=pvDo}catch(t){}\ntry{window.pvApply=pvApply}catch(t){}\ntry{window.pvDel=pvDel}catch(t){}\ntry{window.pvCopyBtn=pvCopyBtn}catch(t){}\ntry{window.delDef=delDef}catch(t){}\ntry{window.resetDef=resetDef}catch(t){}\n\ntry{typeof ni!=\"undefined\"&&(window.useFrame=ni)}catch(t){}try{typeof xy!=\"undefined\"&&(window.xy=xy)}catch(t){}try{typeof ze!=\"undefined\"&&(window.xyMaxX=ze)}catch(t){}try{typeof Ye!=\"undefined\"&&(window.xyMaxY=Ye)}catch(t){}try{typeof Ge!=\"undefined\"&&(window.xyclamp=Ge)}catch(t){}try{typeof yi!=\"undefined\"&&(window.xyrow=yi)}catch(t){}};\n<\/script>\n<style>","type":0}]