+ `)}d(Zl,"injectHealthPanel");function Xl(){let o=$(".side-menu-item").parent();o.length&&!o.find('[data-panel="plugin-mgmt-panel"]').length&&o.append('');let e=$(".content-panel").parent();if(!e.length||$("#plugin-mgmt-panel").length)return;e.append(`
0 总插件数
@@ -3070,7 +3065,7 @@
错误日志 清空日志
无错误记录
缓存命中率
-
`)}d(Zl,"injectPluginMgmtPanel");function Xl(){let o=$(".side-menu-item").parent();o.length&&!o.find('[data-panel="snapshot-panel"]').length&&o.append('');let e=$(".content-panel").parent();if(!e.length||$("#snapshot-panel").length)return;e.append('
创建快照
快照保存当前全部数据状态,可用于恢复。最多保留 10 个,超出自动清理最旧的。
')}d(Xl,"injectSnapshotPanel");function ec(){let o=$(".side-menu-item").parent();o.length&&!o.find('[data-panel="network-panel"]').length&&o.append('');let e=$(".content-panel").parent();if(!e.length||$("#network-panel").length)return;e.append(`
+
`)}d(Xl,"injectPluginMgmtPanel");function ec(){let o=$(".side-menu-item").parent();o.length&&!o.find('[data-panel="snapshot-panel"]').length&&o.append('');let e=$(".content-panel").parent();if(!e.length||$("#snapshot-panel").length)return;e.append('
创建快照
快照保存当前全部数据状态,可用于恢复。最多保留 10 个,超出自动清理最旧的。
')}d(ec,"injectSnapshotPanel");function tc(){let o=$(".side-menu-item").parent();o.length&&!o.find('[data-panel="network-panel"]').length&&o.append('');let e=$(".content-panel").parent();if(!e.length||$("#network-panel").length)return;e.append(`
熔断器配置 连续请求失败达到阈值后,自动停止对该站点的请求,避免拖慢整体体验。
@@ -3078,14 +3073,14 @@
重置全部熔断
站点健康状态 各外部站点的熔断状态和请求统计。
域名使用统计 脚本实际请求过的域名及次数。
清空统计
-
`)}d(ec,"injectNetworkPanel");function tc(){if($("#resource-sources-panel").length)return;$(".content-panel").last().after(`
+
`)}d(tc,"injectNetworkPanel");function sc(){if($("#resource-sources-panel").length)return;$(".content-panel").last().after(`
高级 · 导入 / 导出配置 高级功能:错误修改可能导致自定义来源不可用,保存前会校验配置。
导出资源配置 编辑原始 JSON 校验并导入
-
番号 导入为 请选择 收藏 已下载 已观看 屏蔽 解析预览 确认导入
`),$(".jhs-mobile-sidebar,.setting-sidebar").first().append('')}d(tc,"injectResourceSourcesPanel");function Us(o=void 0,e={}){let t=o?Hl(o,e):null;return`
+
番号 导入为 请选择 收藏 已下载 已观看 屏蔽 解析预览 确认导入
`),$(".jhs-mobile-sidebar,.setting-sidebar").first().append('')}d(sc,"injectResourceSourcesPanel");function zs(o=void 0,e={}){let t=o?Hl(o,e):null;return`
`}d(Us,"buildQuickSettingHtml");async function Et(o){let e=o.getNetworkDiagnostics(),t=e.circuitBreakers,s=e.domainStats,a=await storageManager.getSetting("circuitBreakerThreshold",3),r=await storageManager.getSetting("circuitBreakerCooldown",6e4);$("#circuitBreakerThreshold").each(((l,c)=>{c.dataset.jhsHydrated||(c.value=String(a),c.dataset.jhsHydrated="1")})),$("#circuitBreakerCooldownSec").each(((l,c)=>{c.dataset.jhsHydrated||(c.value=String(Math.round(r/1e3)),c.dataset.jhsHydrated="1")}));let i=Object.entries(t);if(i.length){let l='
域名 状态 失败次数 操作 ';for(let[c,h]of i){let u=h.state==="open"?"熔断":h.state==="half-open"?"半开":"正常",p=h.state==="open"?`剩余${Math.ceil((Number(h.cooldownMs)-(Date.now()-Number(h.openTime)))/1e3)}秒`:"";l+=`${C(c)} ${u} ${p} ${Number(h.failCount)||0} 重置 `}l+="
",$("#site-health-table").html(l)}else $("#site-health-table").html('
暂无熔断记录
');let n=Object.entries(s).sort(((l,c)=>c[1].count-l[1].count));if(n.length){let l='
域名 请求数 错误数 最后使用 ';for(let[c,h]of n){let u=h.lastUsed?new Date(h.lastUsed).toLocaleTimeString():"-";l+=`${C(c)} ${h.count} ${h.errors} ${u} `}l+="
",l+=`
共 ${n.length} 个域名
`,$("#domain-stats-table").html(l)}else $("#domain-stats-table").html('
暂无统计数据
');$(".reset-breaker").off("click").on("click",(l=>{let c=$(l.target).data("domain");o.resetCircuitBreaker(c),show.ok(`已重置 ${c} 的熔断状态`),Et(o)})),$("#resetAllBreakersBtn").off("click").on("click",(()=>{o.resetAllCircuitBreakers(),show.ok("已重置全部熔断状态"),Et(o)})),$("#clearDomainStatsBtn").off("click").on("click",(()=>{o.clearDomainStats(),show.ok("已清空域名统计"),Et(o)}))}d(Et,"renderNetworkPanel");async function as(){let o=await storageManager.getSnapshotList(),e={manual:"手动创建","auto-import":"导入前自动","auto-repair":"修复前自动","auto-restore":"恢复前自动"};if(o.length===0)return void $("#snapshot-list").html('
暂无快照,点击上方按钮创建
');$("#snapshot-list").find(".tabulator").length&&$("#snapshot-list").empty();let t=ze(globalThis.Tabulator,"#snapshot-list",{pagination:!1,layout:"fitColumns",placeholder:"暂无数据",data:o,columnDefaults:{headerHozAlign:"center",hozAlign:"center"},columns:[{title:"名称",field:"name",width:200,headerSort:!1},{title:"来源",field:"source",width:100,headerSort:!1,formatter:d(s=>e[s.getValue()]||s.getValue(),"formatter")},{title:"时间",field:"time",width:170,headerSort:!1},{title:"数据量",field:"itemCount",width:80,headerSort:!1},{title:"操作",minWidth:220,headerSort:!1,formatter:d((s,a,r)=>{let i=s.getData();return r((()=>{let n=s.getElement().querySelector(".snap-restore"),l=s.getElement().querySelector(".snap-download"),c=s.getElement().querySelector(".snap-delete");n&&n.addEventListener("click",(async h=>{utils.q(h,`恢复到快照「${C(i.name)}」? 当前数据会自动备份。`,(async()=>{let u=loading();try{await storageManager.restoreSnapshot(i.id),show.ok("恢复成功, 页面将刷新"),setTimeout(()=>location.reload(),1e3)}catch(p){clog.error(p),show.error("恢复失败: "+(p instanceof Error?p.message:String(p)))}finally{u.close()}}))})),l&&l.addEventListener("click",(async h=>{let u=loading();try{let p=await storageManager.getSnapshot(i.id);if(!p)throw new Error("快照不存在");utils.download(JSON.stringify(p.data),`snapshot_${String(i.name||"snapshot").replace(/[\\/:*?"<>|]/g,"_")}.json`),show.ok("下载成功")}catch(p){show.error("下载失败: "+(p instanceof Error?p.message:String(p)))}finally{u.close()}})),c&&c.addEventListener("click",(async h=>{utils.q(h,`删除快照「${C(i.name)}」?`,(async()=>{try{await storageManager.deleteSnapshot(i.id),show.ok("已删除"),as()}catch(u){clog.error(u),show.error("删除失败: "+(u instanceof Error?u.message:String(u)))}}))}))})),'
恢复 下载 删除 '},"formatter")}]})}d(as,"renderSnapshotPanel");function sc(o,e,t=null,s){let a=o.summary,r=[];for(let[c,h]of Object.entries(o.stores)){if(h.status==="unchanged")continue;let u={store:c,status:h.status,oldCount:h.oldCount,newCount:h.newCount,added:h.added.length,removed:h.removed.length,modified:h.modified.length};r.push(u)}let i='
';if(i+='
',i+=`
${a.added} 新增数据源
`,i+=`
${a.removed} 缺失数据源
`,i+=`
${a.modified} 有变更
`,i+=`
${a.unchanged} 无变化
`,i+="
",r.length>0){i+='
"}else i+='
数据完全一致,无需导入
';i+='
导入将覆盖当前数据,建议先创建快照备份
',i+="
";let n=r.length>0,l=s.open({type:1,title:"数据差异预览",content:i,area:utils.getResponsiveArea(["700px","auto"]),btn:n?["确认导入","取消"]:["知道了","取消"],anim:-1,yes:d(async c=>{if(!n)return void s.close(c);let h=loading();try{await storageManager.createSnapshot("导入前自动备份","auto-import"),t?(await storageManager.importData(t),show.ok("导入成功!"),setTimeout(()=>location.reload(),1e3)):e&&(await storageManager.importData(e),show.ok("导入成功!"),setTimeout(()=>location.reload(),1e3))}catch(u){clog.error(u),show.error("导入失败: "+(u instanceof Error?u.message:String(u)))}finally{h.close()}},"yes")})}d(sc,"showDiffPreview");async function _i(o,e=null){let t=o.exportSnapshot(),s=Ge(await storageManager.getSetting("disabledPlugins","[]")),a=t.legacyPlugins,r=d(S=>{let j=new Set(S);return a.filter((x=>j.has(x)||j.has(Tt(x))))},"effectiveDisabledNames"),{categories:i,pluginMeta:n}=Gl(),l=new Map((t.legacyPluginDescriptors||[]).map(S=>[S.name,S])),c=new Set(a),h="";for(let[S,j]of Object.entries(i)){let x=j.plugins.filter(k=>c.has(k));if(x.length){h+='
"}}$("#plugin-mgmt-list").html(h);let u=r(s),p=a.length-u.length;$("#pm-total").text(a.length),$("#pm-enabled").text(p),$("#pm-disabled").text(u.length),$(".pm-toggle").off("change").on("change",async S=>{let j=$(S.target),x=j.data("plugin"),k=j.is(":checked"),_=!k,E=Ge(await storageManager.getSetting("disabledPlugins","[]")),L=Tt(x);if(k?E=E.filter(A=>A!==x&&A!==L):E.includes(L)||E.push(L),!e)throw new Error("SettingsService is unavailable");let N=d(A=>{let O=t.legacyPlugins,U=r(A);$("#pm-total").text(O.length),$("#pm-enabled").text(O.length-U.length),$("#pm-disabled").text(U.length)},"renderState");N(E);try{await e.set("disabledPlugins",JSON.stringify(E)),show.ok(`插件 "${x}" 已${k?"启用":"禁用"},刷新后生效`)}catch(A){j.prop("checked",_);let O=Ge(await storageManager.getSetting("disabledPlugins","[]"));N(O),clog.error("插件状态保存失败,已恢复",A),show.error(`插件 "${x}" 状态保存失败,已恢复`)}});let g=t.legacyStartup,m=t.legacyTimings,f=d(S=>Number.isFinite(S)?S.toFixed(1):"0.0","formatMs"),v=g?`
就绪: ${f(g.readyMs)} ms 注册: ${f(g.registrationMs)} ms 样式: ${f(g.cssMs)} ms 即时插件: ${f(g.immediateMs)} ms 空闲任务: ${g.idleCompleted}/${g.idleCompleted+g.idlePending}
就绪耗时不包含 @require 下载及浏览器脚本解析时间。
`:"";if(m.length){let S=[...m].sort(((x,k)=>k.elapsed-x.elapsed)),j='
插件 阶段 耗时(ms) 状态 ';for(let x of S){let k=x.status==="disabled"?"is-muted":x.elapsed>500?"is-slow":x.elapsed>200?"is-warning":"",_=x.status==="disabled"?"已禁用":x.status==="error"?"错误":x.status==="pending-idle"?"等待空闲":x.status==="skipped-mobile"?"移动端跳过":"正常";j+=`${C(x.name)} ${x.startupMode==="idle"?"空闲":"即时"} ${x.elapsed.toFixed(1)} ${_} `}j+="
",$("#plugin-timing-table").html(v+j)}else $("#plugin-timing-table").html(v+'
暂无数据,刷新页面后自动采集。
');let b=t.errors.filter(S=>S.source==="legacy-plugin");if(b.length){let S='
时间 插件 阶段 错误信息 ';for(let j of[...b].reverse())S+=`${C(String(j.timestamp||"").substring(11,19))} ${C(j.plugin)} ${C(j.phase)} ${C(j.message)} `;S+="
",$("#plugin-error-log").html(S)}else $("#plugin-error-log").text("无错误记录");let w=storageManager.getCacheHitStats();$("#cache-hit-stats").html(`
命中: ${w.hits} 未命中: ${w.misses} 总计: ${w.total} 命中率: ${w.rate}
`)}d(_i,"renderPluginMgmtPanel");async function rs(){let o=$("#health-data-display");if(o.length){o.text("体检中...");try{let e=await storageManager.inspectDataHealth(),t=e.fixable.reduce(((r,i)=>r+i.count),0),s=e.readonly.reduce(((r,i)=>r+i.count),0),a=d(r=>r.length?r.map((i=>`
${C(i.message)} :${i.count}`)).join(""):"
无 ","i");o.html(`
+
`}d(zs,"buildQuickSettingHtml");async function Dt(o){let e=o.getNetworkDiagnostics(),t=e.circuitBreakers,s=e.domainStats,a=await storageManager.getSetting("circuitBreakerThreshold",3),r=await storageManager.getSetting("circuitBreakerCooldown",6e4);$("#circuitBreakerThreshold").each(((l,c)=>{c.dataset.jhsHydrated||(c.value=String(a),c.dataset.jhsHydrated="1")})),$("#circuitBreakerCooldownSec").each(((l,c)=>{c.dataset.jhsHydrated||(c.value=String(Math.round(r/1e3)),c.dataset.jhsHydrated="1")}));let i=Object.entries(t);if(i.length){let l='
域名 状态 失败次数 操作 ';for(let[c,h]of i){let u=h.state==="open"?"熔断":h.state==="half-open"?"半开":"正常",p=h.state==="open"?`剩余${Math.ceil((Number(h.cooldownMs)-(Date.now()-Number(h.openTime)))/1e3)}秒`:"";l+=`${T(c)} ${u} ${p} ${Number(h.failCount)||0} 重置 `}l+="
",$("#site-health-table").html(l)}else $("#site-health-table").html('
暂无熔断记录
');let n=Object.entries(s).sort(((l,c)=>c[1].count-l[1].count));if(n.length){let l='
域名 请求数 错误数 最后使用 ';for(let[c,h]of n){let u=h.lastUsed?new Date(h.lastUsed).toLocaleTimeString():"-";l+=`${T(c)} ${h.count} ${h.errors} ${u} `}l+="
",l+=`
共 ${n.length} 个域名
`,$("#domain-stats-table").html(l)}else $("#domain-stats-table").html('
暂无统计数据
');$(".reset-breaker").off("click").on("click",(l=>{let c=$(l.target).data("domain");o.resetCircuitBreaker(c),show.ok(`已重置 ${c} 的熔断状态`),Dt(o)})),$("#resetAllBreakersBtn").off("click").on("click",(()=>{o.resetAllCircuitBreakers(),show.ok("已重置全部熔断状态"),Dt(o)})),$("#clearDomainStatsBtn").off("click").on("click",(()=>{o.clearDomainStats(),show.ok("已清空域名统计"),Dt(o)}))}d(Dt,"renderNetworkPanel");async function as(){let o=await storageManager.getSnapshotList(),e={manual:"手动创建","auto-import":"导入前自动","auto-repair":"修复前自动","auto-restore":"恢复前自动"};if(o.length===0)return void $("#snapshot-list").html('
暂无快照,点击上方按钮创建
');$("#snapshot-list").find(".tabulator").length&&$("#snapshot-list").empty();let t=ze(globalThis.Tabulator,"#snapshot-list",{pagination:!1,layout:"fitColumns",placeholder:"暂无数据",data:o,columnDefaults:{headerHozAlign:"center",hozAlign:"center"},columns:[{title:"名称",field:"name",width:200,headerSort:!1},{title:"来源",field:"source",width:100,headerSort:!1,formatter:d(s=>e[s.getValue()]||s.getValue(),"formatter")},{title:"时间",field:"time",width:170,headerSort:!1},{title:"数据量",field:"itemCount",width:80,headerSort:!1},{title:"操作",minWidth:220,headerSort:!1,formatter:d((s,a,r)=>{let i=s.getData();return r((()=>{let n=s.getElement().querySelector(".snap-restore"),l=s.getElement().querySelector(".snap-download"),c=s.getElement().querySelector(".snap-delete");n&&n.addEventListener("click",(async h=>{utils.q(h,`恢复到快照「${T(i.name)}」? 当前数据会自动备份。`,(async()=>{let u=loading();try{await storageManager.restoreSnapshot(i.id),show.ok("恢复成功, 页面将刷新"),setTimeout(()=>location.reload(),1e3)}catch(p){clog.error(p),show.error("恢复失败: "+(p instanceof Error?p.message:String(p)))}finally{u.close()}}))})),l&&l.addEventListener("click",(async h=>{let u=loading();try{let p=await storageManager.getSnapshot(i.id);if(!p)throw new Error("快照不存在");utils.download(JSON.stringify(p.data),`snapshot_${String(i.name||"snapshot").replace(/[\\/:*?"<>|]/g,"_")}.json`),show.ok("下载成功")}catch(p){show.error("下载失败: "+(p instanceof Error?p.message:String(p)))}finally{u.close()}})),c&&c.addEventListener("click",(async h=>{utils.q(h,`删除快照「${T(i.name)}」?`,(async()=>{try{await storageManager.deleteSnapshot(i.id),show.ok("已删除"),as()}catch(u){clog.error(u),show.error("删除失败: "+(u instanceof Error?u.message:String(u)))}}))}))})),'
恢复 下载 删除 '},"formatter")}]})}d(as,"renderSnapshotPanel");function ac(o,e,t=null,s){let a=o.summary,r=[];for(let[c,h]of Object.entries(o.stores)){if(h.status==="unchanged")continue;let u={store:c,status:h.status,oldCount:h.oldCount,newCount:h.newCount,added:h.added.length,removed:h.removed.length,modified:h.modified.length};r.push(u)}let i='
';if(i+='
',i+=`
${a.added} 新增数据源
`,i+=`
${a.removed} 缺失数据源
`,i+=`
${a.modified} 有变更
`,i+=`
${a.unchanged} 无变化
`,i+="
",r.length>0){i+='
"}else i+='
数据完全一致,无需导入
';i+='
导入将覆盖当前数据,建议先创建快照备份
',i+="
";let n=r.length>0,l=s.open({type:1,title:"数据差异预览",content:i,area:utils.getResponsiveArea(["700px","auto"]),btn:n?["确认导入","取消"]:["知道了","取消"],anim:-1,yes:d(async c=>{if(!n)return void s.close(c);let h=loading();try{await storageManager.createSnapshot("导入前自动备份","auto-import"),t?(await storageManager.importData(t),show.ok("导入成功!"),setTimeout(()=>location.reload(),1e3)):e&&(await storageManager.importData(e),show.ok("导入成功!"),setTimeout(()=>location.reload(),1e3))}catch(u){clog.error(u),show.error("导入失败: "+(u instanceof Error?u.message:String(u)))}finally{h.close()}},"yes")})}d(ac,"showDiffPreview");async function $i(o,e=null){let t=o.exportSnapshot(),s=Ge(await storageManager.getSetting("disabledPlugins","[]")),a=t.legacyPlugins,r=d(S=>{let j=new Set(S);return a.filter((k=>j.has(k)||j.has(Tt(k))))},"effectiveDisabledNames"),{categories:i,pluginMeta:n}=Ql(),l=new Map((t.legacyPluginDescriptors||[]).map(S=>[S.name,S])),c=new Set(a),h="";for(let[S,j]of Object.entries(i)){let k=j.plugins.filter(x=>c.has(x));if(k.length){h+='
"}}$("#plugin-mgmt-list").html(h);let u=r(s),p=a.length-u.length;$("#pm-total").text(a.length),$("#pm-enabled").text(p),$("#pm-disabled").text(u.length),$(".pm-toggle").off("change").on("change",async S=>{let j=$(S.target),k=j.data("plugin"),x=j.is(":checked"),_=!x,R=Ge(await storageManager.getSetting("disabledPlugins","[]")),L=Tt(k);if(x?R=R.filter(A=>A!==k&&A!==L):R.includes(L)||R.push(L),!e)throw new Error("SettingsService is unavailable");let N=d(A=>{let O=t.legacyPlugins,U=r(A);$("#pm-total").text(O.length),$("#pm-enabled").text(O.length-U.length),$("#pm-disabled").text(U.length)},"renderState");N(R);try{await e.set("disabledPlugins",JSON.stringify(R)),show.ok(`插件 "${k}" 已${x?"启用":"禁用"},刷新后生效`)}catch(A){j.prop("checked",_);let O=Ge(await storageManager.getSetting("disabledPlugins","[]"));N(O),clog.error("插件状态保存失败,已恢复",A),show.error(`插件 "${k}" 状态保存失败,已恢复`)}});let g=t.legacyStartup,m=t.legacyTimings,f=d(S=>Number.isFinite(S)?S.toFixed(1):"0.0","formatMs"),v=g?`
就绪: ${f(g.readyMs)} ms 注册: ${f(g.registrationMs)} ms 样式: ${f(g.cssMs)} ms 即时插件: ${f(g.immediateMs)} ms 空闲任务: ${g.idleCompleted}/${g.idleCompleted+g.idlePending}
就绪耗时不包含 @require 下载及浏览器脚本解析时间。
`:"";if(m.length){let S=[...m].sort(((k,x)=>x.elapsed-k.elapsed)),j='
插件 阶段 耗时(ms) 状态 ';for(let k of S){let x=k.status==="disabled"?"is-muted":k.elapsed>500?"is-slow":k.elapsed>200?"is-warning":"",_=k.status==="disabled"?"已禁用":k.status==="error"?"错误":k.status==="pending-idle"?"等待空闲":k.status==="skipped-mobile"?"移动端跳过":"正常";j+=`${T(k.name)} ${k.startupMode==="idle"?"空闲":"即时"} ${k.elapsed.toFixed(1)} ${_} `}j+="
",$("#plugin-timing-table").html(v+j)}else $("#plugin-timing-table").html(v+'
暂无数据,刷新页面后自动采集。
');let b=t.errors.filter(S=>S.source==="legacy-plugin");if(b.length){let S='
时间 插件 阶段 错误信息 ';for(let j of[...b].reverse())S+=`${T(String(j.timestamp||"").substring(11,19))} ${T(j.plugin)} ${T(j.phase)} ${T(j.message)} `;S+="
",$("#plugin-error-log").html(S)}else $("#plugin-error-log").text("无错误记录");let w=storageManager.getCacheHitStats();$("#cache-hit-stats").html(`
命中: ${w.hits} 未命中: ${w.misses} 总计: ${w.total} 命中率: ${w.rate}
`)}d($i,"renderPluginMgmtPanel");async function rs(){let o=$("#health-data-display");if(o.length){o.text("体检中...");try{let e=await storageManager.inspectDataHealth(),t=e.fixable.reduce(((r,i)=>r+i.count),0),s=e.readonly.reduce(((r,i)=>r+i.count),0),a=d(r=>r.length?r.map((i=>`
${T(i.message)} :${i.count}`)).join(""):"
无 ","i");o.html(`
番号记录:${e.totals.carList}
收藏演员:${e.totals.favoriteActresses}
黑名单演员:${e.totals.blacklist}
黑名单作品:${e.totals.blacklistCarList}
-
体检时间:${C(e.checkedAt)};可修复问题 ${t} 项,只读问题 ${s} 项。
+
体检时间:${T(e.checkedAt)};可修复问题 ${t} 项,只读问题 ${s} 项。
- `)}catch(e){clog.error(e),o.text("体检失败: "+e)}}}d(rs,"renderDataHealthPanel");async function ac(){let o=JSON.stringify(await storageManager.exportData()),e=`health-backup-${utils.getNowStr("_","_")}.json`;utils.download(o,e);let t=await storageManager.repairDataHealth();show.ok(`已修复 ${t.fixedGroups} 组数据问题,修复前备份已下载`),await rs()}d(ac,"repairDataHealthWithBackup");var $i=class $i extends I{constructor(){super(...arguments),P(this,"folderName","JHS-数据备份"),P(this,"resourceSettings",new nt),P(this,"pendingCarImport",null),P(this,"taskStatusUnsubscribe",null),P(this,"_desktopSettingNavMounted",!1),P(this,"_settingScope",null),P(this,"_settingNavResizeCleanup",null),P(this,"_desktopNavGeneration",0),P(this,"_settingsDialogGeneration",0),P(this,"_fullSettingBinding",null),P(this,"_cloudSettingBinding",null),P(this,"cacheItems",[{key:"jhs_dmm_video",text:"预览视频缓存",title:"预览视频缓存"},{key:"jhs_other_site",text:"第三方站点缓存",title:"第三方站点资源检测结果, 如missav,123Av等"},{key:"jhs_screenShot",text:"缩略图缓存",title:"缩略图缓存"},{key:"jhs_translate",text:"标题翻译",title:"标题翻译"},{key:"jhs_actress_info",text:"演员信息",title:"演员的年龄三围等数据信息"},{key:"jhs_score_info",text:"Top250|热播 评分数据",title:"Top250及热播的评分数据"},{key:"third_party_ttl_cache",text:"第三方TTL缓存",title:"评论、相关清单、磁力搜索、缩略图等请求缓存"},{key:"_circuitBreaker",text:"熔断状态",title:"各站点的熔断计数和状态"},{key:"_domainStats",text:"域名请求统计",title:"各域名的请求次数和错误统计"}])}getName(){return"SettingPlugin"}getFormDependencies(){return Object.freeze({otherSite:this.getOptionalDependency("OtherSitePlugin"),listPage:this.getOptionalDependency("ListPagePlugin"),translate:this.getOptionalDependency("TranslatePlugin"),actressInfo:this.getOptionalDependency("ActressInfoPlugin"),screenshot:this.getOptionalDependency("ScreenShotPlugin"),newVideo:this.getOptionalDependency("NewVideoPlugin"),blacklist:this.getOptionalDependency("BlacklistPlugin"),busImg:this.getOptionalDependency("BusImgPlugin"),host:this.getRuntimeService("host"),movie:this.getRuntimeService("movie"),settings:this.getRuntimeService("settings"),settingsRegistry:this.getRuntimeService("settingsRegistry"),webdav:this.getRuntimeService("webdav")})}async initCss(){let e=this.getRuntimeService("settings").snapshot(),t=e?.containerWidth??"100";utils.isMobileMode()&&(t="100");let s=utils.isMobileMode()?1:e?.containerColumns??5;return fi(e,{busImgPlugin:this.getOptionalDependency("BusImgPlugin"),hostAdapter:this.getRuntimeService("host")}).catch((a=>clog.error("[JHS] applyLayoutFromSettings failed:",a))),zl(t,s,B,M)}async handle(){let e=this.getRuntimeService("settings");this.resourceSettings=new nt({getSetting:d(async(i=null,n)=>i===null?e.snapshot():Object.prototype.hasOwnProperty.call(e.snapshot(),i)?e.snapshot()[i]:n,"getSetting"),saveSettingItem:d((i,n)=>e.set(i,n),"saveSettingItem"),updateSetting:d(i=>e.update(i),"updateSetting"),patch:d(i=>e.patch(i),"patch")}),await storageManager.getSetting("enableClog",R)===R&&clog.show();let t=await this.getRuntimeService("scope")();this._settingScope=t;let s=this.getRuntimeService("settings"),a=d(i=>{let n=i.detail?.names||[];n.length&&(n.includes("themeMode")&&Ht(s.snapshot().themeMode),n.includes("enableClog")&&(s.snapshot().enableClog==="yes"?clog.show():clog.hide()),n.some(l=>["mobileMode","enableVerticalModel","containerColumns","containerWidth"].includes(l))&&fi(s.snapshot(),{busImgPlugin:this.getOptionalDependency("BusImgPlugin"),hostAdapter:this.getRuntimeService("host")}).catch(l=>clog.error("布局设置应用失败",l)))},"onSettingsChanged");s.addEventListener("settings.changed",a),t.addCleanup((()=>s.removeEventListener("settings.changed",a)));let r=d(async(i="backup-panel")=>{try{return await this.openSettingDialog(i)}catch(n){throw clog.error("设置中心打开失败",n),show.error("设置中心打开失败"),n}},"openSettings");t.addCleanup(gl(r)),t.listen(document,"click",(i=>{i.target instanceof Element&&i.target.closest("#setting-btn, #mini-setting-btn")&&(i.preventDefault(),$(".simple-setting, .mini-simple-setting").each((l,c)=>et(c)),clog.lowZIndex(),r().catch((()=>{})))})),t.addCleanup((()=>this.unmountDesktopSettingNav())),this.syncDesktopSettingNav(this.getRuntimeService("profile").current()==="compact")}syncDesktopSettingNav(e){e?this.unmountDesktopSettingNav():this.mountDesktopSettingNav()}mountDesktopSettingNav(){if(this._desktopSettingNavMounted)return;let e=this._settingScope;if(!e)return;this._desktopSettingNavMounted=!0;let t=this._desktopNavGeneration;if(M){let s=d(function(){$(".navbar-search").is(":hidden")?($(".mini-setting-box").hide(),$(".setting-box").show()):($(".mini-setting-box").show(),$(".setting-box").hide())},"e");$("#navbar-menu-user .navbar-end").prepend(`
+ `)}catch(e){clog.error(e),o.text("体检失败: "+e)}}}d(rs,"renderDataHealthPanel");async function rc(){let o=JSON.stringify(await storageManager.exportData()),e=`health-backup-${utils.getNowStr("_","_")}.json`;utils.download(o,e);let t=await storageManager.repairDataHealth();show.ok(`已修复 ${t.fixedGroups} 组数据问题,修复前备份已下载`),await rs()}d(rc,"repairDataHealthWithBackup");var Ti=class Ti extends I{constructor(){super(...arguments),P(this,"folderName","JHS-数据备份"),P(this,"resourceSettings",new ot),P(this,"pendingCarImport",null),P(this,"taskStatusUnsubscribe",null),P(this,"_desktopSettingNavMounted",!1),P(this,"_settingScope",null),P(this,"_settingNavResizeCleanup",null),P(this,"_desktopNavGeneration",0),P(this,"_settingsDialogGeneration",0),P(this,"_fullSettingBinding",null),P(this,"_cloudSettingBinding",null),P(this,"cacheItems",[{key:"jhs_dmm_video",text:"预览视频缓存",title:"预览视频缓存"},{key:"jhs_other_site",text:"第三方站点缓存",title:"第三方站点资源检测结果, 如missav,123Av等"},{key:"jhs_screenShot",text:"缩略图缓存",title:"缩略图缓存"},{key:"jhs_translate",text:"标题翻译",title:"标题翻译"},{key:"jhs_actress_info",text:"演员信息",title:"演员的年龄三围等数据信息"},{key:"jhs_score_info",text:"Top250|热播 评分数据",title:"Top250及热播的评分数据"},{key:"third_party_ttl_cache",text:"第三方TTL缓存",title:"评论、相关清单、磁力搜索、缩略图等请求缓存"},{key:"_circuitBreaker",text:"熔断状态",title:"各站点的熔断计数和状态"},{key:"_domainStats",text:"域名请求统计",title:"各域名的请求次数和错误统计"}])}getName(){return"SettingPlugin"}getFormDependencies(){return Object.freeze({otherSite:this.getOptionalDependency("OtherSitePlugin"),listPage:this.getOptionalDependency("ListPagePlugin"),translate:this.getOptionalDependency("TranslatePlugin"),actressInfo:this.getOptionalDependency("ActressInfoPlugin"),screenshot:this.getOptionalDependency("ScreenShotPlugin"),newVideo:this.getOptionalDependency("NewVideoPlugin"),blacklist:this.getOptionalDependency("BlacklistPlugin"),busImg:this.getOptionalDependency("BusImgPlugin"),host:this.getRuntimeService("host"),movie:this.getRuntimeService("movie"),settings:this.getRuntimeService("settings"),settingsRegistry:this.getRuntimeService("settingsRegistry"),webdav:this.getRuntimeService("webdav")})}async initCss(){let e=this.getRuntimeService("settings").snapshot(),t=e?.containerWidth??"100";utils.isMobileMode()&&(t="100");let s=utils.isMobileMode()?1:e?.containerColumns??5;return vi(e,{busImgPlugin:this.getOptionalDependency("BusImgPlugin"),hostAdapter:this.getRuntimeService("host")}).catch((a=>clog.error("[JHS] applyLayoutFromSettings failed:",a))),Fl(t,s,B,M)}async handle(){let e=this.getRuntimeService("settings");this.resourceSettings=new ot({getSetting:d(async(i=null,n)=>i===null?e.snapshot():Object.prototype.hasOwnProperty.call(e.snapshot(),i)?e.snapshot()[i]:n,"getSetting"),saveSettingItem:d((i,n)=>e.set(i,n),"saveSettingItem"),updateSetting:d(i=>e.update(i),"updateSetting"),patch:d(i=>e.patch(i),"patch")}),await storageManager.getSetting("enableClog",E)===E&&clog.show();let t=await this.getRuntimeService("scope")();this._settingScope=t;let s=this.getRuntimeService("settings"),a=d(i=>{let n=i.detail?.names||[];n.length&&(n.includes("themeMode")&&Ht(s.snapshot().themeMode),n.includes("enableClog")&&(s.snapshot().enableClog==="yes"?clog.show():clog.hide()),n.some(l=>["mobileMode","enableVerticalModel","containerColumns","containerWidth"].includes(l))&&vi(s.snapshot(),{busImgPlugin:this.getOptionalDependency("BusImgPlugin"),hostAdapter:this.getRuntimeService("host")}).catch(l=>clog.error("布局设置应用失败",l)))},"onSettingsChanged");s.addEventListener("settings.changed",a),t.addCleanup((()=>s.removeEventListener("settings.changed",a)));let r=d(async(i="backup-panel")=>{try{return await this.openSettingDialog(i)}catch(n){throw clog.error("设置中心打开失败",n),show.error("设置中心打开失败"),n}},"openSettings");t.addCleanup(ml(r)),t.listen(document,"click",(i=>{i.target instanceof Element&&i.target.closest("#setting-btn, #mini-setting-btn")&&(i.preventDefault(),$(".simple-setting, .mini-simple-setting").each((l,c)=>et(c)),clog.lowZIndex(),r().catch((()=>{})))})),t.addCleanup((()=>this.unmountDesktopSettingNav())),this.syncDesktopSettingNav(this.getRuntimeService("profile").current()==="compact")}syncDesktopSettingNav(e){e?this.unmountDesktopSettingNav():this.mountDesktopSettingNav()}mountDesktopSettingNav(){if(this._desktopSettingNavMounted)return;let e=this._settingScope;if(!e)return;this._desktopSettingNavMounted=!0;let t=this._desktopNavGeneration;if(M){let s=d(function(){$(".navbar-search").is(":hidden")?($(".mini-setting-box").hide(),$(".setting-box").show()):($(".mini-setting-box").show(),$(".setting-box").hide())},"e");$("#navbar-menu-user .navbar-end").prepend(`
设置
@@ -3137,15 +3132,15 @@
- `)}),1,1e4,!1,e)),$(".main-nav, .container-fluid").off("mouseenter.jhsSettingQuick mouseleave.jhsSettingQuick").on("mouseenter.jhsSettingQuick",".setting-box",(async s=>{let a=$(s.currentTarget).find(".simple-setting");et(a),a.html(Us(this.getRuntimeService("settingsRegistry"))).show();try{await Os(this.getFormDependencies(),this.getSelector.bind(this),this.openSettingDialog.bind(this),a)}catch(r){clog.warn("桌面快捷设置初始化失败",r)}clog.lowZIndex()})).on("mouseleave.jhsSettingQuick",".setting-box",(s=>{et($(s.currentTarget).find(".simple-setting"))})).on("mouseenter.jhsSettingQuick",".mini-setting-box",(async s=>{let a=$(s.currentTarget).find(".mini-simple-setting");et(a),a.html(Us(this.getRuntimeService("settingsRegistry"))).show();try{await Os(this.getFormDependencies(),this.getSelector.bind(this),this.openSettingDialog.bind(this),a)}catch(r){clog.warn("迷你快捷设置初始化失败",r)}clog.lowZIndex()})).on("mouseleave.jhsSettingQuick",".mini-setting-box",(s=>{et($(s.currentTarget).find(".mini-simple-setting"))}))}unmountDesktopSettingNav(){this._desktopNavGeneration++,this._desktopSettingNavMounted=!1,this._settingNavResizeCleanup?.(),this._settingNavResizeCleanup=null,$(".simple-setting, .mini-simple-setting").each((e,t)=>et(t)),$(".jhs-setting-nav-item, .jhs-mini-setting-box, .jhs-setting-anchor, .jhs-setting-detail-anchor").remove(),$(".main-nav, .container-fluid").off("mouseenter.jhsSettingQuick mouseleave.jhsSettingQuick")}async openQuickSetting(){$("#jhs-quick-setting-backdrop, #jhs-quick-setting-sheet").remove();let e=document.activeElement;await this.getRuntimeService("settings").waitForIdle();let t=!1,s=d((n=!0)=>{if(t)return;t=!0,$(document).off("keydown.jhsQuickSetting");let l=$("#jhs-quick-setting-sheet .jhs-quick-setting");et(l),$("#jhs-quick-setting-backdrop, #jhs-quick-setting-sheet").remove(),n&&e?.isConnected&&typeof e.focus=="function"&&e.focus()},"closeQuickSetting"),a=$('
'),r=$(`
+ `)}),1,1e4,!1,e)),$(".main-nav, .container-fluid").off("mouseenter.jhsSettingQuick mouseleave.jhsSettingQuick").on("mouseenter.jhsSettingQuick",".setting-box",(async s=>{let a=$(s.currentTarget).find(".simple-setting");et(a),a.html(zs(this.getRuntimeService("settingsRegistry"))).show();try{await Us(this.getFormDependencies(),this.getSelector.bind(this),this.openSettingDialog.bind(this),a)}catch(r){clog.warn("桌面快捷设置初始化失败",r)}clog.lowZIndex()})).on("mouseleave.jhsSettingQuick",".setting-box",(s=>{et($(s.currentTarget).find(".simple-setting"))})).on("mouseenter.jhsSettingQuick",".mini-setting-box",(async s=>{let a=$(s.currentTarget).find(".mini-simple-setting");et(a),a.html(zs(this.getRuntimeService("settingsRegistry"))).show();try{await Us(this.getFormDependencies(),this.getSelector.bind(this),this.openSettingDialog.bind(this),a)}catch(r){clog.warn("迷你快捷设置初始化失败",r)}clog.lowZIndex()})).on("mouseleave.jhsSettingQuick",".mini-setting-box",(s=>{et($(s.currentTarget).find(".mini-simple-setting"))}))}unmountDesktopSettingNav(){this._desktopNavGeneration++,this._desktopSettingNavMounted=!1,this._settingNavResizeCleanup?.(),this._settingNavResizeCleanup=null,$(".simple-setting, .mini-simple-setting").each((e,t)=>et(t)),$(".jhs-setting-nav-item, .jhs-mini-setting-box, .jhs-setting-anchor, .jhs-setting-detail-anchor").remove(),$(".main-nav, .container-fluid").off("mouseenter.jhsSettingQuick mouseleave.jhsSettingQuick")}async openQuickSetting(){$("#jhs-quick-setting-backdrop, #jhs-quick-setting-sheet").remove();let e=document.activeElement;await this.getRuntimeService("settings").waitForIdle();let t=!1,s=d((n=!0)=>{if(t)return;t=!0,$(document).off("keydown.jhsQuickSetting");let l=$("#jhs-quick-setting-sheet .jhs-quick-setting");et(l),$("#jhs-quick-setting-backdrop, #jhs-quick-setting-sheet").remove(),n&&e?.isConnected&&typeof e.focus=="function"&&e.focus()},"closeQuickSetting"),a=$('
'),r=$(``),i=r.find(".jhs-quick-setting");i.html(Us(this.getRuntimeService("settingsRegistry"))),$("body").append(a,r),clog.lowZIndex(),a.on("click.jhsQuickSetting",(()=>s())),r.on("click.jhsQuickSetting",".jhs-quick-setting__close",(()=>s())),$(document).off("keydown.jhsQuickSetting").on("keydown.jhsQuickSetting",(n=>{if(n.key==="Escape")return n.preventDefault(),s();if(n.key!=="Tab")return;let l=r.find('a[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex="-1"])').filter(((u,p)=>!p.hidden&&p.getAttribute("aria-hidden")!=="true"));if(!l.length)return void n.preventDefault();let c=l[0],h=l[l.length-1];n.shiftKey&&document.activeElement===c?(n.preventDefault(),h.focus()):!n.shiftKey&&document.activeElement===h&&(n.preventDefault(),c.focus())}));try{await Os(this.getFormDependencies(),this.getSelector.bind(this),(n=>{s(!1),this.openSettingDialog(n).catch((l=>clog.error("完整设置打开失败",l)))}),i),r.find(".jhs-quick-setting__close").trigger("focus")}catch(n){s(),clog.error("快捷设置初始化失败",n),show.error("快捷设置加载失败")}}async openSettingDialog(e="backup-panel",t){await this.getRuntimeService("settings").waitForIdle();let s=Ql(e,this.cacheItems);this.getRuntimeService("dialog").open({type:1,title:"设置",content:s,ui:{size:"lg",body:"scroll"},area:utils.getDialogArea("lg"),scrollbar:!1,success:d(async(a,r)=>{let i=++this._settingsDialogGeneration,n=$(a);this._settingsFocusCleanup?.(),this._settingsFocusCleanup=utils.trapFocus(n[0]),n.data("jhsSettingsGeneration",i),n.find(".layui-layer-content").css("position","relative"),this.renderTaskStatuses(n),Yl(),Zl(),Xl(),ec(),tc();let l=this.hydrateLiveSettings(n);this._fullSettingBinding=l,this.bindClick(n),n.find(".side-menu-item.active").attr("aria-current","page"),utils.setupEscClose(r),t&&t(),this.renderTaskStatuses(n),this.taskStatusUnsubscribe?.(),this.taskStatusUnsubscribe=V.on("task-status-changed",(()=>this.renderTaskStatuses(n))),utils.isMobileMode()&&this.collapseAdvancedTabs(n);let c=await Promise.allSettled([this.hydrateSettingForm(a,i),this.loadResourceSettings(a,i)]),h=c[1];K.refreshAll(a),h.status==="rejected"&&(clog.error("resource-settings 加载失败",h.reason),this.getRuntimeService("diagnostics").recordError({source:"resource-settings",message:h.reason?.message||String(h.reason)}),show.error("资源设置加载失败,基本设置仍可保存"))},"success"),end:d(()=>{this._settingsDialogGeneration++,this._fullSettingBinding?.dispose?.(),this._fullSettingBinding=null,this._cloudSettingBinding?.dispose?.(),this._cloudSettingBinding=null,this._settingsFocusCleanup?.(),this._settingsFocusCleanup=null,this.taskStatusUnsubscribe?.(),this.taskStatusUnsubscribe=null,this.getOptionalDependency("CoverButtonPlugin")?.enableSvgBtn?.()},"end")})}hydrateLiveSettings(e){let t=$(e),s=t.find("#jhs-live-settings"),a=this.getRuntimeService("settingsRegistry"),r=this.getRuntimeService("settings"),i=this.getRuntimeService("host"),n=new Set(["needClosePage","themeMode","mobileMode","enableClog","containerColumns","containerWidth"]),l=a.list({surfaces:["full"]}).filter(p=>(p.effect||"live")==="live"&&p.section!=="cloud"&&!n.has(p.key));s.length&&l.forEach(p=>{let{row:g}=Bs(p,{value:r.snapshot()[p.key]??p.defaultValue});s.append(g)});let c=s.length?ts(s,l,{settings:r}):null,h=[],u=d(p=>{let g=Fl({settings:r,root:t,...p});g&&h.push(g)},"registerStatic");return u({selector:"#needClosePageBasic",key:"needClosePage",getValue:d(()=>t.find("#needClosePageBasic").is(":checked")?"yes":"no","getValue"),setValue:d(p=>t.find("#needClosePageBasic").prop("checked",p==="yes"||p===!0),"setValue"),fallback:"yes",label:"鉴定后立即关闭"}),u({selector:"#themeMode",key:"themeMode",getValue:d(()=>t.find("#themeMode").val(),"getValue"),setValue:d(p=>t.find("#themeMode").val(String(p??"")),"setValue"),fallback:"light",label:"主题"}),u({selector:"#mobileMode",key:"mobileMode",getValue:d(()=>t.find("#mobileMode").val(),"getValue"),setValue:d(p=>t.find("#mobileMode").val(String(p??"")),"setValue"),fallback:"auto",label:"移动模式"}),u({selector:"#enableClog",key:"enableClog",getValue:d(()=>t.find("#enableClog").val(),"getValue"),setValue:d(p=>t.find("#enableClog").val(String(p??"")),"setValue"),fallback:"yes",label:"日志"}),u({selector:"#containerColumns",key:"containerColumns",getValue:d(()=>Number(t.find("#containerColumns").val())||5,"getValue"),setValue:d(p=>ss(t,i,"containerColumns",p),"setValue"),fallback:5,label:"列表列数"}),u({selector:"#containerWidth",key:"containerWidth",getValue:d(()=>Number(t.find("#containerWidth").val())+70,"getValue"),setValue:d(p=>ss(t,i,"containerWidth",p),"setValue"),fallback:100,label:"列表宽度"}),u({selector:"#defaultQuickFilterTab",key:"defaultQuickFilterTab",getValue:d(()=>Ae(t.find("#defaultQuickFilterTab").val()),"getValue"),setValue:d(p=>t.find("#defaultQuickFilterTab").val(String(p??"")),"setValue"),fallback:"waitCheck",label:"列表默认筛选"}),!c&&!h.length?null:{sync:d(p=>{c?.sync?.(p);for(let g of h)g.sync?.(p)},"sync"),flush:d(async p=>{await c?.flush?.(p),await Promise.all(h.map(g=>g.flush?.(p)))},"flush"),dispose:d(()=>{c?.dispose?.();for(let p of h)p.dispose()},"dispose"),setters:c?.setters??{}}}async hydrateSettingForm(e,t){let s=$(e).find("#saveBtn"),a=$(e).find("#settings-hydration-status");s.attr("data-jhs-settings-ready","false").prop("disabled",!0).attr("title","正在加载设置…"),a.empty().text("正在加载设置…");let r=$(e);try{return await Wl(this.getFormDependencies(),r),!s[0]?.isConnected||t!==this._settingsDialogGeneration||r.data("jhsSettingsGeneration")!==t?!1:(K.refreshAll(e),s.attr("data-jhs-settings-ready","true").prop("disabled",!1).removeAttr("title"),a.empty().text("设置已加载"),!0)}catch(i){if(!s[0]?.isConnected||t!==this._settingsDialogGeneration||r.data("jhsSettingsGeneration")!==t)return!1;clog.error("settings-form 加载失败",i),this.getRuntimeService("diagnostics").recordError({source:"settings-form",message:i?.message||String(i)});let n=$('重试加载 ').on("click",(()=>{this.hydrateSettingForm(e,t)}));return a.empty().append(document.createTextNode("表单加载失败,已禁止保存。"),n),show.error("设置表单加载失败,保存已禁用"),!1}}renderTaskStatuses(e=null){let t=e?$(e).find("#setting-task-status-list"):$("#setting-task-status-list");if(!t.length)return;let s=this.getOptionalDependency("TaskPlugin");if(!s?.getTaskStatusSnapshot)return void t.empty();let a={blacklist:"黑名单",favoriteActress:"演员同步",newVideo:"新作品"},r={idle:"正常",running:"运行中",pending:"等待下一次任务检查",due:"待运行"},i=d(n=>n?new Date(n).toLocaleString():"无","format");t.empty(),["blacklist","favoriteActress","newVideo"].forEach((n=>{let l=s.getTaskStatusSnapshot(n),c=$('
');c.append($(' ').text(`${a[n]}:${r[l.state]}`)),c.append($(' ').text(`上次完成 ${i(l.completedAt)};下次检查 ${l.nextAt?i(l.nextAt):"立即"}`)),t.append(c)}))}collapseAdvancedTabs(e=null){let t=[{id:"health-panel",label:"数据体检",render:d(()=>rs(this.getRuntimeService("diagnostics")),"render")},{id:"plugin-mgmt-panel",label:"插件管理",render:d(()=>_i(this.getRuntimeService("diagnostics"),this.getRuntimeService("settings")),"render")},{id:"snapshot-panel",label:"恢复点",render:as},{id:"network-panel",label:"外部请求",render:d(()=>Et(this.getRuntimeService("diagnostics")),"render")}],s=$(".jhs-mobile-sidebar"),a=$(".content-panel").parent();if(!s.length||!a.length||(t.forEach(l=>{s.find(`[data-panel="${l.id}"]`).remove()}),s.find('[data-panel="more-tools-panel"]').length||s.append(''),$("#more-tools-panel").length))return;let r=t.map((l,c)=>`${l.label} `).join(""),i=t.map((l,c)=>`
`).join(""),n=`
+ `),i=r.find(".jhs-quick-setting");i.html(zs(this.getRuntimeService("settingsRegistry"))),$("body").append(a,r),clog.lowZIndex(),a.on("click.jhsQuickSetting",(()=>s())),r.on("click.jhsQuickSetting",".jhs-quick-setting__close",(()=>s())),$(document).off("keydown.jhsQuickSetting").on("keydown.jhsQuickSetting",(n=>{if(n.key==="Escape")return n.preventDefault(),s();if(n.key!=="Tab")return;let l=r.find('a[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex="-1"])').filter(((u,p)=>!p.hidden&&p.getAttribute("aria-hidden")!=="true"));if(!l.length)return void n.preventDefault();let c=l[0],h=l[l.length-1];n.shiftKey&&document.activeElement===c?(n.preventDefault(),h.focus()):!n.shiftKey&&document.activeElement===h&&(n.preventDefault(),c.focus())}));try{await Us(this.getFormDependencies(),this.getSelector.bind(this),(n=>{s(!1),this.openSettingDialog(n).catch((l=>clog.error("完整设置打开失败",l)))}),i),r.find(".jhs-quick-setting__close").trigger("focus")}catch(n){s(),clog.error("快捷设置初始化失败",n),show.error("快捷设置加载失败")}}async openSettingDialog(e="backup-panel",t){await this.getRuntimeService("settings").waitForIdle();let s=Yl(e,this.cacheItems);this.getRuntimeService("dialog").open({type:1,title:"设置",content:s,ui:{size:"lg",body:"scroll"},area:utils.getDialogArea("lg"),scrollbar:!1,success:d(async(a,r)=>{let i=++this._settingsDialogGeneration,n=$(a);this._settingsFocusCleanup?.(),this._settingsFocusCleanup=utils.trapFocus(n[0]),n.data("jhsSettingsGeneration",i),n.find(".layui-layer-content").css("position","relative"),this.renderTaskStatuses(n),Zl(),Xl(),ec(),tc(),sc();let l=this.hydrateLiveSettings(n);this._fullSettingBinding=l,this.bindClick(n),n.find(".side-menu-item.active").attr("aria-current","page"),utils.setupEscClose(r),t&&t(),this.renderTaskStatuses(n),this.taskStatusUnsubscribe?.(),this.taskStatusUnsubscribe=V.on("task-status-changed",(()=>this.renderTaskStatuses(n))),utils.isMobileMode()&&this.collapseAdvancedTabs(n);let c=await Promise.allSettled([this.hydrateSettingForm(a,i),this.loadResourceSettings(a,i)]),h=c[1];K.refreshAll(a),h.status==="rejected"&&(clog.error("resource-settings 加载失败",h.reason),this.getRuntimeService("diagnostics").recordError({source:"resource-settings",message:h.reason?.message||String(h.reason)}),show.error("资源设置加载失败,基本设置仍可保存"))},"success"),end:d(()=>{this._settingsDialogGeneration++,this._fullSettingBinding?.dispose?.(),this._fullSettingBinding=null,this._cloudSettingBinding?.dispose?.(),this._cloudSettingBinding=null,this._settingsFocusCleanup?.(),this._settingsFocusCleanup=null,this.taskStatusUnsubscribe?.(),this.taskStatusUnsubscribe=null,this.getOptionalDependency("CoverButtonPlugin")?.enableSvgBtn?.()},"end")})}hydrateLiveSettings(e){let t=$(e),s=t.find("#jhs-live-settings"),a=this.getRuntimeService("settingsRegistry"),r=this.getRuntimeService("settings"),i=this.getRuntimeService("host"),n=new Set(["needClosePage","themeMode","mobileMode","enableClog","containerColumns","containerWidth"]),l=a.list({surfaces:["full"]}).filter(p=>(p.effect||"live")==="live"&&p.section!=="cloud"&&!n.has(p.key));s.length&&l.forEach(p=>{let{row:g}=Os(p,{value:r.snapshot()[p.key]??p.defaultValue});s.append(g)});let c=s.length?ts(s,l,{settings:r}):null,h=[],u=d(p=>{let g=Vl({settings:r,root:t,...p});g&&h.push(g)},"registerStatic");return u({selector:"#needClosePageBasic",key:"needClosePage",getValue:d(()=>t.find("#needClosePageBasic").is(":checked")?"yes":"no","getValue"),setValue:d(p=>t.find("#needClosePageBasic").prop("checked",p==="yes"||p===!0),"setValue"),fallback:"yes",label:"鉴定后立即关闭"}),u({selector:"#themeMode",key:"themeMode",getValue:d(()=>t.find("#themeMode").val(),"getValue"),setValue:d(p=>t.find("#themeMode").val(String(p??"")),"setValue"),fallback:"light",label:"主题"}),u({selector:"#mobileMode",key:"mobileMode",getValue:d(()=>t.find("#mobileMode").val(),"getValue"),setValue:d(p=>t.find("#mobileMode").val(String(p??"")),"setValue"),fallback:"auto",label:"移动模式"}),u({selector:"#enableClog",key:"enableClog",getValue:d(()=>t.find("#enableClog").val(),"getValue"),setValue:d(p=>t.find("#enableClog").val(String(p??"")),"setValue"),fallback:"yes",label:"日志"}),u({selector:"#containerColumns",key:"containerColumns",getValue:d(()=>Number(t.find("#containerColumns").val())||5,"getValue"),setValue:d(p=>ss(t,i,"containerColumns",p),"setValue"),fallback:5,label:"列表列数"}),u({selector:"#containerWidth",key:"containerWidth",getValue:d(()=>Number(t.find("#containerWidth").val())+70,"getValue"),setValue:d(p=>ss(t,i,"containerWidth",p),"setValue"),fallback:100,label:"列表宽度"}),u({selector:"#defaultQuickFilterTab",key:"defaultQuickFilterTab",getValue:d(()=>_e(t.find("#defaultQuickFilterTab").val()),"getValue"),setValue:d(p=>t.find("#defaultQuickFilterTab").val(_e(p)),"setValue"),fallback:"waitCheck",label:"列表默认筛选"}),!c&&!h.length?null:{sync:d(p=>{c?.sync?.(p);for(let g of h)g.sync?.(p)},"sync"),flush:d(async p=>{await c?.flush?.(p),await Promise.all(h.map(g=>g.flush?.(p)))},"flush"),dispose:d(()=>{c?.dispose?.();for(let p of h)p.dispose()},"dispose"),setters:c?.setters??{}}}async hydrateSettingForm(e,t){let s=$(e).find("#saveBtn"),a=$(e).find("#settings-hydration-status");s.attr("data-jhs-settings-ready","false").prop("disabled",!0).attr("title","正在加载设置…"),a.empty().text("正在加载设置…");let r=$(e);try{return await Kl(this.getFormDependencies(),r),!s[0]?.isConnected||t!==this._settingsDialogGeneration||r.data("jhsSettingsGeneration")!==t?!1:(K.refreshAll(e),s.attr("data-jhs-settings-ready","true").prop("disabled",!1).removeAttr("title"),a.empty().text("设置已加载"),!0)}catch(i){if(!s[0]?.isConnected||t!==this._settingsDialogGeneration||r.data("jhsSettingsGeneration")!==t)return!1;clog.error("settings-form 加载失败",i),this.getRuntimeService("diagnostics").recordError({source:"settings-form",message:i?.message||String(i)});let n=$('
重试加载 ').on("click",(()=>{this.hydrateSettingForm(e,t)}));return a.empty().append(document.createTextNode("表单加载失败,已禁止保存。"),n),show.error("设置表单加载失败,保存已禁用"),!1}}renderTaskStatuses(e=null){let t=e?$(e).find("#setting-task-status-list"):$("#setting-task-status-list");if(!t.length)return;let s=this.getOptionalDependency("TaskPlugin");if(!s?.getTaskStatusSnapshot)return void t.empty();let a={blacklist:"黑名单",favoriteActress:"演员同步",newVideo:"新作品"},r={idle:"正常",running:"运行中",pending:"等待下一次任务检查",due:"待运行"},i=d(n=>n?new Date(n).toLocaleString():"无","format");t.empty(),["blacklist","favoriteActress","newVideo"].forEach((n=>{let l=s.getTaskStatusSnapshot(n),c=$('
');c.append($('
').text(`${a[n]}:${r[l.state]}`)),c.append($('
').text(`上次完成 ${i(l.completedAt)};下次检查 ${l.nextAt?i(l.nextAt):"立即"}`)),t.append(c)}))}collapseAdvancedTabs(e=null){let t=[{id:"health-panel",label:"数据体检",render:d(()=>rs(this.getRuntimeService("diagnostics")),"render")},{id:"plugin-mgmt-panel",label:"插件管理",render:d(()=>$i(this.getRuntimeService("diagnostics"),this.getRuntimeService("settings")),"render")},{id:"snapshot-panel",label:"恢复点",render:as},{id:"network-panel",label:"外部请求",render:d(()=>Dt(this.getRuntimeService("diagnostics")),"render")}],s=$(".jhs-mobile-sidebar"),a=$(".content-panel").parent();if(!s.length||!a.length||(t.forEach(l=>{s.find(`[data-panel="${l.id}"]`).remove()}),s.find('[data-panel="more-tools-panel"]').length||s.append(''),$("#more-tools-panel").length))return;let r=t.map((l,c)=>`
${l.label} `).join(""),i=t.map((l,c)=>`
`).join(""),n=`
- `;a.append(n),t.forEach(l=>{let c=$(`#${l.id}`);c.length&&(c.children().appendTo(`#sub-${l.id}`),c.remove(),$(`#sub-${l.id}`).attr("data-rendered","true"))}),s.on("click",'[data-panel="more-tools-panel"]',function(){$(".side-menu-item").removeClass("active").attr("aria-current","false"),$(this).addClass("active").attr("aria-current","page"),$(".content-panel").hide(),$("#more-tools-panel").show(),$("#saveBtn").show(),$("#clean-all").addClass("jhs-is-hidden")}),$("#more-tools-panel").on("click",".jhs-sub-tab",function(){let l=$(this).data("sub-panel");$("#more-tools-panel .jhs-sub-tab").removeClass("active").attr({"aria-selected":"false",tabindex:"-1"}),$(this).addClass("active").attr({"aria-selected":"true",tabindex:"0"}),$("#more-tools-panel .jhs-sub-panel").removeClass("active"),$(`#sub-${l}`).addClass("active"),$(`#sub-${l}`).attr("data-rendered")!=="true"&&$(`#sub-${l}`).attr("data-rendered","true");let c=t.find(h=>h.id===l);c&&c.render&&c.render()}).on("keydown",".jhs-sub-tab",function(l){if(!["ArrowLeft","ArrowRight","Home","End"].includes(l.key))return;l.preventDefault();let c=$("#more-tools-panel .jhs-sub-tab"),h=c.index(this),u=l.key==="Home"?0:l.key==="End"?c.length-1:l.key==="ArrowRight"?(h+1)%c.length:(h-1+c.length)%c.length;c.eq(u).trigger("click").trigger("focus")})}bindClick(e=null){let t=this,s=this.getRuntimeService("webdav"),a=this.getRuntimeService("dialog"),r=this.getRuntimeService("diagnostics"),i=this.getRuntimeService("storage"),n=this.getRuntimeService("translation"),l=d((m,f,v=null)=>sc(m,f,v,a),"previewDiff"),c=e?$(e):$(document);c.find("#saveBtn").attr("data-jhs-settings-ready","false").prop("disabled",!0).attr("title","正在加载设置…"),c.find(".side-menu-item").on("click",(function(){c.find(".side-menu-item").removeClass("active").attr("aria-current","false"),$(this).addClass("active").attr("aria-current","page"),c.find(".content-panel").hide();let m=$(this).data("panel");c.find("#"+m).show(),m==="cache-panel"?(c.find("#saveBtn").hide(),c.find("#clean-all").removeClass("jhs-is-hidden")):(c.find("#saveBtn").show(),c.find("#clean-all").addClass("jhs-is-hidden")),m==="health-panel"&&(c.find("#saveBtn").hide(),c.find("#clean-all").addClass("jhs-is-hidden"),rs()),m==="plugin-mgmt-panel"&&(c.find("#saveBtn").hide(),c.find("#clean-all").addClass("jhs-is-hidden"),_i(t.getRuntimeService("diagnostics"),t.getRuntimeService("settings"))),m==="snapshot-panel"&&(c.find("#saveBtn").hide(),c.find("#clean-all").addClass("jhs-is-hidden"),as()),m==="network-panel"&&(c.find("#saveBtn").hide(),c.find("#clean-all").addClass("jhs-is-hidden"),Et(r))})),c.find("#importBtn").on("click",(m=>Ll(l))),c.find("#exportBtn").on("click",(m=>Ul())),c.find("#preview-car-number-import").on("click",(()=>this.previewCarNumbers(c))),c.find("#confirm-car-number-import").on("click",(async m=>this.confirmCarNumbers(m,c))),c.find("#webdavBackupBtn").on("click",(m=>Ml(this.folderName,s))),c.find("#webdavBackupListBtn").on("click",(m=>Bl(this.folderName,(f,v,b)=>Ol(f,v,b,this.folderName,l,a),s))),c.find("#saveBtn").on("click",(async m=>{let f=$(m.currentTarget);if(!(f.data("jhsBusy")||f.attr("data-jhs-settings-ready")!=="true")){f.data("jhsBusy",!0).prop("disabled",!0).attr("aria-busy","true");try{if(await this._fullSettingBinding?.flush?.({throwOnFailure:!0}),(await Kl(this.getFormDependencies(),c))?.canceled)return;show.ok("保存成功")}catch(v){v?.partialFailure?show.error("部分设置保存失败,请重试"):show.error("设置保存失败"),clog.error("设置保存失败",v)}finally{f.removeData("jhsBusy").prop("disabled",f.attr("data-jhs-settings-ready")!=="true").removeAttr("aria-busy")}}})),c.find("#runHealthCheckBtn").on("click",(()=>rs())),c.find("#repairHealthBtn").on("click",(m=>{utils.q(m,"修复前会自动下载备份,是否继续?",(()=>ac()))})),c.find("#pm-clear-log").on("click",(()=>{this.getRuntimeService("diagnostics").clearErrors(),c.find("#plugin-error-log").text("无错误记录"),show.ok("错误日志已清空")})),c.find("#createSnapshotBtn").on("click",(async()=>{let m=loading();try{await storageManager.createSnapshot("手动快照","manual"),show.ok("快照创建成功"),as()}catch(f){clog.error(f),show.error("创建快照失败: "+f.message)}finally{m.close()}})),c.find(".clean-btn").on("click",(async m=>{let f=$(m.currentTarget).data("key"),v=this.cacheItems.find((b=>b.key===f));f===storageManager.third_party_cache_key?(await storageManager.clearThirdPartyCache(),await this.getRuntimeService("cache").clearNamespace("external-detail-v1")):f==="_circuitBreaker"?r.resetAllCircuitBreakers():f==="_domainStats"?r.clearDomainStats():f==="jhs_translate"?await n.clearCache():f==="jhs_actress_info"?(await this.getRuntimeService("cache").clearNamespace("actress-info"),await i.removeLocal(f)):f==="jhs_screenShot"?(await this.getRuntimeService("cache").clearNamespace("screenshot"),await i.removeLocal(f)):i.removeLocal(f),show.ok(`${v.text} 清理成功`),c.find("#cache-data-display").addClass("jhs-is-hidden"),f==="jhs_dmm_video"&&i.removeLocal("jhs_other_site_dmm")})),c.find("#clean-all").on("click",(async()=>{this.cacheItems.forEach((m=>m.key!=="jhs_translate"&&i.removeLocal(m.key))),await n.clearCache(),await this.getRuntimeService("cache").clearAll(),show.ok("全部缓存已清理"),c.find("#cache-data-display").addClass("jhs-is-hidden"),i.removeLocal("jhs_other_site_dmm"),await storageManager.clearThirdPartyCache()})),c.find(".view-btn").on("click",(async m=>{let f=$(m.currentTarget).data("key"),v;f===storageManager.third_party_cache_key?v=JSON.stringify(await storageManager.getThirdPartyCache()):f==="_circuitBreaker"?v=JSON.stringify(r.getNetworkDiagnostics().circuitBreakers):f==="_domainStats"?v=JSON.stringify(r.getNetworkDiagnostics().domainStats):f==="jhs_translate"?v=JSON.stringify(await n.inspectCache()):v=i.getLocal(f);let b=c.find("#cache-data-display"),w=b.find("pre");if(b.removeClass("jhs-is-hidden"),v)try{let S=JSON.parse(v);w.text(JSON.stringify(S,null,2))}catch{w.text(v)}else w.text("无数据")}));let h=c.find("#highlightedTagNumber"),u=c.find("#highlightedTagColor"),p=c.find("#highlightedTagLabel");function g(){let m=h.val(),f=u.val();p.css("border",`${m}px solid ${f}`)}d(g,"updatePreview"),h.on("input",g),u.on("input",g)}async loadResourceSettings(e=null,t=this._settingsDialogGeneration){let s=e?$(e):$(document),[a,r,i,n,l,c]=await Promise.all([this.resourceSettings.getMagnetSources(),this.resourceSettings.getMagnetTagRules(),this.resourceSettings.getMagnetFilterRules(),this.resourceSettings.getBuiltInSources(),this.resourceSettings.getScreenshotSettings(),this.resourceSettings.getCloudSettings()]);if(e&&(!s[0]?.isConnected||t!==this._settingsDialogGeneration))return;let h=[...Ns,...this.getRuntimeService("magnet").getBuiltInSources()];this.resourceState={custom:a,tags:r,filters:i,builtIn:h.map((u=>({...u,...n.find((p=>p.id===u.id))||{}}))),screenshot:{mode:l.mode,providers:Ls.map((u=>{let p={...u,...l.providers.find((g=>g.id===u.id))||{}};return u.implemented===!1?{...p,enabled:!1}:p}))}},this.renderResourceSettings(s),this.renderCloudSettings(s,c),s.find("#resource-sources-panel").off("change.jhsResource",'input[name="screenshotMode"]').on("change.jhsResource",'input[name="screenshotMode"]',(u=>{let p=this.resourceState.screenshot.mode;this.resourceState.screenshot.mode=u.currentTarget.value,this.resourceSettings.saveScreenshotMode(this.resourceState.screenshot.mode).catch(g=>{this.resourceState.screenshot.mode=p,s.find(`input[name="screenshotMode"][value="${p}"]`).prop("checked",!0),clog.error("截图模式保存失败",g),show.error("截图模式保存失败,已恢复原设置")})})),s.find("#add-custom-magnet-source").off("click.jhsResource").on("click.jhsResource",(()=>this.openSourceDialog(null,s))),s.find("#add-magnet-tag-rule").off("click.jhsResource").on("click.jhsResource",(()=>this.openRuleDialog("tag",null,s))),s.find("#add-magnet-filter-rule").off("click.jhsResource").on("click.jhsResource",(()=>this.openRuleDialog("filter",null,s))),s.find("#export-resource-config").off("click.jhsResource").on("click.jhsResource",(async()=>{let u=JSON.stringify(await this.resourceSettings.exportConfig(),null,2);s.find("#advanced-resource-json").val(u).prop("readonly",!0)})),s.find("#edit-resource-config").off("click.jhsResource").on("click.jhsResource",(()=>s.find("#advanced-resource-json").prop("readonly",!1).trigger("focus"))),s.find("#import-resource-config").off("click.jhsResource").on("click.jhsResource",(async()=>{try{await this.resourceSettings.importConfig(s.find("#advanced-resource-json").val()),show.ok("资源配置导入成功"),await this.loadResourceSettings(s,t),K.refreshAll()}catch(u){show.error(u.message)}})),s.find("#car-number-import,#car-number-import-status").off("input.jhsResource change.jhsResource").on("input.jhsResource change.jhsResource",(()=>{this.pendingCarImport=null,s.find("#confirm-car-number-import").prop("disabled",!0).text("确认导入")})),s.find("#check-one-one-five-login").off("click.jhsResource").on("click.jhsResource",(()=>this.checkOneOneFiveLogin(s)))}renderCloudSettings(e,t){let s=e.find("#cloud-settings-catalog");if(!s.length)return;this._cloudSettingBinding?.dispose?.();let a=this.getRuntimeService("settingsRegistry"),r=this.getRuntimeService("settings"),i=a.list({surfaces:["full"]}).filter(l=>l.section==="cloud");s.empty();let n=d(l=>l==="offlineProviderMode"?t.providerMode:l==="oneOneFiveConcurrency"?t.concurrency:l==="oneOneFiveCacheMinutes"?t.cacheMinutes:t[l],"valueFor");i.forEach(l=>{let c=Bs(l,{value:n(l.key)});c.root.attr("id",l.key),s.append(c.row)}),this._cloudSettingBinding=ts(s,i,{settings:r})}renderResourceSettings(e=$(document)){let t=d((s,a,r)=>{let i=$('
');i.append($('
').append($("
").append($("
").text(s.name),s.experimental?'
实验性 ':"",$("
").text(`${s.type||"截图来源"} · ${s.domain||(()=>{try{return new URL(s.searchUrlTemplate).hostname}catch{return"未配置域名"}})()} · 优先级 ${s.priority}`)),$('
').prop("checked",s.enabled)));let n=$('
').append('
测试 ');return a&&n.append('
编辑 删除 '),i.append(n),i.on("change",".jhs-source-toggle",async l=>{let c=!l.currentTarget.checked;s.enabled=l.currentTarget.checked;try{r==="screenshot"?await this.resourceSettings.updateArray("screenshotProviders",h=>{let u=h.find((p=>p.id===s.id));return u?u.enabled=s.enabled:h.push({id:s.id,enabled:s.enabled}),h}):a?await this.resourceSettings.updateArray("customMagnetSources",h=>{let u=h.find((p=>p.id===s.id));return u&&(u.enabled=s.enabled),h}):await this.resourceSettings.updateArray("magnetBuiltInSources",h=>{let u=h.find((p=>p.id===s.id));return u?u.enabled=s.enabled:h.push({id:s.id,enabled:s.enabled}),h}),this.renderResourceSettings(e)}catch{s.enabled=c,$(l.currentTarget).prop("checked",c),show.error("来源设置保存失败,已恢复原设置")}}),i.on("click",".jhs-source-test",l=>this.testSource(l.currentTarget,s.baseUrl||s.searchUrlTemplate?.replace("{keyword}","test"),{custom:a,source:s})),a&&i.on("click",".jhs-source-edit",(()=>this.openSourceDialog(s,e))).on("click",".jhs-source-delete",(l=>utils.q(l,`确认删除来源「${C(s.name)}」?`,(async()=>{try{await this.resourceSettings.updateArray("customMagnetSources",c=>c.filter((h=>h.id!==s.id))),this.resourceState.custom=await this.resourceSettings.getMagnetSources(),this.renderResourceSettings(e)}catch(c){show.error(c.message)}})))),i},"card");e.find("#builtin-magnet-source-list").empty().append(this.resourceState.builtIn.map((s=>t(s,!1,"magnet")))),e.find("#custom-magnet-source-list").empty().append(this.resourceState.custom.length?this.resourceState.custom.map((s=>t(s,!0,"magnet"))):'
暂无自定义来源
'),e.find("#screenshot-source-list").empty().append(this.resourceState.screenshot.providers.map((s=>t(s,!1,"screenshot")))),this.resourceState.screenshot.providers.forEach(((s,a)=>{s.implemented===!1&&e.find("#screenshot-source-list .jhs-resource-card").eq(a).find(".jhs-source-toggle").prop("disabled",!0).end().find("strong").after('
未实现 ').end().find(".jhs-source-test").remove()})),e.find(`input[name="screenshotMode"][value="${this.resourceState.screenshot.mode}"]`).prop("checked",!0),this.renderRules("tag",e),this.renderRules("filter",e)}renderRules(e,t=$(document)){let s=e==="tag"?this.resourceState.tags:this.resourceState.filters,a=t.find("#magnet-"+e+"-rule-list").empty();s.length||a.append('
暂无规则
'),s.forEach((r=>{let i=$('
').append($("
").text(r.name),$("
").text(`${r.type==="regex"?"正则":"包含"}:${r.pattern}${e==="tag"?` · 权重 ${Number(r.weight)>=0?"+":""}${r.weight||0}`:` · ${r.action==="hide"?"隐藏":`降权 ${r.penalty||-20}`}`}`),'
编辑 删除
');i.on("click",".jhs-rule-edit",(()=>this.openRuleDialog(e,r,t))).on("click",".jhs-rule-delete",(n=>utils.q(n,`确认删除规则「${C(r.name)}」?`,(async()=>{try{await this.resourceSettings.updateArray(e==="tag"?"magnetTagRules":"magnetFilterRules",l=>l.filter((c=>c.id!==r.id))),this.resourceState[e==="tag"?"tags":"filters"]=await this.resourceSettings.getArray(e==="tag"?"magnetTagRules":"magnetFilterRules"),this.renderRules(e,t)}catch(l){show.error(l.message)}})))),a.append(i)}))}openSourceDialog(e=null,t=null){let s=this.getRuntimeService("dialog"),a=["rowSelector","titleSelector","magnetSelector","sizeSelector","dateSelector","seedersSelector","leechersSelector","resultsPath","titlePath","magnetPath","hashPath","sizePath","datePath","seedersPath"],r=$('
'),i=d(()=>{let n=r.find('[name="parserType"]').val(),l=n==="torrent-table"?a.slice(0,7):n==="json"?a.slice(7):[];r.find(".jhs-parser-fields").html(l.map((c=>`
${c} `)).join("")),l.forEach((c=>r.find(`[name="${c}"]`).val(e?.[c]||"")))},"renderFields");Object.entries(e||{enabled:!0,priority:100,parserType:"magnet-links"}).forEach(([n,l])=>{let c=r.find(`[name="${n}"]`);c.attr("type")==="checkbox"?c.prop("checked",l):c.val(l)}),r.on("change",'[name="parserType"]',i),i(),r.appendTo("body").hide(),s.open({type:1,title:e?"编辑自定义磁力源":"添加自定义磁力源",content:r,ui:{size:"md",body:"scroll"},area:utils.getDialogArea("md"),btn:["保存","取消"],success:d(()=>r.show(),"success"),end:d(()=>r.remove(),"end"),yes:d(async n=>{let l=Object.fromEntries(r.find("input,select").map(((c,h)=>[h.name,h.type==="checkbox"?h.checked:h.value])).get());try{let c=_l(l,e);await this.resourceSettings.updateArray("customMagnetSources",h=>{let u=e?h.findIndex((p=>p.id===e.id)):-1;return u>=0?h.splice(u,1,c):h.push(c),h}),this.resourceState.custom=await this.resourceSettings.getMagnetSources(),s.close(n),t&&this.renderResourceSettings(t)}catch(c){show.error(c.message)}},"yes")})}openRuleDialog(e,t=null,s=null){let a=this.getRuntimeService("dialog"),r=e==="tag",i=$(`
名称 ${r?"":'匹配范围标题 文件名 '}匹配方式包含 正则 匹配内容 ${r?'权重 ':'动作隐藏 降权 降权分数 '}启用
`);Object.entries(t||{enabled:!0,type:"contains",weight:0,action:"hide",penalty:-20}).forEach(([n,l])=>{let c=i.find(`[name="${n}"]`);c.attr("type")==="checkbox"?c.prop("checked",l):c.val(l)}),i.appendTo("body").hide(),a.open({type:1,title:`${t?"编辑":"新建"}${r?"标签":"过滤"}规则`,content:i,ui:{size:"sm",body:"scroll"},area:utils.getDialogArea("sm"),btn:["保存","取消"],success:d(()=>i.show(),"success"),end:d(()=>i.remove(),"end"),yes:d(async n=>{let l=Object.fromEntries(i.find("input,select").map(((c,h)=>[h.name,h.type==="checkbox"?h.checked:h.value])).get());l.id=t?.id||`rule-${Date.now()}`,l.weight=Number(l.weight),l.penalty=Number(l.penalty);try{Rt(l),await this.resourceSettings.updateArray(r?"magnetTagRules":"magnetFilterRules",c=>{let h=t?c.findIndex((u=>u.id===t.id)):-1;return h>=0?c.splice(h,1,l):c.push(l),c}),this.resourceState[r?"tags":"filters"]=await this.resourceSettings.getArray(r?"magnetTagRules":"magnetFilterRules"),a.close(n),s&&this.renderRules(e,s)}catch(c){show.error(c.message)}},"yes")})}async saveCloudSettings(e=$(document)){await this.resourceSettings.saveCloudSettings({enable123Offline:e.find("#enable123Offline").is(":checked"),enable115Offline:e.find("#enable115Offline").is(":checked"),providerMode:e.find("#offlineProviderMode").val(),enable115Match:e.find("#enable115Match").is(":checked"),enable115LoginRedirect:e.find("#enable115LoginRedirect").is(":checked"),concurrency:Number(e.find("#oneOneFiveConcurrency").val()),cacheMinutes:Number(e.find("#oneOneFiveCacheMinutes").val())})}async checkOneOneFiveLogin(e=$(document)){let t=e.find("#one-one-five-state").text("检测中");try{let s=await this.getRuntimeService("scope")(),a=await this.getRuntimeService("offline").checkAccount("one115",{scope:s});t.text(a.authenticated?"已登录":"未登录")}catch{t.text("检测失败")}}async testSource(e,t,s={}){if(!t)return show.info("本站来源无需跨站测试");let a=$(e).prop("disabled",!0),r=a.siblings(".jhs-source-test-state").length?a.siblings(".jhs-source-test-state"):$('
').insertAfter(a);r.text("检测中");try{let i=new URL(t),n=await this.getRuntimeService("scope")(),l=await this.getRuntimeService("http").request({providerId:`settings-source-${s.source?.id||"unknown"}`,method:"GET",url:i.href,responseType:"text",cacheScope:"none",urlPolicy:s.custom?{trustClass:"custom-public"}:{trustClass:"builtin-public",hosts:[s.source?.domain||i.hostname]}},n);r.text(l.data?"200 · 可解析":"空响应")}catch(i){r.text(i?.code==="NOT_FOUND"?"404":i?.code==="RATE_LIMITED"?"限流":i?.code==="AUTH_REQUIRED"?"需要授权":"请求失败")}finally{a.prop("disabled",!1).text("测试")}}previewCarNumbers(e=$(document)){let t=yl(e.find("#car-number-import").val()),s=e.find("#car-number-import-status").val();this.pendingCarImport=s&&t.values.length?{...t,actionType:s}:null,e.find("#car-number-import-preview").text(`识别 ${t.recognized} 条 · 有效 ${t.values.length} · 重复 ${Math.max(0,t.recognized-t.values.length-t.invalid.length)} · 无效 ${t.invalid.length}${t.invalid.length?` · 异常示例:${t.invalid.slice(0,5).join("、")}`:""}`),e.find("#confirm-car-number-import").prop("disabled",!this.pendingCarImport).text(this.pendingCarImport?`确认导入 ${t.values.length} 条`:"确认导入"),s||show.info("请选择导入状态")}async confirmCarNumbers(e,t=$(document)){if(!this.pendingCarImport)return show.info("请先解析预览");let s=this.pendingCarImport;utils.q(e,`确认导入 ${s.values.length} 条记录?`,(async()=>{let a=new Map((await storageManager.getCarList()).map((h=>[T(h.carNum),h]))),r={added:0,updated:0,failed:0},i=Ce(s.actionType),n=this.getRuntimeService("state"),l=s.values.map(h=>{let u=T(h),p=a.get(u);return u?{carNum:u,url:p?.url||jl(u),names:p?.names||"",publishTime:p?.publishTime||""}:null}).filter(Boolean),c=75;for(let h=0;h
p.carNum),{[i]:!0},{type:"manual-car-number-import",records:u}),u.forEach(p=>a.has(p.carNum)?r.updated++:r.added++)}catch(p){r.failed+=u.length,clog.warn("番号批量导入块失败",p)}}this.pendingCarImport=null,t.find("#confirm-car-number-import").prop("disabled",!0),show.ok(`导入完成:新增 ${r.added},更新 ${r.updated},失败 ${r.failed}`)}))}};d($i,"SettingPlugin");var zs=$i;async function He(o,e,t){let s=new URL(e,window.location.href),a=await o.request({providerId:"host-page",method:"GET",url:s.href,responseType:"text",cacheScope:"none",urlPolicy:{trustClass:"builtin-public",hosts:[window.location.hostname],expectedOrigin:window.location.origin}},t);return String(a.data??a.responseText??"")}d(He,"requestHostPage");function rc(o){let e=globalThis.$,t=o?.jquery?o:e(o),s=[];return t.find('.tags a[href^="/actors/"]').each((a,r)=>{let i=e(r).text().trim();i&&s.push(i)}),t.find('span[onmouseover*="star_"] a').each((a,r)=>{let i=e(r).text().trim();i&&s.push(i)}),[...new Set(s)].join(" ")}d(rc,"readCardNames");function _e(o){let e=globalThis.$,t=o?.jquery?o:e(o),s=t.find("a"),a=t.attr("data-jhs-original-url")||s.attr("href"),r=t.find(".video-title"),i,n,l;if(r.length){let h=r.find("strong");h.length&&(i=h.text().trim()),n=s.attr("title")?s.attr("title").trim():i?r.text().replace(i,"").trim():r.text().trim(),l=t.find(".meta").text().trim()}if(!i){let h=t.find("img");h.length&&(n=h.attr("title")?.trim()||h.attr("data-title")?.trim()||n);let u=t.find("date").map((p,g)=>e(g).text().trim()).get();l=u.find(p=>/^\d{4}-\d{1,2}-\d{1,2}$/.test(p)),i=u.find(p=>!/^\d{4}-\d{1,2}-\d{1,2}$/.test(p))}let c=ee(i);if(!c)throw new TypeError("提取番号信息失败");return Object.freeze({carNum:c,aHref:a,url:a,title:n,publishTime:l,fc2Source:["fc2","123av"].includes(t.attr("data-jhs-fc2-source"))?t.attr("data-jhs-fc2-source"):"fc2"})}d(_e,"readListItem");function Ti(o,e,t){for(let s of o)if(e.includes(s)||t.startsWith(s))return s;return null}d(Ti,"findMatchedTitleKeyword");function is(o={}){return{titleKeywords:Array.isArray(o.titleKeywords)?o.titleKeywords:[],carMap:o.carMap instanceof Map?o.carMap:new Map,actorCarNumToNameMap:o.actorCarNumToNameMap instanceof Map?o.actorCarNumToNameMap:new Map,actressCarNumToNameMap:o.actressCarNumToNameMap instanceof Map?o.actressCarNumToNameMap:new Map,recentCarNums:o.recentCarNums instanceof Set?o.recentCarNums:new Set,settings:o.settings??{}}}d(is,"createListEvaluationContext");function ns(o,e,{filter:t="waitCheck"}={}){let s=o?.carNum,a=s?e.carMap.get(s):null,r=q(a?.stateFlags),n={keyword:!!(e.titleKeywords.length&&s?Ti(e.titleKeywords,o.title||"",s):null),actorBlacklist:s?e.actorCarNumToNameMap.has(s):!1,actressBlacklist:s?e.actressCarNumToNameMap.has(s):!1},l=s?e.recentCarNums.has(s):!1,c=ft(r,n);return{flags:r,visibilityReasons:n,recent:l,hardHidden:c,matchesCurrentFilter:oi(t,r,{visibilityReasons:n,recent:l})}}d(ns,"evaluateListItem");function ic(o){return o.replace(/\/+$/,"")}d(ic,"stripTrailingSlashes");function nc(o,e){try{let t=new URL(o),s=new URL(e);return t.origin===s.origin&&ic(t.pathname)===ic(s.pathname)&&t.search===s.search}catch{return o===e}}d(nc,"isSamePageUrl");async function Fs({startDom:o,itemSelector:e,nextPageSelector:t,fetchHtml:s,parseItem:a,evaluate:r,isCancelled:i=d(()=>!1,"isCancelled"),onProgress:n=d(()=>{},"onProgress"),pageDelayMs:l=500,maxPages:c=200,currentUrl:h=null,firstPageUrl:u=null}){let p=[],g=new Set,m=o,f=1,v=0;if(u&&h&&!nc(u,h)){if(i())return p;let b=await s(u);if(i())return p;let w=new DOMParser().parseFromString(b,"text/html");m=$(w)}for(;m&&m.length&&!i();){n({page:f,scanned:v,matched:p.length});let b=m.find(e).toArray();for(let x of b){if(i())break;let k=null;try{k=a($(x))}catch{continue}if(!k?.carNum)continue;v++;let _=r(k);_?.matchesCurrentFilter&&!g.has(k.carNum)&&(g.add(k.carNum),p.push({...k,flags:_.flags,visibilityReasons:_.visibilityReasons,hardHidden:_.hardHidden}))}let w=m.find(t).attr("href");if(!w||i()||f>=c||(l&&await new Promise(x=>setTimeout(x,l)),i()))break;let S=await s(w),j=new DOMParser().parseFromString(S,"text/html");m=$(j),f++}return p}d(Fs,"scanAllPages");var Dt=null;function Vs(){if(Dt)return null;let o={id:Symbol("batch-run"),cancelRequested:!1};return Dt=o,o}d(Vs,"tryBeginBatchRun");function Nt(o){return Dt===o}d(Nt,"isActiveBatchRun");function oc(o){return!!o?.cancelRequested||!Nt(o)}d(oc,"isBatchRunCancelled");function lc(o){Dt===o&&o&&(o.cancelRequested=!0)}d(lc,"requestCancelBatchRun");function Hs(o){Dt===o&&(Dt=null)}d(Hs,"endBatchRun");function qs(o,e){let t=o.find("title, body").text(),s=/Just a moment|cf-chl-|Cloudflare/i.test(t),a=o.find(e.boxSelector).length>0;return{state:s?"challenge":a?"valid":"invalid",items:a?o.find(e.requestDomItemSelector):null,isEmpty:a&&o.find(e.requestDomItemSelector).length===0}}d(qs,"parseDetailPage");function cc(){if(!V)throw new Error("Blacklist EventBus 未初始化");return V}d(cc,"getBlacklistEventBus");var Ai=class Ai extends I{constructor(){super(...arguments),this.blacklistSearchDebounced=null,this.taskStatusUnsubscribe=null}getName(){return"BlacklistPlugin"}async initCss(){return``}async addBlacklist(e){let t={clientX:e.clientX,clientY:e.clientY+80},s=$("#addBlacklistBtn span").text().includes("已加入"),a,r;if(X.includes("/tags")){let p=new URL(X);p.searchParams.delete("page");let g=$("#jhs-check-tag").text().trim();a={starId:"no-"+g,name:"虚拟演员-"+g,allName:["虚拟演员"],role:"虚拟演员",movieType:g,blacklistUrl:p.toString()},r=`是否将分类 ${C(g)} 加入到黑名单中?`,s&&(r=`分类 ${C(g)} 已在黑名单中, 是否从当前页开始追加屏蔽?`)}else a=this.getActressPageInfo(),r=`是否将该演员 ${C(a.name)} 加入到黑名单中?`,s&&(r=`演员 ${C(a.name)} 已在黑名单中, 是否从当前页开始追加屏蔽?`);let{starId:i,name:n,allName:l,role:c,movieType:h,blacklistUrl:u}=a;if(X.includes("page")&&!X.includes("page=1")&&(r+=" 注意: 当前页面非第一页, 屏蔽数据将从此页面开始"),B){let p=X.split("/star/")[1].split("/");p.length>1&&parseInt(p[1])>1&&(r+=" 注意: 当前页面非第一页, 屏蔽数据将从此页面开始")}utils.q(t,r,(async()=>{let p=this.getOptionalDependency("TaskPlugin");if(!p)return void show.error("后台任务功能已禁用,无法执行黑名单抓取");navigator.locks.request(p.singleTaskKey,{ifAvailable:!0},(async g=>{if(clog.debug("获取锁",g),g){this.loadObj=loading();try{await storageManager.addBlacklistItem({starId:i,name:n,allName:l,role:c,movieType:h,url:u}),await this.filterActorVideo(n,i,null,B?Se:Be);let m=show.ok(`屏蔽结束,是否跳转到最后一页: ${this.lastPageLink}`,{duration:-1,close:!0,onClick:d(()=>{m.closeShow(),window.location.href=this.lastPageLink},"onClick")})}catch(m){clog.error(m);let f=show.error("发生错误, 是否填转到解析失败的那一页? (点击并跳转)",{duration:-1,close:!0,onClick:d(()=>{f.closeShow(),window.location.href=this.nextPageLink},"onClick")})}finally{this.loadObj.close()}}else show.error("当前有定时任务在后台执行中, 无法发起此操作")})).catch((g=>{clog.error("锁任务出现错误:",g)}))}))}async resetBtnTip(){let e=this.getOptionalDependency("TaskPlugin"),t=e?this.getRuntimeService("storage").getLocal(e.lastCheckBlacklistTimeKey)||"无":"任务已禁用",s=await storageManager.getSetting("checkBlacklist_intervalTime",12);this.checkBlacklist_ruleTime=await storageManager.getSetting("checkBlacklist_ruleTime",8760),(this.blacklistRoot||$()).find("#checkBlacklistBtn").attr("data-tip",`上次整批检测: ${t}; 检测间隔时间: ${s}小时`)}async openBlacklistDialog(){let e=this.getOptionalDependency("TaskPlugin"),t=await storageManager.getSetting(),a=`
+ `}async addBlacklist(e){let t={clientX:e.clientX,clientY:e.clientY+80},s=$("#addBlacklistBtn span").text().includes("已加入"),a,r;if(X.includes("/tags")){let p=new URL(X);p.searchParams.delete("page");let g=$("#jhs-check-tag").text().trim();a={starId:"no-"+g,name:"虚拟演员-"+g,allName:["虚拟演员"],role:"虚拟演员",movieType:g,blacklistUrl:p.toString()},r=`是否将分类 ${T(g)} 加入到黑名单中?`,s&&(r=`分类 ${T(g)} 已在黑名单中, 是否从当前页开始追加屏蔽?`)}else a=this.getActressPageInfo(),r=`是否将该演员 ${T(a.name)} 加入到黑名单中?`,s&&(r=`演员 ${T(a.name)} 已在黑名单中, 是否从当前页开始追加屏蔽?`);let{starId:i,name:n,allName:l,role:c,movieType:h,blacklistUrl:u}=a;if(X.includes("page")&&!X.includes("page=1")&&(r+=" 注意: 当前页面非第一页, 屏蔽数据将从此页面开始"),B){let p=X.split("/star/")[1].split("/");p.length>1&&parseInt(p[1])>1&&(r+=" 注意: 当前页面非第一页, 屏蔽数据将从此页面开始")}utils.q(t,r,(async()=>{let p=this.getOptionalDependency("TaskPlugin");if(!p)return void show.error("后台任务功能已禁用,无法执行黑名单抓取");navigator.locks.request(p.singleTaskKey,{ifAvailable:!0},(async g=>{if(clog.debug("获取锁",g),g){this.loadObj=loading();try{await storageManager.addBlacklistItem({starId:i,name:n,allName:l,role:c,movieType:h,url:u}),await this.filterActorVideo(n,i,null,B?Se:Be);let m=show.ok(`屏蔽结束,是否跳转到最后一页: ${this.lastPageLink}`,{duration:-1,close:!0,onClick:d(()=>{m.closeShow(),window.location.href=this.lastPageLink},"onClick")})}catch(m){clog.error(m);let f=show.error("发生错误, 是否填转到解析失败的那一页? (点击并跳转)",{duration:-1,close:!0,onClick:d(()=>{f.closeShow(),window.location.href=this.nextPageLink},"onClick")})}finally{this.loadObj.close()}}else show.error("当前有定时任务在后台执行中, 无法发起此操作")})).catch((g=>{clog.error("锁任务出现错误:",g)}))}))}async resetBtnTip(){let e=this.getOptionalDependency("TaskPlugin"),t=e?this.getRuntimeService("storage").getLocal(e.lastCheckBlacklistTimeKey)||"无":"任务已禁用",s=await storageManager.getSetting("checkBlacklist_intervalTime",12);this.checkBlacklist_ruleTime=await storageManager.getSetting("checkBlacklist_ruleTime",8760),(this.blacklistRoot||$()).find("#checkBlacklistBtn").attr("data-tip",`上次整批检测: ${t}; 检测间隔时间: ${s}小时`)}async openBlacklistDialog(){let e=this.getOptionalDependency("TaskPlugin"),t=await storageManager.getSetting(),a=`
- `;this.getRuntimeService("dialog").open({type:1,title:"演员黑名单",ui:{body:"table"},content:a,scrollbar:!1,area:utils.getDialogArea("xl"),anim:-1,success:d(async r=>{let i=$(r).find(".layui-layer-content > div").first().addClass("jhs-blacklist-layout").removeAttr("style");this.blacklistRoot=i;let n=i.children("div").first().addClass("jhs-blacklist-toolbar").removeAttr("style");n.children("div").addClass("jhs-blacklist-toolbar__group").removeAttr("style"),n.find("select,input,a").removeAttr("style"),i.find("#table-container").removeAttr("style"),i.find("#table-container").before('
'),K.enhance(r),e||i.find("#checkBlacklistBtn").prop("disabled",!0).attr("title","后台任务功能已禁用"),this.renderTaskStatus(),this.taskStatusUnsubscribe?.(),this.taskStatusUnsubscribe=cc().on("task-status-changed",(()=>this.renderTaskStatus())),await this.loadTableData();let l=$(r).find(".layui-layer-content"),c=l.find("#searchValue");this.blacklistSearchDebounced=utils.debounce((()=>{this.reloadTable()}),200),l.on("click","#cleanQueryBtn",(async()=>{c.val(""),K.setValue(this.blacklistRoot.find("#dataType"),"",!1),K.setValue(this.blacklistRoot.find("#statusType"),"",!1),K.setValue(this.blacklistRoot.find("#urlType"),"",!1),await this.reloadTable()})).on("input","#searchValue",this.blacklistSearchDebounced).on("change","#dataType,#statusType,#urlType",(async()=>{await this.reloadTable()})).on("click","#toSetting",(()=>{this.getOptionalDependency("SettingPlugin")?.openSettingDialog?.("task-panel",(()=>{$("#setting-blacklist").css({border:"1px solid var(--jhs-status-filter)"})}))})).on("click",".open-url",(h=>{h.preventDefault();let u=$(h.currentTarget),p=u.attr("data-url"),g=u.attr("data-name");utils.openPage(p,g,!0,h)})).on("click","#checkBlacklistBtn",(h=>{let u=$(h.currentTarget),p=u.find("span").last(),g=p.text();!e||u.attr("aria-busy")==="true"||(u.attr("aria-busy","true").prop("disabled",!0),p.text("检测中…"),navigator.locks.request(e.singleTaskKey,{ifAvailable:!0},(async m=>{m?await e.checkBlacklist(!0):show.error("后台任务正在运行,请稍后再试")})).catch((m=>{clog.error("锁任务出现错误:",m),e.isNetworkBlocked(m)&&show.error(m.message||"任务执行失败")})).finally((()=>{u.removeAttr("aria-busy").prop("disabled",!1),p.text(g)})))}))},"success"),end:d(async()=>{this.blacklistRoot=null,this.blacklistSearchDebounced?.cancel?.(),this.blacklistSearchDebounced=null,this.taskStatusUnsubscribe?.(),this.taskStatusUnsubscribe=null,this.tableObj&&(this.tableObj.destroy(),this.tableObj=null),await cc().emit("blacklist-rules-changed")},"end")})}renderTaskStatus(){let e=(this.blacklistRoot||$()).find("#blacklist-task-status");if(!e.length)return;let t=this.getOptionalDependency("TaskPlugin");if(!t)return void e.empty().text("后台任务功能已禁用");let s=t.getTaskStatusSnapshot("blacklist"),a={idle:"正常",running:"运行中",pending:"等待下一次任务检查",due:"待运行"},r=d(n=>n?new Date(n).toLocaleString():"无","format"),i=s.state;e.empty().append($('
').text(`黑名单:${a[i]||a.idle}`),$('
').text(`上次完成 ${r(s.completedAt)};下次检查 ${s.nextAt?r(s.nextAt):"立即"}`))}async reloadTable(){if(!this.tableObj)return;let e=await this.getTableData();this.tableObj.setData(e)}async getTableData(){let e=this.blacklistRoot||$(),t=await storageManager.getBlacklist(),s=await storageManager.getBlacklistCarList(),a=String(e.find("#searchValue").val()||"").trim().toLocaleLowerCase(),r=e.find("#statusType").val(),i=e.find("#dataType"),n=i.val(),l=e.find("#urlType").val(),c=t.length,h=0,u=0,p=t.map(f=>{f.role===Oe?h++:f.role===at&&u++;let v=!1;return v=gt(f.lastPublishTime,this.checkBlacklist_ruleTime),{...f,isUnCheck:v}}).filter(f=>{let v=Array.isArray(f.allName)?f.allName.join(" "):f.allName||"",b=`${f.name||""} ${v} ${f.starId||""}`.toLocaleLowerCase(),w=!a||b.includes(a),S=!r||r==="normal"&&!f.isUnCheck||r==="stop"&&f.isUnCheck,j=!n||f.role===n,x=f.url.includes("t=");return w&&S&&j&&(!l||l==="hasT"&&x||l==="noT"&&!x)});i.html(`
+ `;this.getRuntimeService("dialog").open({type:1,title:"演员黑名单",ui:{body:"table"},content:a,scrollbar:!1,area:utils.getDialogArea("xl"),anim:-1,success:d(async r=>{let i=$(r).find(".layui-layer-content > div").first().addClass("jhs-blacklist-layout").removeAttr("style");this.blacklistRoot=i;let n=i.children("div").first().addClass("jhs-blacklist-toolbar").removeAttr("style");n.children("div").addClass("jhs-blacklist-toolbar__group").removeAttr("style"),n.find("select,input,a").removeAttr("style"),i.find("#table-container").removeAttr("style"),i.find("#table-container").before('
'),K.enhance(r),e||i.find("#checkBlacklistBtn").prop("disabled",!0).attr("title","后台任务功能已禁用"),this.renderTaskStatus(),this.taskStatusUnsubscribe?.(),this.taskStatusUnsubscribe=dc().on("task-status-changed",(()=>this.renderTaskStatus())),await this.loadTableData();let l=$(r).find(".layui-layer-content"),c=l.find("#searchValue");this.blacklistSearchDebounced=utils.debounce((()=>{this.reloadTable()}),200),l.on("click","#cleanQueryBtn",(async()=>{c.val(""),K.setValue(this.blacklistRoot.find("#dataType"),"",!1),K.setValue(this.blacklistRoot.find("#statusType"),"",!1),K.setValue(this.blacklistRoot.find("#urlType"),"",!1),await this.reloadTable()})).on("input","#searchValue",this.blacklistSearchDebounced).on("change","#dataType,#statusType,#urlType",(async()=>{await this.reloadTable()})).on("click","#toSetting",(()=>{this.getOptionalDependency("SettingPlugin")?.openSettingDialog?.("task-panel",(()=>{$("#setting-blacklist").css({border:"1px solid var(--jhs-status-filter)"})}))})).on("click",".open-url",(h=>{h.preventDefault();let u=$(h.currentTarget),p=u.attr("data-url"),g=u.attr("data-name");utils.openPage(p,g,!0,h)})).on("click","#checkBlacklistBtn",(h=>{let u=$(h.currentTarget),p=u.find("span").last(),g=p.text();!e||u.attr("aria-busy")==="true"||(u.attr("aria-busy","true").prop("disabled",!0),p.text("检测中…"),navigator.locks.request(e.singleTaskKey,{ifAvailable:!0},(async m=>{m?await e.checkBlacklist(!0):show.error("后台任务正在运行,请稍后再试")})).catch((m=>{clog.error("锁任务出现错误:",m),e.isNetworkBlocked(m)&&show.error(m.message||"任务执行失败")})).finally((()=>{u.removeAttr("aria-busy").prop("disabled",!1),p.text(g)})))}))},"success"),end:d(async()=>{this.blacklistRoot=null,this.blacklistSearchDebounced?.cancel?.(),this.blacklistSearchDebounced=null,this.taskStatusUnsubscribe?.(),this.taskStatusUnsubscribe=null,this.tableObj&&(this.tableObj.destroy(),this.tableObj=null),await dc().emit("blacklist-rules-changed")},"end")})}renderTaskStatus(){let e=(this.blacklistRoot||$()).find("#blacklist-task-status");if(!e.length)return;let t=this.getOptionalDependency("TaskPlugin");if(!t)return void e.empty().text("后台任务功能已禁用");let s=t.getTaskStatusSnapshot("blacklist"),a={idle:"正常",running:"运行中",pending:"等待下一次任务检查",due:"待运行"},r=d(n=>n?new Date(n).toLocaleString():"无","format"),i=s.state;e.empty().append($('
').text(`黑名单:${a[i]||a.idle}`),$('
').text(`上次完成 ${r(s.completedAt)};下次检查 ${s.nextAt?r(s.nextAt):"立即"}`))}async reloadTable(){if(!this.tableObj)return;let e=await this.getTableData();this.tableObj.setData(e)}async getTableData(){let e=this.blacklistRoot||$(),t=await storageManager.getBlacklist(),s=await storageManager.getBlacklistCarList(),a=String(e.find("#searchValue").val()||"").trim().toLocaleLowerCase(),r=e.find("#statusType").val(),i=e.find("#dataType"),n=i.val(),l=e.find("#urlType").val(),c=t.length,h=0,u=0,p=t.map(f=>{f.role===Oe?h++:f.role===at&&u++;let v=!1;return v=mt(f.lastPublishTime,this.checkBlacklist_ruleTime),{...f,isUnCheck:v}}).filter(f=>{let v=Array.isArray(f.allName)?f.allName.join(" "):f.allName||"",b=`${f.name||""} ${v} ${f.starId||""}`.toLocaleLowerCase(),w=!a||b.includes(a),S=!r||r==="normal"&&!f.isUnCheck||r==="stop"&&f.isUnCheck,j=!n||f.role===n,k=f.url.includes("t=");return w&&S&&j&&(!l||l==="hasT"&&k||l==="noT"&&!k)});i.html(`
所有 (${c})
男演员 (${h})
女演员 (${u})
- `),K.setValue(i,n,!1);let g=new Map;for(let f of s){let v=f.starId;g.has(v)||g.set(v,[]),g.get(v).push(f)}let m=p.map(f=>{let v=f.starId,b=g.get(v)||[];return{...f,carList:b,count:b.length}});return this.currentCarCount=m.reduce(((f,v)=>f+(v.count||0)),0),m}async loadTableData(){this.checkBlacklist_ruleTime=ae(await storageManager.getSetting("checkBlacklist_ruleTime"),8760,{min:0});let e=await this.getTableData(),t=document.createElement("div");Ue(t,{type:"empty",title:"没有符合当前筛选条件的黑名单记录"});let s=(this.blacklistRoot||$()).find("#table-container").get(0);this.tableObj=ze(globalThis.Tabulator,s,{layout:"fitColumns",placeholder:t,virtualDom:!0,data:e,pagination:!0,paginationMode:"local",paginationSize:20,paginationSizeSelector:[20,50,100,1e3],paginationCounter:d((a,r,i,n,l)=>`演员: ${n} 番号总数: ${this.currentCarCount}
`,"paginationCounter"),responsiveLayout:"collapse",responsiveLayoutCollapse:!0,columnDefaults:{headerHozAlign:"center",hozAlign:"center"},index:"starId",columns:[{title:"演员",field:"name",sorter:"string",minWidth:100,responsive:0,headerSort:!1,formatter:d((a,r,i)=>{let n=a.getData(),l=Ye(n.url),c=document.createElement("a");return c.className="open-url",c.textContent=String(n.name||""),c.dataset.name=String(n.name||""),l?(c.href=l,c.dataset.url=l,c.target="_blank",c.rel="noopener noreferrer"):(c.href="#",c.setAttribute("aria-disabled","true")),c},"formatter")},{title:"性别角色",field:"role",sorter:"string",width:120,responsive:5,formatter:d((a,r,i)=>{let n=a.getData().role,l=n;return n===Oe?l="男演员":n===at&&(l="女演员"),l},"formatter")},{title:"影视类别",field:"movieType",sorter:"string",width:120,responsive:5,formatter:d((a,r,i)=>{let n=a.getData().movieType,l=n;return n===We?l="有码":n===Ke&&(l="无码"),l},"formatter")},{title:"屏蔽类型",field:"url",sorter:"string",minWidth:120,responsive:4,visible:M,formatter:d((a,r,i)=>{let n=a.getData().url.includes("t=");return`
${n?"按所选分类屏蔽":"未筛选分类"} `},"formatter")},{title:"番号数量",field:"count",sorter:"number",width:170,responsive:1},{title:"创建时间",field:"createTime",sorter:"string",width:170,responsive:5},{title:"最后发行时间",field:"lastPublishTime",sorter:"string",width:170,responsive:1},{title:"状态",field:"isUnCheck",sorter:"string",width:120,responsive:1,formatter:d((a,r,i)=>{let n="",l="继续检测";return a.getData().isUnCheck&&(n=`停更${this.checkBlacklist_ruleTime/24/365}年以上, 下轮任务不再进行检测`,l="停更跳过"),`
${l} `},"formatter")},{title:"操作",sorter:"string",cssClass:"action-cell-dropdown",minWidth:150,responsive:0,headerSort:!1,formatter:d((a,r,i)=>{let n=a.getData();return i((()=>{var l,c;(l=a.getElement().querySelector(".delete-btn"))==null||l.addEventListener("click",(h=>{let u=n.name,p=n.starId;u?p?utils.q(h,`是否移除对 ${C(u)} 的屏蔽?`,(async()=>{await storageManager.removeBlacklistCarList(p),await storageManager.deleteBlacklistItem(p),show.info("操作成功"),await this.reloadTable()})):show.error("获取starId失败"):show.error("获取名称失败")})),(c=a.getElement().querySelector(".keyword-btn"))==null||c.addEventListener("click",(h=>{let u=n.carList.reduce(((g,m)=>{let f=m.carNum.split("-")[0]+"-";return g[f]=(g[f]||0)+1,g}),{}),p=Object.entries(u).map((([g,m])=>({prefix:g,count:m}))).sort(((g,m)=>m.count-g.count));clog.debug(p)}))})),'
删除 '},"formatter")}],initialSort:[{column:"createTime",dir:"desc"}]})}async filterAllVideo(e,{filter:t=this.getOptionalDependency("ListPagePlugin")?.activeQuickFilter||"waitCheck",confirm:s=!0,root:a=null}={}){let r=Ae(t),i=Ee[r],n=r==="all"?"将处理当前搜索全部分页的所有作品(包括屏蔽项)并加入黑名单。":`将处理当前搜索全部分页中符合「${i}」筛选的作品并加入黑名单。`;if(s&&!await new Promise(u=>utils.q(null,n,()=>u(!0),()=>u(!1))))return{cancelled:!0};let l=Vs();if(!l)return show.error("已有批量任务正在执行"),{cancelled:!0,busy:!0};let c=d(()=>(this.blacklistRoot||$()).find("#checkBlacklistMsg"),"statusHost");try{$("#favoriteAllVideo, #hasDownAllVideo, #filterAllVideo").attr("aria-disabled","true").addClass("jhs-batch-busy");let h=await this.getRuntimeService("scope")(),u=this.getOptionalDependency("ListPagePlugin"),p=typeof u?.createEvaluationContext=="function"?await u.createEvaluationContext():is({}),g=d(()=>!Nt(l)||!!h?.disposed,"isCancelled"),m=await Fs({startDom:a?$(a):$(document),currentUrl:a?null:window.location.href,firstPageUrl:a?null:this.getRuntimeService("host")?.resolveFirstPageUrl?.(window.location.href)??window.location.href,itemSelector:this.getSelector().requestDomItemSelector,nextPageSelector:this.getSelector().nextPageSelector,fetchHtml:d(async b=>He(this.getRuntimeService("http"),b,h),"fetchHtml"),parseItem:d(b=>_e(b),"parseItem"),evaluate:d(b=>ns({carNum:b.carNum,title:b.title||""},p,{filter:r}),"evaluate"),isCancelled:g,onProgress:d(({page:b,scanned:w,matched:S})=>{let j=c();j.length&&j.text(`正在扫描第 ${b} 页 · 已扫描 ${w} · 匹配 ${S} 个番号`)},"onProgress")});if(g())return{cancelled:!0};let f=0;for(let b=0;b
S.carNum),{blocked:!0},{type:"actor-page-block",records:w.map(S=>({carNum:S.carNum,url:S.url||"",names:e,publishTime:S.publishTime||"",fc2Source:S.fc2Source}))}),f+=w.length,clog.log("一键屏蔽进度",`已屏蔽 ${f}/${m.length} 个番号`)}let v=c();return v.length&&v.text(`处理完成 · 共屏蔽 ${f} 个番号`),{matched:m.length,updated:f}}finally{Nt(l)&&Hs(l),$("#favoriteAllVideo, #hasDownAllVideo, #filterAllVideo").removeAttr("aria-disabled").removeClass("jhs-batch-busy")}}async filterActorVideo(e,t,s,a=B?Se:Be,r=1,i=0,n=new Set){let{nextPageLink:l,recordCount:c}=await this.parseAndSaveFilterInfo(s,e,t,a);if(i+=c,(this.blacklistRoot||$()).find("#checkBlacklistMsg").text(`正在处理第 ${r} 页 · 已屏蔽 ${i} 个番号`),this.nextPageLink=l,l&&r<200&&!n.has(l)){n.add(l);let h;this.lastPageLink=l,clog.log("正在请求下一页内容:",l);let u=await this.getRuntimeService("scope")(),p=await He(this.getRuntimeService("http"),l,u);h=utils.htmlTo$dom(p),await this.filterActorVideo(e,t,h,a,r+1,i,n)}else r>=200?((this.blacklistRoot||$()).find("#checkBlacklistMsg").text(`已达到页数上限(200 页),已停止 · 已屏蔽 ${i} 个番号`),clog.warn("演员视频分页扫描已达上限,已停止")):(this.blacklistRoot||$()).find("#checkBlacklistMsg").text(`处理完成 · ${r} 页 · 新增 ${i} 个番号`)}async parseAndSaveFilterInfo(e,t,s,a){if(![Be,Se].includes(a))throw new Error(`未知黑名单来源站点: ${a}`);let r=e||$(document),i=this.getSelector(a);a===Se&&r.find(".avatar-box").length>0&&r.find(".avatar-box").parent().remove();let n=qs(r,{boxSelector:a===Se?`${i.boxSelector}, #waterfall`:i.boxSelector,requestDomItemSelector:e?i.requestDomItemSelector:i.itemSelector}),l=r.find(i.nextPageSelector).attr("href");if(n.state!=="valid")throw new Error(`黑名单作品页面无效: ${n.state}`);if(n.isEmpty&&l)throw new Error("黑名单作品空页面包含下一页");let c=[],h=[];for(let u of n.items){let p=$(u),{carNum:g,url:m,publishTime:f}=_e(p);f&&h.push(f),m&&g&&c.push({carNum:g,url:m,names:t,actionType:ce,starId:s,publishTime:f})}return await storageManager.batchSaveBlacklistCarList(c),{nextPageLink:l,lastPublishTime:Gt(h),recordCount:c.length}}};d(Ai,"BlacklistPlugin");var Js=Ai;var Pi=class Pi extends I{getName(){return"FilterTitleKeywordPlugin"}async handle(){isDetailPage&&await this.bindDetailRoot(document)}async bindDetailRoot(e,{layerIndex:t=null}={}){if(await storageManager.getSetting("enableTitleSelectFilter",R)!==R)return;let s=$(e),a=M?".title strong, .current-title":B?"h3":".current-title, .origin-title, .jhs-detail-title";s.off("contextmenu.jhsTitleFilter",a).on("contextmenu.jhsTitleFilter",a,(r=>{let i=window.getSelection()?.toString()||"";if(i){r.preventDefault();let n={clientX:r.clientX,clientY:r.clientY+80};utils.q(n,`是否屏蔽标题关键词 ${C(i)}?`,(async()=>{let l=i.replace(/\r?\n+/g," ").replace(/\s{2,}/g," ").trim().slice(0,120);l&&await storageManager.saveTitleFilterKeyword(l),await V?.emit("filter-rules-changed",{scope:"title-keyword"}),utils.closePage({root:s,layerIndex:t})}))}}))}};d(Pi,"FilterTitleKeywordPlugin");var Ws=Pi;function Ks(o,{retry:e=null,tone:t="neutral",extraClass:s=""}={}){let a=globalThis.$,r=a('
').text(o);return s&&r.addClass(s),t==="error"&&r.addClass("is-error"),e&&r.append(" ",a('重试 ').on("click",e)),r}d(Ks,"createPanelState");function dc(o="正在加载…"){return Ks(o)}d(dc,"createPanelLoading");function hc(o,e=null){return Ks(o,{retry:e,tone:"error"})}d(hc,"createPanelError");function Ii(o){try{let e=new URL(String(o||""));return["http:","https:"].includes(e.protocol)?e.href:null}catch{return null}}d(Ii,"normalizeUrl");function he(o,e,t=null){let s=globalThis.$,a=s(o).empty(),r=Ks(e,{retry:t,tone:t?"error":"neutral",extraClass:"jhs-fc2-state"});a.append(r)}d(he,"renderFc2State");function os(o,e,t=null){let s=globalThis.$,a=[...new Set((e||[]).map(Ii).filter(Boolean))],r=o.root.find('[data-jhs-role="gallery-grid"]').empty(),i=o.root.find('[data-jhs-role="main-preview"]').empty();o.galleryUrls=new Set(a);let n=Ii(t);if(n&&i.append(s(" ").attr({src:n,alt:`${o.carNum} 概览`,loading:"eager"})),!a.length)return he(r,"暂无剧照");a.forEach((c,h)=>r.append(s(' ').attr("aria-label",`查看剧照 ${h+1}`).append(s(" ").addClass("jhs-fc2-gallery__image").attr({src:c,alt:`剧照 ${h+1}`,loading:"lazy"}))));let l=o.root.find('[data-jhs-role="screenshot"]');l.find("img").each((c,h)=>{let u=h.getAttribute("src");u&&o.galleryUrls.has(u)&&l.empty()})}d(os,"renderFc2Gallery");function Gs(o,e){let t=globalThis.$,s=t('
'),a=e.sourceUrls({carNum:o.carNum},["fc2ppvdb","fc2content"]);return[[o.source==="123av"?"123AV 原页面":"JavDB 原页面",Ii(o.url)],...a.map(i=>[i.providerId==="fc2ppvdb"?"FC2PPVDB":"FC2 市场",i.url])].forEach(([i,n])=>n&&s.append(t(" ").addClass("jhs-btn jhs-btn--ghost jhs-btn--sm").attr({href:n,target:"_blank",rel:"noopener noreferrer"}).text(i))),s}d(Gs,"createFc2SourceLinks");var Ri=class Ri extends I{constructor(){super(...arguments),this.$contentBox=null,this.$listRoot=null,this.urlParams=new URLSearchParams(window.location.search),this.currentPage=Math.max(1,parseInt(this.urlParams.get("page")||"1",10)||1),this.maxPage=null,this._queryGeneration=0,this.keyword=this.urlParams.get("keyword")||null}getName(){return"Fc2By123AvPlugin"}async resolveMovieId(e){let t=await this.getRuntimeService("scope")();return(await this.getRuntimeService("movie").resolve({carNum:e},{scope:t}))?.movieId||null}async handle(){let e=document.querySelector('#navbar-menu-hero a[href^="/tags/fc2"]');if(e&&!document.querySelector("#jhs-123av-nav")){let t=document.createElement("a");t.id="jhs-123av-nav",t.className="navbar-item",t.href="/tags/fc2?c10=1&jhs_source=123av",t.textContent="123AV · FC2片库",e.after(t)}je(window.location).kind==="external-fc2-catalog"&&(this.hookPage(),await this.handleQuery())}hookPage(){let e=this.getRuntimeService("host"),t=e.locateListRoot?.(),s=e.getListContainer?.();if(!t||!s)throw new Error("JavDB 列表容器不可用");this.$contentBox=$(s),this.$listRoot=$(e.createOwnedListRoot(["jhs-123av-list","jhs-layout-d2c171b1"]));let a=this.$contentBox.find("h2.section-title").first();a.length||(a=$(" ").addClass("section-title").prependTo(this.$contentBox)),a.text("123AV · FC2片库"),a.css("marginBottom","0"),a.append(`
+ `),K.setValue(i,n,!1);let g=new Map;for(let f of s){let v=f.starId;g.has(v)||g.set(v,[]),g.get(v).push(f)}let m=p.map(f=>{let v=f.starId,b=g.get(v)||[];return{...f,carList:b,count:b.length}});return this.currentCarCount=m.reduce(((f,v)=>f+(v.count||0)),0),m}async loadTableData(){this.checkBlacklist_ruleTime=ae(await storageManager.getSetting("checkBlacklist_ruleTime"),8760,{min:0});let e=await this.getTableData(),t=document.createElement("div");Ue(t,{type:"empty",title:"没有符合当前筛选条件的黑名单记录"});let s=(this.blacklistRoot||$()).find("#table-container").get(0);this.tableObj=ze(globalThis.Tabulator,s,{layout:"fitColumns",placeholder:t,virtualDom:!0,data:e,pagination:!0,paginationMode:"local",paginationSize:20,paginationSizeSelector:[20,50,100,1e3],paginationCounter:d((a,r,i,n,l)=>`演员: ${n} 番号总数: ${this.currentCarCount} `,"paginationCounter"),responsiveLayout:"collapse",responsiveLayoutCollapse:!0,columnDefaults:{headerHozAlign:"center",hozAlign:"center"},index:"starId",columns:[{title:"演员",field:"name",sorter:"string",minWidth:100,responsive:0,headerSort:!1,formatter:d((a,r,i)=>{let n=a.getData(),l=Ye(n.url),c=document.createElement("a");return c.className="open-url",c.textContent=String(n.name||""),c.dataset.name=String(n.name||""),l?(c.href=l,c.dataset.url=l,c.target="_blank",c.rel="noopener noreferrer"):(c.href="#",c.setAttribute("aria-disabled","true")),c},"formatter")},{title:"性别角色",field:"role",sorter:"string",width:120,responsive:5,formatter:d((a,r,i)=>{let n=a.getData().role,l=n;return n===Oe?l="男演员":n===at&&(l="女演员"),l},"formatter")},{title:"影视类别",field:"movieType",sorter:"string",width:120,responsive:5,formatter:d((a,r,i)=>{let n=a.getData().movieType,l=n;return n===Je?l="有码":n===Ke&&(l="无码"),l},"formatter")},{title:"屏蔽类型",field:"url",sorter:"string",minWidth:120,responsive:4,visible:M,formatter:d((a,r,i)=>{let n=a.getData().url.includes("t=");return`${n?"按所选分类屏蔽":"未筛选分类"} `},"formatter")},{title:"番号数量",field:"count",sorter:"number",width:170,responsive:1},{title:"创建时间",field:"createTime",sorter:"string",width:170,responsive:5},{title:"最后发行时间",field:"lastPublishTime",sorter:"string",width:170,responsive:1},{title:"状态",field:"isUnCheck",sorter:"string",width:120,responsive:1,formatter:d((a,r,i)=>{let n="",l="继续检测";return a.getData().isUnCheck&&(n=`停更${this.checkBlacklist_ruleTime/24/365}年以上, 下轮任务不再进行检测`,l="停更跳过"),`${l} `},"formatter")},{title:"操作",sorter:"string",cssClass:"action-cell-dropdown",minWidth:150,responsive:0,headerSort:!1,formatter:d((a,r,i)=>{let n=a.getData();return i((()=>{var l,c;(l=a.getElement().querySelector(".delete-btn"))==null||l.addEventListener("click",(h=>{let u=n.name,p=n.starId;u?p?utils.q(h,`是否移除对 ${T(u)} 的屏蔽?`,(async()=>{await storageManager.removeBlacklistCarList(p),await storageManager.deleteBlacklistItem(p),show.info("操作成功"),await this.reloadTable()})):show.error("获取starId失败"):show.error("获取名称失败")})),(c=a.getElement().querySelector(".keyword-btn"))==null||c.addEventListener("click",(h=>{let u=n.carList.reduce(((g,m)=>{let f=m.carNum.split("-")[0]+"-";return g[f]=(g[f]||0)+1,g}),{}),p=Object.entries(u).map((([g,m])=>({prefix:g,count:m}))).sort(((g,m)=>m.count-g.count));clog.debug(p)}))})),'删除 '},"formatter")}],initialSort:[{column:"createTime",dir:"desc"}]})}async filterAllVideo(e,{filter:t=this.getOptionalDependency("ListPagePlugin")?.activeQuickFilter||"waitCheck",confirm:s=!0,root:a=null}={}){let r=_e(t),i=Pe[r],n=r==="all"?"将处理当前搜索全部分页的所有作品(包括屏蔽项)并加入黑名单。":`将处理当前搜索全部分页中符合「${i}」筛选的作品并加入黑名单。`;if(s&&!await new Promise(u=>utils.q(null,n,()=>u(!0),()=>u(!1))))return{cancelled:!0};let l=qs();if(!l)return show.error("已有批量任务正在执行"),{cancelled:!0,busy:!0};let c=d(()=>(this.blacklistRoot||$()).find("#checkBlacklistMsg"),"statusHost");try{$("#favoriteAllVideo, #hasDownAllVideo, #filterAllVideo").attr("aria-disabled","true").addClass("jhs-batch-busy");let h=await this.getRuntimeService("scope")(),u=this.getOptionalDependency("ListPagePlugin"),p=typeof u?.createEvaluationContext=="function"?await u.createEvaluationContext():is({}),g=d(()=>!Lt(l)||!!h?.disposed,"isCancelled"),m=await Vs({startDom:a?$(a):$(document),currentUrl:a?null:window.location.href,firstPageUrl:a?null:this.getRuntimeService("host")?.resolveFirstPageUrl?.(window.location.href)??window.location.href,itemSelector:this.getSelector().requestDomItemSelector,nextPageSelector:this.getSelector().nextPageSelector,fetchHtml:d(async b=>qe(this.getRuntimeService("http"),b,h),"fetchHtml"),parseItem:d(b=>$e(b),"parseItem"),evaluate:d(b=>ns({carNum:b.carNum,title:b.title||""},p,{filter:r}),"evaluate"),isCancelled:g,onProgress:d(({page:b,scanned:w,matched:S})=>{let j=c();j.length&&j.text(`正在扫描第 ${b} 页 · 已扫描 ${w} · 匹配 ${S} 个番号`)},"onProgress")});if(g())return{cancelled:!0};let f=0;for(let b=0;bS.carNum),{blocked:!0},{type:"actor-page-block",records:w.map(S=>({carNum:S.carNum,url:S.url||"",names:e,publishTime:S.publishTime||"",fc2Source:S.fc2Source}))}),f+=w.length,clog.log("一键屏蔽进度",`已屏蔽 ${f}/${m.length} 个番号`)}let v=c();return v.length&&v.text(`处理完成 · 共屏蔽 ${f} 个番号`),{matched:m.length,updated:f}}finally{Lt(l)&&Hs(l),$("#favoriteAllVideo, #hasDownAllVideo, #filterAllVideo").removeAttr("aria-disabled").removeClass("jhs-batch-busy")}}async filterActorVideo(e,t,s,a=B?Se:Be,r=1,i=0,n=new Set){let{nextPageLink:l,recordCount:c}=await this.parseAndSaveFilterInfo(s,e,t,a);if(i+=c,(this.blacklistRoot||$()).find("#checkBlacklistMsg").text(`正在处理第 ${r} 页 · 已屏蔽 ${i} 个番号`),this.nextPageLink=l,l&&r<200&&!n.has(l)){n.add(l);let h;this.lastPageLink=l,clog.log("正在请求下一页内容:",l);let u=await this.getRuntimeService("scope")(),p=await qe(this.getRuntimeService("http"),l,u);h=utils.htmlTo$dom(p),await this.filterActorVideo(e,t,h,a,r+1,i,n)}else r>=200?((this.blacklistRoot||$()).find("#checkBlacklistMsg").text(`已达到页数上限(200 页),已停止 · 已屏蔽 ${i} 个番号`),clog.warn("演员视频分页扫描已达上限,已停止")):(this.blacklistRoot||$()).find("#checkBlacklistMsg").text(`处理完成 · ${r} 页 · 新增 ${i} 个番号`)}async parseAndSaveFilterInfo(e,t,s,a){if(![Be,Se].includes(a))throw new Error(`未知黑名单来源站点: ${a}`);let r=e||$(document),i=this.getSelector(a);a===Se&&r.find(".avatar-box").length>0&&r.find(".avatar-box").parent().remove();let n=Ws(r,{boxSelector:a===Se?`${i.boxSelector}, #waterfall`:i.boxSelector,requestDomItemSelector:e?i.requestDomItemSelector:i.itemSelector}),l=r.find(i.nextPageSelector).attr("href");if(n.state!=="valid")throw new Error(`黑名单作品页面无效: ${n.state}`);if(n.isEmpty&&l)throw new Error("黑名单作品空页面包含下一页");let c=[],h=[];for(let u of n.items){let p=$(u),{carNum:g,url:m,publishTime:f}=$e(p);f&&h.push(f),m&&g&&c.push({carNum:g,url:m,names:t,actionType:ce,starId:s,publishTime:f})}return await storageManager.batchSaveBlacklistCarList(c),{nextPageLink:l,lastPublishTime:Qt(h),recordCount:c.length}}};d(Pi,"BlacklistPlugin");var Js=Pi;var Ri=class Ri extends I{getName(){return"FilterTitleKeywordPlugin"}async handle(){isDetailPage&&await this.bindDetailRoot(document)}async bindDetailRoot(e,{layerIndex:t=null}={}){if(await storageManager.getSetting("enableTitleSelectFilter",E)!==E)return;let s=$(e),a=M?".title strong, .current-title":B?"h3":".current-title, .origin-title, .jhs-detail-title";s.off("contextmenu.jhsTitleFilter",a).on("contextmenu.jhsTitleFilter",a,(r=>{let i=window.getSelection()?.toString()||"";if(i){r.preventDefault();let n={clientX:r.clientX,clientY:r.clientY+80};utils.q(n,`是否屏蔽标题关键词 ${T(i)}?`,(async()=>{let l=i.replace(/\r?\n+/g," ").replace(/\s{2,}/g," ").trim().slice(0,120);l&&await storageManager.saveTitleFilterKeyword(l),await V?.emit("filter-rules-changed",{scope:"title-keyword"}),utils.closePage({root:s,layerIndex:t})}))}}))}};d(Ri,"FilterTitleKeywordPlugin");var Ks=Ri;function Gs(o,{retry:e=null,tone:t="neutral",extraClass:s=""}={}){let a=globalThis.$,r=a('
').text(o);return s&&r.addClass(s),t==="error"&&r.addClass("is-error"),e&&r.append(" ",a('重试 ').on("click",e)),r}d(Gs,"createPanelState");function hc(o="正在加载…"){return Gs(o)}d(hc,"createPanelLoading");function uc(o,e=null){return Gs(o,{retry:e,tone:"error"})}d(uc,"createPanelError");function Ii(o){try{let e=new URL(String(o||""));return["http:","https:"].includes(e.protocol)?e.href:null}catch{return null}}d(Ii,"normalizeUrl");function he(o,e,t=null){let s=globalThis.$,a=s(o).empty(),r=Gs(e,{retry:t,tone:t?"error":"neutral",extraClass:"jhs-fc2-state"});a.append(r)}d(he,"renderFc2State");function os(o,e,t=null){let s=globalThis.$,a=[...new Set((e||[]).map(Ii).filter(Boolean))],r=o.root.find('[data-jhs-role="gallery-grid"]').empty(),i=o.root.find('[data-jhs-role="main-preview"]').empty();o.galleryUrls=new Set(a);let n=Ii(t);if(n&&i.append(s(" ").attr({src:n,alt:`${o.carNum} 概览`,loading:"eager"})),!a.length)return he(r,"暂无剧照");a.forEach((c,h)=>r.append(s(' ').attr("aria-label",`查看剧照 ${h+1}`).append(s(" ").addClass("jhs-fc2-gallery__image").attr({src:c,alt:`剧照 ${h+1}`,loading:"lazy"}))));let l=o.root.find('[data-jhs-role="screenshot"]');l.find("img").each((c,h)=>{let u=h.getAttribute("src");u&&o.galleryUrls.has(u)&&l.empty()})}d(os,"renderFc2Gallery");function Qs(o,e){let t=globalThis.$,s=t('
'),a=e.sourceUrls({carNum:o.carNum},["fc2ppvdb","fc2content"]);return[[o.source==="123av"?"123AV 原页面":"JavDB 原页面",Ii(o.url)],...a.map(i=>[i.providerId==="fc2ppvdb"?"FC2PPVDB":"FC2 市场",i.url])].forEach(([i,n])=>n&&s.append(t(" ").addClass("jhs-btn jhs-btn--ghost jhs-btn--sm").attr({href:n,target:"_blank",rel:"noopener noreferrer"}).text(i))),s}d(Qs,"createFc2SourceLinks");var Ei=class Ei extends I{constructor(){super(...arguments),this.$contentBox=null,this.$listRoot=null,this.urlParams=new URLSearchParams(window.location.search),this.currentPage=Math.max(1,parseInt(this.urlParams.get("page")||"1",10)||1),this.maxPage=null,this._queryGeneration=0,this.keyword=this.urlParams.get("keyword")||null}getName(){return"Fc2By123AvPlugin"}async resolveMovieId(e){let t=await this.getRuntimeService("scope")();return(await this.getRuntimeService("movie").resolve({carNum:e},{scope:t}))?.movieId||null}async handle(){let e=document.querySelector('#navbar-menu-hero a[href^="/tags/fc2"]');if(e&&!document.querySelector("#jhs-123av-nav")){let t=document.createElement("a");t.id="jhs-123av-nav",t.className="navbar-item",t.href="/tags/fc2?c10=1&jhs_source=123av",t.textContent="123AV · FC2片库",e.after(t)}je(window.location).kind==="external-fc2-catalog"&&(this.hookPage(),await this.handleQuery())}hookPage(){let e=this.getRuntimeService("host"),t=e.locateListRoot?.(),s=e.getListContainer?.();if(!t||!s)throw new Error("JavDB 列表容器不可用");this.$contentBox=$(s),this.$listRoot=$(e.createOwnedListRoot(["jhs-123av-list","jhs-layout-d2c171b1"]));let a=this.$contentBox.find("h2.section-title").first();a.length||(a=$(" ").addClass("section-title").prependTo(this.$contentBox)),a.text("123AV · FC2片库"),a.css("marginBottom","0"),a.append(`
搜索
@@ -3200,20 +3195,20 @@
- `),$(document).on("click",".pagination-link",(r=>{r.preventDefault(),this.currentPage=parseInt($(r.target).data("page")),utils.setHrefParam("page",this.currentPage),this.renderPagination(),this.handleQuery()})),$(".pagination-previous").on("click",(r=>{r.preventDefault(),this.currentPage>1&&(this.currentPage--,utils.setHrefParam("page",this.currentPage),this.renderPagination(),this.handleQuery())})),$(".pagination-next").on("click",(r=>{r.preventDefault(),this.currentPage<(this.maxPage??0)&&(this.currentPage++,utils.setHrefParam("page",this.currentPage),this.renderPagination(),this.handleQuery())}))}renderPagination(){let e=$(".pagination-list");e.empty();let t=this.maxPage??1,s=Math.max(1,this.currentPage-2),a=Math.min(t,this.currentPage+2);this.currentPage<=3?a=Math.min(6,t):this.currentPage>=t-2&&(s=Math.max(t-5,1)),s>1&&(e.append('
'),s>2&&e.append('
'));for(let r=s;r<=a;r++){let i=r===this.currentPage?" is-current":"";e.append(`
`)}a
'),e.append(` `))}async handleQuery(){let e=loading(),t=++this._queryGeneration;try{$(".page-box").show();let s=await this.getRuntimeService("scope")();if(t!==this._queryGeneration)return;let a=await this.getRuntimeService("movie").catalog("av123",{page:this.currentPage,keyword:this.keyword||""},{scope:s});if(t!==this._queryGeneration)return;let r=a.items;this.maxPage=Math.max(1,Number(a.maxPage)||1),this.currentPage=Math.min(Math.max(1,this.currentPage),this.maxPage),this.renderPagination(),r.length===0&&(clog.log(r),show.error("无结果"),clog.error("123AV 获取数据失败"));let i=this.markDataListHtml(r);this.$listRoot?.html(i);let n=this.getOptionalDependency("ListPagePlugin");n&&this.$listRoot&&await n.processAddedItems?.(this.$listRoot.find(".item").toArray()),await utils.smoothScrollToTop()}catch(s){clog.error(s)}finally{e.close()}}async loadDetail(e,t){let s=this.loadSummary(e,t),a=this.getImgList(e.carNum),r=this.getActressInfo(e.carNum);a.then((i=>e.isAlive()&&os(e,i,null))).catch((i=>e.isAlive()&&he(e.root.find('[data-jhs-role="gallery-grid"]'),"剧照加载失败",(()=>{this.reloadImages(e)})))),r.then((async i=>{await s.catch((()=>null)),e.isAlive()&&this.render123AvActress(e,i)})).catch((i=>clog.error("FC2 演员信息加载失败",i))),await Promise.allSettled([s,a,r])}async loadSummary(e,t){try{let s=await this.get123AvVideoInfo(e.carNum,t);return e.isAlive()?(this.render123AvSummary(e,s),s):null}catch(s){throw e.isAlive()&&he(e.root.find('[data-jhs-role="summary-content"]'),"影片信息加载失败",(()=>{this.loadSummary(e,t)})),clog.error("123AV 详情加载失败",s),s}}render123AvSummary(e,t){let s=e.root.find('[data-jhs-role="summary-content"]').empty(),a=$(' ');a.find("strong").text(t.title||"无标题"),s.append(a,$('
').append($(" ").text(`番号:${e.carNum}`),$(" ").text(`发行:${t.publishDate||"未知"}`)),'主演: 正在加载演员…
','
',Gs(e,this.getRuntimeService("movie")),$(' ').text(t.publishDate||""))}async get123AvVideoInfo(e,t){let s=await this.getRuntimeService("scope")(),a=await this.getRuntimeService("movie").detail({carNum:e,url:t,providerId:"av123"},{scope:s});return{title:a?.title||"",publishDate:a?.releaseDate||"",moviePoster:null}}async getActressInfo(e){let t=await this.getRuntimeService("scope")();return this.getRuntimeService("movie").people("fc2ppvdb",{carNum:e},{scope:t})}async getImgList(e){let t=await this.getRuntimeService("scope")();return(await this.getRuntimeService("movie").images("fc2content",{carNum:e},{scope:t})).map((s=>s.url))}async reloadImages(e){try{let t=await this.getImgList(e.carNum);e.isAlive()&&os(e,t,null)}catch{e.isAlive()&&he(e.root.find('[data-jhs-role="gallery-grid"]'),"剧照加载失败",(()=>{this.reloadImages(e)}))}}render123AvActress(e,t){let s=e.root.find('[data-jhs-role="actors"]').empty().append("主演: ");t.actors.length?t.actors.forEach((a=>s.append($(" ").addClass("jhs-fc2-actor").attr({href:a.url,target:"_blank",rel:"noopener noreferrer"}).text(a.name)))):s.append($(" ").text("暂无演员信息")),e.root.find('[data-jhs-role="actress-data"]').remove(),e.root.find(".jhs-fc2-summary__body").append($(' ').text(t.actors.map((a=>a.name)).join(" "))),t.seller&&e.root.find('[data-jhs-role="seller"]').empty().append("卖家:",t.seller.url?$(" ").attr({href:t.seller.url,target:"_blank",rel:"noopener noreferrer"}).text(t.seller.name):document.createTextNode(t.seller.name))}markDataListHtml(e){let t="";return e.forEach((s=>{let a=Ye(s.url),r=Ye(s.imageUrl);a&&(t+=`
+ `),$(document).on("click",".pagination-link",(r=>{r.preventDefault(),this.currentPage=parseInt($(r.target).data("page")),utils.setHrefParam("page",this.currentPage),this.renderPagination(),this.handleQuery()})),$(".pagination-previous").on("click",(r=>{r.preventDefault(),this.currentPage>1&&(this.currentPage--,utils.setHrefParam("page",this.currentPage),this.renderPagination(),this.handleQuery())})),$(".pagination-next").on("click",(r=>{r.preventDefault(),this.currentPage<(this.maxPage??0)&&(this.currentPage++,utils.setHrefParam("page",this.currentPage),this.renderPagination(),this.handleQuery())}))}renderPagination(){let e=$(".pagination-list");e.empty();let t=this.maxPage??1,s=Math.max(1,this.currentPage-2),a=Math.min(t,this.currentPage+2);this.currentPage<=3?a=Math.min(6,t):this.currentPage>=t-2&&(s=Math.max(t-5,1)),s>1&&(e.append(' '),s>2&&e.append(' '));for(let r=s;r<=a;r++){let i=r===this.currentPage?" is-current":"";e.append(` `)}a'),e.append(` `))}async handleQuery(){let e=loading(),t=++this._queryGeneration;try{$(".page-box").show();let s=await this.getRuntimeService("scope")();if(t!==this._queryGeneration)return;let a=await this.getRuntimeService("movie").catalog("av123",{page:this.currentPage,keyword:this.keyword||""},{scope:s});if(t!==this._queryGeneration)return;let r=a.items;this.maxPage=Math.max(1,Number(a.maxPage)||1),this.currentPage=Math.min(Math.max(1,this.currentPage),this.maxPage),this.renderPagination(),r.length===0&&(clog.log(r),show.error("无结果"),clog.error("123AV 获取数据失败"));let i=this.markDataListHtml(r);this.$listRoot?.html(i);let n=this.getOptionalDependency("ListPagePlugin");n&&this.$listRoot&&await n.processAddedItems?.(this.$listRoot.find(".item").toArray()),await utils.smoothScrollToTop()}catch(s){clog.error(s)}finally{e.close()}}async loadDetail(e,t){let s=this.loadSummary(e,t),a=this.getImgList(e.carNum),r=this.getActressInfo(e.carNum);a.then((i=>e.isAlive()&&os(e,i,null))).catch((i=>e.isAlive()&&he(e.root.find('[data-jhs-role="gallery-grid"]'),"剧照加载失败",(()=>{this.reloadImages(e)})))),r.then((async i=>{await s.catch((()=>null)),e.isAlive()&&this.render123AvActress(e,i)})).catch((i=>clog.error("FC2 演员信息加载失败",i))),await Promise.allSettled([s,a,r])}async loadSummary(e,t){try{let s=await this.get123AvVideoInfo(e.carNum,t);return e.isAlive()?(this.render123AvSummary(e,s),s):null}catch(s){throw e.isAlive()&&he(e.root.find('[data-jhs-role="summary-content"]'),"影片信息加载失败",(()=>{this.loadSummary(e,t)})),clog.error("123AV 详情加载失败",s),s}}render123AvSummary(e,t){let s=e.root.find('[data-jhs-role="summary-content"]').empty(),a=$(' ');a.find("strong").text(t.title||"无标题"),s.append(a,$('
').append($(" ").text(`番号:${e.carNum}`),$(" ").text(`发行:${t.publishDate||"未知"}`)),'主演: 正在加载演员…
','
',Qs(e,this.getRuntimeService("movie")),$(' ').text(t.publishDate||""))}async get123AvVideoInfo(e,t){let s=await this.getRuntimeService("scope")(),a=await this.getRuntimeService("movie").detail({carNum:e,url:t,providerId:"av123"},{scope:s});return{title:a?.title||"",publishDate:a?.releaseDate||"",moviePoster:null}}async getActressInfo(e){let t=await this.getRuntimeService("scope")();return this.getRuntimeService("movie").people("fc2ppvdb",{carNum:e},{scope:t})}async getImgList(e){let t=await this.getRuntimeService("scope")();return(await this.getRuntimeService("movie").images("fc2content",{carNum:e},{scope:t})).map((s=>s.url))}async reloadImages(e){try{let t=await this.getImgList(e.carNum);e.isAlive()&&os(e,t,null)}catch{e.isAlive()&&he(e.root.find('[data-jhs-role="gallery-grid"]'),"剧照加载失败",(()=>{this.reloadImages(e)}))}}render123AvActress(e,t){let s=e.root.find('[data-jhs-role="actors"]').empty().append("主演: ");t.actors.length?t.actors.forEach((a=>s.append($(" ").addClass("jhs-fc2-actor").attr({href:a.url,target:"_blank",rel:"noopener noreferrer"}).text(a.name)))):s.append($(" ").text("暂无演员信息")),e.root.find('[data-jhs-role="actress-data"]').remove(),e.root.find(".jhs-fc2-summary__body").append($(' ').text(t.actors.map((a=>a.name)).join(" "))),t.seller&&e.root.find('[data-jhs-role="seller"]').empty().append("卖家:",t.seller.url?$(" ").attr({href:t.seller.url,target:"_blank",rel:"noopener noreferrer"}).text(t.seller.name):document.createTextNode(t.seller.name))}markDataListHtml(e){let t="";return e.forEach((s=>{let a=Ye(s.url),r=Ye(s.imageUrl);a&&(t+=`
- `)})),t}};d(Ri,"Fc2By123AvPlugin");var Qs=Ri;var Eh=Object.freeze({blocked:{id:"filterBtn",tone:"filter",label:Le},favorite:{id:"favoriteBtn",tone:"fav",label:Me},downloaded:{id:"hasDownBtn",tone:"down",label:fe},watched:{id:"hasWatchBtn",tone:"watch",label:ve}});function Lt({actions:o=["blocked","favorite","downloaded","watched"],ids:e={}}={}){let t=globalThis.$,s=t('');s.attr("data-jhs-state-count",String(o.length));for(let a of o){let r=Eh[a];if(!r)continue;let i=t(' ');i.attr("id",e[a]||r.id).addClass(`jhs-btn--${r.tone}`).find("span").text(r.label),s.children().append(i)}return s}d(Lt,"createStateActions");var pc={blocked:{selector:"#filterBtn",inactive:d(()=>Le,"inactive"),active:d(()=>tt,"active")},favorite:{selector:"#favoriteBtn",inactive:d(()=>Me,"inactive"),active:d(()=>st,"active")},downloaded:{selector:"#hasDownBtn",inactive:d(()=>fe,"inactive"),active:d(()=>"已标记下载","active")},watched:{selector:"#hasWatchBtn",inactive:d(()=>ve,"inactive"),active:d(()=>"已标记观看","active")}};function uc(){return Object.entries(pc)}d(uc,"stateButtonEntries");var Ei=class Ei{constructor(e){this.stateService=e}bind({root:e=document,closeRoot:t=e,layerIndex:s=null,carNum:a,getRecord:r=null,activityType:i="detail-state",selectors:n={}}){let l={root:e,closeRoot:t,layerIndex:s,carNum:T(a),getRecord:r,activityType:i,selectors:n};for(let[c,h]of uc()){let u=n[c]||h.selector;$(e).find(u).off("click.jhsDetailState").on("click.jhsDetailState",(p=>{p.preventDefault(),p.stopPropagation(),this.requestToggle(l,c,p)}))}return this.render(l),l}async requestToggle(e,t,s=null){if(!e.carNum)return void show.error("番号不可用,无法更新状态");let a=await storageManager.getCar(e.carNum),r=q(a?.stateFlags);return t==="blocked"&&!r.blocked?void utils.q(s,`是否屏蔽${e.carNum}?`,(()=>this.toggle(e,t,s))):this.toggle(e,t,s)}async toggle(e,t,s=null){if(!e.carNum)return void show.error("番号不可用,无法更新状态");let a=e.selectors[t]||pc[t].selector,r=s?.currentTarget?$(s.currentTarget):$(e.root).find(a);if(!r.prop("disabled")){r.prop("disabled",!0).attr("aria-busy","true");try{let i=typeof e.getRecord=="function"?await e.getRecord():e.getRecord||{carNum:e.carNum};await this.stateService.toggle(e.carNum,t,{type:e.activityType,record:i}),await this.render(e),await utils.closePage({layerIndex:e.layerIndex,root:e.closeRoot||e.root})}catch(i){clog.error("详情状态更新失败",i),show.error("操作失败")}finally{r[0]?.isConnected&&r.prop("disabled",!1).removeAttr("aria-busy")}}}async render({root:e=document,carNum:t,selectors:s={}}){let a=await storageManager.getCar(T(t)),r=q(a?.stateFlags);for(let[i,n]of uc()){let l=$(e).find(s[i]||n.selector),c=!!r[i];l.attr("aria-pressed",String(c)).each((h,u)=>$(u).find("span").first().text(c?n.active():n.inactive()))}return r}};d(Ei,"DetailStateController");var Mt=Ei;var mc="https://jdforrepam.com/api",gc=0,Ys="",ls=new Map;async function fc(){let o=globalThis;if(o.credentialService?.get)return o.credentialService.get("jhs_appAuthorization");let e=localStorage.getItem("jhs_appAuthorization");return e?Xe(e):""}d(fc,"readJavDbToken");function Dh(o){return o&&typeof o=="object"?o:{}}d(Dh,"asResponseRecord");function vc(){let o=Math.floor(Date.now()/1e3);return Ys&&o-gc<=20||(gc=o,Ys=`${o}.lpw6vgqzsp.${md5(`${o}71cf27bb3c0bcdf207b64abecddc970098c7421ee7203b9cdae54478478a199e7d5a6e1a57691123c1a931c057842fb73ba3b3c83bcd69c17ccf174081e3d8aa`)}`),Ys}d(vc,"O");async function bc(o){let e=String(o||"").trim(),t=await fc();if(!t)throw Object.assign(new Error("请先登录 JavDB 账号"),{code:"LOGIN_REQUIRED"});if(!e)throw new Error("JavDB 影片 ID 无效");let s="----jhs-javdb-want-watch",a=[["status","want_watch"],["score","0"],["content",""]].map((([r,i])=>`--${s}\r
+ `)})),t}};d(Ei,"Fc2By123AvPlugin");var Ys=Ei;var Dh=Object.freeze({blocked:{id:"filterBtn",tone:"filter",label:Le},favorite:{id:"favoriteBtn",tone:"fav",label:Me},downloaded:{id:"hasDownBtn",tone:"down",label:fe},watched:{id:"hasWatchBtn",tone:"watch",label:ve}});function Mt({actions:o=["blocked","favorite","downloaded","watched"],ids:e={}}={}){let t=globalThis.$,s=t('');s.attr("data-jhs-state-count",String(o.length));for(let a of o){let r=Dh[a];if(!r)continue;let i=t(' ');i.attr("id",e[a]||r.id).addClass(`jhs-btn--${r.tone}`).find("span").text(r.label),s.children().append(i)}return s}d(Mt,"createStateActions");var gc={blocked:{selector:"#filterBtn",inactive:d(()=>Le,"inactive"),active:d(()=>tt,"active")},favorite:{selector:"#favoriteBtn",inactive:d(()=>Me,"inactive"),active:d(()=>st,"active")},downloaded:{selector:"#hasDownBtn",inactive:d(()=>fe,"inactive"),active:d(()=>"已标记下载","active")},watched:{selector:"#hasWatchBtn",inactive:d(()=>ve,"inactive"),active:d(()=>"已标记观看","active")}};function pc(){return Object.entries(gc)}d(pc,"stateButtonEntries");var Di=class Di{constructor(e){this.stateService=e}bind({root:e=document,closeRoot:t=e,layerIndex:s=null,carNum:a,getRecord:r=null,activityType:i="detail-state",selectors:n={}}){let l={root:e,closeRoot:t,layerIndex:s,carNum:C(a),getRecord:r,activityType:i,selectors:n};for(let[c,h]of pc()){let u=n[c]||h.selector;$(e).find(u).off("click.jhsDetailState").on("click.jhsDetailState",(p=>{p.preventDefault(),p.stopPropagation(),this.requestToggle(l,c,p)}))}return this.render(l),l}async requestToggle(e,t,s=null){if(!e.carNum)return void show.error("番号不可用,无法更新状态");let a=await storageManager.getCar(e.carNum),r=H(a?.stateFlags);return t==="blocked"&&!r.blocked?void utils.q(s,`是否屏蔽${e.carNum}?`,(()=>this.toggle(e,t,s))):this.toggle(e,t,s)}async toggle(e,t,s=null){if(!e.carNum)return void show.error("番号不可用,无法更新状态");let a=e.selectors[t]||gc[t].selector,r=s?.currentTarget?$(s.currentTarget):$(e.root).find(a);if(!r.prop("disabled")){r.prop("disabled",!0).attr("aria-busy","true");try{let i=typeof e.getRecord=="function"?await e.getRecord():e.getRecord||{carNum:e.carNum};await this.stateService.toggle(e.carNum,t,{type:e.activityType,record:i}),await this.render(e),await utils.closePage({layerIndex:e.layerIndex,root:e.closeRoot||e.root})}catch(i){clog.error("详情状态更新失败",i),show.error("操作失败")}finally{r[0]?.isConnected&&r.prop("disabled",!1).removeAttr("aria-busy")}}}async render({root:e=document,carNum:t,selectors:s={}}){let a=await storageManager.getCar(C(t)),r=H(a?.stateFlags);for(let[i,n]of pc()){let l=$(e).find(s[i]||n.selector),c=!!r[i];l.attr("aria-pressed",String(c)).each((h,u)=>$(u).find("span").first().text(c?n.active():n.inactive()))}return r}};d(Di,"DetailStateController");var Bt=Di;var fc="https://jdforrepam.com/api",mc=0,Zs="",ls=new Map;async function vc(){let o=globalThis;if(o.credentialService?.get)return o.credentialService.get("jhs_appAuthorization");let e=localStorage.getItem("jhs_appAuthorization");return e?Xe(e):""}d(vc,"readJavDbToken");function Nh(o){return o&&typeof o=="object"?o:{}}d(Nh,"asResponseRecord");function bc(){let o=Math.floor(Date.now()/1e3);return Zs&&o-mc<=20||(mc=o,Zs=`${o}.lpw6vgqzsp.${md5(`${o}71cf27bb3c0bcdf207b64abecddc970098c7421ee7203b9cdae54478478a199e7d5a6e1a57691123c1a931c057842fb73ba3b3c83bcd69c17ccf174081e3d8aa`)}`),Zs}d(bc,"O");async function wc(o){let e=String(o||"").trim(),t=await vc();if(!t)throw Object.assign(new Error("请先登录 JavDB 账号"),{code:"LOGIN_REQUIRED"});if(!e)throw new Error("JavDB 影片 ID 无效");let s="----jhs-javdb-want-watch",a=[["status","want_watch"],["score","0"],["content",""]].map((([r,i])=>`--${s}\r
Content-Disposition: form-data; name="${r}"\r
\r
${i}\r
`)).join("")+`--${s}--\r
-`;try{let r=await gmHttp.gmRequest("POST",`${mc}/v1/movies/${encodeURIComponent(e)}/reviews`,a,{},{"user-agent":"Dart/3.5 (dart:io)","accept-language":"zh-TW",authorization:`Bearer ${t}`,jdsignature:await vc(),"content-type":`multipart/form-data; boundary=${s}`});if(r?.success===0)throw r;return await storageManager.deleteCachedRequest(`movie-detail:${e}`),ls.set(e,!0),r}catch(r){let i=Dh(r);if(i.status===401||i.action==="JWTVerificationError"||/未登录|登录|unauthorized|jwt/i.test(i.message||"")){let n=globalThis;throw n.credentialService?.remove?await n.credentialService.remove("jhs_appAuthorization"):localStorage.removeItem("jhs_appAuthorization"),Object.assign(new Error("JavDB 登录已失效,请重新登录"),{code:"LOGIN_REQUIRED"})}throw r instanceof Error?r:new Error(i.message||"加入 JavDB 想看失败")}}d(bc,"markJavDbWantWatch");async function wc(o){let e=String(o||"").trim(),t=await fc();if(!t)return null;if(!e)throw new Error("JavDB 影片 ID 无效");if(ls.has(e))return ls.get(e);let s=48;for(let a=1;a<=100;a++){let r=`${mc}/v2/users/review_movies?status=want_watch&type=0&sort_by=create&order_by=desc&page=${a}&limit=${s}`,i=await gmHttp.gmRequest("GET",r,null,{},{"user-agent":"Dart/3.5 (dart:io)","accept-language":"zh-TW",authorization:`Bearer ${t}`,jdsignature:await vc()}),n=i?.data?.movies??i?.movies;if(!Array.isArray(n))throw new Error("JavDB 想看状态响应无效");if(n.some(l=>String(l.id)===e))return ls.set(e,!0),!0;if(n.length
登录 ',success:d((r,i)=>{$(r).find("#loginBtn").on("click",async()=>{let n=String($(r).find("#username").val()||""),l=String($(r).find("#password").val()||"");if(!n||!l)return void show.error("请输入用户名和密码");let c=loading();try{let h=await e.login("javdb",{username:n,password:l},{scope:await s()});if(!h.success)return void show.error(h.message);if(!t?.set)throw new Error("凭证服务不可用");await t.set("jhs_appAuthorization",h.token),show.ok("登录成功"),o.close(i),await a?.()}catch(h){clog.error("登录异常:",h),show.error(h instanceof Error?h.message:String(h))}finally{c.close()}})},"success"),end:d(()=>{Zs=!1},"end")})}catch(r){throw Zs=!1,r}}d(yc,"openJavDbLoginDialog");async function Xs(o){if(o.isActive&&o.isActive()===!1)return;let e=globalThis.$,t=o.root?e(o.root):e(document),s=t.find(".origin-title").first();if(s.length||(s=t.find(".current-title").first()),s.length||(s=t.find("h3").first()),!s.length)return;let a=s.text().trim();if(!a)throw new TypeError("获取标题失败, 无法进行翻译");let r=s.nextAll(".translated-title").first();r.length||(r=e('
').insertAfter(s)),r.removeClass("is-error").text("翻译中...");try{let i=await o.translation.translate(a,{cacheAlias:o.carNum,scope:o.scope});if(o.isActive&&!o.isActive()||!s[0]?.isConnected||!r[0]?.isConnected)return;r.text(i)}catch(i){if(o.isActive&&!o.isActive()||!s[0]?.isConnected||!r[0]?.isConnected)return;let n=i instanceof Error?i.message:String(i);globalThis.clog?.error("翻译失败:",i),r.addClass("is-error").text(`翻译失败: ${n}`)}}d(Xs,"renderTranslatedTitle");function Nh(o){try{let e=new URL(String(o||""));return e.protocol==="https:"?e.href:null}catch{return null}}d(Nh,"normalizeImageUrl");function Lh(o,e,t){let s=globalThis.$,a=Nh(e);if(!a)return null;let r=s(" ").attr({src:a,alt:t,loading:"lazy"}).addClass("jhs-fc2-gallery__image"),i=s(' ').attr("aria-label",`查看${t}大图`).append(r);return o.empty().append(i).off("click.jhsScreenshot").on("click.jhsScreenshot",".jhs-fc2-screenshot-thumbnail",n=>{n.preventDefault(),n.stopPropagation(),globalThis.showImageViewer(r[0])}),a}d(Lh,"renderImage");async function ea(o){let e=globalThis.$,t=e(o.target),s=o.isActive??(()=>!0),a=o.providerId??"javstore";if(!t.length||!o.screenshot.isEnabled(o.settings))return t.empty(),null;let{mode:r}=o.screenshot.getScreenshotSettings(o.settings),i=o.screenshot.getEnabledProviders(o.settings);if(r!=="manual"&&!i.some(u=>u.id===a))return t.empty(),null;if(!i.length)return t.empty().append(e('没有可用截图来源
')),t;let n=d(async(u=t,p=a)=>{u.empty().append(dc("正在加载缩略图…"));try{let g=await o.screenshot.resolve({carNum:o.carNum},{providerId:p,scope:o.scope,settings:o.settings});if(!s())return null;let m=Array.isArray(g)?g[0]:g;return!m?.url||o.isDuplicate?.(m.url)?(u.empty(),null):Lh(u,m.url,"缩略图")}catch(g){return s()&&(u.empty().append(hc("缩略图加载失败 ",()=>{n(u,p)})),globalThis.clog?.error("缩略图加载失败",g)),null}},"load");if(r!=="manual")return n();let l=e('
'),c=`jhs-screenshot-result-${String(o.carNum).replace(/[^a-z0-9_-]/gi,"-")}`,h=e('
').attr("id",c).text("请选择截图来源");return i.forEach((u,p)=>{let g=e(' ').attr({"aria-controls":c,tabindex:p===0?"0":"-1"}).text(u.name);g.on("click",async()=>{l.find("[role='tab']").attr({"aria-selected":"false",tabindex:"-1"}),g.attr({"aria-selected":"true",tabindex:"0"}),await n(h,u.id)}),l.append(g)}),l.on("keydown","[role='tab']",(u=>{if(!["ArrowLeft","ArrowRight","Home","End"].includes(u.key))return;u.preventDefault();let p=l.find("[role='tab']"),g=p.index(u.currentTarget),m=u.key==="Home"?0:u.key==="End"?p.length-1:u.key==="ArrowRight"?(g+1)%p.length:(g-1+p.length)%p.length;p.eq(m).trigger("focus").trigger("click")})),t.empty().append(l,h),t}d(ea,"renderScreenshotPanel");var Di=class Di{constructor(e){this.related=e.related,this.settings=e.settings,this.scope=e.scope}async show(e,t,s={}){let a=globalThis.$,r=s.isActive??(()=>!0);if(!t)throw new TypeError("未传入movieId");if(!r()||!e?.length)return a();let i=e.children('[data-jhs-panel="related"]').filter((b,w)=>a(w).attr("data-jhs-movie-id")===String(t)).first();if(i.length)return i;let n=a('').attr("data-jhs-movie-id",String(t)),l=a(''),c=a(' '),h=await this.scope(),u=new te(`related:${t}`);if(!r()||h?.disposed)return a();let p=h?.addCleanup?.(()=>u.dispose());s.ownCleanup?.(()=>{u.dispose(),p?.()});let g={movieId:t,panel:n,panelScope:u,floorIndex:1,loaded:!1,loading:!1,page:1,enabled:!1,generation:0,isActive:d(()=>!u.disposed&&r(),"isActive"),requestScope:null};l.append(c),s.ownedSection?s.ownedSection.find('[data-jhs-section-actions="related"]').first().append(c):n.append(l),n.append('
',''),e.append(n);let m=(this.settings.snapshot().enableLoadRelated??"no")==="yes",f=d(b=>{if(!g.isActive())return;let w=b==="yes";if(g.enabled!==w&&(g.enabled=w,g.generation++,w||(g.requestScope?.dispose(),g.loading=!1)),this.updateToggle(c,w),n.find(".jhs-related-container, .jhs-related-footer").toggle(w),g.loading||n.find(".jhs-related-load-more").prop("disabled",!1).text("加载更多清单"),w&&!g.loaded&&!g.loading)return this.fetch(g)},"applyExpanded");this.settings.addEventListener&&u.listen(this.settings,"settings.changed",b=>{b.detail?.names?.includes("enableLoadRelated")&&f(this.settings.snapshot().enableLoadRelated??"no")});let v=Ve({settings:this.settings,key:"enableLoadRelated",fallback:"no",apply:d(b=>{f(b)},"apply"),onError:d(b=>{globalThis.clog?.error("相关清单展开设置保存失败,已恢复",b),globalThis.show?.error?.("相关清单展开设置保存失败,已恢复原设置")},"onError")});return c.on("click",b=>{b.preventDefault(),b.stopPropagation(),v(g.enabled?"no":"yes")}),u.addCleanup(()=>{g.requestScope?.dispose(),c.off("click"),n.find("button").off("click")}),await f(m?"yes":"no"),n}updateToggle(e,t){e.attr("aria-expanded",String(t)),e.find(".toggle-text").text(t?"折叠":"展开"),e.find(".toggle-icon").text(t?"▲":"▼")}async fetch(e){if(e.loading||!e.enabled||!e.isActive())return;e.loading=!0;let t=e.panel.find(".jhs-related-container"),s=e.panel.find(".jhs-related-footer");t.empty().append(globalThis.$("
").addClass("jhs-panel-state").text("获取清单中...")),s.empty();let a=e.generation,r=new te(`related:${e.movieId}:page:1`),i=e.panelScope.addCleanup(()=>r.dispose());e.requestScope=r;try{let n=await this.related.list({movieId:e.movieId},{page:1,limit:20,scope:r});if(!e.isActive()||r.signal.aborted||a!==e.generation||!e.enabled)return;if(e.loading=!1,e.loaded=!0,t.empty(),!n.length)return void t.append(globalThis.$("
").addClass("jhs-panel-state").text("无清单"));this.display(e,n,t),n.length===20?this.bindLoadMore(e,t,s):s.append(globalThis.$("
").addClass("jhs-panel-end").text("已加载全部清单"))}catch(n){if(a===e.generation&&(e.loading=!1),!e.isActive()||r.signal.aborted||a!==e.generation||!e.enabled)return;globalThis.clog?.error("获取清单失败:",n),this.renderRetry(t,()=>{this.fetch(e)})}finally{i(),e.requestScope===r&&(e.requestScope=null)}}renderRetry(e,t){let s=globalThis.$;e.empty().append(s('
').append(document.createTextNode("获取清单失败 "),s('重试 ').on("click",t)))}bindLoadMore(e,t,s){let a=globalThis.$,r=a('加载更多清单 '),i=a('已加载全部清单
').hide();s.empty().append(r,i),r.on("click",async()=>{if(!e.enabled||!e.isActive()||e.loading)return;let n=e.page+1,l=e.generation,c=new te(`related:${e.movieId}:page:${n}`),h=e.panelScope.addCleanup(()=>c.dispose());e.loading=!0,e.requestScope=c,r.text("加载中...").prop("disabled",!0);try{let u=await this.related.list({movieId:e.movieId},{page:n,limit:20,scope:c});if(!e.isActive()||c.signal.aborted||l!==e.generation||!e.enabled)return;e.page=n,this.display(e,u,t),u.length<20?(r.remove(),i.show()):r.text("加载更多清单").prop("disabled",!1)}catch(u){if(!e.isActive()||c.signal.aborted||l!==e.generation||!e.enabled)return;globalThis.clog?.error("加载更多清单失败:",u),r.text("加载失败,请重试").prop("disabled",!1)}finally{h(),l===e.generation&&(e.loading=!1),e.requestScope===c&&(e.requestScope=null)}})}display(e,t,s){let a=globalThis.$;t.forEach(r=>{let i=a(" ").addClass("jhs-related-title").attr({href:`/lists/${encodeURIComponent(r.id)}`,target:"_blank",rel:"noopener noreferrer"}).text(r.name||"未命名清单"),n=a('
').append(a(" ").addClass("jhs-related-index").text(`#${e.floorIndex++}`),i),l=a('
'),c=r.createdAt?globalThis.utils.formatDate(r.createdAt):"未知";l.append(a(" ").text(`视频:${Number(r.movieCount)||0}`),a(" ").text(`收藏:${Number(r.collectionCount)||0}`),a(" ").text(`查看:${Number(r.viewCount)||0}`),a(' ').text(`创建时间:${c}`)),s.append(a(' ').append(n,l))})}};d(Di,"RelatedPanel");var Bt=Di;var Ni=class Ni{constructor(e){this.review=e.review,this.settings=e.settings,this.storage=e.storage,this.scope=e.scope}async show(e,t,s={}){let a=globalThis.$,r=s.isActive??(()=>!0);if(!r()||!t?.length)return a();let i=t.children('[data-jhs-panel="reviews"]').filter((b,w)=>a(w).attr("data-jhs-movie-id")===String(e)).first();if(i.length)return i;let n=a('').attr("data-jhs-movie-id",String(e)),l=a(''),c=a(' '),h=await this.scope(),u=new te(`reviews:${e}`);if(!r()||h?.disposed)return a();let p=h?.addCleanup?.(()=>u.dispose());s.ownCleanup?.(()=>{u.dispose(),p?.()});let g={movieId:e,panel:n,panelScope:u,floorIndex:1,loaded:!1,loading:!1,page:1,enabled:!1,generation:0,isActive:d(()=>!u.disposed&&r(),"isActive"),requestScope:null};l.append(c),s.ownedSection?s.ownedSection.find('[data-jhs-section-actions="reviews"]').first().append(c):n.append(l),n.append('
',''),t.append(n),this.bindFilter(n);let m=(this.settings.snapshot().enableLoadReview??"yes")==="yes",f=d(b=>{if(!g.isActive())return;let w=b==="yes";if(g.enabled!==w&&(g.enabled=w,g.generation++,w||(g.requestScope?.dispose(),g.loading=!1)),this.updateToggle(c,w),n.find(".jhs-review-container, .jhs-review-footer").toggle(w),n.find(".jhs-review-load-more").prop("disabled",!1).text("加载更多评论"),w&&!g.loaded&&!g.loading)return this.fetch(g)},"applyExpanded");this.settings.addEventListener&&u.listen(this.settings,"settings.changed",b=>{b.detail?.names?.includes("enableLoadReview")&&f(this.settings.snapshot().enableLoadReview??"yes")});let v=Ve({settings:this.settings,key:"enableLoadReview",fallback:"yes",apply:d(b=>{f(b)},"apply"),onError:d(b=>{globalThis.clog?.error("评论面板展开设置保存失败,已恢复",b),globalThis.show?.error?.("评论面板展开设置保存失败,已恢复原设置")},"onError")});return c.on("click",b=>{b.preventDefault(),b.stopPropagation();let S=c.find(".toggle-text").text()==="展开"?"yes":"no";v(S)}),u.addCleanup(()=>{g.requestScope?.dispose(),c.off("click"),n.off("contextmenu.jhsReviewFilter")}),await f(m?"yes":"no"),n}updateToggle(e,t){e.attr("aria-expanded",String(t)),e.find(".toggle-text").text(t?"折叠":"展开"),e.find(".toggle-icon").text(t?"▲":"▼")}async fetch(e){if(e.loading||!e.enabled||!e.isActive())return;let t=globalThis.$,s=e.panel.find(".jhs-review-container"),a=e.panel.find(".jhs-review-footer");e.loading=!0,s.empty().append(t('
').text("获取评论中...")),a.empty();let r=Number(this.settings.snapshot().reviewCount)||20,i=e.generation,n=new te(`reviews:${e.movieId}:page:1`),l=e.panelScope.addCleanup(()=>n.dispose());e.requestScope=n;try{let c=await this.review.list({movieId:e.movieId},{page:1,limit:r,scope:n});if(!e.isActive()||n.signal.aborted||i!==e.generation||!e.enabled)return;let h=await this.getKeywords();if(!e.isActive()||n.signal.aborted||i!==e.generation||!e.enabled)return;if(e.loading=!1,e.loaded=!0,s.empty(),!c.length)return void s.append(t('
').text("无评论"));await this.display(e,c,s,h),c.length===r?this.bindLoadMore(e,r,h,s,a):a.append(t('
').text("已加载全部评论"))}catch(c){if(i===e.generation&&(e.loading=!1),!e.isActive()||n?.signal?.aborted)return;globalThis.clog?.error("获取评论失败:",c),this.renderRetry(s,"获取评论失败",()=>{this.fetch(e)})}finally{l(),e.requestScope===n&&(e.requestScope=null)}}async getKeywords(){return Wt(this.storage)}async saveKeyword(e){await Wt(this.storage,e)}renderRetry(e,t,s){let a=globalThis.$;e.empty().append(a('
').append(document.createTextNode(`${t} `),a('重试 ').on("click",s)))}bindLoadMore(e,t,s,a,r){let i=globalThis.$,n=i('加载更多评论 '),l=i('已加载全部评论
').hide();r.empty().append(n,l),n.on("click",async()=>{if(!e.enabled||!e.isActive()||e.loading)return;let c=e.page+1,h=e.generation,u=new te(`reviews:${e.movieId}:page:${c}`),p=e.panelScope.addCleanup(()=>u.dispose());e.requestScope=u,e.loading=!0,n.text("加载中...").prop("disabled",!0);try{let g=await this.review.list({movieId:e.movieId},{page:c,limit:t,scope:u});if(!e.isActive()||u.signal.aborted||h!==e.generation||!e.enabled)return;e.page=c,await this.display(e,g,a,s),g.lengthn.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")).join("|")):null;for(let n of t){let l=String(n.content||"");if(i?.test(l))continue;let c=r(' '),h=r('
'),u=r('
');h.append(r(" ").addClass("jhs-review-author").text(n.author||"匿名用户"));let p=r(' '),g=Math.max(0,Math.min(5,Number(n.score)||0));for(let f=0;f');let m=globalThis.utils.formatDate(n.createdAt);h.append(p,r(" ").text(m),r(" ").text(`点赞:${Number(n.likes)||0}`),r(" ").addClass("jhs-review-floor").text(`#${e.floorIndex++}楼`)),this.appendContent(u,l),c.append(h,u),s.append(c)}}appendContent(e,t){let s=/ed2k:\/\/\|file\|[^|]+\|\d+\|[a-fA-F0-9]{32}\|\/|magnet:\?[^\s"'<>`,;\u4e00-\u9fa5,。?!()【】]+|https?:\/\/[^\s"'<>`,;\u4e00-\u9fa5,。?!()【】]+/g,a=0,r;for(;r=s.exec(t);)r.index>a&&e.append(document.createTextNode(t.slice(a,r.index))),this.appendLink(e,r[0]),a=r.index+r[0].length;a':' '),c=s(' '),h=a?s(' ').text(i).on("click",()=>globalThis.utils.copyToClipboard(i,t)):s(" ").addClass("jhs-review-link").attr({href:t,target:"_blank",rel:"noopener noreferrer"}).text(i),u=s('复制 ').on("click",()=>globalThis.utils.copyToClipboard(i,t));c.append(h,u),l.append(c),n&&l.append(s(' ').append(s('离线 ').attr("data-resource",t))),e.append(l)}bindFilter(e){e.off("contextmenu.jhsReviewFilter",".review-content").on("contextmenu.jhsReviewFilter",".review-content",async t=>{if((this.settings.snapshot().enableTitleSelectFilter??"yes")!=="yes")return;let s=String(window.getSelection()?.toString()||"");s&&(t.preventDefault(),await globalThis.utils.q(t,`是否将 '${C(s)}' 加入评论区关键词?`,async()=>{await this.saveKeyword(s),globalThis.show.ok("操作成功, 刷新页面后生效")}))})}};d(Ni,"ReviewPanel");var Ot=Ni;function Mh(o,e="other"){if(!o||typeof o!="object"||Array.isArray(o))return null;let t=o,s=T(t.carNum);return s?Object.freeze({...t,carNum:s,movieId:typeof t.movieId=="string"&&t.movieId.trim()?t.movieId.trim():t.movieId??null,surface:t.surface||e}):null}d(Mh,"normalizeWorkspaceMovieContext");function jc({carNum:o="",source:e="fc2",mode:t="dialog"}={}){let s=$('
').attr({"data-jhs-fc2-source":e,"data-jhs-fc2-mode":t,"data-jhs-car-num":T(o)||""});return[["summary","影片概览"],["gallery","预览与剧照"],["resources","资源"],["reviews","评论"],["related","相关清单"]].forEach((([r,i])=>{let n=$('').attr("data-jhs-section",r),l=$(''),c=$(" ").text(i),h=$('
').attr("data-jhs-section-actions",r);n.append(l.append(c,h),$('
').attr("data-jhs-slot",r)),s.append(n)})),s}d(jc,"createFc2DetailShell");function Sc(o,e={}){let t=$(o).is(".jhs-fc2-workspace")?$(o):$(o).find(".jhs-fc2-workspace").first(),s=!1,a=`.jhsFc2Detail${Date.now()}${Math.random().toString(36).slice(2)}`,r=new Set,i=e.mode==="dialog"?"fc2-dialog":"native-detail",n=Mh({...e,carNum:e.carNum||t.attr("data-jhs-car-num"),detailUrl:e.url,surface:i},i),l={...e,movieContext:n,root:t,workspace:t,namespace:a,observers:r,getSlot:d(c=>t.find(`[data-jhs-slot="${c}"]`).first(),"getSlot"),getSection:d(c=>t.find(`[data-jhs-section="${c}"]`).first(),"getSection"),isAlive:d(()=>!s&&t[0]?.isConnected!==!1,"isAlive"),addObserver(c){return c&&r.add(c),c},destroy(){s||(s=!0,t.off(a).find("*").off(a),r.forEach((c=>c.disconnect?.())),r.clear(),t.removeData("jhsFc2Context"))}};return t.data("jhsFc2Context",l).attr("data-jhs-surface",i),n&&t.data("jhsMovieContext",n),l}d(Sc,"createFc2DetailContext");function Bh(o){return cl(o,window.location.origin)}d(Bh,"parseExplicitJavDbMovieId");var Li=class Li extends I{constructor(){super(...arguments),this.detailStateController=null,this.translationGeneration=0}getName(){return"Fc2Plugin"}getDetailStateController(){return this.detailStateController||(this.detailStateController=new Mt(this.getRuntimeService("state")))}async resolveMovieId(e){let t=await this.getRuntimeService("scope")();return(await this.getRuntimeService("movie").resolve({carNum:e},{scope:t}))?.movieId||null}async resolveMovieIdForRecord(e,t=""){return Bh(t)||this.resolveMovieId(e)}async initCss(){return``}async handle(){if(!X.includes("collection_codes?movieId"))return;let e=new URLSearchParams(window.location.search),t=e.get("movieId"),s=e.get("carNum"),a=e.get("url"),r=e.get("source"),i=$("section").first().empty();if(!s||!a)return void i.append($('
').text("FC2 详情参数不完整"));let n=t&&t!=="search"?t:await this.resolveMovieIdForRecord(s,a),l=["fc2","123av"].includes(r||"")?r:await this.resolveFc2Source({url:a}),c=this.mountFc2Detail(i,{movieId:n,carNum:s,url:a,source:l,mode:"page"});$(window).off("pagehide.jhsFc2Detail").one("pagehide.jhsFc2Detail",(()=>c.destroy()))}openFc2Dialog(e,t,s,{source:a=""}={}){a=["fc2","123av"].includes(a)?a:"";let r=null;return this.getRuntimeService("dialog").open({type:1,title:t,content:'
',ui:{size:"workspace",body:"scroll"},area:utils.getDialogArea("workspace"),skin:"movie-detail-layer",scrollbar:!1,shadeClose:!0,success:d((i,n)=>{r=this.mountFc2Detail($(i).find(".jhs-fc2-dialog-host"),{movieId:e,carNum:t,url:s,source:a,layerIndex:n,mode:"dialog"}),utils.setupEscClose(n)},"success"),end:d(()=>r?.destroy(),"end")})}mountFc2Detail(e,t){let s=$(e);s.data("jhsFc2Context")?.destroy?.(),s.empty();let r=jc(t).appendTo(s),i=Sc(r,t);return s.data("jhsFc2Context",i),i.translationGeneration=0,i.screenshotGeneration=0,i.otherSiteGeneration=0,this.initializeWorkspace(i),this.bindFc2FeatureLifecycle(i),i}initializeWorkspace(e){let t=$(''),s=$('
');s.append(Lt()),s.append('JavDB 想看(关联中) ','字幕 (SubtitleCat) ','字幕 (迅雷) '),t.find(".jhs-fc2-summary__body").append(s),e.getSlot("summary").append(t);let a=$('
'),r=$('
');a.on(`click${e.namespace}`,".jhs-fc2-gallery-item",(f=>{let v=$(f.currentTarget).find("img")[0];v&&globalThis.showImageViewer(v,"",{galleryRoot:a[0]})})),e.getSlot("gallery").append(a,r);let i=$('
'),n=this.createResourceGroup("站内磁力","native-magnets"),l=this.createResourceGroup("第三方站点","other-sites"),c=this.createResourceGroup("更多磁力来源","magnet-hub"),h=$('展开磁力搜索 '),u=null;c.find('[data-jhs-role="magnet-hub"]').append(h,'
'),i.append(n,l,c),e.getSlot("resources").append(i),s.on(`click${e.namespace}`,'[data-jhs-action="subtitlecat"]',(f=>{let v=this.getRuntimeService("movie").sourceUrls({carNum:e.carNum},["subtitlecat"])[0]?.url;v&&utils.openPage(v,e.carNum,!1,f)}));let p=this.getOptionalDependency("DetailPageButtonPlugin");p?s.on(`click${e.namespace}`,'[data-jhs-action="xunlei"]',(()=>p.searchXunLeiSubtitle(e.carNum))):s.find('[data-jhs-action="xunlei"]').remove();let g=this.getOptionalDependency("MagnetHubPlugin");g||c.remove(),h.on(`click${e.namespace}`,(async()=>{if(!g||!e.isAlive())return;let f=c.find('[data-jhs-role="magnet-hub-content"]');if(h.attr("aria-expanded")==="true")return c.addClass("is-collapsed"),void h.attr("aria-expanded","false").text("展开磁力搜索");u||(u=g.createMagnetHub({movieContext:e.movieContext,root:e.root}));let b=await u;e.isAlive()&&!f.children().length&&f.append(b),e.isAlive()&&(c.removeClass("is-collapsed"),h.attr("aria-expanded","true").text("收起磁力搜索"),f[0]?.scrollIntoView?.({block:"nearest"}))})),this.getDetailStateController().bind({root:e.root,layerIndex:e.layerIndex??null,carNum:e.carNum,activityType:"fc2-state",getRecord:d(()=>({carNum:e.carNum,url:e.url,fc2Source:e.source,names:e.root.find('[data-jhs-role="actress-data"]').text(),publishTime:e.root.find('[data-jhs-role="publish-time"]').text()}),"getRecord")}),e.source==="123av"?this.load123AvDetail(e):this.loadNativeDetail(e);let m=this.getOptionalDependency("FilterTitleKeywordPlugin");m&&Promise.resolve().then((()=>m.bindDetailRoot(e.root,{layerIndex:e.layerIndex??null}))).catch((f=>clog.error("FC2 关键词过滤初始化失败",f))),this.mountFc2OtherSites(e,l,this.getOptionalDependency("OtherSitePlugin")),this.loadFc2Screenshot(e)}bindFc2FeatureLifecycle(e){let t=this.getRuntimeService("settings"),s=d(a=>{let r=a.detail?.names;if(r?.length&&(r.includes("enableLoadScreenShot")&&(t.snapshot().enableLoadScreenShot==="no"?(e.screenshotGeneration=(e.screenshotGeneration||0)+1,this.unmountFc2Screenshot(e)):this.loadFc2Screenshot(e)),r.includes("translateTitle")&&((t.snapshot().translateTitle??R)===R?this.applyFc2Translation(e):(e.translationGeneration=(e.translationGeneration||0)+1,this.revertFc2Translation(e))),r.includes("enableMagnetsFilter")&&e.magnetFilterApply?.((t.snapshot().enableMagnetsFilter??R)===R),r.includes("enableLoadOtherSite"))){let i=e.getSection("resources").find('[data-jhs-role="other-sites"]').closest(".jhs-fc2-resource-group");t.snapshot().enableLoadOtherSite==="no"?(e.otherSiteGeneration=(e.otherSiteGeneration||0)+1,this.unmountFc2OtherSites(e,i)):this.mountFc2OtherSites(e,i,this.getOptionalDependency("OtherSitePlugin"))}},"handler");t.addEventListener("settings.changed",s),e.addObserver({disconnect:d(()=>t.removeEventListener("settings.changed",s),"disconnect")})}loadFc2Screenshot(e){let t=this.getRuntimeService("screenshot"),s=this.getRuntimeService("settings"),a=e.root.find('[data-jhs-role="screenshot"]');if(!t.isEnabled(s.snapshot()))return void a.empty();let r=(e.screenshotGeneration||0)+1;e.screenshotGeneration=r,Promise.resolve().then((()=>this.getRuntimeService("scope")())).then(i=>ea({target:a,carNum:e.carNum.replace("FC2-",""),screenshot:t,settings:s.snapshot(),scope:i,isActive:d(()=>e.isAlive()&&s.snapshot().enableLoadScreenShot!=="no"&&r===e.screenshotGeneration,"isActive"),isDuplicate:d(n=>!!e.galleryUrls?.has(n),"isDuplicate")})).then(i=>{if(!(!e.isAlive()||r!==e.screenshotGeneration)&&s.snapshot().enableLoadScreenShot==="no")return void a.empty()}).catch(i=>{!e.isAlive()||r!==e.screenshotGeneration||(a.empty(),clog.error("FC2 剧照初始化失败",i))})}unmountFc2Screenshot(e){e.screenshotGeneration=(e.screenshotGeneration||0)+1,e.root.find('[data-jhs-role="screenshot"]').empty()}applyFc2Translation(e){let t=this.getRuntimeService("settings");if(!e.isAlive()||(t.snapshot().translateTitle??R)!==R)return;let s=(e.translationGeneration||0)+1;e.translationGeneration=s,Promise.resolve().then((()=>this.getRuntimeService("scope")())).then(a=>Xs({root:e.root,carNum:e.carNum,translation:this.getRuntimeService("translation"),scope:a,isActive:d(()=>e.isAlive()&&(t.snapshot().translateTitle??R)===R&&s===e.translationGeneration,"isActive")})).catch((a=>clog.error("FC2 标题翻译失败",a)))}revertFc2Translation(e){e.root.find(".translated-title").remove()}mountFc2OtherSites(e,t,s){if(!s)return void t.remove();let a=this.getRuntimeService("settings"),r=(e.otherSiteGeneration||0)+1;e.otherSiteGeneration=r,t.length&&t.show(),Promise.resolve().then((()=>s.loadOtherSite(e.carNum.replace("FC2-",""),e.carNum,{root:e.root,target:t.find('[data-jhs-role="other-sites"]'),autoDetect:!1,isActive:d(()=>e.isAlive()&&a.snapshot().enableLoadOtherSite!=="no"&&r===e.otherSiteGeneration,"isActive")}))).then(i=>{!e.isAlive()||r!==e.otherSiteGeneration||(i?t.show():t.hide())}).catch(i=>{!e.isAlive()||r!==e.otherSiteGeneration||(t.show(),he(e.root.find('[data-jhs-role="other-sites"]'),"外部站点加载失败"),clog.error("FC2 外部站点加载失败",i))})}unmountFc2OtherSites(e,t){e.otherSiteGeneration=(e.otherSiteGeneration||0)+1,e.root.find("[data-jhs-other-site-box],[data-jhs-other-site-settings]").remove(),t.length&&t.hide()}createResourceGroup(e,t){return $('').find("h3").text(e).end().find("div").attr("data-jhs-role",t).end()}async loadNativeDetail(e){let t=Promise.resolve(e.movieId);this.configureJavDbWantButton(e,t),await Promise.allSettled([this.fetchAndRenderNativeDetail(e),this.fetchAndRenderNativeMagnets(e),this.mountPanels(e,t)]),e.isAlive()&&this.applyFc2Translation(e)}async load123AvDetail(e){let t=this.getOptionalDependency("Fc2By123AvPlugin");if(!t)return void he(e.getSlot("summary"),"123AV 详情功能已禁用");let s=t.resolveMovieId(e.carNum);this.configureJavDbWantButton(e,s),this.mountPanels(e,s),s.then((a=>{if(e.isAlive())return this.fetchAndRenderNativeMagnets(e,a)})).catch((a=>{e.isAlive()&&he(e.root.find('[data-jhs-role="native-magnets"]'),"站内磁力关联失败",(()=>{this.load123AvMagnets(e)})),clog.error("123AV 磁力关联失败",a)})),await t.loadDetail(e,e.url),e.isAlive()&&this.applyFc2Translation(e)}async load123AvMagnets(e){let t=this.getOptionalDependency("Fc2By123AvPlugin");if(!t)throw new Error("123AV 详情功能已禁用");let s=await t.resolveMovieId(e.carNum);return this.fetchAndRenderNativeMagnets(e,s)}async configureJavDbWantButton(e,t){let s=e.root.find('[data-jhs-action="javdb-want"]');try{let a=await t;if(!e.isAlive())return;if(!a)return void s.prop("disabled",!0).text("JavDB 暂无对应作品");try{let r=await wc(a);if(!e.isAlive())return;if(r)return void s.prop("disabled",!0).attr("aria-pressed","true").text("已在 JavDB 想看")}catch(r){clog.warn("读取 JavDB 想看状态失败,保留手动操作",r)}s.prop("disabled",!1).text("JavDB 想看").off(`click${e.namespace}`).on(`click${e.namespace}`,(()=>{this.submitJavDbWant(e,a,s)}))}catch(a){e.isAlive()&&s.prop("disabled",!1).text("JavDB 关联失败,重试").off(`click${e.namespace}`).on(`click${e.namespace}`,(()=>{this.configureJavDbWantButton(e,this.resolveMovieId(e.carNum))})),clog.error("FC2 JavDB 想看关联失败",a)}}async submitJavDbWant(e,t,s){if(!(!e.isAlive()||s.data("jhsBusy")||s.attr("aria-pressed")==="true")){s.data("jhsBusy",!0).attr({"aria-busy":"true","aria-disabled":"true"}).text("正在加入想看…");try{if(await bc(t),!e.isAlive())return;s.attr({"aria-pressed":"true","aria-disabled":"false"}).text("已加入 JavDB 想看"),show.ok("已加入 JavDB 想看")}catch(a){if(!e.isAlive())return;let r=a;if(r?.code==="LOGIN_REQUIRED")return s.attr("aria-disabled","false").text("JavDB 想看"),yc({dialog:this.getRuntimeService("dialog"),account:this.getRuntimeService("account"),credential:this.getRuntimeService("credential"),getScope:this.getRuntimeService("scope"),onSuccess:d(()=>this.submitJavDbWant(e,t,s),"onSuccess")});s.attr("aria-disabled","false").text("JavDB 想看"),show.error(r?.message||"加入 JavDB 想看失败"),clog.error("加入 JavDB 想看失败",a)}finally{e.isAlive()&&s.removeData("jhsBusy").removeAttr("aria-busy")}}}async fetchAndRenderNativeDetail(e){try{let t=await this.getRuntimeService("scope")(),s=await this.getRuntimeService("movie").detail({movieId:e.movieId,carNum:e.carNum,providerId:"javdb"},{scope:t});if(!s)throw new Error("JavDB 影片详情不存在");if(!e.isAlive())return;this.renderSummary(e,s),os(e,s.imageUrls||[],s.coverUrl||null)}catch(t){e.isAlive()&&he(e.root.find('[data-jhs-role="summary-content"]'),"影片信息加载失败",(()=>{this.fetchAndRenderNativeDetail(e)})),clog.error("FC2 详情加载失败",t)}}renderSummary(e,t){let s=e.root.find('[data-jhs-role="summary-content"]').empty(),a=$(' ');a.find("strong").text(t.title||"无标题"),s.append(a),t.originalTitle&&t.originalTitle!==t.title&&s.append($('
').text(t.originalTitle));let r=$('
');[`番号:${t.carNum||e.carNum}`,`发行:${t.releaseDate||"未知"}`,`评分:${Number.isFinite(Number(t.score))?t.score:"无"}`,`时长:${Number.isFinite(Number(t.duration))?t.duration+" 分钟":"无"}`].forEach((l=>r.append($(" ").text(l)))),s.append(r);let i=[],n=$('主演:
');(t.actors||[]).forEach((l=>{n.append($(" ").addClass("jhs-fc2-actor").attr({href:`/actors/${encodeURIComponent(l.id)}`,target:"_blank",rel:"noopener noreferrer"}).text(l.name||"未知演员")),l.gender===0&&i.push(l.name)})),t.actors?.length||n.append($(" ").text("暂无演员信息")),s.append(n,Gs(e,this.getRuntimeService("movie")),$(' ').text(i.join(" ")),$(' ').text(t.releaseDate||""))}async fetchAndRenderNativeMagnets(e,t=e.movieId){let s=e.root.find('[data-jhs-role="native-magnets"]');he(s,"正在加载站内磁力…");try{if(!t)return he(s,"JavDB 暂无对应作品");let a=await this.getRuntimeService("scope")(),r=await this.getRuntimeService("magnet").listNative({movieId:t,providerId:"javdb"},{scope:a});if(!e.isAlive())return;if(s.empty(),!r.length)return he(s,"暂无站内磁力");let i=[],n=this.getRuntimeService("magnet");r.forEach((l=>{let c=wl(l.hash);if(!c)return;let h=`magnet:?xt=urn:btih:${c}`,u=n.assess({title:l.title,hasHdTag:l.hasHdTag,hasSubtitleTag:l.hasSubtitleTag,date:l.createdAt,seeders:l.seeders}),p=$('
').attr("data-jhs-high-quality",String(u.highQuality)),g=$('
'),m=$('
'),f=$('
');i.push(u),f.append($(" ").addClass("jhs-badge").attr("title",`磁力质量评分 ${u.score.total}`).text(`${u.grade} ${u.score.total}`)),l.hasHdTag&&f.append('高清 '),l.hasSubtitleTag&&f.append('字幕 '),g.append($(" ").attr("href",h).text(l.title||h),$("
").addClass("jhs-fc2-meta").text(`${(Number(l.sizeMb||0)/1024).toFixed(2)} GB · ${Number(l.fileCount)||0} 个文件${l.createdAt?` · ${l.createdAt}`:""}`),f),m.append($('复制 ').attr("data-clipboard-text",h),$('离线 ').attr({"data-resource":h,"data-jhs-offline-owner":"fc2"})),s.append(p.append(g,m))})),await this.bindNativeMagnetFilter(e,s,i.some((l=>l.highQuality)))}catch(a){e.isAlive()&&he(s,"站内磁力加载失败",(()=>{this.fetchAndRenderNativeMagnets(e,t)})),clog.error("FC2 磁力加载失败",a)}}async bindNativeMagnetFilter(e,t,s){let a=e.getSection("resources"),r=a.find(".jhs-fc2-section__actions");r.find('[data-jhs-action="filter-native-magnets"]').remove();let n=$(' '),l=d(u=>{t.find(".jhs-fc2-magnet-item").show(),u&&s&&t.find('.jhs-fc2-magnet-item[data-jhs-high-quality="false"]').hide(),n.attr("aria-pressed",String(u&&s)).text(s?u?"显示全部磁力":"过滤低质量":"暂无可过滤项").prop("disabled",!s)},"apply"),c=this.getRuntimeService("settings"),h=Ve({settings:c,key:"enableMagnetsFilter",fallback:"no",apply:d(u=>l(u===R),"apply"),onError:d(u=>{clog.error("磁力过滤设置保存失败,已恢复",u),show.error("磁力过滤设置保存失败,已恢复原设置")},"onError")});e.magnetFilterApply=l,r.append(n),l((c.snapshot().enableMagnetsFilter??R)===R),n.on(`click${e.namespace}`,(async()=>{let u=n.attr("aria-pressed")!=="true";await h(u?R:"no")}))}async mountPanels(e,t){try{let s=await t;if(!e.isAlive())return;if(!s)return this.clearOwnedPanel(e,"reviews"),this.clearOwnedPanel(e,"related"),he(e.getSlot("reviews"),"JavDB 暂无对应作品"),he(e.getSlot("related"),"JavDB 暂无对应作品");this.clearOwnedPanel(e,"reviews"),this.clearOwnedPanel(e,"related");let a=d(()=>this.getRuntimeService("scope")(),"scope"),r=new Bt({related:this.getRuntimeService("related"),settings:this.getRuntimeService("settings"),scope:a}),i=new Ot({review:this.getRuntimeService("review"),settings:this.getRuntimeService("settings"),storage:this.getRuntimeService("storage"),scope:a});await Promise.allSettled([i.show(s,e.getSlot("reviews"),{ownedSection:e.getSection("reviews"),isActive:e.isAlive,ownCleanup:d(n=>e.addObserver({disconnect:n}),"ownCleanup")}),r.show(e.getSlot("related"),s,{ownedSection:e.getSection("related"),isActive:e.isAlive,ownCleanup:d(n=>e.addObserver({disconnect:n}),"ownCleanup")})])}catch(s){if(!e.isAlive())return;this.clearOwnedPanel(e,"reviews"),this.clearOwnedPanel(e,"related");let a=d(()=>{this.mountPanels(e,this.resolveMovieId(e.carNum))},"retry");he(e.getSlot("reviews"),"评论关联失败",a),he(e.getSlot("related"),"相关清单关联失败",a),clog.error("FC2 JavDB 关联失败",s)}}clearOwnedPanel(e,t){e.getSlot(t).empty(),e.getSection(t).find(".jhs-fc2-section__actions").empty()}async resolveFc2Source(e={}){if(e.fc2Source&&["fc2","123av"].includes(e.fc2Source))return e.fc2Source;try{let t=new URL(e.url||"",window.location.origin);return this.getRuntimeService("movie").matchesProviderUrl("av123",t.href)?"123av":t.origin===window.location.origin?"fc2":""}catch{return""}}createFc2PageUrl(e,t,s,{source:a=""}={}){if(!String(e||"").trim())throw new TypeError("FC2 owned detail requires movieId");let r=new URL("/users/collection_codes",window.location.origin);return r.searchParams.set("movieId",String(e).trim()),r.searchParams.set("carNum",t),r.searchParams.set("url",s),r.searchParams.set("source",a),r.href}async openFc2Page(e,t,s,a={newTab:!0},{source:r=""}={}){r=["fc2","123av"].includes(r)?r:"";let i=String(e||"").trim();if(!i)return void utils.openPage(s,t,!0,a);utils.openPage(this.createFc2PageUrl(i,t,s,{source:r}),t,!0,a)}};d(Li,"Fc2Plugin");var ta=Li;var Mi=class Mi extends I{getName(){return"HitShowPlugin"}async handle(){let e=je(window.location);if(e.kind!=="playback-ranking")return;let t=this.getRuntimeService("host").locateListRoot?.();t&&(t.setAttribute("data-jhs-ranking","playback"),t.setAttribute("data-jhs-ranking-period",e.period),t.setAttribute("data-jhs-ranking-filter",e.filter))}};d(Mi,"HitShowPlugin");var sa=Mi;var Bi=class Bi extends I{getName(){return"JavTrailersPlugin"}constructor(){super(),this.hasBand=!1}async handle(){let e=window.location.href;if(!e.includes("handle=1"))return;if($("h1:contains('Page not found')").length){clog.log("番号无法匹配, 跳搜索");let a=e.split("?")[0].split("video/")[1].toLowerCase().replace("00","-");return void(window.location.href="/search/"+encodeURIComponent(a)+window.location.search)}let t=$(".videos-list .video-link").toArray();if(t.length){let a=e.split("?")[0].split("search/")[1].toLowerCase(),r=t.find((i=>$(i).find(".vid-title").text().toLowerCase().includes(a)));if(r)return void(window.location.href=$(r).attr("href")+window.location.search)}let s=await this.getRuntimeService("scope")();this.handlePlayJavTrailers(s),this.bindPlaybackControls(s)}bindPlaybackControls(e){let t=$("#videoPlayerContainer"),s=d(()=>this.handlePlayJavTrailers(e),"replay");t.off("click.jhsJavTrailers").on("click.jhsJavTrailers",s),e.addCleanup((()=>t.off("click.jhsJavTrailers",s))),e.listen(window,"message",(()=>{let a=document.getElementById("vjs_video_3_html5_api");a&&(a.currentTime+=5)}))}handlePlayJavTrailers(e){if(this.hasBand||e.signal.aborted)return;let t=utils.loopDetector((()=>$("#vjs_video_3_html5_api").length!==0),(()=>{e.signal.aborted||e.ownTimeout(setTimeout((()=>{if(e.signal.aborted)return;this.hasBand=!0;let a=document.getElementById("vjs_video_3_html5_api");a&&(clog.debug(a),de(a,{context:"JavTrailers 预览"}),a.currentTime=5,e.listen(a,"timeupdate",(function(){a.currentTime>=14&&a.currentTime<16&&(a.currentTime+=2)})),$("#vjs_video_3_html5_api").css({position:"fixed",width:"100vw",height:"100vh",objectFit:"cover",zIndex:String(W.debug)}),$(".vjs-control-bar").css({position:"fixed",bottom:"20px",zIndex:String(W.debug)}))}),100))}),20,1e4,!0,e),s=utils.loopDetector((()=>$("#vjs_video_3 canvas").length>0),(()=>{e.signal.aborted||$("#vjs_video_3 canvas").length!==0&&$("#vjs_video_3 canvas").css({position:"fixed",width:"100vw",height:"100vh",objectFit:"cover",top:"0",right:"0",zIndex:String(W.debug-1)})}),20,1e4,!0,e);e.addCleanup(t),e.addCleanup(s)}};d(Bi,"JavTrailersPlugin");var aa=Bi;var ra=Object.freeze({magnet:216e5,screenshot:6048e5,screenshotNegative:432e5,match115:36e5,externalDetail:864e5}),Oi=class Oi extends Error{constructor(e,t,s,a={}){super(s,{cause:a.cause}),this.name="ProviderError",this.provider=e,this.code=t,this.status=a.status||0,this.url=a.url||"",this.retryable=!!a.retryable}};d(Oi,"ProviderError");var we=Oi;function cs(o){let e=0,t=Number(o.seeders)||0,s=t>=50?35:t>=10?25:t>=1?15:3;e+=s;let a=String(o.title||"").toLowerCase(),r=String(o.resolution||"").toLowerCase(),i=/4k|2160p/.test(r)||/4k|2160p/.test(a)?25:/1080p/.test(r)||/1080p/.test(a)?20:/720p/.test(r)||/720p/.test(a)?15:5;e+=i;let n=o.hasSubtitle||/-c\b|-uc\b|chinese|中字|字幕/.test(a)?20:0;e+=n;let l=Oh(o.date),c=l<=7?15:l<=30?12:l<=90?8:3;e+=c;let h=/sample|预告|trailer/.test(a)?-15:0;return e+=h,{total:Math.max(0,Math.min(100,e)),seeders:s,resolution:i,subtitle:n,freshness:c,completeness:h}}d(cs,"calcMagnetScore");function Oh(o){try{let e=new Date(String(o||""));return Number.isNaN(e.getTime())?999:Math.max(0,Math.floor((Date.now()-e.getTime())/864e5))}catch{return 999}}d(Oh,"daysSince");function Ui(o,e=!1){let t=String(o||"").toLowerCase(),s=/(?:4k|2160p|1080p|720p)/.exec(t)?.[0]||"",a=e||/(?:-c\b|-u(?:c)?\b|chinese|中字|字幕)/.test(t);return{resolution:s,subtitle:a,recognized:!!s||a,highQuality:s==="4k"||s==="2160p"||a}}d(Ui,"getMagnetQualitySignals");function xc({title:o="",hasHdTag:e=!1,hasSubtitleTag:t=!1,date:s=null,seeders:a=0}={}){let r=Ui(o,t),i=e||r.highQuality,n=cs({title:o,date:s,seeders:a,resolution:e&&!r.resolution?"1080p":r.resolution,hasSubtitle:r.subtitle});return{...r,highQuality:i,score:n,grade:n.total>=70?"高":n.total>=40?"中":"低"}}d(xc,"assessMagnetQuality");function wt(o,e="other"){if(!o||typeof o!="object"||Array.isArray(o))return null;let t=o,s=T(t.carNum);return s?Object.freeze({...t,carNum:s,movieId:typeof t.movieId=="string"&&t.movieId.trim()?t.movieId.trim():null,surface:t.surface||e}):null}d(wt,"normalizeMovieContext");function kc(o,e="other"){let t=wt(o,e);if(!t)throw new TypeError("Movie context requires a valid carNum");return t}d(kc,"createMovieContext");function ia(o){let e=o?.nodeType?o:o?.[0]||null;for(;e;){let s=(typeof globalThis.$=="function"?globalThis.$(e):null)?.data?.("jhsMovieContext")||e.__jhsMovieContext,a=wt(s);if(a)return a;e=e.parentElement||null}return null}d(ia,"readOwnedMovieContext");function zi(o={}){let e=wt(o.explicitContext);if(e)return{context:e,source:"explicit"};let t=wt(o.ownedResolver?.()??ia(o.trigger),"other");if(t)return{context:t,source:t.surface==="fc2-dialog"?"fc2-workspace":"owned-surface"};let s=wt(o.listResolver?.(),"list-item");if(s)return{context:s,source:"list-item"};let a=wt(o.nativeResolver?.(),"native-detail");if(a)return{context:a,source:"native-detail"};let r=wt(o.legacyResolver?.(),"other");return r?(o.logger?.("movie-context source=legacy-fallback",r),{context:r,source:"legacy-fallback"}):{context:null,source:"missing"}}d(zi,"resolveMovieContext");var Fi=class Fi extends I{constructor(){super(...arguments),this.sourceRegistry=new Yt,this.searchEngines=[]}async initializeSources(){let e=new nt,t=this.getRuntimeService("magnet"),s=await e.getBuiltInSources(),a=await e.getMagnetSources(),r=t.getBuiltInSources(),i=[...Ns,...r],n=d(h=>({...i.find(u=>u.id===h)||{},...s.find(u=>u.id===h)||{}}),"configured"),l=r.map((h=>{let u=n(h.id),p=String(u.baseUrl||h.baseUrl).replace(/\/$/,"");return{...h,...u,search:d(async g=>t.searchSource(h.id,g,{baseUrl:p,scope:await this.getRuntimeService("scope")()}),"search"),targetUrl:d(g=>t.getSourceTargetUrl(h.id,g,{baseUrl:p}),"targetUrl")}}));this.sourceRegistry=new Yt([{name:"JavDB 本站",id:"native-javdb",applicable:M,enabled:M,priority:1,search:d(async(h,u=document)=>ci(u?.jquery?u[0]:u,"javdb"),"search"),targetUrl:d(()=>window.location.href,"targetUrl")},{name:"JavBus 本站",id:"native-javbus",applicable:B,enabled:B,priority:2,search:d(async(h,u=document)=>ci(u?.jquery?u[0]:u,"javbus"),"search"),targetUrl:d(()=>window.location.href,"targetUrl")},...l].map((h=>{let u=n(h.id),p=h.applicable??!0;return{...h,...u,enabled:p&&(u.enabled??h.enabled??!0),search:h.search,targetUrl:h.targetUrl}}))),a.filter(h=>h.enabled).forEach(h=>this.sourceRegistry.register({...h,id:`custom:${h.id}`,search:d(u=>this.searchCustomSource(h,u),"search"),targetUrl:d(u=>h.targetUrlTemplate.replaceAll("{keyword}",encodeURIComponent(u)),"targetUrl")}));let c=this.sourceRegistry.getEnabledSources().map((h=>({...h,targetPage:h.targetUrl("{keyword}").replace("%7Bkeyword%7D","{keyword}")})));this.searchEngines=c.length?[{id:"all",name:"全部",priority:0,targetPage:"#",targetUrl:d(()=>"#","targetUrl"),search:d(h=>this.searchAllSources(c,h),"search")},...c]:[]}getName(){return"MagnetHubPlugin"}async initCss(){return``}async handle(){if(!X.includes("collection_codes?movieId"))return;let e=new URLSearchParams(window.location.search),t=e.get("movieId"),s=e.get("carNum"),a=e.get("url"),r=e.get("source"),i=$("section").first().empty();if(!s||!a)return void i.append($('
').text("FC2 详情参数不完整"));let n=t&&t!=="search"?t:await this.resolveMovieIdForRecord(s,a),l=["fc2","123av"].includes(r||"")?r:await this.resolveFc2Source({url:a}),c=this.mountFc2Detail(i,{movieId:n,carNum:s,url:a,source:l,mode:"page"});$(window).off("pagehide.jhsFc2Detail").one("pagehide.jhsFc2Detail",(()=>c.destroy()))}openFc2Dialog(e,t,s,{source:a=""}={}){a=["fc2","123av"].includes(a)?a:"";let r=null;return this.getRuntimeService("dialog").open({type:1,title:t,content:'
',ui:{size:"workspace",body:"scroll"},area:utils.getDialogArea("workspace"),skin:"movie-detail-layer",scrollbar:!1,shadeClose:!0,success:d((i,n)=>{r=this.mountFc2Detail($(i).find(".jhs-fc2-dialog-host"),{movieId:e,carNum:t,url:s,source:a,layerIndex:n,mode:"dialog"}),utils.setupEscClose(n)},"success"),end:d(()=>r?.destroy(),"end")})}mountFc2Detail(e,t){let s=$(e);s.data("jhsFc2Context")?.destroy?.(),s.empty();let r=Sc(t).appendTo(s),i=xc(r,t);return s.data("jhsFc2Context",i),i.translationGeneration=0,i.screenshotGeneration=0,i.otherSiteGeneration=0,this.initializeWorkspace(i),this.bindFc2FeatureLifecycle(i),i}initializeWorkspace(e){let t=$(''),s=$('
');s.append(Mt()),s.append('JavDB 想看(关联中) ','字幕 (SubtitleCat) ','字幕 (迅雷) '),t.find(".jhs-fc2-summary__body").append(s),e.getSlot("summary").append(t);let a=$('
'),r=$('
');a.on(`click${e.namespace}`,".jhs-fc2-gallery-item",(f=>{let v=$(f.currentTarget).find("img")[0];v&&globalThis.showImageViewer(v,"",{galleryRoot:a[0]})})),e.getSlot("gallery").append(a,r);let i=$('
'),n=this.createResourceGroup("站内磁力","native-magnets"),l=this.createResourceGroup("第三方站点","other-sites"),c=this.createResourceGroup("更多磁力来源","magnet-hub"),h=$('展开磁力搜索 '),u=null;c.find('[data-jhs-role="magnet-hub"]').append(h,'
'),i.append(n,l,c),e.getSlot("resources").append(i),s.on(`click${e.namespace}`,'[data-jhs-action="subtitlecat"]',(f=>{let v=this.getRuntimeService("movie").sourceUrls({carNum:e.carNum},["subtitlecat"])[0]?.url;v&&utils.openPage(v,e.carNum,!1,f)}));let p=this.getOptionalDependency("DetailPageButtonPlugin");p?s.on(`click${e.namespace}`,'[data-jhs-action="xunlei"]',(()=>p.searchXunLeiSubtitle(e.carNum))):s.find('[data-jhs-action="xunlei"]').remove();let g=this.getOptionalDependency("MagnetHubPlugin");g||c.remove(),h.on(`click${e.namespace}`,(async()=>{if(!g||!e.isAlive())return;let f=c.find('[data-jhs-role="magnet-hub-content"]');if(h.attr("aria-expanded")==="true")return c.addClass("is-collapsed"),void h.attr("aria-expanded","false").text("展开磁力搜索");u||(u=g.createMagnetHub({movieContext:e.movieContext,root:e.root}));let b=await u;e.isAlive()&&!f.children().length&&f.append(b),e.isAlive()&&(c.removeClass("is-collapsed"),h.attr("aria-expanded","true").text("收起磁力搜索"),f[0]?.scrollIntoView?.({block:"nearest"}))})),this.getDetailStateController().bind({root:e.root,layerIndex:e.layerIndex??null,carNum:e.carNum,activityType:"fc2-state",getRecord:d(()=>({carNum:e.carNum,url:e.url,fc2Source:e.source,names:e.root.find('[data-jhs-role="actress-data"]').text(),publishTime:e.root.find('[data-jhs-role="publish-time"]').text()}),"getRecord")}),e.source==="123av"?this.load123AvDetail(e):this.loadNativeDetail(e);let m=this.getOptionalDependency("FilterTitleKeywordPlugin");m&&Promise.resolve().then((()=>m.bindDetailRoot(e.root,{layerIndex:e.layerIndex??null}))).catch((f=>clog.error("FC2 关键词过滤初始化失败",f))),this.mountFc2OtherSites(e,l,this.getOptionalDependency("OtherSitePlugin")),this.loadFc2Screenshot(e)}bindFc2FeatureLifecycle(e){let t=this.getRuntimeService("settings"),s=d(a=>{let r=a.detail?.names;if(r?.length&&(r.includes("enableLoadScreenShot")&&(t.snapshot().enableLoadScreenShot==="no"?(e.screenshotGeneration=(e.screenshotGeneration||0)+1,this.unmountFc2Screenshot(e)):this.loadFc2Screenshot(e)),r.includes("translateTitle")&&((t.snapshot().translateTitle??E)===E?this.applyFc2Translation(e):(e.translationGeneration=(e.translationGeneration||0)+1,this.revertFc2Translation(e))),r.includes("enableMagnetsFilter")&&e.magnetFilterApply?.((t.snapshot().enableMagnetsFilter??E)===E),r.includes("enableLoadOtherSite"))){let i=e.getSection("resources").find('[data-jhs-role="other-sites"]').closest(".jhs-fc2-resource-group");t.snapshot().enableLoadOtherSite==="no"?(e.otherSiteGeneration=(e.otherSiteGeneration||0)+1,this.unmountFc2OtherSites(e,i)):this.mountFc2OtherSites(e,i,this.getOptionalDependency("OtherSitePlugin"))}},"handler");t.addEventListener("settings.changed",s),e.addObserver({disconnect:d(()=>t.removeEventListener("settings.changed",s),"disconnect")})}loadFc2Screenshot(e){let t=this.getRuntimeService("screenshot"),s=this.getRuntimeService("settings"),a=e.root.find('[data-jhs-role="screenshot"]');if(!t.isEnabled(s.snapshot()))return void a.empty();let r=(e.screenshotGeneration||0)+1;e.screenshotGeneration=r,Promise.resolve().then((()=>this.getRuntimeService("scope")())).then(i=>ta({target:a,carNum:e.carNum.replace("FC2-",""),screenshot:t,settings:s.snapshot(),scope:i,isActive:d(()=>e.isAlive()&&s.snapshot().enableLoadScreenShot!=="no"&&r===e.screenshotGeneration,"isActive"),isDuplicate:d(n=>!!e.galleryUrls?.has(n),"isDuplicate")})).then(i=>{if(!(!e.isAlive()||r!==e.screenshotGeneration)&&s.snapshot().enableLoadScreenShot==="no")return void a.empty()}).catch(i=>{!e.isAlive()||r!==e.screenshotGeneration||(a.empty(),clog.error("FC2 剧照初始化失败",i))})}unmountFc2Screenshot(e){e.screenshotGeneration=(e.screenshotGeneration||0)+1,e.root.find('[data-jhs-role="screenshot"]').empty()}applyFc2Translation(e){let t=this.getRuntimeService("settings");if(!e.isAlive()||(t.snapshot().translateTitle??E)!==E)return;let s=(e.translationGeneration||0)+1;e.translationGeneration=s,Promise.resolve().then((()=>this.getRuntimeService("scope")())).then(a=>ea({root:e.root,carNum:e.carNum,translation:this.getRuntimeService("translation"),scope:a,isActive:d(()=>e.isAlive()&&(t.snapshot().translateTitle??E)===E&&s===e.translationGeneration,"isActive")})).catch((a=>clog.error("FC2 标题翻译失败",a)))}revertFc2Translation(e){e.root.find(".translated-title").remove()}mountFc2OtherSites(e,t,s){if(!s)return void t.remove();let a=this.getRuntimeService("settings"),r=(e.otherSiteGeneration||0)+1;e.otherSiteGeneration=r,t.length&&t.show(),Promise.resolve().then((()=>s.loadOtherSite(e.carNum.replace("FC2-",""),e.carNum,{root:e.root,target:t.find('[data-jhs-role="other-sites"]'),autoDetect:!1,isActive:d(()=>e.isAlive()&&a.snapshot().enableLoadOtherSite!=="no"&&r===e.otherSiteGeneration,"isActive")}))).then(i=>{!e.isAlive()||r!==e.otherSiteGeneration||(i?t.show():t.hide())}).catch(i=>{!e.isAlive()||r!==e.otherSiteGeneration||(t.show(),he(e.root.find('[data-jhs-role="other-sites"]'),"外部站点加载失败"),clog.error("FC2 外部站点加载失败",i))})}unmountFc2OtherSites(e,t){e.otherSiteGeneration=(e.otherSiteGeneration||0)+1,e.root.find("[data-jhs-other-site-box],[data-jhs-other-site-settings]").remove(),t.length&&t.hide()}createResourceGroup(e,t){return $('').find("h3").text(e).end().find("div").attr("data-jhs-role",t).end()}async loadNativeDetail(e){let t=Promise.resolve(e.movieId);this.configureJavDbWantButton(e,t),await Promise.allSettled([this.fetchAndRenderNativeDetail(e),this.fetchAndRenderNativeMagnets(e),this.mountPanels(e,t)]),e.isAlive()&&this.applyFc2Translation(e)}async load123AvDetail(e){let t=this.getOptionalDependency("Fc2By123AvPlugin");if(!t)return void he(e.getSlot("summary"),"123AV 详情功能已禁用");let s=t.resolveMovieId(e.carNum);this.configureJavDbWantButton(e,s),this.mountPanels(e,s),s.then((a=>{if(e.isAlive())return this.fetchAndRenderNativeMagnets(e,a)})).catch((a=>{e.isAlive()&&he(e.root.find('[data-jhs-role="native-magnets"]'),"站内磁力关联失败",(()=>{this.load123AvMagnets(e)})),clog.error("123AV 磁力关联失败",a)})),await t.loadDetail(e,e.url),e.isAlive()&&this.applyFc2Translation(e)}async load123AvMagnets(e){let t=this.getOptionalDependency("Fc2By123AvPlugin");if(!t)throw new Error("123AV 详情功能已禁用");let s=await t.resolveMovieId(e.carNum);return this.fetchAndRenderNativeMagnets(e,s)}async configureJavDbWantButton(e,t){let s=e.root.find('[data-jhs-action="javdb-want"]');try{let a=await t;if(!e.isAlive())return;if(!a)return void s.prop("disabled",!0).text("JavDB 暂无对应作品");try{let r=await yc(a);if(!e.isAlive())return;if(r)return void s.prop("disabled",!0).attr("aria-pressed","true").text("已在 JavDB 想看")}catch(r){clog.warn("读取 JavDB 想看状态失败,保留手动操作",r)}s.prop("disabled",!1).text("JavDB 想看").off(`click${e.namespace}`).on(`click${e.namespace}`,(()=>{this.submitJavDbWant(e,a,s)}))}catch(a){e.isAlive()&&s.prop("disabled",!1).text("JavDB 关联失败,重试").off(`click${e.namespace}`).on(`click${e.namespace}`,(()=>{this.configureJavDbWantButton(e,this.resolveMovieId(e.carNum))})),clog.error("FC2 JavDB 想看关联失败",a)}}async submitJavDbWant(e,t,s){if(!(!e.isAlive()||s.data("jhsBusy")||s.attr("aria-pressed")==="true")){s.data("jhsBusy",!0).attr({"aria-busy":"true","aria-disabled":"true"}).text("正在加入想看…");try{if(await wc(t),!e.isAlive())return;s.attr({"aria-pressed":"true","aria-disabled":"false"}).text("已加入 JavDB 想看"),show.ok("已加入 JavDB 想看")}catch(a){if(!e.isAlive())return;let r=a;if(r?.code==="LOGIN_REQUIRED")return s.attr("aria-disabled","false").text("JavDB 想看"),jc({dialog:this.getRuntimeService("dialog"),account:this.getRuntimeService("account"),credential:this.getRuntimeService("credential"),getScope:this.getRuntimeService("scope"),onSuccess:d(()=>this.submitJavDbWant(e,t,s),"onSuccess")});s.attr("aria-disabled","false").text("JavDB 想看"),show.error(r?.message||"加入 JavDB 想看失败"),clog.error("加入 JavDB 想看失败",a)}finally{e.isAlive()&&s.removeData("jhsBusy").removeAttr("aria-busy")}}}async fetchAndRenderNativeDetail(e){try{let t=await this.getRuntimeService("scope")(),s=await this.getRuntimeService("movie").detail({movieId:e.movieId,carNum:e.carNum,providerId:"javdb"},{scope:t});if(!s)throw new Error("JavDB 影片详情不存在");if(!e.isAlive())return;this.renderSummary(e,s),os(e,s.imageUrls||[],s.coverUrl||null)}catch(t){e.isAlive()&&he(e.root.find('[data-jhs-role="summary-content"]'),"影片信息加载失败",(()=>{this.fetchAndRenderNativeDetail(e)})),clog.error("FC2 详情加载失败",t)}}renderSummary(e,t){let s=e.root.find('[data-jhs-role="summary-content"]').empty(),a=$(' ');a.find("strong").text(t.title||"无标题"),s.append(a),t.originalTitle&&t.originalTitle!==t.title&&s.append($('
').text(t.originalTitle));let r=$('
');[`番号:${t.carNum||e.carNum}`,`发行:${t.releaseDate||"未知"}`,`评分:${Number.isFinite(Number(t.score))?t.score:"无"}`,`时长:${Number.isFinite(Number(t.duration))?t.duration+" 分钟":"无"}`].forEach((l=>r.append($(" ").text(l)))),s.append(r);let i=[],n=$('主演:
');(t.actors||[]).forEach((l=>{n.append($(" ").addClass("jhs-fc2-actor").attr({href:`/actors/${encodeURIComponent(l.id)}`,target:"_blank",rel:"noopener noreferrer"}).text(l.name||"未知演员")),l.gender===0&&i.push(l.name)})),t.actors?.length||n.append($(" ").text("暂无演员信息")),s.append(n,Qs(e,this.getRuntimeService("movie")),$(' ').text(i.join(" ")),$(' ').text(t.releaseDate||""))}async fetchAndRenderNativeMagnets(e,t=e.movieId){let s=e.root.find('[data-jhs-role="native-magnets"]');he(s,"正在加载站内磁力…");try{if(!t)return he(s,"JavDB 暂无对应作品");let a=await this.getRuntimeService("scope")(),r=await this.getRuntimeService("magnet").listNative({movieId:t,providerId:"javdb"},{scope:a});if(!e.isAlive())return;if(s.empty(),!r.length)return he(s,"暂无站内磁力");let i=[],n=this.getRuntimeService("magnet");r.forEach((l=>{let c=yl(l.hash);if(!c)return;let h=`magnet:?xt=urn:btih:${c}`,u=n.assess({title:l.title,hasHdTag:l.hasHdTag,hasSubtitleTag:l.hasSubtitleTag,date:l.createdAt,seeders:l.seeders}),p=$('
').attr("data-jhs-high-quality",String(u.highQuality)),g=$('
'),m=$('
'),f=$('
');i.push(u),f.append($(" ").addClass("jhs-badge").attr("title",`磁力质量评分 ${u.score.total}`).text(`${u.grade} ${u.score.total}`)),l.hasHdTag&&f.append('高清 '),l.hasSubtitleTag&&f.append('字幕 '),g.append($(" ").attr("href",h).text(l.title||h),$("
").addClass("jhs-fc2-meta").text(`${(Number(l.sizeMb||0)/1024).toFixed(2)} GB · ${Number(l.fileCount)||0} 个文件${l.createdAt?` · ${l.createdAt}`:""}`),f),m.append($('复制 ').attr("data-clipboard-text",h),$('离线 ').attr({"data-resource":h,"data-jhs-offline-owner":"fc2"})),s.append(p.append(g,m))})),await this.bindNativeMagnetFilter(e,s,i.some((l=>l.highQuality)))}catch(a){e.isAlive()&&he(s,"站内磁力加载失败",(()=>{this.fetchAndRenderNativeMagnets(e,t)})),clog.error("FC2 磁力加载失败",a)}}async bindNativeMagnetFilter(e,t,s){let a=e.getSection("resources"),r=a.find(".jhs-fc2-section__actions");r.find('[data-jhs-action="filter-native-magnets"]').remove();let n=$(' '),l=d(u=>{t.find(".jhs-fc2-magnet-item").show(),u&&s&&t.find('.jhs-fc2-magnet-item[data-jhs-high-quality="false"]').hide(),n.attr("aria-pressed",String(u&&s)).text(s?u?"显示全部磁力":"过滤低质量":"暂无可过滤项").prop("disabled",!s)},"apply"),c=this.getRuntimeService("settings"),h=Ve({settings:c,key:"enableMagnetsFilter",fallback:"no",apply:d(u=>l(u===E),"apply"),onError:d(u=>{clog.error("磁力过滤设置保存失败,已恢复",u),show.error("磁力过滤设置保存失败,已恢复原设置")},"onError")});e.magnetFilterApply=l,r.append(n),l((c.snapshot().enableMagnetsFilter??E)===E),n.on(`click${e.namespace}`,(async()=>{let u=n.attr("aria-pressed")!=="true";await h(u?E:"no")}))}async mountPanels(e,t){try{let s=await t;if(!e.isAlive())return;if(!s)return this.clearOwnedPanel(e,"reviews"),this.clearOwnedPanel(e,"related"),he(e.getSlot("reviews"),"JavDB 暂无对应作品"),he(e.getSlot("related"),"JavDB 暂无对应作品");this.clearOwnedPanel(e,"reviews"),this.clearOwnedPanel(e,"related");let a=d(()=>this.getRuntimeService("scope")(),"scope"),r=new Ot({related:this.getRuntimeService("related"),settings:this.getRuntimeService("settings"),scope:a}),i=new Ut({review:this.getRuntimeService("review"),settings:this.getRuntimeService("settings"),storage:this.getRuntimeService("storage"),scope:a});await Promise.allSettled([i.show(s,e.getSlot("reviews"),{ownedSection:e.getSection("reviews"),isActive:e.isAlive,ownCleanup:d(n=>e.addObserver({disconnect:n}),"ownCleanup")}),r.show(e.getSlot("related"),s,{ownedSection:e.getSection("related"),isActive:e.isAlive,ownCleanup:d(n=>e.addObserver({disconnect:n}),"ownCleanup")})])}catch(s){if(!e.isAlive())return;this.clearOwnedPanel(e,"reviews"),this.clearOwnedPanel(e,"related");let a=d(()=>{this.mountPanels(e,this.resolveMovieId(e.carNum))},"retry");he(e.getSlot("reviews"),"评论关联失败",a),he(e.getSlot("related"),"相关清单关联失败",a),clog.error("FC2 JavDB 关联失败",s)}}clearOwnedPanel(e,t){e.getSlot(t).empty(),e.getSection(t).find(".jhs-fc2-section__actions").empty()}async resolveFc2Source(e={}){if(e.fc2Source&&["fc2","123av"].includes(e.fc2Source))return e.fc2Source;try{let t=new URL(e.url||"",window.location.origin);return this.getRuntimeService("movie").matchesProviderUrl("av123",t.href)?"123av":t.origin===window.location.origin?"fc2":""}catch{return""}}createFc2PageUrl(e,t,s,{source:a=""}={}){if(!String(e||"").trim())throw new TypeError("FC2 owned detail requires movieId");let r=new URL("/users/collection_codes",window.location.origin);return r.searchParams.set("movieId",String(e).trim()),r.searchParams.set("carNum",t),r.searchParams.set("url",s),r.searchParams.set("source",a),r.href}async openFc2Page(e,t,s,a={newTab:!0},{source:r=""}={}){r=["fc2","123av"].includes(r)?r:"";let i=String(e||"").trim();if(!i)return void utils.openPage(s,t,!0,a);utils.openPage(this.createFc2PageUrl(i,t,s,{source:r}),t,!0,a)}};d(Mi,"Fc2Plugin");var sa=Mi;var Bi=class Bi extends I{getName(){return"HitShowPlugin"}async handle(){let e=je(window.location);if(e.kind!=="playback-ranking")return;let t=this.getRuntimeService("host").locateListRoot?.();t&&(t.setAttribute("data-jhs-ranking","playback"),t.setAttribute("data-jhs-ranking-period",e.period),t.setAttribute("data-jhs-ranking-filter",e.filter))}};d(Bi,"HitShowPlugin");var aa=Bi;var Oi=class Oi extends I{getName(){return"JavTrailersPlugin"}constructor(){super(),this.hasBand=!1}async handle(){let e=window.location.href;if(!e.includes("handle=1"))return;if($("h1:contains('Page not found')").length){clog.log("番号无法匹配, 跳搜索");let a=e.split("?")[0].split("video/")[1].toLowerCase().replace("00","-");return void(window.location.href="/search/"+encodeURIComponent(a)+window.location.search)}let t=$(".videos-list .video-link").toArray();if(t.length){let a=e.split("?")[0].split("search/")[1].toLowerCase(),r=t.find((i=>$(i).find(".vid-title").text().toLowerCase().includes(a)));if(r)return void(window.location.href=$(r).attr("href")+window.location.search)}let s=await this.getRuntimeService("scope")();this.handlePlayJavTrailers(s),this.bindPlaybackControls(s)}bindPlaybackControls(e){let t=$("#videoPlayerContainer"),s=d(()=>this.handlePlayJavTrailers(e),"replay");t.off("click.jhsJavTrailers").on("click.jhsJavTrailers",s),e.addCleanup((()=>t.off("click.jhsJavTrailers",s))),e.listen(window,"message",(()=>{let a=document.getElementById("vjs_video_3_html5_api");a&&(a.currentTime+=5)}))}handlePlayJavTrailers(e){if(this.hasBand||e.signal.aborted)return;let t=utils.loopDetector((()=>$("#vjs_video_3_html5_api").length!==0),(()=>{e.signal.aborted||e.ownTimeout(setTimeout((()=>{if(e.signal.aborted)return;this.hasBand=!0;let a=document.getElementById("vjs_video_3_html5_api");a&&(clog.debug(a),de(a,{context:"JavTrailers 预览"}),a.currentTime=5,e.listen(a,"timeupdate",(function(){a.currentTime>=14&&a.currentTime<16&&(a.currentTime+=2)})),$("#vjs_video_3_html5_api").css({position:"fixed",width:"100vw",height:"100vh",objectFit:"cover",zIndex:String(J.debug)}),$(".vjs-control-bar").css({position:"fixed",bottom:"20px",zIndex:String(J.debug)}))}),100))}),20,1e4,!0,e),s=utils.loopDetector((()=>$("#vjs_video_3 canvas").length>0),(()=>{e.signal.aborted||$("#vjs_video_3 canvas").length!==0&&$("#vjs_video_3 canvas").css({position:"fixed",width:"100vw",height:"100vh",objectFit:"cover",top:"0",right:"0",zIndex:String(J.debug-1)})}),20,1e4,!0,e);e.addCleanup(t),e.addCleanup(s)}};d(Oi,"JavTrailersPlugin");var ra=Oi;var ia=Object.freeze({magnet:216e5,screenshot:6048e5,screenshotNegative:432e5,match115:36e5,externalDetail:864e5}),Ui=class Ui extends Error{constructor(e,t,s,a={}){super(s,{cause:a.cause}),this.name="ProviderError",this.provider=e,this.code=t,this.status=a.status||0,this.url=a.url||"",this.retryable=!!a.retryable}};d(Ui,"ProviderError");var we=Ui;function cs(o){let e=0,t=Number(o.seeders)||0,s=t>=50?35:t>=10?25:t>=1?15:3;e+=s;let a=String(o.title||"").toLowerCase(),r=String(o.resolution||"").toLowerCase(),i=/4k|2160p/.test(r)||/4k|2160p/.test(a)?25:/1080p/.test(r)||/1080p/.test(a)?20:/720p/.test(r)||/720p/.test(a)?15:5;e+=i;let n=o.hasSubtitle||/-c\b|-uc\b|chinese|中字|字幕/.test(a)?20:0;e+=n;let l=Uh(o.date),c=l<=7?15:l<=30?12:l<=90?8:3;e+=c;let h=/sample|预告|trailer/.test(a)?-15:0;return e+=h,{total:Math.max(0,Math.min(100,e)),seeders:s,resolution:i,subtitle:n,freshness:c,completeness:h}}d(cs,"calcMagnetScore");function Uh(o){try{let e=new Date(String(o||""));return Number.isNaN(e.getTime())?999:Math.max(0,Math.floor((Date.now()-e.getTime())/864e5))}catch{return 999}}d(Uh,"daysSince");function zi(o,e=!1){let t=String(o||"").toLowerCase(),s=/(?:4k|2160p|1080p|720p)/.exec(t)?.[0]||"",a=e||/(?:-c\b|-u(?:c)?\b|chinese|中字|字幕)/.test(t);return{resolution:s,subtitle:a,recognized:!!s||a,highQuality:s==="4k"||s==="2160p"||a}}d(zi,"getMagnetQualitySignals");function kc({title:o="",hasHdTag:e=!1,hasSubtitleTag:t=!1,date:s=null,seeders:a=0}={}){let r=zi(o,t),i=e||r.highQuality,n=cs({title:o,date:s,seeders:a,resolution:e&&!r.resolution?"1080p":r.resolution,hasSubtitle:r.subtitle});return{...r,highQuality:i,score:n,grade:n.total>=70?"高":n.total>=40?"中":"低"}}d(kc,"assessMagnetQuality");function wt(o,e="other"){if(!o||typeof o!="object"||Array.isArray(o))return null;let t=o,s=C(t.carNum);return s?Object.freeze({...t,carNum:s,movieId:typeof t.movieId=="string"&&t.movieId.trim()?t.movieId.trim():null,surface:t.surface||e}):null}d(wt,"normalizeMovieContext");function Cc(o,e="other"){let t=wt(o,e);if(!t)throw new TypeError("Movie context requires a valid carNum");return t}d(Cc,"createMovieContext");function na(o){let e=o?.nodeType?o:o?.[0]||null;for(;e;){let s=(typeof globalThis.$=="function"?globalThis.$(e):null)?.data?.("jhsMovieContext")||e.__jhsMovieContext,a=wt(s);if(a)return a;e=e.parentElement||null}return null}d(na,"readOwnedMovieContext");function Fi(o={}){let e=wt(o.explicitContext);if(e)return{context:e,source:"explicit"};let t=wt(o.ownedResolver?.()??na(o.trigger),"other");if(t)return{context:t,source:t.surface==="fc2-dialog"?"fc2-workspace":"owned-surface"};let s=wt(o.listResolver?.(),"list-item");if(s)return{context:s,source:"list-item"};let a=wt(o.nativeResolver?.(),"native-detail");if(a)return{context:a,source:"native-detail"};let r=wt(o.legacyResolver?.(),"other");return r?(o.logger?.("movie-context source=legacy-fallback",r),{context:r,source:"legacy-fallback"}):{context:null,source:"missing"}}d(Fi,"resolveMovieContext");var Vi=class Vi extends I{constructor(){super(...arguments),this.sourceRegistry=new Yt,this.searchEngines=[]}async initializeSources(){let e=new ot,t=this.getRuntimeService("magnet"),s=await e.getBuiltInSources(),a=await e.getMagnetSources(),r=t.getBuiltInSources(),i=[...Ls,...r],n=d(h=>({...i.find(u=>u.id===h)||{},...s.find(u=>u.id===h)||{}}),"configured"),l=r.map((h=>{let u=n(h.id),p=String(u.baseUrl||h.baseUrl).replace(/\/$/,"");return{...h,...u,search:d(async g=>t.searchSource(h.id,g,{baseUrl:p,scope:await this.getRuntimeService("scope")()}),"search"),targetUrl:d(g=>t.getSourceTargetUrl(h.id,g,{baseUrl:p}),"targetUrl")}}));this.sourceRegistry=new Yt([{name:"JavDB 本站",id:"native-javdb",applicable:M,enabled:M,priority:1,search:d(async(h,u=document)=>di(u?.jquery?u[0]:u,"javdb"),"search"),targetUrl:d(()=>window.location.href,"targetUrl")},{name:"JavBus 本站",id:"native-javbus",applicable:B,enabled:B,priority:2,search:d(async(h,u=document)=>di(u?.jquery?u[0]:u,"javbus"),"search"),targetUrl:d(()=>window.location.href,"targetUrl")},...l].map((h=>{let u=n(h.id),p=h.applicable??!0;return{...h,...u,enabled:p&&(u.enabled??h.enabled??!0),search:h.search,targetUrl:h.targetUrl}}))),a.filter(h=>h.enabled).forEach(h=>this.sourceRegistry.register({...h,id:`custom:${h.id}`,search:d(u=>this.searchCustomSource(h,u),"search"),targetUrl:d(u=>h.targetUrlTemplate.replaceAll("{keyword}",encodeURIComponent(u)),"targetUrl")}));let c=this.sourceRegistry.getEnabledSources().map((h=>({...h,targetPage:h.targetUrl("{keyword}").replace("%7Bkeyword%7D","{keyword}")})));this.searchEngines=c.length?[{id:"all",name:"全部",priority:0,targetPage:"#",targetUrl:d(()=>"#","targetUrl"),search:d(h=>this.searchAllSources(c,h),"search")},...c]:[]}getName(){return"MagnetHubPlugin"}async initCss(){return``}async createMagnetHub(e,t={}){await this.initializeSources();let s=typeof e=="string"?null:e,a=typeof e=="string"?kc({carNum:e}):s?.movieContext;if(!a?.carNum)return $('
').append($('
').text("无法确定影片身份,未加载磁力"));let r=a.carNum.replace("FC2-",""),i=t.root??s?.root?$(t.root??s?.root):$(document),n=[...this.searchEngines],l=this.getRuntimeService("storage"),c=$('
'),h=$('
'),u="jhs_magnetHub_selectedEngine",p=l.getLocal(u);c.data("jhsMovieContext",a);let g=$('
'),m=n.find((w=>w.id===p))||n[0];if(!m)return c.append($('
').text("暂无可用磁力来源,请前往设置启用来源"));let f=m;n.forEach((w=>g.append($(' ').attr("data-engine",w.id).text(w.name).toggleClass("active",w.id===f.id))));let v=$('原网页 ').attr("href",(f.targetPage||"#").replace("{keyword}",encodeURIComponent(r))).toggle(f.id!=="all");h.append(g),h.append(v),g.find(".magnet-tab.active").attr({"aria-selected":"true",tabindex:"0"}),c.append(h);let b=$('
');return c.append(b),c.on("click",".magnet-tab",(w=>{let S=$(w.target).data("engine");f=n.find((j=>j.id===S))||f,f&&(c.find('[data-jhs-role="magnet-target"]').attr("href",(f.targetPage||"#").replace("{keyword}",encodeURIComponent(r))).toggle(f.id!=="all"),l.setLocal(u,S),c.find(".magnet-tab").removeClass("active").attr({"aria-selected":"false",tabindex:"-1"}),$(w.target).addClass("active").attr({"aria-selected":"true",tabindex:"0"}),this.searchEngine(b,f,r,i))})),c.on("keydown",".magnet-tab",(w=>{if(!["ArrowLeft","ArrowRight","Home","End"].includes(w.key))return;w.preventDefault();let S=c.find(".magnet-tab"),j=S.index(w.currentTarget),x=w.key==="Home"?0:w.key==="End"?S.length-1:w.key==="ArrowRight"?(j+1)%S.length:(j-1+S.length)%S.length;S.eq(x).trigger("click").trigger("focus")})),this.searchEngine(b,f,r,i),c}async searchEngine(e,t,s,a=$(document)){e.html(`正在从 ${C(t.name)} 搜索 "${C(s)}"...
`);let r=`${t.name}_${s}`;if(t.search)try{return void this.displayResults(e,await this.applyRuntimeRules(Es(await t.search(s,a))),t.name)}catch(i){return clog.error(`磁力源 ${t.name} 请求失败`,i),void e.html(`${C(t.name)} 请求失败
`)}if(t.parseHtml)try{let i=t.url.replace("{keyword}",encodeURIComponent(s)),n=await this.requestSource(t.id,i,{ttlMs:216e5}),l=t.parseHtml.call(this,n,s);return void this.displayResults(e,l,t.name)}catch(i){return void e.html(`解析 ${C(t.name)} 结果失败: ${C(i instanceof Error?i.message:String(i))}
`)}t.parseJson&&await t.parseJson.call(this,e,t,s,r)}async searchCustomSources(e){let s=JSON.parse(await storageManager.getSetting("customMagnetSources","[]")).filter(r=>r.enabled).map(bt),a=await Te(s,4,(async r=>{let i=r.searchUrlTemplate.replaceAll("{keyword}",encodeURIComponent(e));try{let n=await this.requestSource(r.id,i,{ttlMs:ra.magnet,custom:!0,responseType:r.parserType==="json"?"json":"text"}),l=r.parserType==="json"&&typeof n=="string"?JSON.parse(n):n;return di(r,l,r.id)}catch(n){let l=n;return clog.error(`自定义磁力源 ${r.name} 失败`,new we(r.id,l.code||"HTTP_ERROR",l.message||String(n),{cause:n,url:i,status:l.status,retryable:l.retryable})),[]}}));return Es(a.flat())}async searchCustomSource(e,t){let s=e.searchUrlTemplate.replaceAll("{keyword}",encodeURIComponent(t)),a=await this.requestSource(e.id,s,{ttlMs:ra.magnet,custom:!0,responseType:e.parserType==="json"?"json":"text"});return di(e,e.parserType==="json"&&typeof a=="string"?JSON.parse(a):a,e.id)}async searchAllSources(e,t){let s=await Te(e,3,(async a=>{try{return await a.search(t)}catch(r){return clog.warn(`磁力源 ${a.name} 聚合失败`,r),[]}}));return Es(s.flat())}async requestSource(e,t,s={}){let a=await this.getRuntimeService("scope")();return(await this.getRuntimeService("http").request({providerId:`magnet:${e}`,method:s.method||"GET",url:t,body:s.body,headers:s.headers,responseType:s.responseType||"text",cacheScope:s.method&&s.method!=="GET"?"none":"public",ttlMs:s.ttlMs??ra.magnet,urlPolicy:s.custom?{trustClass:"custom-public"}:{trustClass:"builtin-public",hosts:s.hosts||[new URL(t).hostname]}},a)).data}async applyRuntimeRules(e){let t=new nt,[s,a]=await Promise.all([t.getMagnetTagRules(),t.getMagnetFilterRules()]);return e.map((r=>Cl(r,s,a.filter((i=>(i.target||"title")==="title")),a.filter((i=>i.target==="file"))))).filter((r=>!r.hidden))}async displayResults(e,t,s){function a(r){let i=r.text();r.addClass("copied").text("已复制"),setTimeout((()=>{r.removeClass("copied").text(i)}),2e3)}d(a,"a"),e.empty(),t.length!==0?(t.forEach((r=>{let i=this.calcMagnetScore(r);r._score={...i,total:Math.max(0,Math.min(100,i.total+(r.customTagWeight||0)+(r.filterPenalty||0)))}})),t.sort(((r,i)=>i._score.total-r._score.total)),t.forEach((r=>{let i=r._score?r._score.total:0,n=i>=80?"高":i>=60?"中":"低",l=r._score?`做种:${r._score.seeders}/35 分辨率:${r._score.resolution}/25 字幕:${r._score.subtitle}/20 新鲜度:${r._score.freshness}/15 完整性:${r._score.completeness}/5`:"",c=C(r.title),h=C(r.magnet),u=C(String(r.size||"未知")),p=C(String(r.date||"未知")),g=$(`
+ `}async createMagnetHub(e,t={}){await this.initializeSources();let s=typeof e=="string"?null:e,a=typeof e=="string"?Cc({carNum:e}):s?.movieContext;if(!a?.carNum)return $('
').append($('
').text("无法确定影片身份,未加载磁力"));let r=a.carNum.replace("FC2-",""),i=t.root??s?.root?$(t.root??s?.root):$(document),n=[...this.searchEngines],l=this.getRuntimeService("storage"),c=$('
'),h=$('
'),u="jhs_magnetHub_selectedEngine",p=l.getLocal(u);c.data("jhsMovieContext",a);let g=$('
'),m=n.find((w=>w.id===p))||n[0];if(!m)return c.append($('
').text("暂无可用磁力来源,请前往设置启用来源"));let f=m;n.forEach((w=>g.append($(' ').attr("data-engine",w.id).text(w.name).toggleClass("active",w.id===f.id))));let v=$('原网页 ').attr("href",(f.targetPage||"#").replace("{keyword}",encodeURIComponent(r))).toggle(f.id!=="all");h.append(g),h.append(v),g.find(".magnet-tab.active").attr({"aria-selected":"true",tabindex:"0"}),c.append(h);let b=$('
');return c.append(b),c.on("click",".magnet-tab",(w=>{let S=$(w.target).data("engine");f=n.find((j=>j.id===S))||f,f&&(c.find('[data-jhs-role="magnet-target"]').attr("href",(f.targetPage||"#").replace("{keyword}",encodeURIComponent(r))).toggle(f.id!=="all"),l.setLocal(u,S),c.find(".magnet-tab").removeClass("active").attr({"aria-selected":"false",tabindex:"-1"}),$(w.target).addClass("active").attr({"aria-selected":"true",tabindex:"0"}),this.searchEngine(b,f,r,i))})),c.on("keydown",".magnet-tab",(w=>{if(!["ArrowLeft","ArrowRight","Home","End"].includes(w.key))return;w.preventDefault();let S=c.find(".magnet-tab"),j=S.index(w.currentTarget),k=w.key==="Home"?0:w.key==="End"?S.length-1:w.key==="ArrowRight"?(j+1)%S.length:(j-1+S.length)%S.length;S.eq(k).trigger("click").trigger("focus")})),this.searchEngine(b,f,r,i),c}async searchEngine(e,t,s,a=$(document)){e.html(`正在从 ${T(t.name)} 搜索 "${T(s)}"...
`);let r=`${t.name}_${s}`;if(t.search)try{return void this.displayResults(e,await this.applyRuntimeRules(Ds(await t.search(s,a))),t.name)}catch(i){return clog.error(`磁力源 ${t.name} 请求失败`,i),void e.html(`${T(t.name)} 请求失败
`)}if(t.parseHtml)try{let i=t.url.replace("{keyword}",encodeURIComponent(s)),n=await this.requestSource(t.id,i,{ttlMs:216e5}),l=t.parseHtml.call(this,n,s);return void this.displayResults(e,l,t.name)}catch(i){return void e.html(`解析 ${T(t.name)} 结果失败: ${T(i instanceof Error?i.message:String(i))}
`)}t.parseJson&&await t.parseJson.call(this,e,t,s,r)}async searchCustomSources(e){let s=JSON.parse(await storageManager.getSetting("customMagnetSources","[]")).filter(r=>r.enabled).map(bt),a=await Ae(s,4,(async r=>{let i=r.searchUrlTemplate.replaceAll("{keyword}",encodeURIComponent(e));try{let n=await this.requestSource(r.id,i,{ttlMs:ia.magnet,custom:!0,responseType:r.parserType==="json"?"json":"text"}),l=r.parserType==="json"&&typeof n=="string"?JSON.parse(n):n;return hi(r,l,r.id)}catch(n){let l=n;return clog.error(`自定义磁力源 ${r.name} 失败`,new we(r.id,l.code||"HTTP_ERROR",l.message||String(n),{cause:n,url:i,status:l.status,retryable:l.retryable})),[]}}));return Ds(a.flat())}async searchCustomSource(e,t){let s=e.searchUrlTemplate.replaceAll("{keyword}",encodeURIComponent(t)),a=await this.requestSource(e.id,s,{ttlMs:ia.magnet,custom:!0,responseType:e.parserType==="json"?"json":"text"});return hi(e,e.parserType==="json"&&typeof a=="string"?JSON.parse(a):a,e.id)}async searchAllSources(e,t){let s=await Ae(e,3,(async a=>{try{return await a.search(t)}catch(r){return clog.warn(`磁力源 ${a.name} 聚合失败`,r),[]}}));return Ds(s.flat())}async requestSource(e,t,s={}){let a=await this.getRuntimeService("scope")();return(await this.getRuntimeService("http").request({providerId:`magnet:${e}`,method:s.method||"GET",url:t,body:s.body,headers:s.headers,responseType:s.responseType||"text",cacheScope:s.method&&s.method!=="GET"?"none":"public",ttlMs:s.ttlMs??ia.magnet,urlPolicy:s.custom?{trustClass:"custom-public"}:{trustClass:"builtin-public",hosts:s.hosts||[new URL(t).hostname]}},a)).data}async applyRuntimeRules(e){let t=new ot,[s,a]=await Promise.all([t.getMagnetTagRules(),t.getMagnetFilterRules()]);return e.map((r=>_l(r,s,a.filter((i=>(i.target||"title")==="title")),a.filter((i=>i.target==="file"))))).filter((r=>!r.hidden))}async displayResults(e,t,s){function a(r){let i=r.text();r.addClass("copied").text("已复制"),setTimeout((()=>{r.removeClass("copied").text(i)}),2e3)}d(a,"a"),e.empty(),t.length!==0?(t.forEach((r=>{let i=this.calcMagnetScore(r);r._score={...i,total:Math.max(0,Math.min(100,i.total+(r.customTagWeight||0)+(r.filterPenalty||0)))}})),t.sort(((r,i)=>i._score.total-r._score.total)),t.forEach((r=>{let i=r._score?r._score.total:0,n=i>=80?"高":i>=60?"中":"低",l=r._score?`做种:${r._score.seeders}/35 分辨率:${r._score.resolution}/25 字幕:${r._score.subtitle}/20 新鲜度:${r._score.freshness}/15 完整性:${r._score.completeness}/5`:"",c=T(r.title),h=T(r.magnet),u=T(String(r.size||"未知")),p=T(String(r.date||"未知")),g=$(`
${n} ${i}
@@ -3289,7 +3284,7 @@ ${i}\r
复制链接
- `);r.tags?.length&&g.find(".magnet-info").after($("
").addClass("magnet-tags").append(r.tags.map((f=>$(" ").addClass("jhs-badge").text(f)))));let m=g.find(".magnet-copy");g.find(".copy-btn").removeClass("magnet-hub-btn").addClass("jhs-btn--secondary"),m.append(`离线 `),g.appendTo(e)})),e.on("click",".copy-btn",(async r=>{let i=$(r.currentTarget),n=i.data("magnet");await utils.copyToClipboard("磁力链接",n)&&a(i)}))):e.append('没有找到相关结果
')}calcMagnetScore(e){return cs(e)}};d(Fi,"MagnetHubPlugin");var na=Fi;var Vi=class Vi extends I{constructor(){super(...arguments),this.mountGeneration=0,this._mountGenerations=new WeakMap,this.siteConfigs=[{id:"javTrailersBtn"},{id:"123AvBtn",providerId:"av123"},{id:"jableBtn"},{id:"avgleBtn"},{id:"missAvBtn"},{id:"supJavBtn"},{id:"javDbBtn",condition:d(()=>B,"condition")},{id:"javBusBtn",condition:d(e=>!!(M&&e&&!e.includes("FC2")),"condition")},{id:"fanzaBtn",providerId:"dmm",noHandle:!0,condition:d(e=>!!(e&&!e.includes("FC2")),"condition")}]}getName(){return"OtherSitePlugin"}async getSiteConfigs(){let e=await this.getSettingCache(),t=this.getRuntimeService("movie").externalSites(e);return this.siteConfigs.map(s=>({...t.find((a=>a.id===s.id))||{},...s}))}async initCss(){return`
+ `);r.tags?.length&&g.find(".magnet-info").after($("
").addClass("magnet-tags").append(r.tags.map((f=>$(" ").addClass("jhs-badge").text(f)))));let m=g.find(".magnet-copy");g.find(".copy-btn").removeClass("magnet-hub-btn").addClass("jhs-btn--secondary"),m.append(`离线 `),g.appendTo(e)})),e.on("click",".copy-btn",(async r=>{let i=$(r.currentTarget),n=i.data("magnet");await utils.copyToClipboard("磁力链接",n)&&a(i)}))):e.append('没有找到相关结果
')}calcMagnetScore(e){return cs(e)}};d(Vi,"MagnetHubPlugin");var oa=Vi;var qi=class qi extends I{constructor(){super(...arguments),this.mountGeneration=0,this._mountGenerations=new WeakMap,this.siteConfigs=[{id:"javTrailersBtn"},{id:"123AvBtn",providerId:"av123"},{id:"jableBtn"},{id:"avgleBtn"},{id:"missAvBtn"},{id:"supJavBtn"},{id:"javDbBtn",condition:d(()=>B,"condition")},{id:"javBusBtn",condition:d(e=>!!(M&&e&&!e.includes("FC2")),"condition")},{id:"fanzaBtn",providerId:"dmm",noHandle:!0,condition:d(e=>!!(e&&!e.includes("FC2")),"condition")}]}getName(){return"OtherSitePlugin"}async getSiteConfigs(){let e=await this.getSettingCache(),t=this.getRuntimeService("movie").externalSites(e);return this.siteConfigs.map(s=>({...t.find((a=>a.id===s.id))||{},...s}))}async initCss(){return`
`}async handle(){let e=this.getRuntimeService("settings"),t=await this.getRuntimeService("scope")(),s=d(a=>{a.detail?.names?.includes("enableLoadOtherSite")&&(e.snapshot().enableLoadOtherSite==="no"?this.unmount():this.mount().catch((i=>clog.error("外部站点重新挂载失败",i))))},"onSettingsChanged");e.addEventListener("settings.changed",s),t.addCleanup((()=>e.removeEventListener("settings.changed",s))),await this.mount()}async mount(){isDetailPage&&this.getRuntimeService("settings").snapshot().enableLoadOtherSite!=="no"&&await this.loadOtherSite(null,null,{autoDetect:!1})}unmount(){this.mountGeneration++,this._mountGenerations.set(document,(this._mountGenerations.get(document)||0)+1),$("[data-jhs-other-site-box],[data-jhs-other-site-settings]").remove()}async loadOtherSite(e,t,s={}){let a=this.getRuntimeService("settings");if(a.snapshot().enableLoadOtherSite==="no")return;let r=s.root?.[0]||null,i=r?(this._mountGenerations.get(r)||0)+1:++this.mountGeneration;r&&this._mountGenerations.set(r,i);let n=d(()=>(r?i===this._mountGenerations.get(r):i===this.mountGeneration)&&(typeof s.isActive=="function"?s.isActive():!0)&&a.snapshot().enableLoadOtherSite!=="no","isActive"),l=s.root?$(s.root):$(document),c=s.target?$(s.target):$(this.getRuntimeService("host").locateDetailSlots().summary);if(!c.length||!n())return;l.find("#otherSiteBox,#settingsArea,[data-jhs-other-site-box],[data-jhs-other-site-settings]").remove(),e=T(e)||this.getPageInfo().carNum;let h=this.getEnabledSites(),u=(await this.getSiteConfigs()).map((v=>({...v,sourceCarNum:t})));if(!n())return;let p={root:l,target:c,configs:u,carNum:e,isActive:n},g=$(''),m=g.find(".jhs-site-list"),f=$('');if(u.forEach((v=>{if(v.condition&&v.condition(v.sourceCarNum)===!1)return;let b=$(' ').attr("data-jhs-site-id",v.id).toggleClass("jhs-is-hidden",!h.includes(v.id));b.find("span").text(v.id.replace("Btn","")),m.append(b)})),m.append('检测外部站点 ','设置 '),c.append(g,f),p.box=g,p.settings=f,!e)return g.find(".site-btn").removeAttr("href").attr({"aria-disabled":"true",title:"番号不可用"}),g.find('[data-jhs-role="detect-sites"]').prop("disabled",!0),this.renderSettingsArea(p),this.setupEventListeners(p),void clog.warn("跳过第三方站点解析:番号不可用");if(g.find('[data-jhs-site-id="javTrailersBtn"]').on("click",(v=>{v.preventDefault();let b=$(v.currentTarget).attr("href"),w=v.ctrlKey||v.metaKey?b:b+"?handle=1";utils.openPage(w,e,!1,v)})),await Te(u,4,(async v=>{v.condition&&v.condition(v.sourceCarNum)===!1||await this.prepareSiteLink(e,v,p)})),!!n())return this.renderSettingsArea(p),this.setupEventListeners(p),g.find('[data-jhs-role="detect-sites"]').off("click").on("click",(v=>{v.preventDefault(),this.detectOtherSites(e,p)})),s.autoDetect&&await this.detectOtherSites(e,p),g}async prepareSiteLink(e,t,s={root:$(document),configs:[],isActive:d(()=>!0,"isActive")}){let a=s.root.find(`[data-jhs-site-id="${t.id}"],#${t.id}`).first();if(!(e=T(e)))return a.removeAttr("href").attr({"aria-disabled":"true",title:"番号不可用"}),void this.setSiteState(a,"idle");if(t.providerId){let r=this.getRuntimeService("movie").searchUrl(t.providerId,{carNum:e});return void(r?(a.attr("href",r),a.attr("title","点击前往外部搜索页"),this.setSiteState(a,"idle")):(a.attr("title","外部站点地址不可用"),this.setSiteState(a,"domain-error")))}try{s.isActive?.()!==!1&&t.searchUrl&&(a.attr("href",t.searchUrl(e)),a.attr("title","点击前往外部搜索页;点击检测按钮后才自动检测"),this.setSiteState(a,"idle"))}catch{s.isActive?.()!==!1&&(a.attr("title","外部站点地址未配置或不可用"),this.setSiteState(a,"domain-error"))}}async detectOtherSites(e,t={root:$(document),configs:this.siteConfigs,isActive:d(()=>!0,"isActive")}){let s=t.root.find('[data-jhs-role="detect-sites"],#detectOtherSiteBtn').first(),a=s.text();return(e=T(e))?(s.text("检测中").prop("disabled",!0).addClass("is-checking"),await Te(t.configs,4,(async r=>{r.condition&&r.condition(r.sourceCarNum)===!1||await this.handleSite(e,r,t)})),t.isActive?.()!==!1&&s.text(a).prop("disabled",!1).removeClass("is-checking")):(s.prop("disabled",!0),void clog.warn("跳过第三方站点检测:番号不可用"))}setSiteState(e,t){e.removeClass("is-checking is-available is-unavailable is-domain-error"),t!=="idle"&&e.addClass(`is-${t}`)}async handleSite(e,t,s={root:$(document),configs:[],isActive:d(()=>!0,"isActive")}){let a=s.root.find(`[data-jhs-site-id="${t.id}"],#${t.id}`).first();if(a.removeAttr("href").find(".site-tag").remove(),this.setSiteState(a,"checking"),t.noHandle&&t.noHandle===!0){a.attr("href",this.getRuntimeService("movie").searchUrl(t.providerId,{carNum:e})||"");let r="jhs_other_site_dmm",i=this.getRuntimeService("storage").getLocal(r),n=null;try{let l=i?JSON.parse(i):{};n=l&&typeof l=="object"?l[e]:null}catch{n=null}n?(a.attr("href",n.url),n.type==="multiple"&&a.append('多结果 '),this.setSiteState(a,"available")):this.setSiteState(a,"idle")}else if(t.providerId)try{let r=await this.getRuntimeService("scope")(),i=await this.getRuntimeService("movie").resolve({carNum:e,providerId:t.providerId},{scope:r});if(s.isActive?.()===!1)return;let n=this.getRuntimeService("movie").searchUrl(t.providerId,{carNum:e});a.attr("href",i?.url||n||""),this.setSiteState(a,i?.url?"available":"unavailable"),i?.url||a.attr("title","未查询到, 点击前往搜索页")}catch{s.isActive?.()!==!1&&(a.attr("title","请求失败。"),this.setSiteState(a,"unavailable"),clog.warn(`检测第三方资源失败, ${t.id.replace("Btn","")}`))}else try{if(a.attr("href"))return void this.setSiteState(a,"idle");if(utils.isHidden(a))return;let r="jhs_other_site",i=this.getRuntimeService("storage"),n=i.getLocal(r),l=n?JSON.parse(n):{},c=e+"_"+t.id.replace("Btn",""),h=l[c],u=Date.now();if(h&&h.time&&u-h.time<864e5)return a.attr("href",h.url),h.type==="multiple"&&a.append('多结果 '),void this.setSiteState(a,"available");let p=await this.getRuntimeService("scope")(),g=await this.getRuntimeService("movie").searchExternalSite(t.id,e,{settings:await this.getSettingCache(),scope:p}),m=g.searchUrl;if(a.attr("href",m),s.isActive?.()===!1)return;let f=g.matches,v="",b=null;if(f.length===1){let w=f[0];a.attr("href",w),this.setSiteState(a,"available"),b={type:"single",url:w,time:u}}else f.length>1?(a.attr("href",m),v+='多结果 ',this.setSiteState(a,"available"),b={type:"multiple",url:m,time:u}):(a.attr("href",m),a.attr("title","未查询到, 点击前往搜索页"),this.setSiteState(a,"unavailable"));if(b){let w=i.getLocal(r),S=w?JSON.parse(w):{};S[c]=b,i.setLocal(r,JSON.stringify(S))}v&&a.append(v)}catch(r){let i=String(r),n=t.id.replace("Btn",""),l=r?.code;l==="CIRCUIT_OPEN"?(a.attr("title",i),this.setSiteState(a,"domain-error"),clog.warn(`检测第三方资源跳过, ${n} 已熔断`)):l==="CF_BLOCKED"?(a.attr("title","请求失败:Cloudflare 安全检查。"),this.setSiteState(a,"domain-error"),clog.warn(`检测第三方资源失败, ${n} 需Cloudflare安全检查`)):l==="INVALID_URL"?(a.attr("title","域名失效"),this.setSiteState(a,"domain-error"),clog.warn(`检测第三方资源失败, ${n} 域名或重定向无效`)):l==="NOT_FOUND"?(a.attr("title","未查询到, 点击前往搜索页"),this.setSiteState(a,"unavailable")):(clog.error(r),a.attr("title","请求失败。"),this.setSiteState(a,"unavailable"),clog.warn(`检测第三方资源失败, ${n}`))}}async getSettingCache(){return this.getRuntimeService("settings").snapshot()}async getMissAvUrl(){return(await this.getSiteConfigs()).find(e=>e.id==="missAvBtn")?.baseUrl||""}async getjableUrl(){return(await this.getSiteConfigs()).find(e=>e.id==="jableBtn")?.baseUrl||""}async getAvgleUrl(){return(await this.getSiteConfigs()).find(e=>e.id==="avgleBtn")?.baseUrl||""}async getJavTrailersUrl(){return(await this.getSiteConfigs()).find(e=>e.id==="javTrailersBtn")?.baseUrl||""}async getAv123Url(){return this.getRuntimeService("movie").providerOrigin("av123")||""}async getJavDbUrl(){return(await this.getSiteConfigs()).find(e=>e.id==="javDbBtn")?.baseUrl||""}async getJavBusUrl(){return(await this.getSiteConfigs()).find(e=>e.id==="javBusBtn")?.baseUrl||""}async getSupJavUrl(){return(await this.getSiteConfigs()).find(e=>e.id==="supJavBtn")?.baseUrl||""}getEnabledSites(){let e=this.siteConfigs.map((t=>t.id));try{let t=this.getRuntimeService("storage").getLocal("jhs_enabled_sites");if(!t)return e;let s=JSON.parse(t);return Array.isArray(s)?s.filter((a=>e.includes(a))):e}catch(t){return clog.warn("外部站点配置损坏,已回退默认值",t),e}}saveEnabledSites(e){this.getRuntimeService("storage").setLocal("jhs_enabled_sites",JSON.stringify(e))}renderSettingsArea(e={root:$(document),configs:this.siteConfigs}){let t=this.getEnabledSites(),s=e.root.find('[data-jhs-role="site-checkboxes"],#siteCheckboxes').first().empty();e.configs.forEach((a=>{let r=$(' ').attr("data-site-id",a.id).prop("checked",t.includes(a.id));s.append($(' ').append(r,$(" ").text(a.id.replace("Btn",""))))}))}setupEventListeners(e={root:$(document),configs:this.siteConfigs,carNum:null}){let t=e.root.find("[data-jhs-other-site-settings],#settingsArea").first();e.root.find('[data-jhs-role="site-settings"],#settingSiteBtn').off("click.jhsOtherSite").on("click.jhsOtherSite",(()=>{t.toggleClass("jhs-is-hidden")})),t.off("change.jhsOtherSite").on("change.jhsOtherSite",'input[type="checkbox"]',(async s=>{let a=$(s.currentTarget).attr("data-site-id");try{if(s.currentTarget.checked){e.root.find(`[data-jhs-site-id="${a}"],#${a}`).removeClass("jhs-is-hidden");let r=e.carNum||this.getPageInfo().carNum,i=e.configs.find((n=>n.id===a));i&&await this.prepareSiteLink(r,i,e)}else e.root.find(`[data-jhs-site-id="${a}"],#${a}`).addClass("jhs-is-hidden");this.saveEnabledSites(t.find('input[type="checkbox"]:checked').map(((r,i)=>$(i).attr("data-site-id"))).get())}catch(r){clog.warn(`外部站点 ${a||"unknown"} 状态更新失败`,r)}}))}};d(Vi,"OtherSitePlugin");var oa=Vi;var Hi=class Hi extends I{getName(){return"RelatedPlugin"}async handle(){if(!window.isDetailPage||!M)return;let e=new URL(window.location.href).pathname.split("/").filter(Boolean).pop();e&&await this.showRelated(this.getHostedSlot("related"),e)}getHostedSlot(e){let t=this.getRuntimeService("host").locateDetailSlots()[e];return t?$(t):$()}async showRelated(e,t,s={}){return new Bt({related:this.getRuntimeService("related"),settings:this.getRuntimeService("settings"),scope:d(()=>this.getRuntimeService("scope")(),"scope")}).show(e?.length?e:this.getHostedSlot("related"),t,s)}};d(Hi,"RelatedPlugin");var la=Hi;var qi=class qi extends I{getName(){return"ReviewPlugin"}async handle(){if(window.isDetailPage){if(M){let e=this.parseMovieId(window.location.href);await this.showReview(e,this.getHostedSlot("reviews"))}if(B){let e=this.getPageInfo().carNum;if(!e)return void clog.warn("跳过 JavBus 评论解析:番号不可用");let t=await this.getRuntimeService("scope")(),s=this.getRuntimeService("settings"),a=!1,r=d(async()=>{if(!(a||t?.disposed||s.snapshot().enableLoadReview==="no")){a=!0;try{let i=await this.getRuntimeService("movie").resolve({carNum:e},{scope:t});i?.movieId&&!t?.disposed&&s.snapshot().enableLoadReview!=="no"&&await this.showReview(i.movieId,this.getHostedSlot("reviews"))}finally{a=!1}}},"mount");t?.listen?.(s,"settings.changed",i=>{i.detail?.names?.includes("enableLoadReview")&&r().catch(n=>clog.error("加载评论失败",n))}),await r()}}}getHostedSlot(e){let t=this.getRuntimeService("host").locateDetailSlots()[e];return t?$(t):$()}async showReview(e,t,s={}){return new Ot({review:this.getRuntimeService("review"),settings:this.getRuntimeService("settings"),storage:this.getRuntimeService("storage"),scope:d(()=>this.getRuntimeService("scope")(),"scope")}).show(e,t?.length?t:this.getHostedSlot("reviews"),s)}};d(qi,"ReviewPlugin");var ca=qi;function Uh(o){return[...o.querySelectorAll(".tags .tag")].some(e=>/中字磁[链鏈]/u.test(e.textContent||""))}d(Uh,"hasChineseSubtitleMagnet");var ha=class ha extends I{getName(){return"TOP250Plugin"}async initCss(){return""}async handle(){if(je(window.location).kind!=="top250-ranking")return;let e=this.getRuntimeService("host"),t=e.locateListRoot?.(),s=e.getTop250FilterContainer?.();if(!t||!s||s.querySelector(".jhs-top250-subtitle"))return;let a=document.createElement("div");a.className="jhs-top250-subtitle",a.setAttribute("role","group"),a.setAttribute("aria-label","TOP250 已加载条目筛选");for(let[i,n]of[["all","已加载条目:全部"],["with","已加载条目:含中字磁链"],["without","已加载条目:无中字磁链"]]){let l=document.createElement("button");l.type="button",l.className="jhs-btn jhs-btn--secondary",l.dataset.jhsSubtitle=i,l.textContent=n,a.append(l)}e.mountTop250SubtitleControls(a);let r=new URLSearchParams(window.location.search).get("jhs_subtitle");this.applySubtitleFilter(["with","without"].includes(r||"")?r:"all",a),a.addEventListener("click",i=>{let l=i.target?.closest("button[data-jhs-subtitle]")?.getAttribute("data-jhs-subtitle");if(!["all","with","without"].includes(l||""))return;let c=new URL(window.location.href);l==="all"?c.searchParams.delete("jhs_subtitle"):c.searchParams.set("jhs_subtitle",l),window.history.replaceState(window.history.state,"",c.href),this.applySubtitleFilter(l,a)})}applySubtitleFilter(e,t){let s=this.getRuntimeService("host");for(let a of s.locateTop250SubtitleCards()){let r=Uh(a);a.classList.toggle("jhs-top250-subtitle-hidden",e==="with"?!r:e==="without"&&r)}t.querySelectorAll("button[data-jhs-subtitle]").forEach(a=>{let r=a.getAttribute("data-jhs-subtitle")===e;a.setAttribute("aria-pressed",String(r)),a.classList.toggle("active",r)}),s.syncTop250SubtitleLinks?.(e)}};d(ha,"Top250Plugin"),ct(ha,"legacyPluginId","TOP250Plugin");var da=ha;var Ji=class Ji extends I{getName(){return"FavoriteActressesPlugin"}getStartupMode(){return"idle"}bindImmediateEvents(){this.bindEvent()}async handle(){await this.highlightActress(),this.replaceActressAvatar()}async highlightActress(){if(!isDetailPage||await storageManager.getSetting("enableFavoriteActresses",R)!==R)return;let e=await storageManager.getFavoriteActressList();if(!e||e.length===0)return;let t=new Set;e.forEach((s=>{s.starId&&t.add(String(s.starId).trim())})),t.size!==0&&$(".female").prev().each(((s,a)=>{let r=$(a),i=r.attr("href"),n=null;if(i){let c=(i.endsWith("/")?i.slice(0,-1):i).split("/"),h=c[c.length-1];h&&(n=h.trim())}let l=!1;n&&(l=t.has(n)),l&&(r.addClass("highlighted"),r.attr("title","高亮已收藏演员, 可在设置-基础配置中关闭"))}))}async removeActorFromStorage(e){await storageManager.removeFavoriteActress(e)&&(clog.log("移除演员成功"),document.dispatchEvent(new CustomEvent("actress-state-changed",{detail:{starId:String(e)}})))}bindEvent(){let e=/\/actors\/(\w+)\/(collect|uncollect)/;$(document).on("confirm:complete",'a[href*="/actors/"][href*="/uncollect"]',(async t=>{let[s]=t.detail;if(!s)return;let a=$(t.currentTarget).attr("href").match(e),r=a?a[1]:null;r&&await this.removeActorFromStorage(r)})),$("#button-collect-actor").click((async t=>{let s=$("#button-collect-actor").attr("href").match(e),a=s?s[1]:null,r=[],i=$(".actor-section-name");i.length&&i.text().trim().split(",").forEach((u=>{r.push(u.trim())}));let n=$(".section-meta:not(:contains('影片'))");if(n.length&&n.text().trim().split(",").forEach((u=>{r.push(u.trim())})),!r.length)return void clog.error("获取演员名称失败");let l=r[0];if(!a)return void clog.error("无法获取演员ID进行收藏操作。");let c=($(".avatar").first().css("background-image")||"").replace(/^url\(["']?|["']?\)$/g,""),h={starId:a,name:l,allName:r,avatar:c};await storageManager.addFavoriteActressList([h])===1?(clog.log(`收藏演员成功: ${l} (ID: ${a})`),document.dispatchEvent(new CustomEvent("actress-state-changed",{detail:{starId:String(a)}}))):clog.log(`收藏演员失败: ${l} (ID: ${a})`)})),$("#button-uncollect-actor").click((async t=>{let s=$("#button-uncollect-actor").attr("href").match(e),a=s?s[1]:null;a?await this.removeActorFromStorage(a):clog.error("无法获取演员ID进行取消收藏操作。")}))}async replaceActressAvatar(){let e=this.getActressId();if(!e)return;let t=(await storageManager.getFavoriteActressList()).find((s=>s.starId===e));if(t&&t.avatar){let s=`url('${t.avatar}')`,a=$(".avatar").first();if(a.length===0&&($(".section-columns").prepend(''),a=$(".avatar").first()),a.length===0)return;a.css("background-image").trim().toLowerCase()!==s.trim().toLowerCase()&&(a.css("background-image",s),a.css("background-size","cover"),a.css("background-position","top center"),a.css("background-repeat","no-repeat"))}}};d(Ji,"FavoriteActressesPlugin");var ua=Ji;var Wi=class Wi extends I{getName(){return"BusImgPlugin"}handle(){}async getVisibleImageItems(e,t){let s=[],a=document.querySelectorAll(e);for(let r of a)if(!utils.isHidden(r)){let i=r.querySelector(t);if(!(i instanceof HTMLImageElement))continue;i.style.removeProperty("height");let n=i.offsetHeight;n>0&&s.push({element:r,imgElement:i,height:n})}return s}async logImageHeightsByRow(e={}){let t=e.vertical??e.enableVerticalModel??await storageManager.getSetting("enableVerticalModel",ne),s=e.columns??e.containerColumns??await storageManager.getSetting("containerColumns",5);if(t===R)return;let a=this.getSelector().itemSelector,r=Number(s)||5,i=await this.getVisibleImageItems(a,"img");if(i.length===0)return;let n=[];for(let l=0;l{let h=l.map((m=>m.height));if(h.length<2)return;let u=Math.min(...h),p=Math.max(...h),g=0;p-u>50&&(g=u,l.forEach((m=>{if(m.height!==g){let f=`${g}px`;m.imgElement.style.setProperty("height",f,"important")}})))}))}};d(Wi,"BusImgPlugin");var pa=Wi;var Ut=d((o,e)=>{if(!o||o.length===0)return null;let t=new Set(o);if(e&&t.has(e))return e;let s=rt.map((a=>a.quality)).reverse();for(let a of s)if(t.has(a))return a;return o[0]||null},"Z"),Ki="jhs_dmm_video",zh=30*864e5,Cc=500;function Gi(o){if(!o)return{};try{let e=JSON.parse(o);return e&&typeof e=="object"&&!Array.isArray(e)?e:{}}catch{return{}}}d(Gi,"parseJsonMap");function Qi(o){let e=Date.now();for(let s of Object.keys(o)){let a=o[s];(!a||a.time&&e-a.time>zh)&&delete o[s]}let t=Object.keys(o);if(t.length>Cc){t.sort(((s,a)=>(o[s].time||0)-(o[a].time||0)));for(let s of t.slice(0,t.length-Cc))delete o[s]}return o}d(Qi,"pruneDmmCache");function Pe(o){return o?.enablePreviewVideo!=="no"}d(Pe,"isPreviewEnabled");function ds(o){return o?.enableLoadPreviewVideo!=="no"}d(ds,"isDmmEnabled");function _c(o){return Pe(o)}d(_c,"canUsePreview");function zt(o){return Pe(o)&&ds(o)}d(zt,"canUseDmmPreview");function ga(o){return zt(o)}d(ga,"canUseCardPreview");var Xi=class Xi{constructor(e,t,s,a){this.carNum=e||"",this.storage=t,this.movie=s,this.scope=a,this.lastError=null}_checkCache(){let e=Qi(Gi(this.storage.getLocal(Ki)));return e[this.carNum]?(clog.debug("缓存中存在预览视频信息",e[this.carNum]),e[this.carNum]):null}_updateCache(e){let t=Qi(Gi(this.storage.getLocal(Ki)));t[this.carNum]={...e,time:Date.now()},clog.debug("成功解析出预览视频并已缓存:",e),this.storage.setLocal(Ki,JSON.stringify(t))}async _fetchRemote(){let e=await this.movie.preview("dmm",{carNum:this.carNum},{scope:this.scope}),t=$("#fanzaBtn");if(!e.sources)return clog.warn("所有关键词尝试均未找到匹配的Content ID, 解析Dmm视频失败"),t.attr("href",e.searchUrl).attr("title","未查询到, 点击前往搜索页").css("backgroundColor","var(--jhs-status-filter)"),null;t.attr("href",e.pageUrl).css("backgroundColor","var(--jhs-status-down)"),e.matchType==="multiple"&&t.append('多结果 ');let s="jhs_other_site_dmm",a=Qi(Gi(this.storage.getLocal(s)));return a[this.carNum]={type:e.matchType,url:e.pageUrl,time:Date.now()},this.storage.setLocal(s,JSON.stringify(a)),e.sources}async fetchVideo(){let e=T(this.carNum);if(!e)return clog.warn("跳过 DMM 解析:番号不可用"),null;this.carNum=e;let t=this._checkCache();if(t)return t;try{let s=this.carNum.toLowerCase();if(s.startsWith("heyzo")||/^(n\d+|\d+(-\d+)*)$/.test(s)||/^n\d+$/.test(s))return clog.debug("无码番号类型,取消 DMM 解析"),null;if(this.carNum.includes("VR-"))return clog.debug("VR 类型,取消 DMM 解析"),null;let a=await this._fetchRemote();return a?(this._updateCache(a),a):null}catch(s){let a=s;this.lastError=s instanceof we?s:new we("dmm",a?.code||"PARSE_ERROR",a?.message||String(s),{cause:s,retryable:a?.retryable===!0}),clog.error("DMM API 搜索失败:",this.lastError);let r=$("#fanzaBtn");return r.attr("href",this.movie.searchUrl("dmm",{carNum:this.carNum})),r.attr("title","未查询到, 点击前往搜索页"),r.css("backgroundColor","var(--jhs-status-filter)"),null}}};d(Xi,"DmmPreviewParser");var Yi=Xi;async function Zi(o,e,t,s){let a=new Yi(o,e,t,s);return{sources:await a.fetchVideo(),error:a.lastError}}d(Zi,"fetchDmmPreview");async function ma(o,e,t,s,a){return ds(a)?Zi(o,e,t,s):{sources:null,error:null}}d(ma,"fetchDmmPreviewIfEnabled");var en=class en extends I{constructor(){super(...arguments),this._busPreviewGeneration=0}getName(){return"BusPreviewVideoPlugin"}async initCss(){return`
+ `}async handle(){let e=this.getRuntimeService("settings"),t=await this.getRuntimeService("scope")(),s=d(a=>{a.detail?.names?.includes("enableLoadOtherSite")&&(e.snapshot().enableLoadOtherSite==="no"?this.unmount():this.mount().catch((i=>clog.error("外部站点重新挂载失败",i))))},"onSettingsChanged");e.addEventListener("settings.changed",s),t.addCleanup((()=>e.removeEventListener("settings.changed",s))),await this.mount()}async mount(){isDetailPage&&this.getRuntimeService("settings").snapshot().enableLoadOtherSite!=="no"&&await this.loadOtherSite(null,null,{autoDetect:!1})}unmount(){this.mountGeneration++,this._mountGenerations.set(document,(this._mountGenerations.get(document)||0)+1),$("[data-jhs-other-site-box],[data-jhs-other-site-settings]").remove()}async loadOtherSite(e,t,s={}){let a=this.getRuntimeService("settings");if(a.snapshot().enableLoadOtherSite==="no")return;let r=s.root?.[0]||null,i=r?(this._mountGenerations.get(r)||0)+1:++this.mountGeneration;r&&this._mountGenerations.set(r,i);let n=d(()=>(r?i===this._mountGenerations.get(r):i===this.mountGeneration)&&(typeof s.isActive=="function"?s.isActive():!0)&&a.snapshot().enableLoadOtherSite!=="no","isActive"),l=s.root?$(s.root):$(document),c=s.target?$(s.target):$(this.getRuntimeService("host").locateDetailSlots().summary);if(!c.length||!n())return;l.find("#otherSiteBox,#settingsArea,[data-jhs-other-site-box],[data-jhs-other-site-settings]").remove(),e=C(e)||this.getPageInfo().carNum;let h=this.getEnabledSites(),u=(await this.getSiteConfigs()).map((v=>({...v,sourceCarNum:t})));if(!n())return;let p={root:l,target:c,configs:u,carNum:e,isActive:n},g=$(''),m=g.find(".jhs-site-list"),f=$('');if(u.forEach((v=>{if(v.condition&&v.condition(v.sourceCarNum)===!1)return;let b=$(' ').attr("data-jhs-site-id",v.id).toggleClass("jhs-is-hidden",!h.includes(v.id));b.find("span").text(v.id.replace("Btn","")),m.append(b)})),m.append('检测外部站点 ','设置 '),c.append(g,f),p.box=g,p.settings=f,!e)return g.find(".site-btn").removeAttr("href").attr({"aria-disabled":"true",title:"番号不可用"}),g.find('[data-jhs-role="detect-sites"]').prop("disabled",!0),this.renderSettingsArea(p),this.setupEventListeners(p),void clog.warn("跳过第三方站点解析:番号不可用");if(g.find('[data-jhs-site-id="javTrailersBtn"]').on("click",(v=>{v.preventDefault();let b=$(v.currentTarget).attr("href"),w=v.ctrlKey||v.metaKey?b:b+"?handle=1";utils.openPage(w,e,!1,v)})),await Ae(u,4,(async v=>{v.condition&&v.condition(v.sourceCarNum)===!1||await this.prepareSiteLink(e,v,p)})),!!n())return this.renderSettingsArea(p),this.setupEventListeners(p),g.find('[data-jhs-role="detect-sites"]').off("click").on("click",(v=>{v.preventDefault(),this.detectOtherSites(e,p)})),s.autoDetect&&await this.detectOtherSites(e,p),g}async prepareSiteLink(e,t,s={root:$(document),configs:[],isActive:d(()=>!0,"isActive")}){let a=s.root.find(`[data-jhs-site-id="${t.id}"],#${t.id}`).first();if(!(e=C(e)))return a.removeAttr("href").attr({"aria-disabled":"true",title:"番号不可用"}),void this.setSiteState(a,"idle");if(t.providerId){let r=this.getRuntimeService("movie").searchUrl(t.providerId,{carNum:e});return void(r?(a.attr("href",r),a.attr("title","点击前往外部搜索页"),this.setSiteState(a,"idle")):(a.attr("title","外部站点地址不可用"),this.setSiteState(a,"domain-error")))}try{s.isActive?.()!==!1&&t.searchUrl&&(a.attr("href",t.searchUrl(e)),a.attr("title","点击前往外部搜索页;点击检测按钮后才自动检测"),this.setSiteState(a,"idle"))}catch{s.isActive?.()!==!1&&(a.attr("title","外部站点地址未配置或不可用"),this.setSiteState(a,"domain-error"))}}async detectOtherSites(e,t={root:$(document),configs:this.siteConfigs,isActive:d(()=>!0,"isActive")}){let s=t.root.find('[data-jhs-role="detect-sites"],#detectOtherSiteBtn').first(),a=s.text();return(e=C(e))?(s.text("检测中").prop("disabled",!0).addClass("is-checking"),await Ae(t.configs,4,(async r=>{r.condition&&r.condition(r.sourceCarNum)===!1||await this.handleSite(e,r,t)})),t.isActive?.()!==!1&&s.text(a).prop("disabled",!1).removeClass("is-checking")):(s.prop("disabled",!0),void clog.warn("跳过第三方站点检测:番号不可用"))}setSiteState(e,t){e.removeClass("is-checking is-available is-unavailable is-domain-error"),t!=="idle"&&e.addClass(`is-${t}`)}async handleSite(e,t,s={root:$(document),configs:[],isActive:d(()=>!0,"isActive")}){let a=s.root.find(`[data-jhs-site-id="${t.id}"],#${t.id}`).first();if(a.removeAttr("href").find(".site-tag").remove(),this.setSiteState(a,"checking"),t.noHandle&&t.noHandle===!0){a.attr("href",this.getRuntimeService("movie").searchUrl(t.providerId,{carNum:e})||"");let r="jhs_other_site_dmm",i=this.getRuntimeService("storage").getLocal(r),n=null;try{let l=i?JSON.parse(i):{};n=l&&typeof l=="object"?l[e]:null}catch{n=null}n?(a.attr("href",n.url),n.type==="multiple"&&a.append('多结果 '),this.setSiteState(a,"available")):this.setSiteState(a,"idle")}else if(t.providerId)try{let r=await this.getRuntimeService("scope")(),i=await this.getRuntimeService("movie").resolve({carNum:e,providerId:t.providerId},{scope:r});if(s.isActive?.()===!1)return;let n=this.getRuntimeService("movie").searchUrl(t.providerId,{carNum:e});a.attr("href",i?.url||n||""),this.setSiteState(a,i?.url?"available":"unavailable"),i?.url||a.attr("title","未查询到, 点击前往搜索页")}catch{s.isActive?.()!==!1&&(a.attr("title","请求失败。"),this.setSiteState(a,"unavailable"),clog.warn(`检测第三方资源失败, ${t.id.replace("Btn","")}`))}else try{if(a.attr("href"))return void this.setSiteState(a,"idle");if(utils.isHidden(a))return;let r="jhs_other_site",i=this.getRuntimeService("storage"),n=i.getLocal(r),l=n?JSON.parse(n):{},c=e+"_"+t.id.replace("Btn",""),h=l[c],u=Date.now();if(h&&h.time&&u-h.time<864e5)return a.attr("href",h.url),h.type==="multiple"&&a.append('多结果 '),void this.setSiteState(a,"available");let p=await this.getRuntimeService("scope")(),g=await this.getRuntimeService("movie").searchExternalSite(t.id,e,{settings:await this.getSettingCache(),scope:p}),m=g.searchUrl;if(a.attr("href",m),s.isActive?.()===!1)return;let f=g.matches,v="",b=null;if(f.length===1){let w=f[0];a.attr("href",w),this.setSiteState(a,"available"),b={type:"single",url:w,time:u}}else f.length>1?(a.attr("href",m),v+='多结果 ',this.setSiteState(a,"available"),b={type:"multiple",url:m,time:u}):(a.attr("href",m),a.attr("title","未查询到, 点击前往搜索页"),this.setSiteState(a,"unavailable"));if(b){let w=i.getLocal(r),S=w?JSON.parse(w):{};S[c]=b,i.setLocal(r,JSON.stringify(S))}v&&a.append(v)}catch(r){let i=String(r),n=t.id.replace("Btn",""),l=r?.code;l==="CIRCUIT_OPEN"?(a.attr("title",i),this.setSiteState(a,"domain-error"),clog.warn(`检测第三方资源跳过, ${n} 已熔断`)):l==="CF_BLOCKED"?(a.attr("title","请求失败:Cloudflare 安全检查。"),this.setSiteState(a,"domain-error"),clog.warn(`检测第三方资源失败, ${n} 需Cloudflare安全检查`)):l==="INVALID_URL"?(a.attr("title","域名失效"),this.setSiteState(a,"domain-error"),clog.warn(`检测第三方资源失败, ${n} 域名或重定向无效`)):l==="NOT_FOUND"?(a.attr("title","未查询到, 点击前往搜索页"),this.setSiteState(a,"unavailable")):(clog.error(r),a.attr("title","请求失败。"),this.setSiteState(a,"unavailable"),clog.warn(`检测第三方资源失败, ${n}`))}}async getSettingCache(){return this.getRuntimeService("settings").snapshot()}async getMissAvUrl(){return(await this.getSiteConfigs()).find(e=>e.id==="missAvBtn")?.baseUrl||""}async getjableUrl(){return(await this.getSiteConfigs()).find(e=>e.id==="jableBtn")?.baseUrl||""}async getAvgleUrl(){return(await this.getSiteConfigs()).find(e=>e.id==="avgleBtn")?.baseUrl||""}async getJavTrailersUrl(){return(await this.getSiteConfigs()).find(e=>e.id==="javTrailersBtn")?.baseUrl||""}async getAv123Url(){return this.getRuntimeService("movie").providerOrigin("av123")||""}async getJavDbUrl(){return(await this.getSiteConfigs()).find(e=>e.id==="javDbBtn")?.baseUrl||""}async getJavBusUrl(){return(await this.getSiteConfigs()).find(e=>e.id==="javBusBtn")?.baseUrl||""}async getSupJavUrl(){return(await this.getSiteConfigs()).find(e=>e.id==="supJavBtn")?.baseUrl||""}getEnabledSites(){let e=this.siteConfigs.map((t=>t.id));try{let t=this.getRuntimeService("storage").getLocal("jhs_enabled_sites");if(!t)return e;let s=JSON.parse(t);return Array.isArray(s)?s.filter((a=>e.includes(a))):e}catch(t){return clog.warn("外部站点配置损坏,已回退默认值",t),e}}saveEnabledSites(e){this.getRuntimeService("storage").setLocal("jhs_enabled_sites",JSON.stringify(e))}renderSettingsArea(e={root:$(document),configs:this.siteConfigs}){let t=this.getEnabledSites(),s=e.root.find('[data-jhs-role="site-checkboxes"],#siteCheckboxes').first().empty();e.configs.forEach((a=>{let r=$(' ').attr("data-site-id",a.id).prop("checked",t.includes(a.id));s.append($(' ').append(r,$(" ").text(a.id.replace("Btn",""))))}))}setupEventListeners(e={root:$(document),configs:this.siteConfigs,carNum:null}){let t=e.root.find("[data-jhs-other-site-settings],#settingsArea").first();e.root.find('[data-jhs-role="site-settings"],#settingSiteBtn').off("click.jhsOtherSite").on("click.jhsOtherSite",(()=>{t.toggleClass("jhs-is-hidden")})),t.off("change.jhsOtherSite").on("change.jhsOtherSite",'input[type="checkbox"]',(async s=>{let a=$(s.currentTarget).attr("data-site-id");try{if(s.currentTarget.checked){e.root.find(`[data-jhs-site-id="${a}"],#${a}`).removeClass("jhs-is-hidden");let r=e.carNum||this.getPageInfo().carNum,i=e.configs.find((n=>n.id===a));i&&await this.prepareSiteLink(r,i,e)}else e.root.find(`[data-jhs-site-id="${a}"],#${a}`).addClass("jhs-is-hidden");this.saveEnabledSites(t.find('input[type="checkbox"]:checked').map(((r,i)=>$(i).attr("data-site-id"))).get())}catch(r){clog.warn(`外部站点 ${a||"unknown"} 状态更新失败`,r)}}))}};d(qi,"OtherSitePlugin");var la=qi;var Hi=class Hi extends I{getName(){return"RelatedPlugin"}async handle(){if(!window.isDetailPage||!M)return;let e=new URL(window.location.href).pathname.split("/").filter(Boolean).pop();e&&await this.showRelated(this.getHostedSlot("related"),e)}getHostedSlot(e){let t=this.getRuntimeService("host").locateDetailSlots()[e];return t?$(t):$()}async showRelated(e,t,s={}){return new Ot({related:this.getRuntimeService("related"),settings:this.getRuntimeService("settings"),scope:d(()=>this.getRuntimeService("scope")(),"scope")}).show(e?.length?e:this.getHostedSlot("related"),t,s)}};d(Hi,"RelatedPlugin");var ca=Hi;var Wi=class Wi extends I{getName(){return"ReviewPlugin"}async handle(){if(window.isDetailPage){if(M){let e=this.parseMovieId(window.location.href);await this.showReview(e,this.getHostedSlot("reviews"))}if(B){let e=this.getPageInfo().carNum;if(!e)return void clog.warn("跳过 JavBus 评论解析:番号不可用");let t=await this.getRuntimeService("scope")(),s=this.getRuntimeService("settings"),a=!1,r=d(async()=>{if(!(a||t?.disposed||s.snapshot().enableLoadReview==="no")){a=!0;try{let i=await this.getRuntimeService("movie").resolve({carNum:e},{scope:t});i?.movieId&&!t?.disposed&&s.snapshot().enableLoadReview!=="no"&&await this.showReview(i.movieId,this.getHostedSlot("reviews"))}finally{a=!1}}},"mount");t?.listen?.(s,"settings.changed",i=>{i.detail?.names?.includes("enableLoadReview")&&r().catch(n=>clog.error("加载评论失败",n))}),await r()}}}getHostedSlot(e){let t=this.getRuntimeService("host").locateDetailSlots()[e];return t?$(t):$()}async showReview(e,t,s={}){return new Ut({review:this.getRuntimeService("review"),settings:this.getRuntimeService("settings"),storage:this.getRuntimeService("storage"),scope:d(()=>this.getRuntimeService("scope")(),"scope")}).show(e,t?.length?t:this.getHostedSlot("reviews"),s)}};d(Wi,"ReviewPlugin");var da=Wi;function zh(o){return[...o.querySelectorAll(".tags .tag")].some(e=>/中字磁[链鏈]/u.test(e.textContent||""))}d(zh,"hasChineseSubtitleMagnet");var ua=class ua extends I{getName(){return"TOP250Plugin"}async initCss(){return""}async handle(){if(je(window.location).kind!=="top250-ranking")return;let e=this.getRuntimeService("host"),t=e.locateListRoot?.(),s=e.getTop250FilterContainer?.();if(!t||!s||s.querySelector(".jhs-top250-subtitle"))return;let a=document.createElement("div");a.className="jhs-top250-subtitle",a.setAttribute("role","group"),a.setAttribute("aria-label","TOP250 已加载条目筛选");for(let[i,n]of[["all","已加载条目:全部"],["with","已加载条目:含中字磁链"],["without","已加载条目:无中字磁链"]]){let l=document.createElement("button");l.type="button",l.className="jhs-btn jhs-btn--secondary",l.dataset.jhsSubtitle=i,l.textContent=n,a.append(l)}e.mountTop250SubtitleControls(a);let r=new URLSearchParams(window.location.search).get("jhs_subtitle");this.applySubtitleFilter(["with","without"].includes(r||"")?r:"all",a),a.addEventListener("click",i=>{let l=i.target?.closest("button[data-jhs-subtitle]")?.getAttribute("data-jhs-subtitle");if(!["all","with","without"].includes(l||""))return;let c=new URL(window.location.href);l==="all"?c.searchParams.delete("jhs_subtitle"):c.searchParams.set("jhs_subtitle",l),window.history.replaceState(window.history.state,"",c.href),this.applySubtitleFilter(l,a)})}applySubtitleFilter(e,t){let s=this.getRuntimeService("host");for(let a of s.locateTop250SubtitleCards()){let r=zh(a);a.classList.toggle("jhs-top250-subtitle-hidden",e==="with"?!r:e==="without"&&r)}t.querySelectorAll("button[data-jhs-subtitle]").forEach(a=>{let r=a.getAttribute("data-jhs-subtitle")===e;a.setAttribute("aria-pressed",String(r)),a.classList.toggle("active",r)}),s.syncTop250SubtitleLinks?.(e)}};d(ua,"Top250Plugin"),dt(ua,"legacyPluginId","TOP250Plugin");var ha=ua;var Ji=class Ji extends I{getName(){return"FavoriteActressesPlugin"}getStartupMode(){return"idle"}bindImmediateEvents(){this.bindEvent()}async handle(){await this.highlightActress(),this.replaceActressAvatar()}async highlightActress(){if(!isDetailPage||await storageManager.getSetting("enableFavoriteActresses",E)!==E)return;let e=await storageManager.getFavoriteActressList();if(!e||e.length===0)return;let t=new Set;e.forEach((s=>{s.starId&&t.add(String(s.starId).trim())})),t.size!==0&&$(".female").prev().each(((s,a)=>{let r=$(a),i=r.attr("href"),n=null;if(i){let c=(i.endsWith("/")?i.slice(0,-1):i).split("/"),h=c[c.length-1];h&&(n=h.trim())}let l=!1;n&&(l=t.has(n)),l&&(r.addClass("highlighted"),r.attr("title","高亮已收藏演员, 可在设置-基础配置中关闭"))}))}async removeActorFromStorage(e){await storageManager.removeFavoriteActress(e)&&(clog.log("移除演员成功"),document.dispatchEvent(new CustomEvent("actress-state-changed",{detail:{starId:String(e)}})))}bindEvent(){let e=/\/actors\/(\w+)\/(collect|uncollect)/;$(document).on("confirm:complete",'a[href*="/actors/"][href*="/uncollect"]',(async t=>{let[s]=t.detail;if(!s)return;let a=$(t.currentTarget).attr("href").match(e),r=a?a[1]:null;r&&await this.removeActorFromStorage(r)})),$("#button-collect-actor").click((async t=>{let s=$("#button-collect-actor").attr("href").match(e),a=s?s[1]:null,r=[],i=$(".actor-section-name");i.length&&i.text().trim().split(",").forEach((u=>{r.push(u.trim())}));let n=$(".section-meta:not(:contains('影片'))");if(n.length&&n.text().trim().split(",").forEach((u=>{r.push(u.trim())})),!r.length)return void clog.error("获取演员名称失败");let l=r[0];if(!a)return void clog.error("无法获取演员ID进行收藏操作。");let c=($(".avatar").first().css("background-image")||"").replace(/^url\(["']?|["']?\)$/g,""),h={starId:a,name:l,allName:r,avatar:c};await storageManager.addFavoriteActressList([h])===1?(clog.log(`收藏演员成功: ${l} (ID: ${a})`),document.dispatchEvent(new CustomEvent("actress-state-changed",{detail:{starId:String(a)}}))):clog.log(`收藏演员失败: ${l} (ID: ${a})`)})),$("#button-uncollect-actor").click((async t=>{let s=$("#button-uncollect-actor").attr("href").match(e),a=s?s[1]:null;a?await this.removeActorFromStorage(a):clog.error("无法获取演员ID进行取消收藏操作。")}))}async replaceActressAvatar(){let e=this.getActressId();if(!e)return;let t=(await storageManager.getFavoriteActressList()).find((s=>s.starId===e));if(t&&t.avatar){let s=`url('${t.avatar}')`,a=$(".avatar").first();if(a.length===0&&($(".section-columns").prepend(''),a=$(".avatar").first()),a.length===0)return;a.css("background-image").trim().toLowerCase()!==s.trim().toLowerCase()&&(a.css("background-image",s),a.css("background-size","cover"),a.css("background-position","top center"),a.css("background-repeat","no-repeat"))}}};d(Ji,"FavoriteActressesPlugin");var pa=Ji;var Ki=class Ki extends I{getName(){return"BusImgPlugin"}handle(){}async getVisibleImageItems(e,t){let s=[],a=document.querySelectorAll(e);for(let r of a)if(!utils.isHidden(r)){let i=r.querySelector(t);if(!(i instanceof HTMLImageElement))continue;i.style.removeProperty("height");let n=i.offsetHeight;n>0&&s.push({element:r,imgElement:i,height:n})}return s}async logImageHeightsByRow(e={}){let t=e.vertical??e.enableVerticalModel??await storageManager.getSetting("enableVerticalModel",ne),s=e.columns??e.containerColumns??await storageManager.getSetting("containerColumns",5);if(t===E)return;let a=this.getSelector().itemSelector,r=Number(s)||5,i=await this.getVisibleImageItems(a,"img");if(i.length===0)return;let n=[];for(let l=0;l{let h=l.map((m=>m.height));if(h.length<2)return;let u=Math.min(...h),p=Math.max(...h),g=0;p-u>50&&(g=u,l.forEach((m=>{if(m.height!==g){let f=`${g}px`;m.imgElement.style.setProperty("height",f,"important")}})))}))}};d(Ki,"BusImgPlugin");var ga=Ki;var zt=d((o,e)=>{if(!o||o.length===0)return null;let t=new Set(o);if(e&&t.has(e))return e;let s=rt.map((a=>a.quality)).reverse();for(let a of s)if(t.has(a))return a;return o[0]||null},"Z"),Gi="jhs_dmm_video",Fh=30*864e5,_c=500;function Qi(o){if(!o)return{};try{let e=JSON.parse(o);return e&&typeof e=="object"&&!Array.isArray(e)?e:{}}catch{return{}}}d(Qi,"parseJsonMap");function Yi(o){let e=Date.now();for(let s of Object.keys(o)){let a=o[s];(!a||a.time&&e-a.time>Fh)&&delete o[s]}let t=Object.keys(o);if(t.length>_c){t.sort(((s,a)=>(o[s].time||0)-(o[a].time||0)));for(let s of t.slice(0,t.length-_c))delete o[s]}return o}d(Yi,"pruneDmmCache");function Re(o){return o?.enablePreviewVideo!=="no"}d(Re,"isPreviewEnabled");function ds(o){return o?.enableLoadPreviewVideo!=="no"}d(ds,"isDmmEnabled");function $c(o){return Re(o)}d($c,"canUsePreview");function Ft(o){return Re(o)&&ds(o)}d(Ft,"canUseDmmPreview");function ma(o){return Ft(o)}d(ma,"canUseCardPreview");var en=class en{constructor(e,t,s,a){this.carNum=e||"",this.storage=t,this.movie=s,this.scope=a,this.lastError=null}_checkCache(){let e=Yi(Qi(this.storage.getLocal(Gi)));return e[this.carNum]?(clog.debug("缓存中存在预览视频信息",e[this.carNum]),e[this.carNum]):null}_updateCache(e){let t=Yi(Qi(this.storage.getLocal(Gi)));t[this.carNum]={...e,time:Date.now()},clog.debug("成功解析出预览视频并已缓存:",e),this.storage.setLocal(Gi,JSON.stringify(t))}async _fetchRemote(){let e=await this.movie.preview("dmm",{carNum:this.carNum},{scope:this.scope}),t=$("#fanzaBtn");if(!e.sources)return clog.warn("所有关键词尝试均未找到匹配的Content ID, 解析Dmm视频失败"),t.attr("href",e.searchUrl).attr("title","未查询到, 点击前往搜索页").css("backgroundColor","var(--jhs-status-filter)"),null;t.attr("href",e.pageUrl).css("backgroundColor","var(--jhs-status-down)"),e.matchType==="multiple"&&t.append('多结果 ');let s="jhs_other_site_dmm",a=Yi(Qi(this.storage.getLocal(s)));return a[this.carNum]={type:e.matchType,url:e.pageUrl,time:Date.now()},this.storage.setLocal(s,JSON.stringify(a)),e.sources}async fetchVideo(){let e=C(this.carNum);if(!e)return clog.warn("跳过 DMM 解析:番号不可用"),null;this.carNum=e;let t=this._checkCache();if(t)return t;try{let s=this.carNum.toLowerCase();if(s.startsWith("heyzo")||/^(n\d+|\d+(-\d+)*)$/.test(s)||/^n\d+$/.test(s))return clog.debug("无码番号类型,取消 DMM 解析"),null;if(this.carNum.includes("VR-"))return clog.debug("VR 类型,取消 DMM 解析"),null;let a=await this._fetchRemote();return a?(this._updateCache(a),a):null}catch(s){let a=s;this.lastError=s instanceof we?s:new we("dmm",a?.code||"PARSE_ERROR",a?.message||String(s),{cause:s,retryable:a?.retryable===!0}),clog.error("DMM API 搜索失败:",this.lastError);let r=$("#fanzaBtn");return r.attr("href",this.movie.searchUrl("dmm",{carNum:this.carNum})),r.attr("title","未查询到, 点击前往搜索页"),r.css("backgroundColor","var(--jhs-status-filter)"),null}}};d(en,"DmmPreviewParser");var Zi=en;async function Xi(o,e,t,s){let a=new Zi(o,e,t,s);return{sources:await a.fetchVideo(),error:a.lastError}}d(Xi,"fetchDmmPreview");async function fa(o,e,t,s,a){return ds(a)?Xi(o,e,t,s):{sources:null,error:null}}d(fa,"fetchDmmPreviewIfEnabled");var tn=class tn extends I{constructor(){super(...arguments),this._busPreviewGeneration=0}getName(){return"BusPreviewVideoPlugin"}async initCss(){return`
.bus-preview-modal { position:fixed; inset:0; z-index:var(--jhs-z-modal); display:flex; align-items:center; justify-content:center; visibility:hidden; opacity:0; background:rgba(0,0,0,.95); transition:opacity var(--jhs-motion-base) var(--jhs-ease); }
.bus-preview-modal.is-open { visibility:visible; opacity:1; }
.bus-preview-modal-content { position:relative; display:flex; max-width:95%; max-height:95%; flex-direction:column; align-items:center; gap:var(--jhs-space-3); }
@@ -3316,7 +3311,7 @@ ${i}\r
- `);let t=$("#bus-preview-modal");t.on("click",(s=>{s.target instanceof Element&&s.target.id==="bus-preview-modal"&&this.closeVideoModal()})),e.listen(document,"keydown",(s=>{s instanceof KeyboardEvent&&s.key==="Escape"&&t.hasClass("is-open")&&this.closeVideoModal()})),e.addCleanup((()=>{t.off(),t.remove()}))}}closeVideoModal(){let e=$("#preview-video");e.length>0&&e[0].pause(),$("#bus-preview-modal").removeClass("is-open")}unmountPreview(){this._busPreviewMounted=!1,this.closeVideoModal(),$("#bus-preview-modal").remove(),$(".preview-video-container").off("click.jhsBusPreview").remove()}async handle(){if(!isDetailPage)return;let e=this.getRuntimeService("settings");if(this._busScope||(this._busScope=await this.getRuntimeService("scope")()),!this._settingsListenerBound){this._settingsListenerBound=!0;let t=d(s=>{s.detail?.names?.some(r=>r==="enablePreviewVideo"||r==="enableLoadPreviewVideo")&&this.reconfigure()},"onSettingsChanged");e.addEventListener("settings.changed",t),this._busScope.addCleanup((()=>{e.removeEventListener("settings.changed",t),this._settingsListenerBound=!1}))}this.reconfigure()}reconfigure(){this._busPreviewGeneration++;let e=this.getRuntimeService("settings").snapshot();if(!zt(e))return void this.unmountPreview();this.mountPreview()}mountPreview(){if(this._busPreviewMounted)return;this._busPreviewMounted=!0;let e=this._busScope;this.initModal(e);let t=$("#sample-waterfall .sample-box .photo-frame img:first").attr("src"),s=$(`
+ `);let t=$("#bus-preview-modal");t.on("click",(s=>{s.target instanceof Element&&s.target.id==="bus-preview-modal"&&this.closeVideoModal()})),e.listen(document,"keydown",(s=>{s instanceof KeyboardEvent&&s.key==="Escape"&&t.hasClass("is-open")&&this.closeVideoModal()})),e.addCleanup((()=>{t.off(),t.remove()}))}}closeVideoModal(){let e=$("#preview-video");e.length>0&&e[0].pause(),$("#bus-preview-modal").removeClass("is-open")}unmountPreview(){this._busPreviewMounted=!1,this.closeVideoModal(),$("#bus-preview-modal").remove(),$(".preview-video-container").off("click.jhsBusPreview").remove()}async handle(){if(!isDetailPage)return;let e=this.getRuntimeService("settings");if(this._busScope||(this._busScope=await this.getRuntimeService("scope")()),!this._settingsListenerBound){this._settingsListenerBound=!0;let t=d(s=>{s.detail?.names?.some(r=>r==="enablePreviewVideo"||r==="enableLoadPreviewVideo")&&this.reconfigure()},"onSettingsChanged");e.addEventListener("settings.changed",t),this._busScope.addCleanup((()=>{e.removeEventListener("settings.changed",t),this._settingsListenerBound=!1}))}this.reconfigure()}reconfigure(){this._busPreviewGeneration++;let e=this.getRuntimeService("settings").snapshot();if(!Ft(e))return void this.unmountPreview();this.mountPreview()}mountPreview(){if(this._busPreviewMounted)return;this._busPreviewMounted=!0;let e=this._busScope;this.initModal(e);let t=$("#sample-waterfall .sample-box .photo-frame img:first").attr("src"),s=$(`
@@ -3324,7 +3319,7 @@ ${i}\r
▶
- `);$("#sample-waterfall").prepend(s);let a=!1,r=$(".preview-video-container");r.on("click",(async i=>{if(i.preventDefault(),i.stopPropagation(),a)show.info("正在加载中, 勿重复点击");else{a=!0;try{await this.handleVideo()}finally{a=!1}}})),window.location.href.includes("autoPlay=1")&&r.trigger("click")}async handleVideo(){let e=this._busPreviewGeneration,t=$("#bus-preview-modal"),s=t.find(".bus-preview-modal-content"),a=$("#preview-video");if(e!==this._busPreviewGeneration||!Pe(this.getRuntimeService("settings").snapshot()))return;if(a.length>0)return t.addClass("is-open"),void await de(a[0],{context:"JavBus 预览视频",notify:!0});let r=this.getPageInfo().carNum,i=await this.getRuntimeService("scope")(),{sources:n,error:l}=await ma(r,this.getRuntimeService("storage"),this.getRuntimeService("movie"),i,this.getRuntimeService("settings").snapshot());e!==this._busPreviewGeneration||!Pe(this.getRuntimeService("settings").snapshot())||(n&&Object.keys(n).length!==0?(await this.createVideoPlayerAndControls(n,s),a=$("#preview-video"),a.length>0?(t.addClass("is-open"),await de(a[0],{context:"JavBus 预览视频",notify:!0,message:l?.code==="REGION_BLOCKED"?l.message:"当前视频源无法播放"})):show.error("视频播放器创建失败。")):show.error(l?.code==="REGION_BLOCKED"?l.message:"未找到可用的视频源。"))}async createVideoPlayerAndControls(e,t){let s=this.getRuntimeService("settings").snapshot().videoQuality;s=Ut(Object.keys(e),s);let a=e[s],r=$('