@jonathanleelx/meddle 0.5.0-beta.5 → 0.5.0-beta.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. package/package.json +1 -1
  2. package/web/dist/assets/{checkbox-DqL9h3Nm.js → checkbox-D1Z9DtjF.js} +1 -1
  3. package/web/dist/assets/{code-fixer-tlmkXPph.js → code-fixer-D48sCDtp.js} +1 -1
  4. package/web/dist/assets/detail-panel-BSFz9CUw.js +4 -0
  5. package/web/dist/assets/{global-panel-shell-DW6N2Buq.js → global-panel-shell-5cJneeis.js} +1 -1
  6. package/web/dist/assets/{health-panel-B9MX-flD.js → health-panel-BS3L2e5d.js} +1 -1
  7. package/web/dist/assets/{index-B-2u47xL.js → index-CvTR1IVi.js} +2 -2
  8. package/web/dist/assets/index-bfV7sxx5.css +2 -0
  9. package/web/dist/assets/{mobile-proxy-panel-DGAUgKqk.js → mobile-proxy-panel-tU0NyJ3P.js} +1 -1
  10. package/web/dist/assets/{mock-config-rse9jc7P.js → mock-config-CULJP6Vt.js} +1 -1
  11. package/web/dist/assets/{mock-editor-panel-DrTdEXwy.js → mock-editor-panel-9wlDaySA.js} +1 -1
  12. package/web/dist/assets/{monaco-editor-C__Z0Ze6.js → monaco-editor-BttaUoOz.js} +1 -1
  13. package/web/dist/assets/{plugin-code-editor-CLi0UR9b.js → plugin-code-editor-BAIBp4lg.js} +2 -2
  14. package/web/dist/assets/{plugin-config-Bqvii8b7.js → plugin-config-ButUV2SZ.js} +1 -1
  15. package/web/dist/assets/{plugin-generator-BGsDNPVh.js → plugin-generator-uceUPSCv.js} +1 -1
  16. package/web/dist/assets/{plugin-test-dialog-B7yq_LYP.js → plugin-test-dialog-BrJ4HfRX.js} +1 -1
  17. package/web/dist/assets/{route-preview-lO-2IK_z.js → route-preview-C4cGrS1-.js} +1 -1
  18. package/web/dist/assets/{rule-ai-assistant-panel-Bwwr38Xs.js → rule-ai-assistant-panel-DMh0F9dr.js} +2 -2
  19. package/web/dist/assets/{rule-config-D3hKcS83.js → rule-config-BTTGNwMs.js} +2 -2
  20. package/web/dist/assets/{rule-overview-panel-BGKjBz-X.js → rule-overview-panel-SFR2OloL.js} +1 -1
  21. package/web/dist/assets/{select-DwbCNt0T.js → select-aBXQ0zNa.js} +1 -1
  22. package/web/dist/assets/{settings-panel-BkDMAXRK.js → settings-panel-BMReDG8b.js} +1 -1
  23. package/web/dist/index.html +2 -2
  24. package/web/dist/assets/detail-panel-CIXvpxu6.js +0 -4
  25. package/web/dist/assets/index-CaHxRfdf.css +0 -2
@@ -1,2 +1,2 @@
1
- import{a as e,f as t,t as n,u as r}from"./button-BTToMaBW.js";import"./dist-C6eaYCUo.js";import{t as i}from"./circle-x-C9USji_R.js";import{t as a}from"./code-5_eJ_XpJ.js";import{t as o}from"./copy-BYjq1hdN.js";import{t as s}from"./wand-sparkles-CJ7fSnom.js";import"./es2015-DG46NGN7.js";import{o as ee,r as te}from"./ai-config-store-C8D_PUGV.js";import{B as c,Z as l,_ as ne,_t as re,b as u,ct as d,d as ie,et as ae,f as oe,g as se,h as ce,j as f,m as p,p as le,u as m,v as ue,vt as de,y as fe}from"./index-B-2u47xL.js";import{t as pe}from"./textarea-BSI0rnW6.js";var h=t(r(),1),g=e();function _({open:e=!1,onOpenChange:t,embedded:r=!1,onPluginSaved:_}){let[v,y]=(0,h.useState)(``),[b,x]=(0,h.useState)(``),[S,C]=(0,h.useState)(``),[w,T]=(0,h.useState)(``),[E,D]=(0,h.useState)(!1),[O,k]=(0,h.useState)(!1),[A,j]=(0,h.useState)(``),[M,N]=(0,h.useState)(``),[P,F]=(0,h.useState)(null),[I,L]=(0,h.useState)(null),[R,z]=(0,h.useState)(``),[me,B]=(0,h.useState)(!1),[V,H]=(0,h.useState)(0),[U,W]=(0,h.useState)(0),[G,K]=(0,h.useState)(!1),[q,J]=(0,h.useState)(!1),Y=te(),X=ee(Y),he=async()=>{if(!v.trim()||!b.trim()){L(`error`),z(`请填写插件名称和描述`);return}if(!X){L(`error`),z(`AI 配置未完成,请先配置 AI 服务`);return}D(!0),L(null),z(`正在连接 AI 服务...`),j(``),H(0),W(0);let e=Date.now(),t=0;try{let n={name:v,description:b,hooks:S.split(`,`).map(e=>e.trim()).filter(Boolean),permissions:w.split(`,`).map(e=>e.trim()).filter(Boolean)},r=await fetch(`/api/plugins/generate-stream`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({requirement:n,aiConfig:{provider:Y.provider,apiKey:Y.apiKey,baseUrl:Y.baseUrl,model:Y.model}})});if(!r.ok)throw Error(`请求失败: ${r.status}`);let i=r.body?.getReader(),a=new TextDecoder;if(!i)throw Error(`无法读取响应流`);let o=``;for(;;){let{done:n,value:r}=await i.read();if(n)break;o+=a.decode(r,{stream:!0});let s=o.split(`
1
+ import{a as e,f as t,t as n,u as r}from"./button-BTToMaBW.js";import"./dist-C6eaYCUo.js";import{t as i}from"./circle-x-C9USji_R.js";import{t as a}from"./code-5_eJ_XpJ.js";import{t as o}from"./copy-BYjq1hdN.js";import{t as s}from"./wand-sparkles-CJ7fSnom.js";import"./es2015-DG46NGN7.js";import{o as ee,r as te}from"./ai-config-store-C8D_PUGV.js";import{B as c,Z as l,_ as ne,_t as re,b as u,ct as d,d as ie,et as ae,f as oe,g as se,h as ce,j as f,m as p,p as le,u as m,v as ue,vt as de,y as fe}from"./index-CvTR1IVi.js";import{t as pe}from"./textarea-BSI0rnW6.js";var h=t(r(),1),g=e();function _({open:e=!1,onOpenChange:t,embedded:r=!1,onPluginSaved:_}){let[v,y]=(0,h.useState)(``),[b,x]=(0,h.useState)(``),[S,C]=(0,h.useState)(``),[w,T]=(0,h.useState)(``),[E,D]=(0,h.useState)(!1),[O,k]=(0,h.useState)(!1),[A,j]=(0,h.useState)(``),[M,N]=(0,h.useState)(``),[P,F]=(0,h.useState)(null),[I,L]=(0,h.useState)(null),[R,z]=(0,h.useState)(``),[me,B]=(0,h.useState)(!1),[V,H]=(0,h.useState)(0),[U,W]=(0,h.useState)(0),[G,K]=(0,h.useState)(!1),[q,J]=(0,h.useState)(!1),Y=te(),X=ee(Y),he=async()=>{if(!v.trim()||!b.trim()){L(`error`),z(`请填写插件名称和描述`);return}if(!X){L(`error`),z(`AI 配置未完成,请先配置 AI 服务`);return}D(!0),L(null),z(`正在连接 AI 服务...`),j(``),H(0),W(0);let e=Date.now(),t=0;try{let n={name:v,description:b,hooks:S.split(`,`).map(e=>e.trim()).filter(Boolean),permissions:w.split(`,`).map(e=>e.trim()).filter(Boolean)},r=await fetch(`/api/plugins/generate-stream`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({requirement:n,aiConfig:{provider:Y.provider,apiKey:Y.apiKey,baseUrl:Y.baseUrl,model:Y.model}})});if(!r.ok)throw Error(`请求失败: ${r.status}`);let i=r.body?.getReader(),a=new TextDecoder;if(!i)throw Error(`无法读取响应流`);let o=``;for(;;){let{done:n,value:r}=await i.read();if(n)break;o+=a.decode(r,{stream:!0});let s=o.split(`
2
2
  `);o=s.pop()||``;for(let n of s)if(!n.startsWith(`event:`)&&n.startsWith(`data:`)){let r=n.slice(5).trim();try{let n=JSON.parse(r);if(n.status===`generating`)z(`AI 正在生成代码...`),W(10);else if(n.chunk){t++;let r=n.accumulated||n.chunk;j(r),H(r.length),W(Math.min(90,10+t*2));let i=((Date.now()-e)/1e3).toFixed(1);z(`生成中... (${r.length} 字符, ${i}s)`)}else if(n.status===`success`){j(n.plugin.code),N(n.plugin.filename),F(n.plugin.manifest),H(n.plugin.code.length),W(100),L(`success`);let t=((Date.now()-e)/1e3).toFixed(1);z(`插件代码生成成功!(${n.plugin.code.length} 字符, ${t}s)`)}else if(n.error)throw Error(n.error)}catch(e){if(e instanceof Error&&e.message!==`Unexpected end of JSON input`)throw e}}}}catch(e){L(`error`),z(e instanceof Error?e.message:`生成失败`),W(0)}finally{D(!1)}},Z=async()=>{if(!A||!M){L(`error`),z(`没有可保存的插件代码`);return}k(!0),L(null),z(`正在保存插件...`);try{let e=await fetch(`/api/plugins/save`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({filename:M,code:A})});if(!e.ok){let t=await e.json();throw Error(t.error||`保存失败`)}await e.json(),L(`success`),z(`插件已保存!现在可以热加载并测试。`),K(!0),window.dispatchEvent(new CustomEvent(`plugins-custom-updated`)),m.success(`插件保存成功`),_&&_(),window.dispatchEvent(new CustomEvent(`plugins-custom-updated`))}catch(e){let t=e instanceof Error?e.message:`保存失败`;L(`error`),z(t),m.error(t)}finally{k(!1)}};ie({active:(e||r)&&!!A&&!G,enabled:!O&&!E&&!!M,priority:oe.panel,onSave:Z});let ge=async()=>{A&&(await navigator.clipboard.writeText(A),B(!0),setTimeout(()=>B(!1),2e3))},_e=async()=>{J(!0);try{let e=await fetch(`/api/plugins/reload`,{method:`POST`});if(!e.ok){let t=await e.json();throw Error(t.error||`热加载失败`)}let n=await e.json();L(`success`),z(`成功热加载 ${n.count} 个插件!插件已激活,可以使用了。`),_&&_(),setTimeout(()=>{t?.(!1),Q()},3e3)}catch(e){L(`error`),z(e instanceof Error?e.message:`热加载失败`)}finally{J(!1)}},Q=()=>{y(``),x(``),C(``),T(``),j(``),N(``),F(null),L(null),z(``),B(!1),H(0),W(0),K(!1),J(!1)},$=(0,g.jsxs)(g.Fragment,{children:[(0,g.jsxs)(ue,{className:`px-6 pt-6 pb-4`,children:[(0,g.jsxs)(fe,{className:`flex items-center gap-2`,children:[(0,g.jsx)(l,{className:`h-5 w-5`}),`AI 插件生成器`]}),(0,g.jsx)(ne,{children:`使用 AI 根据插件系统设计和您的需求自动生成自定义插件代码`})]}),(0,g.jsx)(p,{}),(0,g.jsxs)(`div`,{className:`app-panel-content`,children:[!X&&(0,g.jsx)(`div`,{className:`bg-yellow-50 dark:bg-yellow-950/20 border border-yellow-200 dark:border-yellow-900 rounded-md p-3`,children:(0,g.jsx)(`p`,{className:`text-sm text-yellow-700 dark:text-yellow-300`,children:`AI 功能未配置或未启用,请先在设置中配置 AI 服务`})}),(0,g.jsxs)(`div`,{className:`app-section`,children:[(0,g.jsxs)(`div`,{className:`app-field-group`,children:[(0,g.jsxs)(u,{htmlFor:`pluginName`,children:[`插件名称 `,(0,g.jsx)(`span`,{className:`text-red-500`,children:`*`})]}),(0,g.jsx)(f,{id:`pluginName`,value:v,onChange:e=>y(e.target.value),placeholder:`例如:请求日志分析器`,disabled:E||O})]}),(0,g.jsxs)(`div`,{className:`app-field-group`,children:[(0,g.jsxs)(u,{htmlFor:`pluginDescription`,children:[`插件描述 `,(0,g.jsx)(`span`,{className:`text-red-500`,children:`*`})]}),(0,g.jsx)(pe,{id:`pluginDescription`,value:b,onChange:e=>x(e.target.value),placeholder:`详细描述插件的功能,例如:分析HTTP请求日志,统计各个API的调用次数、响应时间等信息,并在控制台输出统计报告`,rows:4,disabled:E||O})]}),(0,g.jsxs)(`div`,{className:`app-field-group`,children:[(0,g.jsx)(u,{htmlFor:`hooks`,children:`需要的 Hooks(可选,用逗号分隔)`}),(0,g.jsx)(f,{id:`hooks`,value:S,onChange:e=>C(e.target.value),placeholder:`例如:onRequestStart, onAfterResponse`,disabled:E||O}),(0,g.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`可选:onRequestStart, onBeforeProxy, onBeforeResponse, onAfterResponse, onError`})]}),(0,g.jsxs)(`div`,{className:`app-field-group`,children:[(0,g.jsx)(u,{htmlFor:`permissions`,children:`需要的权限(可选,用逗号分隔)`}),(0,g.jsx)(f,{id:`permissions`,value:w,onChange:e=>T(e.target.value),placeholder:`例如:proxy:read, storage:write`,disabled:E||O}),(0,g.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`可选:proxy:read, proxy:write, response:shortcircuit, storage:read, storage:write`})]})]}),E&&U>0&&(0,g.jsxs)(`div`,{className:`app-field-group`,children:[(0,g.jsxs)(`div`,{className:`flex items-center justify-between text-sm`,children:[(0,g.jsx)(`span`,{className:`text-muted-foreground`,children:`生成进度`}),(0,g.jsxs)(`span`,{className:`font-medium`,children:[U,`%`]})]}),(0,g.jsx)(`div`,{className:`w-full bg-muted rounded-full h-2 overflow-hidden`,children:(0,g.jsx)(`div`,{className:`bg-primary h-full transition-all duration-300 ease-out`,style:{width:`${U}%`}})})]}),(A||E)&&(0,g.jsxs)(`div`,{className:`app-field-group`,children:[(0,g.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,g.jsxs)(u,{className:`flex items-center gap-2`,children:[(0,g.jsx)(a,{className:`h-4 w-4`}),E?`正在生成插件代码`:`生成的插件代码`]}),(0,g.jsxs)(`div`,{className:`flex items-center gap-2`,children:[V>0&&(0,g.jsxs)(`span`,{className:`text-xs text-muted-foreground`,children:[V,` 字符`]}),!E&&A&&(0,g.jsx)(n,{variant:`ghost`,size:`sm`,onClick:ge,className:`h-8`,children:me?(0,g.jsxs)(g.Fragment,{children:[(0,g.jsx)(de,{className:`h-4 w-4 mr-1`}),`已复制`]}):(0,g.jsxs)(g.Fragment,{children:[(0,g.jsx)(o,{className:`h-4 w-4 mr-1`}),`复制`]})})]})]}),(0,g.jsxs)(`div`,{className:`bg-muted rounded-md p-4 max-h-[400px] overflow-auto relative`,children:[E&&(0,g.jsx)(`div`,{className:`absolute top-2 right-2`,children:(0,g.jsx)(d,{className:`h-4 w-4 animate-spin text-muted-foreground`})}),(0,g.jsx)(`pre`,{className:`text-xs font-mono whitespace-pre-wrap break-all`,children:A||`等待 AI 响应...`})]}),P&&(0,g.jsxs)(`div`,{className:`bg-blue-50 dark:bg-blue-950/20 border border-blue-200 dark:border-blue-900 rounded-md p-3 space-y-2`,children:[(0,g.jsx)(`p`,{className:`text-sm font-medium text-blue-900 dark:text-blue-100`,children:`插件信息`}),(0,g.jsxs)(`div`,{className:`text-xs space-y-1 text-blue-700 dark:text-blue-300`,children:[(0,g.jsxs)(`div`,{children:[(0,g.jsx)(`strong`,{children:`ID:`}),` `,P.id]}),(0,g.jsxs)(`div`,{children:[(0,g.jsx)(`strong`,{children:`名称:`}),` `,P.name]}),(0,g.jsxs)(`div`,{children:[(0,g.jsx)(`strong`,{children:`版本:`}),` `,P.version]}),(0,g.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,g.jsx)(`strong`,{children:`Hooks:`}),(0,g.jsx)(`div`,{className:`flex flex-wrap gap-1`,children:P.hooks.map(e=>(0,g.jsx)(c,{variant:`secondary`,className:`text-xs`,children:e},e))})]}),(0,g.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,g.jsx)(`strong`,{children:`权限:`}),(0,g.jsx)(`div`,{className:`flex flex-wrap gap-1`,children:P.permissions.map(e=>(0,g.jsx)(c,{variant:`outline`,className:`text-xs`,children:e},e))})]})]})]})]}),R&&(0,g.jsxs)(`div`,{className:`flex items-start gap-2 p-3 rounded-md border ${I===`success`?`bg-green-50 dark:bg-green-950/20 border-green-200 dark:border-green-900`:I===`error`?`bg-red-50 dark:bg-red-950/20 border-red-200 dark:border-red-900`:`bg-blue-50 dark:bg-blue-950/20 border-blue-200 dark:border-blue-900`}`,children:[I===`success`&&(0,g.jsx)(re,{className:`h-4 w-4 text-green-600 dark:text-green-400 mt-0.5`}),I===`error`&&(0,g.jsx)(i,{className:`h-4 w-4 text-red-600 dark:text-red-400 mt-0.5`}),E&&(0,g.jsx)(d,{className:`h-4 w-4 text-blue-600 dark:text-blue-400 mt-0.5 animate-spin`}),(0,g.jsx)(`span`,{className:`text-xs flex-1 ${I===`success`?`text-green-700 dark:text-green-300`:I===`error`?`text-red-700 dark:text-red-300`:`text-blue-700 dark:text-blue-300`}`,children:R})]})]}),(0,g.jsx)(p,{}),(0,g.jsxs)(`div`,{className:`px-6 py-4 flex justify-between gap-2`,children:[(0,g.jsx)(n,{variant:`outline`,size:`sm`,onClick:()=>{t?.(!1),Q()},disabled:E||O||q,children:G?`完成`:`取消`}),(0,g.jsx)(`div`,{className:`flex gap-2`,children:A?G?(0,g.jsx)(n,{size:`sm`,onClick:_e,disabled:q,className:`bg-green-600 hover:bg-green-700`,children:q?(0,g.jsxs)(g.Fragment,{children:[(0,g.jsx)(d,{className:`h-4 w-4 mr-1 animate-spin`}),`加载中...`]}):(0,g.jsxs)(g.Fragment,{children:[(0,g.jsx)(l,{className:`h-4 w-4 mr-1`}),`热加载并测试`]})}):(0,g.jsxs)(g.Fragment,{children:[(0,g.jsx)(n,{variant:`outline`,size:`sm`,onClick:()=>{j(``),N(``),F(null),L(null),z(``)},disabled:E||O,children:`重新生成`}),(0,g.jsx)(le,{size:`sm`,onClick:Z,disabled:O,children:O?(0,g.jsxs)(g.Fragment,{children:[(0,g.jsx)(d,{"data-icon":`inline-start`,className:`animate-spin`}),`保存中...`]}):(0,g.jsxs)(g.Fragment,{children:[(0,g.jsx)(ae,{"data-icon":`inline-start`}),`保存插件`]})})]}):(0,g.jsx)(n,{size:`sm`,onClick:he,disabled:!X||E||O||!v.trim()||!b.trim(),children:E?(0,g.jsxs)(g.Fragment,{children:[(0,g.jsx)(d,{className:`h-4 w-4 mr-1 animate-spin`}),`生成中...`]}):(0,g.jsxs)(g.Fragment,{children:[(0,g.jsx)(s,{className:`h-4 w-4 mr-1`}),`生成插件`]})})})]})]});return r?(0,g.jsx)(`div`,{className:`flex h-full min-h-0 flex-col`,children:$}):(0,g.jsx)(ce,{open:e,onOpenChange:e=>{t?.(e),e||Q()},children:(0,g.jsx)(se,{className:`p-0 flex flex-col`,resizable:!0,defaultWidth:900,storageKey:`plugin-generator`,children:$})})}export{_ as PluginGenerator};
@@ -1,4 +1,4 @@
1
- import{a as e,f as t,l as n,t as r,u as i}from"./button-BTToMaBW.js";import"./dist-C6eaYCUo.js";import{t as a}from"./arrow-right-B4Mrlj2-.js";import{t as o}from"./circle-alert-Q8cZk9Rv.js";import{t as s}from"./circle-x-C9USji_R.js";import{t as ee}from"./pencil-line-Cqe41E4h.js";import{t as c}from"./refresh-cw-CG3HaiQT.js";import{t as te}from"./wand-sparkles-CJ7fSnom.js";import"./es2015-DG46NGN7.js";import{i as ne,o as re,r as ie}from"./ai-config-store-C8D_PUGV.js";import{B as l,J as ae,U as u,V as d,W as f,_ as oe,_t as se,b as p,ct as m,dt as ce,g as le,gt as ue,h as de,j as fe,m as h,pt as pe,v as me,y as he}from"./index-B-2u47xL.js";import{t as g}from"./body-diff-view-B-4XWmL6.js";import{n as ge,t as _e}from"./monaco-editor-C__Z0Ze6.js";import{t as ve}from"./textarea-BSI0rnW6.js";var ye=n(`circle-play`,[[`path`,{d:`M9 9.003a1 1 0 0 1 1.517-.859l4.997 2.997a1 1 0 0 1 0 1.718l-4.997 2.997A1 1 0 0 1 9 14.996z`,key:`kmsa83`}],[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}]]),_=t(i(),1),v=e();function y(e){let t=new Map;return!e||typeof e!=`object`||Object.entries(e).forEach(([e,n])=>{t.set(e.toLowerCase(),{displayKey:e,value:n==null?``:String(n)})}),t}function b(e,t){let n=y(e),r=y(t);return Array.from(new Set([...n.keys(),...r.keys()])).sort().map(e=>{let t=n.get(e),i=r.get(e),a=t?.value??``,o=i?.value??``,s=`unchanged`;return!t&&i?s=`added`:t&&!i?s=`removed`:a!==o&&(s=`changed`),{key:e,displayKey:i?.displayKey??t?.displayKey??e,originalValue:a,modifiedValue:o,status:s}})}function x(e,t){let n=`rounded-md border px-2 py-1.5`;return e===`unchanged`?`${n} border-transparent`:e===`changed`?`${n} border-orange-300 bg-orange-500/10`:e===`added`?t===`modified`?`${n} border-green-300 bg-green-500/10`:`${n} border-transparent opacity-50`:e===`removed`?t===`original`?`${n} border-red-300 bg-red-500/10`:`${n} border-transparent opacity-50`:n}function be({original:e,modified:t,mode:n=`split`}){let r=b(e,t);return n===`inline`?(0,v.jsx)(`div`,{className:`bg-muted/50 rounded-md p-2 text-xs font-mono max-h-[220px] overflow-auto space-y-1`,children:r.map(e=>(0,v.jsxs)(`div`,{className:`rounded-md border px-2 py-1.5 ${e.status===`unchanged`?`border-transparent`:e.status===`changed`?`border-orange-300 bg-orange-500/10`:e.status===`added`?`border-green-300 bg-green-500/10`:`border-red-300 bg-red-500/10`}`,children:[(0,v.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,v.jsx)(`span`,{className:`text-muted-foreground`,children:e.displayKey}),(0,v.jsx)(l,{variant:`outline`,className:`h-5 px-1.5 text-[10px] font-normal`,children:e.status===`unchanged`?`未变`:e.status===`changed`?`修改`:e.status===`added`?`新增`:`删除`})]}),e.status===`changed`&&(0,v.jsxs)(`div`,{className:`mt-1 space-y-1`,children:[(0,v.jsxs)(`div`,{className:`text-red-700 dark:text-red-300`,children:[(0,v.jsx)(`span`,{className:`mr-1`,children:`-`}),e.originalValue||(0,v.jsx)(`span`,{className:`text-muted-foreground italic`,children:`(无)`})]}),(0,v.jsxs)(`div`,{className:`text-green-700 dark:text-green-300`,children:[(0,v.jsx)(`span`,{className:`mr-1`,children:`+`}),e.modifiedValue||(0,v.jsx)(`span`,{className:`text-muted-foreground italic`,children:`(无)`})]})]}),e.status===`added`&&(0,v.jsxs)(`div`,{className:`mt-1 text-green-700 dark:text-green-300`,children:[(0,v.jsx)(`span`,{className:`mr-1`,children:`+`}),e.modifiedValue||(0,v.jsx)(`span`,{className:`text-muted-foreground italic`,children:`(无)`})]}),e.status===`removed`&&(0,v.jsxs)(`div`,{className:`mt-1 text-red-700 dark:text-red-300`,children:[(0,v.jsx)(`span`,{className:`mr-1`,children:`-`}),e.originalValue||(0,v.jsx)(`span`,{className:`text-muted-foreground italic`,children:`(无)`})]}),e.status===`unchanged`&&(0,v.jsx)(`div`,{className:`mt-1`,children:e.modifiedValue||e.originalValue||(0,v.jsx)(`span`,{className:`text-muted-foreground italic`,children:`(无)`})})]},e.key))}):(0,v.jsxs)(`div`,{className:`grid grid-cols-2 gap-2`,children:[(0,v.jsxs)(`div`,{children:[(0,v.jsx)(`div`,{className:`text-[10px] text-muted-foreground mb-0.5`,children:`原始`}),(0,v.jsx)(`div`,{className:`bg-muted/50 rounded-md p-2 text-xs font-mono max-h-[220px] overflow-auto space-y-1`,children:r.map(e=>(0,v.jsxs)(`div`,{className:x(e.status,`original`),children:[(0,v.jsxs)(`span`,{className:`text-muted-foreground`,children:[e.displayKey,`:`]}),` `,e.originalValue||(0,v.jsx)(`span`,{className:`text-muted-foreground italic`,children:`(无)`})]},`original-${e.key}`))})]}),(0,v.jsxs)(`div`,{children:[(0,v.jsx)(`div`,{className:`text-[10px] text-muted-foreground mb-0.5`,children:`修改后`}),(0,v.jsx)(`div`,{className:`bg-muted/50 rounded-md p-2 text-xs font-mono max-h-[220px] overflow-auto space-y-1`,children:r.map(e=>(0,v.jsxs)(`div`,{className:x(e.status,`modified`),children:[(0,v.jsxs)(`span`,{className:`text-muted-foreground`,children:[e.displayKey,`:`]}),` `,e.modifiedValue||(0,v.jsx)(`span`,{className:`text-muted-foreground italic`,children:`(无)`})]},`modified-${e.key}`))})]})]})}function xe(e){switch(e){case`generating`:return`AI 正在流式生成修复代码`;case`saving`:return`正在保存修复后的插件代码`;case`reloading`:return`正在热加载插件`;case`retesting`:return`正在重新执行插件测试`;default:return``}}function S({open:e=!1,onOpenChange:t,embedded:n=!1,pluginId:i,pluginName:y,hooks:b,onPluginFixed:x}){let[S,Se]=(0,_.useState)(!1),[C,w]=(0,_.useState)(!1),[Ce,we]=(0,_.useState)(`https://365.wps.cn/home`),[Te,Ee]=(0,_.useState)(`GET`),[T,E]=(0,_.useState)(`standalone`),[D,O]=(0,_.useState)(null),[k,De]=(0,_.useState)(`split`),[A,Oe]=(0,_.useState)(`inline`),[j,M]=(0,_.useState)(null),[N,P]=(0,_.useState)(``),[F,I]=(0,_.useState)(``),[L,ke]=(0,_.useState)(!1),[R,z]=(0,_.useState)(null),[B,V]=(0,_.useState)(``),[Ae,H]=(0,_.useState)(`normal`),[U,je]=(0,_.useState)(``),[W,G]=(0,_.useState)(`idle`),K=ie(),q=ne(K),Me=q?{provider:q.provider,apiKey:q.apiKey,baseUrl:q.baseUrl,model:q.model}:{provider:K.provider,apiKey:K.apiKey,baseUrl:K.baseUrl,model:K.model},J=re(K),Y=i.startsWith(`local.`)?`${i.slice(6)}.js`:``,X=(0,_.useCallback)(async()=>{if(!Y||!e){P(``),I(``),z(null);return}ke(!0),z(null);try{let e=await fetch(`/api/plugins/custom/${encodeURIComponent(Y)}/code`);if(!e.ok){let t=await e.json();throw Error(t.error||`读取插件源码失败`)}let t=await e.json();P(t.code||``),!C&&!B&&I(t.code||``)}catch(e){P(``),I(``),z(e instanceof Error?e.message:`读取插件源码失败`)}finally{ke(!1)}},[Y,C,B,e]);(0,_.useEffect)(()=>{X()},[X]);let Z=(0,_.useMemo)(()=>{let e=[];return D?.error&&e.push({hookName:`test`,message:D.error}),Object.entries(D?.hookResults||{}).forEach(([t,n])=>{n?.status===`error`&&e.push({hookName:t,message:n.error||`未知错误`,stack:n.stack})}),D?.realRequest?.fetchError&&e.push({hookName:`fetch`,message:D.realRequest.fetchError}),e},[D]),Q=Z.length>0&&!!Y,Ne=!!F&&!!(B||W===`idle`&&F&&N&&F!==N),Pe=async(e,t,n)=>{G(`saving`);let r=await fetch(`/api/plugins/custom/${encodeURIComponent(Y)}/code`,{method:`PUT`,headers:{"Content-Type":`application/json`},body:JSON.stringify({code:e})});if(!r.ok){let e=await r.json();throw Error(e.error||`保存修复后的代码失败`)}G(`reloading`);let i=await fetch(`/api/plugins/reload`,{method:`POST`});if(!i.ok){let e=await i.json().catch(()=>({error:`热加载失败`}));throw Error(e.error||`热加载失败`)}P(e),V(e),H(`diff`),window.dispatchEvent(new CustomEvent(`plugins-custom-updated`)),x?.(),n&&(G(`retesting`),await Fe()),M({status:`success`,message:t}),G(`idle`)},Fe=async()=>{Se(!0),O(null),M(null);try{let e=await fetch(`/api/plugins/test`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({pluginId:i,url:Ce,method:Te,integrated:T===`integrated`})});if(!e.ok){let t=await e.json();throw Error(t.error||`测试失败`)}O((await e.json()).results)}catch(e){O({error:e instanceof Error?e.message:`测试失败`})}finally{Se(!1)}},$=(0,v.jsxs)(v.Fragment,{children:[(0,v.jsxs)(me,{className:`px-6 pt-6 pb-4`,children:[(0,v.jsxs)(he,{className:`flex items-center gap-2`,children:[(0,v.jsx)(ae,{className:`h-5 w-5`}),`测试插件: `,y]}),(0,v.jsx)(oe,{children:`发起真实 HTTP 请求,在请求/响应过程中运行插件代码`})]}),(0,v.jsx)(h,{}),(0,v.jsxs)(`div`,{className:`app-panel-content`,children:[(0,v.jsxs)(`div`,{className:`app-section`,children:[(0,v.jsxs)(`div`,{className:`app-field-group`,children:[(0,v.jsx)(p,{htmlFor:`testUrl`,children:`请求 URL`}),(0,v.jsx)(fe,{id:`testUrl`,value:Ce,onChange:e=>we(e.target.value),placeholder:`https://example.com/page`,disabled:S})]}),(0,v.jsxs)(`div`,{className:`app-field-group`,children:[(0,v.jsx)(p,{children:`HTTP 方法`}),(0,v.jsx)(`div`,{className:`flex gap-2`,children:[`GET`,`POST`,`PUT`,`DELETE`].map(e=>(0,v.jsx)(r,{type:`button`,variant:Te===e?`selected`:`outline`,size:`sm`,onClick:()=>Ee(e),disabled:S,children:e},e))})]}),(0,v.jsxs)(`div`,{className:`app-field-group`,children:[(0,v.jsx)(p,{children:`测试模式`}),(0,v.jsxs)(`div`,{className:`flex gap-2 flex-wrap`,children:[(0,v.jsx)(r,{type:`button`,variant:T===`standalone`?`selected`:`outline`,size:`sm`,onClick:()=>E(`standalone`),disabled:S,title:`直接请求 URL,不走路由与 Mock,便于排查插件自身逻辑`,children:`单独测试`}),(0,v.jsx)(r,{type:`button`,variant:T===`integrated`?`selected`:`outline`,size:`sm`,onClick:()=>E(`integrated`),disabled:S,title:`与真实代理一致:先路由解析、Mock 匹配,再请求,便于排查整体链路`,children:`集成测试`})]}),(0,v.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:T===`standalone`?`直接请求上述 URL,不经过路由规则和 Mock,适合验证插件逻辑。`:`先按路由规则解析目标、匹配 Mock,再请求,与经代理的真实请求一致,适合排查链路问题。`})]}),(0,v.jsx)(`div`,{className:`bg-blue-50 dark:bg-blue-950/20 border border-blue-200 dark:border-blue-900 rounded-md p-3`,children:(0,v.jsxs)(`p`,{className:`text-xs text-blue-700 dark:text-blue-300`,children:[(0,v.jsx)(`strong`,{children:`测试流程:`}),` 发起真实请求 → 获取服务器响应 → 运行插件 Hook(`,b.join(`, `),`)→ 展示对比结果`]})})]}),!!Y&&(0,v.jsxs)(`div`,{className:`space-y-3`,children:[(0,v.jsx)(h,{}),(0,v.jsxs)(`div`,{className:`space-y-2`,children:[(0,v.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,v.jsxs)(`h3`,{className:`text-sm font-medium flex items-center gap-2`,children:[(0,v.jsx)(ue,{className:`h-4 w-4`}),`插件代码`]}),(0,v.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,v.jsx)(d,{value:Ae,onValueChange:e=>H(e),children:(0,v.jsxs)(u,{className:`h-7`,children:[(0,v.jsx)(f,{value:`normal`,className:`px-2 text-xs`,children:`正常视图`}),(0,v.jsx)(f,{value:`diff`,className:`px-2 text-xs`,disabled:!Ne,children:`Diff 视图`})]})}),(0,v.jsx)(l,{variant:`outline`,className:`text-xs font-normal`,children:Y}),(0,v.jsx)(r,{size:`sm`,variant:`ghost`,onClick:X,disabled:L||C,children:L?(0,v.jsxs)(v.Fragment,{children:[(0,v.jsx)(m,{className:`h-4 w-4 mr-1 animate-spin`}),`读取中`]}):(0,v.jsxs)(v.Fragment,{children:[(0,v.jsx)(c,{className:`h-4 w-4 mr-1`}),`刷新代码`]})})]})]}),R?(0,v.jsx)(`div`,{className:`rounded-md border border-red-200 bg-red-50/80 p-3 text-sm text-red-700 dark:border-red-900 dark:bg-red-950/20 dark:text-red-300`,children:R}):Ae===`diff`&&Ne?(0,v.jsxs)(`div`,{className:`space-y-2`,children:[(0,v.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,v.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:`左侧是原代码,右侧是 AI 修复后的代码`}),W!==`idle`&&(0,v.jsx)(l,{variant:`outline`,className:`text-xs font-normal`,children:xe(W)})]}),(0,v.jsx)(_e,{original:F||N,modified:B||N,language:`javascript`,minHeight:`320px`})]}):(0,v.jsx)(ge,{value:C&&B?B:N,onChange:()=>{},language:`javascript`,readOnly:!0,minHeight:`260px`}),(0,v.jsxs)(`div`,{className:`space-y-2 pt-2`,children:[(0,v.jsx)(p,{htmlFor:`plugin-extra-instruction`,children:`额外信息`}),(0,v.jsx)(ve,{id:`plugin-extra-instruction`,value:U,onChange:e=>je(e.target.value),placeholder:`例如:补充 onBeforeResponse 里对 JSON 响应的判空逻辑;保留现有 hooks 和 manifest,不要改插件 id。`,className:`min-h-[88px]`,disabled:C||L}),(0,v.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,v.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`输入额外要求后,AI 会基于当前插件代码直接更新并热加载。`}),(0,v.jsx)(r,{size:`sm`,variant:`outline`,onClick:async()=>{if(!(!Y||!U.trim()||!J||C)){w(!0),M(null),V(``),I(N);try{G(`generating`);let e=await fetch(`/api/plugins/revise-stream`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({originalCode:N,instruction:U.trim(),requirement:{name:y,description:`根据额外要求更新插件 ${y},并保持 hooks 行为正确。Hooks: ${b.join(`, `)}`,hooks:b},aiConfig:Me})});if(!e.ok){let t=await e.json();throw Error(t.error||`AI 更新代码失败`)}let t=e.body?.getReader(),n=new TextDecoder;if(!t)throw Error(`无法读取 AI 更新流`);let r=``,i=``;for(;;){let{done:e,value:a}=await t.read();if(e)break;i+=n.decode(a,{stream:!0});let o=i.split(`
1
+ import{a as e,f as t,l as n,t as r,u as i}from"./button-BTToMaBW.js";import"./dist-C6eaYCUo.js";import{t as a}from"./arrow-right-B4Mrlj2-.js";import{t as o}from"./circle-alert-Q8cZk9Rv.js";import{t as s}from"./circle-x-C9USji_R.js";import{t as ee}from"./pencil-line-Cqe41E4h.js";import{t as c}from"./refresh-cw-CG3HaiQT.js";import{t as te}from"./wand-sparkles-CJ7fSnom.js";import"./es2015-DG46NGN7.js";import{i as ne,o as re,r as ie}from"./ai-config-store-C8D_PUGV.js";import{B as l,J as ae,U as u,V as d,W as f,_ as oe,_t as se,b as p,ct as m,dt as ce,g as le,gt as ue,h as de,j as fe,m as h,pt as pe,v as me,y as he}from"./index-CvTR1IVi.js";import{t as g}from"./body-diff-view-B-4XWmL6.js";import{n as ge,t as _e}from"./monaco-editor-BttaUoOz.js";import{t as ve}from"./textarea-BSI0rnW6.js";var ye=n(`circle-play`,[[`path`,{d:`M9 9.003a1 1 0 0 1 1.517-.859l4.997 2.997a1 1 0 0 1 0 1.718l-4.997 2.997A1 1 0 0 1 9 14.996z`,key:`kmsa83`}],[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}]]),_=t(i(),1),v=e();function y(e){let t=new Map;return!e||typeof e!=`object`||Object.entries(e).forEach(([e,n])=>{t.set(e.toLowerCase(),{displayKey:e,value:n==null?``:String(n)})}),t}function b(e,t){let n=y(e),r=y(t);return Array.from(new Set([...n.keys(),...r.keys()])).sort().map(e=>{let t=n.get(e),i=r.get(e),a=t?.value??``,o=i?.value??``,s=`unchanged`;return!t&&i?s=`added`:t&&!i?s=`removed`:a!==o&&(s=`changed`),{key:e,displayKey:i?.displayKey??t?.displayKey??e,originalValue:a,modifiedValue:o,status:s}})}function x(e,t){let n=`rounded-md border px-2 py-1.5`;return e===`unchanged`?`${n} border-transparent`:e===`changed`?`${n} border-orange-300 bg-orange-500/10`:e===`added`?t===`modified`?`${n} border-green-300 bg-green-500/10`:`${n} border-transparent opacity-50`:e===`removed`?t===`original`?`${n} border-red-300 bg-red-500/10`:`${n} border-transparent opacity-50`:n}function be({original:e,modified:t,mode:n=`split`}){let r=b(e,t);return n===`inline`?(0,v.jsx)(`div`,{className:`bg-muted/50 rounded-md p-2 text-xs font-mono max-h-[220px] overflow-auto space-y-1`,children:r.map(e=>(0,v.jsxs)(`div`,{className:`rounded-md border px-2 py-1.5 ${e.status===`unchanged`?`border-transparent`:e.status===`changed`?`border-orange-300 bg-orange-500/10`:e.status===`added`?`border-green-300 bg-green-500/10`:`border-red-300 bg-red-500/10`}`,children:[(0,v.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,v.jsx)(`span`,{className:`text-muted-foreground`,children:e.displayKey}),(0,v.jsx)(l,{variant:`outline`,className:`h-5 px-1.5 text-[10px] font-normal`,children:e.status===`unchanged`?`未变`:e.status===`changed`?`修改`:e.status===`added`?`新增`:`删除`})]}),e.status===`changed`&&(0,v.jsxs)(`div`,{className:`mt-1 space-y-1`,children:[(0,v.jsxs)(`div`,{className:`text-red-700 dark:text-red-300`,children:[(0,v.jsx)(`span`,{className:`mr-1`,children:`-`}),e.originalValue||(0,v.jsx)(`span`,{className:`text-muted-foreground italic`,children:`(无)`})]}),(0,v.jsxs)(`div`,{className:`text-green-700 dark:text-green-300`,children:[(0,v.jsx)(`span`,{className:`mr-1`,children:`+`}),e.modifiedValue||(0,v.jsx)(`span`,{className:`text-muted-foreground italic`,children:`(无)`})]})]}),e.status===`added`&&(0,v.jsxs)(`div`,{className:`mt-1 text-green-700 dark:text-green-300`,children:[(0,v.jsx)(`span`,{className:`mr-1`,children:`+`}),e.modifiedValue||(0,v.jsx)(`span`,{className:`text-muted-foreground italic`,children:`(无)`})]}),e.status===`removed`&&(0,v.jsxs)(`div`,{className:`mt-1 text-red-700 dark:text-red-300`,children:[(0,v.jsx)(`span`,{className:`mr-1`,children:`-`}),e.originalValue||(0,v.jsx)(`span`,{className:`text-muted-foreground italic`,children:`(无)`})]}),e.status===`unchanged`&&(0,v.jsx)(`div`,{className:`mt-1`,children:e.modifiedValue||e.originalValue||(0,v.jsx)(`span`,{className:`text-muted-foreground italic`,children:`(无)`})})]},e.key))}):(0,v.jsxs)(`div`,{className:`grid grid-cols-2 gap-2`,children:[(0,v.jsxs)(`div`,{children:[(0,v.jsx)(`div`,{className:`text-[10px] text-muted-foreground mb-0.5`,children:`原始`}),(0,v.jsx)(`div`,{className:`bg-muted/50 rounded-md p-2 text-xs font-mono max-h-[220px] overflow-auto space-y-1`,children:r.map(e=>(0,v.jsxs)(`div`,{className:x(e.status,`original`),children:[(0,v.jsxs)(`span`,{className:`text-muted-foreground`,children:[e.displayKey,`:`]}),` `,e.originalValue||(0,v.jsx)(`span`,{className:`text-muted-foreground italic`,children:`(无)`})]},`original-${e.key}`))})]}),(0,v.jsxs)(`div`,{children:[(0,v.jsx)(`div`,{className:`text-[10px] text-muted-foreground mb-0.5`,children:`修改后`}),(0,v.jsx)(`div`,{className:`bg-muted/50 rounded-md p-2 text-xs font-mono max-h-[220px] overflow-auto space-y-1`,children:r.map(e=>(0,v.jsxs)(`div`,{className:x(e.status,`modified`),children:[(0,v.jsxs)(`span`,{className:`text-muted-foreground`,children:[e.displayKey,`:`]}),` `,e.modifiedValue||(0,v.jsx)(`span`,{className:`text-muted-foreground italic`,children:`(无)`})]},`modified-${e.key}`))})]})]})}function xe(e){switch(e){case`generating`:return`AI 正在流式生成修复代码`;case`saving`:return`正在保存修复后的插件代码`;case`reloading`:return`正在热加载插件`;case`retesting`:return`正在重新执行插件测试`;default:return``}}function S({open:e=!1,onOpenChange:t,embedded:n=!1,pluginId:i,pluginName:y,hooks:b,onPluginFixed:x}){let[S,Se]=(0,_.useState)(!1),[C,w]=(0,_.useState)(!1),[Ce,we]=(0,_.useState)(`https://365.wps.cn/home`),[Te,Ee]=(0,_.useState)(`GET`),[T,E]=(0,_.useState)(`standalone`),[D,O]=(0,_.useState)(null),[k,De]=(0,_.useState)(`split`),[A,Oe]=(0,_.useState)(`inline`),[j,M]=(0,_.useState)(null),[N,P]=(0,_.useState)(``),[F,I]=(0,_.useState)(``),[L,ke]=(0,_.useState)(!1),[R,z]=(0,_.useState)(null),[B,V]=(0,_.useState)(``),[Ae,H]=(0,_.useState)(`normal`),[U,je]=(0,_.useState)(``),[W,G]=(0,_.useState)(`idle`),K=ie(),q=ne(K),Me=q?{provider:q.provider,apiKey:q.apiKey,baseUrl:q.baseUrl,model:q.model}:{provider:K.provider,apiKey:K.apiKey,baseUrl:K.baseUrl,model:K.model},J=re(K),Y=i.startsWith(`local.`)?`${i.slice(6)}.js`:``,X=(0,_.useCallback)(async()=>{if(!Y||!e){P(``),I(``),z(null);return}ke(!0),z(null);try{let e=await fetch(`/api/plugins/custom/${encodeURIComponent(Y)}/code`);if(!e.ok){let t=await e.json();throw Error(t.error||`读取插件源码失败`)}let t=await e.json();P(t.code||``),!C&&!B&&I(t.code||``)}catch(e){P(``),I(``),z(e instanceof Error?e.message:`读取插件源码失败`)}finally{ke(!1)}},[Y,C,B,e]);(0,_.useEffect)(()=>{X()},[X]);let Z=(0,_.useMemo)(()=>{let e=[];return D?.error&&e.push({hookName:`test`,message:D.error}),Object.entries(D?.hookResults||{}).forEach(([t,n])=>{n?.status===`error`&&e.push({hookName:t,message:n.error||`未知错误`,stack:n.stack})}),D?.realRequest?.fetchError&&e.push({hookName:`fetch`,message:D.realRequest.fetchError}),e},[D]),Q=Z.length>0&&!!Y,Ne=!!F&&!!(B||W===`idle`&&F&&N&&F!==N),Pe=async(e,t,n)=>{G(`saving`);let r=await fetch(`/api/plugins/custom/${encodeURIComponent(Y)}/code`,{method:`PUT`,headers:{"Content-Type":`application/json`},body:JSON.stringify({code:e})});if(!r.ok){let e=await r.json();throw Error(e.error||`保存修复后的代码失败`)}G(`reloading`);let i=await fetch(`/api/plugins/reload`,{method:`POST`});if(!i.ok){let e=await i.json().catch(()=>({error:`热加载失败`}));throw Error(e.error||`热加载失败`)}P(e),V(e),H(`diff`),window.dispatchEvent(new CustomEvent(`plugins-custom-updated`)),x?.(),n&&(G(`retesting`),await Fe()),M({status:`success`,message:t}),G(`idle`)},Fe=async()=>{Se(!0),O(null),M(null);try{let e=await fetch(`/api/plugins/test`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({pluginId:i,url:Ce,method:Te,integrated:T===`integrated`})});if(!e.ok){let t=await e.json();throw Error(t.error||`测试失败`)}O((await e.json()).results)}catch(e){O({error:e instanceof Error?e.message:`测试失败`})}finally{Se(!1)}},$=(0,v.jsxs)(v.Fragment,{children:[(0,v.jsxs)(me,{className:`px-6 pt-6 pb-4`,children:[(0,v.jsxs)(he,{className:`flex items-center gap-2`,children:[(0,v.jsx)(ae,{className:`h-5 w-5`}),`测试插件: `,y]}),(0,v.jsx)(oe,{children:`发起真实 HTTP 请求,在请求/响应过程中运行插件代码`})]}),(0,v.jsx)(h,{}),(0,v.jsxs)(`div`,{className:`app-panel-content`,children:[(0,v.jsxs)(`div`,{className:`app-section`,children:[(0,v.jsxs)(`div`,{className:`app-field-group`,children:[(0,v.jsx)(p,{htmlFor:`testUrl`,children:`请求 URL`}),(0,v.jsx)(fe,{id:`testUrl`,value:Ce,onChange:e=>we(e.target.value),placeholder:`https://example.com/page`,disabled:S})]}),(0,v.jsxs)(`div`,{className:`app-field-group`,children:[(0,v.jsx)(p,{children:`HTTP 方法`}),(0,v.jsx)(`div`,{className:`flex gap-2`,children:[`GET`,`POST`,`PUT`,`DELETE`].map(e=>(0,v.jsx)(r,{type:`button`,variant:Te===e?`selected`:`outline`,size:`sm`,onClick:()=>Ee(e),disabled:S,children:e},e))})]}),(0,v.jsxs)(`div`,{className:`app-field-group`,children:[(0,v.jsx)(p,{children:`测试模式`}),(0,v.jsxs)(`div`,{className:`flex gap-2 flex-wrap`,children:[(0,v.jsx)(r,{type:`button`,variant:T===`standalone`?`selected`:`outline`,size:`sm`,onClick:()=>E(`standalone`),disabled:S,title:`直接请求 URL,不走路由与 Mock,便于排查插件自身逻辑`,children:`单独测试`}),(0,v.jsx)(r,{type:`button`,variant:T===`integrated`?`selected`:`outline`,size:`sm`,onClick:()=>E(`integrated`),disabled:S,title:`与真实代理一致:先路由解析、Mock 匹配,再请求,便于排查整体链路`,children:`集成测试`})]}),(0,v.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:T===`standalone`?`直接请求上述 URL,不经过路由规则和 Mock,适合验证插件逻辑。`:`先按路由规则解析目标、匹配 Mock,再请求,与经代理的真实请求一致,适合排查链路问题。`})]}),(0,v.jsx)(`div`,{className:`bg-blue-50 dark:bg-blue-950/20 border border-blue-200 dark:border-blue-900 rounded-md p-3`,children:(0,v.jsxs)(`p`,{className:`text-xs text-blue-700 dark:text-blue-300`,children:[(0,v.jsx)(`strong`,{children:`测试流程:`}),` 发起真实请求 → 获取服务器响应 → 运行插件 Hook(`,b.join(`, `),`)→ 展示对比结果`]})})]}),!!Y&&(0,v.jsxs)(`div`,{className:`space-y-3`,children:[(0,v.jsx)(h,{}),(0,v.jsxs)(`div`,{className:`space-y-2`,children:[(0,v.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,v.jsxs)(`h3`,{className:`text-sm font-medium flex items-center gap-2`,children:[(0,v.jsx)(ue,{className:`h-4 w-4`}),`插件代码`]}),(0,v.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,v.jsx)(d,{value:Ae,onValueChange:e=>H(e),children:(0,v.jsxs)(u,{className:`h-7`,children:[(0,v.jsx)(f,{value:`normal`,className:`px-2 text-xs`,children:`正常视图`}),(0,v.jsx)(f,{value:`diff`,className:`px-2 text-xs`,disabled:!Ne,children:`Diff 视图`})]})}),(0,v.jsx)(l,{variant:`outline`,className:`text-xs font-normal`,children:Y}),(0,v.jsx)(r,{size:`sm`,variant:`ghost`,onClick:X,disabled:L||C,children:L?(0,v.jsxs)(v.Fragment,{children:[(0,v.jsx)(m,{className:`h-4 w-4 mr-1 animate-spin`}),`读取中`]}):(0,v.jsxs)(v.Fragment,{children:[(0,v.jsx)(c,{className:`h-4 w-4 mr-1`}),`刷新代码`]})})]})]}),R?(0,v.jsx)(`div`,{className:`rounded-md border border-red-200 bg-red-50/80 p-3 text-sm text-red-700 dark:border-red-900 dark:bg-red-950/20 dark:text-red-300`,children:R}):Ae===`diff`&&Ne?(0,v.jsxs)(`div`,{className:`space-y-2`,children:[(0,v.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,v.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:`左侧是原代码,右侧是 AI 修复后的代码`}),W!==`idle`&&(0,v.jsx)(l,{variant:`outline`,className:`text-xs font-normal`,children:xe(W)})]}),(0,v.jsx)(_e,{original:F||N,modified:B||N,language:`javascript`,minHeight:`320px`})]}):(0,v.jsx)(ge,{value:C&&B?B:N,onChange:()=>{},language:`javascript`,readOnly:!0,minHeight:`260px`}),(0,v.jsxs)(`div`,{className:`space-y-2 pt-2`,children:[(0,v.jsx)(p,{htmlFor:`plugin-extra-instruction`,children:`额外信息`}),(0,v.jsx)(ve,{id:`plugin-extra-instruction`,value:U,onChange:e=>je(e.target.value),placeholder:`例如:补充 onBeforeResponse 里对 JSON 响应的判空逻辑;保留现有 hooks 和 manifest,不要改插件 id。`,className:`min-h-[88px]`,disabled:C||L}),(0,v.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,v.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`输入额外要求后,AI 会基于当前插件代码直接更新并热加载。`}),(0,v.jsx)(r,{size:`sm`,variant:`outline`,onClick:async()=>{if(!(!Y||!U.trim()||!J||C)){w(!0),M(null),V(``),I(N);try{G(`generating`);let e=await fetch(`/api/plugins/revise-stream`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({originalCode:N,instruction:U.trim(),requirement:{name:y,description:`根据额外要求更新插件 ${y},并保持 hooks 行为正确。Hooks: ${b.join(`, `)}`,hooks:b},aiConfig:Me})});if(!e.ok){let t=await e.json();throw Error(t.error||`AI 更新代码失败`)}let t=e.body?.getReader(),n=new TextDecoder;if(!t)throw Error(`无法读取 AI 更新流`);let r=``,i=``;for(;;){let{done:e,value:a}=await t.read();if(e)break;i+=n.decode(a,{stream:!0});let o=i.split(`
2
2
  `);i=o.pop()||``;for(let e of o){if(!e.startsWith(`data:`))continue;let t=e.slice(5).trim();if(t)try{let e=JSON.parse(t);if(e.status===`generating`)M({status:`success`,message:`AI 正在根据额外要求更新插件代码...`});else if(e.chunk)r=e.accumulated||`${r}${e.chunk}`,V(r),H(`diff`);else if(e.status===`success`)r=e.revisedCode||r,V(r),H(`diff`);else if(e.error)throw Error(e.error)}catch(e){if(e instanceof Error&&e.message!==`Unexpected end of JSON input`)throw e}}}if(!r||typeof r!=`string`)throw Error(`AI 未返回有效代码`);M({status:`success`,message:`AI 已生成更新后的代码,正在保存并热加载...`}),await Pe(r,`AI 已根据额外要求更新插件代码并完成热加载。`,!1),je(``)}catch(e){M({status:`error`,message:e instanceof Error?e.message:`AI 更新代码失败`})}finally{G(`idle`),w(!1)}}},disabled:!Y||!U.trim()||!J||C||L||!!R,children:C&&W!==`retesting`?(0,v.jsxs)(v.Fragment,{children:[(0,v.jsx)(m,{className:`h-4 w-4 mr-1 animate-spin`}),`AI 更新中...`]}):(0,v.jsxs)(v.Fragment,{children:[(0,v.jsx)(ee,{className:`h-4 w-4 mr-1`}),`根据额外信息更新代码`]})})]})]})]})]}),D&&(0,v.jsxs)(`div`,{className:`space-y-3`,children:[(0,v.jsx)(h,{}),D.error?(0,v.jsx)(`div`,{className:`bg-red-50 dark:bg-red-950/20 border border-red-200 dark:border-red-900 rounded-md p-3`,children:(0,v.jsxs)(`div`,{className:`flex items-start gap-2`,children:[(0,v.jsx)(s,{className:`h-4 w-4 text-red-600 mt-0.5 shrink-0`}),(0,v.jsx)(`span`,{className:`text-sm text-red-700 dark:text-red-300`,children:D.error})]})}):(0,v.jsxs)(v.Fragment,{children:[(0,v.jsxs)(`div`,{className:`flex flex-wrap gap-4 items-center rounded-md border bg-muted/20 px-3 py-2`,children:[(0,v.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,v.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`Header 对比`}),(0,v.jsx)(d,{value:k,onValueChange:e=>De(e),children:(0,v.jsxs)(u,{className:`h-7`,children:[(0,v.jsx)(f,{value:`split`,className:`px-2 text-xs`,children:`分栏`}),(0,v.jsx)(f,{value:`inline`,className:`px-2 text-xs`,children:`行内`})]})})]}),(0,v.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,v.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`Body 对比`}),(0,v.jsx)(d,{value:A,onValueChange:e=>Oe(e),children:(0,v.jsxs)(u,{className:`h-7`,children:[(0,v.jsx)(f,{value:`inline`,className:`px-2 text-xs`,children:`行内`}),(0,v.jsx)(f,{value:`split`,className:`px-2 text-xs`,children:`分栏`})]})})]})]}),D.realRequest&&(0,v.jsxs)(`div`,{className:`space-y-2`,children:[(0,v.jsxs)(`h3`,{className:`text-sm font-medium flex items-center gap-2`,children:[(0,v.jsx)(ce,{className:`h-4 w-4`}),`真实请求`,D.realRequest.testMode&&(0,v.jsx)(l,{variant:`outline`,className:`text-xs font-normal`,children:D.realRequest.testMode===`integrated`?`集成测试`:`单独测试`})]}),(0,v.jsxs)(`div`,{className:`bg-muted/50 rounded-md p-3 text-xs space-y-1`,children:[(0,v.jsxs)(`div`,{className:`flex gap-2`,children:[(0,v.jsx)(l,{variant:`outline`,className:`text-xs`,children:D.realRequest.method}),(0,v.jsx)(`span`,{className:`font-mono break-all`,children:D.realRequest.url})]}),D.realRequest.fetchError?(0,v.jsxs)(`div`,{className:`text-red-600 flex items-center gap-1 mt-1`,children:[(0,v.jsx)(s,{className:`h-3 w-3`}),`请求失败: `,D.realRequest.fetchError]}):(0,v.jsxs)(`div`,{className:`text-muted-foreground space-y-0.5`,children:[(0,v.jsxs)(`div`,{children:[`耗时: `,D.realRequest.fetchDuration,`ms`,D.originalResponse&&(0,v.jsxs)(v.Fragment,{children:[` · 状态码: `,(0,v.jsx)(l,{variant:`outline`,className:`text-xs`,children:D.originalResponse.statusCode}),` · 响应大小: `,D.originalResponse.bodyLength,` 字符`]})]}),(D.realRequest.targetResolved||D.realRequest.usedMock)&&(0,v.jsxs)(`div`,{className:`flex flex-wrap gap-1 mt-1`,children:[D.realRequest.targetResolved&&(0,v.jsx)(l,{variant:`outline`,className:`text-xs text-blue-600 border-blue-300`,children:`路由已改写`}),D.realRequest.usedMock&&(0,v.jsx)(l,{variant:`outline`,className:`text-xs text-orange-600 border-orange-300`,children:`已使用 Mock`})]})]})]})]}),(0,v.jsxs)(`div`,{className:`space-y-2`,children:[(0,v.jsxs)(`h3`,{className:`text-sm font-medium flex items-center gap-2`,children:[(0,v.jsx)(ae,{className:`h-4 w-4`}),`Hook 执行结果`]}),Object.keys(D.hookResults||{}).length===0?(0,v.jsx)(`div`,{className:`text-xs text-muted-foreground bg-muted/50 rounded-md p-3`,children:`没有 Hook 被执行`}):(0,v.jsx)(`div`,{className:`space-y-2`,children:Object.entries(D.hookResults||{}).map(([e,t])=>(0,v.jsxs)(`div`,{className:`border rounded-md p-3 ${t.status===`success`?`bg-green-50 dark:bg-green-950/20 border-green-200 dark:border-green-900`:`bg-red-50 dark:bg-red-950/20 border-red-200 dark:border-red-900`}`,children:[(0,v.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,v.jsxs)(`div`,{className:`flex items-center gap-2`,children:[t.status===`success`?(0,v.jsx)(se,{className:`h-4 w-4 text-green-600`}):(0,v.jsx)(s,{className:`h-4 w-4 text-red-600`}),(0,v.jsx)(`span`,{className:`font-medium text-sm`,children:e})]}),t.duration!==void 0&&(0,v.jsxs)(l,{variant:`outline`,className:`text-xs`,children:[t.duration,`ms`]})]}),t.status===`error`&&(0,v.jsxs)(`div`,{className:`mt-2 space-y-2`,children:[(0,v.jsxs)(`div`,{className:`rounded-md border border-red-200 bg-red-100/60 px-2 py-2 text-xs text-red-800 dark:border-red-900 dark:bg-red-950/20 dark:text-red-300`,children:[(0,v.jsx)(`div`,{className:`font-medium mb-1`,children:`错误原因`}),(0,v.jsx)(`pre`,{className:`font-mono whitespace-pre-wrap break-all`,children:t.error})]}),t.stack&&(0,v.jsxs)(`details`,{className:`rounded-md border border-red-200 bg-background/60 px-2 py-2 text-xs dark:border-red-900`,children:[(0,v.jsx)(`summary`,{className:`cursor-pointer text-red-700 dark:text-red-300`,children:`查看错误堆栈`}),(0,v.jsx)(`pre`,{className:`font-mono whitespace-pre-wrap break-all mt-2 text-muted-foreground`,children:t.stack})]})]}),t.targetChanged&&(0,v.jsxs)(`div`,{className:`text-xs text-blue-700 mt-1 flex items-center gap-1`,children:[(0,v.jsx)(a,{className:`h-3 w-3`}),`Target 已修改为: `,t.targetChanged]})]},e))})]}),Z.length>0&&(0,v.jsxs)(`div`,{className:`space-y-2`,children:[(0,v.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,v.jsxs)(`h3`,{className:`text-sm font-medium flex items-center gap-2`,children:[(0,v.jsx)(o,{className:`h-4 w-4 text-red-500`}),`错误详情`]}),(0,v.jsxs)(`div`,{className:`flex items-center gap-2`,children:[!J&&(0,v.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`AI 未配置,无法自动修复`}),(0,v.jsx)(r,{size:`sm`,variant:`outline`,onClick:async()=>{if(!(!Q||!J)){w(!0),M(null),V(``),I(N);try{G(`generating`);let e={code:N};if(!e.code)throw Error(`插件源码为空,无法修复`);let t=Z.map(e=>`Hook: ${e.hookName}\nError: ${e.message}${e.stack?`\nStack:\n${e.stack}`:``}`).join(`
3
3
 
4
4
  ---
@@ -1 +1 @@
1
- import{a as e,f as t,l as n,t as r,u as i}from"./button-BTToMaBW.js";import{t as a}from"./arrow-right-B4Mrlj2-.js";import{$ as o,B as s,G as c,a as l,ct as u,j as d,pt as f}from"./index-B-2u47xL.js";var p=n(`locate-fixed`,[[`line`,{x1:`2`,x2:`5`,y1:`12`,y2:`12`,key:`bvdh0s`}],[`line`,{x1:`19`,x2:`22`,y1:`12`,y2:`12`,key:`1tbv5k`}],[`line`,{x1:`12`,x2:`12`,y1:`2`,y2:`5`,key:`11lu5j`}],[`line`,{x1:`12`,x2:`12`,y1:`19`,y2:`22`,key:`x3vr5v`}],[`circle`,{cx:`12`,cy:`12`,r:`7`,key:`fim9np`}],[`circle`,{cx:`12`,cy:`12`,r:`3`,key:`1v7zrd`}]]),m=t(i(),1),h=e();function g({rules:e,activeFileName:t,embedded:n=!1,onRevealRule:i}){let[g,_]=(0,m.useState)(``),[v,y]=(0,m.useState)(!1),[b,x]=(0,m.useState)(null),[S,C]=(0,m.useState)(null),w=(0,m.useMemo)(()=>l(e),[e]),T=n?`global-route-preview-url`:`route-preview-url`;(0,m.useEffect)(()=>{if(!n)return;let e=window.requestAnimationFrame(()=>{document.getElementById(T)?.focus()});return()=>window.cancelAnimationFrame(e)},[n,T]);let E=(0,m.useCallback)(async()=>{let e=g.trim();if(!e){C(`请输入待预览的 URL`),x(null);return}y(!0),C(null);try{let t=await fetch(`/api/rules/preview`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({url:e,rulesText:w})}),n=await t.json();if(!t.ok)throw Error(n?.error||`预览失败`);x(n)}catch(e){x(null),C(e instanceof Error?e.message:`预览失败`)}finally{y(!1)}},[g,w]),D=(0,m.useCallback)(e=>{e.key===`Enter`&&E()},[E]);return(0,h.jsxs)(`div`,{className:n?`app-panel-content h-full`:`rounded-lg border bg-card p-4 space-y-3`,children:[(0,h.jsxs)(`div`,{className:`flex items-start justify-between gap-3`,children:[(0,h.jsxs)(`div`,{className:`space-y-1`,children:[(0,h.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,h.jsx)(o,{className:`h-4 w-4 text-primary`}),(0,h.jsx)(`h3`,{className:`text-sm font-semibold`,children:`URL 预览`})]}),(0,h.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`输入一个请求 URL,后端会用当前编辑中的规则直接计算真实转发地址。`})]}),t&&(0,h.jsxs)(s,{variant:`outline`,className:`text-[11px] font-normal`,children:[(0,h.jsx)(f,{className:`h-3 w-3 mr-1`}),t]})]}),(0,h.jsxs)(`div`,{className:`flex gap-2`,children:[(0,h.jsx)(d,{id:T,value:g,onChange:e=>_(e.target.value),onKeyDown:D,placeholder:`https://solution.wps.cn/docs/price/detail.html?source=navbar`,className:`h-9 font-mono text-xs`}),(0,h.jsx)(r,{onClick:E,disabled:v,className:`h-9 shrink-0`,children:v?(0,h.jsx)(u,{className:`h-4 w-4 animate-spin`}):`预览`})]}),n&&(0,h.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:`使用当前编辑区内尚未保存的规则进行计算,结果会与路由规则页的预览保持一致。`}),S&&(0,h.jsx)(`div`,{className:`rounded-md border border-amber-200 bg-amber-50 px-3 py-2 text-xs text-amber-800`,children:(0,h.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,h.jsx)(c,{className:`h-3.5 w-3.5 shrink-0`}),(0,h.jsx)(`span`,{children:S})]})}),b&&(0,h.jsxs)(`div`,{className:n?`min-h-0 flex-1 space-y-3 overflow-auto rounded-md border bg-muted/20 p-3`:`space-y-3 rounded-md border bg-muted/20 p-3`,children:[(0,h.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,h.jsx)(s,{className:b.matched?`bg-green-100 text-green-800 border-green-200`:`bg-blue-100 text-blue-800 border-blue-200`,children:b.matched?`已命中规则`:`未命中规则`}),b.matchedRule&&(0,h.jsx)(s,{variant:`outline`,className:`text-[11px] font-normal`,children:b.matchedRule.kind})]}),(0,h.jsxs)(`div`,{className:`space-y-1`,children:[(0,h.jsx)(`div`,{className:`text-[11px] uppercase tracking-wide text-muted-foreground`,children:`真实 URL`}),(0,h.jsx)(`div`,{className:`rounded-md border bg-background px-3 py-2 font-mono text-xs break-all`,children:b.resolvedUrl})]}),b.matchedRule&&(0,h.jsxs)(`div`,{className:`space-y-1`,children:[(0,h.jsx)(`div`,{className:`text-[11px] uppercase tracking-wide text-muted-foreground`,children:`命中规则`}),(0,h.jsxs)(`div`,{className:`flex items-stretch gap-2`,children:[(0,h.jsxs)(`div`,{className:`min-w-0 flex-1 rounded-md border bg-background px-3 py-2 font-mono text-xs break-all`,children:[b.matchedRule.pattern,(0,h.jsx)(`span`,{className:`text-muted-foreground`,children:` → `}),b.matchedRule.target]}),i&&(0,h.jsxs)(r,{type:`button`,variant:`outline`,size:`sm`,className:`h-auto shrink-0 gap-1.5 px-3 text-xs`,onClick:()=>b.matchedRule&&i(b.matchedRule),title:`在路由规则页面定位这条规则`,children:[(0,h.jsx)(p,{className:`h-3.5 w-3.5`}),`定位`]})]})]}),(0,h.jsxs)(`div`,{className:`space-y-1`,children:[(0,h.jsx)(`div`,{className:`text-[11px] uppercase tracking-wide text-muted-foreground`,children:`说明`}),(0,h.jsx)(`div`,{className:`space-y-1 rounded-md border bg-background px-3 py-2 text-xs`,children:b.notes.length>0?b.notes.map(e=>(0,h.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,h.jsx)(a,{className:`h-3 w-3 text-muted-foreground shrink-0`}),(0,h.jsx)(`span`,{children:e})]},e)):(0,h.jsx)(`span`,{className:`text-muted-foreground`,children:`无`})})]})]})]})}export{g as RoutePreview};
1
+ import{a as e,f as t,l as n,t as r,u as i}from"./button-BTToMaBW.js";import{t as a}from"./arrow-right-B4Mrlj2-.js";import{$ as o,B as s,G as c,a as l,ct as u,j as d,pt as f}from"./index-CvTR1IVi.js";var p=n(`locate-fixed`,[[`line`,{x1:`2`,x2:`5`,y1:`12`,y2:`12`,key:`bvdh0s`}],[`line`,{x1:`19`,x2:`22`,y1:`12`,y2:`12`,key:`1tbv5k`}],[`line`,{x1:`12`,x2:`12`,y1:`2`,y2:`5`,key:`11lu5j`}],[`line`,{x1:`12`,x2:`12`,y1:`19`,y2:`22`,key:`x3vr5v`}],[`circle`,{cx:`12`,cy:`12`,r:`7`,key:`fim9np`}],[`circle`,{cx:`12`,cy:`12`,r:`3`,key:`1v7zrd`}]]),m=t(i(),1),h=e();function g({rules:e,activeFileName:t,embedded:n=!1,onRevealRule:i}){let[g,_]=(0,m.useState)(``),[v,y]=(0,m.useState)(!1),[b,x]=(0,m.useState)(null),[S,C]=(0,m.useState)(null),w=(0,m.useMemo)(()=>l(e),[e]),T=n?`global-route-preview-url`:`route-preview-url`;(0,m.useEffect)(()=>{if(!n)return;let e=window.requestAnimationFrame(()=>{document.getElementById(T)?.focus()});return()=>window.cancelAnimationFrame(e)},[n,T]);let E=(0,m.useCallback)(async()=>{let e=g.trim();if(!e){C(`请输入待预览的 URL`),x(null);return}y(!0),C(null);try{let t=await fetch(`/api/rules/preview`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({url:e,rulesText:w})}),n=await t.json();if(!t.ok)throw Error(n?.error||`预览失败`);x(n)}catch(e){x(null),C(e instanceof Error?e.message:`预览失败`)}finally{y(!1)}},[g,w]),D=(0,m.useCallback)(e=>{e.key===`Enter`&&E()},[E]);return(0,h.jsxs)(`div`,{className:n?`app-panel-content h-full`:`rounded-lg border bg-card p-4 space-y-3`,children:[(0,h.jsxs)(`div`,{className:`flex items-start justify-between gap-3`,children:[(0,h.jsxs)(`div`,{className:`space-y-1`,children:[(0,h.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,h.jsx)(o,{className:`h-4 w-4 text-primary`}),(0,h.jsx)(`h3`,{className:`text-sm font-semibold`,children:`URL 预览`})]}),(0,h.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`输入一个请求 URL,后端会用当前编辑中的规则直接计算真实转发地址。`})]}),t&&(0,h.jsxs)(s,{variant:`outline`,className:`text-[11px] font-normal`,children:[(0,h.jsx)(f,{className:`h-3 w-3 mr-1`}),t]})]}),(0,h.jsxs)(`div`,{className:`flex gap-2`,children:[(0,h.jsx)(d,{id:T,value:g,onChange:e=>_(e.target.value),onKeyDown:D,placeholder:`https://solution.wps.cn/docs/price/detail.html?source=navbar`,className:`h-9 font-mono text-xs`}),(0,h.jsx)(r,{onClick:E,disabled:v,className:`h-9 shrink-0`,children:v?(0,h.jsx)(u,{className:`h-4 w-4 animate-spin`}):`预览`})]}),n&&(0,h.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:`使用当前编辑区内尚未保存的规则进行计算,结果会与路由规则页的预览保持一致。`}),S&&(0,h.jsx)(`div`,{className:`rounded-md border border-amber-200 bg-amber-50 px-3 py-2 text-xs text-amber-800`,children:(0,h.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,h.jsx)(c,{className:`h-3.5 w-3.5 shrink-0`}),(0,h.jsx)(`span`,{children:S})]})}),b&&(0,h.jsxs)(`div`,{className:n?`min-h-0 flex-1 space-y-3 overflow-auto rounded-md border bg-muted/20 p-3`:`space-y-3 rounded-md border bg-muted/20 p-3`,children:[(0,h.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,h.jsx)(s,{className:b.matched?`bg-green-100 text-green-800 border-green-200`:`bg-blue-100 text-blue-800 border-blue-200`,children:b.matched?`已命中规则`:`未命中规则`}),b.matchedRule&&(0,h.jsx)(s,{variant:`outline`,className:`text-[11px] font-normal`,children:b.matchedRule.kind})]}),(0,h.jsxs)(`div`,{className:`space-y-1`,children:[(0,h.jsx)(`div`,{className:`text-[11px] uppercase tracking-wide text-muted-foreground`,children:`真实 URL`}),(0,h.jsx)(`div`,{className:`rounded-md border bg-background px-3 py-2 font-mono text-xs break-all`,children:b.resolvedUrl})]}),b.matchedRule&&(0,h.jsxs)(`div`,{className:`space-y-1`,children:[(0,h.jsx)(`div`,{className:`text-[11px] uppercase tracking-wide text-muted-foreground`,children:`命中规则`}),(0,h.jsxs)(`div`,{className:`flex items-stretch gap-2`,children:[(0,h.jsxs)(`div`,{className:`min-w-0 flex-1 rounded-md border bg-background px-3 py-2 font-mono text-xs break-all`,children:[b.matchedRule.pattern,(0,h.jsx)(`span`,{className:`text-muted-foreground`,children:` → `}),b.matchedRule.target]}),i&&(0,h.jsxs)(r,{type:`button`,variant:`outline`,size:`sm`,className:`h-auto shrink-0 gap-1.5 px-3 text-xs`,onClick:()=>b.matchedRule&&i(b.matchedRule),title:`在路由规则页面定位这条规则`,children:[(0,h.jsx)(p,{className:`h-3.5 w-3.5`}),`定位`]})]})]}),(0,h.jsxs)(`div`,{className:`space-y-1`,children:[(0,h.jsx)(`div`,{className:`text-[11px] uppercase tracking-wide text-muted-foreground`,children:`说明`}),(0,h.jsx)(`div`,{className:`space-y-1 rounded-md border bg-background px-3 py-2 text-xs`,children:b.notes.length>0?b.notes.map(e=>(0,h.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,h.jsx)(a,{className:`h-3 w-3 text-muted-foreground shrink-0`}),(0,h.jsx)(`span`,{children:e})]},e)):(0,h.jsx)(`span`,{className:`text-muted-foreground`,children:`无`})})]})]})]})}export{g as RoutePreview};
@@ -1,4 +1,4 @@
1
- import{a as e,f as t,t as n,u as r}from"./button-BTToMaBW.js";import{t as i}from"./wand-sparkles-CJ7fSnom.js";import{i as a,o,r as s}from"./ai-config-store-C8D_PUGV.js";import{B as c,Z as l,a as u,ct as d,i as f}from"./index-B-2u47xL.js";import{n as p,t as m}from"./alert-DCvlZAiv.js";import{t as h}from"./textarea-BSI0rnW6.js";var g=t(r(),1);function _(e){return e.replace(/^```[a-z]*\n?/i,``).replace(/\n?```$/i,``).trim()}function v(){let e=s(),t=a(e);return t?{enabled:e.enabled,provider:t.provider,apiKey:t.apiKey,baseUrl:t.baseUrl,model:t.model}:e}function y(e,t){return{system:`你是 Meddle 的路由规则整理助手。你的任务是合并和精简用户的路由规则,在不改变语义的前提下尽量减少规则数量。
1
+ import{a as e,f as t,t as n,u as r}from"./button-BTToMaBW.js";import{t as i}from"./wand-sparkles-CJ7fSnom.js";import{i as a,o,r as s}from"./ai-config-store-C8D_PUGV.js";import{B as c,Z as l,a as u,ct as d,i as f}from"./index-CvTR1IVi.js";import{n as p,t as m}from"./alert-DCvlZAiv.js";import{t as h}from"./textarea-BSI0rnW6.js";var g=t(r(),1);function _(e){return e.replace(/^```[a-z]*\n?/i,``).replace(/\n?```$/i,``).trim()}function v(){let e=s(),t=a(e);return t?{enabled:e.enabled,provider:t.provider,apiKey:t.apiKey,baseUrl:t.baseUrl,model:t.model}:e}function y(e,t){return{system:`你是 Meddle 的路由规则整理助手。你的任务是合并和精简用户的路由规则,在不改变语义的前提下尽量减少规则数量。
2
2
 
3
3
  请严格遵守以下要求:
4
4
  1. 只输出最终规则文本,不要输出解释、标题、Markdown 代码块或额外说明。
@@ -44,4 +44,4 @@ ${e.trim()}
44
44
  ${t.trim()||`(empty)`}`}}async function x(e,t,n){let r=await fetch(e.baseUrl,{method:`POST`,headers:{"Content-Type":`application/json`,Authorization:`Bearer ${e.apiKey}`},body:JSON.stringify({model:e.model,messages:[{role:`system`,content:t},{role:`user`,content:n}],temperature:.1,max_tokens:3e3})});if(!r.ok)throw Error(`OpenAI API 错误 (${r.status}): ${await r.text()}`);let i=(await r.json()).choices?.[0]?.message?.content;if(!i||typeof i!=`string`)throw Error(`OpenAI 返回了空结果`);return _(i)}async function S(e,t,n){let r=await fetch(e.baseUrl,{method:`POST`,headers:{"Content-Type":`application/json`,"x-api-key":e.apiKey,"anthropic-version":`2023-06-01`},body:JSON.stringify({model:e.model,max_tokens:3e3,temperature:.1,system:t,messages:[{role:`user`,content:n}]})});if(!r.ok)throw Error(`Anthropic API 错误 (${r.status}): ${await r.text()}`);let i=(await r.json()).content?.[0]?.text;if(!i||typeof i!=`string`)throw Error(`Anthropic 返回了空结果`);return _(i)}async function C(e,t,n){let r=v();if(!o(r))throw Error(`AI 配置不可用,请先在设置中启用并配置可用模型`);let{system:i,user:a}=y(e,t),s=n?.trim()?`${a}
45
45
 
46
46
  额外优化要求:
47
- ${n.trim()}`:a;return r.provider===`anthropic`?S(r,i,s):x(r,i,s)}async function w(e,t,n){let r=v();if(!o(r))throw Error(`AI 配置不可用,请先在设置中启用并配置可用模型`);if(!e.trim())throw Error(`请输入用于生成规则的提示词`);let{system:i,user:a}=b(e,t,n);return r.provider===`anthropic`?S(r,i,a):x(r,i,a)}var T=e();function E({rules:e,setRules:t,ruleFiles:r,activeFileName:a,fetchRuleFileRawContent:o}){let[s,_]=(0,g.useState)(``),[v,y]=(0,g.useState)(!1),[b,x]=(0,g.useState)(!1),[S,E]=(0,g.useState)(null),[D,O]=(0,g.useState)(null),k=(0,g.useCallback)(async()=>Promise.all(r.filter(e=>e.enabled&&e.name!==a).map(async e=>({name:e.name,content:await o(e.name)}))),[a,o,r]),A=(0,g.useCallback)(async()=>{if(a){x(!0),E(null),O(null);try{let n=f(await w(s,u(e),await k()));if(n.length===0)throw Error(`AI 没有生成可用规则,请调整提示词后重试`);t(e=>[...n,...e]),E(`AI 已生成 ${n.length} 条规则,并追加到当前编辑区顶部。当前未自动保存。`)}catch(e){O(e instanceof Error?e.message:`AI 生成规则失败`)}finally{x(!1)}}},[a,k,s,e,t]),j=(0,g.useCallback)(async()=>{if(!(!a||e.length===0)){y(!0),E(null),O(null);try{let n=f(await C(u(e),await k(),s));if(e.length>0&&n.length===0)throw Error(`AI 返回的规则为空,请调整提示词或检查模型输出`);t(n),E(`AI 已完成规则合并:${e.length} 条 -> ${n.length} 条。当前仅替换编辑区,未自动保存。`)}catch(e){O(e instanceof Error?e.message:`AI 合并失败`)}finally{y(!1)}}},[a,k,s,e,t]),M=b||v;return(0,T.jsxs)(`div`,{className:`flex h-full min-h-0 flex-col`,children:[(0,T.jsxs)(`div`,{className:`app-panel-content`,children:[(0,T.jsxs)(`div`,{className:`flex flex-wrap gap-2 text-[11px] text-muted-foreground`,children:[(0,T.jsx)(`span`,{className:`rounded-full border bg-muted/40 px-2 py-1`,children:`支持通配符合并`}),(0,T.jsx)(`span`,{className:`rounded-full border bg-muted/40 px-2 py-1`,children:`可带额外优化提示词`}),(0,T.jsx)(`span`,{className:`rounded-full border bg-muted/40 px-2 py-1`,children:`结果写回当前编辑区`})]}),(0,T.jsx)(c,{variant:`outline`,className:`border-primary/20 bg-background/70 text-xs font-normal`,children:a?`当前文件:${a}`:`未选择规则文件`}),S&&(0,T.jsx)(m,{className:`border-green-200 bg-green-50/80 dark:border-green-900 dark:bg-green-950/20`,children:(0,T.jsx)(p,{children:S})}),D&&(0,T.jsx)(m,{variant:`destructive`,children:(0,T.jsx)(p,{children:D})}),(0,T.jsxs)(`div`,{className:`app-field-group`,children:[(0,T.jsx)(`div`,{className:`text-sm font-medium`,children:`AI 规则提示词`}),(0,T.jsx)(h,{value:s,onChange:e=>_(e.target.value),placeholder:`例如:将 wps.cn 域名都转发到 120.92.124.158 IP;或:优先使用通配符合并同一业务域名,不要把 openapi 相关域名并到 *.wps.cn。`,className:`min-h-[180px] bg-background`,disabled:M})]}),(0,T.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`这段提示词同时用于“AI 生成规则”和“AI 合并规则”。生成规则时必填;合并规则时可留空。`})]}),(0,T.jsx)(`div`,{className:`border-t p-4`,children:(0,T.jsxs)(`div`,{className:`flex flex-wrap justify-end gap-2`,children:[(0,T.jsxs)(n,{size:`sm`,onClick:A,disabled:!a||!s.trim()||M,children:[b?(0,T.jsx)(d,{className:`h-4 w-4 animate-spin`}):(0,T.jsx)(i,{className:`h-4 w-4`}),b?`AI 生成中...`:`AI 生成规则`]}),(0,T.jsxs)(n,{variant:`outline`,size:`sm`,onClick:j,disabled:!a||e.length===0||M,children:[v?(0,T.jsx)(d,{className:`h-4 w-4 animate-spin`}):(0,T.jsx)(l,{className:`h-4 w-4`}),v?`AI 合并中...`:`AI 合并规则`]})]})})]})}export{E as RuleAiAssistantPanel};
47
+ ${n.trim()}`:a;return r.provider===`anthropic`?S(r,i,s):x(r,i,s)}async function w(e,t,n){let r=v();if(!o(r))throw Error(`AI 配置不可用,请先在设置中启用并配置可用模型`);if(!e.trim())throw Error(`请输入用于生成规则的提示词`);let{system:i,user:a}=b(e,t,n);return r.provider===`anthropic`?S(r,i,a):x(r,i,a)}var T=e();function E({rules:e,setRules:t,ruleFiles:r,activeFileName:a,fetchRuleFileRawContent:o}){let[s,_]=(0,g.useState)(``),[v,y]=(0,g.useState)(!1),[b,x]=(0,g.useState)(!1),[S,E]=(0,g.useState)(null),[D,O]=(0,g.useState)(null),k=(0,g.useCallback)(async()=>Promise.all(r.filter(e=>e.enabled&&e.name!==a).map(async e=>({name:e.name,content:await o(e.name)}))),[a,o,r]),A=(0,g.useCallback)(async()=>{if(a){x(!0),E(null),O(null);try{let n=f(await w(s,u(e),await k()));if(n.length===0)throw Error(`AI 没有生成可用规则,请调整提示词后重试`);t(e=>[...n,...e]),E(`AI 已生成 ${n.length} 条规则,并追加到当前编辑区顶部。当前未自动保存。`)}catch(e){O(e instanceof Error?e.message:`AI 生成规则失败`)}finally{x(!1)}}},[a,k,s,e,t]),j=(0,g.useCallback)(async()=>{if(!(!a||e.length===0)){y(!0),E(null),O(null);try{let n=f(await C(u(e),await k(),s));if(e.length>0&&n.length===0)throw Error(`AI 返回的规则为空,请调整提示词或检查模型输出`);t(n),E(`AI 已完成规则合并:${e.length} 条 -> ${n.length} 条。当前仅替换编辑区,未自动保存。`)}catch(e){O(e instanceof Error?e.message:`AI 合并失败`)}finally{y(!1)}}},[a,k,s,e,t]),M=b||v;return(0,T.jsxs)(`div`,{className:`flex h-full min-h-0 flex-col`,children:[(0,T.jsxs)(`div`,{className:`app-panel-content`,children:[(0,T.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[(0,T.jsx)(c,{variant:`secondary`,className:`bg-muted/40 text-[11px] font-normal text-muted-foreground`,children:`支持通配符合并`}),(0,T.jsx)(c,{variant:`secondary`,className:`bg-muted/40 text-[11px] font-normal text-muted-foreground`,children:`可带额外优化提示词`}),(0,T.jsx)(c,{variant:`secondary`,className:`bg-muted/40 text-[11px] font-normal text-muted-foreground`,children:`结果写回当前编辑区`})]}),(0,T.jsx)(c,{variant:`outline`,className:`border-primary/20 bg-background/70 text-xs font-normal`,children:a?`当前文件:${a}`:`未选择规则文件`}),S&&(0,T.jsx)(m,{className:`border-green-200 bg-green-50/80 dark:border-green-900 dark:bg-green-950/20`,children:(0,T.jsx)(p,{children:S})}),D&&(0,T.jsx)(m,{variant:`destructive`,children:(0,T.jsx)(p,{children:D})}),(0,T.jsxs)(`div`,{className:`app-field-group`,children:[(0,T.jsx)(`div`,{className:`text-sm font-medium`,children:`AI 规则提示词`}),(0,T.jsx)(h,{value:s,onChange:e=>_(e.target.value),placeholder:`例如:将 wps.cn 域名都转发到 120.92.124.158 IP;或:优先使用通配符合并同一业务域名,不要把 openapi 相关域名并到 *.wps.cn。`,className:`min-h-[180px] bg-background`,disabled:M})]}),(0,T.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`这段提示词同时用于“AI 生成规则”和“AI 合并规则”。生成规则时必填;合并规则时可留空。`})]}),(0,T.jsx)(`div`,{className:`border-t p-4`,children:(0,T.jsxs)(`div`,{className:`flex flex-wrap justify-end gap-2`,children:[(0,T.jsxs)(n,{size:`sm`,onClick:A,disabled:!a||!s.trim()||M,children:[b?(0,T.jsx)(d,{className:`h-4 w-4 animate-spin`}):(0,T.jsx)(i,{className:`h-4 w-4`}),b?`AI 生成中...`:`AI 生成规则`]}),(0,T.jsxs)(n,{variant:`outline`,size:`sm`,onClick:j,disabled:!a||e.length===0||M,children:[v?(0,T.jsx)(d,{className:`h-4 w-4 animate-spin`}):(0,T.jsx)(l,{className:`h-4 w-4`}),v?`AI 合并中...`:`AI 合并规则`]})]})})]})}export{E as RuleAiAssistantPanel};
@@ -1,4 +1,4 @@
1
- import{a as e,d as t,f as n,l as r,n as i,t as a,u as o}from"./button-BTToMaBW.js";import{c as s}from"./dist-C6eaYCUo.js";import{n as c,t as l}from"./checkbox-DqL9h3Nm.js";import{t as u}from"./plus-tVxSydJ8.js";import{t as d}from"./table-2-BR5e3z8m.js";import{a as f,c as p,i as m,n as h,o as g,r as _,s as v,t as y}from"./dist-C8RHq5At.js";import"./es2015-DG46NGN7.js";import{A as b,B as x,F as S,K as C,L as w,N as T,R as E,S as D,U as O,V as k,W as A,a as j,ct as M,d as N,et as P,f as F,ft as I,i as L,j as R,k as ee,n as z,p as te,r as B,u as ne,ut as V,vt as re,z as ie}from"./index-B-2u47xL.js";import{r as ae}from"./syntax-highlight-Dk0-ewLI.js";import{a as oe,i as se,n as ce,o as le,r as H,t as ue}from"./table-nW7uQVcl.js";import{t as de}from"./file-system-access-_og-Tg9o.js";var fe=r(`arrow-up-to-line`,[[`path`,{d:`M5 3h14`,key:`7usisc`}],[`path`,{d:`m18 13-6-6-6 6`,key:`1kf1n9`}],[`path`,{d:`M12 7v14`,key:`1akyts`}]]),pe=r(`clipboard-paste`,[[`path`,{d:`M11 14h10`,key:`1w8e9d`}],[`path`,{d:`M16 4h2a2 2 0 0 1 2 2v1.344`,key:`1e62lh`}],[`path`,{d:`m17 18 4-4-4-4`,key:`z2g111`}],[`path`,{d:`M8 4H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 1.793-1.113`,key:`bjbb7m`}],[`rect`,{x:`8`,y:`2`,width:`8`,height:`4`,rx:`1`,key:`ublpy`}]]),me=r(`file-code-corner`,[[`path`,{d:`M4 12.15V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.706.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2h-3.35`,key:`1wthlu`}],[`path`,{d:`M14 2v5a1 1 0 0 0 1 1h5`,key:`wfsgrz`}],[`path`,{d:`m5 16-3 3 3 3`,key:`331omg`}],[`path`,{d:`m9 22 3-3-3-3`,key:`lsp7cz`}]]),he=r(`folder-open`,[[`path`,{d:`m6 14 1.5-2.9A2 2 0 0 1 9.24 10H20a2 2 0 0 1 1.94 2.5l-1.54 6a2 2 0 0 1-1.95 1.5H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H18a2 2 0 0 1 2 2v2`,key:`usdka0`}]]),ge=r(`git-branch`,[[`line`,{x1:`6`,x2:`6`,y1:`3`,y2:`15`,key:`17qcm7`}],[`circle`,{cx:`18`,cy:`6`,r:`3`,key:`1h7g24`}],[`circle`,{cx:`6`,cy:`18`,r:`3`,key:`fqmcym`}],[`path`,{d:`M18 9a9 9 0 0 1-9 9`,key:`n2h4wq`}]]),_e=r(`toggle-left`,[[`circle`,{cx:`9`,cy:`12`,r:`3`,key:`u3jwor`}],[`rect`,{width:`20`,height:`14`,x:`2`,y:`5`,rx:`7`,key:`g7kal2`}]]),ve=r(`toggle-right`,[[`circle`,{cx:`15`,cy:`12`,r:`3`,key:`1afu0r`}],[`rect`,{width:`20`,height:`14`,x:`2`,y:`5`,rx:`7`,key:`g7kal2`}]]),ye=t((e=>{var t=o();function n(e,t){return e===t&&(e!==0||1/e==1/t)||e!==e&&t!==t}var r=typeof Object.is==`function`?Object.is:n,i=t.useState,a=t.useEffect,s=t.useLayoutEffect,c=t.useDebugValue;function l(e,t){var n=t(),r=i({inst:{value:n,getSnapshot:t}}),o=r[0].inst,l=r[1];return s(function(){o.value=n,o.getSnapshot=t,u(o)&&l({inst:o})},[e,n,t]),a(function(){return u(o)&&l({inst:o}),e(function(){u(o)&&l({inst:o})})},[e]),c(n),n}function u(e){var t=e.getSnapshot;e=e.value;try{var n=t();return!r(e,n)}catch{return!0}}function d(e,t){return t()}var f=typeof window>`u`||window.document===void 0||window.document.createElement===void 0?d:l;e.useSyncExternalStore=t.useSyncExternalStore===void 0?f:t.useSyncExternalStore})),be=t(((e,t)=>{t.exports=ye()})),U=n(o()),W=e();function xe({className:e,...t}){return(0,W.jsx)(M,{role:`status`,"aria-label":`Loading`,className:i(`size-4 animate-spin`,e),...t})}var Se=n(s());function Ce(){var e=[...arguments];return(0,U.useMemo)(()=>t=>{e.forEach(e=>e(t))},e)}var we=typeof window<`u`&&window.document!==void 0&&window.document.createElement!==void 0;function Te(e){let t=Object.prototype.toString.call(e);return t===`[object Window]`||t===`[object global]`}function Ee(e){return`nodeType`in e}function G(e){return e?Te(e)?e:Ee(e)?e.ownerDocument?.defaultView??window:window:window}function De(e){let{Document:t}=G(e);return e instanceof t}function Oe(e){return Te(e)?!1:e instanceof G(e).HTMLElement}function ke(e){return e instanceof G(e).SVGElement}function Ae(e){return e?Te(e)?e.document:Ee(e)?De(e)?e:Oe(e)||ke(e)?e.ownerDocument:document:document:document}var je=we?U.useLayoutEffect:U.useEffect;function Me(e){let t=(0,U.useRef)(e);return je(()=>{t.current=e}),(0,U.useCallback)(function(){var e=[...arguments];return t.current==null?void 0:t.current(...e)},[])}function Ne(){let e=(0,U.useRef)(null);return[(0,U.useCallback)((t,n)=>{e.current=setInterval(t,n)},[]),(0,U.useCallback)(()=>{e.current!==null&&(clearInterval(e.current),e.current=null)},[])]}function Pe(e,t){t===void 0&&(t=[e]);let n=(0,U.useRef)(e);return je(()=>{n.current!==e&&(n.current=e)},t),n}function Fe(e,t){let n=(0,U.useRef)();return(0,U.useMemo)(()=>{let t=e(n.current);return n.current=t,t},[...t])}function Ie(e){let t=Me(e),n=(0,U.useRef)(null);return[n,(0,U.useCallback)(e=>{e!==n.current&&t?.(e,n.current),n.current=e},[])]}function Le(e){let t=(0,U.useRef)();return(0,U.useEffect)(()=>{t.current=e},[e]),t.current}var Re={};function ze(e,t){return(0,U.useMemo)(()=>{if(t)return t;let n=Re[e]==null?0:Re[e]+1;return Re[e]=n,e+`-`+n},[e,t])}function Be(e){return function(t){return[...arguments].slice(1).reduce((t,n)=>{let r=Object.entries(n);for(let[n,i]of r){let r=t[n];r!=null&&(t[n]=r+e*i)}return t},{...t})}}var Ve=Be(1),He=Be(-1);function Ue(e){return`clientX`in e&&`clientY`in e}function We(e){if(!e)return!1;let{KeyboardEvent:t}=G(e.target);return t&&e instanceof t}function Ge(e){if(!e)return!1;let{TouchEvent:t}=G(e.target);return t&&e instanceof t}function Ke(e){if(Ge(e)){if(e.touches&&e.touches.length){let{clientX:t,clientY:n}=e.touches[0];return{x:t,y:n}}else if(e.changedTouches&&e.changedTouches.length){let{clientX:t,clientY:n}=e.changedTouches[0];return{x:t,y:n}}}return Ue(e)?{x:e.clientX,y:e.clientY}:null}var qe=Object.freeze({Translate:{toString(e){if(!e)return;let{x:t,y:n}=e;return`translate3d(`+(t?Math.round(t):0)+`px, `+(n?Math.round(n):0)+`px, 0)`}},Scale:{toString(e){if(!e)return;let{scaleX:t,scaleY:n}=e;return`scaleX(`+t+`) scaleY(`+n+`)`}},Transform:{toString(e){if(e)return[qe.Translate.toString(e),qe.Scale.toString(e)].join(` `)}},Transition:{toString(e){let{property:t,duration:n,easing:r}=e;return t+` `+n+`ms `+r}}}),Je=`a,frame,iframe,input:not([type=hidden]):not(:disabled),select:not(:disabled),textarea:not(:disabled),button:not(:disabled),*[tabindex]`;function Ye(e){return e.matches(Je)?e:e.querySelector(Je)}var Xe={display:`none`};function Ze(e){let{id:t,value:n}=e;return U.createElement(`div`,{id:t,style:Xe},n)}function Qe(e){let{id:t,announcement:n,ariaLiveType:r=`assertive`}=e;return U.createElement(`div`,{id:t,style:{position:`fixed`,top:0,left:0,width:1,height:1,margin:-1,border:0,padding:0,overflow:`hidden`,clip:`rect(0 0 0 0)`,clipPath:`inset(100%)`,whiteSpace:`nowrap`},role:`status`,"aria-live":r,"aria-atomic":!0},n)}function $e(){let[e,t]=(0,U.useState)(``);return{announce:(0,U.useCallback)(e=>{e!=null&&t(e)},[]),announcement:e}}var et=(0,U.createContext)(null);function tt(e){let t=(0,U.useContext)(et);(0,U.useEffect)(()=>{if(!t)throw Error(`useDndMonitor must be used within a children of <DndContext>`);return t(e)},[e,t])}function nt(){let[e]=(0,U.useState)(()=>new Set),t=(0,U.useCallback)(t=>(e.add(t),()=>e.delete(t)),[e]);return[(0,U.useCallback)(t=>{let{type:n,event:r}=t;e.forEach(e=>e[n]?.call(e,r))},[e]),t]}var rt={draggable:`
1
+ import{a as e,d as t,f as n,l as r,n as i,t as a,u as o}from"./button-BTToMaBW.js";import{c as s}from"./dist-C6eaYCUo.js";import{n as c,t as l}from"./checkbox-D1Z9DtjF.js";import{t as u}from"./plus-tVxSydJ8.js";import{t as d}from"./table-2-BR5e3z8m.js";import{a as f,c as p,i as m,n as h,o as g,r as _,s as v,t as y}from"./dist-C8RHq5At.js";import"./es2015-DG46NGN7.js";import{A as b,B as x,F as S,K as C,L as w,N as T,R as E,S as D,U as O,V as k,W as A,a as j,ct as M,d as N,et as P,f as F,ft as I,i as L,j as R,k as ee,n as z,p as te,r as B,u as ne,ut as V,vt as re,z as ie}from"./index-CvTR1IVi.js";import{r as ae}from"./syntax-highlight-Dk0-ewLI.js";import{a as oe,i as se,n as ce,o as le,r as H,t as ue}from"./table-nW7uQVcl.js";import{t as de}from"./file-system-access-_og-Tg9o.js";var fe=r(`arrow-up-to-line`,[[`path`,{d:`M5 3h14`,key:`7usisc`}],[`path`,{d:`m18 13-6-6-6 6`,key:`1kf1n9`}],[`path`,{d:`M12 7v14`,key:`1akyts`}]]),pe=r(`clipboard-paste`,[[`path`,{d:`M11 14h10`,key:`1w8e9d`}],[`path`,{d:`M16 4h2a2 2 0 0 1 2 2v1.344`,key:`1e62lh`}],[`path`,{d:`m17 18 4-4-4-4`,key:`z2g111`}],[`path`,{d:`M8 4H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 1.793-1.113`,key:`bjbb7m`}],[`rect`,{x:`8`,y:`2`,width:`8`,height:`4`,rx:`1`,key:`ublpy`}]]),me=r(`file-code-corner`,[[`path`,{d:`M4 12.15V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.706.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2h-3.35`,key:`1wthlu`}],[`path`,{d:`M14 2v5a1 1 0 0 0 1 1h5`,key:`wfsgrz`}],[`path`,{d:`m5 16-3 3 3 3`,key:`331omg`}],[`path`,{d:`m9 22 3-3-3-3`,key:`lsp7cz`}]]),he=r(`folder-open`,[[`path`,{d:`m6 14 1.5-2.9A2 2 0 0 1 9.24 10H20a2 2 0 0 1 1.94 2.5l-1.54 6a2 2 0 0 1-1.95 1.5H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H18a2 2 0 0 1 2 2v2`,key:`usdka0`}]]),ge=r(`git-branch`,[[`line`,{x1:`6`,x2:`6`,y1:`3`,y2:`15`,key:`17qcm7`}],[`circle`,{cx:`18`,cy:`6`,r:`3`,key:`1h7g24`}],[`circle`,{cx:`6`,cy:`18`,r:`3`,key:`fqmcym`}],[`path`,{d:`M18 9a9 9 0 0 1-9 9`,key:`n2h4wq`}]]),_e=r(`toggle-left`,[[`circle`,{cx:`9`,cy:`12`,r:`3`,key:`u3jwor`}],[`rect`,{width:`20`,height:`14`,x:`2`,y:`5`,rx:`7`,key:`g7kal2`}]]),ve=r(`toggle-right`,[[`circle`,{cx:`15`,cy:`12`,r:`3`,key:`1afu0r`}],[`rect`,{width:`20`,height:`14`,x:`2`,y:`5`,rx:`7`,key:`g7kal2`}]]),ye=t((e=>{var t=o();function n(e,t){return e===t&&(e!==0||1/e==1/t)||e!==e&&t!==t}var r=typeof Object.is==`function`?Object.is:n,i=t.useState,a=t.useEffect,s=t.useLayoutEffect,c=t.useDebugValue;function l(e,t){var n=t(),r=i({inst:{value:n,getSnapshot:t}}),o=r[0].inst,l=r[1];return s(function(){o.value=n,o.getSnapshot=t,u(o)&&l({inst:o})},[e,n,t]),a(function(){return u(o)&&l({inst:o}),e(function(){u(o)&&l({inst:o})})},[e]),c(n),n}function u(e){var t=e.getSnapshot;e=e.value;try{var n=t();return!r(e,n)}catch{return!0}}function d(e,t){return t()}var f=typeof window>`u`||window.document===void 0||window.document.createElement===void 0?d:l;e.useSyncExternalStore=t.useSyncExternalStore===void 0?f:t.useSyncExternalStore})),be=t(((e,t)=>{t.exports=ye()})),U=n(o()),W=e();function xe({className:e,...t}){return(0,W.jsx)(M,{role:`status`,"aria-label":`Loading`,className:i(`size-4 animate-spin`,e),...t})}var Se=n(s());function Ce(){var e=[...arguments];return(0,U.useMemo)(()=>t=>{e.forEach(e=>e(t))},e)}var we=typeof window<`u`&&window.document!==void 0&&window.document.createElement!==void 0;function Te(e){let t=Object.prototype.toString.call(e);return t===`[object Window]`||t===`[object global]`}function Ee(e){return`nodeType`in e}function G(e){return e?Te(e)?e:Ee(e)?e.ownerDocument?.defaultView??window:window:window}function De(e){let{Document:t}=G(e);return e instanceof t}function Oe(e){return Te(e)?!1:e instanceof G(e).HTMLElement}function ke(e){return e instanceof G(e).SVGElement}function Ae(e){return e?Te(e)?e.document:Ee(e)?De(e)?e:Oe(e)||ke(e)?e.ownerDocument:document:document:document}var je=we?U.useLayoutEffect:U.useEffect;function Me(e){let t=(0,U.useRef)(e);return je(()=>{t.current=e}),(0,U.useCallback)(function(){var e=[...arguments];return t.current==null?void 0:t.current(...e)},[])}function Ne(){let e=(0,U.useRef)(null);return[(0,U.useCallback)((t,n)=>{e.current=setInterval(t,n)},[]),(0,U.useCallback)(()=>{e.current!==null&&(clearInterval(e.current),e.current=null)},[])]}function Pe(e,t){t===void 0&&(t=[e]);let n=(0,U.useRef)(e);return je(()=>{n.current!==e&&(n.current=e)},t),n}function Fe(e,t){let n=(0,U.useRef)();return(0,U.useMemo)(()=>{let t=e(n.current);return n.current=t,t},[...t])}function Ie(e){let t=Me(e),n=(0,U.useRef)(null);return[n,(0,U.useCallback)(e=>{e!==n.current&&t?.(e,n.current),n.current=e},[])]}function Le(e){let t=(0,U.useRef)();return(0,U.useEffect)(()=>{t.current=e},[e]),t.current}var Re={};function ze(e,t){return(0,U.useMemo)(()=>{if(t)return t;let n=Re[e]==null?0:Re[e]+1;return Re[e]=n,e+`-`+n},[e,t])}function Be(e){return function(t){return[...arguments].slice(1).reduce((t,n)=>{let r=Object.entries(n);for(let[n,i]of r){let r=t[n];r!=null&&(t[n]=r+e*i)}return t},{...t})}}var Ve=Be(1),He=Be(-1);function Ue(e){return`clientX`in e&&`clientY`in e}function We(e){if(!e)return!1;let{KeyboardEvent:t}=G(e.target);return t&&e instanceof t}function Ge(e){if(!e)return!1;let{TouchEvent:t}=G(e.target);return t&&e instanceof t}function Ke(e){if(Ge(e)){if(e.touches&&e.touches.length){let{clientX:t,clientY:n}=e.touches[0];return{x:t,y:n}}else if(e.changedTouches&&e.changedTouches.length){let{clientX:t,clientY:n}=e.changedTouches[0];return{x:t,y:n}}}return Ue(e)?{x:e.clientX,y:e.clientY}:null}var qe=Object.freeze({Translate:{toString(e){if(!e)return;let{x:t,y:n}=e;return`translate3d(`+(t?Math.round(t):0)+`px, `+(n?Math.round(n):0)+`px, 0)`}},Scale:{toString(e){if(!e)return;let{scaleX:t,scaleY:n}=e;return`scaleX(`+t+`) scaleY(`+n+`)`}},Transform:{toString(e){if(e)return[qe.Translate.toString(e),qe.Scale.toString(e)].join(` `)}},Transition:{toString(e){let{property:t,duration:n,easing:r}=e;return t+` `+n+`ms `+r}}}),Je=`a,frame,iframe,input:not([type=hidden]):not(:disabled),select:not(:disabled),textarea:not(:disabled),button:not(:disabled),*[tabindex]`;function Ye(e){return e.matches(Je)?e:e.querySelector(Je)}var Xe={display:`none`};function Ze(e){let{id:t,value:n}=e;return U.createElement(`div`,{id:t,style:Xe},n)}function Qe(e){let{id:t,announcement:n,ariaLiveType:r=`assertive`}=e;return U.createElement(`div`,{id:t,style:{position:`fixed`,top:0,left:0,width:1,height:1,margin:-1,border:0,padding:0,overflow:`hidden`,clip:`rect(0 0 0 0)`,clipPath:`inset(100%)`,whiteSpace:`nowrap`},role:`status`,"aria-live":r,"aria-atomic":!0},n)}function $e(){let[e,t]=(0,U.useState)(``);return{announce:(0,U.useCallback)(e=>{e!=null&&t(e)},[]),announcement:e}}var et=(0,U.createContext)(null);function tt(e){let t=(0,U.useContext)(et);(0,U.useEffect)(()=>{if(!t)throw Error(`useDndMonitor must be used within a children of <DndContext>`);return t(e)},[e,t])}function nt(){let[e]=(0,U.useState)(()=>new Set),t=(0,U.useCallback)(t=>(e.add(t),()=>e.delete(t)),[e]);return[(0,U.useCallback)(t=>{let{type:n,event:r}=t;e.forEach(e=>e[n]?.call(e,r))},[e]),t]}var rt={draggable:`
2
2
  To pick up a draggable item, press the space bar.
3
3
  While dragging, use the arrow keys to move the item.
4
4
  Press space again to drop the item in its new position, or press escape to cancel.
@@ -11,5 +11,5 @@ import{a as e,d as t,f as n,l as r,n as i,t as a,u as o}from"./button-BTToMaBW.j
11
11
  M${w.x},${w.y}h${w.width}v${w.height}h${-w.width}z`,fillRule:`evenodd`,pointerEvents:`none`})]})})}rg.displayName=`MiniMap`,(0,U.memo)(rg);var ig=e=>t=>e?`${Math.max(1/t.transform[2],1)}`:void 0,ag={[sf.Line]:`right`,[sf.Handle]:`bottom-right`};function og({nodeId:e,position:t,variant:n=sf.Handle,className:r,style:i=void 0,children:a,color:o,minWidth:s=10,minHeight:c=10,maxWidth:l=Number.MAX_VALUE,maxHeight:u=Number.MAX_VALUE,keepAspectRatio:d=!1,resizeDirection:f,autoScale:p=!0,shouldResize:m,onResizeStart:h,onResize:g,onResizeEnd:_}){let v=Kp(),y=typeof e==`string`?e:v,b=$(),x=(0,U.useRef)(null),S=n===sf.Handle,C=Q((0,U.useCallback)(ig(S&&p),[S,p]),Z),w=(0,U.useRef)(null),T=t??ag[n];return(0,U.useEffect)(()=>{if(!(!x.current||!y))return w.current||=yf({domNode:x.current,nodeId:y,getStoreItems:()=>{let{nodeLookup:e,transform:t,snapGrid:n,snapToGrid:r,nodeOrigin:i,domNode:a}=b.getState();return{nodeLookup:e,transform:t,snapGrid:n,snapToGrid:r,nodeOrigin:i,paneDomNode:a}},onChange:(e,t)=>{let{triggerNodeChanges:n,nodeLookup:r,parentLookup:i,nodeOrigin:a}=b.getState(),o=[],s={x:e.x,y:e.y},c=r.get(y);if(c&&c.expandParent&&c.parentId){let t=c.origin??a,n=e.width??c.measured.width??0,l=e.height??c.measured.height??0,u=wd([{id:c.id,parentId:c.parentId,rect:{width:n,height:l,...ku({x:e.x??c.position.x,y:e.y??c.position.y},{width:n,height:l},c.parentId,r,t)}}],r,i,a);o.push(...u),s.x=e.x?Math.max(t[0]*n,e.x):void 0,s.y=e.y?Math.max(t[1]*l,e.y):void 0}if(s.x!==void 0&&s.y!==void 0){let e={id:y,type:`position`,position:{...s}};o.push(e)}if(e.width!==void 0&&e.height!==void 0){let t={id:y,type:`dimensions`,resizing:!0,setAttributes:f?f===`horizontal`?`width`:`height`:!0,dimensions:{width:e.width,height:e.height}};o.push(t)}for(let e of t){let t={...e,type:`position`};o.push(t)}n(o)},onEnd:({width:e,height:t})=>{let n={id:y,type:`dimensions`,resizing:!1,dimensions:{width:e,height:t}};b.getState().triggerNodeChanges([n])}}),w.current.update({controlPosition:T,boundaries:{minWidth:s,minHeight:c,maxWidth:l,maxHeight:u},keepAspectRatio:d,resizeDirection:f,onResizeStart:h,onResize:g,onResizeEnd:_,shouldResize:m}),()=>{w.current?.destroy()}},[T,s,c,l,u,d,h,g,_,m]),(0,W.jsx)(`div`,{className:Y([`react-flow__resize-control`,`nodrag`,...T.split(`-`),n,r]),ref:x,style:{...i,scale:C,...o&&{[S?`backgroundColor`:`borderColor`]:o}},children:a})}(0,U.memo)(og);var sg=28,cg=470,lg=24,ug=64,dg=268,fg=84,pg=264,mg=16,hg=52,gg=360,_g=28,vg=56;function yg(e){let t=e.entries.length*ug+Math.max(0,e.entries.length-1)*mg;return Math.max(t,fg)}function bg(e,t){return{id:`source:${e.id}`,type:`routeSource`,position:{x:sg,y:t},draggable:!1,selectable:!1,data:{label:e.rule||`未填写规则`,enabledOrder:e.enabledOrder,marker:e.marker},style:{width:dg,height:ug}}}function xg(e,t){return{id:`target:${e.key}`,type:`routeTarget`,position:{x:cg,y:t},draggable:!1,selectable:!1,data:{label:e.targetMeta.displayTarget,targetKind:e.targetMeta.kind},style:{width:pg,height:fg}}}function Sg(e,t){return{id:`edge:${e.id}:${t.key}`,source:`source:${e.id}`,target:`target:${t.key}`,type:`routeBranch`,animated:e.enabled,selectable:!1,focusable:!1,data:{branchX:cg-vg,direct:t.entries.length===1},style:{stroke:e.enabled?`var(--color-primary)`:`var(--color-border)`,strokeWidth:e.enabled?2.2:1.3,opacity:e.enabled?.95:.45},markerEnd:{type:Hl.ArrowClosed,width:16,height:16,color:e.enabled?`var(--color-primary)`:`var(--color-border)`}}}function Cg(e){let t=[],n=[],r=lg;return e.groups.forEach(e=>{let i=e.entries.length*ug+Math.max(0,e.entries.length-1)*mg,a=yg(e),o=r+Math.max(0,(a-i)/2),s=r+Math.max(0,(a-fg)/2);t.push(xg(e,s)),e.entries.forEach((r,i)=>{let a=o+i*(ug+mg);t.push(bg(r,a)),n.push(Sg(r,e))}),r+=a+hg}),{nodes:t,edges:n,canvasHeight:Math.max(gg,r-hg+_g)}}var wg={empty:`未配置`,file:`本地文件`,"absolute-url":`完整 URL`,host:`主机转发`};function Tg({data:e}){let t=e.enabledOrder!=null;return(0,W.jsxs)(`div`,{className:i(`route-canvas-node flex h-full flex-col justify-center rounded-2xl border px-3.5 py-2.5 shadow-sm`,t?`border-border bg-card`:`border-dashed border-border/80 bg-muted/35 opacity-85`),children:[(0,W.jsx)(Xp,{type:`source`,position:X.Right,isConnectable:!1,className:`route-canvas-handle`}),(0,W.jsxs)(`div`,{className:`flex items-center gap-2 flex-wrap`,children:[(0,W.jsx)(x,{variant:t?`default`:`secondary`,className:`font-mono`,children:e.enabledOrder==null?`停用`:`#${e.enabledOrder}`}),(0,W.jsx)(`span`,{className:`text-[13px] font-medium break-all`,children:e.label})]}),e.marker&&(0,W.jsx)(`div`,{className:`mt-1.5 text-[10px] text-muted-foreground`,children:`[${e.marker}]`})]})}function Eg({data:e}){return(0,W.jsxs)(`div`,{className:i(`route-canvas-node flex h-full items-center rounded-[22px] border px-4 py-3 shadow-[0_18px_45px_rgba(15,23,42,0.08)]`,`border-primary/20 bg-primary/6`),children:[(0,W.jsx)(Xp,{type:`target`,position:X.Left,isConnectable:!1,className:`route-canvas-handle`}),(0,W.jsx)(`div`,{className:`flex items-center gap-3`,children:(0,W.jsxs)(`div`,{className:`min-w-0`,children:[(0,W.jsx)(`div`,{className:`flex items-center gap-2`,children:(0,W.jsx)(x,{variant:`outline`,children:wg[e.targetKind]})}),(0,W.jsx)(`div`,{className:`mt-2 text-[14px] font-semibold break-all leading-5`,children:e.label})]})})]})}function Dg({sourceX:e,sourceY:t,targetX:n,targetY:r,markerEnd:i,style:a,data:o}){let s=o,c=s?.branchX??e+72;return(0,W.jsx)(Am,{path:s?.direct?`M ${e} ${t} L ${n} ${t}`:`M ${e} ${t} L ${c} ${t} L ${c} ${r} L ${n} ${r}`,markerEnd:i,style:a})}var Og={routeSource:Tg,routeTarget:Eg},kg={routeBranch:Dg};function Ag({graphData:e}){let{nodes:t,edges:n,canvasHeight:r}=(0,U.useMemo)(()=>Cg(e),[e]);return(0,W.jsx)(`div`,{className:`route-canvas rounded-[24px] border bg-[linear-gradient(135deg,rgba(15,23,42,0.03),rgba(15,23,42,0.01)),radial-gradient(circle_at_top_left,rgba(59,130,246,0.06),transparent_22%),radial-gradient(circle_at_bottom_right,rgba(16,185,129,0.06),transparent_24%)] p-2`,children:(0,W.jsx)(`div`,{className:`overflow-hidden rounded-[20px] border bg-background/85`,style:{height:r},children:(0,W.jsx)(Oh,{nodes:t,edges:n,nodeTypes:Og,edgeTypes:kg,fitView:!0,fitViewOptions:{padding:.1,maxZoom:1.02},minZoom:.5,maxZoom:1.8,nodesDraggable:!1,nodesConnectable:!1,elementsSelectable:!1,panOnDrag:!0,zoomOnDoubleClick:!1,preventScrolling:!1,colorMode:`light`,className:`route-canvas-flow h-full w-full`,children:(0,W.jsx)(Fh,{variant:jh.Dots,gap:18,size:1})})})})}var jg={ruleGraphView:(e=>e?[`1`,`true`,`on`,`yes`].includes(e.trim().toLowerCase()):!1)(void 0)},Mg={left:!1,right:!1};function Ng(){let e=(0,U.useRef)(null),[t,n]=(0,U.useState)(Mg),r=(0,U.useCallback)(()=>{let t=e.current;if(!t){n(Mg);return}let{scrollLeft:r,scrollWidth:i,clientWidth:a}=t;if(i<=a){n(Mg);return}n({left:r>1,right:r+a<i-1})},[]);return(0,U.useLayoutEffect)(()=>{let t=e.current;if(!t)return;r();let n=()=>r();t.addEventListener(`scroll`,n,{passive:!0});let i;typeof ResizeObserver<`u`&&(i=new ResizeObserver(()=>r()),i.observe(t));let a;return typeof MutationObserver<`u`&&(a=new MutationObserver(()=>r()),a.observe(t,{childList:!0,subtree:!0,characterData:!0})),()=>{t.removeEventListener(`scroll`,n),i?.disconnect(),a?.disconnect()}},[r]),(0,U.useEffect)(()=>{let e=()=>r();return window.addEventListener(`resize`,e),()=>window.removeEventListener(`resize`,e)},[r]),{ref:e,state:t}}var Pg=`text-muted-foreground italic`,Fg=`text-amber-600 dark:text-amber-400`,Ig=`text-red-500 dark:text-red-400`,Lg=`text-emerald-600 dark:text-emerald-400`,Rg=`text-purple-600 dark:text-purple-400`,zg=`text-foreground`;function Bg(e){let t=e.replace(/\r$/,``);if(t.length===0)return[{text:``,className:zg}];if(/^\s*#/.test(t))return[{text:t,className:Pg}];let n=[],r=t,i=r.match(/^(\s*)(\/\/)/);i&&(i[1]&&n.push({text:i[1],className:zg}),n.push({text:i[2],className:Fg}),r=r.slice(i[0].length));let a=r.split(/(\s+)/),o=-1;for(let e=a.length-1;e>=0;e--){let t=a[e];if(!(t===``||/^\s+$/.test(t))&&!t.startsWith(`!`)){o=e;break}}for(let e=0;e<a.length;e++){let t=a[e];if(t!==``){if(/^\s+$/.test(t)){n.push({text:t,className:zg});continue}if(t.startsWith(`!`)){n.push({text:t,className:Ig});continue}if(e===o){Vg(n,t,Lg);continue}Vg(n,t,zg)}}return n}function Vg(e,t,n){let r=[...t.matchAll(/\[[^\]]+\]/g)];if(r.length===0){e.push({text:t,className:n});return}let i=0;for(let a of r){let r=a[0],o=a.index;o>i&&e.push({text:t.slice(i,o),className:n}),e.push({text:r,className:Rg}),i=o+r.length}i<t.length&&e.push({text:t.slice(i),className:n})}function Hg(e){if(!ae(e))return[e];let t=[],n=e.split(`
12
12
  `);return n.forEach((e,r)=>{Bg(e).forEach((e,n)=>{e.text.length!==0&&t.push((0,W.jsx)(`span`,{className:e.className,children:e.text},`${r}-${n}`))}),r<n.length-1&&t.push(`
13
13
  `)}),t}function Ug({value:e,onChange:t,placeholder:n,className:r,disabled:i,ariaLabel:a}){let o=(0,U.useRef)(null),s=(0,U.useRef)(null),c=(0,U.useCallback)(()=>{o.current&&s.current&&(s.current.scrollTop=o.current.scrollTop,s.current.scrollLeft=o.current.scrollLeft)},[]),l=e.trim().length>0&&ae(e),u=(0,U.useMemo)(()=>l?Hg(e):[],[l,e]),d=u.length>0,f=`font-mono text-sm leading-6 whitespace-pre-wrap break-words`;return(0,W.jsxs)(`div`,{className:`relative flex min-h-0 flex-1 flex-col overflow-hidden ${r||``}`,children:[(0,W.jsxs)(`pre`,{ref:s,"aria-hidden":`true`,className:`absolute inset-0 m-0 overflow-auto px-4 py-3 ${f} pointer-events-none select-none`,children:[d?u:(0,W.jsx)(`span`,{className:i?`text-muted-foreground`:`text-foreground`,children:e||` `}),`
14
- `]}),(0,W.jsx)(`textarea`,{ref:o,value:e,onChange:e=>t(e.target.value),onScroll:c,placeholder:n,spellCheck:!1,disabled:i,"aria-label":a,className:`absolute inset-0 resize-none overflow-auto rounded-none border-0 bg-transparent px-4 py-3 ${f} shadow-none outline-none ring-0 focus-visible:ring-0 ${d&&!i?`text-transparent caret-foreground`:``}`})]})}function Wg({...e}){return(0,W.jsx)(g,{"data-slot":`dialog`,...e})}function Gg({...e}){return(0,W.jsx)(f,{"data-slot":`dialog-portal`,...e})}function Kg({className:e,...t}){return(0,W.jsx)(m,{"data-slot":`dialog-overlay`,className:i(`data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50`,e),...t})}function qg({className:e,children:t,showCloseButton:n=!0,...r}){return(0,W.jsxs)(Gg,{"data-slot":`dialog-portal`,children:[(0,W.jsx)(Kg,{}),(0,W.jsxs)(h,{"data-slot":`dialog-content`,className:i(`bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg`,e),...r,children:[t,n&&(0,W.jsxs)(y,{"data-slot":`dialog-close`,className:`ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none`,children:[(0,W.jsx)(p,{className:`size-4`}),(0,W.jsx)(`span`,{className:`sr-only`,children:`关闭`})]})]})]})}function Jg({className:e,...t}){return(0,W.jsx)(`div`,{"data-slot":`dialog-header`,className:i(`flex flex-col gap-2 text-center sm:text-left`,e),...t})}function Yg({className:e,...t}){return(0,W.jsx)(`div`,{"data-slot":`dialog-footer`,className:i(`flex flex-col-reverse gap-2 sm:flex-row sm:justify-end`,e),...t})}function Xg({className:e,...t}){return(0,W.jsx)(v,{"data-slot":`dialog-title`,className:i(`text-lg leading-none font-semibold`,e),...t})}function Zg({className:e,...t}){return(0,W.jsx)(_,{"data-slot":`dialog-description`,className:i(`text-muted-foreground text-sm`,e),...t})}var Qg=`bg-primary/10 shadow-[inset_3px_0_0_var(--primary)] transition-[background-color,box-shadow]`;function $g(e,t){return e.length===t.length&&e.every((e,n)=>e===t[n])}function e_(e){return e.split(/\s+/).filter(Boolean)}function t_(e,t){let n=new Set(e.map(e=>e.name));if(!n.has(t))return t;let r=2;for(;n.has(`${t}-${r}`);)r+=1;return`${t}-${r}`}var n_=(0,U.memo)(function({exclusions:e,onCommit:t}){let[n,r]=(0,U.useState)(e.join(` `)),i=(0,U.useCallback)(()=>{t(e_(n))},[n,t]);return(0,W.jsx)(R,{value:n,onChange:e=>r(e.target.value),onBlur:i,onKeyDown:e=>{e.key===`Enter`&&i()},placeholder:`!/api !/ws`,className:`h-8`})}),r_=(0,U.memo)(function({id:e,item:t,highlighted:n,highlightRef:r,onToggle:i,onUpdateRule:o,onDelete:s,onMoveToTop:u}){let{attributes:d,listeners:f,setNodeRef:p,transform:m,transition:h,isDragging:g}=Pr({id:e}),_={transform:qe.Transform.toString(m),transition:h,opacity:g?.85:1,position:`relative`,zIndex:g?1:void 0},v=(0,U.useCallback)(()=>i(),[i]),y=(0,U.useCallback)(e=>t=>{o(e,t.target.value)},[o]),b=(0,U.useCallback)(e=>{o(`exclusions`,e)},[o]),x=(0,U.useCallback)(()=>s(),[s]),S=(0,U.useCallback)(()=>u(),[u]);return(0,W.jsxs)(le,{ref:(0,U.useCallback)(e=>{p(e),n&&r&&(r.current=e)},[r,n,p]),style:_,className:n?Qg:void 0,children:[(0,W.jsx)(H,{className:`w-8 cursor-grab active:cursor-grabbing`,...d,...f,children:(0,W.jsx)(c,{className:`h-4 w-4 text-muted-foreground`})}),(0,W.jsx)(H,{className:`w-12`,children:(0,W.jsx)(l,{checked:t.enabled,onCheckedChange:v})}),(0,W.jsx)(H,{children:(0,W.jsx)(R,{value:t.rule,onChange:y(`rule`),placeholder:`example.com`,className:`h-8`})}),(0,W.jsx)(H,{children:(0,W.jsx)(n_,{exclusions:t.exclusions||[],onCommit:b},JSON.stringify(t.exclusions||[]))}),(0,W.jsx)(H,{children:(0,W.jsx)(R,{value:t.target,onChange:y(`target`),placeholder:`127.0.0.1:3000`,className:`h-8`})}),(0,W.jsx)(H,{className:`w-24`,children:(0,W.jsxs)(`div`,{className:`flex gap-1`,children:[(0,W.jsx)(a,{variant:`ghost`,size:`sm`,onClick:S,className:`h-8 w-8 p-0 text-muted-foreground hover:text-primary`,title:`置顶`,children:(0,W.jsx)(fe,{className:`h-4 w-4`})}),(0,W.jsx)(a,{variant:`ghost`,size:`sm`,onClick:x,className:`h-8 w-8 p-0 text-muted-foreground hover:text-destructive`,children:(0,W.jsx)(C,{className:`h-4 w-4`})})]})})]})},(e,t)=>e.item===t.item&&e.highlighted===t.highlighted&&e.id===t.id),i_=(0,U.memo)(function({item:e,highlighted:t,highlightRef:n,onToggle:r,onUpdateRule:i,onDelete:o,onMoveToTop:s}){let c=(0,U.useCallback)(()=>r(),[r]),u=(0,U.useCallback)(e=>t=>{i(e,t.target.value)},[i]),d=(0,U.useCallback)(e=>{i(`exclusions`,e)},[i]),f=(0,U.useCallback)(()=>o(),[o]),p=(0,U.useCallback)(()=>s(),[s]);return(0,W.jsxs)(le,{ref:t?n:void 0,className:t?Qg:void 0,children:[(0,W.jsx)(H,{children:(0,W.jsx)(l,{checked:e.enabled,onCheckedChange:c})}),(0,W.jsx)(H,{children:(0,W.jsx)(R,{value:e.rule,onChange:u(`rule`),placeholder:`example.com`,className:`h-8`})}),(0,W.jsx)(H,{children:(0,W.jsx)(n_,{exclusions:e.exclusions||[],onCommit:d},JSON.stringify(e.exclusions||[]))}),(0,W.jsx)(H,{children:(0,W.jsx)(R,{value:e.target,onChange:u(`target`),placeholder:`127.0.0.1:3000`,className:`h-8`})}),(0,W.jsx)(H,{children:(0,W.jsxs)(`div`,{className:`flex gap-1`,children:[(0,W.jsx)(a,{variant:`ghost`,size:`sm`,onClick:p,className:`h-8 w-8 p-0 text-muted-foreground hover:text-primary`,title:`置顶`,children:(0,W.jsx)(fe,{className:`h-4 w-4`})}),(0,W.jsx)(a,{variant:`ghost`,size:`sm`,onClick:f,className:`h-8 w-8 p-0 text-muted-foreground hover:text-destructive`,children:(0,W.jsx)(C,{className:`h-4 w-4`})})]})})]})},(e,t)=>e.item===t.item&&e.highlighted===t.highlighted);function a_({showDragColumn:e}){return e?(0,W.jsxs)(`colgroup`,{children:[(0,W.jsx)(`col`,{style:{width:`2rem`}}),(0,W.jsx)(`col`,{style:{width:`3rem`}}),(0,W.jsx)(`col`,{}),(0,W.jsx)(`col`,{}),(0,W.jsx)(`col`,{}),(0,W.jsx)(`col`,{style:{width:`6rem`}})]}):(0,W.jsxs)(`colgroup`,{children:[(0,W.jsx)(`col`,{style:{width:`3rem`}}),(0,W.jsx)(`col`,{}),(0,W.jsx)(`col`,{}),(0,W.jsx)(`col`,{}),(0,W.jsx)(`col`,{style:{width:`6rem`}})]})}function o_({showDragColumn:e}){return(0,W.jsxs)(le,{children:[e&&(0,W.jsx)(se,{className:`w-8`}),(0,W.jsx)(se,{className:`w-12`,children:`启用`}),(0,W.jsx)(se,{children:`规则`}),(0,W.jsx)(se,{children:`排除`}),(0,W.jsx)(se,{children:`目标`}),(0,W.jsx)(se,{className:`w-24`,children:`操作`})]})}function s_(e){let{rules:t,setRules:n,ruleFiles:r,activeFileName:i,fetchRuleFiles:o,fetchFileContent:s,fetchRuleFileRawContent:c,saveRuleFileRawContent:l,saveFileContent:f,createRuleFile:m,toggleRuleFile:h,renameRuleFile:g,deleteRuleFile:_}=e,[v,y]=(0,U.useState)(!1),C=(0,U.useCallback)(()=>{window.dispatchEvent(new CustomEvent(`global-panel:open-panel`,{detail:{id:`rules.overview`,title:`全局规则总览`,description:`总览全部规则文件与代理实际生效的路由规则`,size:`lg`}}))},[]),[M,ae]=(0,U.useState)(`table`),[se,fe]=(0,U.useState)(``),[ye,be]=(0,U.useState)(null),Se=(0,U.useRef)(``),[Ce,we]=(0,U.useState)(null),Te=(0,U.useRef)(null),Ee=(0,U.useRef)(0),G=(0,U.useCallback)(()=>`rule-${Ee.current++}`,[]),[De,Oe]=(0,U.useState)(()=>t.map(()=>G())),ke=Ng(),[Ae,je]=(0,U.useState)(!1),[Me,Ne]=(0,U.useState)(`默认规则`),[Pe,Fe]=(0,U.useState)(null),[Ie,Le]=(0,U.useState)(null),[Re,ze]=(0,U.useState)(``),[Be,Ve]=(0,U.useState)(null),He=(0,U.useRef)(!1),[Ue,We]=(0,U.useState)(!1),[Ge,Ke]=(0,U.useState)(``),[qe,Je]=(0,U.useState)(null),Ye=(0,U.useRef)(null),[Xe,Ze]=(0,U.useState)(!1),[Qe,$e]=(0,U.useState)(``),[et,tt]=(0,U.useState)(``),[nt,rt]=(0,U.useState)(null),[it,at]=(0,U.useState)(!1),[K,ot]=(0,U.useState)(!1),[q,lt]=(0,U.useState)(``),[ut,dt]=(0,U.useState)(``),ft=(0,U.useDeferredValue)(q),pt=(0,U.useDeferredValue)(ut),[mt,gt]=(0,U.useTransition)(),_t=(0,U.useCallback)(()=>{je(!1),We(!1),Je(null),Ke(``),Fe(null)},[]),vt=(0,U.useCallback)(()=>{Ne(t_(r,`默认规则`)),je(!0),We(!1),Je(null),Ke(``),Fe(null)},[r]);(0,U.useEffect)(()=>{o().then(e=>{e.length>0&&!i&&s((e.find(e=>e.enabled)||e[0]).name)})},[]);let yt=(0,U.useCallback)(async e=>{await s(e)},[s]);(0,U.useEffect)(()=>{let e=!1;if(!i){Se.current=``;return}return c(i).then(t=>{e||(Se.current=t,fe(t))}).catch(()=>{if(!e){let e=j(t);Se.current=e,fe(e)}}).finally(()=>{e||be(i)}),()=>{e=!0}},[i,c]),(0,U.useEffect)(()=>{if(!i||M===`text`)return;let e=j(t);j(L(Se.current))!==e&&(Se.current=e,fe(e))},[i,t,M]),(0,U.useEffect)(()=>{Oe(e=>e.length===t.length?e:e.length>t.length?e.slice(0,t.length):[...e,...Array.from({length:t.length-e.length},()=>G())])},[G,t.length]);let bt=(0,U.useCallback)(async()=>{if(!Me.trim())return;Fe(null);let e=qe||``,t=await m(Me.trim(),e);t.success?(_t(),Ne(`默认规则`),await s(Me.trim())):Fe(t.error||`创建失败`)},[m,Me,qe,_t,s]),xt=(0,U.useCallback)(async()=>{if(de(window))try{let[e]=await window.showOpenFilePicker({types:[{description:`规则文件`,accept:{"text/plain":[`.txt`,`.rules`]}}],multiple:!1}),t=await e.getFile(),n=await t.text(),r=t.name.replace(/\.[^.]+$/,``);Je(n),Ke(r),Ne(r),We(!0),je(!0);return}catch{}Ye.current?.click()},[]),St=(0,U.useCallback)(e=>{let t=e.target.files?.[0];t&&t.text().then(e=>{let n=t.name.replace(/\.[^.]+$/,``);Je(e),Ke(n),Ne(n),We(!0),je(!0)}),e.target.value=``},[]),Ct=(0,U.useCallback)(()=>{$e(t_(r,`文本导入`)),tt(``),rt(null),at(!1),Ze(!0)},[r]),wt=(0,U.useMemo)(()=>L(B(et)),[et]),Tt=(0,U.useMemo)(()=>z(B(et)),[et]),Et=(0,U.useCallback)(async()=>{let e=Qe.trim();if(!e){rt(`规则文件名称不能为空`);return}let t=B(et);if(!t.trim()){rt(`请输入规则文本`);return}if(z(t).length>0){rt(`规则文本存在无法识别的行,请先修正`);return}at(!0);let n=await m(e,t);at(!1),n.success?(Ze(!1),await s(e)):rt(n.error||`创建失败`)},[m,s,et,Qe]),Dt=(0,U.useCallback)(async()=>{if(!i||M===`text`&&z(se).length>0)return;y(!0);let e=M===`text`?await l(i,se):await f(i,t);y(!1),e?(o(),ne.success(`规则保存成功`)):ne.error(`规则保存失败`)},[i,o,t,f,l,se,M]),Ot=(0,U.useCallback)(async e=>{confirm(`确定要删除规则文件「${e}」吗?`)&&await _(e)},[_]),kt=(0,U.useCallback)(e=>{Le(e),ze(e),Ve(null)},[]),At=(0,U.useCallback)(()=>{Le(null),ze(``),Ve(null)},[]),jt=(0,U.useCallback)(async()=>{if(!Ie||He.current)return;let e=Re.trim();if(!e){Ve(`规则文件名称不能为空`);return}if(e===Ie){At();return}He.current=!0;try{let t=await g(Ie,e);t.success?(Le(null),ze(``),Ve(null),await s(t.name||e)):Ve(t.error||`重命名失败`)}finally{He.current=!1}},[At,s,Re,g,Ie]),Mt=(0,U.useCallback)(e=>{gt(()=>n(t=>t.map((t,n)=>n===e?{...t,enabled:!t.enabled}:t)))},[n]),Nt=(0,U.useCallback)((e,t,r)=>{n(n=>n.map((n,i)=>i===e?{...n,[t]:r}:n))},[n]),Pt=(0,U.useCallback)(e=>{Oe(t=>t.filter((t,n)=>n!==e)),gt(()=>n(t=>t.filter((t,n)=>n!==e)))},[n]),Ft=(0,U.useCallback)(()=>{Oe(e=>[G(),...e]),gt(()=>n(e=>[{enabled:!0,rule:``,target:``,exclusions:[]},...e])),we(0)},[G,n]),It=(0,U.useCallback)(e=>{Oe(t=>hr(t,e,0)),gt(()=>n(t=>{let n=[...t],[r]=n.splice(e,1);return n.unshift(r),n})),we(0)},[n]),Lt=(0,U.useCallback)(e=>{Se.current=e,fe(e),n(L(e))},[n]),Rt=(0,U.useCallback)(e=>{let{active:t,over:r}=e,i=r?Vr(De,t.id,r.id):De;$g(i,De)||(Oe(i),n(e=>Hr(e,De,i)))},[De,n]),zt=ct(st(ln),st(rn,{coordinateGetter:Rr}));(0,U.useEffect)(()=>{if(Ce==null)return;let e=requestAnimationFrame(()=>{Te.current?.scrollIntoView({behavior:`smooth`,block:`center`})}),t=setTimeout(()=>we(null),1600);return()=>{cancelAnimationFrame(e),clearTimeout(t)}},[t,Ce]),(0,U.useEffect)(()=>{let e=e=>{let n=e.detail||{},r=n.pattern?.trim(),i=n.target?.trim();if(!r||i==null)return;let a=t.findIndex(e=>e.rule.trim()===r&&e.target.trim()===i);a<0||(ae(`table`),lt(``),dt(``),we(a))};return window.addEventListener(`route-rule:highlight`,e),()=>window.removeEventListener(`route-rule:highlight`,e)},[t]);let Bt=(0,U.useMemo)(()=>{if(!ft&&!pt)return t.map((e,t)=>({item:e,index:t}));let e=ft.toLowerCase(),n=pt.toLowerCase();return t.map((e,t)=>({item:e,index:t})).filter(({item:t})=>(!ft||t.rule.toLowerCase().includes(e))&&(!pt||t.target.toLowerCase().includes(n)))},[t,ft,pt]),Vt=(0,U.useMemo)(()=>{let e=t.map((e,t)=>({item:e,index:t,id:De[t]})).filter(e=>!!e.id),n=new Map(e.map(e=>[e.id,e]));return De.map(e=>n.get(e)).filter(e=>!!e)},[De,t]),Ht=(0,U.useMemo)(()=>{let e=new Set;return t.forEach(t=>{t.target.trim()&&e.add(t.target.trim())}),Array.from(e).sort()},[t]),Ut=(0,U.useMemo)(()=>Jr(t,Bt.map(({index:e})=>e)),[t,Bt]),Wt=i?se:``,Gt=!!(i&&ye!==i),Kt=(0,U.useMemo)(()=>z(Wt),[Wt]),qt=M===`text`&&Kt.length>0,Jt=!q&&!ut;N({active:!Xe,enabled:!!i&&!v&&!Gt&&!qt,priority:F.page,onSave:Dt});let Yt=(0,U.useCallback)(e=>()=>Mt(e),[Mt]),Xt=(0,U.useCallback)(e=>(t,n)=>Nt(e,t,n),[Nt]),Zt=(0,U.useCallback)(e=>()=>Pt(e),[Pt]),Qt=(0,U.useCallback)(e=>()=>It(e),[It]);return(0,W.jsxs)(`div`,{className:`app-page-stack`,children:[(0,W.jsxs)(T,{"data-testid":`rule-panel-card`,className:`min-h-0 flex-1 gap-0 overflow-hidden py-0 shadow-none`,children:[(0,W.jsxs)(`div`,{"data-slot":`rule-config-sticky-controls`,className:`shrink-0 rounded-t-xl bg-card`,children:[(0,W.jsxs)(E,{className:`block border-b bg-muted/30 p-0 [.border-b]:pb-0`,children:[(0,W.jsx)(ie,{className:`sr-only`,children:`规则内容`}),(0,W.jsxs)(`div`,{className:`flex min-w-0 items-center px-3 py-2`,children:[(0,W.jsx)(`div`,{"data-slot":`rule-file-tabs-scroll-wrap`,className:`meddle-tabs-scroll-wrap flex min-w-0 flex-1`,"data-shadow-left":ke.state.left?`true`:`false`,"data-shadow-right":ke.state.right?`true`:`false`,children:(0,W.jsx)(`div`,{"data-slot":`rule-file-tabs-scroll`,ref:ke.ref,className:`meddle-tabs-scroll min-w-0 flex-1 overflow-x-auto`,children:(0,W.jsx)(k,{className:`min-w-max`,value:i||``,onValueChange:yt,children:(0,W.jsx)(O,{className:`h-auto min-w-max justify-start gap-1 rounded-none bg-transparent p-0`,children:r.map(e=>(0,W.jsxs)(A,{value:e.name,className:`group relative flex-none gap-1.5`,children:[(0,W.jsx)(`span`,{role:`button`,tabIndex:0,className:`shrink-0`,onClick:t=>{t.stopPropagation(),h(e.name,!e.enabled)},onKeyDown:t=>{(t.key===`Enter`||t.key===` `)&&(t.preventDefault(),t.stopPropagation(),h(e.name,!e.enabled))},title:e.enabled?`点击禁用路由`:`点击启用路由`,children:e.enabled?(0,W.jsx)(ve,{className:`size-4 text-primary`}):(0,W.jsx)(_e,{className:`size-4 text-muted-foreground`})}),Ie===e.name?(0,W.jsx)(`input`,{value:Re,onChange:e=>{ze(e.target.value),Ve(null)},onClick:e=>e.stopPropagation(),onDoubleClick:e=>e.stopPropagation(),onFocus:e=>e.currentTarget.select(),onBlur:()=>void jt(),onKeyDown:e=>{e.stopPropagation(),e.key===`Enter`?(e.preventDefault(),jt()):e.key===`Escape`&&(e.preventDefault(),At())},className:`h-6 w-28 rounded border bg-background px-1.5 text-sm text-foreground outline-none focus:border-ring focus:ring-2 focus:ring-ring/30`,"aria-label":`重命名规则文件 ${e.name}`,autoFocus:!0}):(0,W.jsx)(`span`,{onDoubleClick:t=>{t.stopPropagation(),kt(e.name)},title:`双击重命名`,children:e.name}),(0,W.jsx)(x,{variant:`secondary`,className:`text-[10px] px-1 py-0`,children:e.ruleCount}),r.length>1&&(0,W.jsx)(`span`,{role:`button`,tabIndex:0,className:`opacity-0 group-hover:opacity-100 transition-opacity text-muted-foreground hover:text-destructive`,onClick:t=>{t.stopPropagation(),Ot(e.name)},onKeyDown:t=>{(t.key===`Enter`||t.key===` `)&&(t.preventDefault(),t.stopPropagation(),Ot(e.name))},title:`删除规则文件`,children:(0,W.jsx)(p,{className:`size-3`})})]},e.name))})})})}),(0,W.jsx)(`div`,{"data-slot":`rule-file-actions`,className:`ml-2 flex shrink-0 items-center border-l pl-2`,children:Ae?(0,W.jsxs)(`div`,{role:`group`,"aria-label":Ue?`从文件导入为新规则`:`创建新规则文件`,className:`flex h-8 items-center gap-1 rounded-md border border-primary/30 bg-background px-1 shadow-sm`,title:Ue&&Ge?`导入自: ${Ge}`:void 0,children:[(0,W.jsx)(R,{value:Me,onChange:e=>{Ne(e.target.value),Fe(null)},placeholder:`规则文件名称`,className:`h-6 w-36 border-0 bg-transparent px-1.5 shadow-none focus-visible:ring-0`,"aria-label":`新规则文件名称`,autoFocus:!0,onKeyDown:e=>{e.stopPropagation(),e.key===`Enter`?(e.preventDefault(),bt()):e.key===`Escape`&&(e.preventDefault(),_t())}}),(0,W.jsx)(a,{type:`button`,variant:`ghost`,size:`icon-xs`,onClick:()=>void bt(),"aria-label":`确认创建规则文件`,title:`创建`,children:(0,W.jsx)(re,{})}),(0,W.jsx)(a,{type:`button`,variant:`ghost`,size:`icon-xs`,onClick:_t,"aria-label":`取消创建规则文件`,title:`取消`,children:(0,W.jsx)(p,{})})]}):(0,W.jsxs)(W.Fragment,{children:[(0,W.jsx)(a,{type:`button`,variant:`ghost`,size:`icon-sm`,onClick:C,"aria-label":`查看所有规则`,title:`查看所有规则`,children:(0,W.jsx)(V,{})}),(0,W.jsx)(a,{type:`button`,variant:`ghost`,size:`icon-sm`,onClick:vt,"aria-label":`创建规则文件`,title:`创建规则文件`,children:(0,W.jsx)(u,{})})]})})]})]}),(0,W.jsxs)(`div`,{className:`flex flex-row flex-wrap items-center justify-between gap-3 border-b px-3 py-2`,children:[(0,W.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,W.jsxs)(ee,{type:`single`,value:M,onValueChange:e=>{e&&ae(e)},variant:`outline`,size:`sm`,spacing:0,className:`bg-background`,"aria-label":`规则视图`,children:[(0,W.jsxs)(b,{value:`table`,children:[(0,W.jsx)(d,{}),`表格`]}),(0,W.jsxs)(b,{value:`text`,children:[(0,W.jsx)(me,{}),`文本`]}),jg.ruleGraphView&&(0,W.jsxs)(b,{value:`graph`,children:[(0,W.jsx)(ge,{}),`图表`]})]}),mt&&(0,W.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`更新中...`})]}),(0,W.jsxs)(`div`,{className:`flex flex-wrap items-center justify-end gap-2`,children:[M!==`text`&&(0,W.jsxs)(a,{variant:K?`selected`:`outline`,size:`sm`,onClick:()=>ot(e=>!e),title:`显示/隐藏筛选器`,children:[(0,W.jsx)(I,{"data-icon":`inline-start`}),`筛选`]}),M===`table`&&(0,W.jsxs)(W.Fragment,{children:[(0,W.jsxs)(a,{variant:`outline`,size:`sm`,onClick:Ft,disabled:!i,children:[(0,W.jsx)(u,{"data-icon":`inline-start`}),`添加规则`]}),(0,W.jsx)(`input`,{ref:Ye,type:`file`,accept:`.txt,.rules`,className:`hidden`,onChange:St}),(0,W.jsxs)(a,{variant:`outline`,size:`sm`,onClick:xt,children:[(0,W.jsx)(he,{"data-icon":`inline-start`}),`从文件加载`]}),(0,W.jsxs)(a,{variant:`outline`,size:`sm`,onClick:Ct,children:[(0,W.jsx)(pe,{"data-icon":`inline-start`}),`文本导入`]})]}),i&&(0,W.jsxs)(te,{size:`sm`,onClick:Dt,disabled:v||Gt||qt,title:qt?`${Kt.length} 行内容无法识别,请先修正`:`保存 (⌘+S / Ctrl+S)`,children:[v?(0,W.jsx)(xe,{"data-icon":`inline-start`}):(0,W.jsx)(P,{"data-icon":`inline-start`}),`保存`]})]})]})]}),(Be||Pe)&&(0,W.jsxs)(`div`,{className:`flex shrink-0 flex-col gap-1 border-b px-3 py-2 text-xs text-destructive`,children:[Be&&(0,W.jsx)(`p`,{children:Be}),Pe&&(0,W.jsx)(`p`,{children:Pe})]}),K&&M!==`text`&&(0,W.jsxs)(`div`,{className:`flex shrink-0 flex-col gap-3 border-b bg-muted/20 p-3 md:flex-row md:items-end`,children:[(0,W.jsxs)(`div`,{className:`flex flex-1 flex-col gap-1`,children:[(0,W.jsx)(`label`,{className:`text-xs font-medium text-muted-foreground`,children:`筛选规则`}),(0,W.jsxs)(`div`,{className:`relative`,children:[(0,W.jsx)(R,{value:q,onChange:e=>lt(e.target.value),placeholder:`输入规则名称进行筛选...`,className:`h-9`}),q&&(0,W.jsx)(a,{variant:`ghost`,size:`sm`,className:`absolute right-1 top-1/2 h-7 w-7 -translate-y-1/2 p-0`,onClick:()=>lt(``),children:(0,W.jsx)(p,{className:`h-3 w-3`})})]})]}),(0,W.jsxs)(`div`,{className:`flex flex-1 flex-col gap-1`,children:[(0,W.jsx)(`label`,{className:`text-xs font-medium text-muted-foreground`,children:`筛选目标`}),(0,W.jsxs)(`div`,{className:`relative`,children:[(0,W.jsx)(R,{value:ut,onChange:e=>dt(e.target.value),placeholder:`输入目标地址进行筛选...`,className:`h-9`,list:`target-list`}),(0,W.jsx)(`datalist`,{id:`target-list`,children:Ht.map(e=>(0,W.jsx)(`option`,{value:e},e))}),ut&&(0,W.jsx)(a,{variant:`ghost`,size:`sm`,className:`absolute right-1 top-1/2 h-7 w-7 -translate-y-1/2 p-0`,onClick:()=>dt(``),children:(0,W.jsx)(p,{className:`h-3 w-3`})})]})]}),(q||ut)&&(0,W.jsx)(a,{variant:`outline`,size:`sm`,onClick:()=>{lt(``),dt(``)},className:`h-9`,children:`清除筛选`})]}),(0,W.jsx)(S,{className:`flex min-h-0 flex-1 flex-col overflow-hidden p-0`,children:M===`text`?(0,W.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col overflow-hidden`,children:[(0,W.jsx)(Ug,{ariaLabel:`规则文本`,value:Wt,onChange:Lt,disabled:!i||Gt,placeholder:i?`example.com !/api localhost:3000`:`请先选择或创建一个规则文件`}),(0,W.jsxs)(`div`,{className:`flex shrink-0 flex-wrap items-center justify-between gap-2 border-t px-4 py-2 text-xs text-muted-foreground`,children:[(0,W.jsx)(`span`,{children:Gt?`正在加载规则文本...`:`已解析 ${t.length} 条规则`}),Kt.length>0&&(0,W.jsxs)(x,{variant:`destructive`,title:`存在无法识别的行,保存已禁用`,children:[Kt.length,` 行未识别:`,Kt.slice(0,3).map(e=>e.line).join(`、`),Kt.length>3?`…`:``]})]})]}):M===`table`||!jg.ruleGraphView?(0,W.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col overflow-hidden`,children:[(0,W.jsx)(`div`,{"data-slot":`rule-table-header`,className:`z-10 shrink-0 overflow-x-auto bg-card`,children:(0,W.jsxs)(ue,{className:`table-fixed`,children:[(0,W.jsx)(a_,{showDragColumn:Jt}),(0,W.jsx)(oe,{children:(0,W.jsx)(o_,{showDragColumn:Jt})})]})}),(0,W.jsx)(D,{className:`min-h-0 flex-1`,children:(0,W.jsxs)(ue,{className:`table-fixed`,children:[(0,W.jsx)(a_,{showDragColumn:Jt}),(0,W.jsx)(ce,{children:i?t.length===0?(0,W.jsx)(le,{children:(0,W.jsx)(H,{colSpan:6,className:`text-center text-muted-foreground py-8`,children:`暂无规则,点击"添加规则"开始配置`})}):Bt.length===0?(0,W.jsx)(le,{children:(0,W.jsx)(H,{colSpan:6,className:`text-center text-muted-foreground py-8`,children:`没有匹配的规则,请调整筛选条件`})}):q||ut?Bt.map(({item:e,index:t})=>(0,W.jsx)(i_,{item:e,highlighted:Ce===t,highlightRef:Te,onToggle:Yt(t),onUpdateRule:Xt(t),onDelete:Zt(t),onMoveToTop:Qt(t)},t)):(0,W.jsx)(or,{sensors:zt,collisionDetection:ht,onDragEnd:Rt,children:(0,W.jsx)(Er,{items:Vt.map(e=>e.id),strategy:Sr,children:Vt.map(({item:e,index:t,id:n})=>(0,W.jsx)(r_,{id:n,item:e,highlighted:Ce===t,highlightRef:Te,onToggle:Yt(t),onUpdateRule:Xt(t),onDelete:Zt(t),onMoveToTop:Qt(t)},n))})}):(0,W.jsx)(le,{children:(0,W.jsx)(H,{colSpan:6,className:`text-center text-muted-foreground py-8`,children:`请选择或创建一个规则文件`})})})]})})]}):(0,W.jsx)(D,{className:`min-h-0 flex-1`,children:(0,W.jsx)(`div`,{className:`flex flex-col gap-4 p-4`,children:i?t.length===0?(0,W.jsx)(`div`,{className:`rounded-xl border border-dashed p-8 text-center text-muted-foreground`,children:`暂无规则,点击“添加规则”后这里会自动生成路由流向图`}):Bt.length===0?(0,W.jsx)(`div`,{className:`rounded-xl border border-dashed p-8 text-center text-muted-foreground`,children:`没有匹配的规则,请调整筛选条件后再查看图表`}):(0,W.jsx)(Ag,{graphData:Ut}):(0,W.jsx)(`div`,{className:`rounded-xl border border-dashed p-8 text-center text-muted-foreground`,children:`请选择或创建一个规则文件后查看图表`})})})}),(q||ut)&&Bt.length>0&&(0,W.jsxs)(w,{className:`shrink-0 border-t px-4 py-2 text-sm text-muted-foreground [.border-t]:pt-2`,children:[`显示 `,Bt.length,` / `,t.length,` 条规则`]})]}),(0,W.jsx)(Wg,{open:Xe,onOpenChange:Ze,children:(0,W.jsxs)(qg,{className:`flex max-h-[90vh] flex-col gap-4 sm:max-w-2xl`,children:[(0,W.jsxs)(Jg,{children:[(0,W.jsx)(Xg,{children:`文本导入`}),(0,W.jsxs)(Zg,{children:[`粘贴或编辑规则文本,支持 hosts 文件格式自动转换。每行一条规则,格式:`,(0,W.jsx)(`code`,{className:`rounded bg-muted px-1 py-0.5 font-mono text-xs`,children:`规则 [排除项] 目标`})]})]}),(0,W.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,W.jsx)(`label`,{className:`text-xs font-medium text-muted-foreground`,htmlFor:`text-import-name`,children:`规则文件名称`}),(0,W.jsx)(R,{id:`text-import-name`,value:Qe,onChange:e=>{$e(e.target.value),rt(null)},placeholder:`规则文件名称`,className:`font-mono`})]}),(0,W.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col gap-2 overflow-hidden`,children:[(0,W.jsx)(`label`,{className:`text-xs font-medium text-muted-foreground`,htmlFor:`text-import-content`,children:`规则文本`}),(0,W.jsx)(`div`,{className:`min-h-[220px] flex-1 overflow-hidden rounded-md border`,children:(0,W.jsx)(Ug,{ariaLabel:`导入规则文本`,value:et,onChange:tt,placeholder:`127.0.0.1 example.com api.example.com
14
+ `]}),(0,W.jsx)(`textarea`,{ref:o,value:e,onChange:e=>t(e.target.value),onScroll:c,placeholder:n,spellCheck:!1,disabled:i,"aria-label":a,className:`absolute inset-0 resize-none overflow-auto rounded-none border-0 bg-transparent px-4 py-3 ${f} shadow-none outline-none ring-0 focus-visible:ring-0 ${d&&!i?`text-transparent caret-foreground`:``}`})]})}function Wg({...e}){return(0,W.jsx)(g,{"data-slot":`dialog`,...e})}function Gg({...e}){return(0,W.jsx)(f,{"data-slot":`dialog-portal`,...e})}function Kg({className:e,...t}){return(0,W.jsx)(m,{"data-slot":`dialog-overlay`,className:i(`data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50`,e),...t})}function qg({className:e,children:t,showCloseButton:n=!0,...r}){return(0,W.jsxs)(Gg,{"data-slot":`dialog-portal`,children:[(0,W.jsx)(Kg,{}),(0,W.jsxs)(h,{"data-slot":`dialog-content`,className:i(`bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg`,e),...r,children:[t,n&&(0,W.jsxs)(y,{"data-slot":`dialog-close`,className:`ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none`,children:[(0,W.jsx)(p,{className:`size-4`}),(0,W.jsx)(`span`,{className:`sr-only`,children:`关闭`})]})]})]})}function Jg({className:e,...t}){return(0,W.jsx)(`div`,{"data-slot":`dialog-header`,className:i(`flex flex-col gap-2 text-center sm:text-left`,e),...t})}function Yg({className:e,...t}){return(0,W.jsx)(`div`,{"data-slot":`dialog-footer`,className:i(`flex flex-col-reverse gap-2 sm:flex-row sm:justify-end`,e),...t})}function Xg({className:e,...t}){return(0,W.jsx)(v,{"data-slot":`dialog-title`,className:i(`text-lg leading-none font-semibold`,e),...t})}function Zg({className:e,...t}){return(0,W.jsx)(_,{"data-slot":`dialog-description`,className:i(`text-muted-foreground text-sm`,e),...t})}var Qg=`bg-primary/10 shadow-[inset_3px_0_0_var(--primary)] transition-[background-color,box-shadow]`;function $g(e,t){return e.length===t.length&&e.every((e,n)=>e===t[n])}function e_(e){return e.split(/\s+/).filter(Boolean)}function t_(e,t){let n=new Set(e.map(e=>e.name));if(!n.has(t))return t;let r=2;for(;n.has(`${t}-${r}`);)r+=1;return`${t}-${r}`}var n_=(0,U.memo)(function({exclusions:e,onCommit:t}){let[n,r]=(0,U.useState)(e.join(` `)),i=(0,U.useCallback)(()=>{t(e_(n))},[n,t]);return(0,W.jsx)(R,{value:n,onChange:e=>r(e.target.value),onBlur:i,onKeyDown:e=>{e.key===`Enter`&&i()},placeholder:`!/api !/ws`,className:`h-8`})}),r_=(0,U.memo)(function({id:e,item:t,highlighted:n,highlightRef:r,onToggle:i,onUpdateRule:o,onDelete:s,onMoveToTop:u}){let{attributes:d,listeners:f,setNodeRef:p,transform:m,transition:h,isDragging:g}=Pr({id:e}),_={transform:qe.Transform.toString(m),transition:h,opacity:g?.85:1,position:`relative`,zIndex:g?1:void 0},v=(0,U.useCallback)(()=>i(),[i]),y=(0,U.useCallback)(e=>t=>{o(e,t.target.value)},[o]),b=(0,U.useCallback)(e=>{o(`exclusions`,e)},[o]),x=(0,U.useCallback)(()=>s(),[s]),S=(0,U.useCallback)(()=>u(),[u]);return(0,W.jsxs)(le,{ref:(0,U.useCallback)(e=>{p(e),n&&r&&(r.current=e)},[r,n,p]),style:_,className:n?Qg:void 0,children:[(0,W.jsx)(H,{className:`w-8 cursor-grab active:cursor-grabbing`,...d,...f,children:(0,W.jsx)(c,{className:`h-4 w-4 text-muted-foreground`})}),(0,W.jsx)(H,{className:`w-12`,children:(0,W.jsx)(l,{checked:t.enabled,onCheckedChange:v})}),(0,W.jsx)(H,{children:(0,W.jsx)(R,{value:t.rule,onChange:y(`rule`),placeholder:`example.com`,className:`h-8`})}),(0,W.jsx)(H,{children:(0,W.jsx)(n_,{exclusions:t.exclusions||[],onCommit:b},JSON.stringify(t.exclusions||[]))}),(0,W.jsx)(H,{children:(0,W.jsx)(R,{value:t.target,onChange:y(`target`),placeholder:`127.0.0.1:3000`,className:`h-8`})}),(0,W.jsx)(H,{className:`w-24`,children:(0,W.jsxs)(`div`,{className:`flex gap-1`,children:[(0,W.jsx)(a,{variant:`ghost`,size:`icon-sm`,onClick:S,className:`text-muted-foreground hover:text-primary`,title:`置顶`,"aria-label":`置顶`,children:(0,W.jsx)(fe,{className:`h-4 w-4`})}),(0,W.jsx)(a,{variant:`ghost`,size:`icon-sm`,onClick:x,className:`text-muted-foreground hover:text-destructive`,"aria-label":`删除规则`,children:(0,W.jsx)(C,{className:`h-4 w-4`})})]})})]})},(e,t)=>e.item===t.item&&e.highlighted===t.highlighted&&e.id===t.id),i_=(0,U.memo)(function({item:e,highlighted:t,highlightRef:n,onToggle:r,onUpdateRule:i,onDelete:o,onMoveToTop:s}){let c=(0,U.useCallback)(()=>r(),[r]),u=(0,U.useCallback)(e=>t=>{i(e,t.target.value)},[i]),d=(0,U.useCallback)(e=>{i(`exclusions`,e)},[i]),f=(0,U.useCallback)(()=>o(),[o]),p=(0,U.useCallback)(()=>s(),[s]);return(0,W.jsxs)(le,{ref:t?n:void 0,className:t?Qg:void 0,children:[(0,W.jsx)(H,{children:(0,W.jsx)(l,{checked:e.enabled,onCheckedChange:c})}),(0,W.jsx)(H,{children:(0,W.jsx)(R,{value:e.rule,onChange:u(`rule`),placeholder:`example.com`,className:`h-8`})}),(0,W.jsx)(H,{children:(0,W.jsx)(n_,{exclusions:e.exclusions||[],onCommit:d},JSON.stringify(e.exclusions||[]))}),(0,W.jsx)(H,{children:(0,W.jsx)(R,{value:e.target,onChange:u(`target`),placeholder:`127.0.0.1:3000`,className:`h-8`})}),(0,W.jsx)(H,{children:(0,W.jsxs)(`div`,{className:`flex gap-1`,children:[(0,W.jsx)(a,{variant:`ghost`,size:`icon-sm`,onClick:p,className:`text-muted-foreground hover:text-primary`,title:`置顶`,"aria-label":`置顶`,children:(0,W.jsx)(fe,{className:`h-4 w-4`})}),(0,W.jsx)(a,{variant:`ghost`,size:`icon-sm`,onClick:f,className:`text-muted-foreground hover:text-destructive`,"aria-label":`删除规则`,children:(0,W.jsx)(C,{className:`h-4 w-4`})})]})})]})},(e,t)=>e.item===t.item&&e.highlighted===t.highlighted);function a_({showDragColumn:e}){return e?(0,W.jsxs)(`colgroup`,{children:[(0,W.jsx)(`col`,{style:{width:`2rem`}}),(0,W.jsx)(`col`,{style:{width:`3rem`}}),(0,W.jsx)(`col`,{}),(0,W.jsx)(`col`,{}),(0,W.jsx)(`col`,{}),(0,W.jsx)(`col`,{style:{width:`6rem`}})]}):(0,W.jsxs)(`colgroup`,{children:[(0,W.jsx)(`col`,{style:{width:`3rem`}}),(0,W.jsx)(`col`,{}),(0,W.jsx)(`col`,{}),(0,W.jsx)(`col`,{}),(0,W.jsx)(`col`,{style:{width:`6rem`}})]})}function o_({showDragColumn:e}){return(0,W.jsxs)(le,{children:[e&&(0,W.jsx)(se,{className:`w-8`}),(0,W.jsx)(se,{className:`w-12`,children:`启用`}),(0,W.jsx)(se,{children:`规则`}),(0,W.jsx)(se,{children:`排除`}),(0,W.jsx)(se,{children:`目标`}),(0,W.jsx)(se,{className:`w-24`,children:`操作`})]})}function s_(e){let{rules:t,setRules:n,ruleFiles:r,activeFileName:i,fetchRuleFiles:o,fetchFileContent:s,fetchRuleFileRawContent:c,saveRuleFileRawContent:l,saveFileContent:f,createRuleFile:m,toggleRuleFile:h,renameRuleFile:g,deleteRuleFile:_}=e,[v,y]=(0,U.useState)(!1),C=(0,U.useCallback)(()=>{window.dispatchEvent(new CustomEvent(`global-panel:open-panel`,{detail:{id:`rules.overview`,title:`全局规则总览`,description:`总览全部规则文件与代理实际生效的路由规则`,size:`lg`}}))},[]),[M,ae]=(0,U.useState)(`table`),[se,fe]=(0,U.useState)(``),[ye,be]=(0,U.useState)(null),Se=(0,U.useRef)(``),[Ce,we]=(0,U.useState)(null),Te=(0,U.useRef)(null),Ee=(0,U.useRef)(0),G=(0,U.useCallback)(()=>`rule-${Ee.current++}`,[]),[De,Oe]=(0,U.useState)(()=>t.map(()=>G())),ke=Ng(),[Ae,je]=(0,U.useState)(!1),[Me,Ne]=(0,U.useState)(`默认规则`),[Pe,Fe]=(0,U.useState)(null),[Ie,Le]=(0,U.useState)(null),[Re,ze]=(0,U.useState)(``),[Be,Ve]=(0,U.useState)(null),He=(0,U.useRef)(!1),[Ue,We]=(0,U.useState)(!1),[Ge,Ke]=(0,U.useState)(``),[qe,Je]=(0,U.useState)(null),Ye=(0,U.useRef)(null),[Xe,Ze]=(0,U.useState)(!1),[Qe,$e]=(0,U.useState)(``),[et,tt]=(0,U.useState)(``),[nt,rt]=(0,U.useState)(null),[it,at]=(0,U.useState)(!1),[K,ot]=(0,U.useState)(!1),[q,lt]=(0,U.useState)(``),[ut,dt]=(0,U.useState)(``),ft=(0,U.useDeferredValue)(q),pt=(0,U.useDeferredValue)(ut),[mt,gt]=(0,U.useTransition)(),_t=(0,U.useCallback)(()=>{je(!1),We(!1),Je(null),Ke(``),Fe(null)},[]),vt=(0,U.useCallback)(()=>{Ne(t_(r,`默认规则`)),je(!0),We(!1),Je(null),Ke(``),Fe(null)},[r]);(0,U.useEffect)(()=>{o().then(e=>{e.length>0&&!i&&s((e.find(e=>e.enabled)||e[0]).name)})},[]);let yt=(0,U.useCallback)(async e=>{await s(e)},[s]);(0,U.useEffect)(()=>{let e=!1;if(!i){Se.current=``;return}return c(i).then(t=>{e||(Se.current=t,fe(t))}).catch(()=>{if(!e){let e=j(t);Se.current=e,fe(e)}}).finally(()=>{e||be(i)}),()=>{e=!0}},[i,c]),(0,U.useEffect)(()=>{if(!i||M===`text`)return;let e=j(t);j(L(Se.current))!==e&&(Se.current=e,fe(e))},[i,t,M]),(0,U.useEffect)(()=>{Oe(e=>e.length===t.length?e:e.length>t.length?e.slice(0,t.length):[...e,...Array.from({length:t.length-e.length},()=>G())])},[G,t.length]);let bt=(0,U.useCallback)(async()=>{if(!Me.trim())return;Fe(null);let e=qe||``,t=await m(Me.trim(),e);t.success?(_t(),Ne(`默认规则`),await s(Me.trim())):Fe(t.error||`创建失败`)},[m,Me,qe,_t,s]),xt=(0,U.useCallback)(async()=>{if(de(window))try{let[e]=await window.showOpenFilePicker({types:[{description:`规则文件`,accept:{"text/plain":[`.txt`,`.rules`]}}],multiple:!1}),t=await e.getFile(),n=await t.text(),r=t.name.replace(/\.[^.]+$/,``);Je(n),Ke(r),Ne(r),We(!0),je(!0);return}catch{}Ye.current?.click()},[]),St=(0,U.useCallback)(e=>{let t=e.target.files?.[0];t&&t.text().then(e=>{let n=t.name.replace(/\.[^.]+$/,``);Je(e),Ke(n),Ne(n),We(!0),je(!0)}),e.target.value=``},[]),Ct=(0,U.useCallback)(()=>{$e(t_(r,`文本导入`)),tt(``),rt(null),at(!1),Ze(!0)},[r]),wt=(0,U.useMemo)(()=>L(B(et)),[et]),Tt=(0,U.useMemo)(()=>z(B(et)),[et]),Et=(0,U.useCallback)(async()=>{let e=Qe.trim();if(!e){rt(`规则文件名称不能为空`);return}let t=B(et);if(!t.trim()){rt(`请输入规则文本`);return}if(z(t).length>0){rt(`规则文本存在无法识别的行,请先修正`);return}at(!0);let n=await m(e,t);at(!1),n.success?(Ze(!1),await s(e)):rt(n.error||`创建失败`)},[m,s,et,Qe]),Dt=(0,U.useCallback)(async()=>{if(!i||M===`text`&&z(se).length>0)return;y(!0);let e=M===`text`?await l(i,se):await f(i,t);y(!1),e?(o(),ne.success(`规则保存成功`)):ne.error(`规则保存失败`)},[i,o,t,f,l,se,M]),Ot=(0,U.useCallback)(async e=>{confirm(`确定要删除规则文件「${e}」吗?`)&&await _(e)},[_]),kt=(0,U.useCallback)(e=>{Le(e),ze(e),Ve(null)},[]),At=(0,U.useCallback)(()=>{Le(null),ze(``),Ve(null)},[]),jt=(0,U.useCallback)(async()=>{if(!Ie||He.current)return;let e=Re.trim();if(!e){Ve(`规则文件名称不能为空`);return}if(e===Ie){At();return}He.current=!0;try{let t=await g(Ie,e);t.success?(Le(null),ze(``),Ve(null),await s(t.name||e)):Ve(t.error||`重命名失败`)}finally{He.current=!1}},[At,s,Re,g,Ie]),Mt=(0,U.useCallback)(e=>{gt(()=>n(t=>t.map((t,n)=>n===e?{...t,enabled:!t.enabled}:t)))},[n]),Nt=(0,U.useCallback)((e,t,r)=>{n(n=>n.map((n,i)=>i===e?{...n,[t]:r}:n))},[n]),Pt=(0,U.useCallback)(e=>{Oe(t=>t.filter((t,n)=>n!==e)),gt(()=>n(t=>t.filter((t,n)=>n!==e)))},[n]),Ft=(0,U.useCallback)(()=>{Oe(e=>[G(),...e]),gt(()=>n(e=>[{enabled:!0,rule:``,target:``,exclusions:[]},...e])),we(0)},[G,n]),It=(0,U.useCallback)(e=>{Oe(t=>hr(t,e,0)),gt(()=>n(t=>{let n=[...t],[r]=n.splice(e,1);return n.unshift(r),n})),we(0)},[n]),Lt=(0,U.useCallback)(e=>{Se.current=e,fe(e),n(L(e))},[n]),Rt=(0,U.useCallback)(e=>{let{active:t,over:r}=e,i=r?Vr(De,t.id,r.id):De;$g(i,De)||(Oe(i),n(e=>Hr(e,De,i)))},[De,n]),zt=ct(st(ln),st(rn,{coordinateGetter:Rr}));(0,U.useEffect)(()=>{if(Ce==null)return;let e=requestAnimationFrame(()=>{Te.current?.scrollIntoView({behavior:`smooth`,block:`center`})}),t=setTimeout(()=>we(null),1600);return()=>{cancelAnimationFrame(e),clearTimeout(t)}},[t,Ce]),(0,U.useEffect)(()=>{let e=e=>{let n=e.detail||{},r=n.pattern?.trim(),i=n.target?.trim();if(!r||i==null)return;let a=t.findIndex(e=>e.rule.trim()===r&&e.target.trim()===i);a<0||(ae(`table`),lt(``),dt(``),we(a))};return window.addEventListener(`route-rule:highlight`,e),()=>window.removeEventListener(`route-rule:highlight`,e)},[t]);let Bt=(0,U.useMemo)(()=>{if(!ft&&!pt)return t.map((e,t)=>({item:e,index:t}));let e=ft.toLowerCase(),n=pt.toLowerCase();return t.map((e,t)=>({item:e,index:t})).filter(({item:t})=>(!ft||t.rule.toLowerCase().includes(e))&&(!pt||t.target.toLowerCase().includes(n)))},[t,ft,pt]),Vt=(0,U.useMemo)(()=>{let e=t.map((e,t)=>({item:e,index:t,id:De[t]})).filter(e=>!!e.id),n=new Map(e.map(e=>[e.id,e]));return De.map(e=>n.get(e)).filter(e=>!!e)},[De,t]),Ht=(0,U.useMemo)(()=>{let e=new Set;return t.forEach(t=>{t.target.trim()&&e.add(t.target.trim())}),Array.from(e).sort()},[t]),Ut=(0,U.useMemo)(()=>Jr(t,Bt.map(({index:e})=>e)),[t,Bt]),Wt=i?se:``,Gt=!!(i&&ye!==i),Kt=(0,U.useMemo)(()=>z(Wt),[Wt]),qt=M===`text`&&Kt.length>0,Jt=!q&&!ut;N({active:!Xe,enabled:!!i&&!v&&!Gt&&!qt,priority:F.page,onSave:Dt});let Yt=(0,U.useCallback)(e=>()=>Mt(e),[Mt]),Xt=(0,U.useCallback)(e=>(t,n)=>Nt(e,t,n),[Nt]),Zt=(0,U.useCallback)(e=>()=>Pt(e),[Pt]),Qt=(0,U.useCallback)(e=>()=>It(e),[It]);return(0,W.jsxs)(`div`,{className:`app-page-stack`,children:[(0,W.jsxs)(T,{"data-testid":`rule-panel-card`,className:`min-h-0 flex-1 gap-0 overflow-hidden py-0 shadow-none`,children:[(0,W.jsxs)(`div`,{"data-slot":`rule-config-sticky-controls`,className:`shrink-0 rounded-t-xl bg-card`,children:[(0,W.jsxs)(E,{className:`block border-b bg-muted/30 p-0 [.border-b]:pb-0`,children:[(0,W.jsx)(ie,{className:`sr-only`,children:`规则内容`}),(0,W.jsxs)(`div`,{className:`flex min-w-0 items-center px-3 py-2`,children:[(0,W.jsx)(`div`,{"data-slot":`rule-file-tabs-scroll-wrap`,className:`meddle-tabs-scroll-wrap flex min-w-0 flex-1`,"data-shadow-left":ke.state.left?`true`:`false`,"data-shadow-right":ke.state.right?`true`:`false`,children:(0,W.jsx)(`div`,{"data-slot":`rule-file-tabs-scroll`,ref:ke.ref,className:`meddle-tabs-scroll min-w-0 flex-1 overflow-x-auto`,children:(0,W.jsx)(k,{className:`min-w-max`,value:i||``,onValueChange:yt,children:(0,W.jsx)(O,{className:`h-auto min-w-max justify-start gap-1 rounded-none bg-transparent p-0`,children:r.map(e=>(0,W.jsxs)(A,{value:e.name,className:`group relative flex-none gap-1.5`,children:[(0,W.jsx)(`span`,{role:`button`,tabIndex:0,className:`shrink-0`,onClick:t=>{t.stopPropagation(),h(e.name,!e.enabled)},onKeyDown:t=>{(t.key===`Enter`||t.key===` `)&&(t.preventDefault(),t.stopPropagation(),h(e.name,!e.enabled))},title:e.enabled?`点击禁用路由`:`点击启用路由`,children:e.enabled?(0,W.jsx)(ve,{className:`size-4 text-primary`}):(0,W.jsx)(_e,{className:`size-4 text-muted-foreground`})}),Ie===e.name?(0,W.jsx)(`input`,{value:Re,onChange:e=>{ze(e.target.value),Ve(null)},onClick:e=>e.stopPropagation(),onDoubleClick:e=>e.stopPropagation(),onFocus:e=>e.currentTarget.select(),onBlur:()=>void jt(),onKeyDown:e=>{e.stopPropagation(),e.key===`Enter`?(e.preventDefault(),jt()):e.key===`Escape`&&(e.preventDefault(),At())},className:`h-6 w-28 rounded border bg-background px-1.5 text-sm text-foreground outline-none focus:border-ring focus:ring-2 focus:ring-ring/30`,"aria-label":`重命名规则文件 ${e.name}`,autoFocus:!0}):(0,W.jsx)(`span`,{onDoubleClick:t=>{t.stopPropagation(),kt(e.name)},title:`双击重命名`,children:e.name}),(0,W.jsx)(x,{variant:`secondary`,className:`text-[10px] px-1 py-0`,children:e.ruleCount}),r.length>1&&(0,W.jsx)(`span`,{role:`button`,tabIndex:0,className:`opacity-0 group-hover:opacity-100 transition-opacity text-muted-foreground hover:text-destructive`,onClick:t=>{t.stopPropagation(),Ot(e.name)},onKeyDown:t=>{(t.key===`Enter`||t.key===` `)&&(t.preventDefault(),t.stopPropagation(),Ot(e.name))},title:`删除规则文件`,children:(0,W.jsx)(p,{className:`size-3`})})]},e.name))})})})}),(0,W.jsx)(`div`,{"data-slot":`rule-file-actions`,className:`ml-2 flex shrink-0 items-center border-l pl-2`,children:Ae?(0,W.jsxs)(`div`,{role:`group`,"aria-label":Ue?`从文件导入为新规则`:`创建新规则文件`,className:`flex h-8 items-center gap-1 rounded-md border border-primary/30 bg-background px-1 shadow-sm`,title:Ue&&Ge?`导入自: ${Ge}`:void 0,children:[(0,W.jsx)(R,{value:Me,onChange:e=>{Ne(e.target.value),Fe(null)},placeholder:`规则文件名称`,className:`h-6 w-36 border-0 bg-transparent px-1.5 shadow-none focus-visible:ring-0`,"aria-label":`新规则文件名称`,autoFocus:!0,onKeyDown:e=>{e.stopPropagation(),e.key===`Enter`?(e.preventDefault(),bt()):e.key===`Escape`&&(e.preventDefault(),_t())}}),(0,W.jsx)(a,{type:`button`,variant:`ghost`,size:`icon-xs`,onClick:()=>void bt(),"aria-label":`确认创建规则文件`,title:`创建`,children:(0,W.jsx)(re,{})}),(0,W.jsx)(a,{type:`button`,variant:`ghost`,size:`icon-xs`,onClick:_t,"aria-label":`取消创建规则文件`,title:`取消`,children:(0,W.jsx)(p,{})})]}):(0,W.jsxs)(W.Fragment,{children:[(0,W.jsx)(a,{type:`button`,variant:`ghost`,size:`icon-sm`,onClick:C,"aria-label":`查看所有规则`,title:`查看所有规则`,children:(0,W.jsx)(V,{})}),(0,W.jsx)(a,{type:`button`,variant:`ghost`,size:`icon-sm`,onClick:vt,"aria-label":`创建规则文件`,title:`创建规则文件`,children:(0,W.jsx)(u,{})})]})})]})]}),(0,W.jsxs)(`div`,{className:`flex flex-row flex-wrap items-center justify-between gap-3 border-b px-3 py-2`,children:[(0,W.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,W.jsxs)(ee,{type:`single`,value:M,onValueChange:e=>{e&&ae(e)},variant:`outline`,size:`sm`,spacing:0,className:`bg-background`,"aria-label":`规则视图`,children:[(0,W.jsxs)(b,{value:`table`,children:[(0,W.jsx)(d,{}),`表格`]}),(0,W.jsxs)(b,{value:`text`,children:[(0,W.jsx)(me,{}),`文本`]}),jg.ruleGraphView&&(0,W.jsxs)(b,{value:`graph`,children:[(0,W.jsx)(ge,{}),`图表`]})]}),mt&&(0,W.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`更新中...`})]}),(0,W.jsxs)(`div`,{className:`flex flex-wrap items-center justify-end gap-2`,children:[M!==`text`&&(0,W.jsxs)(a,{variant:K?`selected`:`outline`,size:`sm`,onClick:()=>ot(e=>!e),title:`显示/隐藏筛选器`,children:[(0,W.jsx)(I,{"data-icon":`inline-start`}),`筛选`]}),M===`table`&&(0,W.jsxs)(W.Fragment,{children:[(0,W.jsxs)(a,{variant:`outline`,size:`sm`,onClick:Ft,disabled:!i,children:[(0,W.jsx)(u,{"data-icon":`inline-start`}),`添加规则`]}),(0,W.jsx)(`input`,{ref:Ye,type:`file`,accept:`.txt,.rules`,className:`hidden`,onChange:St}),(0,W.jsxs)(a,{variant:`outline`,size:`sm`,onClick:xt,children:[(0,W.jsx)(he,{"data-icon":`inline-start`}),`从文件加载`]}),(0,W.jsxs)(a,{variant:`outline`,size:`sm`,onClick:Ct,children:[(0,W.jsx)(pe,{"data-icon":`inline-start`}),`文本导入`]})]}),i&&(0,W.jsxs)(te,{size:`sm`,onClick:Dt,disabled:v||Gt||qt,title:qt?`${Kt.length} 行内容无法识别,请先修正`:`保存 (⌘+S / Ctrl+S)`,children:[v?(0,W.jsx)(xe,{"data-icon":`inline-start`}):(0,W.jsx)(P,{"data-icon":`inline-start`}),`保存`]})]})]})]}),(Be||Pe)&&(0,W.jsxs)(`div`,{className:`flex shrink-0 flex-col gap-1 border-b px-3 py-2 text-xs text-destructive`,children:[Be&&(0,W.jsx)(`p`,{children:Be}),Pe&&(0,W.jsx)(`p`,{children:Pe})]}),K&&M!==`text`&&(0,W.jsxs)(`div`,{className:`flex shrink-0 flex-col gap-3 border-b bg-muted/20 p-3 md:flex-row md:items-end`,children:[(0,W.jsxs)(`div`,{className:`flex flex-1 flex-col gap-1`,children:[(0,W.jsx)(`label`,{className:`text-xs font-medium text-muted-foreground`,children:`筛选规则`}),(0,W.jsxs)(`div`,{className:`relative`,children:[(0,W.jsx)(R,{value:q,onChange:e=>lt(e.target.value),placeholder:`输入规则名称进行筛选...`,className:`h-9`}),q&&(0,W.jsx)(a,{variant:`ghost`,size:`icon-sm`,className:`absolute right-1 top-1/2 -translate-y-1/2`,onClick:()=>lt(``),"aria-label":`清除规则筛选`,children:(0,W.jsx)(p,{className:`h-3 w-3`})})]})]}),(0,W.jsxs)(`div`,{className:`flex flex-1 flex-col gap-1`,children:[(0,W.jsx)(`label`,{className:`text-xs font-medium text-muted-foreground`,children:`筛选目标`}),(0,W.jsxs)(`div`,{className:`relative`,children:[(0,W.jsx)(R,{value:ut,onChange:e=>dt(e.target.value),placeholder:`输入目标地址进行筛选...`,className:`h-9`,list:`target-list`}),(0,W.jsx)(`datalist`,{id:`target-list`,children:Ht.map(e=>(0,W.jsx)(`option`,{value:e},e))}),ut&&(0,W.jsx)(a,{variant:`ghost`,size:`icon-sm`,className:`absolute right-1 top-1/2 -translate-y-1/2`,onClick:()=>dt(``),"aria-label":`清除目标筛选`,children:(0,W.jsx)(p,{className:`h-3 w-3`})})]})]}),(q||ut)&&(0,W.jsx)(a,{variant:`outline`,size:`sm`,onClick:()=>{lt(``),dt(``)},className:`h-9`,children:`清除筛选`})]}),(0,W.jsx)(S,{className:`flex min-h-0 flex-1 flex-col overflow-hidden p-0`,children:M===`text`?(0,W.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col overflow-hidden`,children:[(0,W.jsx)(Ug,{ariaLabel:`规则文本`,value:Wt,onChange:Lt,disabled:!i||Gt,placeholder:i?`example.com !/api localhost:3000`:`请先选择或创建一个规则文件`}),(0,W.jsxs)(`div`,{className:`flex shrink-0 flex-wrap items-center justify-between gap-2 border-t px-4 py-2 text-xs text-muted-foreground`,children:[(0,W.jsx)(`span`,{children:Gt?`正在加载规则文本...`:`已解析 ${t.length} 条规则`}),Kt.length>0&&(0,W.jsxs)(x,{variant:`destructive`,title:`存在无法识别的行,保存已禁用`,children:[Kt.length,` 行未识别:`,Kt.slice(0,3).map(e=>e.line).join(`、`),Kt.length>3?`…`:``]})]})]}):M===`table`||!jg.ruleGraphView?(0,W.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col overflow-hidden`,children:[(0,W.jsx)(`div`,{"data-slot":`rule-table-header`,className:`z-10 shrink-0 overflow-x-auto bg-card`,children:(0,W.jsxs)(ue,{className:`table-fixed`,children:[(0,W.jsx)(a_,{showDragColumn:Jt}),(0,W.jsx)(oe,{children:(0,W.jsx)(o_,{showDragColumn:Jt})})]})}),(0,W.jsx)(D,{className:`min-h-0 flex-1`,children:(0,W.jsxs)(ue,{className:`table-fixed`,children:[(0,W.jsx)(a_,{showDragColumn:Jt}),(0,W.jsx)(ce,{children:i?t.length===0?(0,W.jsx)(le,{children:(0,W.jsx)(H,{colSpan:6,className:`text-center text-muted-foreground py-8`,children:`暂无规则,点击"添加规则"开始配置`})}):Bt.length===0?(0,W.jsx)(le,{children:(0,W.jsx)(H,{colSpan:6,className:`text-center text-muted-foreground py-8`,children:`没有匹配的规则,请调整筛选条件`})}):q||ut?Bt.map(({item:e,index:t})=>(0,W.jsx)(i_,{item:e,highlighted:Ce===t,highlightRef:Te,onToggle:Yt(t),onUpdateRule:Xt(t),onDelete:Zt(t),onMoveToTop:Qt(t)},t)):(0,W.jsx)(or,{sensors:zt,collisionDetection:ht,onDragEnd:Rt,children:(0,W.jsx)(Er,{items:Vt.map(e=>e.id),strategy:Sr,children:Vt.map(({item:e,index:t,id:n})=>(0,W.jsx)(r_,{id:n,item:e,highlighted:Ce===t,highlightRef:Te,onToggle:Yt(t),onUpdateRule:Xt(t),onDelete:Zt(t),onMoveToTop:Qt(t)},n))})}):(0,W.jsx)(le,{children:(0,W.jsx)(H,{colSpan:6,className:`text-center text-muted-foreground py-8`,children:`请选择或创建一个规则文件`})})})]})})]}):(0,W.jsx)(D,{className:`min-h-0 flex-1`,children:(0,W.jsx)(`div`,{className:`flex flex-col gap-4 p-4`,children:i?t.length===0?(0,W.jsx)(`div`,{className:`rounded-xl border border-dashed p-8 text-center text-muted-foreground`,children:`暂无规则,点击“添加规则”后这里会自动生成路由流向图`}):Bt.length===0?(0,W.jsx)(`div`,{className:`rounded-xl border border-dashed p-8 text-center text-muted-foreground`,children:`没有匹配的规则,请调整筛选条件后再查看图表`}):(0,W.jsx)(Ag,{graphData:Ut}):(0,W.jsx)(`div`,{className:`rounded-xl border border-dashed p-8 text-center text-muted-foreground`,children:`请选择或创建一个规则文件后查看图表`})})})}),(q||ut)&&Bt.length>0&&(0,W.jsxs)(w,{className:`shrink-0 border-t px-4 py-2 text-sm text-muted-foreground [.border-t]:pt-2`,children:[`显示 `,Bt.length,` / `,t.length,` 条规则`]})]}),(0,W.jsx)(Wg,{open:Xe,onOpenChange:Ze,children:(0,W.jsxs)(qg,{className:`flex max-h-[90vh] flex-col gap-4 sm:max-w-2xl`,children:[(0,W.jsxs)(Jg,{children:[(0,W.jsx)(Xg,{children:`文本导入`}),(0,W.jsxs)(Zg,{children:[`粘贴或编辑规则文本,支持 hosts 文件格式自动转换。每行一条规则,格式:`,(0,W.jsx)(`code`,{className:`rounded bg-muted px-1 py-0.5 font-mono text-xs`,children:`规则 [排除项] 目标`})]})]}),(0,W.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,W.jsx)(`label`,{className:`text-xs font-medium text-muted-foreground`,htmlFor:`text-import-name`,children:`规则文件名称`}),(0,W.jsx)(R,{id:`text-import-name`,value:Qe,onChange:e=>{$e(e.target.value),rt(null)},placeholder:`规则文件名称`,className:`font-mono`})]}),(0,W.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col gap-2 overflow-hidden`,children:[(0,W.jsx)(`label`,{className:`text-xs font-medium text-muted-foreground`,htmlFor:`text-import-content`,children:`规则文本`}),(0,W.jsx)(`div`,{className:`min-h-[220px] flex-1 overflow-hidden rounded-md border`,children:(0,W.jsx)(Ug,{ariaLabel:`导入规则文本`,value:et,onChange:tt,placeholder:`127.0.0.1 example.com api.example.com
15
15
  ::1 local.example.test`})}),(0,W.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-2 text-xs text-muted-foreground`,children:[(0,W.jsxs)(`span`,{children:[`已解析 `,wt.length,` 条规则`]}),Tt.length>0&&(0,W.jsxs)(x,{variant:`destructive`,children:[Tt.length,` 行未识别:`,Tt.slice(0,3).map(e=>e.line).join(`、`),Tt.length>3?`…`:``]})]})]}),nt&&(0,W.jsx)(`p`,{className:`text-xs text-destructive`,children:nt}),(0,W.jsxs)(Yg,{children:[(0,W.jsx)(a,{variant:`outline`,onClick:()=>Ze(!1),disabled:it,children:`取消`}),(0,W.jsxs)(a,{onClick:Et,disabled:it,children:[it?(0,W.jsx)(xe,{"data-icon":`inline-start`}):(0,W.jsx)(re,{"data-icon":`inline-start`}),`确认创建`]})]})]})})]})}export{s_ as RuleConfig};
@@ -1 +1 @@
1
- import{a as e,f as t,t as n,u as r}from"./button-BTToMaBW.js";import"./dist-C6eaYCUo.js";import{t as i}from"./refresh-cw-CG3HaiQT.js";import{t as a}from"./table-2-BR5e3z8m.js";import{$ as o,A as s,B as c,C as l,D as u,E as d,G as f,M as p,O as m,S as h,T as g,a as _,j as v,k as y,lt as ee,rt as te,w as b}from"./index-B-2u47xL.js";import{a as x,i as S,n as C,o as w,r as T,t as E}from"./table-nW7uQVcl.js";var D=t(r(),1),O=e(),k=`border-l-2 border-l-transparent`,A=`text-muted-foreground opacity-75`;function j(e){return e.length>0?e.map(e=>`!${e}`).join(` `):`—`}function M({rules:e,activeFileName:t,onLocateRule:r,onSelectFile:M}){let[N,ne]=(0,D.useState)(null),[P,F]=(0,D.useState)(!0),[I,L]=(0,D.useState)(null),[R,z]=(0,D.useState)(`merged`),[B,V]=(0,D.useState)(``),H=(0,D.useDeferredValue)(B),U=(0,D.useCallback)(async()=>{F(!0),L(null);try{let e=await fetch(`/api/rule-files/overview`);if(!e.ok)throw Error(`加载失败(${e.status})`);ne(await e.json())}catch(e){L(e instanceof Error?e.message:`加载失败`)}finally{F(!1)}},[]);(0,D.useEffect)(()=>{U()},[U]);let W=(0,D.useMemo)(()=>N?.perFileRules.find(e=>e.name===t)??null,[N,t]),G=(0,D.useMemo)(()=>{if(!W||W.error)return!1;let t=W.rules.map(e=>({rule:e.rawRule,target:e.rawTarget,enabled:e.enabled,exclusions:e.exclusions}));return _(e)!==_(t)},[W,e]),K=(0,D.useMemo)(()=>{let e=new Map;for(let t of N?.conflicts??[])e.set(t.pattern,t);return e},[N]),q=(0,D.useCallback)(e=>{let t=H.trim().toLowerCase();return t?e.some(e=>e&&e.toLowerCase().includes(t)):!0},[H]),J=(0,D.useMemo)(()=>(N?.mergedRules??[]).map(e=>({winner:e,shadowed:K.get(e.pattern)?.shadowed??[]})).filter(({winner:e,shadowed:t})=>q([e.rawRule,e.rawTarget,e.file])||t.some(e=>q([e.rawRule,e.rawTarget,e.file]))),[N,K,q]),Y=N?.mergedRules.length??0,X=N?.conflicts.reduce((e,t)=>e+t.shadowed.length,0)??0,Z=(0,D.useMemo)(()=>(N?.perFileRules??[]).map(e=>({...e,matched:e.rules.filter(t=>q([t.rawRule,t.rawTarget,e.name]))})).filter(e=>e.error!=null||q([e.name])||e.matched.length>0),[N,q]),re=N?.perFileRules.reduce((e,t)=>e+t.rules.length,0)??0,ie=Z.reduce((e,t)=>e+t.matched.length,0),Q=(0,D.useCallback)((e,t,n)=>{r(e,t,n)},[r]),ae=(0,D.useCallback)((e,t)=>{(e.key===`Enter`||e.key===` `)&&(e.preventDefault(),M(t))},[M]),oe=()=>{if(P)return(0,O.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col gap-2 p-2`,children:[(0,O.jsx)(p,{className:`h-8 w-full`}),(0,O.jsx)(p,{className:`h-8 w-full`}),(0,O.jsx)(p,{className:`h-8 w-3/4`})]});if(I)return(0,O.jsxs)(l,{className:`min-h-0 flex-1`,children:[(0,O.jsxs)(d,{children:[(0,O.jsx)(u,{variant:`icon`,children:(0,O.jsx)(f,{})}),(0,O.jsx)(m,{children:`加载失败`}),(0,O.jsx)(g,{children:I})]}),(0,O.jsx)(b,{children:(0,O.jsxs)(n,{variant:`outline`,onClick:()=>void U(),children:[(0,O.jsx)(i,{"data-icon":`inline-start`}),`重试`]})})]});let e=(N?.files.length??0)>0,t=N?.perFileRules.some(e=>e.rules.length>0||e.error!=null)??!1,r=H.trim().length>0;return e?t?R===`merged`&&!r&&(N?.mergedRules.length??0)===0?(0,O.jsx)(l,{className:`min-h-0 flex-1`,children:(0,O.jsxs)(d,{children:[(0,O.jsx)(u,{variant:`icon`,children:(0,O.jsx)(te,{})}),(0,O.jsx)(m,{children:`没有生效中的规则`}),(0,O.jsx)(g,{children:`规则全部被禁用,或没有启用任何规则文件;切换到「按文件」查看全部规则`})]})}):r&&R===`merged`&&J.length===0||r&&R===`files`&&Z.every(e=>e.matched.length===0&&e.error==null)?$():R===`merged`?se():ce():(0,O.jsx)(l,{className:`min-h-0 flex-1`,children:(0,O.jsxs)(d,{children:[(0,O.jsx)(u,{variant:`icon`,children:(0,O.jsx)(ee,{})}),(0,O.jsx)(m,{children:`所有规则文件都是空的`}),(0,O.jsx)(g,{children:`还没有任何路由规则,先去路由规则页添加一条吧`})]})}):(0,O.jsx)(l,{className:`min-h-0 flex-1`,children:(0,O.jsxs)(d,{children:[(0,O.jsx)(u,{variant:`icon`,children:(0,O.jsx)(a,{})}),(0,O.jsx)(m,{children:`还没有规则文件`}),(0,O.jsx)(g,{children:`在路由规则页点击「+」创建第一个规则文件`})]})})},$=()=>(0,O.jsxs)(l,{className:`min-h-0 flex-1`,children:[(0,O.jsxs)(d,{children:[(0,O.jsx)(u,{variant:`icon`,children:(0,O.jsx)(o,{})}),(0,O.jsx)(m,{children:`无匹配结果`}),(0,O.jsxs)(g,{children:[`没有找到符合「`,H.trim(),`」的规则`]})]}),(0,O.jsx)(b,{children:(0,O.jsx)(n,{variant:`outline`,onClick:()=>V(``),children:`清空筛选`})})]}),se=()=>(0,O.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col overflow-hidden rounded-md border`,children:[(0,O.jsx)(`div`,{className:`shrink-0 overflow-x-auto bg-card`,children:(0,O.jsxs)(E,{className:`table-fixed`,children:[(0,O.jsxs)(`colgroup`,{children:[(0,O.jsx)(`col`,{style:{width:`6rem`}}),(0,O.jsx)(`col`,{}),(0,O.jsx)(`col`,{style:{width:`8rem`}}),(0,O.jsx)(`col`,{})]}),(0,O.jsx)(x,{children:(0,O.jsxs)(w,{children:[(0,O.jsx)(S,{children:`来源`}),(0,O.jsx)(S,{children:`规则`}),(0,O.jsx)(S,{className:`hidden md:table-cell`,children:`排除`}),(0,O.jsx)(S,{children:`目标`})]})})]})}),(0,O.jsx)(h,{className:`min-h-0 flex-1`,children:(0,O.jsxs)(E,{className:`table-fixed`,children:[(0,O.jsxs)(`colgroup`,{children:[(0,O.jsx)(`col`,{style:{width:`6rem`}}),(0,O.jsx)(`col`,{}),(0,O.jsx)(`col`,{style:{width:`8rem`}}),(0,O.jsx)(`col`,{})]}),(0,O.jsx)(C,{children:J.map(({winner:e,shadowed:t})=>(0,O.jsxs)(D.Fragment,{children:[(0,O.jsxs)(w,{className:`${k} cursor-pointer`,onClick:()=>Q(e.file,e.rawRule,e.rawTarget),title:`点击定位到该规则`,children:[(0,O.jsx)(T,{className:`truncate text-xs text-muted-foreground`,children:e.file}),(0,O.jsxs)(T,{className:`break-all font-mono text-xs`,children:[e.rawRule,t.length>0&&(0,O.jsx)(c,{variant:`default`,className:`ml-2 px-1 py-0 text-[10px]`,title:`同名规则最终生效的定义`,children:`生效`})]}),(0,O.jsx)(T,{className:`hidden break-all font-mono text-xs text-muted-foreground md:table-cell`,children:j(e.exclusions)}),(0,O.jsx)(T,{className:`break-all font-mono text-xs`,children:e.rawTarget})]}),t.map((t,n)=>(0,O.jsxs)(w,{className:`${k} cursor-pointer ${A}`,onClick:()=>Q(t.file,t.rawRule,t.rawTarget),title:`点击定位到该规则`,children:[(0,O.jsx)(T,{className:`truncate text-xs`,children:t.file}),(0,O.jsx)(T,{className:`break-all font-mono text-xs`,children:(0,O.jsxs)(`span`,{className:`inline-flex flex-wrap items-center gap-1.5`,children:[t.rawRule,(0,O.jsx)(c,{variant:`destructive`,className:`px-1 py-0 text-[10px]`,title:`已被 ${e.file} 中的同名规则覆盖,实际不生效`,children:`已被覆盖`})]})}),(0,O.jsx)(T,{className:`hidden break-all font-mono text-xs md:table-cell`,children:`—`}),(0,O.jsx)(T,{className:`break-all font-mono text-xs`,children:t.rawTarget})]},`merged-shadowed-${n}`))]},`merged-group-${e.pattern}`))})]})})]}),ce=()=>(0,O.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col overflow-hidden rounded-md border`,children:[(0,O.jsx)(`div`,{className:`shrink-0 overflow-x-auto bg-card`,children:(0,O.jsxs)(E,{className:`table-fixed`,children:[(0,O.jsxs)(`colgroup`,{children:[(0,O.jsx)(`col`,{style:{width:`3.5rem`}}),(0,O.jsx)(`col`,{}),(0,O.jsx)(`col`,{style:{width:`8rem`}}),(0,O.jsx)(`col`,{})]}),(0,O.jsx)(x,{children:(0,O.jsxs)(w,{children:[(0,O.jsx)(S,{children:`状态`}),(0,O.jsx)(S,{children:`规则`}),(0,O.jsx)(S,{className:`hidden md:table-cell`,children:`排除`}),(0,O.jsx)(S,{children:`目标`})]})})]})}),(0,O.jsx)(h,{className:`min-h-0 flex-1`,children:(0,O.jsxs)(E,{className:`table-fixed`,children:[(0,O.jsxs)(`colgroup`,{children:[(0,O.jsx)(`col`,{style:{width:`3.5rem`}}),(0,O.jsx)(`col`,{}),(0,O.jsx)(`col`,{style:{width:`8rem`}}),(0,O.jsx)(`col`,{})]}),(0,O.jsx)(C,{children:Z.map(e=>(0,O.jsxs)(D.Fragment,{children:[(0,O.jsx)(w,{className:`hover:bg-accent/60`,children:(0,O.jsx)(T,{colSpan:4,className:`cursor-pointer bg-muted/50 p-2 align-middle`,role:`button`,tabIndex:0,onClick:()=>M(e.name),onKeyDown:t=>ae(t,e.name),title:`点击切换到该规则文件`,children:(0,O.jsxs)(`span`,{className:`flex flex-wrap items-center gap-2 font-medium`,children:[e.name,(0,O.jsx)(c,{variant:e.enabled?`default`:`secondary`,className:`px-1 py-0 text-[10px]`,children:e.enabled?`启用`:`禁用`}),(0,O.jsx)(c,{variant:`secondary`,className:`px-1 py-0 text-[10px]`,children:e.rules.length})]})})}),e.error&&(0,O.jsx)(w,{className:`text-destructive`,children:(0,O.jsx)(T,{colSpan:4,className:`p-2 text-xs`,children:(0,O.jsxs)(`span`,{className:`flex items-center gap-2`,children:[(0,O.jsx)(f,{className:`h-3.5 w-3.5 shrink-0`}),`读取失败:`,e.error]})})}),e.matched.map((t,n)=>(0,O.jsxs)(w,{className:`cursor-pointer ${t.enabled?``:`opacity-60`}`,onClick:()=>Q(e.name,t.rawRule,t.rawTarget),title:`点击定位到该规则`,children:[(0,O.jsx)(T,{children:(0,O.jsx)(c,{variant:t.enabled?`default`:`secondary`,className:`px-1 py-0 text-[10px]`,children:t.enabled?`启用`:`禁用`})}),(0,O.jsx)(T,{className:`break-all font-mono text-xs`,children:t.rawRule}),(0,O.jsx)(T,{className:`hidden break-all font-mono text-xs text-muted-foreground md:table-cell`,children:j(t.exclusions)}),(0,O.jsx)(T,{className:`break-all font-mono text-xs ${t.enabled?``:`line-through`}`,children:t.rawTarget})]},`file-rule-${n}`))]},`file-group-${e.name}`))})]})})]}),le=R===`merged`?Y+X:re,ue=R===`merged`?J.reduce((e,t)=>e+1+t.shadowed.length,0):ie;return(0,O.jsxs)(`div`,{className:`app-panel-content flex h-full flex-col gap-3`,children:[(0,O.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,O.jsxs)(y,{type:`single`,value:R,onValueChange:e=>{e&&z(e)},variant:`outline`,size:`sm`,className:`bg-background`,"aria-label":`总览视图`,children:[(0,O.jsx)(s,{value:`merged`,children:`生效规则`}),(0,O.jsx)(s,{value:`files`,children:`按文件`})]}),(0,O.jsxs)(`div`,{className:`relative min-w-40 flex-1`,children:[(0,O.jsx)(o,{className:`pointer-events-none absolute top-1/2 left-2 h-4 w-4 -translate-y-1/2 text-muted-foreground`}),(0,O.jsx)(v,{value:B,onChange:e=>V(e.target.value),placeholder:`搜索规则 / 目标 / 文件名`,className:`h-8 pl-8`,"aria-label":`搜索规则`})]}),(0,O.jsx)(n,{type:`button`,variant:`ghost`,size:`icon-sm`,onClick:()=>void U(),disabled:P,"aria-label":`刷新总览`,title:`刷新`,children:(0,O.jsx)(i,{})})]}),G&&(0,O.jsxs)(`div`,{className:`flex items-center gap-2 rounded-md border border-amber-200 bg-amber-50 px-3 py-2 text-xs text-amber-800`,children:[(0,O.jsx)(f,{className:`h-3.5 w-3.5 shrink-0`}),(0,O.jsxs)(`span`,{children:[`「`,t,`」有未保存修改,此处展示的是代理当前使用的`,(0,O.jsx)(`b`,{children:`已保存内容`})]})]}),!P&&!I&&(N?.files.length??0)>0&&(0,O.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-2 text-xs text-muted-foreground`,children:[(0,O.jsxs)(`span`,{children:[ue,` / `,le,` 条`,R===`merged`&&H.trim()===``&&X>0?`,其中 ${X} 条被同名规则覆盖`:``]}),R===`merged`&&(0,O.jsx)(`span`,{children:`按代理实际生效顺序排列(后定义覆盖先定义)`}),R===`files`&&(0,O.jsx)(`span`,{children:`点击文件名切换到该文件`})]}),oe()]})}export{M as RuleOverviewPanel};
1
+ import{a as e,f as t,t as n,u as r}from"./button-BTToMaBW.js";import"./dist-C6eaYCUo.js";import{t as i}from"./refresh-cw-CG3HaiQT.js";import{t as a}from"./table-2-BR5e3z8m.js";import{$ as o,A as s,B as c,C as l,D as u,E as d,G as f,M as p,O as m,S as h,T as g,a as _,j as v,k as y,lt as ee,rt as te,w as b}from"./index-CvTR1IVi.js";import{a as x,i as S,n as C,o as w,r as T,t as E}from"./table-nW7uQVcl.js";var D=t(r(),1),O=e(),k=`border-l-2 border-l-transparent`,A=`text-muted-foreground opacity-75`;function j(e){return e.length>0?e.map(e=>`!${e}`).join(` `):`—`}function M({rules:e,activeFileName:t,onLocateRule:r,onSelectFile:M}){let[N,ne]=(0,D.useState)(null),[P,F]=(0,D.useState)(!0),[I,L]=(0,D.useState)(null),[R,z]=(0,D.useState)(`merged`),[B,V]=(0,D.useState)(``),H=(0,D.useDeferredValue)(B),U=(0,D.useCallback)(async()=>{F(!0),L(null);try{let e=await fetch(`/api/rule-files/overview`);if(!e.ok)throw Error(`加载失败(${e.status})`);ne(await e.json())}catch(e){L(e instanceof Error?e.message:`加载失败`)}finally{F(!1)}},[]);(0,D.useEffect)(()=>{U()},[U]);let W=(0,D.useMemo)(()=>N?.perFileRules.find(e=>e.name===t)??null,[N,t]),G=(0,D.useMemo)(()=>{if(!W||W.error)return!1;let t=W.rules.map(e=>({rule:e.rawRule,target:e.rawTarget,enabled:e.enabled,exclusions:e.exclusions}));return _(e)!==_(t)},[W,e]),K=(0,D.useMemo)(()=>{let e=new Map;for(let t of N?.conflicts??[])e.set(t.pattern,t);return e},[N]),q=(0,D.useCallback)(e=>{let t=H.trim().toLowerCase();return t?e.some(e=>e&&e.toLowerCase().includes(t)):!0},[H]),J=(0,D.useMemo)(()=>(N?.mergedRules??[]).map(e=>({winner:e,shadowed:K.get(e.pattern)?.shadowed??[]})).filter(({winner:e,shadowed:t})=>q([e.rawRule,e.rawTarget,e.file])||t.some(e=>q([e.rawRule,e.rawTarget,e.file]))),[N,K,q]),Y=N?.mergedRules.length??0,X=N?.conflicts.reduce((e,t)=>e+t.shadowed.length,0)??0,Z=(0,D.useMemo)(()=>(N?.perFileRules??[]).map(e=>({...e,matched:e.rules.filter(t=>q([t.rawRule,t.rawTarget,e.name]))})).filter(e=>e.error!=null||q([e.name])||e.matched.length>0),[N,q]),re=N?.perFileRules.reduce((e,t)=>e+t.rules.length,0)??0,ie=Z.reduce((e,t)=>e+t.matched.length,0),Q=(0,D.useCallback)((e,t,n)=>{r(e,t,n)},[r]),ae=(0,D.useCallback)((e,t)=>{(e.key===`Enter`||e.key===` `)&&(e.preventDefault(),M(t))},[M]),oe=()=>{if(P)return(0,O.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col gap-2 p-2`,children:[(0,O.jsx)(p,{className:`h-8 w-full`}),(0,O.jsx)(p,{className:`h-8 w-full`}),(0,O.jsx)(p,{className:`h-8 w-3/4`})]});if(I)return(0,O.jsxs)(l,{className:`min-h-0 flex-1`,children:[(0,O.jsxs)(d,{children:[(0,O.jsx)(u,{variant:`icon`,children:(0,O.jsx)(f,{})}),(0,O.jsx)(m,{children:`加载失败`}),(0,O.jsx)(g,{children:I})]}),(0,O.jsx)(b,{children:(0,O.jsxs)(n,{variant:`outline`,onClick:()=>void U(),children:[(0,O.jsx)(i,{"data-icon":`inline-start`}),`重试`]})})]});let e=(N?.files.length??0)>0,t=N?.perFileRules.some(e=>e.rules.length>0||e.error!=null)??!1,r=H.trim().length>0;return e?t?R===`merged`&&!r&&(N?.mergedRules.length??0)===0?(0,O.jsx)(l,{className:`min-h-0 flex-1`,children:(0,O.jsxs)(d,{children:[(0,O.jsx)(u,{variant:`icon`,children:(0,O.jsx)(te,{})}),(0,O.jsx)(m,{children:`没有生效中的规则`}),(0,O.jsx)(g,{children:`规则全部被禁用,或没有启用任何规则文件;切换到「按文件」查看全部规则`})]})}):r&&R===`merged`&&J.length===0||r&&R===`files`&&Z.every(e=>e.matched.length===0&&e.error==null)?$():R===`merged`?se():ce():(0,O.jsx)(l,{className:`min-h-0 flex-1`,children:(0,O.jsxs)(d,{children:[(0,O.jsx)(u,{variant:`icon`,children:(0,O.jsx)(ee,{})}),(0,O.jsx)(m,{children:`所有规则文件都是空的`}),(0,O.jsx)(g,{children:`还没有任何路由规则,先去路由规则页添加一条吧`})]})}):(0,O.jsx)(l,{className:`min-h-0 flex-1`,children:(0,O.jsxs)(d,{children:[(0,O.jsx)(u,{variant:`icon`,children:(0,O.jsx)(a,{})}),(0,O.jsx)(m,{children:`还没有规则文件`}),(0,O.jsx)(g,{children:`在路由规则页点击「+」创建第一个规则文件`})]})})},$=()=>(0,O.jsxs)(l,{className:`min-h-0 flex-1`,children:[(0,O.jsxs)(d,{children:[(0,O.jsx)(u,{variant:`icon`,children:(0,O.jsx)(o,{})}),(0,O.jsx)(m,{children:`无匹配结果`}),(0,O.jsxs)(g,{children:[`没有找到符合「`,H.trim(),`」的规则`]})]}),(0,O.jsx)(b,{children:(0,O.jsx)(n,{variant:`outline`,onClick:()=>V(``),children:`清空筛选`})})]}),se=()=>(0,O.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col overflow-hidden rounded-md border`,children:[(0,O.jsx)(`div`,{className:`shrink-0 overflow-x-auto bg-card`,children:(0,O.jsxs)(E,{className:`table-fixed`,children:[(0,O.jsxs)(`colgroup`,{children:[(0,O.jsx)(`col`,{style:{width:`6rem`}}),(0,O.jsx)(`col`,{}),(0,O.jsx)(`col`,{style:{width:`8rem`}}),(0,O.jsx)(`col`,{})]}),(0,O.jsx)(x,{children:(0,O.jsxs)(w,{children:[(0,O.jsx)(S,{children:`来源`}),(0,O.jsx)(S,{children:`规则`}),(0,O.jsx)(S,{className:`hidden md:table-cell`,children:`排除`}),(0,O.jsx)(S,{children:`目标`})]})})]})}),(0,O.jsx)(h,{className:`min-h-0 flex-1`,children:(0,O.jsxs)(E,{className:`table-fixed`,children:[(0,O.jsxs)(`colgroup`,{children:[(0,O.jsx)(`col`,{style:{width:`6rem`}}),(0,O.jsx)(`col`,{}),(0,O.jsx)(`col`,{style:{width:`8rem`}}),(0,O.jsx)(`col`,{})]}),(0,O.jsx)(C,{children:J.map(({winner:e,shadowed:t})=>(0,O.jsxs)(D.Fragment,{children:[(0,O.jsxs)(w,{className:`${k} cursor-pointer`,onClick:()=>Q(e.file,e.rawRule,e.rawTarget),title:`点击定位到该规则`,children:[(0,O.jsx)(T,{className:`truncate text-xs text-muted-foreground`,children:e.file}),(0,O.jsxs)(T,{className:`break-all font-mono text-xs`,children:[e.rawRule,t.length>0&&(0,O.jsx)(c,{variant:`default`,className:`ml-2 px-1 py-0 text-[10px]`,title:`同名规则最终生效的定义`,children:`生效`})]}),(0,O.jsx)(T,{className:`hidden break-all font-mono text-xs text-muted-foreground md:table-cell`,children:j(e.exclusions)}),(0,O.jsx)(T,{className:`break-all font-mono text-xs`,children:e.rawTarget})]}),t.map((t,n)=>(0,O.jsxs)(w,{className:`${k} cursor-pointer ${A}`,onClick:()=>Q(t.file,t.rawRule,t.rawTarget),title:`点击定位到该规则`,children:[(0,O.jsx)(T,{className:`truncate text-xs`,children:t.file}),(0,O.jsx)(T,{className:`break-all font-mono text-xs`,children:(0,O.jsxs)(`span`,{className:`inline-flex flex-wrap items-center gap-1.5`,children:[t.rawRule,(0,O.jsx)(c,{variant:`destructive`,className:`px-1 py-0 text-[10px]`,title:`已被 ${e.file} 中的同名规则覆盖,实际不生效`,children:`已被覆盖`})]})}),(0,O.jsx)(T,{className:`hidden break-all font-mono text-xs md:table-cell`,children:`—`}),(0,O.jsx)(T,{className:`break-all font-mono text-xs`,children:t.rawTarget})]},`merged-shadowed-${n}`))]},`merged-group-${e.pattern}`))})]})})]}),ce=()=>(0,O.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col overflow-hidden rounded-md border`,children:[(0,O.jsx)(`div`,{className:`shrink-0 overflow-x-auto bg-card`,children:(0,O.jsxs)(E,{className:`table-fixed`,children:[(0,O.jsxs)(`colgroup`,{children:[(0,O.jsx)(`col`,{style:{width:`3.5rem`}}),(0,O.jsx)(`col`,{}),(0,O.jsx)(`col`,{style:{width:`8rem`}}),(0,O.jsx)(`col`,{})]}),(0,O.jsx)(x,{children:(0,O.jsxs)(w,{children:[(0,O.jsx)(S,{children:`状态`}),(0,O.jsx)(S,{children:`规则`}),(0,O.jsx)(S,{className:`hidden md:table-cell`,children:`排除`}),(0,O.jsx)(S,{children:`目标`})]})})]})}),(0,O.jsx)(h,{className:`min-h-0 flex-1`,children:(0,O.jsxs)(E,{className:`table-fixed`,children:[(0,O.jsxs)(`colgroup`,{children:[(0,O.jsx)(`col`,{style:{width:`3.5rem`}}),(0,O.jsx)(`col`,{}),(0,O.jsx)(`col`,{style:{width:`8rem`}}),(0,O.jsx)(`col`,{})]}),(0,O.jsx)(C,{children:Z.map(e=>(0,O.jsxs)(D.Fragment,{children:[(0,O.jsx)(w,{className:`hover:bg-accent/60`,children:(0,O.jsx)(T,{colSpan:4,className:`cursor-pointer bg-muted/50 p-2 align-middle`,role:`button`,tabIndex:0,onClick:()=>M(e.name),onKeyDown:t=>ae(t,e.name),title:`点击切换到该规则文件`,children:(0,O.jsxs)(`span`,{className:`flex flex-wrap items-center gap-2 font-medium`,children:[e.name,(0,O.jsx)(c,{variant:e.enabled?`default`:`secondary`,className:`px-1 py-0 text-[10px]`,children:e.enabled?`启用`:`禁用`}),(0,O.jsx)(c,{variant:`secondary`,className:`px-1 py-0 text-[10px]`,children:e.rules.length})]})})}),e.error&&(0,O.jsx)(w,{className:`text-destructive`,children:(0,O.jsx)(T,{colSpan:4,className:`p-2 text-xs`,children:(0,O.jsxs)(`span`,{className:`flex items-center gap-2`,children:[(0,O.jsx)(f,{className:`h-3.5 w-3.5 shrink-0`}),`读取失败:`,e.error]})})}),e.matched.map((t,n)=>(0,O.jsxs)(w,{className:`cursor-pointer ${t.enabled?``:`opacity-60`}`,onClick:()=>Q(e.name,t.rawRule,t.rawTarget),title:`点击定位到该规则`,children:[(0,O.jsx)(T,{children:(0,O.jsx)(c,{variant:t.enabled?`default`:`secondary`,className:`px-1 py-0 text-[10px]`,children:t.enabled?`启用`:`禁用`})}),(0,O.jsx)(T,{className:`break-all font-mono text-xs`,children:t.rawRule}),(0,O.jsx)(T,{className:`hidden break-all font-mono text-xs text-muted-foreground md:table-cell`,children:j(t.exclusions)}),(0,O.jsx)(T,{className:`break-all font-mono text-xs ${t.enabled?``:`line-through`}`,children:t.rawTarget})]},`file-rule-${n}`))]},`file-group-${e.name}`))})]})})]}),le=R===`merged`?Y+X:re,ue=R===`merged`?J.reduce((e,t)=>e+1+t.shadowed.length,0):ie;return(0,O.jsxs)(`div`,{className:`app-panel-content flex h-full flex-col gap-3`,children:[(0,O.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,O.jsxs)(y,{type:`single`,value:R,onValueChange:e=>{e&&z(e)},variant:`outline`,size:`sm`,className:`bg-background`,"aria-label":`总览视图`,children:[(0,O.jsx)(s,{value:`merged`,children:`生效规则`}),(0,O.jsx)(s,{value:`files`,children:`按文件`})]}),(0,O.jsxs)(`div`,{className:`relative min-w-40 flex-1`,children:[(0,O.jsx)(o,{className:`pointer-events-none absolute top-1/2 left-2 h-4 w-4 -translate-y-1/2 text-muted-foreground`}),(0,O.jsx)(v,{value:B,onChange:e=>V(e.target.value),placeholder:`搜索规则 / 目标 / 文件名`,className:`h-8 pl-8`,"aria-label":`搜索规则`})]}),(0,O.jsx)(n,{type:`button`,variant:`ghost`,size:`icon-sm`,onClick:()=>void U(),disabled:P,"aria-label":`刷新总览`,title:`刷新`,children:(0,O.jsx)(i,{})})]}),G&&(0,O.jsxs)(`div`,{className:`flex items-center gap-2 rounded-md border border-amber-200 bg-amber-50 px-3 py-2 text-xs text-amber-800`,children:[(0,O.jsx)(f,{className:`h-3.5 w-3.5 shrink-0`}),(0,O.jsxs)(`span`,{children:[`「`,t,`」有未保存修改,此处展示的是代理当前使用的`,(0,O.jsx)(`b`,{children:`已保存内容`})]})]}),!P&&!I&&(N?.files.length??0)>0&&(0,O.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-2 text-xs text-muted-foreground`,children:[(0,O.jsxs)(`span`,{children:[ue,` / `,le,` 条`,R===`merged`&&H.trim()===``&&X>0?`,其中 ${X} 条被同名规则覆盖`:``]}),R===`merged`&&(0,O.jsx)(`span`,{children:`按代理实际生效顺序排列(后定义覆盖先定义)`}),R===`files`&&(0,O.jsx)(`span`,{children:`点击文件名切换到该文件`})]}),oe()]})}export{M as RuleOverviewPanel};