dns-worker 1.1.5 → 1.1.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 (47) hide show
  1. package/LICENSE +154 -155
  2. package/README.md +1 -3
  3. package/dist/serverfull.mjs +49 -49
  4. package/dist/serverfull.mjs.map +4 -4
  5. package/package.json +7 -3
  6. package/static/assets/AccountView-DIeqrGlp.js +4 -0
  7. package/static/assets/AnalyticsView-BzZ61m0y.js +2 -0
  8. package/static/assets/{DestinationMap-Bwv9zW4k.js → DestinationMap-DAk0zqdP.js} +1 -1
  9. package/static/assets/{FilteringView-hYm_mlJ0.js → FilteringView-CkcgGa7_.js} +1 -1
  10. package/static/assets/LogsView-Bb2JGWSY.js +5 -0
  11. package/static/assets/{RulesView-DLhxdWLq.js → RulesView-BKZXclmK.js} +1 -1
  12. package/static/assets/{SettingsView-VR3JolCU.js → SettingsView-BIUiIVIC.js} +1 -1
  13. package/static/assets/SetupView-MjSOUYm0.js +1 -0
  14. package/static/assets/{TrendChart-wcrIRt7R.js → TrendChart-CDyqUTCQ.js} +1 -1
  15. package/static/assets/date-D8IlsmbP.js +1 -0
  16. package/static/assets/de-DE-BXtoHcnB.js +12 -0
  17. package/static/assets/es-ES-HzsKZWQV.js +12 -0
  18. package/static/assets/fr-FR-cS1x6c9J.js +12 -0
  19. package/static/assets/index-BJJdTKLc.css +2 -0
  20. package/static/assets/index-C5rHE6WK.js +17 -0
  21. package/static/assets/ja-JP-Dxk2el-P.js +12 -0
  22. package/static/assets/ko-KR-Bj56Fs_D.js +12 -0
  23. package/static/assets/ru-RU-D1z3XQQZ.js +12 -0
  24. package/static/assets/{services-BYhiWUn8.js → services-B-OKDv75.js} +1 -1
  25. package/static/assets/useLogsE2ee-Crd_rHKZ.js +1 -0
  26. package/static/assets/vi-VN-YQQX1woE.js +12 -0
  27. package/static/assets/zh-CN-B0jDBZPP.js +12 -0
  28. package/static/assets/zh-TW-DOnIGWL3.js +12 -0
  29. package/static/index.html +2 -2
  30. package/static/sw.js +1 -1
  31. package/static/assets/AccountView-t2HnohwK.js +0 -4
  32. package/static/assets/AnalyticsView-DDNyezYl.js +0 -2
  33. package/static/assets/LogsView-BSRCO63V.js +0 -5
  34. package/static/assets/SetupView-BEaDE8T8.js +0 -1
  35. package/static/assets/date-DG8jTrEB.js +0 -1
  36. package/static/assets/de-DE-BiPVfS40.js +0 -12
  37. package/static/assets/es-ES-CM9mOh6j.js +0 -12
  38. package/static/assets/fr-FR-_-PAIgSj.js +0 -12
  39. package/static/assets/index-CrB_HdIL.js +0 -17
  40. package/static/assets/index-DZNm9qiP.css +0 -2
  41. package/static/assets/ja-JP-CYATQiqp.js +0 -12
  42. package/static/assets/ko-KR-DCPI1Twu.js +0 -12
  43. package/static/assets/ru-RU-D5bj5X0j.js +0 -12
  44. package/static/assets/vi-VN-D1YSdAMz.js +0 -12
  45. package/static/assets/zh-CN-Dhtte9ac.js +0 -12
  46. package/static/assets/zh-TW-CiUsmXXj.js +0 -12
  47. /package/static/assets/{SwipeableDrawer-DkPacJ1O.js → SwipeableDrawer-BrlOF_Xg.js} +0 -0
@@ -1 +1 @@
1
- import{i as e}from"./rolldown-runtime-C4Xdq4VV.js";import{C as t,Mt as n,O as r,Qt as i,St as a,bt as o,pt as s,tt as c,wt as l,yt as u,z as d}from"./vendor-react-De1zEwOV.js";import{S as f,b as p}from"./vendor-icons-other-BTYC6Wvz.js";import"./vendor-i18next-CevVzhh3.js";import{C as m,H as h,N as g,O as _,P as v,S as y,T as b,V as x,b as S,d as C,f as w,p as T,r as E,u as D,x as O,y as k}from"./vendor-ui-core-ClwQiwMI.js";import{_t as A}from"./vendor-utils-rmW6cqPl.js";import{$t as j,D as M,J as N,Q as P,V as F,dt as I,h as L,nt as R}from"./index-CrB_HdIL.js";var z=e(f(),1),B=e(p(),1);const V=({newRule:e,setNewRule:t,addRule:n,loading:r})=>{let{t:a}=i();return(0,B.jsx)(O,{elevation:h.ONE,className:`mb-8 p-6`,children:(0,B.jsxs)(`div`,{className:`flex flex-col gap-6`,children:[(0,B.jsxs)(`div`,{className:`flex flex-col lg:flex-row justify-between gap-4 items-start lg:items-end`,children:[(0,B.jsx)(`div`,{className:`w-full lg:w-48`,children:(0,B.jsx)(T,{label:a(`rules.action`),labelFor:`rule-type`,children:(0,B.jsx)(C,{id:`rule-type`,fill:!0,large:!0,value:e.type,onChange:n=>t({...e,type:n.target.value}),options:[{label:a(`rules.typeBlock`),value:`BLOCK`},{label:a(`rules.typeAllow`),value:`ALLOW`},{label:a(`rules.typeRedirect`),value:`REDIRECT`}]})})}),(0,B.jsx)(`div`,{className:`flex-1 w-full lg:w-48`,children:(0,B.jsx)(T,{label:a(`rules.pattern`),labelFor:`rule-pattern`,children:(0,B.jsx)(w,{id:`rule-pattern`,size:`large`,placeholder:a(`rules.patternPlaceholder`),value:e.pattern,onChange:n=>t({...e,pattern:n.target.value})})})}),e.type!==`REDIRECT`&&(0,B.jsx)(T,{label:``,labelFor:``,children:(0,B.jsx)(g,{intent:x.PRIMARY,size:`large`,icon:(0,B.jsx)(d,{size:18}),onClick:n,loading:r,disabled:r,children:a(`rules.addRule`)})})]}),e.type===`REDIRECT`&&(0,B.jsxs)(`div`,{className:`bg-gray-50 dark:bg-gray-800/50 p-6 rounded-xl border border-gray-200 dark:border-gray-700`,children:[(0,B.jsxs)(`div`,{className:`flex items-center gap-2 mb-4 text-blue-600 dark:text-blue-400`,children:[(0,B.jsx)(c,{size:16}),(0,B.jsx)(`span`,{className:`text-xs font-bold uppercase tracking-wider`,children:a(`rules.redirectSettings`)})]}),(0,B.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-x-8 gap-y-4`,children:[(0,B.jsx)(T,{label:a(`rules.aRecord`),labelInfo:a(`rules.optional`),children:(0,B.jsx)(w,{placeholder:a(`rules.ipv4Placeholder`),value:e.v_a,onChange:n=>t({...e,v_a:n.target.value})})}),(0,B.jsx)(T,{label:a(`rules.aaaaRecord`),labelInfo:a(`rules.optional`),children:(0,B.jsx)(w,{placeholder:a(`rules.ipv6Placeholder`),value:e.v_aaaa,onChange:n=>t({...e,v_aaaa:n.target.value})})}),(0,B.jsx)(T,{label:a(`rules.cnameRecord`),labelInfo:a(`rules.optional`),children:(0,B.jsx)(w,{placeholder:a(`rules.cnamePlaceholder`),value:e.v_cname,onChange:n=>t({...e,v_cname:n.target.value})})}),(0,B.jsx)(T,{label:a(`rules.txtRecord`),labelInfo:a(`rules.optional`),children:(0,B.jsx)(w,{placeholder:a(`rules.txtPlaceholder`),value:e.v_txt,onChange:n=>t({...e,v_txt:n.target.value})})})]}),(0,B.jsx)(`div`,{className:`mt-6 pt-4 border-t border-gray-200 dark:border-gray-700 flex justify-end`,children:(0,B.jsx)(g,{intent:x.PRIMARY,large:!0,icon:(0,B.jsx)(d,{size:18}),onClick:n,text:a(`rules.saveRedirectRule`),loading:r,disabled:r})})]})]})})},H=({rules:e,startEdit:t,getBlockDetail:n})=>{let{t:c}=i(),[d,f]=(0,z.useState)(`created_at`),[p,m]=(0,z.useState)(`desc`),h=e=>{d===e?m(e=>e===`asc`?`desc`:`asc`):(f(e),m(e===`created_at`?`desc`:`asc`))},g=e=>e.type===`REDIRECT`?[e.v_a,e.v_aaaa,e.v_cname,e.v_txt].filter(Boolean).join(` `):e.type===`BLOCK`?n():c(`rules.detailAllow`,`Forward to upstream`),_=(0,z.useMemo)(()=>[...e].sort((e,t)=>{let n=0;switch(d){case`action`:n=e.type.localeCompare(t.type);break;case`pattern`:n=e.pattern.localeCompare(t.pattern);break;case`details`:n=g(e).localeCompare(g(t));break;case`created_at`:n=(e.created_at??e.id)-(t.created_at??t.id);break}return n===0&&(n=e.id-t.id),p===`asc`?n:-n}),[e,d,p,n,c]),v=[{key:`action`,header:c(`rules.tableAction`),headerClassName:`w-32`,render:e=>(0,B.jsxs)(B.Fragment,{children:[e.type===`BLOCK`&&(0,B.jsx)(E,{intent:x.DANGER,minimal:!0,icon:(0,B.jsx)(r,{size:12,className:`mr-1`}),children:c(`rules.labelBlock`)}),e.type===`ALLOW`&&(0,B.jsx)(E,{intent:x.SUCCESS,minimal:!0,icon:(0,B.jsx)(s,{size:12,className:`mr-1`}),children:c(`rules.labelAllow`)}),e.type===`REDIRECT`&&(0,B.jsx)(E,{intent:x.WARNING,minimal:!0,icon:(0,B.jsx)(a,{size:12,className:`mr-1`}),children:c(`rules.labelRedirect`)})]})},{key:`pattern`,header:c(`rules.tablePattern`),headerClassName:`w-1/4`,cellClassName:`font-mono font-bold`,render:e=>e.pattern},{key:`details`,header:c(`rules.tableDetails`),cellClassName:`py-2`,render:e=>(0,B.jsx)(B.Fragment,{children:e.type===`REDIRECT`?(0,B.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[e.v_a&&(0,B.jsxs)(E,{minimal:!0,className:`font-mono text-[10px]`,children:[`A: `,e.v_a]}),e.v_aaaa&&(0,B.jsxs)(E,{minimal:!0,className:`font-mono text-[10px]`,children:[`AAAA: `,e.v_aaaa]}),e.v_cname&&(0,B.jsxs)(E,{minimal:!0,className:`font-mono text-[10px]`,children:[`CNAME: `,e.v_cname]}),e.v_txt&&(0,B.jsxs)(E,{minimal:!0,className:`font-mono text-[10px]`,children:[`TXT: `,e.v_txt]})]}):e.type===`BLOCK`?(0,B.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,B.jsx)(`span`,{className:`text-gray-400 text-xs italic`,children:c(`rules.detailBlock`)}),(0,B.jsx)(E,{minimal:!0,round:!0,className:`text-[9px] px-1.5 opacity-70`,children:n()})]}):(0,B.jsx)(`span`,{className:`text-gray-400 text-xs italic`,children:c(`rules.detailAllow`)})})},{key:`created_at`,header:c(`rules.tableCreatedAt`,`添加时间`),headerClassName:`w-44`,cellClassName:`text-xs text-gray-500 align-middle`,render:e=>e.created_at?L(new Date(e.created_at*1e3)):`—`}];return(0,B.jsx)(`div`,{className:`w-full max-w-full overflow-x-auto pb-4`,children:(0,B.jsxs)(D,{interactive:!0,striped:!0,className:`w-full min-w-max whitespace-nowrap`,children:[(0,B.jsx)(`thead`,{children:(0,B.jsx)(`tr`,{children:v.map(e=>(0,B.jsx)(`th`,{onClick:()=>h(e.key),className:A(e.headerClassName,`cursor-pointer select-none transition-colors hover:text-blue-500`),title:c(`rules.clickToSort`,`点击排序`),children:(0,B.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,B.jsx)(`span`,{children:e.header}),d===e.key?p===`asc`?(0,B.jsx)(u,{size:13,className:`text-blue-500 shrink-0`}):(0,B.jsx)(l,{size:13,className:`text-blue-500 shrink-0`}):(0,B.jsx)(o,{size:12,className:`opacity-30 hover:opacity-75 shrink-0`})]})},e.key))})}),(0,B.jsx)(`tbody`,{children:_.map(e=>(0,B.jsx)(`tr`,{onClick:()=>t(e),className:`cursor-pointer`,children:v.map(t=>(0,B.jsx)(`td`,{className:t.cellClassName,children:t.render(e)},t.key))},e.id))})]})})},U=({editRule:e,setEditRule:n,saveEditRule:r,cancelEdit:a,deleteRule:o,isSaving:s,isDeleting:l})=>{let{t:u}=i();return(0,B.jsxs)(_,{isOpen:!!e,onClose:a,title:u(`rules.editRule`,`Edit Rule`),style:{width:`600px`},children:[(0,B.jsx)(S,{children:e&&(0,B.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,B.jsxs)(`div`,{className:`flex gap-4`,children:[(0,B.jsx)(T,{label:u(`rules.action`),className:`w-40 mb-0`,children:(0,B.jsx)(C,{fill:!0,value:e.type,onChange:t=>n({...e,type:t.target.value}),options:[{label:u(`rules.typeBlock`),value:`BLOCK`},{label:u(`rules.typeAllow`),value:`ALLOW`},{label:u(`rules.typeRedirect`),value:`REDIRECT`}]})}),(0,B.jsx)(T,{label:u(`rules.pattern`),className:`flex-1 mb-0`,children:(0,B.jsx)(w,{placeholder:u(`rules.patternPlaceholder`),value:e.pattern,onChange:t=>n({...e,pattern:t.target.value})})})]}),e.type===`REDIRECT`&&(0,B.jsxs)(`div`,{className:`bg-gray-50 dark:bg-gray-800 p-4 rounded-lg border border-gray-200 dark:border-gray-700`,children:[(0,B.jsxs)(`div`,{className:`flex items-center gap-2 mb-4 text-blue-600 dark:text-blue-400`,children:[(0,B.jsx)(c,{size:14}),(0,B.jsx)(`span`,{className:`text-xs font-bold uppercase tracking-wider`,children:u(`rules.redirectSettings`)})]}),(0,B.jsxs)(`div`,{className:`grid grid-cols-2 gap-4`,children:[(0,B.jsx)(T,{label:u(`rules.aRecord`),className:`mb-0`,children:(0,B.jsx)(w,{placeholder:u(`rules.ipv4Placeholder`),value:e.v_a||``,onChange:t=>n({...e,v_a:t.target.value})})}),(0,B.jsx)(T,{label:u(`rules.aaaaRecord`),className:`mb-0`,children:(0,B.jsx)(w,{placeholder:u(`rules.ipv6Placeholder`),value:e.v_aaaa||``,onChange:t=>n({...e,v_aaaa:t.target.value})})}),(0,B.jsx)(T,{label:u(`rules.cnameRecord`),className:`mb-0`,children:(0,B.jsx)(w,{placeholder:u(`rules.cnamePlaceholder`),value:e.v_cname||``,onChange:t=>n({...e,v_cname:t.target.value})})}),(0,B.jsx)(T,{label:u(`rules.txtRecord`),className:`mb-0`,children:(0,B.jsx)(w,{placeholder:u(`rules.txtPlaceholder`),value:e.v_txt||``,onChange:t=>n({...e,v_txt:t.target.value})})})]})]})]})}),(0,B.jsx)(k,{actions:(0,B.jsxs)(`div`,{className:`flex gap-2`,children:[(0,B.jsx)(g,{onClick:a,disabled:s||l,children:u(`rules.cancel`,`Cancel`)}),(0,B.jsx)(g,{intent:x.PRIMARY,onClick:r,loading:s,disabled:s||l,children:u(`rules.saveChanges`,`Save Changes`)})]}),children:(0,B.jsx)(g,{icon:(0,B.jsx)(t,{size:14}),intent:x.DANGER,text:u(`rules.delete`,`Delete`),onClick:()=>{e&&o(e.id)},loading:l,disabled:s||l})})]})},W=({profileId:e,prefill:t,onPrefillUsed:r,toasterRef:a})=>{let o=n(),[s,c]=(0,z.useState)([]),[l,u]=(0,z.useState)(null),[d,f]=(0,z.useState)(!0),[p,h]=(0,z.useState)(!1),[_,S]=(0,z.useState)(!1),[C,w]=(0,z.useState)(!1),{t:T}=i(),D=j(),[O,k]=(0,z.useState)({type:`BLOCK`,pattern:``,v_a:``,v_aaaa:``,v_txt:``,v_cname:``}),[L,W]=(0,z.useState)(null),[G,K]=(0,z.useState)(`www.okx.com`),[q,J]=(0,z.useState)(!1);(0,z.useEffect)(()=>{M().then(e=>{e.substituteDomain&&K(e.substituteDomain)}).catch(e=>console.warn(`Failed to fetch clientInfo for substituteDomain:`,e))},[]);let Y=(0,z.useMemo)(()=>{let e=window.location.hostname.trim().toLowerCase();return e?s.some(t=>{if(t.type!==`REDIRECT`)return!1;let n=t.pattern.trim().toLowerCase();return n===e||n===`*.${e}`}):!1},[s]),X=()=>{J(!1),k({type:`REDIRECT`,pattern:window.location.hostname,v_a:``,v_aaaa:``,v_txt:``,v_cname:G||`www.okx.com`}),setTimeout(()=>{document.getElementById(`rule-pattern`)?.focus()},100)};(0,z.useEffect)(()=>{t&&(k({type:t.type,pattern:t.domain,v_a:t.recordType===`A`?`0.0.0.0`:``,v_aaaa:t.recordType===`AAAA`?`::`:``,v_txt:t.recordType===`TXT`?`Pre-filled`:``,v_cname:t.recordType===`CNAME`?`target.com`:``}),r?.())},[t,r]);let Z=async()=>{f(!0);try{let[t,n]=await Promise.all([R(e),P(e)]);c(t),u(JSON.parse(n.settings||`{}`))}catch(e){console.error(`Failed to fetch data`,e)}finally{f(!1)}};return(0,z.useEffect)(()=>{Z()},[e]),(0,B.jsxs)(`div`,{className:A(`md:px-8 w-full min-w-0 max-w-5xl mx-auto`,D?`p-1`:`px-8`),children:[(0,B.jsx)(`div`,{className:`mb-8`,children:(0,B.jsxs)(`div`,{className:`flex flex-col md:flex-row justify-between items-start md:items-center gap-4`,children:[(0,B.jsxs)(`div`,{className:`w-full md:w-auto flex-1`,children:[D?(0,B.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,B.jsxs)(m,{minimal:!0,fill:D,className:`flex-1`,children:[(0,B.jsx)(g,{active:!0,onClick:()=>o(`/dash/${e}/rules`),text:T(`rules.title`),large:!0}),(0,B.jsx)(g,{active:!1,onClick:()=>o(`/dash/${e}/filter`),text:T(`filtering.title`),large:!0})]}),d&&(0,B.jsx)(v,{size:16})]}):(0,B.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,B.jsx)(`h1`,{className:`bp6-heading m-0`,children:T(`rules.title`)}),d&&(0,B.jsx)(v,{size:20})]}),(0,B.jsx)(`p`,{className:`bp6-text-muted mt-2!`,children:T(`rules.subtitle`)})]}),!d&&!Y&&(0,B.jsx)(`div`,{className:`flex items-center gap-3 self-start md:self-auto`,children:(0,B.jsx)(b,{isOpen:q,onInteraction:J,placement:`bottom-end`,portalClassName:`z-20000`,content:(0,B.jsxs)(`div`,{className:`p-4 w-72 sm:w-80 space-y-3 text-sm`,children:[(0,B.jsx)(`p`,{className:`text-xs text-gray-700 dark:text-gray-300 leading-relaxed m-0`,children:T(`rules.addSelfRedirectPrompt`,`是否增加指向本站的 CNAME 规则,用于地区网络优化(中国大陆用户推荐)?`)}),(0,B.jsxs)(`div`,{className:`flex justify-end gap-2 pt-1`,children:[(0,B.jsx)(g,{size:`small`,variant:`minimal`,text:T(`common.no`,`否`),onClick:()=>J(!1)}),(0,B.jsx)(g,{size:`small`,intent:x.PRIMARY,text:T(`common.yes`,`是`),onClick:X})]})]}),children:(0,B.jsx)(E,{minimal:!0,interactive:!0,intent:x.PRIMARY,className:`cursor-pointer select-none font-medium`,children:T(`rules.addSelfRedirectTag`,`增加本站重定向?`)})})})]})}),(0,B.jsx)(V,{newRule:O,setNewRule:k,addRule:async()=>{let t=O.pattern.trim();if(!t){a?.current?.show({message:T(`rules.patternEmpty`,`Domain pattern cannot be empty`),intent:x.DANGER});return}let n=t.toLowerCase();if(s.some(e=>e.pattern.trim().toLowerCase()===n)){a?.current?.show({message:T(`rules.duplicatePattern`,`Rule for this domain already exists`),intent:x.DANGER});return}h(!0);try{await F(e,{...O,pattern:t}),a?.current?.show({message:T(`rules.addSuccess`,`Rule added successfully`),intent:x.SUCCESS}),k({type:`BLOCK`,pattern:``,v_a:``,v_aaaa:``,v_txt:``,v_cname:``}),await Z()}catch(e){a?.current?.show({message:e.message||T(`rules.addFailed`,`Failed to add rule`),intent:x.DANGER})}finally{h(!1)}},loading:p}),d&&s.length===0?(0,B.jsxs)(`div`,{className:`p-16 flex flex-col justify-center items-center gap-3`,children:[(0,B.jsx)(v,{size:32}),(0,B.jsx)(`span`,{className:`text-xs text-gray-500 dark:text-gray-400 font-medium`,children:T(`common.loading`,`加载中...`)})]}):s.length===0?(0,B.jsx)(y,{title:T(`rules.noRulesTitle`),children:T(`rules.noRulesDesc`)}):(0,B.jsxs)(`div`,{className:`relative`,children:[d&&(0,B.jsx)(`div`,{className:`absolute inset-0 bg-white/40 dark:bg-gray-900/40 backdrop-blur-xs flex items-center justify-center z-10 rounded-lg`,children:(0,B.jsx)(v,{size:32})}),(0,B.jsx)(H,{rules:s,startEdit:e=>{W({...e})},getBlockDetail:()=>{if(!l)return T(`rules.detailBlock`);switch(l.block_mode||`NULL_IP`){case`NXDOMAIN`:return`NXDOMAIN`;case`NODATA`:return`NODATA`;case`CUSTOM_IP`:return`${l.custom_block_ipv4||`0.0.0.0`} / ${l.custom_block_ipv6||`::`}`;default:return`0.0.0.0 / ::`}}})]}),(0,B.jsx)(U,{editRule:L,setEditRule:W,saveEditRule:async()=>{if(!L)return;let t=L.pattern.trim();if(!t){a?.current?.show({message:T(`rules.patternEmpty`,`Domain pattern cannot be empty`),intent:x.DANGER});return}let n=t.toLowerCase();if(s.some(e=>e.id!==L.id&&e.pattern.trim().toLowerCase()===n)){a?.current?.show({message:T(`rules.duplicatePattern`,`Rule for this domain already exists`),intent:x.DANGER});return}S(!0);try{await I(e,{...L,pattern:t}),a?.current?.show({message:T(`rules.updateSuccess`,`Rule updated successfully`),intent:x.SUCCESS}),W(null),await Z()}catch(e){a?.current?.show({message:e.message||T(`rules.updateFailed`,`Failed to update rule`),intent:x.DANGER})}finally{S(!1)}},cancelEdit:()=>{W(null)},deleteRule:async t=>{w(!0);try{await N(e,t)}catch(e){console.error(e)}finally{w(!1)}W(null),await Z()},isSaving:_,isDeleting:C})]})};export{W as RulesView};
1
+ import{i as e}from"./rolldown-runtime-C4Xdq4VV.js";import{C as t,Mt as n,O as r,Qt as i,St as a,bt as o,pt as s,tt as c,wt as l,yt as u,z as d}from"./vendor-react-De1zEwOV.js";import{S as f,b as p}from"./vendor-icons-other-BTYC6Wvz.js";import"./vendor-i18next-CevVzhh3.js";import{C as m,H as h,N as g,O as _,P as v,S as y,T as b,V as x,b as S,d as C,f as w,p as T,r as E,u as D,x as O,y as k}from"./vendor-ui-core-ClwQiwMI.js";import{_t as A}from"./vendor-utils-rmW6cqPl.js";import{$t as j,D as M,J as N,Q as P,V as F,dt as I,h as L,nt as R}from"./index-C5rHE6WK.js";var z=e(f(),1),B=e(p(),1);const V=({newRule:e,setNewRule:t,addRule:n,loading:r})=>{let{t:a}=i();return(0,B.jsx)(O,{elevation:h.ONE,className:`mb-8 p-6`,children:(0,B.jsxs)(`div`,{className:`flex flex-col gap-6`,children:[(0,B.jsxs)(`div`,{className:`flex flex-col lg:flex-row justify-between gap-4 items-start lg:items-end`,children:[(0,B.jsx)(`div`,{className:`w-full lg:w-48`,children:(0,B.jsx)(T,{label:a(`rules.action`),labelFor:`rule-type`,children:(0,B.jsx)(C,{id:`rule-type`,fill:!0,large:!0,value:e.type,onChange:n=>t({...e,type:n.target.value}),options:[{label:a(`rules.typeBlock`),value:`BLOCK`},{label:a(`rules.typeAllow`),value:`ALLOW`},{label:a(`rules.typeRedirect`),value:`REDIRECT`}]})})}),(0,B.jsx)(`div`,{className:`flex-1 w-full lg:w-48`,children:(0,B.jsx)(T,{label:a(`rules.pattern`),labelFor:`rule-pattern`,children:(0,B.jsx)(w,{id:`rule-pattern`,size:`large`,placeholder:a(`rules.patternPlaceholder`),value:e.pattern,onChange:n=>t({...e,pattern:n.target.value})})})}),e.type!==`REDIRECT`&&(0,B.jsx)(T,{label:``,labelFor:``,children:(0,B.jsx)(g,{intent:x.PRIMARY,size:`large`,icon:(0,B.jsx)(d,{size:18}),onClick:n,loading:r,disabled:r,children:a(`rules.addRule`)})})]}),e.type===`REDIRECT`&&(0,B.jsxs)(`div`,{className:`bg-gray-50 dark:bg-gray-800/50 p-6 rounded-xl border border-gray-200 dark:border-gray-700`,children:[(0,B.jsxs)(`div`,{className:`flex items-center gap-2 mb-4 text-blue-600 dark:text-blue-400`,children:[(0,B.jsx)(c,{size:16}),(0,B.jsx)(`span`,{className:`text-xs font-bold uppercase tracking-wider`,children:a(`rules.redirectSettings`)})]}),(0,B.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-x-8 gap-y-4`,children:[(0,B.jsx)(T,{label:a(`rules.aRecord`),labelInfo:a(`rules.optional`),children:(0,B.jsx)(w,{placeholder:a(`rules.ipv4Placeholder`),value:e.v_a,onChange:n=>t({...e,v_a:n.target.value})})}),(0,B.jsx)(T,{label:a(`rules.aaaaRecord`),labelInfo:a(`rules.optional`),children:(0,B.jsx)(w,{placeholder:a(`rules.ipv6Placeholder`),value:e.v_aaaa,onChange:n=>t({...e,v_aaaa:n.target.value})})}),(0,B.jsx)(T,{label:a(`rules.cnameRecord`),labelInfo:a(`rules.optional`),children:(0,B.jsx)(w,{placeholder:a(`rules.cnamePlaceholder`),value:e.v_cname,onChange:n=>t({...e,v_cname:n.target.value})})}),(0,B.jsx)(T,{label:a(`rules.txtRecord`),labelInfo:a(`rules.optional`),children:(0,B.jsx)(w,{placeholder:a(`rules.txtPlaceholder`),value:e.v_txt,onChange:n=>t({...e,v_txt:n.target.value})})})]}),(0,B.jsx)(`div`,{className:`mt-6 pt-4 border-t border-gray-200 dark:border-gray-700 flex justify-end`,children:(0,B.jsx)(g,{intent:x.PRIMARY,large:!0,icon:(0,B.jsx)(d,{size:18}),onClick:n,text:a(`rules.saveRedirectRule`),loading:r,disabled:r})})]})]})})},H=({rules:e,startEdit:t,getBlockDetail:n})=>{let{t:c}=i(),[d,f]=(0,z.useState)(`created_at`),[p,m]=(0,z.useState)(`desc`),h=e=>{d===e?m(e=>e===`asc`?`desc`:`asc`):(f(e),m(e===`created_at`?`desc`:`asc`))},g=e=>e.type===`REDIRECT`?[e.v_a,e.v_aaaa,e.v_cname,e.v_txt].filter(Boolean).join(` `):e.type===`BLOCK`?n():c(`rules.detailAllow`,`Forward to upstream`),_=(0,z.useMemo)(()=>[...e].sort((e,t)=>{let n=0;switch(d){case`action`:n=e.type.localeCompare(t.type);break;case`pattern`:n=e.pattern.localeCompare(t.pattern);break;case`details`:n=g(e).localeCompare(g(t));break;case`created_at`:n=(e.created_at??e.id)-(t.created_at??t.id);break}return n===0&&(n=e.id-t.id),p===`asc`?n:-n}),[e,d,p,n,c]),v=[{key:`action`,header:c(`rules.tableAction`),headerClassName:`w-32`,render:e=>(0,B.jsxs)(B.Fragment,{children:[e.type===`BLOCK`&&(0,B.jsx)(E,{intent:x.DANGER,minimal:!0,icon:(0,B.jsx)(r,{size:12,className:`mr-1`}),children:c(`rules.labelBlock`)}),e.type===`ALLOW`&&(0,B.jsx)(E,{intent:x.SUCCESS,minimal:!0,icon:(0,B.jsx)(s,{size:12,className:`mr-1`}),children:c(`rules.labelAllow`)}),e.type===`REDIRECT`&&(0,B.jsx)(E,{intent:x.WARNING,minimal:!0,icon:(0,B.jsx)(a,{size:12,className:`mr-1`}),children:c(`rules.labelRedirect`)})]})},{key:`pattern`,header:c(`rules.tablePattern`),headerClassName:`w-1/4`,cellClassName:`font-mono font-bold`,render:e=>e.pattern},{key:`details`,header:c(`rules.tableDetails`),cellClassName:`py-2`,render:e=>(0,B.jsx)(B.Fragment,{children:e.type===`REDIRECT`?(0,B.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[e.v_a&&(0,B.jsxs)(E,{minimal:!0,className:`font-mono text-[10px]`,children:[`A: `,e.v_a]}),e.v_aaaa&&(0,B.jsxs)(E,{minimal:!0,className:`font-mono text-[10px]`,children:[`AAAA: `,e.v_aaaa]}),e.v_cname&&(0,B.jsxs)(E,{minimal:!0,className:`font-mono text-[10px]`,children:[`CNAME: `,e.v_cname]}),e.v_txt&&(0,B.jsxs)(E,{minimal:!0,className:`font-mono text-[10px]`,children:[`TXT: `,e.v_txt]})]}):e.type===`BLOCK`?(0,B.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,B.jsx)(`span`,{className:`text-gray-400 text-xs italic`,children:c(`rules.detailBlock`)}),(0,B.jsx)(E,{minimal:!0,round:!0,className:`text-[9px] px-1.5 opacity-70`,children:n()})]}):(0,B.jsx)(`span`,{className:`text-gray-400 text-xs italic`,children:c(`rules.detailAllow`)})})},{key:`created_at`,header:c(`rules.tableCreatedAt`,`添加时间`),headerClassName:`w-44`,cellClassName:`text-xs text-gray-500 align-middle`,render:e=>e.created_at?L(new Date(e.created_at*1e3)):`—`}];return(0,B.jsx)(`div`,{className:`w-full max-w-full overflow-x-auto pb-4`,children:(0,B.jsxs)(D,{interactive:!0,striped:!0,className:`w-full min-w-max whitespace-nowrap`,children:[(0,B.jsx)(`thead`,{children:(0,B.jsx)(`tr`,{children:v.map(e=>(0,B.jsx)(`th`,{onClick:()=>h(e.key),className:A(e.headerClassName,`cursor-pointer select-none transition-colors hover:text-blue-500`),title:c(`rules.clickToSort`,`点击排序`),children:(0,B.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,B.jsx)(`span`,{children:e.header}),d===e.key?p===`asc`?(0,B.jsx)(u,{size:13,className:`text-blue-500 shrink-0`}):(0,B.jsx)(l,{size:13,className:`text-blue-500 shrink-0`}):(0,B.jsx)(o,{size:12,className:`opacity-30 hover:opacity-75 shrink-0`})]})},e.key))})}),(0,B.jsx)(`tbody`,{children:_.map(e=>(0,B.jsx)(`tr`,{onClick:()=>t(e),className:`cursor-pointer`,children:v.map(t=>(0,B.jsx)(`td`,{className:t.cellClassName,children:t.render(e)},t.key))},e.id))})]})})},U=({editRule:e,setEditRule:n,saveEditRule:r,cancelEdit:a,deleteRule:o,isSaving:s,isDeleting:l})=>{let{t:u}=i();return(0,B.jsxs)(_,{isOpen:!!e,onClose:a,title:u(`rules.editRule`,`Edit Rule`),style:{width:`600px`},children:[(0,B.jsx)(S,{children:e&&(0,B.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,B.jsxs)(`div`,{className:`flex gap-4`,children:[(0,B.jsx)(T,{label:u(`rules.action`),className:`w-40 mb-0`,children:(0,B.jsx)(C,{fill:!0,value:e.type,onChange:t=>n({...e,type:t.target.value}),options:[{label:u(`rules.typeBlock`),value:`BLOCK`},{label:u(`rules.typeAllow`),value:`ALLOW`},{label:u(`rules.typeRedirect`),value:`REDIRECT`}]})}),(0,B.jsx)(T,{label:u(`rules.pattern`),className:`flex-1 mb-0`,children:(0,B.jsx)(w,{placeholder:u(`rules.patternPlaceholder`),value:e.pattern,onChange:t=>n({...e,pattern:t.target.value})})})]}),e.type===`REDIRECT`&&(0,B.jsxs)(`div`,{className:`bg-gray-50 dark:bg-gray-800 p-4 rounded-lg border border-gray-200 dark:border-gray-700`,children:[(0,B.jsxs)(`div`,{className:`flex items-center gap-2 mb-4 text-blue-600 dark:text-blue-400`,children:[(0,B.jsx)(c,{size:14}),(0,B.jsx)(`span`,{className:`text-xs font-bold uppercase tracking-wider`,children:u(`rules.redirectSettings`)})]}),(0,B.jsxs)(`div`,{className:`grid grid-cols-2 gap-4`,children:[(0,B.jsx)(T,{label:u(`rules.aRecord`),className:`mb-0`,children:(0,B.jsx)(w,{placeholder:u(`rules.ipv4Placeholder`),value:e.v_a||``,onChange:t=>n({...e,v_a:t.target.value})})}),(0,B.jsx)(T,{label:u(`rules.aaaaRecord`),className:`mb-0`,children:(0,B.jsx)(w,{placeholder:u(`rules.ipv6Placeholder`),value:e.v_aaaa||``,onChange:t=>n({...e,v_aaaa:t.target.value})})}),(0,B.jsx)(T,{label:u(`rules.cnameRecord`),className:`mb-0`,children:(0,B.jsx)(w,{placeholder:u(`rules.cnamePlaceholder`),value:e.v_cname||``,onChange:t=>n({...e,v_cname:t.target.value})})}),(0,B.jsx)(T,{label:u(`rules.txtRecord`),className:`mb-0`,children:(0,B.jsx)(w,{placeholder:u(`rules.txtPlaceholder`),value:e.v_txt||``,onChange:t=>n({...e,v_txt:t.target.value})})})]})]})]})}),(0,B.jsx)(k,{actions:(0,B.jsxs)(`div`,{className:`flex gap-2`,children:[(0,B.jsx)(g,{onClick:a,disabled:s||l,children:u(`rules.cancel`,`Cancel`)}),(0,B.jsx)(g,{intent:x.PRIMARY,onClick:r,loading:s,disabled:s||l,children:u(`rules.saveChanges`,`Save Changes`)})]}),children:(0,B.jsx)(g,{icon:(0,B.jsx)(t,{size:14}),intent:x.DANGER,text:u(`rules.delete`,`Delete`),onClick:()=>{e&&o(e.id)},loading:l,disabled:s||l})})]})},W=({profileId:e,prefill:t,onPrefillUsed:r,toasterRef:a})=>{let o=n(),[s,c]=(0,z.useState)([]),[l,u]=(0,z.useState)(null),[d,f]=(0,z.useState)(!0),[p,h]=(0,z.useState)(!1),[_,S]=(0,z.useState)(!1),[C,w]=(0,z.useState)(!1),{t:T}=i(),D=j(),[O,k]=(0,z.useState)({type:`BLOCK`,pattern:``,v_a:``,v_aaaa:``,v_txt:``,v_cname:``}),[L,W]=(0,z.useState)(null),[G,K]=(0,z.useState)(`www.okx.com`),[q,J]=(0,z.useState)(!1);(0,z.useEffect)(()=>{M().then(e=>{e.substituteDomain&&K(e.substituteDomain)}).catch(e=>console.warn(`Failed to fetch clientInfo for substituteDomain:`,e))},[]);let Y=(0,z.useMemo)(()=>{let e=window.location.hostname.trim().toLowerCase();return e?s.some(t=>{if(t.type!==`REDIRECT`)return!1;let n=t.pattern.trim().toLowerCase();return n===e||n===`*.${e}`}):!1},[s]),X=()=>{J(!1),k({type:`REDIRECT`,pattern:window.location.hostname,v_a:``,v_aaaa:``,v_txt:``,v_cname:G||`www.okx.com`}),setTimeout(()=>{document.getElementById(`rule-pattern`)?.focus()},100)};(0,z.useEffect)(()=>{t&&(k({type:t.type,pattern:t.domain,v_a:t.recordType===`A`?`0.0.0.0`:``,v_aaaa:t.recordType===`AAAA`?`::`:``,v_txt:t.recordType===`TXT`?`Pre-filled`:``,v_cname:t.recordType===`CNAME`?`target.com`:``}),r?.())},[t,r]);let Z=async()=>{f(!0);try{let[t,n]=await Promise.all([R(e),P(e)]);c(t),u(JSON.parse(n.settings||`{}`))}catch(e){console.error(`Failed to fetch data`,e)}finally{f(!1)}};return(0,z.useEffect)(()=>{Z()},[e]),(0,B.jsxs)(`div`,{className:A(`md:px-8 w-full min-w-0 max-w-5xl mx-auto`,D?`p-1`:`px-8`),children:[(0,B.jsx)(`div`,{className:`mb-8`,children:(0,B.jsxs)(`div`,{className:`flex flex-col md:flex-row justify-between items-start md:items-center gap-4`,children:[(0,B.jsxs)(`div`,{className:`w-full md:w-auto flex-1`,children:[D?(0,B.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,B.jsxs)(m,{minimal:!0,fill:D,className:`flex-1`,children:[(0,B.jsx)(g,{active:!0,onClick:()=>o(`/dash/${e}/rules`),text:T(`rules.title`),large:!0}),(0,B.jsx)(g,{active:!1,onClick:()=>o(`/dash/${e}/filter`),text:T(`filtering.title`),large:!0})]}),d&&(0,B.jsx)(v,{size:16})]}):(0,B.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,B.jsx)(`h1`,{className:`bp6-heading m-0`,children:T(`rules.title`)}),d&&(0,B.jsx)(v,{size:20})]}),(0,B.jsx)(`p`,{className:`bp6-text-muted mt-2!`,children:T(`rules.subtitle`)})]}),!d&&!Y&&(0,B.jsx)(`div`,{className:`flex items-center gap-3 self-start md:self-auto`,children:(0,B.jsx)(b,{isOpen:q,onInteraction:J,placement:`bottom-end`,portalClassName:`z-20000`,content:(0,B.jsxs)(`div`,{className:`p-4 w-72 sm:w-80 space-y-3 text-sm`,children:[(0,B.jsx)(`p`,{className:`text-xs text-gray-700 dark:text-gray-300 leading-relaxed m-0`,children:T(`rules.addSelfRedirectPrompt`,`是否增加指向本站的 CNAME 规则,用于地区网络优化(中国大陆用户推荐)?`)}),(0,B.jsxs)(`div`,{className:`flex justify-end gap-2 pt-1`,children:[(0,B.jsx)(g,{size:`small`,variant:`minimal`,text:T(`common.no`,`否`),onClick:()=>J(!1)}),(0,B.jsx)(g,{size:`small`,intent:x.PRIMARY,text:T(`common.yes`,`是`),onClick:X})]})]}),children:(0,B.jsx)(E,{minimal:!0,interactive:!0,intent:x.PRIMARY,className:`cursor-pointer select-none font-medium`,children:T(`rules.addSelfRedirectTag`,`增加本站重定向?`)})})})]})}),(0,B.jsx)(V,{newRule:O,setNewRule:k,addRule:async()=>{let t=O.pattern.trim();if(!t){a?.current?.show({message:T(`rules.patternEmpty`,`Domain pattern cannot be empty`),intent:x.DANGER});return}let n=t.toLowerCase();if(s.some(e=>e.pattern.trim().toLowerCase()===n)){a?.current?.show({message:T(`rules.duplicatePattern`,`Rule for this domain already exists`),intent:x.DANGER});return}h(!0);try{await F(e,{...O,pattern:t}),a?.current?.show({message:T(`rules.addSuccess`,`Rule added successfully`),intent:x.SUCCESS}),k({type:`BLOCK`,pattern:``,v_a:``,v_aaaa:``,v_txt:``,v_cname:``}),await Z()}catch(e){a?.current?.show({message:e.message||T(`rules.addFailed`,`Failed to add rule`),intent:x.DANGER})}finally{h(!1)}},loading:p}),d&&s.length===0?(0,B.jsxs)(`div`,{className:`p-16 flex flex-col justify-center items-center gap-3`,children:[(0,B.jsx)(v,{size:32}),(0,B.jsx)(`span`,{className:`text-xs text-gray-500 dark:text-gray-400 font-medium`,children:T(`common.loading`,`加载中...`)})]}):s.length===0?(0,B.jsx)(y,{title:T(`rules.noRulesTitle`),children:T(`rules.noRulesDesc`)}):(0,B.jsxs)(`div`,{className:`relative`,children:[d&&(0,B.jsx)(`div`,{className:`absolute inset-0 bg-white/40 dark:bg-gray-900/40 backdrop-blur-xs flex items-center justify-center z-10 rounded-lg`,children:(0,B.jsx)(v,{size:32})}),(0,B.jsx)(H,{rules:s,startEdit:e=>{W({...e})},getBlockDetail:()=>{if(!l)return T(`rules.detailBlock`);switch(l.block_mode||`NULL_IP`){case`NXDOMAIN`:return`NXDOMAIN`;case`NODATA`:return`NODATA`;case`CUSTOM_IP`:return`${l.custom_block_ipv4||`0.0.0.0`} / ${l.custom_block_ipv6||`::`}`;default:return`0.0.0.0 / ::`}}})]}),(0,B.jsx)(U,{editRule:L,setEditRule:W,saveEditRule:async()=>{if(!L)return;let t=L.pattern.trim();if(!t){a?.current?.show({message:T(`rules.patternEmpty`,`Domain pattern cannot be empty`),intent:x.DANGER});return}let n=t.toLowerCase();if(s.some(e=>e.id!==L.id&&e.pattern.trim().toLowerCase()===n)){a?.current?.show({message:T(`rules.duplicatePattern`,`Rule for this domain already exists`),intent:x.DANGER});return}S(!0);try{await I(e,{...L,pattern:t}),a?.current?.show({message:T(`rules.updateSuccess`,`Rule updated successfully`),intent:x.SUCCESS}),W(null),await Z()}catch(e){a?.current?.show({message:e.message||T(`rules.updateFailed`,`Failed to update rule`),intent:x.DANGER})}finally{S(!1)}},cancelEdit:()=>{W(null)},deleteRule:async t=>{w(!0);try{await N(e,t)}catch(e){console.error(e)}finally{w(!1)}W(null),await Z()},isSaving:_,isDeleting:C})]})};export{W as RulesView};
@@ -1 +1 @@
1
- import{i as e}from"./rolldown-runtime-C4Xdq4VV.js";import{B as t,C as n,D as r,Et as i,P as a,Qt as o,X as s,at as c,dt as l,et as u,gt as d,ot as f,q as p,st as m,tt as h,v as g,y as _}from"./vendor-react-De1zEwOV.js";import{S as v,b as y}from"./vendor-icons-other-BTYC6Wvz.js";import"./vendor-i18next-CevVzhh3.js";import{B as b,D as x,E as S,H as C,M as w,N as T,P as E,S as D,T as O,V as k,_ as A,d as j,f as M,h as N,p as P,r as F,v as I,w as L,x as R}from"./vendor-ui-core-ClwQiwMI.js";import"./vendor-utils-rmW6cqPl.js";import{$ as z,A as B,M as V,Q as H,at as U,c as W,ft as G,lt as K,nt as q,y as J}from"./index-CrB_HdIL.js";var Y=e(v(),1),X=e(y(),1);const Z=({profile:e,isEditingName:n,setIsEditingName:r,editName:i,setEditName:a,updateProfileName:s,exportProfile:c})=>{let{t:l}=o(),[u,p]=(0,Y.useState)(!1);return(0,X.jsxs)(`div`,{className:`mb-6 flex flex-col md:flex-row justify-between items-start md:items-center gap-4`,children:[(0,X.jsxs)(`div`,{className:`flex flex-col justify-start`,children:[n?(0,X.jsxs)(`div`,{className:`flex items-center gap-2 mb-1`,children:[(0,X.jsx)(I,{content:l(`common.profileNameFormatTip`,`Profile Name tip: 1-30 characters, duplicates not allowed`),isOpen:u,position:b.TOP,intent:k.PRIMARY,className:`flex-1`,children:(0,X.jsx)(`div`,{className:`w-full block`,children:(0,X.jsx)(M,{value:i,onChange:e=>a(e.target.value),onFocus:()=>p(!0),onBlur:()=>p(!1),autoFocus:!0,onKeyDown:t=>{t.key===`Enter`&&s(),t.key===`Escape`&&(r(!1),a(e?.name||``))}})})}),(0,X.jsx)(T,{icon:(0,X.jsx)(d,{size:16}),intent:k.SUCCESS,minimal:!0,onClick:s,disabled:!W.test(i)}),(0,X.jsx)(T,{icon:(0,X.jsx)(_,{size:16}),minimal:!0,onClick:()=>{r(!1),a(e?.name||``)}})]}):(0,X.jsxs)(`div`,{className:`group flex items-center gap-2 mb-1 cursor-pointer`,onClick:()=>r(!0),children:[(0,X.jsx)(`h2`,{className:`bp6-heading mb-0`,children:e?.name}),(0,X.jsx)(T,{icon:(0,X.jsx)(t,{size:14}),minimal:!0,className:`opacity-30 group-hover:opacity-100 transition-opacity`})]}),(0,X.jsx)(`p`,{className:`bp6-text-muted`,children:l(`settings.subtitle`)})]}),(0,X.jsx)(`div`,{className:`flex gap-2 items-center`,children:(0,X.jsx)(T,{size:`large`,icon:(0,X.jsx)(f,{size:18}),text:l(`settings.export`,`导出配置`),onClick:c})})]})},Q=()=>{let{t:e}=o(),[t,n]=(0,Y.useState)([]);return(0,Y.useEffect)(()=>{V().then(t=>{t&&Array.isArray(t)&&n(t.map(t=>({label:e(t.label),url:t.url})))}).catch(e=>console.warn(`Failed to fetch preset upstreams from API`,e))},[e]),t},$=(e,t)=>{let{t:n}=o();return(0,Y.useMemo)(()=>{let e=t>0?t:30,r=n(`settings.retentionMaxSuffix`,`(最长)`),i=[{label:n(`settings.retentionDisabled`,`关闭 (隐私需要)`),value:0},{label:n(`settings.retention10m`,`10 分钟`),value:.007},{label:n(`settings.retention1h`,`1 小时`),value:.0416},{label:n(`settings.retention24h`,`24 小时`),value:1},{label:n(`settings.retention7d`,`7 天`),value:7},{label:n(`settings.retention30d`,`30 天`),value:30},{label:n(`settings.retention90d`,`90 天`),value:90},{label:n(`settings.retention180d`,`180 天`),value:180},{label:n(`settings.retention360d`,`360 天`),value:360}],a=i.filter(t=>t.value<=e);return e>0&&!a.some(t=>t.value===e)&&(a.push({label:`${e} ${n(`settings.daysUnit`,`天`)}`,value:e}),a.sort((e,t)=>e.value-t.value)),a.length===0?[i[0]]:a.map(t=>t.value===e&&t.value>0?{...t,label:`${t.label} ${r}`}:t)},[n,t])},ee=({settings:e,setSettings:t})=>{let{t:n}=o(),r=(0,X.jsx)(S,{className:`min-w-96`,children:Q().map((n,r)=>(0,X.jsx)(L,{text:n.label,onClick:()=>t({...e,upstream:[n.url]}),labelElement:(0,X.jsx)(`div`,{className:`flex flex-col items-end text-right`,children:(0,X.jsx)(`span`,{className:`text-[9px] opacity-85 max-w-64 truncate`,title:n.url,children:n.url})})},r))});return(0,X.jsxs)(R,{elevation:C.ONE,className:`dark:bg-gray-900 dark:border-gray-800`,children:[(0,X.jsxs)(w,{className:`flex items-center gap-2 mb-4 font-bold`,children:[(0,X.jsx)(a,{size:18,className:`text-blue-500`}),` `,n(`settings.upstreamTitle`)]}),(0,X.jsx)(P,{label:`DoH (https://) / DoT (tls://) / DNS Stamp (sdns://) / ${n(`settings.classicDns`)}`,children:(0,X.jsx)(M,{fill:!0,placeholder:`https://... | tls://... | sdns://... | 1.1.1.1`,value:e.upstream?.[0]||``,onChange:n=>t({...e,upstream:[n.target.value]}),onFocus:e=>e.target.select(),rightElement:(0,X.jsx)(O,{content:r,placement:`bottom-end`,animation:`minimal`,arrow:!1,children:(0,X.jsx)(T,{variant:`minimal`,icon:`chevron-down`})})})}),(0,X.jsx)(`p`,{className:`text-xs opacity-60`,children:n(`settings.upstreamDesc`)})]})},te=({settings:e,setSettings:t})=>{let{t:n}=o();return(0,X.jsxs)(R,{elevation:C.ONE,className:`dark:bg-gray-900 dark:border-gray-800`,children:[(0,X.jsxs)(w,{className:`flex items-center gap-2 mb-4 font-bold`,children:[(0,X.jsx)(r,{size:18,className:`text-green-500`}),` `,n(`settings.defaultPolicyTitle`)]}),(0,X.jsxs)(`div`,{className:`space-y-4`,children:[(0,X.jsx)(P,{label:n(`settings.onNoMatch`),children:(0,X.jsxs)(j,{fill:!0,value:e.default_policy,onChange:n=>t({...e,default_policy:n.target.value}),children:[(0,X.jsx)(`option`,{value:`ALLOW`,children:n(`settings.allowAll`)}),(0,X.jsx)(`option`,{value:`BLOCK`,children:n(`settings.blockAll`)})]})}),(0,X.jsx)(A,{}),(0,X.jsx)(P,{label:n(`settings.blockModeTitle`),helperText:n(`settings.blockModeDesc`),children:(0,X.jsxs)(j,{fill:!0,value:e.block_mode||`NULL_IP`,onChange:n=>t({...e,block_mode:n.target.value}),children:[(0,X.jsxs)(`option`,{value:`NULL_IP`,children:[`0.0.0.0 / :: (`,n(`settings.default`),`)`]}),(0,X.jsxs)(`option`,{value:`NXDOMAIN`,children:[`NXDOMAIN (`,n(`settings.NXDOMAIN`),`)`]}),(0,X.jsxs)(`option`,{value:`NODATA`,children:[`NODATA (`,n(`settings.NODATA`),`)`]}),(0,X.jsx)(`option`,{value:`CUSTOM_IP`,children:n(`settings.customIP`)})]})}),e.block_mode===`CUSTOM_IP`&&(0,X.jsxs)(`div`,{className:`space-y-2 animate-in fade-in slide-in-from-top-1`,children:[(0,X.jsx)(M,{placeholder:`IPv4: 127.0.0.1`,value:e.custom_block_ipv4||``,onChange:n=>t({...e,custom_block_ipv4:n.target.value})}),(0,X.jsx)(M,{placeholder:`IPv6: ::1`,value:e.custom_block_ipv6||``,onChange:n=>t({...e,custom_block_ipv6:n.target.value})})]})]})]})},ne=({settings:e,setSettings:t,isAdmin:n,maxRetentionDays:r})=>{let{t:i}=o(),a=$(n,r);Y.useEffect(()=>{if(r>0&&e.log_retention_days>r&&a.length>0){let n=a[a.length-1];n&&e.log_retention_days!==n.value&&t({...e,log_retention_days:n.value})}},[r,e.log_retention_days,a,t]);let s=e.log_retention_days===0;return(0,X.jsxs)(R,{elevation:C.ONE,className:`dark:bg-gray-900 dark:border-gray-800`,children:[(0,X.jsxs)(w,{className:`flex items-center gap-2 mb-4 font-bold`,children:[(0,X.jsx)(l,{size:18,className:`text-purple-500`}),` `,i(`settings.logRetentionTitle`)]}),(0,X.jsxs)(`div`,{className:`space-y-4`,children:[(0,X.jsx)(P,{label:i(`settings.retentionDuration`),children:(0,X.jsx)(j,{fill:!0,value:e.log_retention_days,onChange:n=>t({...e,log_retention_days:parseFloat(n.target.value)}),children:a.map(e=>(0,X.jsx)(`option`,{value:e.value,children:e.label},e.value))})}),(0,X.jsx)(`p`,{className:`text-xs opacity-60`,children:s?i(`settings.retentionDisabledDesc`,`已关闭日志记录。系统将不会记录任何 DNS 查询日志并立即清空历史日志。`):i(`settings.retentionDesc`)}),(0,X.jsxs)(`div`,{className:`pt-3 border-t border-gray-100 dark:border-gray-800/80`,children:[(0,X.jsx)(N,{label:i(`settings.skipLogOnPass`,`不记录放行记录`),checked:!s&&!!e.skip_log_on_pass,disabled:s,onChange:n=>t({...e,skip_log_on_pass:n.currentTarget.checked})}),(0,X.jsx)(`p`,{className:`text-xs opacity-60 mt-1`,children:i(`settings.skipLogOnPassDesc`,`启用后不记录正常放行的 DNS 查询,仅记录被拦截、重定向或解析失败的记录。可大幅减少存储占用与写操作。`)})]})]})]})},re=({profileId:e,toasterRef:t})=>{let{t:r}=o(),[i,a]=(0,Y.useState)(()=>J.getLocalRetentionDays()),[s,c]=(0,Y.useState)(!1),[l,d]=(0,Y.useState)(null),[f,p]=(0,Y.useState)(!1),[h,g]=(0,Y.useState)(!1),_=(0,Y.useCallback)(async()=>{try{await J.init();let t=await J.getStorageInfo();c(t?.isOpfs??J.getIsOpfs());let n=t.profileStats.find(t=>t.profile_id===e);d(n?n.count:0)}catch(e){console.error(`[LocalRetentionCard] Failed to load storage info:`,e),c(J.getIsOpfs()),d(0)}},[e]);(0,Y.useEffect)(()=>{_()},[_]);let v=e=>{a(e),J.setLocalRetentionDays(e),_()};return(0,X.jsxs)(R,{elevation:C.ONE,className:`dark:bg-gray-900 dark:border-gray-800`,children:[(0,X.jsxs)(w,{className:`flex items-center gap-2 mb-4 font-bold`,children:[(0,X.jsx)(m,{size:18,className:`text-cyan-500`}),` `,r(`settings.localRetentionTitle`,`本地存储与留存`)]}),(0,X.jsxs)(`div`,{className:`space-y-4`,children:[(0,X.jsx)(P,{label:r(`settings.localRetentionDuration`,`本地保留时长`),children:(0,X.jsxs)(j,{fill:!0,value:i,onChange:e=>v(parseInt(e.target.value,10)),children:[(0,X.jsx)(`option`,{value:30,children:r(`settings.localRetention30d`,`30 天`)}),(0,X.jsx)(`option`,{value:90,children:r(`settings.localRetention90d`,`90 天 (推荐)`)}),(0,X.jsx)(`option`,{value:180,children:r(`settings.localRetention180d`,`180 天`)}),(0,X.jsx)(`option`,{value:365,children:r(`settings.localRetention365d`,`365 天 (1 年)`)}),(0,X.jsx)(`option`,{value:0,children:r(`settings.localRetentionUnlimited`,`永久保留 (直到手动清除)`)})]})}),(0,X.jsx)(`p`,{className:`text-xs opacity-60`,children:r(`settings.localRetentionDesc`,`日志将持久化保存在当前浏览器本地的 SQLite 数据库 (OPFS) 中,提供秒级本地搜索并节省云端存储费用。超出此时长的本地日志将自动清除。`)}),(0,X.jsxs)(`div`,{className:`pt-3 border-t border-gray-100 dark:border-gray-800/80 space-y-3`,children:[(0,X.jsxs)(`div`,{className:`flex items-center justify-between text-xs`,children:[(0,X.jsxs)(`span`,{className:`flex items-center gap-1.5 opacity-70`,children:[(0,X.jsx)(u,{size:14}),r(`settings.localEngineStorage`,`存储引擎`),`:`]}),(0,X.jsx)(F,{minimal:!0,intent:s?k.SUCCESS:k.WARNING,className:`text-[11px]`,children:s?r(`settings.localEngineOpfs`,`OPFS 本地持久化`):r(`settings.localEngineMemory`,`内存临时存储 (无痕/私密模式)`)})]}),(0,X.jsxs)(`div`,{className:`flex items-center justify-between text-xs`,children:[(0,X.jsxs)(`span`,{className:`opacity-70`,children:[r(`settings.localCachedCount`,`本地已缓存日志`),`:`]}),(0,X.jsx)(`span`,{className:`font-mono font-medium`,children:l===null?`...`:r(`settings.localCachedCountUnit`,`{{count}} 条记录`,{count:l})})]}),(0,X.jsx)(`div`,{className:`pt-1 flex justify-end`,children:(0,X.jsx)(T,{minimal:!0,small:!0,intent:k.DANGER,icon:(0,X.jsx)(n,{size:13}),text:r(`settings.clearLocalData`,`清空本地日志`),disabled:l===0||l===null||h,onClick:()=>p(!0)})})]})]}),(0,X.jsx)(x,{isOpen:f,confirmButtonText:r(`common.confirm`,`确认清空`),cancelButtonText:r(`common.cancel`,`取消`),intent:k.DANGER,icon:`trash`,onConfirm:async()=>{g(!0);try{await J.clearProfile(e),d(0),t?.current?.show({message:r(`settings.clearLocalDataSuccess`,`本地日志已成功清空`),intent:k.SUCCESS,icon:`tick`})}catch(e){console.error(`[LocalRetentionCard] Failed to clear local profile logs:`,e),t?.current?.show({message:r(`settings.clearLocalDataError`,`清空本地日志失败`),intent:k.DANGER,icon:`error`})}finally{g(!1),p(!1)}},onCancel:()=>p(!1),loading:h,children:(0,X.jsx)(`p`,{children:r(`settings.clearLocalDataConfirm`,`确定要清空此配置在本地保存的所有日志吗?(云端日志不受影响)`)})})]})},ie=({settings:e,setSettings:t})=>{let{t:n}=o();return(0,X.jsxs)(R,{elevation:C.ONE,className:`dark:bg-gray-900 dark:border-gray-800`,children:[(0,X.jsxs)(w,{className:`flex items-center gap-2 mb-3 font-bold`,children:[(0,X.jsx)(h,{size:18,className:`text-orange-500`}),` `,n(`settings.ecsTitle`)]}),(0,X.jsxs)(`div`,{className:`space-y-4`,children:[(0,X.jsx)(N,{label:n(`settings.sendEcs`),checked:e.ecs.enabled,onChange:n=>t({...e,ecs:{...e.ecs,enabled:n.currentTarget.checked}})}),(0,X.jsx)(N,{label:n(`settings.customSubnet`),disabled:!e.ecs.enabled,checked:!e.ecs.use_client_ip,onChange:n=>t({...e,ecs:{...e.ecs,use_client_ip:!n.currentTarget.checked}})}),(0,X.jsxs)(`div`,{className:`space-y-3 pt-2 border-t border-gray-100 dark:border-gray-800`,children:[(0,X.jsx)(P,{label:n(`settings.customIpv4`),labelInfo:n(`settings.ipv4Hint`),disabled:!(e.ecs.enabled&&!e.ecs.use_client_ip),children:(0,X.jsx)(M,{placeholder:`0.0.0.0/0`,value:e.ecs.ipv4_cidr||``,disabled:!(e.ecs.enabled&&!e.ecs.use_client_ip),onChange:n=>t({...e,ecs:{...e.ecs,ipv4_cidr:n.target.value}})})}),(0,X.jsx)(P,{label:n(`settings.customIpv6`),labelInfo:n(`settings.ipv6Hint`),disabled:!(e.ecs.enabled&&!e.ecs.use_client_ip),children:(0,X.jsx)(M,{placeholder:`::/0`,value:e.ecs.ipv6_cidr||``,disabled:!(e.ecs.enabled&&!e.ecs.use_client_ip),onChange:n=>t({...e,ecs:{...e.ecs,ipv6_cidr:n.target.value}})})})]}),(0,X.jsx)(`p`,{className:`text-xs opacity-60`,children:n(`settings.ecsUpstreamHint`)})]})]})};var ae=[{domain:`cloudflare-ech.com`,isPreferred:!0},{domain:`crypto.cloudflare.com`,isPreferred:!1},{domain:`one.one.one.one`,isPreferred:!1},{domain:`www.cloudflare.com`,isPreferred:!1},{domain:`encryptedsni.com`,isPreferred:!1},{domain:`cdnjs.com`,isPreferred:!1}];const oe=({settings:e,setSettings:t})=>{let{t:n}=o(),[r,i]=Y.useState(ae);Y.useEffect(()=>{B().then(e=>{Array.isArray(e)&&e.length>0&&i(e.map(e=>typeof e==`string`?{domain:e,isPreferred:e===`cloudflare-ech.com`}:{domain:e.domain,isPreferred:!!e.isPreferred}))}).catch(e=>console.warn(`Failed to fetch preset ECH fronting domains from API`,e))},[]);let a=typeof e.best_effort_ech==`boolean`?e.best_effort_ech:!!e.best_effort_ech?.enabled,l=typeof e.best_effort_ech==`object`&&e.best_effort_ech?.fronting_domain?e.best_effort_ech.fronting_domain:`cloudflare-ech.com`,u=n=>{t({...e,best_effort_ech:{enabled:n,fronting_domain:l||`cloudflare-ech.com`}})},d=n=>{t({...e,best_effort_ech:{enabled:a,fronting_domain:n}})},f=(0,X.jsx)(S,{className:`min-w-72`,children:r.map(e=>(0,X.jsx)(L,{text:e.domain,onClick:()=>d(e.domain),labelElement:e.isPreferred?(0,X.jsx)(F,{minimal:!0,intent:k.PRIMARY,className:`text-[10px]`,children:n(`settings.echPreferred`,`首选`)}):void 0},e.domain))});return(0,X.jsxs)(R,{elevation:C.ONE,className:`dark:bg-gray-900 dark:border-gray-800`,children:[(0,X.jsxs)(`div`,{className:`flex items-center justify-between mb-3`,children:[(0,X.jsxs)(w,{className:`flex items-center gap-2 m-0 font-bold text-purple-600 dark:text-purple-400`,children:[(0,X.jsx)(s,{size:18}),` `,n(`settings.echTitle`)]}),(0,X.jsx)(O,{placement:`bottom-end`,usePortal:!0,content:(0,X.jsxs)(`div`,{className:`p-4 max-w-sm`,children:[(0,X.jsx)(w,{children:n(`settings.whatIsEch`,`何为 ECH (Encrypted Client Hello)?`)}),(0,X.jsx)(`p`,{className:`text-sm mb-2`,children:n(`settings.echHelpDesc`)}),(0,X.jsxs)(`ul`,{className:`list-disc list-inside text-sm opacity-80 mb-3 space-y-1`,children:[(0,X.jsx)(`li`,{children:n(`settings.echHelpBenefit1`)}),(0,X.jsx)(`li`,{children:n(`settings.echHelpBenefit2`)})]}),(0,X.jsx)(`div`,{className:`text-xs border-t border-gray-100 dark:border-gray-700 pt-2`,children:(0,X.jsxs)(`a`,{href:`https://en.wikipedia.org/wiki/Encrypted_Client_Hello`,target:`_blank`,rel:`noreferrer`,className:`flex items-center gap-1 text-blue-500 hover:underline`,children:[(0,X.jsx)(c,{size:10}),` `,n(`setup.learnMore`,`了解更多`)]})})]}),children:(0,X.jsx)(T,{icon:`help`,variant:`minimal`,intent:k.NONE})})]}),(0,X.jsxs)(`div`,{className:`space-y-4`,children:[(0,X.jsx)(N,{label:n(`settings.enableEch`,`启用重写 ECH`),checked:a,onChange:e=>u(e.currentTarget.checked)}),(0,X.jsx)(`p`,{className:`text-xs opacity-60 leading-relaxed`,children:n(`settings.echDesc`,`针对由 Cloudflare 代理的域名,当查询 HTTPS (Type 65) 或 SVCB (Type 64) 记录且上游未配置 ECH 时,自动重写注入 ECH 参数以保护 SNI 隐私。`)}),a&&(0,X.jsx)(`div`,{className:`space-y-3 pt-3 border-t border-gray-100 dark:border-gray-800`,children:(0,X.jsx)(P,{label:n(`settings.echFrontingTitle`,`表层 SNI (ECH Fronting)`),labelInfo:(0,X.jsx)(`span`,{className:`text-xs opacity-60`,children:n(`settings.echFrontingDesc`,`TLS 握手外层可见的伪装域名`)}),children:(0,X.jsx)(M,{fill:!0,placeholder:n(`settings.echFrontingCustomPlaceholder`,`输入自定义表层域名,例如 crypto.cloudflare.com`),value:l,onChange:e=>d(e.target.value),onFocus:e=>e.target.select(),className:`font-mono text-sm`,rightElement:(0,X.jsx)(O,{content:f,placement:`bottom-end`,animation:`minimal`,arrow:!1,children:(0,X.jsx)(T,{variant:`minimal`,icon:`chevron-down`})})})})})]})]})},se=({testInput:e,setTestInput:t,handleDnsTest:n,testing:r,testResult:a})=>{let{t:s}=o();return(0,X.jsxs)(R,{elevation:C.TWO,className:`dark:bg-gray-900 border-t-2 border-blue-500`,children:[(0,X.jsxs)(w,{className:`flex items-center gap-2 mb-6 font-bold`,children:[(0,X.jsx)(g,{size:20,className:`text-yellow-500 fill-yellow-500`}),` `,s(`settings.testToolTitle`)]}),(0,X.jsxs)(`div`,{className:`flex flex-col space-y-6`,children:[(0,X.jsx)(P,{label:s(`settings.testDomain`),className:`mb-0`,children:(0,X.jsx)(M,{fill:!0,large:!0,placeholder:s(`settings.domainPlaceholder`),value:e.domain,onChange:n=>t({...e,domain:n.target.value}),onKeyDown:e=>e.key===`Enter`&&n()})}),(0,X.jsxs)(`div`,{className:`flex justify-end gap-4 items-end`,children:[(0,X.jsx)(P,{label:s(`settings.recordType`),className:`w-32 mb-0`,children:(0,X.jsxs)(j,{fill:!0,large:!0,value:e.type,onChange:n=>t({...e,type:n.target.value}),children:[(0,X.jsx)(`option`,{value:`A`,children:`A`}),(0,X.jsx)(`option`,{value:`AAAA`,children:`AAAA`}),(0,X.jsx)(`option`,{value:`CNAME`,children:`CNAME`}),(0,X.jsx)(`option`,{value:`TXT`,children:`TXT`})]})}),(0,X.jsx)(P,{label:`\xA0`,className:`mb-0`,children:(0,X.jsx)(T,{size:`large`,intent:k.PRIMARY,icon:`search`,text:s(`settings.runTest`),onClick:n,loading:r})})]}),a&&(0,X.jsxs)(`div`,{className:`bg-gray-50 dark:bg-gray-800/50 p-6 rounded-xl border border-gray-100 dark:border-gray-800 space-y-6 animate-in fade-in slide-in-from-top-4`,children:[(0,X.jsxs)(`div`,{className:`flex flex-wrap gap-4 items-center`,children:[(0,X.jsx)(F,{large:!0,round:!0,intent:a.action===`PASS`?k.SUCCESS:a.action===`BLOCK`?k.DANGER:k.WARNING,className:`px-4 font-bold`,children:a.action}),(0,X.jsxs)(`div`,{className:`flex flex-col`,children:[(0,X.jsx)(`span`,{className:`text-[10px] uppercase font-bold opacity-40`,children:s(`settings.hitRule`)}),(0,X.jsx)(`span`,{className:`text-sm font-bold`,children:a.reason||s(`settings.defaultAllow`)})]}),(0,X.jsxs)(`div`,{className:`flex flex-col border-l border-gray-200 dark:border-gray-700 pl-4`,children:[(0,X.jsx)(`span`,{className:`text-[10px] uppercase font-bold opacity-40`,children:s(`settings.parseLatency`)}),(0,X.jsx)(`span`,{className:`text-sm font-mono font-bold`,children:a.latency?`${a.latency}ms`:`-`})]}),a.timings&&(0,X.jsx)(`div`,{className:`flex flex-wrap gap-x-4 gap-y-1 border-l border-gray-200 dark:border-gray-700 pl-4 max-w-md`,children:Object.entries(a.timings).map(([e,t])=>(0,X.jsxs)(`div`,{className:`flex gap-1 items-baseline`,children:[(0,X.jsxs)(`span`,{className:`text-[9px] opacity-40 uppercase font-mono`,children:[e,`:`]}),(0,X.jsxs)(`span`,{className:`text-[10px] font-mono font-bold`,children:[t,`ms`]})]},e))}),(0,X.jsx)(A,{}),(0,X.jsxs)(`div`,{className:`flex items-center gap-2 bg-white dark:bg-gray-900 px-3 py-1.5 rounded-lg shadow-sm border border-gray-100 dark:border-gray-800`,children:[(0,X.jsx)(p,{size:14,className:`text-red-500`}),(0,X.jsxs)(`div`,{className:`flex flex-col`,children:[(0,X.jsx)(`span`,{className:`text-[10px] uppercase font-bold opacity-40 leading-none`,children:s(`settings.sourceIp`)}),(0,X.jsxs)(`span`,{className:`text-xs font-mono`,children:[a.client_ip,` (`,a.geo_country,`)`]})]})]})]}),(0,X.jsxs)(`div`,{className:`space-y-3`,children:[(0,X.jsxs)(`div`,{className:`text-[10px] uppercase font-bold opacity-40 flex items-center gap-1`,children:[(0,X.jsx)(i,{size:10}),` `,s(`settings.answerSection`)]}),(0,X.jsx)(`div`,{className:`font-mono text-sm leading-relaxed bg-white dark:bg-gray-900 p-4 rounded-xl border border-gray-100 dark:border-gray-800 shadow-inner`,children:a.answers&&a.answers.length>0?a.answers.map((e,t)=>(0,X.jsxs)(`div`,{className:`flex gap-4 py-1 border-b border-gray-50 dark:border-gray-800 last:border-0 hover:bg-blue-50/50 dark:hover:bg-blue-900/10 transition-colors px-2`,children:[(0,X.jsx)(`span`,{className:`w-16 font-bold text-blue-500`,children:e.type}),(0,X.jsx)(`span`,{className:`flex-1 dark:text-gray-300`,children:e.data}),(0,X.jsxs)(`span`,{className:`text-[10px] opacity-30 italic`,children:[`TTL: `,e.ttl,`s`]})]},t)):(0,X.jsx)(`div`,{className:`p-4 opacity-40 italic text-center`,children:s(`settings.noRecordsReturned`)})})]}),a.diagnostics&&(0,X.jsx)(D,{minimal:!0,intent:a.action===`FAIL`?k.DANGER:k.NONE,className:`text-xs font-mono`,children:(0,X.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,X.jsxs)(`div`,{className:`flex justify-between items-center`,children:[(0,X.jsx)(`span`,{className:`font-bold uppercase tracking-wider`,children:s(`settings.diagnostics`)}),(0,X.jsx)(`span`,{className:`font-bold`,children:a.action===`FAIL`?a.diagnostics.status>0?`HTTP ${a.diagnostics.status}${a.diagnostics.status_text?` (${a.diagnostics.status_text})`:``}`:`Network / Connection Error`:a.diagnostics.method===`POST`||a.diagnostics.method===`GET`?`HTTP ${a.diagnostics.status}${a.diagnostics.status_text?` (${a.diagnostics.status_text})`:``}`:`Connected (OK)`})]}),(0,X.jsxs)(`div`,{className:`flex items-center gap-2 text-xs opacity-80`,children:[(0,X.jsx)(`span`,{className:`px-1.5 py-0.5 bg-gray-200 dark:bg-gray-700 rounded text-[10px] font-bold`,children:a.diagnostics.method}),(0,X.jsx)(`span`,{className:`break-all`,children:a.diagnostics.upstream_url})]}),a.diagnostics.cf_ray&&(0,X.jsxs)(`div`,{className:`text-[11px] opacity-75`,children:[`CF-Ray: `,(0,X.jsx)(`span`,{className:`font-bold`,children:a.diagnostics.cf_ray})]}),a.diagnostics.error_detail&&a.action===`FAIL`&&(0,X.jsxs)(`div`,{className:`p-2 bg-red-50 dark:bg-red-950/40 rounded border border-red-200 dark:border-red-900/50 text-red-700 dark:text-red-300 break-words`,children:[(0,X.jsxs)(`div`,{className:`font-bold mb-0.5`,children:[s(`settings.errorDetail`),`:`]}),(0,X.jsx)(`div`,{children:a.diagnostics.error_detail})]}),a.diagnostics.response_body&&(0,X.jsxs)(`div`,{className:`p-2 bg-gray-100 dark:bg-gray-900 rounded border border-gray-200 dark:border-gray-700 text-gray-700 dark:text-gray-300 break-words text-[11px]`,children:[(0,X.jsxs)(`div`,{className:`font-bold mb-0.5 opacity-60`,children:[s(`settings.upstreamResponse`),`:`]}),(0,X.jsx)(`div`,{className:`line-clamp-3`,children:a.diagnostics.response_body})]})]})})]})]})]})},ce=({profileId:e,toasterRef:t,currentUser:n,onSavingChange:r})=>{let[i,a]=(0,Y.useState)(null),[s,c]=(0,Y.useState)(null),[l,u]=(0,Y.useState)(!0),[d,f]=(0,Y.useState)(!1),{t:p}=o();(0,Y.useEffect)(()=>(r?.(d),()=>{r?.(!1)}),[d,r]);let m=(0,Y.useRef)(!0),h=(0,Y.useRef)(null),[g,_]=(0,Y.useState)(!1),[v,y]=(0,Y.useState)(``),[b,x]=(0,Y.useState)({domain:`o-o.myaddr.l.google.com`,type:`TXT`}),[S,C]=(0,Y.useState)(null),[w,T]=(0,Y.useState)(!1);(0,Y.useEffect)(()=>{(async()=>{try{let t=await H(e);return a(t),y(t.name),c(JSON.parse(t.settings)),i}catch(e){console.error(e)}finally{u(!1)}})()},[e]),(0,Y.useEffect)(()=>{if(!l&&s){let e=setTimeout(()=>{m.current=!1},500);return()=>clearTimeout(e)}},[l,s]),(0,Y.useEffect)(()=>()=>{h.current&&clearTimeout(h.current)},[]);let D=async()=>{if(!v||v===i?.name){_(!1);return}try{await U(e,v),a(e=>e?{...e,name:v}:null),_(!1),t?.current?.show({message:p(`settings.nameUpdateSuccess`,`名称已更新`),intent:k.SUCCESS})}catch(e){console.error(e);let n=e.message,r=n;n===`The profile name already exists`?r=p(`common.profileNameExists`,`The profile name already exists`):n===`Invalid Profile Name format`&&(r=p(`common.profileNameFormatError`,`Invalid Profile Name format`)),t?.current?.show({message:r||p(`settings.nameUpdateFailed`,`更新失败`),intent:k.DANGER})}},O=(0,Y.useCallback)(async n=>{if(n){f(!0);try{await G(e,n)}catch(e){console.error(e),t?.current?.show({message:p(`settings.saveError`),intent:k.DANGER,icon:`error`})}finally{f(!1)}}},[e,t,p]),A=(0,Y.useCallback)(e=>{h.current&&clearTimeout(h.current),h.current=setTimeout(()=>{O(e)},600)},[O]),j=(0,Y.useCallback)(e=>{c(e),m.current||A(e)},[A]);return l||!s?(0,X.jsx)(`div`,{className:`p-20 flex justify-center`,children:(0,X.jsx)(E,{})}):(0,X.jsxs)(`div`,{className:`p-0 sm:px-4 lg:px-8 max-w-5xl mx-auto space-y-8 pb-20`,children:[(0,X.jsx)(Z,{profile:i,isEditingName:g,setIsEditingName:_,editName:v,setEditName:y,updateProfileName:D,exportProfile:async()=>{if(!(!i||!s))try{let[n,r]=await Promise.all([q(e).catch(()=>[]),z(e).catch(()=>[])]),a=new Set,o=(n||[]).filter(e=>{let t=(e.pattern||``).trim().toLowerCase();return!t||a.has(t)?!1:(a.add(t),!0)}),c=new Set,l=(r||[]).filter(e=>{let t=(e.url||``).trim().toLowerCase();return!t||c.has(t)?!1:(c.add(t),!0)}).map(e=>({url:e.url,enabled:!!e.enabled})),u={version:2,name:i.name,settings:s,rules:o,filters:l,exported_at:Math.floor(Date.now()/1e3)},d=new Blob([JSON.stringify(u,null,2)],{type:`application/json`}),f=URL.createObjectURL(d),m=document.createElement(`a`);m.href=f,m.download=`dns-worker-${i.name||e}.json`,document.body.appendChild(m),m.click(),document.body.removeChild(m),URL.revokeObjectURL(f),t?.current?.show({message:p(`settings.exportSuccess`,`配置成功导出`),intent:k.SUCCESS,icon:`download`})}catch(e){console.error(e),t?.current?.show({message:p(`settings.exportError`,`导出失败`),intent:k.DANGER,icon:`error`})}}}),(0,X.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-6`,children:[(0,X.jsx)(ee,{settings:s,setSettings:j}),(0,X.jsx)(te,{settings:s,setSettings:j}),(0,X.jsx)(ne,{settings:s,setSettings:j,isAdmin:n?.role===`admin`,maxRetentionDays:n?.max_log_retention_days??(n?.role===`admin`?30:7)}),(0,X.jsx)(re,{profileId:e,toasterRef:t}),(0,X.jsx)(ie,{settings:s,setSettings:j}),(0,X.jsx)(oe,{settings:s,setSettings:j})]}),(0,X.jsx)(se,{testInput:b,setTestInput:x,handleDnsTest:async()=>{if(b.domain){T(!0),C(null);try{C(await K(e,b))}catch(e){console.error(e)}finally{T(!1)}}},testing:w,testResult:S})]})};export{ce as SettingsView};
1
+ import{i as e}from"./rolldown-runtime-C4Xdq4VV.js";import{B as t,C as n,D as r,Et as i,P as a,Qt as o,X as s,at as c,dt as l,et as u,gt as d,ot as f,q as p,st as m,tt as h,v as g,y as _}from"./vendor-react-De1zEwOV.js";import{S as v,b as y}from"./vendor-icons-other-BTYC6Wvz.js";import"./vendor-i18next-CevVzhh3.js";import{B as b,D as x,E as S,H as C,M as w,N as T,P as E,S as D,T as O,V as k,_ as A,d as j,f as M,h as N,p as P,r as F,v as I,w as L,x as R}from"./vendor-ui-core-ClwQiwMI.js";import"./vendor-utils-rmW6cqPl.js";import{$ as z,A as B,M as V,Q as H,at as U,c as W,ft as G,lt as K,nt as q,y as J}from"./index-C5rHE6WK.js";var Y=e(v(),1),X=e(y(),1);const Z=({profile:e,isEditingName:n,setIsEditingName:r,editName:i,setEditName:a,updateProfileName:s,exportProfile:c})=>{let{t:l}=o(),[u,p]=(0,Y.useState)(!1);return(0,X.jsxs)(`div`,{className:`mb-6 flex flex-col md:flex-row justify-between items-start md:items-center gap-4`,children:[(0,X.jsxs)(`div`,{className:`flex flex-col justify-start`,children:[n?(0,X.jsxs)(`div`,{className:`flex items-center gap-2 mb-1`,children:[(0,X.jsx)(I,{content:l(`common.profileNameFormatTip`,`Profile Name tip: 1-30 characters, duplicates not allowed`),isOpen:u,position:b.TOP,intent:k.PRIMARY,className:`flex-1`,children:(0,X.jsx)(`div`,{className:`w-full block`,children:(0,X.jsx)(M,{value:i,onChange:e=>a(e.target.value),onFocus:()=>p(!0),onBlur:()=>p(!1),autoFocus:!0,onKeyDown:t=>{t.key===`Enter`&&s(),t.key===`Escape`&&(r(!1),a(e?.name||``))}})})}),(0,X.jsx)(T,{icon:(0,X.jsx)(d,{size:16}),intent:k.SUCCESS,minimal:!0,onClick:s,disabled:!W.test(i)}),(0,X.jsx)(T,{icon:(0,X.jsx)(_,{size:16}),minimal:!0,onClick:()=>{r(!1),a(e?.name||``)}})]}):(0,X.jsxs)(`div`,{className:`group flex items-center gap-2 mb-1 cursor-pointer`,onClick:()=>r(!0),children:[(0,X.jsx)(`h2`,{className:`bp6-heading mb-0`,children:e?.name}),(0,X.jsx)(T,{icon:(0,X.jsx)(t,{size:14}),minimal:!0,className:`opacity-30 group-hover:opacity-100 transition-opacity`})]}),(0,X.jsx)(`p`,{className:`bp6-text-muted`,children:l(`settings.subtitle`)})]}),(0,X.jsx)(`div`,{className:`flex gap-2 items-center`,children:(0,X.jsx)(T,{size:`large`,icon:(0,X.jsx)(f,{size:18}),text:l(`settings.export`,`导出配置`),onClick:c})})]})},Q=()=>{let{t:e}=o(),[t,n]=(0,Y.useState)([]);return(0,Y.useEffect)(()=>{V().then(t=>{t&&Array.isArray(t)&&n(t.map(t=>({label:e(t.label),url:t.url})))}).catch(e=>console.warn(`Failed to fetch preset upstreams from API`,e))},[e]),t},$=(e,t)=>{let{t:n}=o();return(0,Y.useMemo)(()=>{let e=t>0?t:30,r=n(`settings.retentionMaxSuffix`,`(最长)`),i=[{label:n(`settings.retentionDisabled`,`关闭 (隐私需要)`),value:0},{label:n(`settings.retention10m`,`10 分钟`),value:.007},{label:n(`settings.retention1h`,`1 小时`),value:.0416},{label:n(`settings.retention24h`,`24 小时`),value:1},{label:n(`settings.retention7d`,`7 天`),value:7},{label:n(`settings.retention30d`,`30 天`),value:30},{label:n(`settings.retention90d`,`90 天`),value:90},{label:n(`settings.retention180d`,`180 天`),value:180},{label:n(`settings.retention360d`,`360 天`),value:360}],a=i.filter(t=>t.value<=e);return e>0&&!a.some(t=>t.value===e)&&(a.push({label:`${e} ${n(`settings.daysUnit`,`天`)}`,value:e}),a.sort((e,t)=>e.value-t.value)),a.length===0?[i[0]]:a.map(t=>t.value===e&&t.value>0?{...t,label:`${t.label} ${r}`}:t)},[n,t])},ee=({settings:e,setSettings:t})=>{let{t:n}=o(),r=(0,X.jsx)(S,{className:`min-w-96`,children:Q().map((n,r)=>(0,X.jsx)(L,{text:n.label,onClick:()=>t({...e,upstream:[n.url]}),labelElement:(0,X.jsx)(`div`,{className:`flex flex-col items-end text-right`,children:(0,X.jsx)(`span`,{className:`text-[9px] opacity-85 max-w-64 truncate`,title:n.url,children:n.url})})},r))});return(0,X.jsxs)(R,{elevation:C.ONE,className:`dark:bg-gray-900 dark:border-gray-800`,children:[(0,X.jsxs)(w,{className:`flex items-center gap-2 mb-4 font-bold`,children:[(0,X.jsx)(a,{size:18,className:`text-blue-500`}),` `,n(`settings.upstreamTitle`)]}),(0,X.jsx)(P,{label:`DoH (https://) / DoT (tls://) / DNS Stamp (sdns://) / ${n(`settings.classicDns`)}`,children:(0,X.jsx)(M,{fill:!0,placeholder:`https://... | tls://... | sdns://... | 1.1.1.1`,value:e.upstream?.[0]||``,onChange:n=>t({...e,upstream:[n.target.value]}),onFocus:e=>e.target.select(),rightElement:(0,X.jsx)(O,{content:r,placement:`bottom-end`,animation:`minimal`,arrow:!1,children:(0,X.jsx)(T,{variant:`minimal`,icon:`chevron-down`})})})}),(0,X.jsx)(`p`,{className:`text-xs opacity-60`,children:n(`settings.upstreamDesc`)})]})},te=({settings:e,setSettings:t})=>{let{t:n}=o();return(0,X.jsxs)(R,{elevation:C.ONE,className:`dark:bg-gray-900 dark:border-gray-800`,children:[(0,X.jsxs)(w,{className:`flex items-center gap-2 mb-4 font-bold`,children:[(0,X.jsx)(r,{size:18,className:`text-green-500`}),` `,n(`settings.defaultPolicyTitle`)]}),(0,X.jsxs)(`div`,{className:`space-y-4`,children:[(0,X.jsx)(P,{label:n(`settings.onNoMatch`),children:(0,X.jsxs)(j,{fill:!0,value:e.default_policy,onChange:n=>t({...e,default_policy:n.target.value}),children:[(0,X.jsx)(`option`,{value:`ALLOW`,children:n(`settings.allowAll`)}),(0,X.jsx)(`option`,{value:`BLOCK`,children:n(`settings.blockAll`)})]})}),(0,X.jsx)(A,{}),(0,X.jsx)(P,{label:n(`settings.blockModeTitle`),helperText:n(`settings.blockModeDesc`),children:(0,X.jsxs)(j,{fill:!0,value:e.block_mode||`NULL_IP`,onChange:n=>t({...e,block_mode:n.target.value}),children:[(0,X.jsxs)(`option`,{value:`NULL_IP`,children:[`0.0.0.0 / :: (`,n(`settings.default`),`)`]}),(0,X.jsxs)(`option`,{value:`NXDOMAIN`,children:[`NXDOMAIN (`,n(`settings.NXDOMAIN`),`)`]}),(0,X.jsxs)(`option`,{value:`NODATA`,children:[`NODATA (`,n(`settings.NODATA`),`)`]}),(0,X.jsx)(`option`,{value:`CUSTOM_IP`,children:n(`settings.customIP`)})]})}),e.block_mode===`CUSTOM_IP`&&(0,X.jsxs)(`div`,{className:`space-y-2 animate-in fade-in slide-in-from-top-1`,children:[(0,X.jsx)(M,{placeholder:`IPv4: 127.0.0.1`,value:e.custom_block_ipv4||``,onChange:n=>t({...e,custom_block_ipv4:n.target.value})}),(0,X.jsx)(M,{placeholder:`IPv6: ::1`,value:e.custom_block_ipv6||``,onChange:n=>t({...e,custom_block_ipv6:n.target.value})})]})]})]})},ne=({settings:e,setSettings:t,isAdmin:n,maxRetentionDays:r})=>{let{t:i}=o(),a=$(n,r);Y.useEffect(()=>{if(r>0&&e.log_retention_days>r&&a.length>0){let n=a[a.length-1];n&&e.log_retention_days!==n.value&&t({...e,log_retention_days:n.value})}},[r,e.log_retention_days,a,t]);let s=e.log_retention_days===0;return(0,X.jsxs)(R,{elevation:C.ONE,className:`dark:bg-gray-900 dark:border-gray-800`,children:[(0,X.jsxs)(w,{className:`flex items-center gap-2 mb-4 font-bold`,children:[(0,X.jsx)(l,{size:18,className:`text-purple-500`}),` `,i(`settings.logRetentionTitle`)]}),(0,X.jsxs)(`div`,{className:`space-y-4`,children:[(0,X.jsx)(P,{label:i(`settings.retentionDuration`),children:(0,X.jsx)(j,{fill:!0,value:e.log_retention_days,onChange:n=>t({...e,log_retention_days:parseFloat(n.target.value)}),children:a.map(e=>(0,X.jsx)(`option`,{value:e.value,children:e.label},e.value))})}),(0,X.jsx)(`p`,{className:`text-xs opacity-60`,children:s?i(`settings.retentionDisabledDesc`,`已关闭日志记录。系统将不会记录任何 DNS 查询日志并立即清空历史日志。`):i(`settings.retentionDesc`)}),(0,X.jsxs)(`div`,{className:`pt-3 border-t border-gray-100 dark:border-gray-800/80`,children:[(0,X.jsx)(N,{label:i(`settings.skipLogOnPass`,`不记录放行记录`),checked:!s&&!!e.skip_log_on_pass,disabled:s,onChange:n=>t({...e,skip_log_on_pass:n.currentTarget.checked})}),(0,X.jsx)(`p`,{className:`text-xs opacity-60 mt-1`,children:i(`settings.skipLogOnPassDesc`,`启用后不记录正常放行的 DNS 查询,仅记录被拦截、重定向或解析失败的记录。可大幅减少存储占用与写操作。`)})]})]})]})},re=({profileId:e,toasterRef:t})=>{let{t:r}=o(),[i,a]=(0,Y.useState)(()=>J.getLocalRetentionDays()),[s,c]=(0,Y.useState)(!1),[l,d]=(0,Y.useState)(null),[f,p]=(0,Y.useState)(!1),[h,g]=(0,Y.useState)(!1),_=(0,Y.useCallback)(async()=>{try{await J.init();let t=await J.getStorageInfo();c(t?.isOpfs??J.getIsOpfs());let n=t.profileStats.find(t=>t.profile_id===e);d(n?n.count:0)}catch(e){console.error(`[LocalRetentionCard] Failed to load storage info:`,e),c(J.getIsOpfs()),d(0)}},[e]);(0,Y.useEffect)(()=>{_()},[_]);let v=e=>{a(e),J.setLocalRetentionDays(e),_()};return(0,X.jsxs)(R,{elevation:C.ONE,className:`dark:bg-gray-900 dark:border-gray-800`,children:[(0,X.jsxs)(w,{className:`flex items-center gap-2 mb-4 font-bold`,children:[(0,X.jsx)(m,{size:18,className:`text-cyan-500`}),` `,r(`settings.localRetentionTitle`,`本地存储与留存`)]}),(0,X.jsxs)(`div`,{className:`space-y-4`,children:[(0,X.jsx)(P,{label:r(`settings.localRetentionDuration`,`本地保留时长`),children:(0,X.jsxs)(j,{fill:!0,value:i,onChange:e=>v(parseInt(e.target.value,10)),children:[(0,X.jsx)(`option`,{value:30,children:r(`settings.localRetention30d`,`30 天`)}),(0,X.jsx)(`option`,{value:90,children:r(`settings.localRetention90d`,`90 天 (推荐)`)}),(0,X.jsx)(`option`,{value:180,children:r(`settings.localRetention180d`,`180 天`)}),(0,X.jsx)(`option`,{value:365,children:r(`settings.localRetention365d`,`365 天 (1 年)`)}),(0,X.jsx)(`option`,{value:0,children:r(`settings.localRetentionUnlimited`,`永久保留 (直到手动清除)`)})]})}),(0,X.jsx)(`p`,{className:`text-xs opacity-60`,children:r(`settings.localRetentionDesc`,`日志将持久化保存在当前浏览器本地的 SQLite 数据库 (OPFS) 中,提供秒级本地搜索并节省云端存储费用。超出此时长的本地日志将自动清除。`)}),(0,X.jsxs)(`div`,{className:`pt-3 border-t border-gray-100 dark:border-gray-800/80 space-y-3`,children:[(0,X.jsxs)(`div`,{className:`flex items-center justify-between text-xs`,children:[(0,X.jsxs)(`span`,{className:`flex items-center gap-1.5 opacity-70`,children:[(0,X.jsx)(u,{size:14}),r(`settings.localEngineStorage`,`存储引擎`),`:`]}),(0,X.jsx)(F,{minimal:!0,intent:s?k.SUCCESS:k.WARNING,className:`text-[11px]`,children:s?r(`settings.localEngineOpfs`,`OPFS 本地持久化`):r(`settings.localEngineMemory`,`内存临时存储 (无痕/私密模式)`)})]}),(0,X.jsxs)(`div`,{className:`flex items-center justify-between text-xs`,children:[(0,X.jsxs)(`span`,{className:`opacity-70`,children:[r(`settings.localCachedCount`,`本地已缓存日志`),`:`]}),(0,X.jsx)(`span`,{className:`font-mono font-medium`,children:l===null?`...`:r(`settings.localCachedCountUnit`,`{{count}} 条记录`,{count:l})})]}),(0,X.jsx)(`div`,{className:`pt-1 flex justify-end`,children:(0,X.jsx)(T,{minimal:!0,small:!0,intent:k.DANGER,icon:(0,X.jsx)(n,{size:13}),text:r(`settings.clearLocalData`,`清空本地日志`),disabled:l===0||l===null||h,onClick:()=>p(!0)})})]})]}),(0,X.jsx)(x,{isOpen:f,confirmButtonText:r(`common.confirm`,`确认清空`),cancelButtonText:r(`common.cancel`,`取消`),intent:k.DANGER,icon:`trash`,onConfirm:async()=>{g(!0);try{await J.clearProfile(e),d(0),t?.current?.show({message:r(`settings.clearLocalDataSuccess`,`本地日志已成功清空`),intent:k.SUCCESS,icon:`tick`})}catch(e){console.error(`[LocalRetentionCard] Failed to clear local profile logs:`,e),t?.current?.show({message:r(`settings.clearLocalDataError`,`清空本地日志失败`),intent:k.DANGER,icon:`error`})}finally{g(!1),p(!1)}},onCancel:()=>p(!1),loading:h,children:(0,X.jsx)(`p`,{children:r(`settings.clearLocalDataConfirm`,`确定要清空此配置在本地保存的所有日志吗?(云端日志不受影响)`)})})]})},ie=({settings:e,setSettings:t})=>{let{t:n}=o();return(0,X.jsxs)(R,{elevation:C.ONE,className:`dark:bg-gray-900 dark:border-gray-800`,children:[(0,X.jsxs)(w,{className:`flex items-center gap-2 mb-3 font-bold`,children:[(0,X.jsx)(h,{size:18,className:`text-orange-500`}),` `,n(`settings.ecsTitle`)]}),(0,X.jsxs)(`div`,{className:`space-y-4`,children:[(0,X.jsx)(N,{label:n(`settings.sendEcs`),checked:e.ecs.enabled,onChange:n=>t({...e,ecs:{...e.ecs,enabled:n.currentTarget.checked}})}),(0,X.jsx)(N,{label:n(`settings.customSubnet`),disabled:!e.ecs.enabled,checked:!e.ecs.use_client_ip,onChange:n=>t({...e,ecs:{...e.ecs,use_client_ip:!n.currentTarget.checked}})}),(0,X.jsxs)(`div`,{className:`space-y-3 pt-2 border-t border-gray-100 dark:border-gray-800`,children:[(0,X.jsx)(P,{label:n(`settings.customIpv4`),labelInfo:n(`settings.ipv4Hint`),disabled:!(e.ecs.enabled&&!e.ecs.use_client_ip),children:(0,X.jsx)(M,{placeholder:`0.0.0.0/0`,value:e.ecs.ipv4_cidr||``,disabled:!(e.ecs.enabled&&!e.ecs.use_client_ip),onChange:n=>t({...e,ecs:{...e.ecs,ipv4_cidr:n.target.value}})})}),(0,X.jsx)(P,{label:n(`settings.customIpv6`),labelInfo:n(`settings.ipv6Hint`),disabled:!(e.ecs.enabled&&!e.ecs.use_client_ip),children:(0,X.jsx)(M,{placeholder:`::/0`,value:e.ecs.ipv6_cidr||``,disabled:!(e.ecs.enabled&&!e.ecs.use_client_ip),onChange:n=>t({...e,ecs:{...e.ecs,ipv6_cidr:n.target.value}})})})]}),(0,X.jsx)(`p`,{className:`text-xs opacity-60`,children:n(`settings.ecsUpstreamHint`)})]})]})};var ae=[{domain:`cloudflare-ech.com`,isPreferred:!0},{domain:`crypto.cloudflare.com`,isPreferred:!1},{domain:`one.one.one.one`,isPreferred:!1},{domain:`www.cloudflare.com`,isPreferred:!1},{domain:`encryptedsni.com`,isPreferred:!1},{domain:`cdnjs.com`,isPreferred:!1}];const oe=({settings:e,setSettings:t})=>{let{t:n}=o(),[r,i]=Y.useState(ae);Y.useEffect(()=>{B().then(e=>{Array.isArray(e)&&e.length>0&&i(e.map(e=>typeof e==`string`?{domain:e,isPreferred:e===`cloudflare-ech.com`}:{domain:e.domain,isPreferred:!!e.isPreferred}))}).catch(e=>console.warn(`Failed to fetch preset ECH fronting domains from API`,e))},[]);let a=typeof e.best_effort_ech==`boolean`?e.best_effort_ech:!!e.best_effort_ech?.enabled,l=typeof e.best_effort_ech==`object`&&e.best_effort_ech?.fronting_domain?e.best_effort_ech.fronting_domain:`cloudflare-ech.com`,u=n=>{t({...e,best_effort_ech:{enabled:n,fronting_domain:l||`cloudflare-ech.com`}})},d=n=>{t({...e,best_effort_ech:{enabled:a,fronting_domain:n}})},f=(0,X.jsx)(S,{className:`min-w-72`,children:r.map(e=>(0,X.jsx)(L,{text:e.domain,onClick:()=>d(e.domain),labelElement:e.isPreferred?(0,X.jsx)(F,{minimal:!0,intent:k.PRIMARY,className:`text-[10px]`,children:n(`settings.echPreferred`,`首选`)}):void 0},e.domain))});return(0,X.jsxs)(R,{elevation:C.ONE,className:`dark:bg-gray-900 dark:border-gray-800`,children:[(0,X.jsxs)(`div`,{className:`flex items-center justify-between mb-3`,children:[(0,X.jsxs)(w,{className:`flex items-center gap-2 m-0 font-bold text-purple-600 dark:text-purple-400`,children:[(0,X.jsx)(s,{size:18}),` `,n(`settings.echTitle`)]}),(0,X.jsx)(O,{placement:`bottom-end`,usePortal:!0,content:(0,X.jsxs)(`div`,{className:`p-4 max-w-sm`,children:[(0,X.jsx)(w,{children:n(`settings.whatIsEch`,`何为 ECH (Encrypted Client Hello)?`)}),(0,X.jsx)(`p`,{className:`text-sm mb-2`,children:n(`settings.echHelpDesc`)}),(0,X.jsxs)(`ul`,{className:`list-disc list-inside text-sm opacity-80 mb-3 space-y-1`,children:[(0,X.jsx)(`li`,{children:n(`settings.echHelpBenefit1`)}),(0,X.jsx)(`li`,{children:n(`settings.echHelpBenefit2`)})]}),(0,X.jsx)(`div`,{className:`text-xs border-t border-gray-100 dark:border-gray-700 pt-2`,children:(0,X.jsxs)(`a`,{href:`https://en.wikipedia.org/wiki/Encrypted_Client_Hello`,target:`_blank`,rel:`noreferrer`,className:`flex items-center gap-1 text-blue-500 hover:underline`,children:[(0,X.jsx)(c,{size:10}),` `,n(`setup.learnMore`,`了解更多`)]})})]}),children:(0,X.jsx)(T,{icon:`help`,variant:`minimal`,intent:k.NONE})})]}),(0,X.jsxs)(`div`,{className:`space-y-4`,children:[(0,X.jsx)(N,{label:n(`settings.enableEch`,`启用重写 ECH`),checked:a,onChange:e=>u(e.currentTarget.checked)}),(0,X.jsx)(`p`,{className:`text-xs opacity-60 leading-relaxed`,children:n(`settings.echDesc`,`针对由 Cloudflare 代理的域名,当查询 HTTPS (Type 65) 或 SVCB (Type 64) 记录且上游未配置 ECH 时,自动重写注入 ECH 参数以保护 SNI 隐私。`)}),a&&(0,X.jsx)(`div`,{className:`space-y-3 pt-3 border-t border-gray-100 dark:border-gray-800`,children:(0,X.jsx)(P,{label:n(`settings.echFrontingTitle`,`表层 SNI (ECH Fronting)`),labelInfo:(0,X.jsx)(`span`,{className:`text-xs opacity-60`,children:n(`settings.echFrontingDesc`,`TLS 握手外层可见的伪装域名`)}),children:(0,X.jsx)(M,{fill:!0,placeholder:n(`settings.echFrontingCustomPlaceholder`,`输入自定义表层域名,例如 crypto.cloudflare.com`),value:l,onChange:e=>d(e.target.value),onFocus:e=>e.target.select(),className:`font-mono text-sm`,rightElement:(0,X.jsx)(O,{content:f,placement:`bottom-end`,animation:`minimal`,arrow:!1,children:(0,X.jsx)(T,{variant:`minimal`,icon:`chevron-down`})})})})})]})]})},se=({testInput:e,setTestInput:t,handleDnsTest:n,testing:r,testResult:a})=>{let{t:s}=o();return(0,X.jsxs)(R,{elevation:C.TWO,className:`dark:bg-gray-900 border-t-2 border-blue-500`,children:[(0,X.jsxs)(w,{className:`flex items-center gap-2 mb-6 font-bold`,children:[(0,X.jsx)(g,{size:20,className:`text-yellow-500 fill-yellow-500`}),` `,s(`settings.testToolTitle`)]}),(0,X.jsxs)(`div`,{className:`flex flex-col space-y-6`,children:[(0,X.jsx)(P,{label:s(`settings.testDomain`),className:`mb-0`,children:(0,X.jsx)(M,{fill:!0,large:!0,placeholder:s(`settings.domainPlaceholder`),value:e.domain,onChange:n=>t({...e,domain:n.target.value}),onKeyDown:e=>e.key===`Enter`&&n()})}),(0,X.jsxs)(`div`,{className:`flex justify-end gap-4 items-end`,children:[(0,X.jsx)(P,{label:s(`settings.recordType`),className:`w-32 mb-0`,children:(0,X.jsxs)(j,{fill:!0,large:!0,value:e.type,onChange:n=>t({...e,type:n.target.value}),children:[(0,X.jsx)(`option`,{value:`A`,children:`A`}),(0,X.jsx)(`option`,{value:`AAAA`,children:`AAAA`}),(0,X.jsx)(`option`,{value:`CNAME`,children:`CNAME`}),(0,X.jsx)(`option`,{value:`TXT`,children:`TXT`})]})}),(0,X.jsx)(P,{label:`\xA0`,className:`mb-0`,children:(0,X.jsx)(T,{size:`large`,intent:k.PRIMARY,icon:`search`,text:s(`settings.runTest`),onClick:n,loading:r})})]}),a&&(0,X.jsxs)(`div`,{className:`bg-gray-50 dark:bg-gray-800/50 p-6 rounded-xl border border-gray-100 dark:border-gray-800 space-y-6 animate-in fade-in slide-in-from-top-4`,children:[(0,X.jsxs)(`div`,{className:`flex flex-wrap gap-4 items-center`,children:[(0,X.jsx)(F,{large:!0,round:!0,intent:a.action===`PASS`?k.SUCCESS:a.action===`BLOCK`?k.DANGER:k.WARNING,className:`px-4 font-bold`,children:a.action}),(0,X.jsxs)(`div`,{className:`flex flex-col`,children:[(0,X.jsx)(`span`,{className:`text-[10px] uppercase font-bold opacity-40`,children:s(`settings.hitRule`)}),(0,X.jsx)(`span`,{className:`text-sm font-bold`,children:a.reason||s(`settings.defaultAllow`)})]}),(0,X.jsxs)(`div`,{className:`flex flex-col border-l border-gray-200 dark:border-gray-700 pl-4`,children:[(0,X.jsx)(`span`,{className:`text-[10px] uppercase font-bold opacity-40`,children:s(`settings.parseLatency`)}),(0,X.jsx)(`span`,{className:`text-sm font-mono font-bold`,children:a.latency?`${a.latency}ms`:`-`})]}),a.timings&&(0,X.jsx)(`div`,{className:`flex flex-wrap gap-x-4 gap-y-1 border-l border-gray-200 dark:border-gray-700 pl-4 max-w-md`,children:Object.entries(a.timings).map(([e,t])=>(0,X.jsxs)(`div`,{className:`flex gap-1 items-baseline`,children:[(0,X.jsxs)(`span`,{className:`text-[9px] opacity-40 uppercase font-mono`,children:[e,`:`]}),(0,X.jsxs)(`span`,{className:`text-[10px] font-mono font-bold`,children:[t,`ms`]})]},e))}),(0,X.jsx)(A,{}),(0,X.jsxs)(`div`,{className:`flex items-center gap-2 bg-white dark:bg-gray-900 px-3 py-1.5 rounded-lg shadow-sm border border-gray-100 dark:border-gray-800`,children:[(0,X.jsx)(p,{size:14,className:`text-red-500`}),(0,X.jsxs)(`div`,{className:`flex flex-col`,children:[(0,X.jsx)(`span`,{className:`text-[10px] uppercase font-bold opacity-40 leading-none`,children:s(`settings.sourceIp`)}),(0,X.jsxs)(`span`,{className:`text-xs font-mono`,children:[a.client_ip,` (`,a.geo_country,`)`]})]})]})]}),(0,X.jsxs)(`div`,{className:`space-y-3`,children:[(0,X.jsxs)(`div`,{className:`text-[10px] uppercase font-bold opacity-40 flex items-center gap-1`,children:[(0,X.jsx)(i,{size:10}),` `,s(`settings.answerSection`)]}),(0,X.jsx)(`div`,{className:`font-mono text-sm leading-relaxed bg-white dark:bg-gray-900 p-4 rounded-xl border border-gray-100 dark:border-gray-800 shadow-inner`,children:a.answers&&a.answers.length>0?a.answers.map((e,t)=>(0,X.jsxs)(`div`,{className:`flex gap-4 py-1 border-b border-gray-50 dark:border-gray-800 last:border-0 hover:bg-blue-50/50 dark:hover:bg-blue-900/10 transition-colors px-2`,children:[(0,X.jsx)(`span`,{className:`w-16 font-bold text-blue-500`,children:e.type}),(0,X.jsx)(`span`,{className:`flex-1 dark:text-gray-300`,children:e.data}),(0,X.jsxs)(`span`,{className:`text-[10px] opacity-30 italic`,children:[`TTL: `,e.ttl,`s`]})]},t)):(0,X.jsx)(`div`,{className:`p-4 opacity-40 italic text-center`,children:s(`settings.noRecordsReturned`)})})]}),a.diagnostics&&(0,X.jsx)(D,{minimal:!0,intent:a.action===`FAIL`?k.DANGER:k.NONE,className:`text-xs font-mono`,children:(0,X.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,X.jsxs)(`div`,{className:`flex justify-between items-center`,children:[(0,X.jsx)(`span`,{className:`font-bold uppercase tracking-wider`,children:s(`settings.diagnostics`)}),(0,X.jsx)(`span`,{className:`font-bold`,children:a.action===`FAIL`?a.diagnostics.status>0?`HTTP ${a.diagnostics.status}${a.diagnostics.status_text?` (${a.diagnostics.status_text})`:``}`:`Network / Connection Error`:a.diagnostics.method===`POST`||a.diagnostics.method===`GET`?`HTTP ${a.diagnostics.status}${a.diagnostics.status_text?` (${a.diagnostics.status_text})`:``}`:`Connected (OK)`})]}),(0,X.jsxs)(`div`,{className:`flex items-center gap-2 text-xs opacity-80`,children:[(0,X.jsx)(`span`,{className:`px-1.5 py-0.5 bg-gray-200 dark:bg-gray-700 rounded text-[10px] font-bold`,children:a.diagnostics.method}),(0,X.jsx)(`span`,{className:`break-all`,children:a.diagnostics.upstream_url})]}),a.diagnostics.cf_ray&&(0,X.jsxs)(`div`,{className:`text-[11px] opacity-75`,children:[`CF-Ray: `,(0,X.jsx)(`span`,{className:`font-bold`,children:a.diagnostics.cf_ray})]}),a.diagnostics.error_detail&&a.action===`FAIL`&&(0,X.jsxs)(`div`,{className:`p-2 bg-red-50 dark:bg-red-950/40 rounded border border-red-200 dark:border-red-900/50 text-red-700 dark:text-red-300 break-words`,children:[(0,X.jsxs)(`div`,{className:`font-bold mb-0.5`,children:[s(`settings.errorDetail`),`:`]}),(0,X.jsx)(`div`,{children:a.diagnostics.error_detail})]}),a.diagnostics.response_body&&(0,X.jsxs)(`div`,{className:`p-2 bg-gray-100 dark:bg-gray-900 rounded border border-gray-200 dark:border-gray-700 text-gray-700 dark:text-gray-300 break-words text-[11px]`,children:[(0,X.jsxs)(`div`,{className:`font-bold mb-0.5 opacity-60`,children:[s(`settings.upstreamResponse`),`:`]}),(0,X.jsx)(`div`,{className:`line-clamp-3`,children:a.diagnostics.response_body})]})]})})]})]})]})},ce=({profileId:e,toasterRef:t,currentUser:n,onSavingChange:r})=>{let[i,a]=(0,Y.useState)(null),[s,c]=(0,Y.useState)(null),[l,u]=(0,Y.useState)(!0),[d,f]=(0,Y.useState)(!1),{t:p}=o();(0,Y.useEffect)(()=>(r?.(d),()=>{r?.(!1)}),[d,r]);let m=(0,Y.useRef)(!0),h=(0,Y.useRef)(null),g=(0,Y.useRef)(null),_=(0,Y.useRef)(0),v=e=>typeof structuredClone==`function`?structuredClone(e):JSON.parse(JSON.stringify(e)),[y,b]=(0,Y.useState)(!1),[x,S]=(0,Y.useState)(``),[C,w]=(0,Y.useState)({domain:`o-o.myaddr.l.google.com`,type:`TXT`}),[T,D]=(0,Y.useState)(null),[O,A]=(0,Y.useState)(!1);(0,Y.useEffect)(()=>{m.current=!0,h.current&&=(clearTimeout(h.current),null),(async()=>{u(!0);try{let t=await H(e);a(t),S(t.name);let n=JSON.parse(t.settings);return g.current=v(n),c(n),i}catch(e){console.error(e)}finally{u(!1)}})()},[e]),(0,Y.useEffect)(()=>{if(!l&&s&&m.current){let e=setTimeout(()=>{m.current=!1,s&&(g.current=v(s))},500);return()=>clearTimeout(e)}},[l,s]),(0,Y.useEffect)(()=>()=>{h.current&&clearTimeout(h.current)},[]);let j=async()=>{if(!x||x===i?.name){b(!1);return}try{await U(e,x),a(e=>e?{...e,name:x}:null),b(!1),t?.current?.show({message:p(`settings.nameUpdateSuccess`,`名称已更新`),intent:k.SUCCESS})}catch(e){console.error(e);let n=e.message,r=n;n===`The profile name already exists`?r=p(`common.profileNameExists`,`The profile name already exists`):n===`Invalid Profile Name format`&&(r=p(`common.profileNameFormatError`,`Invalid Profile Name format`)),t?.current?.show({message:r||p(`settings.nameUpdateFailed`,`更新失败`),intent:k.DANGER})}},M=(0,Y.useCallback)(async n=>{if(!n)return;let r=++_.current;f(!0);try{await G(e,n),r===_.current&&(g.current=v(n))}catch(e){console.error(e),r===_.current&&(h.current&&=(clearTimeout(h.current),null),g.current&&c(v(g.current)),t?.current?.show({message:p(`settings.saveError`,`保存失败`),intent:k.DANGER,icon:`error`}))}finally{r===_.current&&f(!1)}},[e,t,p]),N=(0,Y.useCallback)(e=>{h.current&&clearTimeout(h.current),h.current=setTimeout(()=>{M(e)},600)},[M]),P=(0,Y.useCallback)(e=>{c(e),m.current||N(e)},[N]);return l||!s?(0,X.jsx)(`div`,{className:`p-20 flex justify-center`,children:(0,X.jsx)(E,{})}):(0,X.jsxs)(`div`,{className:`p-0 sm:px-4 lg:px-8 max-w-5xl mx-auto space-y-8 pb-20`,children:[(0,X.jsx)(Z,{profile:i,isEditingName:y,setIsEditingName:b,editName:x,setEditName:S,updateProfileName:j,exportProfile:async()=>{if(!(!i||!s))try{let[n,r]=await Promise.all([q(e).catch(()=>[]),z(e).catch(()=>[])]),a=new Set,o=(n||[]).filter(e=>{let t=(e.pattern||``).trim().toLowerCase();return!t||a.has(t)?!1:(a.add(t),!0)}),c=new Set,l=(r||[]).filter(e=>{let t=(e.url||``).trim().toLowerCase();return!t||c.has(t)?!1:(c.add(t),!0)}).map(e=>({url:e.url,enabled:!!e.enabled})),u={version:2,name:i.name,settings:s,rules:o,filters:l,exported_at:Math.floor(Date.now()/1e3)},d=new Blob([JSON.stringify(u,null,2)],{type:`application/json`}),f=URL.createObjectURL(d),m=document.createElement(`a`);m.href=f,m.download=`dns-worker-${i.name||e}.json`,document.body.appendChild(m),m.click(),document.body.removeChild(m),URL.revokeObjectURL(f),t?.current?.show({message:p(`settings.exportSuccess`,`配置成功导出`),intent:k.SUCCESS,icon:`download`})}catch(e){console.error(e),t?.current?.show({message:p(`settings.exportError`,`导出失败`),intent:k.DANGER,icon:`error`})}}}),(0,X.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-6`,children:[(0,X.jsx)(ee,{settings:s,setSettings:P}),(0,X.jsx)(te,{settings:s,setSettings:P}),(0,X.jsx)(ne,{settings:s,setSettings:P,isAdmin:n?.role===`admin`,maxRetentionDays:n?.max_log_retention_days??(n?.role===`admin`?30:7)}),(0,X.jsx)(re,{profileId:e,toasterRef:t}),(0,X.jsx)(ie,{settings:s,setSettings:P}),(0,X.jsx)(oe,{settings:s,setSettings:P})]}),(0,X.jsx)(se,{testInput:C,setTestInput:w,handleDnsTest:async()=>{if(C.domain){A(!0),D(null);try{D(await K(e,C))}catch(e){console.error(e)}finally{A(!1)}}},testing:O,testResult:T})]})};export{ce as SettingsView};
@@ -0,0 +1 @@
1
+ import{i as e}from"./rolldown-runtime-C4Xdq4VV.js";import{A as t,B as n,C as r,E as i,Et as a,F as o,G as s,I as c,M as l,P as u,Qt as d,R as f,Tt as p,W as m,at as h,it as g,lt as _,q as v,rt as y,tt as b,w as x,z as S}from"./vendor-react-De1zEwOV.js";import{S as C,b as w}from"./vendor-icons-other-BTYC6Wvz.js";import"./vendor-i18next-CevVzhh3.js";import{A as T,B as E,F as D,L as O,M as k,N as A,O as j,P as M,R as N,S as P,T as F,V as I,a as L,d as R,f as z,i as B,n as V,o as H,r as U,v as W,z as G}from"./vendor-ui-core-ClwQiwMI.js";import{_t as K,t as ee,vt as q}from"./vendor-utils-rmW6cqPl.js";import{$t as te,D as ne,F as J,L as re,N as ie,O as ae,P as oe,Q as se,X as ce,_ as le,a as ue,h as de,n as Y,ot as fe,q as pe,st as me,t as he,z as ge}from"./index-C5rHE6WK.js";import{t as _e}from"./SwipeableDrawer-BrlOF_Xg.js";var X=e(C(),1),Z=e(w(),1);const ve=()=>{let{t:e}=d();return(0,Z.jsxs)(`div`,{className:`flex flex-col sm:flex-row justify-between items-start sm:items-center gap-4`,children:[(0,Z.jsxs)(`div`,{children:[(0,Z.jsx)(T,{className:`font-bold text-gray-900 dark:text-white m-0`,children:e(`setup.title`)}),(0,Z.jsx)(`p`,{className:`bp6-text-muted m-0 mt-1`,children:e(`setup.subtitle`)})]}),(0,Z.jsx)(`div`,{className:`flex items-center`,children:(0,Z.jsx)(he,{})})]})},ye=({isVerifying:e,verifyResult:n,handleVerify:r,isMobile:i,clientInfo:o,showIp:s,setShowIp:c,showLocation:l,setShowLocation:f,traceInfo:p,edgeLocation:m})=>{let{t:h}=d(),{isServerfull:_}=Y(),[x,S]=(0,X.useState)(!1),C=(0,Z.jsxs)(`div`,{className:q(`bg-white dark:bg-gray-900 p-4 rounded-lg border border-gray-100 dark:border-gray-800 shadow-sm flex items-start gap-3 select-none h-full transition-all`,!_),children:[(0,Z.jsx)(u,{size:18,className:`text-purple-500 mt-1 shrink-0`}),(0,Z.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,Z.jsx)(`div`,{className:`text-[10px] uppercase font-bold opacity-40`,children:_?h(`setup.serverLocation`,`服务器位置`):h(`setup.edgeServer`)}),(0,Z.jsx)(`div`,{className:`font-bold truncate`,title:_?m||``:m||p?.colo||``,children:_?m||h(`setup.detecting`):m||p?.colo||h(`setup.detecting`)})]})]});return(0,Z.jsx)(H,{title:h(`setup.verifyConnection`),icon:(0,Z.jsx)(a,{size:16}),children:(0,Z.jsx)(L,{children:(0,Z.jsxs)(`div`,{className:`flex flex-col space-y-6`,children:[(0,Z.jsxs)(`div`,{className:`flex flex-col md:flex-row items-center justify-between bg-gray-50 dark:bg-gray-800/50 p-6 rounded-xl border border-gray-100 dark:border-gray-800 gap-6`,children:[(0,Z.jsxs)(`div`,{className:`flex flex-col md:flex-row items-center gap-4 text-center md:text-left`,children:[(0,Z.jsx)(`div`,{className:`p-3 rounded-full ${n?.success?`bg-green-100 text-green-600`:n?`bg-red-100 text-red-600`:`bg-blue-100 text-blue-600`}`,children:e?(0,Z.jsx)(M,{size:24}):n?.success?(0,Z.jsx)(t,{size:24}):(0,Z.jsx)(u,{size:24})}),(0,Z.jsxs)(`div`,{children:[(0,Z.jsx)(`div`,{className:`font-bold text-lg`,children:e?h(`setup.verifying`):n?.success?h(`setup.connected`):h(`setup.notConnected`)}),(0,Z.jsx)(`div`,{className:`text-sm opacity-60`,children:n?.success?n.profileMatch?h(`setup.profileMatch`):h(`setup.profileMismatch`):h(`setup.verifyHint`)})]})]}),(0,Z.jsx)(A,{size:`large`,intent:n?.success?I.SUCCESS:I.PRIMARY,icon:`refresh`,text:h(`setup.refreshStatus`),onClick:r,loading:e,fill:i})]}),o&&(0,Z.jsxs)(`div`,{className:`grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-4`,children:[(0,Z.jsxs)(`div`,{className:`bg-white dark:bg-gray-900 p-4 rounded-lg border border-gray-100 dark:border-gray-800 shadow-sm flex items-start gap-3`,children:[(0,Z.jsx)(b,{size:18,className:`text-blue-500 mt-1`}),(0,Z.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,Z.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,Z.jsx)(`div`,{className:`text-[10px] uppercase font-bold opacity-40`,children:h(`setup.egressIp`)}),(0,Z.jsx)(`button`,{onClick:()=>c(!s),className:`text-gray-400 hover:text-blue-500 transition-colors`,children:s?(0,Z.jsx)(y,{size:16}):(0,Z.jsx)(g,{size:16})})]}),(0,Z.jsx)(`div`,{className:`font-mono font-bold text-blue-600 dark:text-blue-400 truncate`,children:(0,Z.jsx)(`span`,{className:q(`transition-[filter] duration-200 inline-block`,!s&&`filter blur-[6px] select-none`),children:o.ip})})]})]}),(0,Z.jsxs)(`div`,{className:`bg-white dark:bg-gray-900 p-4 rounded-lg border border-gray-100 dark:border-gray-800 shadow-sm flex items-start gap-3`,children:[(0,Z.jsx)(v,{size:18,className:`text-red-500 mt-1`}),(0,Z.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,Z.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,Z.jsx)(`div`,{className:`text-[10px] uppercase font-bold opacity-40`,children:h(`setup.currentLocation`)}),(0,Z.jsx)(`button`,{onClick:()=>f(!l),className:`text-gray-400 hover:text-red-500 transition-colors`,children:l?(0,Z.jsx)(y,{size:16}):(0,Z.jsx)(g,{size:16})})]}),(0,Z.jsx)(`div`,{className:`font-bold truncate`,children:(0,Z.jsx)(`span`,{className:q(`transition-[filter] duration-200 inline-block`,!l&&`filter blur-[6px] select-none`),children:(()=>{let e=[o.city,o.region,o.country].filter(e=>!!(e&&e!==`UNKNOWN`));return e.length>0?e.join(`, `):h(`setup.detecting`)})()})})]})]}),_?C:(0,Z.jsx)(F,{isOpen:x,onInteraction:S,placement:`bottom-end`,portalClassName:`z-20000`,fill:!0,targetProps:{className:`h-full`},content:(0,Z.jsxs)(`div`,{className:`p-3 select-text w-72 sm:w-80 max-w-[85vw] space-y-2`,children:[(0,Z.jsx)(`div`,{className:`text-[11px] font-mono font-bold text-gray-500 dark:text-gray-400 tracking-wide border-b border-gray-100 dark:border-gray-800 pb-1.5`,children:`/cdn-cgi/trace`}),(0,Z.jsx)(`pre`,{className:`m-0 font-mono text-xs leading-relaxed whitespace-pre-wrap break-all overflow-x-hidden max-h-64 overflow-y-auto text-gray-800 dark:text-gray-200`,children:p?.raw||h(`setup.noTraceData`,`暂无 Trace 数据`)})]}),children:C})]})]})})})},Q=({step:e,className:t,size:n=144})=>{let r=e===1?47:50,i=e===1?45.5:45;return(0,Z.jsx)(`div`,{"aria-hidden":`true`,className:K(`absolute -top-7 -left-7 pointer-events-none select-none z-0`,`text-blue-600/[0.08] dark:text-blue-400/[0.12]`,`transition-all duration-500 ease-out`,`blur-none group-hover:blur-md group-hover:opacity-0`,t),style:{width:n,height:n},children:(0,Z.jsxs)(`svg`,{viewBox:`0 0 100 100`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`,className:`w-full h-full`,children:[(0,Z.jsx)(`circle`,{cx:`50`,cy:`50`,r:`46`,stroke:`currentColor`,strokeWidth:`4`}),(0,Z.jsx)(`text`,{x:r,y:i,textAnchor:`middle`,dominantBaseline:`central`,fill:`currentColor`,fontSize:`80`,fontWeight:`900`,fontFamily:`'Helvetica Neue', Helvetica, Arial, sans-serif`,children:e})]})})},be=({accessPoints:e,selectedApId:t,onSelectAp:n,accessPointName:r,onManageAccessPoints:i,isMobile:a})=>{let{t:o}=d();return(0,Z.jsxs)(H,{title:o(`setup.accessPointsCardTitle`,`接入点`),icon:(0,Z.jsx)(s,{size:16}),className:`group relative overflow-hidden [&_.bp6-section-header]:relative [&_.bp6-section-header]:z-10 [&_.bp6-section-card]:relative [&_.bp6-section-card]:z-10`,children:[(0,Z.jsx)(Q,{step:1}),(0,Z.jsx)(L,{children:(0,Z.jsxs)(`div`,{className:`flex flex-col sm:flex-row items-start sm:items-center justify-between gap-4`,children:[(0,Z.jsxs)(`div`,{className:`flex flex-col gap-1.5 w-full sm:w-auto`,children:[(0,Z.jsx)(`span`,{className:`text-xs opacity-50 font-medium`,children:o(`setup.selectAccessPointToConfigure`)}),(0,Z.jsxs)(`div`,{className:`flex items-center gap-3`,children:[e.length>0?(0,Z.jsx)(R,{value:t||``,onChange:e=>n(e.target.value),options:e.map(e=>({label:e.name,value:e.id})),className:`font-semibold text-gray-900 dark:text-gray-100`}):(0,Z.jsx)(`div`,{className:`font-semibold text-gray-900 dark:text-gray-100 flex items-center gap-2`,children:r||o(`setup.defaultAccessPointName`,`设备-1`)}),e.length>0&&(0,Z.jsx)(U,{minimal:!0,round:!0,intent:I.PRIMARY,className:`text-xs`,children:e.length})]})]}),(0,Z.jsx)(A,{variant:`outlined`,intent:I.NONE,icon:(0,Z.jsx)(l,{size:14}),text:o(`setup.manageAccessPoints`,`管理接入点`),onClick:i,fill:a,className:`shrink-0`})]})})]})},xe=({dohUrl:e,copyToClipboard:t,isMobile:n})=>{let{t:r}=d();return(0,Z.jsxs)(H,{title:r(`setup.accessPointTitle`,`Access DoH URL`),icon:`globe`,className:`group relative overflow-hidden [&_.bp6-section-header]:relative [&_.bp6-section-header]:z-10 [&_.bp6-section-card]:relative [&_.bp6-section-card]:z-10`,rightElement:(0,Z.jsx)(F,{placement:`bottom-end`,usePortal:!0,content:(0,Z.jsxs)(`div`,{className:`p-4 max-w-sm`,children:[(0,Z.jsx)(k,{children:r(`setup.whatIsDoh`)}),(0,Z.jsx)(`p`,{className:`text-sm mb-2`,children:r(`setup.dohDesc`)}),(0,Z.jsxs)(`ul`,{className:`list-disc list-inside text-sm opacity-80 mb-3 space-y-1`,children:[(0,Z.jsx)(`li`,{children:r(`setup.dohBenefit1`)}),(0,Z.jsx)(`li`,{children:r(`setup.dohBenefit2`)})]}),(0,Z.jsx)(`div`,{className:`text-xs border-t border-gray-100 dark:border-gray-700 pt-2`,children:(0,Z.jsxs)(`a`,{href:`https://en.wikipedia.org/wiki/DNS_over_HTTPS`,target:`_blank`,rel:`noreferrer`,className:`flex items-center gap-1 text-blue-500 hover:underline`,children:[(0,Z.jsx)(h,{size:10}),` `,r(`setup.learnMore`)]})})]}),children:(0,Z.jsx)(A,{icon:`help`,variant:`minimal`,intent:I.NONE})}),children:[(0,Z.jsx)(Q,{step:2}),(0,Z.jsx)(L,{children:(0,Z.jsxs)(`div`,{className:`w-full bg-gray-100 dark:bg-gray-800 p-3 rounded-lg border border-gray-200 dark:border-gray-700 flex flex-col sm:flex-row items-stretch sm:items-center justify-between gap-3`,children:[(0,Z.jsx)(`span`,{className:`font-mono text-blue-600 dark:text-blue-400 break-all text-xs sm:text-sm`,children:e}),(0,Z.jsx)(A,{intent:I.PRIMARY,icon:`duplicate`,text:r(`setup.copyUrl`),fill:n,onClick:()=>t(e),className:`shrink-0`})]})})]})};function Se(e){let t=e.trim();try{return new URL(t.startsWith(`http://`)||t.startsWith(`https://`)?t:`https://${t}`).hostname||t}catch{return t.replace(/^https?:\/\//,``).split(`/`)[0].split(`:`)[0]||t}}function $(e,t){let n=(e||``).trim(),r=(t||``).trim();if(!r&&n.includes(`(`)&&n.endsWith(`)`)){let e=n.match(/^(.+?)\s*\((.+?)\)$/);e&&(n=e[1].trim(),r=e[2].trim())}let i=n&&n!==`DNS Worker`?n:``,a=r&&r!==`DNS Worker`?r:``;return i&&a?i.toLowerCase()===a.toLowerCase()?i:`${i} - ${a}`:i||a||``}function Ce(e,t,n,r){let i,a,o,s;typeof e==`object`?(i=e.profileKey,a=e.profileName,o=e.accessPointName,s=e.origin):(i=e,a=t,s=n||``,o=r);let c=s.trim(),l=Se(c),u=`${c}/${i}`,d=$(a,o),f=crypto.randomUUID(),p=crypto.randomUUID(),m=d?`DNS Worker - ${l} (${d})`:`DNS Worker (${l})`,h=d?`DNS Worker DoH - ${l} (${d})`:`DNS Worker DoH - ${l}`,g=d?`DNS Worker DoH configuration profile for ${d} via ${l}`:`DNS Worker DoH configuration profile via ${l}`,_=d?`Configures encrypted DNS over HTTPS (DoH) for ${d} via ${l}`:`Configures encrypted DNS over HTTPS (DoH) via ${l}`;return ee({PayloadContent:[{DNSSettings:{DNSProtocol:`HTTPS`,ServerHTTPVersion:3,ServerURL:u},OnDemandRules:[{Action:`Connect`,InterfaceTypeMatch:`WiFi`},{Action:`Connect`,InterfaceTypeMatch:`Cellular`},{Action:`Disconnect`}],PayloadDescription:_,PayloadDisplayName:h,PayloadIdentifier:`com.apple.dnsSettings.managed.${f}`,PayloadName:h,PayloadType:`com.apple.dnsSettings.managed`,PayloadUUID:f,PayloadVersion:1}],PayloadDescription:g,PayloadDisplayName:m,PayloadIdentifier:`com.dnsworker.profile.${i}`,PayloadName:m,PayloadRemovalDisallowed:!1,PayloadType:`Configuration`,PayloadUUID:p,PayloadVersion:1},{indent:` `})}const we=({isMobile:e,copyToClipboard:t,profileKey:n,profileName:r,accessPointName:a,currentIps:o,dotDomain:s})=>{let{t:l}=d(),{isCloudflare:u}=Y();return(0,Z.jsxs)(`div`,{className:`group relative overflow-hidden rounded-xl border border-gray-200 dark:border-gray-800 bg-white dark:bg-gray-900 shadow-sm`,children:[(0,Z.jsx)(Q,{step:3}),(0,Z.jsxs)(V,{id:`setup-tabs`,renderActiveTabPanelOnly:!0,vertical:!e,size:`large`,className:K(`p-4 md:p-6 setup-tabs-container relative z-10 bg-transparent`,e&&[`[&_.bp6-tab-list]:overflow-x-auto!`,`[&_.bp6-tab-list]:flex-nowrap!`,`[&_.bp6-tab-list]:pb-1`,`[&_.bp6-tab-list]:scrollbar-none`,`[&_.bp6-tab-list]:[-ms-overflow-style:none]`,`[&_.bp6-tab-list::-webkit-scrollbar]:hidden`,`[&_.bp6-tab]:shrink-0`]),children:[(0,Z.jsx)(B,{id:`browsers`,title:(0,Z.jsxs)(`span`,{children:[(0,Z.jsx)(b,{size:16,className:`inline mr-2`}),l(`setup.browsers`)]}),panel:(0,Z.jsxs)(`div`,{className:`space-y-4 md:ml-4 mt-4 md:mt-0`,children:[(0,Z.jsx)(k,{className:`font-bold`,children:l(`setup.browserTitle`)}),(0,Z.jsx)(`p`,{className:`text-sm`,children:l(`setup.browserSteps`)}),(0,Z.jsx)(`p`,{className:`text-[10px] opacity-50 cursor-pointer`,onClick:()=>t(`chrome://settings/security`),children:l(`setup.browserTips`,`or copy this URL to the address bar: `)+`chrome://settings/security`})]})}),(0,Z.jsx)(B,{id:`apple`,title:(0,Z.jsxs)(`span`,{children:[(0,Z.jsx)(p,{size:16,className:`inline mr-2`}),l(`setup.apple`)]}),panel:(0,Z.jsxs)(`div`,{className:`space-y-4 md:ml-4 mt-4 md:mt-0`,children:[(0,Z.jsx)(k,{className:`font-bold`,children:l(`setup.appleTitle`)}),(0,Z.jsx)(`p`,{className:`text-sm`,children:l(`setup.appleDesc`)}),(0,Z.jsx)(`p`,{className:`text-[10px] opacity-50 text-center`,children:l(`setup.appleWarning`)}),(0,Z.jsxs)(`div`,{className:`p-6 bg-gray-50 dark:bg-gray-800 rounded-xl border border-dashed border-gray-300 dark:border-gray-700 flex flex-col items-center justify-center`,children:[(0,Z.jsx)(D,{icon:`document`,size:40,className:`opacity-20 mb-4`}),(0,Z.jsx)(A,{intent:I.PRIMARY,text:l(`setup.downloadConfig`),icon:`download`,onClick:()=>{let e=Ce({profileKey:n,profileName:r,accessPointName:a,origin:window.location.origin}),t=new Blob([e],{type:`application/x-apple-aspen-config`}),i=URL.createObjectURL(t),o=document.createElement(`a`);o.href=i;let s=$(r,a),c=Se(window.location.origin);o.download=`dns_worker-${(s||c).replace(/[^a-zA-Z0-9_\-\u4e00-\u9fa5]/g,`_`).replace(/_+/g,`_`).replace(/^_|_$/g,``)}-${n}.mobileconfig`,o.click(),URL.revokeObjectURL(i)}})]}),(0,Z.jsx)(`p`,{className:`text-[10px] opacity-50 mt-4! text-center`,children:l(`setup.appleInstallHint`)})]})}),(0,Z.jsx)(B,{id:`windows`,title:(0,Z.jsxs)(`span`,{children:[(0,Z.jsx)(m,{size:16,className:`inline mr-2`}),l(`setup.windows`)]}),panel:(0,Z.jsxs)(`div`,{className:`space-y-4 md:ml-4 mt-4 md:mt-0`,children:[(0,Z.jsx)(k,{className:`font-bold`,children:l(`setup.windowsTitle`)}),(0,Z.jsxs)(`ol`,{className:`list-decimal list-inside space-y-4 text-sm leading-relaxed`,children:[(0,Z.jsx)(`li`,{children:(0,Z.jsx)(`a`,{href:`ms-settings:network-status`,children:l(`setup.windowsStep0`)})}),(0,Z.jsx)(`li`,{children:l(`setup.windowsStep1`)}),(0,Z.jsxs)(`li`,{children:[l(`setup.windowsStep2`),(0,Z.jsx)(`div`,{className:`mt-2 flex flex-wrap gap-2`,children:o.map(e=>(0,Z.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,Z.jsx)(U,{minimal:!0,interactive:!0,onClick:()=>t(e.ip),icon:`duplicate`,className:`font-mono`,children:e.ip}),(0,Z.jsx)(`span`,{className:`text-[9px] opacity-50 ml-1 font-mono`,children:e.area})]},e.ip))})]}),(0,Z.jsx)(`li`,{children:l(`setup.windowsStep3`)}),(0,Z.jsx)(`li`,{children:l(`setup.windowsStep4`)})]})]})}),(0,Z.jsx)(B,{id:`linux`,title:(0,Z.jsxs)(`span`,{children:[(0,Z.jsx)(x,{size:16,className:`inline mr-2`}),l(`setup.linux`)]}),panel:(0,Z.jsxs)(`div`,{className:`space-y-4 md:ml-4 mt-4 md:mt-0`,children:[(0,Z.jsx)(k,{className:`font-bold`,children:l(`setup.linuxTitle`)}),(0,Z.jsx)(`p`,{className:`text-sm`,children:l(`setup.linuxDesc`)}),(0,Z.jsxs)(`div`,{className:`mt-4`,children:[(0,Z.jsx)(`p`,{className:`text-sm font-bold mb-2`,children:l(`setup.linuxStep1`)}),(0,Z.jsxs)(`div`,{className:`relative group`,children:[(0,Z.jsx)(`pre`,{className:`bg-gray-100 dark:bg-gray-800 p-4 rounded-lg overflow-x-auto text-xs font-mono border border-gray-200 dark:border-gray-700`,children:(0,Z.jsx)(`code`,{children:`curl -sL "${window.location.origin}/setup.sh?key=${n}&origin=${window.location.origin}" | sudo bash`})}),(0,Z.jsx)(A,{className:`absolute top-2 right-2 opacity-0 group-hover:opacity-100 transition-opacity`,icon:`duplicate`,minimal:!0,small:!0,onClick:()=>{t(`curl -sL "${window.location.origin}/setup.sh?key=${n}&origin=${window.location.origin}" | sudo bash`)}})]})]}),(0,Z.jsx)(`div`,{className:`mt-4`,children:(0,Z.jsx)(`p`,{className:`text-sm font-bold`,children:l(`setup.linuxStep2`)})})]})}),(0,Z.jsx)(B,{id:`routeros`,title:(0,Z.jsxs)(`span`,{children:[(0,Z.jsx)(c,{size:16,className:`inline mr-2`}),l(`setup.routeros`)]}),panel:(0,Z.jsxs)(`div`,{className:`space-y-4 md:ml-4 mt-4 md:mt-0`,children:[(0,Z.jsx)(k,{className:`font-bold`,children:l(`setup.routerosTitle`)}),(0,Z.jsx)(`p`,{className:`text-sm`,children:l(`setup.routerosDesc`)}),(0,Z.jsxs)(`div`,{className:`mt-4`,children:[(0,Z.jsx)(`p`,{className:`text-sm font-bold mb-2`,children:l(`setup.routerosStep1`)}),(0,Z.jsxs)(`div`,{className:`relative group`,children:[(0,Z.jsx)(`pre`,{className:`bg-gray-100 dark:bg-gray-800 p-4 rounded-lg overflow-x-auto text-xs font-mono border border-gray-200 dark:border-gray-700`,children:(0,Z.jsx)(`code`,{children:`/ip dns set use-doh-server="${window.location.origin}/${n}" verify-doh-cert=yes`})}),(0,Z.jsx)(A,{className:`absolute top-2 right-2 opacity-0 group-hover:opacity-100 transition-opacity`,icon:`duplicate`,minimal:!0,small:!0,onClick:()=>{t(`/ip dns set use-doh-server="${window.location.origin}/${n}" verify-doh-cert=yes`)}})]})]}),(0,Z.jsx)(`p`,{className:`text-sm`,children:l(`setup.routerosNote`)}),(0,Z.jsxs)(`a`,{href:`https://help.mikrotik.com/docs/spaces/ROS/pages/37748767/DNS`,target:`_blank`,rel:`noreferrer`,className:`flex items-center gap-1 text-xs text-blue-500 hover:underline`,children:[(0,Z.jsx)(h,{size:10}),` `,l(`setup.routerosDocs`)]})]})}),(0,Z.jsx)(B,{id:`android`,title:(0,Z.jsxs)(`span`,{children:[(0,Z.jsx)(i,{size:16,className:`inline mr-2`}),l(`setup.android`)]}),panel:(0,Z.jsxs)(`div`,{className:`space-y-4 md:ml-4 mt-4 md:mt-0`,children:[(0,Z.jsx)(k,{className:`font-bold`,children:l(`setup.androidTitle`)}),(0,Z.jsx)(`p`,{className:`text-sm`,children:l(`setup.androidDesc`)}),u?(0,Z.jsxs)(P,{intent:I.WARNING,icon:`warning-sign`,className:`text-xs`,children:[(0,Z.jsx)(`div`,{className:`font-semibold mb-1`,children:l(`setup.dotUnavailableCfTitle`)}),(0,Z.jsx)(`div`,{children:l(`setup.dotUnavailableCfDesc`)})]}):(()=>{let e=/^(\d{1,3}\.){3}\d{1,3}$/.test(window.location.hostname)||window.location.hostname===`localhost`||window.location.hostname===`127.0.0.1`||window.location.hostname.includes(`:`),r=(s||``).trim().replace(/^\*\./,``),i=!J(r)&&r||(e?``:window.location.hostname);return(0,Z.jsxs)(`div`,{className:`p-4 bg-gray-50 dark:bg-gray-800/60 rounded-xl border border-gray-200 dark:border-gray-700 space-y-3`,children:[(0,Z.jsx)(`div`,{className:`text-xs font-semibold text-gray-700 dark:text-gray-300`,children:l(`setup.androidDotTitle`,`私有 DNS (DoT / DoQ)`)}),(0,Z.jsx)(`p`,{className:`text-xs text-gray-500 dark:text-gray-400`,children:l(`setup.androidDotDesc`,`支持 Android 原生“私有 DNS (DoT)”及各类现代 DoQ 客户端。提供商主机名:`)}),i?(0,Z.jsx)(`div`,{className:`space-y-3 pt-1`,children:(0,Z.jsx)(`div`,{className:`flex flex-col sm:flex-row sm:items-center gap-1.5 sm:gap-2`,children:(0,Z.jsx)(U,{minimal:!0,interactive:!0,onClick:()=>t(`${n}.${i}`),icon:`duplicate`,className:`font-mono text-xs sm:text-sm py-1 px-3 self-start`,intent:I.PRIMARY,children:`${n}.${i}`})})}):(0,Z.jsx)(P,{intent:I.WARNING,icon:`warning-sign`,className:`text-xs`,children:l(`setup.androidIpNotice`,`检测到当前通过 IP 或本地地址访问面板。DoT / DoQ 仅接受域名,请在 .env 中配置 SERVERFULL_DOT_DOMAIN (例如 dns.example.com) 后刷新。`)})]})})(),!u&&(0,Z.jsx)(P,{intent:I.PRIMARY,icon:`info-sign`,className:`text-xs`,children:l(`setup.androidWarning`)})]})})]})]})};function Te({profileId:e,accessPoints:t,onRefresh:n,toasterRef:r}){let{t:i}=d(),[a,o]=(0,X.useState)(!1),[s,c]=(0,X.useState)(``),[l,u]=(0,X.useState)(!1),[f,p]=(0,X.useState)(null),[m,h]=(0,X.useState)(``),[g,_]=(0,X.useState)(!1),[v,y]=(0,X.useState)(null),[b,x]=(0,X.useState)(null),[S,C]=(0,X.useState)(!1),[w,T]=(0,X.useState)(!1),[E,D]=(0,X.useState)(null),[O,k]=(0,X.useState)(!1),[A,j]=(0,X.useState)(``);return{isAddDialogOpen:a,setIsAddDialogOpen:o,newApName:s,setNewApName:c,isAdding:l,renameApId:f,setRenameApId:p,renameApName:m,setRenameApName:h,isRenaming:g,rotatingApId:v,deletingApId:b,newApNameFocused:S,setNewApNameFocused:C,renameApNameFocused:w,setRenameApNameFocused:T,rotateConfirmApId:E,setRotateConfirmApId:D,isSearchOpen:O,setIsSearchOpen:k,searchQuery:A,setSearchQuery:j,filteredAccessPoints:t.filter(e=>e.name.toLowerCase().includes(A.toLowerCase())||e.token.toLowerCase().includes(A.toLowerCase())),isValidApName:e=>ue.test(e),handleAdd:async()=>{let a=s.trim();if(a){if(t.some(e=>e.name.toLowerCase()===a.toLowerCase())){r.current?.show({message:i(`setup.accessPointNameExists`,`Access Point name already exists`),intent:I.DANGER});return}u(!0);try{await ge(e,a),r.current?.show({message:i(`setup.accessPointCreated`),intent:I.SUCCESS}),o(!1),c(``),n()}catch(e){let t=e.message||`Failed to create access point`,n=t;if(t.startsWith(`Access point limit exceeded`)){let e=t.match(/\(max (\d+)\)/),r=e?e[1]:`100`;n=i(`setup.accessPointLimitExceeded`,{max:r,defaultValue:`Access Point limit exceeded (max ${r})`})}r.current?.show({message:n,intent:I.DANGER})}finally{u(!1)}}},handleRename:async()=>{let a=m.trim();if(!(!a||!f)){if(t.some(e=>e.id!==f&&e.name.toLowerCase()===a.toLowerCase())){r.current?.show({message:i(`setup.accessPointNameExists`,`Access Point name already exists`),intent:I.DANGER});return}_(!0);try{await fe(e,f,a),r.current?.show({message:i(`setup.accessPointRenamed`),intent:I.SUCCESS}),p(null),n()}catch(e){r.current?.show({message:e.message||`Failed to rename access point`,intent:I.DANGER})}finally{_(!1)}}},handleRotate:async t=>{y(t);try{await me(e,t),r.current?.show({message:i(`setup.tokenRotated`),intent:I.SUCCESS}),n()}catch(e){console.error(e)}finally{y(null)}},handleDelete:async t=>{if(confirm(i(`setup.deleteAccessPointConfirm`))){x(t);try{await pe(e,t),r.current?.show({message:i(`setup.accessPointDeleted`),intent:I.SUCCESS}),n()}catch(e){console.error(e)}finally{x(null)}}}}}const Ee=({isOpen:e,onClose:t,newApName:n,setNewApName:r,newApNameFocused:i,setNewApNameFocused:a,handleAdd:o,isAdding:s,isValidApName:c})=>{let{t:l}=d();return(0,Z.jsxs)(j,{isOpen:e,onClose:t,title:l(`setup.addAccessPoint`),children:[(0,Z.jsx)(`div`,{className:O,children:(0,Z.jsx)(W,{content:l(`setup.accessPointNameFormatTip`,`1-30 characters, letters, numbers, hyphens and underscores allowed`),isOpen:i,position:E.TOP,intent:I.PRIMARY,className:`w-full`,children:(0,Z.jsx)(`div`,{className:`w-full block`,children:(0,Z.jsx)(z,{autoFocus:!0,large:!0,placeholder:l(`setup.accessPointName`),value:n,onChange:e=>r(e.target.value),onFocus:()=>a(!0),onBlur:()=>a(!1)})})})}),(0,Z.jsx)(`div`,{className:N,children:(0,Z.jsxs)(`div`,{className:G,children:[(0,Z.jsx)(A,{onClick:t,children:l(`common.cancel`,`Cancel`)}),(0,Z.jsx)(A,{intent:I.PRIMARY,onClick:o,loading:s,disabled:!c(n),children:l(`common.create`)})]})})]})},De=({isOpen:e,onClose:t,renameApName:n,setRenameApName:r,renameApNameFocused:i,setRenameApNameFocused:a,handleRename:o,isRenaming:s,isValidApName:c})=>{let{t:l}=d();return(0,Z.jsxs)(j,{isOpen:e,onClose:t,title:l(`setup.renameAccessPoint`),children:[(0,Z.jsx)(`div`,{className:O,children:(0,Z.jsx)(W,{content:l(`setup.accessPointNameFormatTip`,`1-30 characters, letters, numbers, hyphens and underscores allowed`),isOpen:i,position:E.TOP,intent:I.PRIMARY,className:`w-full`,children:(0,Z.jsx)(`div`,{className:`w-full block`,children:(0,Z.jsx)(z,{autoFocus:!0,large:!0,placeholder:l(`setup.accessPointName`),value:n,onChange:e=>r(e.target.value),onFocus:()=>a(!0),onBlur:()=>a(!1)})})})}),(0,Z.jsx)(`div`,{className:N,children:(0,Z.jsxs)(`div`,{className:G,children:[(0,Z.jsx)(A,{onClick:t,children:l(`common.cancel`,`Cancel`)}),(0,Z.jsx)(A,{intent:I.PRIMARY,onClick:o,loading:s,disabled:!c(n),children:l(`common.save`)})]})})]})},Oe=({ap:e,totalApCount:t,toasterRef:i,onRenameTrigger:a,rotateConfirmApId:o,setRotateConfirmApId:c,rotatingApId:l,handleRotate:u,deletingApId:p,handleDelete:m})=>{let{t:h}=d();return(0,Z.jsx)(H,{title:(0,Z.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,Z.jsx)(s,{size:16}),(0,Z.jsx)(`span`,{children:e.name})]}),className:`shadow-none! rounded-lg!`,children:(0,Z.jsxs)(L,{children:[(0,Z.jsxs)(`div`,{className:`space-y-3`,children:[(0,Z.jsxs)(`div`,{className:`flex justify-between items-start gap-4`,children:[(0,Z.jsx)(`span`,{className:`text-xs opacity-50 mt-1`,children:`DoH URL`}),(0,Z.jsxs)(`div`,{className:`flex items-center gap-2 text-sm font-mono bg-blue-50 text-blue-600 dark:bg-blue-900/20 dark:text-blue-400 px-2 py-1 rounded cursor-pointer hover:bg-blue-100 dark:hover:bg-blue-900/40 transition-colors break-all`,onClick:()=>{navigator.clipboard.writeText(`${window.location.origin}/${e.token}`),i.current?.show({message:h(`setup.copied`),intent:I.SUCCESS})},title:h(`setup.copyUrl`),children:[(0,Z.jsx)(`span`,{className:`select-all`,children:`${window.location.origin}/${e.token}`}),(0,Z.jsx)(_,{size:14,className:`shrink-0`})]})]}),(0,Z.jsxs)(`div`,{className:`flex justify-between items-start gap-4`,children:[(0,Z.jsx)(`span`,{className:`text-xs opacity-50 mt-1`,children:h(`setup.accessPointToken`)}),(0,Z.jsx)(`span`,{className:`text-sm font-mono bg-gray-100 dark:bg-gray-800 px-2 py-1 rounded select-all break-all`,children:e.token})]}),(0,Z.jsxs)(`div`,{className:`flex justify-between items-start gap-4`,children:[(0,Z.jsx)(`span`,{className:`text-xs opacity-50 mt-1`,children:`Created`}),(0,Z.jsx)(`span`,{className:`text-sm`,children:de(new Date(e.created_at*1e3))})]})]}),(0,Z.jsxs)(`div`,{className:`mt-4 flex gap-2 flex-wrap`,children:[(0,Z.jsx)(A,{small:!0,icon:(0,Z.jsx)(n,{size:14}),text:h(`setup.renameAccessPoint`),onClick:()=>a(e.id,e.name)}),(0,Z.jsx)(F,{isOpen:o===e.id,onInteraction:e=>{e||c(null)},content:(0,Z.jsxs)(`div`,{className:`p-4 space-y-3 dark:bg-gray-800 dark:text-white max-w-xs`,children:[(0,Z.jsx)(`p`,{className:`text-xs font-semibold leading-relaxed`,children:h(`setup.rotateTokenConfirmDesc`,`Rotating the key will immediately disconnect devices using the old key. Are you sure you want to continue?`)}),(0,Z.jsxs)(`div`,{className:`flex justify-end gap-2`,children:[(0,Z.jsx)(A,{small:!0,minimal:!0,text:h(`common.cancel`,`Cancel`),onClick:()=>c(null)}),(0,Z.jsx)(A,{small:!0,intent:I.DANGER,text:h(`common.confirm`,`Confirm`),onClick:()=>{c(null),u(e.id)}})]})]}),placement:`top`,children:(0,Z.jsx)(A,{small:!0,icon:(0,Z.jsx)(f,{size:14}),text:h(`setup.rotateToken`),loading:l===e.id,onClick:()=>c(e.id)})}),(0,Z.jsx)(A,{small:!0,intent:I.DANGER,icon:(0,Z.jsx)(r,{size:14}),text:h(`setup.deleteAccessPoint`),loading:p===e.id,onClick:()=>m(e.id),disabled:t<=1,title:t<=1?`Cannot delete the only access point`:void 0})]})]})})},ke=({isOpen:e,onClose:t,profileId:n,isMobile:r,accessPoints:i,loading:a,onRefresh:s,toasterRef:c})=>{let{t:l}=d(),{isAddDialogOpen:u,setIsAddDialogOpen:f,newApName:p,setNewApName:m,isAdding:h,renameApId:g,setRenameApId:_,renameApName:v,setRenameApName:y,isRenaming:b,rotatingApId:x,deletingApId:C,newApNameFocused:w,setNewApNameFocused:T,renameApNameFocused:E,setRenameApNameFocused:D,rotateConfirmApId:O,setRotateConfirmApId:k,isSearchOpen:j,setIsSearchOpen:N,searchQuery:P,setSearchQuery:F,filteredAccessPoints:L,isValidApName:R,handleAdd:B,handleRename:V,handleRotate:H,handleDelete:U}=Te({profileId:n,accessPoints:i,onRefresh:s,toasterRef:c});return(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsxs)(_e,{isOpen:e,onClose:t,title:j?(0,Z.jsx)(z,{leftIcon:`search`,placeholder:l(`setup.searchAccessPoints`,`Search...`),value:P,onChange:e=>F(e.target.value),rightElement:(0,Z.jsx)(A,{icon:`cross`,minimal:!0,onClick:()=>{N(!1),F(``)}}),autoFocus:!0}):(0,Z.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,Z.jsx)(`span`,{children:l(`setup.manageAccessPoints`)}),(0,Z.jsx)(A,{icon:(0,Z.jsx)(o,{size:14}),minimal:!0,onClick:()=>N(!0),className:`opacity-50 hover:opacity-100`})]}),icon:`diagram-tree`,size:r?`100%`:`450px`,children:[(0,Z.jsx)(A,{fill:!0,intent:I.PRIMARY,icon:(0,Z.jsx)(S,{size:16}),text:l(`setup.addAccessPoint`),onClick:()=>f(!0),large:!0}),a?(0,Z.jsx)(`div`,{className:`flex justify-center p-8`,children:(0,Z.jsx)(M,{})}):(0,Z.jsx)(`div`,{className:`space-y-4 mt-4`,children:L.map(e=>(0,Z.jsx)(Oe,{ap:e,totalApCount:i.length,toasterRef:c,onRenameTrigger:(e,t)=>{_(e),y(t)},rotateConfirmApId:O,setRotateConfirmApId:k,rotatingApId:x,handleRotate:H,deletingApId:C,handleDelete:U},e.id))})]}),(0,Z.jsx)(Ee,{isOpen:u,onClose:()=>{f(!1),m(``)},newApName:p,setNewApName:m,newApNameFocused:w,setNewApNameFocused:T,handleAdd:B,isAdding:h,isValidApName:R}),(0,Z.jsx)(De,{isOpen:!!g,onClose:()=>_(null),renameApName:v,setRenameApName:y,renameApNameFocused:E,setRenameApNameFocused:D,handleRename:V,isRenaming:b,isValidApName:R})]})},Ae=({profileId:e,profileKey:t,profileName:n,toasterRef:r})=>{let i=te(),{t:a}=d(),[o,s]=(0,X.useState)([]),[c,l]=(0,X.useState)(!1),[u,f]=(0,X.useState)(!1),[p,m]=(0,X.useState)(null),h=async()=>{l(!0);try{s(await ce(e))}catch(e){console.error(e)}finally{l(!1)}};(0,X.useEffect)(()=>{h()},[e]);let[g,_]=(0,X.useState)(n||``);(0,X.useEffect)(()=>{n?_(n):e&&se(e).then(e=>{e?.name&&_(e.name)}).catch(()=>{})},[e,n]);let v=(0,X.useMemo)(()=>o.length===0?null:o.find(e=>e.id===p)||o[0],[o,p]),y=v?v.token:t,b=v?v.name:void 0,x=`${window.location.origin}/${y}`,[S,C]=(0,X.useState)(null),[w,T]=(0,X.useState)(!1),[E,D]=(0,X.useState)(!1),[O,k]=(0,X.useState)(!1),[A,j]=(0,X.useState)(null),[M,N]=(0,X.useState)(null),[P,F]=(0,X.useState)({ipv4:[],ipv6:[]}),[L,R]=(0,X.useState)(null),z=e=>{navigator.clipboard.writeText(e),r?.current?.show({message:a(`setup.copied`),intent:I.SUCCESS})},B=async()=>{T(!0),R(null);try{let[t,n]=await Promise.all([ne(),oe()]);if(t.ip&&(t.country===`UNKNOWN`||!t.country))try{let e=await fetch(`/api/geoip?ip=${encodeURIComponent(t.ip)}`);if(e.ok){let n=await e.json();n.success&&(n.country&&(t.country=n.country),n.region&&(t.region=n.region),n.city&&(t.city=n.city),n.timezone?.id&&(t.timezone=n.timezone.id),n.connection?.org&&(t.asOrganization=n.connection.org))}}catch{}C(t),j(n),t.timezone&&t.timezone!==`UNKNOWN`&&le(t.timezone);let r=window.location.hostname===`localhost`||window.location.hostname===`127.0.0.1`||window.location.hostname===`::1`||window.location.hostname.startsWith(`192.168.`)||window.location.hostname.startsWith(`10.`)||/^172\.(1[6-9]|2\d|3[01])\./.test(window.location.hostname),i=!!(t.dotDomain&&!J(t.dotDomain));ae(r&&i||i?t.dotDomain:window.location.hostname||``).then(e=>N(e)).catch(e=>console.warn(`Failed fetching domain geo location:`,e));let a=t.substituteDomain||`www.okx.com`;ie().then(e=>{F(t=>t.ipv4.length>0||t.ipv6.length>0?t:{ipv4:e.ip?[e.ip]:[],ipv6:e.ipv6?[e.ipv6]:[]})}).catch(()=>{}),re(a).then(e=>{(e.ipv4.length>0||e.ipv6.length>0)&&F(e)}).catch(e=>console.warn(`Failed resolving substitute domain DNS IPs:`,e)),R({success:!!t.connectedProfileId,profileMatch:t.connectedProfileId===e})}catch(e){console.error(`Verification failed`,e)}finally{T(!1)}};(0,X.useEffect)(()=>{B()},[e]);let V=(0,X.useMemo)(()=>{let e=[],t=(P.ipv4||[]).slice(0,2),n=(P.ipv6||[]).slice(0,2),r=S?.substituteDomain||`www.okx.com`;for(let n of t)e.push({ip:n,area:`${r} IPv4`});for(let t of n)e.push({ip:t,area:`${r} IPv6`});return e},[P,S?.substituteDomain]);return(0,Z.jsxs)(`div`,{className:`mx-auto space-y-8 pb-24 ${i?`p-1`:`px-8 max-w-5xl`}`,children:[(0,Z.jsx)(ve,{isMobile:i}),(0,Z.jsx)(ye,{isVerifying:w,verifyResult:L,handleVerify:B,isMobile:i,clientInfo:S,showIp:E,setShowIp:D,showLocation:O,setShowLocation:k,traceInfo:A,edgeLocation:M}),(0,Z.jsx)(be,{accessPoints:o,selectedApId:v?.id||null,onSelectAp:m,accessPointName:b,onManageAccessPoints:()=>f(!0),isMobile:i}),(0,Z.jsx)(xe,{dohUrl:x,copyToClipboard:z,isMobile:i}),(0,Z.jsx)(we,{isMobile:i,copyToClipboard:z,profileKey:y,profileName:g||void 0,accessPointName:b,currentIps:V,dotDomain:S?.dotDomain}),(0,Z.jsx)(ke,{isOpen:u,onClose:()=>f(!1),profileId:e,isMobile:i,accessPoints:o,loading:c,onRefresh:h,toasterRef:r})]})};export{Ae as SetupView};
@@ -1,4 +1,4 @@
1
- import{i as e,n as t}from"./rolldown-runtime-C4Xdq4VV.js";import{n,nn as r,t as i}from"./vendor-react-De1zEwOV.js";import{S as a,b as o}from"./vendor-icons-other-BTYC6Wvz.js";import{$ as s,A as c,B as l,C as u,D as d,E as f,F as p,G as m,H as h,I as g,J as _,K as v,L as y,M as b,N as x,O as S,P as C,Q as w,R as T,S as E,T as D,U as ee,V as O,W as k,X as A,Y as te,Z as ne,_ as re,_t as j,a as ie,at as ae,b as oe,c as se,ct as ce,d as le,dt as ue,et as de,f as fe,ft as pe,g as me,h as he,ht as ge,i as _e,it as ve,j as ye,k as be,l as xe,lt as Se,m as Ce,mt as we,n as Te,nt as Ee,o as De,ot as Oe,p as ke,pt as Ae,q as je,r as Me,rt as Ne,s as Pe,st as Fe,tt as Ie,u as Le,ut as Re,v as ze,w as Be,x as Ve,y as He,z as M}from"./vendor-utils-rmW6cqPl.js";import{h as Ue}from"./index-CrB_HdIL.js";var We=`dangerouslySetInnerHTML.onCopy.onCopyCapture.onCut.onCutCapture.onPaste.onPasteCapture.onCompositionEnd.onCompositionEndCapture.onCompositionStart.onCompositionStartCapture.onCompositionUpdate.onCompositionUpdateCapture.onFocus.onFocusCapture.onBlur.onBlurCapture.onChange.onChangeCapture.onBeforeInput.onBeforeInputCapture.onInput.onInputCapture.onReset.onResetCapture.onSubmit.onSubmitCapture.onInvalid.onInvalidCapture.onLoad.onLoadCapture.onError.onErrorCapture.onKeyDown.onKeyDownCapture.onKeyPress.onKeyPressCapture.onKeyUp.onKeyUpCapture.onAbort.onAbortCapture.onCanPlay.onCanPlayCapture.onCanPlayThrough.onCanPlayThroughCapture.onDurationChange.onDurationChangeCapture.onEmptied.onEmptiedCapture.onEncrypted.onEncryptedCapture.onEnded.onEndedCapture.onLoadedData.onLoadedDataCapture.onLoadedMetadata.onLoadedMetadataCapture.onLoadStart.onLoadStartCapture.onPause.onPauseCapture.onPlay.onPlayCapture.onPlaying.onPlayingCapture.onProgress.onProgressCapture.onRateChange.onRateChangeCapture.onSeeked.onSeekedCapture.onSeeking.onSeekingCapture.onStalled.onStalledCapture.onSuspend.onSuspendCapture.onTimeUpdate.onTimeUpdateCapture.onVolumeChange.onVolumeChangeCapture.onWaiting.onWaitingCapture.onAuxClick.onAuxClickCapture.onClick.onClickCapture.onContextMenu.onContextMenuCapture.onDoubleClick.onDoubleClickCapture.onDrag.onDragCapture.onDragEnd.onDragEndCapture.onDragEnter.onDragEnterCapture.onDragExit.onDragExitCapture.onDragLeave.onDragLeaveCapture.onDragOver.onDragOverCapture.onDragStart.onDragStartCapture.onDrop.onDropCapture.onMouseDown.onMouseDownCapture.onMouseEnter.onMouseLeave.onMouseMove.onMouseMoveCapture.onMouseOut.onMouseOutCapture.onMouseOver.onMouseOverCapture.onMouseUp.onMouseUpCapture.onSelect.onSelectCapture.onTouchCancel.onTouchCancelCapture.onTouchEnd.onTouchEndCapture.onTouchMove.onTouchMoveCapture.onTouchStart.onTouchStartCapture.onPointerDown.onPointerDownCapture.onPointerMove.onPointerMoveCapture.onPointerUp.onPointerUpCapture.onPointerCancel.onPointerCancelCapture.onPointerEnter.onPointerEnterCapture.onPointerLeave.onPointerLeaveCapture.onPointerOver.onPointerOverCapture.onPointerOut.onPointerOutCapture.onGotPointerCapture.onGotPointerCaptureCapture.onLostPointerCapture.onLostPointerCaptureCapture.onScroll.onScrollCapture.onWheel.onWheelCapture.onAnimationStart.onAnimationStartCapture.onAnimationEnd.onAnimationEndCapture.onAnimationIteration.onAnimationIterationCapture.onTransitionEnd.onTransitionEndCapture`.split(`.`);function Ge(e){return typeof e==`string`?We.includes(e):!1}var N=e(a()),Ke=new Set(`aria-activedescendant.aria-atomic.aria-autocomplete.aria-busy.aria-checked.aria-colcount.aria-colindex.aria-colspan.aria-controls.aria-current.aria-describedby.aria-details.aria-disabled.aria-errormessage.aria-expanded.aria-flowto.aria-haspopup.aria-hidden.aria-invalid.aria-keyshortcuts.aria-label.aria-labelledby.aria-level.aria-live.aria-modal.aria-multiline.aria-multiselectable.aria-orientation.aria-owns.aria-placeholder.aria-posinset.aria-pressed.aria-readonly.aria-relevant.aria-required.aria-roledescription.aria-rowcount.aria-rowindex.aria-rowspan.aria-selected.aria-setsize.aria-sort.aria-valuemax.aria-valuemin.aria-valuenow.aria-valuetext.className.color.height.id.lang.max.media.method.min.name.style.target.width.role.tabIndex.accentHeight.accumulate.additive.alignmentBaseline.allowReorder.alphabetic.amplitude.arabicForm.ascent.attributeName.attributeType.autoReverse.azimuth.baseFrequency.baselineShift.baseProfile.bbox.begin.bias.by.calcMode.capHeight.clip.clipPath.clipPathUnits.clipRule.colorInterpolation.colorInterpolationFilters.colorProfile.colorRendering.contentScriptType.contentStyleType.cursor.cx.cy.d.decelerate.descent.diffuseConstant.direction.display.divisor.dominantBaseline.dur.dx.dy.edgeMode.elevation.enableBackground.end.exponent.externalResourcesRequired.fill.fillOpacity.fillRule.filter.filterRes.filterUnits.floodColor.floodOpacity.focusable.fontFamily.fontSize.fontSizeAdjust.fontStretch.fontStyle.fontVariant.fontWeight.format.from.fx.fy.g1.g2.glyphName.glyphOrientationHorizontal.glyphOrientationVertical.glyphRef.gradientTransform.gradientUnits.hanging.horizAdvX.horizOriginX.href.ideographic.imageRendering.in2.in.intercept.k1.k2.k3.k4.k.kernelMatrix.kernelUnitLength.kerning.keyPoints.keySplines.keyTimes.lengthAdjust.letterSpacing.lightingColor.limitingConeAngle.local.markerEnd.markerHeight.markerMid.markerStart.markerUnits.markerWidth.mask.maskContentUnits.maskUnits.mathematical.mode.numOctaves.offset.opacity.operator.order.orient.orientation.origin.overflow.overlinePosition.overlineThickness.paintOrder.panose1.pathLength.patternContentUnits.patternTransform.patternUnits.pointerEvents.pointsAtX.pointsAtY.pointsAtZ.preserveAlpha.preserveAspectRatio.primitiveUnits.r.radius.refX.refY.renderingIntent.repeatCount.repeatDur.requiredExtensions.requiredFeatures.restart.result.rotate.rx.ry.seed.shapeRendering.slope.spacing.specularConstant.specularExponent.speed.spreadMethod.startOffset.stdDeviation.stemh.stemv.stitchTiles.stopColor.stopOpacity.strikethroughPosition.strikethroughThickness.string.stroke.strokeDasharray.strokeDashoffset.strokeLinecap.strokeLinejoin.strokeMiterlimit.strokeOpacity.strokeWidth.surfaceScale.systemLanguage.tableValues.targetX.targetY.textAnchor.textDecoration.textLength.textRendering.to.transform.u1.u2.underlinePosition.underlineThickness.unicode.unicodeBidi.unicodeRange.unitsPerEm.vAlphabetic.values.vectorEffect.version.vertAdvY.vertOriginX.vertOriginY.vHanging.vIdeographic.viewTarget.visibility.vMathematical.widths.wordSpacing.writingMode.x1.x2.x.xChannelSelector.xHeight.xlinkActuate.xlinkArcrole.xlinkHref.xlinkRole.xlinkShow.xlinkTitle.xlinkType.xmlBase.xmlLang.xmlns.xmlnsXlink.xmlSpace.y1.y2.y.yChannelSelector.z.zoomAndPan.ref.key.angle`.split(`.`));function qe(e){return typeof e==`string`?Ke.has(e):!1}function Je(e){return typeof e==`string`&&e.startsWith(`data-`)}function Ye(e){if(typeof e!=`object`||!e)return{};var t={};for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(qe(n)||Je(n))&&(t[n]=e[n]);return t}function Xe(e){if(e==null)return null;if((0,N.isValidElement)(e)&&typeof e.props==`object`&&e.props!==null){var t=e.props;return Ye(t)}return typeof e==`object`&&!Array.isArray(e)?Ye(e):null}function Ze(e){var t={};for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(qe(n)||Je(n)||Ge(n))&&(t[n]=e[n]);return t}function Qe(e){return e==null?null:(0,N.isValidElement)(e)?Ze(e.props):typeof e==`object`&&!Array.isArray(e)?Ze(e):null}var $e=[`children`,`width`,`height`,`viewBox`,`className`,`style`,`title`,`desc`];function et(){return et=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)({}).hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},et.apply(null,arguments)}function tt(e,t){if(e==null)return{};var n,r,i=nt(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)===-1&&{}.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function nt(e,t){if(e==null)return{};var n={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(t.indexOf(r)!==-1)continue;n[r]=e[r]}return n}var rt=(0,N.forwardRef)((e,t)=>{var n=e.children,r=e.width,i=e.height,a=e.viewBox,o=e.className,s=e.style,c=e.title,l=e.desc,u=tt(e,$e),d=a||{width:r,height:i,x:0,y:0},f=j(`recharts-surface`,o);return N.createElement(`svg`,et({},Ze(u),{className:f,width:r,height:i,style:s,viewBox:`${d.x} ${d.y} ${d.width} ${d.height}`,ref:t}),N.createElement(`title`,null,c),N.createElement(`desc`,null,l),n)}),it=[`children`,`className`];function at(){return at=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)({}).hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},at.apply(null,arguments)}function ot(e,t){if(e==null)return{};var n,r,i=st(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)===-1&&{}.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function st(e,t){if(e==null)return{};var n={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(t.indexOf(r)!==-1)continue;n[r]=e[r]}return n}var ct=N.forwardRef((e,t)=>{var n=e.children,r=e.className,i=ot(e,it),a=j(`recharts-layer`,r);return N.createElement(`g`,at({className:a},Ze(i),{ref:t}),n)}),lt=4;function ut(e){var t=10**(arguments.length>1&&arguments[1]!==void 0?arguments[1]:lt),n=Math.round(e*t)/t;return Object.is(n,-0)?0:n}function P(e){var t=[...arguments].slice(1);return e.reduce((e,n,r)=>{var i=t[r-1];return typeof i==`string`?e+i+n:i===void 0?e+n:e+ut(i)+n},``)}var dt=e=>e===0?0:e>0?1:-1,ft=e=>typeof e==`number`&&e!=+e,pt=e=>typeof e==`string`&&e.length>1&&e.indexOf(`%`)===e.length-1,F=e=>(typeof e==`number`||e instanceof Number)&&!ft(e),mt=e=>F(e)||typeof e==`string`,ht=0,gt=e=>{var t=++ht;return`${e||``}${t}`},_t=function(e,t){var n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:0,r=arguments.length>3&&arguments[3]!==void 0?arguments[3]:!1;if(!F(e)&&typeof e!=`string`)return n;var i;if(pt(e)){if(t==null)return n;var a=e.indexOf(`%`);i=t*parseFloat(e.slice(0,a))/100}else i=+e;return ft(i)&&(i=n),r&&t!=null&&i>t&&(i=t),i},vt=e=>{if(!Array.isArray(e))return!1;for(var t=e.length,n={},r=0;r<t;r++)if(!n[String(e[r])])n[String(e[r])]=!0;else return!0;return!1};function yt(e,t,n){return F(e)&&F(t)?ut(e+n*(t-e)):t}function bt(e,t,n){if(!(!e||!e.length))return e.find(e=>e&&(typeof t==`function`?t(e):ge(e,t))===n)}var I=e=>e==null,xt=e=>I(e)?e:`${e.charAt(0).toUpperCase()}${e.slice(1)}`;function St(e){return e!=null}function Ct(){}function wt(e){if(e)return{x:e.x,y:e.y,upperWidth:`upperWidth`in e?e.upperWidth:e.width,lowerWidth:`lowerWidth`in e?e.lowerWidth:e.width,width:e.width,height:e.height}}function Tt(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function Et(e){for(var t=1;t<arguments.length;t++){var n=arguments[t]==null?{}:arguments[t];t%2?Tt(Object(n),!0).forEach(function(t){Dt(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):Tt(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function Dt(e,t,n){return(t=Ot(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function Ot(e){var t=kt(e,`string`);return typeof t==`symbol`?t:t+``}function kt(e,t){if(typeof e!=`object`||!e)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t||`default`);if(typeof r!=`object`)return r;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(t===`string`?String:Number)(e)}var At=e=>{var t=e.viewBox,n=e.position,r=e.offset,i=r===void 0?0:r,a=e.parentViewBox,o=e.clamp,s=wt(t),c=s.x,l=s.y,u=s.height,d=s.upperWidth,f=s.lowerWidth,p=c,m=c+(d-f)/2,h=(p+m)/2,g=(d+f)/2,_=p+d/2,v=u>=0?1:-1,y=v*i,b=v>0?`end`:`start`,x=v>0?`start`:`end`,S=d>=0?1:-1,C=S*i,w=S>0?`end`:`start`,T=S>0?`start`:`end`,E=a;if(n===`top`){var D={x:p+d/2,y:l-y,horizontalAnchor:`middle`,verticalAnchor:b};return o&&E&&(D.height=Math.max(l-E.y,0),D.width=d),D}if(n===`bottom`){var ee={x:m+f/2,y:l+u+y,horizontalAnchor:`middle`,verticalAnchor:x};return o&&E&&(ee.height=Math.max(E.y+E.height-(l+u),0),ee.width=f),ee}if(n===`left`){var O={x:h-C,y:l+u/2,horizontalAnchor:w,verticalAnchor:`middle`};return o&&E&&(O.width=Math.max(O.x-E.x,0),O.height=u),O}if(n===`right`){var k={x:h+g+C,y:l+u/2,horizontalAnchor:T,verticalAnchor:`middle`};return o&&E&&(k.width=Math.max(E.x+E.width-k.x,0),k.height=u),k}var A=o&&E?{width:g,height:u}:{};return n===`insideLeft`?Et({x:h+C,y:l+u/2,horizontalAnchor:T,verticalAnchor:`middle`},A):n===`insideRight`?Et({x:h+g-C,y:l+u/2,horizontalAnchor:w,verticalAnchor:`middle`},A):n===`insideTop`?Et({x:p+d/2,y:l+y,horizontalAnchor:`middle`,verticalAnchor:x},A):n===`insideBottom`?Et({x:m+f/2,y:l+u-y,horizontalAnchor:`middle`,verticalAnchor:b},A):n===`insideTopLeft`?Et({x:p+C,y:l+y,horizontalAnchor:T,verticalAnchor:x},A):n===`insideTopRight`?Et({x:p+d-C,y:l+y,horizontalAnchor:w,verticalAnchor:x},A):n===`insideBottomLeft`?Et({x:m+C,y:l+u-y,horizontalAnchor:T,verticalAnchor:b},A):n===`insideBottomRight`?Et({x:m+f-C,y:l+u-y,horizontalAnchor:w,verticalAnchor:b},A):n&&typeof n==`object`&&(F(n.x)||pt(n.x))&&(F(n.y)||pt(n.y))?Et({x:c+_t(n.x,g),y:l+_t(n.y,u),horizontalAnchor:`end`,verticalAnchor:`end`},A):Et({x:_,y:l+u/2,horizontalAnchor:`middle`,verticalAnchor:`middle`},A)},jt=[`top`,`left`,`right`,`bottom`];function Mt(e){return e==null?!1:typeof e==`object`?!0:jt.includes(e)}var Nt=(0,N.createContext)(null),Pt=e=>`radius`in e&&`startAngle`in e&&`endAngle`in e,Ft=(e,t)=>{if(!e||typeof e==`function`||typeof e==`boolean`)return null;var n=e;if((0,N.isValidElement)(e)&&(n=e.props),typeof n!=`object`&&typeof n!=`function`)return null;var r={};return Object.keys(n).forEach(e=>{Ge(e)&&typeof n[e]==`function`&&(r[e]=t||(t=>n[e](n,t)))}),r},It=(e,t,n)=>r=>(e(t,n,r),null),Lt=(e,t,n)=>{if(e===null||typeof e!=`object`&&typeof e!=`function`)return null;var r=null;return Object.keys(e).forEach(i=>{var a=e[i];Ge(i)&&typeof a==`function`&&(r||={},r[i]=It(a,t,n))}),r};function Rt(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function zt(e){for(var t=1;t<arguments.length;t++){var n=arguments[t]==null?{}:arguments[t];t%2?Rt(Object(n),!0).forEach(function(t){Bt(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):Rt(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function Bt(e,t,n){return(t=Vt(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function Vt(e){var t=Ht(e,`string`);return typeof t==`symbol`?t:t+``}function Ht(e,t){if(typeof e!=`object`||!e)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t||`default`);if(typeof r!=`object`)return r;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(t===`string`?String:Number)(e)}function Ut(e,t){var n=zt({},e),r=t;return Object.keys(t).reduce((e,t)=>(e[t]===void 0&&r[t]!==void 0&&(e[t]=r[t]),e),n)}function Wt(e,t,n){return t===!0?je(e,n):typeof t==`function`?je(e,t):e}var Gt=(0,N.createContext)(null),Kt=v(),qt=e=>e,L=()=>{var e=(0,N.useContext)(Gt);return e?e.store.dispatch:qt},Jt=()=>{},Yt=()=>Jt,Xt=(e,t)=>e===t;function R(e){var t=(0,N.useContext)(Gt),n=(0,N.useMemo)(()=>t?t=>{if(t!=null)return e(t)}:Jt,[t,e]);return(0,Kt.useSyncExternalStoreWithSelector)(t?t.subscription.addNestedSub:Yt,t?t.store.getState:Jt,t?t.store.getState:Jt,n,Xt)}var Zt=e=>e.legend.settings,Qt=e=>e.legend.size;m([e=>e.legend.payload,Zt],(e,t)=>{var n=t.itemSorter,r=e.flat(1);return n?k(r,n):r});function $t(e,t){return an(e)||rn(e,t)||tn(e,t)||en()}function en(){throw TypeError(`Invalid attempt to destructure non-iterable instance.
1
+ import{i as e,n as t}from"./rolldown-runtime-C4Xdq4VV.js";import{n,nn as r,t as i}from"./vendor-react-De1zEwOV.js";import{S as a,b as o}from"./vendor-icons-other-BTYC6Wvz.js";import{$ as s,A as c,B as l,C as u,D as d,E as f,F as p,G as m,H as h,I as g,J as _,K as v,L as y,M as b,N as x,O as S,P as C,Q as w,R as T,S as E,T as D,U as ee,V as O,W as k,X as A,Y as te,Z as ne,_ as re,_t as j,a as ie,at as ae,b as oe,c as se,ct as ce,d as le,dt as ue,et as de,f as fe,ft as pe,g as me,h as he,ht as ge,i as _e,it as ve,j as ye,k as be,l as xe,lt as Se,m as Ce,mt as we,n as Te,nt as Ee,o as De,ot as Oe,p as ke,pt as Ae,q as je,r as Me,rt as Ne,s as Pe,st as Fe,tt as Ie,u as Le,ut as Re,v as ze,w as Be,x as Ve,y as He,z as M}from"./vendor-utils-rmW6cqPl.js";import{h as Ue}from"./index-C5rHE6WK.js";var We=`dangerouslySetInnerHTML.onCopy.onCopyCapture.onCut.onCutCapture.onPaste.onPasteCapture.onCompositionEnd.onCompositionEndCapture.onCompositionStart.onCompositionStartCapture.onCompositionUpdate.onCompositionUpdateCapture.onFocus.onFocusCapture.onBlur.onBlurCapture.onChange.onChangeCapture.onBeforeInput.onBeforeInputCapture.onInput.onInputCapture.onReset.onResetCapture.onSubmit.onSubmitCapture.onInvalid.onInvalidCapture.onLoad.onLoadCapture.onError.onErrorCapture.onKeyDown.onKeyDownCapture.onKeyPress.onKeyPressCapture.onKeyUp.onKeyUpCapture.onAbort.onAbortCapture.onCanPlay.onCanPlayCapture.onCanPlayThrough.onCanPlayThroughCapture.onDurationChange.onDurationChangeCapture.onEmptied.onEmptiedCapture.onEncrypted.onEncryptedCapture.onEnded.onEndedCapture.onLoadedData.onLoadedDataCapture.onLoadedMetadata.onLoadedMetadataCapture.onLoadStart.onLoadStartCapture.onPause.onPauseCapture.onPlay.onPlayCapture.onPlaying.onPlayingCapture.onProgress.onProgressCapture.onRateChange.onRateChangeCapture.onSeeked.onSeekedCapture.onSeeking.onSeekingCapture.onStalled.onStalledCapture.onSuspend.onSuspendCapture.onTimeUpdate.onTimeUpdateCapture.onVolumeChange.onVolumeChangeCapture.onWaiting.onWaitingCapture.onAuxClick.onAuxClickCapture.onClick.onClickCapture.onContextMenu.onContextMenuCapture.onDoubleClick.onDoubleClickCapture.onDrag.onDragCapture.onDragEnd.onDragEndCapture.onDragEnter.onDragEnterCapture.onDragExit.onDragExitCapture.onDragLeave.onDragLeaveCapture.onDragOver.onDragOverCapture.onDragStart.onDragStartCapture.onDrop.onDropCapture.onMouseDown.onMouseDownCapture.onMouseEnter.onMouseLeave.onMouseMove.onMouseMoveCapture.onMouseOut.onMouseOutCapture.onMouseOver.onMouseOverCapture.onMouseUp.onMouseUpCapture.onSelect.onSelectCapture.onTouchCancel.onTouchCancelCapture.onTouchEnd.onTouchEndCapture.onTouchMove.onTouchMoveCapture.onTouchStart.onTouchStartCapture.onPointerDown.onPointerDownCapture.onPointerMove.onPointerMoveCapture.onPointerUp.onPointerUpCapture.onPointerCancel.onPointerCancelCapture.onPointerEnter.onPointerEnterCapture.onPointerLeave.onPointerLeaveCapture.onPointerOver.onPointerOverCapture.onPointerOut.onPointerOutCapture.onGotPointerCapture.onGotPointerCaptureCapture.onLostPointerCapture.onLostPointerCaptureCapture.onScroll.onScrollCapture.onWheel.onWheelCapture.onAnimationStart.onAnimationStartCapture.onAnimationEnd.onAnimationEndCapture.onAnimationIteration.onAnimationIterationCapture.onTransitionEnd.onTransitionEndCapture`.split(`.`);function Ge(e){return typeof e==`string`?We.includes(e):!1}var N=e(a()),Ke=new Set(`aria-activedescendant.aria-atomic.aria-autocomplete.aria-busy.aria-checked.aria-colcount.aria-colindex.aria-colspan.aria-controls.aria-current.aria-describedby.aria-details.aria-disabled.aria-errormessage.aria-expanded.aria-flowto.aria-haspopup.aria-hidden.aria-invalid.aria-keyshortcuts.aria-label.aria-labelledby.aria-level.aria-live.aria-modal.aria-multiline.aria-multiselectable.aria-orientation.aria-owns.aria-placeholder.aria-posinset.aria-pressed.aria-readonly.aria-relevant.aria-required.aria-roledescription.aria-rowcount.aria-rowindex.aria-rowspan.aria-selected.aria-setsize.aria-sort.aria-valuemax.aria-valuemin.aria-valuenow.aria-valuetext.className.color.height.id.lang.max.media.method.min.name.style.target.width.role.tabIndex.accentHeight.accumulate.additive.alignmentBaseline.allowReorder.alphabetic.amplitude.arabicForm.ascent.attributeName.attributeType.autoReverse.azimuth.baseFrequency.baselineShift.baseProfile.bbox.begin.bias.by.calcMode.capHeight.clip.clipPath.clipPathUnits.clipRule.colorInterpolation.colorInterpolationFilters.colorProfile.colorRendering.contentScriptType.contentStyleType.cursor.cx.cy.d.decelerate.descent.diffuseConstant.direction.display.divisor.dominantBaseline.dur.dx.dy.edgeMode.elevation.enableBackground.end.exponent.externalResourcesRequired.fill.fillOpacity.fillRule.filter.filterRes.filterUnits.floodColor.floodOpacity.focusable.fontFamily.fontSize.fontSizeAdjust.fontStretch.fontStyle.fontVariant.fontWeight.format.from.fx.fy.g1.g2.glyphName.glyphOrientationHorizontal.glyphOrientationVertical.glyphRef.gradientTransform.gradientUnits.hanging.horizAdvX.horizOriginX.href.ideographic.imageRendering.in2.in.intercept.k1.k2.k3.k4.k.kernelMatrix.kernelUnitLength.kerning.keyPoints.keySplines.keyTimes.lengthAdjust.letterSpacing.lightingColor.limitingConeAngle.local.markerEnd.markerHeight.markerMid.markerStart.markerUnits.markerWidth.mask.maskContentUnits.maskUnits.mathematical.mode.numOctaves.offset.opacity.operator.order.orient.orientation.origin.overflow.overlinePosition.overlineThickness.paintOrder.panose1.pathLength.patternContentUnits.patternTransform.patternUnits.pointerEvents.pointsAtX.pointsAtY.pointsAtZ.preserveAlpha.preserveAspectRatio.primitiveUnits.r.radius.refX.refY.renderingIntent.repeatCount.repeatDur.requiredExtensions.requiredFeatures.restart.result.rotate.rx.ry.seed.shapeRendering.slope.spacing.specularConstant.specularExponent.speed.spreadMethod.startOffset.stdDeviation.stemh.stemv.stitchTiles.stopColor.stopOpacity.strikethroughPosition.strikethroughThickness.string.stroke.strokeDasharray.strokeDashoffset.strokeLinecap.strokeLinejoin.strokeMiterlimit.strokeOpacity.strokeWidth.surfaceScale.systemLanguage.tableValues.targetX.targetY.textAnchor.textDecoration.textLength.textRendering.to.transform.u1.u2.underlinePosition.underlineThickness.unicode.unicodeBidi.unicodeRange.unitsPerEm.vAlphabetic.values.vectorEffect.version.vertAdvY.vertOriginX.vertOriginY.vHanging.vIdeographic.viewTarget.visibility.vMathematical.widths.wordSpacing.writingMode.x1.x2.x.xChannelSelector.xHeight.xlinkActuate.xlinkArcrole.xlinkHref.xlinkRole.xlinkShow.xlinkTitle.xlinkType.xmlBase.xmlLang.xmlns.xmlnsXlink.xmlSpace.y1.y2.y.yChannelSelector.z.zoomAndPan.ref.key.angle`.split(`.`));function qe(e){return typeof e==`string`?Ke.has(e):!1}function Je(e){return typeof e==`string`&&e.startsWith(`data-`)}function Ye(e){if(typeof e!=`object`||!e)return{};var t={};for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(qe(n)||Je(n))&&(t[n]=e[n]);return t}function Xe(e){if(e==null)return null;if((0,N.isValidElement)(e)&&typeof e.props==`object`&&e.props!==null){var t=e.props;return Ye(t)}return typeof e==`object`&&!Array.isArray(e)?Ye(e):null}function Ze(e){var t={};for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(qe(n)||Je(n)||Ge(n))&&(t[n]=e[n]);return t}function Qe(e){return e==null?null:(0,N.isValidElement)(e)?Ze(e.props):typeof e==`object`&&!Array.isArray(e)?Ze(e):null}var $e=[`children`,`width`,`height`,`viewBox`,`className`,`style`,`title`,`desc`];function et(){return et=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)({}).hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},et.apply(null,arguments)}function tt(e,t){if(e==null)return{};var n,r,i=nt(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)===-1&&{}.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function nt(e,t){if(e==null)return{};var n={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(t.indexOf(r)!==-1)continue;n[r]=e[r]}return n}var rt=(0,N.forwardRef)((e,t)=>{var n=e.children,r=e.width,i=e.height,a=e.viewBox,o=e.className,s=e.style,c=e.title,l=e.desc,u=tt(e,$e),d=a||{width:r,height:i,x:0,y:0},f=j(`recharts-surface`,o);return N.createElement(`svg`,et({},Ze(u),{className:f,width:r,height:i,style:s,viewBox:`${d.x} ${d.y} ${d.width} ${d.height}`,ref:t}),N.createElement(`title`,null,c),N.createElement(`desc`,null,l),n)}),it=[`children`,`className`];function at(){return at=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)({}).hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},at.apply(null,arguments)}function ot(e,t){if(e==null)return{};var n,r,i=st(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)===-1&&{}.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function st(e,t){if(e==null)return{};var n={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(t.indexOf(r)!==-1)continue;n[r]=e[r]}return n}var ct=N.forwardRef((e,t)=>{var n=e.children,r=e.className,i=ot(e,it),a=j(`recharts-layer`,r);return N.createElement(`g`,at({className:a},Ze(i),{ref:t}),n)}),lt=4;function ut(e){var t=10**(arguments.length>1&&arguments[1]!==void 0?arguments[1]:lt),n=Math.round(e*t)/t;return Object.is(n,-0)?0:n}function P(e){var t=[...arguments].slice(1);return e.reduce((e,n,r)=>{var i=t[r-1];return typeof i==`string`?e+i+n:i===void 0?e+n:e+ut(i)+n},``)}var dt=e=>e===0?0:e>0?1:-1,ft=e=>typeof e==`number`&&e!=+e,pt=e=>typeof e==`string`&&e.length>1&&e.indexOf(`%`)===e.length-1,F=e=>(typeof e==`number`||e instanceof Number)&&!ft(e),mt=e=>F(e)||typeof e==`string`,ht=0,gt=e=>{var t=++ht;return`${e||``}${t}`},_t=function(e,t){var n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:0,r=arguments.length>3&&arguments[3]!==void 0?arguments[3]:!1;if(!F(e)&&typeof e!=`string`)return n;var i;if(pt(e)){if(t==null)return n;var a=e.indexOf(`%`);i=t*parseFloat(e.slice(0,a))/100}else i=+e;return ft(i)&&(i=n),r&&t!=null&&i>t&&(i=t),i},vt=e=>{if(!Array.isArray(e))return!1;for(var t=e.length,n={},r=0;r<t;r++)if(!n[String(e[r])])n[String(e[r])]=!0;else return!0;return!1};function yt(e,t,n){return F(e)&&F(t)?ut(e+n*(t-e)):t}function bt(e,t,n){if(!(!e||!e.length))return e.find(e=>e&&(typeof t==`function`?t(e):ge(e,t))===n)}var I=e=>e==null,xt=e=>I(e)?e:`${e.charAt(0).toUpperCase()}${e.slice(1)}`;function St(e){return e!=null}function Ct(){}function wt(e){if(e)return{x:e.x,y:e.y,upperWidth:`upperWidth`in e?e.upperWidth:e.width,lowerWidth:`lowerWidth`in e?e.lowerWidth:e.width,width:e.width,height:e.height}}function Tt(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function Et(e){for(var t=1;t<arguments.length;t++){var n=arguments[t]==null?{}:arguments[t];t%2?Tt(Object(n),!0).forEach(function(t){Dt(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):Tt(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function Dt(e,t,n){return(t=Ot(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function Ot(e){var t=kt(e,`string`);return typeof t==`symbol`?t:t+``}function kt(e,t){if(typeof e!=`object`||!e)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t||`default`);if(typeof r!=`object`)return r;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(t===`string`?String:Number)(e)}var At=e=>{var t=e.viewBox,n=e.position,r=e.offset,i=r===void 0?0:r,a=e.parentViewBox,o=e.clamp,s=wt(t),c=s.x,l=s.y,u=s.height,d=s.upperWidth,f=s.lowerWidth,p=c,m=c+(d-f)/2,h=(p+m)/2,g=(d+f)/2,_=p+d/2,v=u>=0?1:-1,y=v*i,b=v>0?`end`:`start`,x=v>0?`start`:`end`,S=d>=0?1:-1,C=S*i,w=S>0?`end`:`start`,T=S>0?`start`:`end`,E=a;if(n===`top`){var D={x:p+d/2,y:l-y,horizontalAnchor:`middle`,verticalAnchor:b};return o&&E&&(D.height=Math.max(l-E.y,0),D.width=d),D}if(n===`bottom`){var ee={x:m+f/2,y:l+u+y,horizontalAnchor:`middle`,verticalAnchor:x};return o&&E&&(ee.height=Math.max(E.y+E.height-(l+u),0),ee.width=f),ee}if(n===`left`){var O={x:h-C,y:l+u/2,horizontalAnchor:w,verticalAnchor:`middle`};return o&&E&&(O.width=Math.max(O.x-E.x,0),O.height=u),O}if(n===`right`){var k={x:h+g+C,y:l+u/2,horizontalAnchor:T,verticalAnchor:`middle`};return o&&E&&(k.width=Math.max(E.x+E.width-k.x,0),k.height=u),k}var A=o&&E?{width:g,height:u}:{};return n===`insideLeft`?Et({x:h+C,y:l+u/2,horizontalAnchor:T,verticalAnchor:`middle`},A):n===`insideRight`?Et({x:h+g-C,y:l+u/2,horizontalAnchor:w,verticalAnchor:`middle`},A):n===`insideTop`?Et({x:p+d/2,y:l+y,horizontalAnchor:`middle`,verticalAnchor:x},A):n===`insideBottom`?Et({x:m+f/2,y:l+u-y,horizontalAnchor:`middle`,verticalAnchor:b},A):n===`insideTopLeft`?Et({x:p+C,y:l+y,horizontalAnchor:T,verticalAnchor:x},A):n===`insideTopRight`?Et({x:p+d-C,y:l+y,horizontalAnchor:w,verticalAnchor:x},A):n===`insideBottomLeft`?Et({x:m+C,y:l+u-y,horizontalAnchor:T,verticalAnchor:b},A):n===`insideBottomRight`?Et({x:m+f-C,y:l+u-y,horizontalAnchor:w,verticalAnchor:b},A):n&&typeof n==`object`&&(F(n.x)||pt(n.x))&&(F(n.y)||pt(n.y))?Et({x:c+_t(n.x,g),y:l+_t(n.y,u),horizontalAnchor:`end`,verticalAnchor:`end`},A):Et({x:_,y:l+u/2,horizontalAnchor:`middle`,verticalAnchor:`middle`},A)},jt=[`top`,`left`,`right`,`bottom`];function Mt(e){return e==null?!1:typeof e==`object`?!0:jt.includes(e)}var Nt=(0,N.createContext)(null),Pt=e=>`radius`in e&&`startAngle`in e&&`endAngle`in e,Ft=(e,t)=>{if(!e||typeof e==`function`||typeof e==`boolean`)return null;var n=e;if((0,N.isValidElement)(e)&&(n=e.props),typeof n!=`object`&&typeof n!=`function`)return null;var r={};return Object.keys(n).forEach(e=>{Ge(e)&&typeof n[e]==`function`&&(r[e]=t||(t=>n[e](n,t)))}),r},It=(e,t,n)=>r=>(e(t,n,r),null),Lt=(e,t,n)=>{if(e===null||typeof e!=`object`&&typeof e!=`function`)return null;var r=null;return Object.keys(e).forEach(i=>{var a=e[i];Ge(i)&&typeof a==`function`&&(r||={},r[i]=It(a,t,n))}),r};function Rt(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function zt(e){for(var t=1;t<arguments.length;t++){var n=arguments[t]==null?{}:arguments[t];t%2?Rt(Object(n),!0).forEach(function(t){Bt(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):Rt(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function Bt(e,t,n){return(t=Vt(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function Vt(e){var t=Ht(e,`string`);return typeof t==`symbol`?t:t+``}function Ht(e,t){if(typeof e!=`object`||!e)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t||`default`);if(typeof r!=`object`)return r;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(t===`string`?String:Number)(e)}function Ut(e,t){var n=zt({},e),r=t;return Object.keys(t).reduce((e,t)=>(e[t]===void 0&&r[t]!==void 0&&(e[t]=r[t]),e),n)}function Wt(e,t,n){return t===!0?je(e,n):typeof t==`function`?je(e,t):e}var Gt=(0,N.createContext)(null),Kt=v(),qt=e=>e,L=()=>{var e=(0,N.useContext)(Gt);return e?e.store.dispatch:qt},Jt=()=>{},Yt=()=>Jt,Xt=(e,t)=>e===t;function R(e){var t=(0,N.useContext)(Gt),n=(0,N.useMemo)(()=>t?t=>{if(t!=null)return e(t)}:Jt,[t,e]);return(0,Kt.useSyncExternalStoreWithSelector)(t?t.subscription.addNestedSub:Yt,t?t.store.getState:Jt,t?t.store.getState:Jt,n,Xt)}var Zt=e=>e.legend.settings,Qt=e=>e.legend.size;m([e=>e.legend.payload,Zt],(e,t)=>{var n=t.itemSorter,r=e.flat(1);return n?k(r,n):r});function $t(e,t){return an(e)||rn(e,t)||tn(e,t)||en()}function en(){throw TypeError(`Invalid attempt to destructure non-iterable instance.
2
2
  In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function tn(e,t){if(e){if(typeof e==`string`)return nn(e,t);var n={}.toString.call(e).slice(8,-1);return n===`Object`&&e.constructor&&(n=e.constructor.name),n===`Map`||n===`Set`?Array.from(e):n===`Arguments`||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?nn(e,t):void 0}}function nn(e,t){(t==null||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n<t;n++)r[n]=e[n];return r}function rn(e,t){var n=e==null?null:typeof Symbol<`u`&&e[Symbol.iterator]||e[`@@iterator`];if(n!=null){var r,i,a,o,s=[],c=!0,l=!1;try{if(a=(n=n.call(e)).next,t===0){if(Object(n)!==n)return;c=!1}else for(;!(c=(r=a.call(n)).done)&&(s.push(r.value),s.length!==t);c=!0);}catch(e){l=!0,i=e}finally{try{if(!c&&n.return!=null&&(o=n.return(),Object(o)!==o))return}finally{if(l)throw i}}return s}}function an(e){if(Array.isArray(e))return e}var on=1;function sn(e,t){return Math.abs(e.height-t.height)>on||Math.abs(e.left-t.left)>on||Math.abs(e.top-t.top)>on||Math.abs(e.width-t.width)>on}function cn(e){var t=e.getBoundingClientRect();return{height:t.height,left:t.left,top:t.top,width:t.width}}function ln(){var e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:[],t=$t((0,N.useState)({height:0,left:0,top:0,width:0}),2),n=t[0],r=t[1],i=(0,N.useRef)(null),a=(0,N.useRef)(n);a.current=n;var o=(0,N.useCallback)(e=>{if(i.current!=null&&(i.current.disconnect(),i.current=null),e!=null){var t=cn(e);if(sn(t,a.current)&&r(t),typeof ResizeObserver<`u`){var n=new ResizeObserver(()=>{var t=cn(e);sn(t,a.current)&&r(t)});n.observe(e),i.current=n}}},[...e]);return(0,N.useEffect)(()=>()=>{var e;(e=i.current)==null||e.disconnect()},[]),[n,o]}var un=M({name:`chartLayout`,initialState:{layoutType:`horizontal`,width:0,height:0,margin:{top:5,right:5,bottom:5,left:5},scale:1},reducers:{setLayout(e,t){e.layoutType=t.payload},setChartSize(e,t){e.width=t.payload.width,e.height=t.payload.height},setMargin(e,t){e.margin.top=t.payload.top??0,e.margin.right=t.payload.right??0,e.margin.bottom=t.payload.bottom??0,e.margin.left=t.payload.left??0},setScale(e,t){e.scale=t.payload}}}),dn=un.actions,fn=dn.setMargin,pn=dn.setLayout,mn=dn.setChartSize,hn=dn.setScale,gn=un.reducer;function _n(e,t,n){return Array.isArray(e)&&e&&t+n!==0?e.slice(t,n+1):e}function z(e){return Number.isFinite(e)}function vn(e){return typeof e==`number`&&e>0&&Number.isFinite(e)}function yn(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function bn(e){for(var t=1;t<arguments.length;t++){var n=arguments[t]==null?{}:arguments[t];t%2?yn(Object(n),!0).forEach(function(t){xn(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):yn(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function xn(e,t,n){return(t=Sn(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function Sn(e){var t=Cn(e,`string`);return typeof t==`symbol`?t:t+``}function Cn(e,t){if(typeof e!=`object`||!e)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t||`default`);if(typeof r!=`object`)return r;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(t===`string`?String:Number)(e)}function B(e,t,n){return I(e)||I(t)?n:mt(t)?ge(e,t,n):typeof t==`function`?t(e):n}var wn=(e,t,n)=>{if(t&&n){var r=n.width,i=n.height,a=t.align,o=t.verticalAlign,s=t.layout,c=t.position,l=t.offset,u=l===void 0?0:l;if(c!=null){if(Mt(c)){if(c===`top`&&F(e.top))return bn(bn({},e),{},{top:e.top+(i||0)+u});if(c===`bottom`&&F(e.bottom))return bn(bn({},e),{},{bottom:e.bottom+(i||0)+u});if(c===`left`&&F(e.left))return bn(bn({},e),{},{left:e.left+(r||0)+u});if(c===`right`&&F(e.right))return bn(bn({},e),{},{right:e.right+(r||0)+u})}return e}if((s===`vertical`||s===`horizontal`&&o===`middle`)&&a!==`center`&&F(e[a]))return bn(bn({},e),{},{[a]:e[a]+(r||0)});if((s===`horizontal`||s===`vertical`&&a===`center`)&&o!==`middle`&&F(e[o]))return bn(bn({},e),{},{[o]:e[o]+(i||0)})}return e},Tn=(e,t)=>e===`horizontal`&&t===`xAxis`||e===`vertical`&&t===`yAxis`||e===`centric`&&t===`angleAxis`||e===`radial`&&t===`radiusAxis`,En=(e,t,n,r)=>{if(r)return e.map(e=>e.coordinate);var i,a,o=e.map(e=>(e.coordinate===t&&(i=!0),e.coordinate===n&&(a=!0),e.coordinate));return i||o.push(t),a||o.push(n),o},Dn=(e,t,n)=>{if(!e)return null;var r=e.duplicateDomain,i=e.type,a=e.range,o=e.scale,s=e.realScaleType,c=e.isCategorical,l=e.categoricalDomain,u=e.tickCount,d=e.ticks,f=e.niceTicks,p=e.axisType;if(!o)return null;var m=s===`scaleBand`&&o.bandwidth?o.bandwidth()/2:2,h=(t||n)&&i===`category`&&o.bandwidth?o.bandwidth()/m:0;return h=p===`angleAxis`&&a&&a.length>=2?dt(a[0]-a[1])*2*h:h,t&&(d||f)?(d||f||[]).map((e,t)=>{var n=r?r.indexOf(e):e,i=o.map(n);return z(i)?{coordinate:i+h,value:e,offset:h,index:t}:null}).filter(St):c&&l?l.map((e,t)=>{var n=o.map(e);return z(n)?{coordinate:n+h,value:e,index:t,offset:h}:null}).filter(St):o.ticks&&!n&&u!=null?o.ticks(u).map((e,t)=>{var n=o.map(e);return z(n)?{coordinate:n+h,value:e,index:t,offset:h}:null}).filter(St):o.domain().map((e,t)=>{var n=o.map(e);return z(n)?{coordinate:n+h,value:r?r[e]:e,index:t,offset:h}:null}).filter(St)},On={sign:e=>{var t=e.length;if(!(t<=0)){var n=e[0]?.length;if(!(n==null||n<=0))for(var r=0;r<n;++r)for(var i=0,a=0,o=0;o<t;++o){var s=e[o]?.[r];if(s!=null){var c=s[1],l=s[0],u=ft(c)?l:c;u>=0?(s[0]=i,i+=u,s[1]=i):(s[0]=a,a+=u,s[1]=a)}}}},expand:A,none:s,silhouette:te,wiggle:_,positive:e=>{var t=e.length;if(!(t<=0)){var n=e[0]?.length;if(!(n==null||n<=0))for(var r=0;r<n;++r)for(var i=0,a=0;a<t;++a){var o=e[a]?.[r];if(o!=null){var s=ft(o[1])?o[0]:o[1];s>=0?(o[0]=i,i+=s,o[1]=i):(o[0]=0,o[1]=0)}}}}},kn=(e,t,n)=>{var r=On[n]??s,i=ne().keys(t).value((e,t)=>Number(B(e,t,0))).order(w).offset(r)(e);return i.forEach((n,r)=>{n.forEach((n,i)=>{var a=B(e[i],t[r],0);Array.isArray(a)&&a.length===2&&F(a[0])&&F(a[1])&&(n[0]=a[0],n[1]=a[1])})}),i};function An(e){return e==null?void 0:String(e)}function jn(e){var t=e.axis,n=e.ticks,r=e.bandSize,i=e.entry,a=e.index,o=e.dataKey;if(t.type===`category`){if(!t.allowDuplicatedCategory&&t.dataKey&&!I(i[t.dataKey])){var s=bt(n,`value`,i[t.dataKey]);if(s)return s.coordinate+r/2}return n!=null&&n[a]?n[a].coordinate+r/2:null}var c=B(i,I(o)?t.dataKey:o),l=t.scale.map(c);return F(l)?l:null}var Mn=e=>{var t=e.flat(2).filter(F);return[Math.min(...t),Math.max(...t)]},Nn=e=>[e[0]===1/0?0:e[0],e[1]===-1/0?0:e[1]],Pn=(e,t,n)=>{if(!(e==null||Object.keys(e).length===0))return Nn(Object.keys(e).reduce((r,i)=>{var a=e[i];if(!a)return r;var o=a.stackedData.reduce((e,r)=>{var i=Mn(_n(r,t,n));return!z(i[0])||!z(i[1])?e:[Math.min(e[0],i[0]),Math.max(e[1],i[1])]},[1/0,-1/0]);return[Math.min(o[0],r[0]),Math.max(o[1],r[1])]},[1/0,-1/0]))},Fn=/^dataMin[\s]*-[\s]*([0-9]+([.]{1}[0-9]+){0,1})$/,In=/^dataMax[\s]*\+[\s]*([0-9]+([.]{1}[0-9]+){0,1})$/,Ln=(e,t,n)=>{if(e&&e.scale&&e.scale.bandwidth){var r=e.scale.bandwidth();if(!n||r>0)return r}if(e&&t&&t.length>=2){for(var i=k(t,e=>e.coordinate),a=[],o=0,s=1,c=i.length;s<c;s++){var l=(i[s]?.coordinate||0)-(i[s-1]?.coordinate||0);a.push(l),o=Math.max(l,o)}var u=o*1e-4,d=1/0;for(var f of a)f>u&&(d=Math.min(f,d));return d===1/0?0:d}return n?void 0:0};function Rn(e){var t=e.tooltipEntrySettings,n=e.dataKey,r=e.payload,i=e.value,a=e.name;return bn(bn({},t),{},{dataKey:n,payload:r,value:i,name:a})}function zn(e,t){if(e!=null)return String(e);if(typeof t==`string`)return t}var Bn=(e,t)=>{if(t===`horizontal`)return e.relativeX;if(t===`vertical`)return e.relativeY},Vn=(e,t)=>t===`centric`?e.angle:e.radius,Hn=e=>e.layout.width,Un=e=>e.layout.height,Wn=e=>e.layout.scale,Gn=e=>e.layout.margin,Kn=m(e=>e.cartesianAxis.xAxis,e=>Object.values(e)),qn=m(e=>e.cartesianAxis.yAxis,e=>Object.values(e)),Jn=`data-recharts-item-index`;function Yn(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function Xn(e){for(var t=1;t<arguments.length;t++){var n=arguments[t]==null?{}:arguments[t];t%2?Yn(Object(n),!0).forEach(function(t){Zn(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):Yn(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function Zn(e,t,n){return(t=Qn(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function Qn(e){var t=$n(e,`string`);return typeof t==`symbol`?t:t+``}function $n(e,t){if(typeof e!=`object`||!e)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t||`default`);if(typeof r!=`object`)return r;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(t===`string`?String:Number)(e)}var er=e=>e.brush.height;function tr(e){return qn(e).reduce((e,t)=>t.orientation===`left`&&!t.mirror&&!t.hide?e+(typeof t.width==`number`?t.width:60):e,0)}function nr(e){return qn(e).reduce((e,t)=>t.orientation===`right`&&!t.mirror&&!t.hide?e+(typeof t.width==`number`?t.width:60):e,0)}function rr(e){return Kn(e).reduce((e,t)=>t.orientation===`top`&&!t.mirror&&!t.hide?e+(typeof t.height==`number`?t.height:30):e,0)}function ir(e){return Kn(e).reduce((e,t)=>t.orientation===`bottom`&&!t.mirror&&!t.hide?e+(typeof t.height==`number`?t.height:30):e,0)}var V=m([Hn,Un,Gn,er,tr,nr,rr,ir,Zt,Qt],(e,t,n,r,i,a,o,s,c,l)=>{var u={left:(n.left||0)+i,right:(n.right||0)+a},d=Xn(Xn({},{top:(n.top||0)+o,bottom:(n.bottom||0)+s}),u),f=d.bottom;d.bottom+=r,d=wn(d,c,l);var p=e-d.left-d.right,m=t-d.top-d.bottom;return Xn(Xn({brushBottom:f},d),{},{width:Math.max(p,0),height:Math.max(m,0)})}),ar=m(V,e=>({x:e.left,y:e.top,width:e.width,height:e.height})),or=m(Hn,Un,(e,t)=>({x:0,y:0,width:e,height:t})),sr=(0,N.createContext)(null),cr=()=>(0,N.useContext)(sr)!=null,lr=e=>e.brush,ur=m([lr,V,Gn],(e,t,n)=>({height:e.height,x:F(e.x)?e.x:t.left,y:F(e.y)?e.y:t.top+t.height+t.brushBottom-(n?.bottom||0),width:F(e.width)?e.width:t.width})),dr=!0,fr=function(e,t){var n=[...arguments].slice(2);if(dr&&typeof console<`u`&&console.warn&&(t===void 0&&console.warn(`LogUtils requires an error message argument`),!e))if(t===void 0)console.warn(`Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.`);else{var r=0;console.warn(t.replace(/%s/g,()=>n[r++]))}},pr={width:`100%`,height:`100%`,debounce:0,minWidth:0,initialDimension:{width:-1,height:-1}},mr=(e,t,n)=>{var r=n.width,i=r===void 0?pr.width:r,a=n.height,o=a===void 0?pr.height:a,s=n.aspect,c=n.maxHeight,l=pt(i)?e:Number(i),u=pt(o)?t:Number(o);return s&&s>0&&(l?u=l/s:u&&(l=u*s),c&&u!=null&&u>c&&(u=c)),{calculatedWidth:l,calculatedHeight:u}},hr={width:0,height:0,overflow:`visible`},gr={width:0,overflowX:`visible`},_r={height:0,overflowY:`visible`},vr={},yr=e=>{var t=e.width,n=e.height,r=pt(t),i=pt(n);return r&&i?hr:r?gr:i?_r:vr};function br(e){var t=e.width,n=e.height,r=e.aspect,i=t,a=n;return i===void 0&&a===void 0?(i=pr.width,a=pr.height):i===void 0?i=r&&r>0?void 0:pr.width:a===void 0&&(a=r&&r>0?void 0:pr.height),{width:i,height:a}}var xr=[`aspect`,`initialDimension`,`width`,`height`,`minWidth`,`minHeight`,`maxHeight`,`children`,`debounce`,`id`,`className`,`onResize`,`style`];function Sr(){return Sr=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)({}).hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},Sr.apply(null,arguments)}function Cr(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function wr(e){for(var t=1;t<arguments.length;t++){var n=arguments[t]==null?{}:arguments[t];t%2?Cr(Object(n),!0).forEach(function(t){Tr(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):Cr(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function Tr(e,t,n){return(t=Er(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function Er(e){var t=Dr(e,`string`);return typeof t==`symbol`?t:t+``}function Dr(e,t){if(typeof e!=`object`||!e)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t||`default`);if(typeof r!=`object`)return r;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(t===`string`?String:Number)(e)}function Or(e,t){return Nr(e)||Mr(e,t)||Ar(e,t)||kr()}function kr(){throw TypeError(`Invalid attempt to destructure non-iterable instance.
3
3
  In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function Ar(e,t){if(e){if(typeof e==`string`)return jr(e,t);var n={}.toString.call(e).slice(8,-1);return n===`Object`&&e.constructor&&(n=e.constructor.name),n===`Map`||n===`Set`?Array.from(e):n===`Arguments`||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?jr(e,t):void 0}}function jr(e,t){(t==null||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n<t;n++)r[n]=e[n];return r}function Mr(e,t){var n=e==null?null:typeof Symbol<`u`&&e[Symbol.iterator]||e[`@@iterator`];if(n!=null){var r,i,a,o,s=[],c=!0,l=!1;try{if(a=(n=n.call(e)).next,t===0){if(Object(n)!==n)return;c=!1}else for(;!(c=(r=a.call(n)).done)&&(s.push(r.value),s.length!==t);c=!0);}catch(e){l=!0,i=e}finally{try{if(!c&&n.return!=null&&(o=n.return(),Object(o)!==o))return}finally{if(l)throw i}}return s}}function Nr(e){if(Array.isArray(e))return e}function Pr(e,t){if(e==null)return{};var n,r,i=Fr(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)===-1&&{}.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function Fr(e,t){if(e==null)return{};var n={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(t.indexOf(r)!==-1)continue;n[r]=e[r]}return n}var Ir=(0,N.createContext)(pr.initialDimension);function Lr(e){return vn(e.width)&&vn(e.height)}function Rr(e){var t=e.children,n=e.width,r=e.height,i=(0,N.useMemo)(()=>({width:n,height:r}),[n,r]);return Lr(i)?N.createElement(Ir.Provider,{value:i},t):null}var zr=()=>(0,N.useContext)(Ir),Br=(0,N.forwardRef)((e,t)=>{var n=e.aspect,r=e.initialDimension,i=r===void 0?pr.initialDimension:r,a=e.width,o=e.height,s=e.minWidth,c=s===void 0?pr.minWidth:s,l=e.minHeight,u=e.maxHeight,d=e.children,f=e.debounce,p=f===void 0?pr.debounce:f,m=e.id,h=e.className,g=e.onResize,_=e.style,v=_===void 0?{}:_,y=Pr(e,xr),b=(0,N.useRef)(null),x=(0,N.useRef)();x.current=g,(0,N.useImperativeHandle)(t,()=>b.current);var S=Or((0,N.useState)({containerWidth:i.width,containerHeight:i.height}),2),w=S[0],T=S[1],E=(0,N.useCallback)((e,t)=>{T(n=>{var r=Math.round(e),i=Math.round(t);return n.containerWidth===r&&n.containerHeight===i?n:{containerWidth:r,containerHeight:i}})},[]);(0,N.useEffect)(()=>{if(b.current==null||typeof ResizeObserver>`u`)return Ct;var e=e=>{var t,n=e[0];if(n!=null){var r=n.contentRect,i=r.width,a=r.height;E(i,a),(t=x.current)==null||t.call(x,i,a)}};p>0&&(e=C(e,p,{trailing:!0,leading:!1}));var t=new ResizeObserver(e),n=b.current.getBoundingClientRect(),r=n.width,i=n.height;return E(r,i),t.observe(b.current),()=>{t.disconnect()}},[E,p]);var D=w.containerWidth,ee=w.containerHeight;fr(!n||n>0,`The aspect(%s) must be greater than zero.`,n);var O=mr(D,ee,{width:a,height:o,aspect:n,maxHeight:u}),k=O.calculatedWidth,A=O.calculatedHeight;return fr(D<0||ee<0||k!=null&&k>0||A!=null&&A>0,`The width(%s) and height(%s) of chart should be greater than 0,
4
4
  please check the style of container, or the props width(%s) and height(%s),
@@ -0,0 +1 @@
1
+ import{_ as e,g as t,h as n}from"./index-C5rHE6WK.js";export{t as setSystemLocale,e as setSystemTimeZone};
@@ -0,0 +1,12 @@
1
+ const e={account:`Konto`,logout:`Abmelden`,selectProfile:`Profil auswählen`,add:`Hinzufügen`,newProfileName:`Neuer Profilname...`,profileNameFormatTip:`Hinweis zum Profilnamen: 1-30 Zeichen. Muss sich von bestehenden Namen unterscheiden`,profileLimitExceeded:`Maximale Anzahl an Profilen erreicht (max. {{max}})`,profileNameExists:`Dieser Profilname existiert bereits`,profileNameFormatError:`Ungültiges Profilnamensformat`,create:`Erstellen`,welcome:`Willkommen`,createProfileToStart:`Erstellen Sie ein Profil, um zu beginnen.`,loading:`Wird geladen...`,errorNetwork:`Netzwerkfehler`,confirmDelete:`Sind Sie sicher, dass Sie dieses Profil löschen möchten?`,confirmLogout:`Sind Sie sicher, dass Sie sich abmelden möchten?`,notFound:`404 - Seite nicht gefunden`,notFoundDesc:`Die von Ihnen gesuchte Seite existiert nicht oder wurde verschoben.`,backToHome:`Zurück zur Startseite`,apac:`Asien-Pazifik`,mainlandChina:`Festlandchina`,HongKong:`Hongkong`,Singapore:`Singapur`,Tokyo:`Tokio`,NorthAmerica:`Nordamerika`,nae:`Nordamerika-Ost`,naw:`Nordamerika-West`,eu:`Europa`,invalidFormat:`Ungültiges Dateiformat`,import:`Importieren`,importSuccess:`Profil erfolgreich importiert`,importError:`Profilimport fehlgeschlagen. Bitte überprüfen Sie das Format und versuchen Sie es später noch einmal`,save:`Speichern`,saveSuccess:`Einstellungen gespeichert`,close:`Schließen`,cancel:`Abbrechen`,yes:`Ja`,no:`Nein`,continue:`Fortfahren`,back:`Zurück`,copy:`Kopieren`,copied:`Kopiert`,copyKey:`Neuen Wiederherstellungsschlüssel kopieren`,confirm:`Bestätigen`,delete:`Löschen`,rename:`Umbenennen`,disable:`Deaktivieren`,confirmDisable:`Deaktivierung bestätigen`,modeServerfull:`Serverfull-Modus`,modeCloudflare:`Cloudflare Worker-Modus`,unknown:`Unbekannt`},t={setup:`Installation`,rules:`Regeln`,stats:`Statistiken`,logs:`Protokolle`,filter:`Filterlisten`,settings:`Einstellungen`},n={light:`Hell`,dark:`Dunkel`,system:`System`},r={login:`Bei DNS Worker anmelden`,signup:`Konto erstellen, um zu beginnen`,welcomeBack:`Willkommen zurück! Bitte geben Sie Ihre Anmeldedaten ein`,protectInternet:`Schützen Sie Ihren ersten Schritt ins Internet`,error:`Fehler`,username:`Benutzername`,usernamePlaceholder:`Ihr Benutzername`,password:`Passwort`,passwordPlaceholder:`Ihr Passwort`,loginBtn:`Anmelden`,unlockSession:`Bildschirm entsperren`,signupBtn:`Registrieren`,totpVerification:`2FA/TOTP-Verifizierung`,noAccount:`Kein Konto? Jetzt registrieren`,haveAccount:`Bereits ein Konto? Zurück zur Anmeldung`,formatTipUsername:`Hinweis zum Benutzernamen: 5 bis 32 Zeichen, Unix-Format (muss mit einem Kleinbuchstaben oder Unterstrich beginnen und darf nur Kleinbuchstaben, Zahlen, Unterstriche und Bindestriche enthalten)`,formatTipPassword:`Hinweis zum Passwort: 12-100 Zeichen.`,authFailed:`Authentifizierung fehlgeschlagen. Bitte überprüfen Sie Ihren Benutzernamen oder Ihr Passwort`,networkError:`Netzwerkfehler. Bitte versuchen Sie es später noch einmal`,turnstileRequired:`Bitte lösen Sie das Captcha`,turnstileError:`Captcha-Dienst konnte nicht geladen werden. Bitte überprüfen Sie den Site-Key oder die Domain-Konfiguration`,verifying:`Sicherheitsprüfung wird durchgeführt...`,passwordLeaked:`Dieses Passwort wurde kompromittiert. Verwenden Sie ein zufälliges/starkes Passwort für Ihre Sicherheit.`,usernameExists:`Dieser Benutzername ist bereits registriert. Bitte versuchen Sie einen anderen.`,skip:`Überspringen`,showPassword:`Passwort anzeigen`,hidePassword:`Passwort ausblenden`,geolocationRequired:`Geolokalisierung fehlgeschlagen. Bitte versuchen Sie es erneut.`,unauthorizedDefault:`Ihre Sitzung ist abgelaufen. Bitte melden Sie sich erneut an.`,unauthorizedGeo:`Standortänderung erkannt (Entfernungslimit überschritten). Sitzung wurde beendet.`,unauthorizedExpired:`Ihre Sitzung ist abgelaufen. Bitte melden Sie sich erneut an.`,unauthorizedReuse:`Sicherheitsalarm: Mehrfachanmeldung erkannt. Sitzung beendet.`,unauthorizedRevoked:`Ihre Sitzung wurde widerrufen oder gelöscht. Bitte melden Sie sich erneut an.`,sessionLockTitle:`Inaktivitätssperre`,sessionLockDesc:`Sperren Sie die Benutzeroberfläche bei Inaktivität mit einer 4-stelligen PIN, um aktive Sitzungen vor unbefugtem physischen Zugriff zu schützen.`,enableSessionLock:`Inaktivitätssperre aktivieren`,inactivityTimeout:`Inaktivitäts-Timeout`,timeout1m:`1 Minute`,timeout2m:`2 Minuten`,timeout5m:`5 Minuten`,timeout15m:`15 Minuten`,timeout30m:`30 Minuten`,timeout60m:`60 Minuten`,changePin:`PIN ändern`,disablePin:`Inaktivitätssperre deaktivieren`,configurePin:`PIN einrichten`,newPin:`Neue 4-stellige PIN`,pinHelper:`Nur Ziffern, z. B. 1234`,confirmPin:`Neue PIN bestätigen`,verifyIdentity:`Identität verifizieren`,usePassword:`Passwort verwenden`,use2fa:`TOTP-Code verwenden`,totpCode:`TOTP-Code`,currentPassword:`Aktuelles Passwort`,disablePinWarning:`Durch das Deaktivieren der PIN wird die automatische Inaktivitätssperre vollständig abgeschaltet.`,pinFormatTip:`Die PIN muss genau 4 Ziffern lang sein`,pinMatchTip:`Die PINs stimmen nicht überein`,passwordRequired:`Passwort zur Verifizierung erforderlich`,sessionLocked:`Sitzung wegen Inaktivität gesperrt`,sessionExpired:`Sitzung abgelaufen. Bitte erneut anmelden.`,pinIncorrect:`Falsche PIN`,attemptsRemaining:`{{count}} verbleibende Versuche`,logoutAndReturn:`Sitzung abmelden`,lockNow:`Jetzt sperren`,cfErrorWithDetails:`Cloudflare-Edge-Fehler (Fehler {{code}}: {{desc}}). Der Dienst ist vorübergehend nicht verfügbar, bitte versuchen Sie es später erneut. {{rayId}}`,cfErrorCodeOnly:`Cloudflare-Edge-Fehler (Fehler {{code}}). Der Dienst ist vorübergehend nicht verfügbar. {{rayId}}`,cfErrorGeneric:`Cloudflare-Edge-Fehler. Der Dienst ist vorübergehend nicht verfügbar, bitte versuchen Sie es später erneut. {{rayId}}`,htmlErrorGeneric:`Der Server hat eine unerwartete Antwort zurückgegeben (HTTP {{status}}). Bitte versuchen Sie es später erneut.`,tooManyAttempts:`Zu viele Anfragen oder Versuche. Bitte versuchen Sie es später erneut.`,dbQuotaExceeded:`Das tägliche Lesekontingent der Datenbank wurde überschritten. Bitte warten Sie auf den täglichen Reset.`,noUsersRegistered:`Noch keine Konten registriert. Bitte registrieren Sie sich als Administrator.`,registerAdminTitle:`Administratorkonto registrieren`,registerAdminDesc:`Keine Konten im System. Der erste Benutzer wird Systemadministrator.`,goToRegisterAdmin:`Admin registrieren`,dbNotInitialized:`Datenbank nicht initialisiert oder Tabellen fehlen. Bitte führen Sie npm run db:migrate:prod aus.`,verifyWithPasskey:`Mit Passkey bestätigen`,orUseTotp:`Oder Authentifikator-Code verwenden`,passwordRequiredFirst:`Bitte geben Sie zuerst Ihr Passwort ein`,passkeyVerification:`Passkey-Verifizierung`,passkeyPromptDesc:`Verifizieren Sie mit Ihrer registrierten Biometrie oder Ihrem Sicherheitsschlüssel`,forgotPassword:`Passwort vergessen?`,forgotPasswordTitle:`Passwort zurücksetzen`,forgotPasswordDesc:`Stellen Sie Ihr Konto sicher über Multi-Faktor-Authentifizierung (Passkey oder TOTP) wieder her.`,noMfaContactAdmin:`Für dieses Konto ist keine Multi-Faktor-Authentifizierung (Passkey oder TOTP) eingerichtet. Bitte wenden Sie sich an einen Administrator, um Ihr Passwort zurückzusetzen.`,chooseMfaForReset:`Wählen Sie eine Methode zur Identitätsprüfung:`,authViaPasskey:`Mit Passkey verifizieren`,authViaPasskeyDesc:`Ein-Klick-Verifizierung über Biometrie oder Hardware-Sicherheitsschlüssel`,authViaTotp:`Mit Authentifikator-App (TOTP) verifizieren`,authViaTotpDesc:`Geben Sie den 6-stelligen Code aus Ihrer Authentifikator-App ein`,authViaRecoveryKey:`Notfall-Wiederherstellungsschlüssel verwenden`,authViaRecoveryKeyDesc:`Geben Sie einen 10-stelligen Notfall-Wiederherstellungsschlüssel ein`,verifyAndProceed:`Verifizieren und fortfahren`,setNewPassword:`Neues Passwort festlegen`,setNewPasswordDesc:`Identität bestätigt. Bitte legen Sie ein neues Passwort für Ihr Konto fest.`,newPassword:`Neues Passwort`,confirmNewPassword:`Neues Passwort bestätigen`,passwordMismatch:`Die Passwörter stimmen nicht überein`,saveAndReset:`Speichern und zurücksetzen`,resetSuccessTitle:`Passwort erfolgreich zurückgesetzt`,resetSuccessDesc:`Ihr Passwort wurde aktualisiert und alle bestehenden Sitzungen wurden beendet. Bitte melden Sie sich mit Ihrem neuen Passwort an.`,goToLogin:`Zur Anmeldung`,mfaSetupTitle:`Kontosicherheit erhöhen`,mfaSetupDesc:`Die Einrichtung der Multi-Faktor-Authentifizierung (MFA) schützt Ihr Konto und ermöglicht passwortlose Anmeldung sowie Kontowiederherstellung.`,mfaRecommended:`Empfohlen`,passkeySignupDesc:`Verwenden Sie Touch ID, Face ID oder Sicherheitsschlüssel. Schnell und phishing-resistent.`,bindPasskeyNow:`Jetzt Passkey registrieren`,mfaUniversal:`Universell`,totpSignupDesc:`Verwenden Sie Google Authenticator, 1Password oder eine andere TOTP-App.`,setupTotpBtn:`Authentifikator-App einrichten`,skipMfaSetup:`Vorläufig überspringen`,backToMfaOptions:`Zurück zur Auswahl`,otherOptions:`Andere Optionen`,next:`Weiter`,mfaVerification:`Multi-Faktor-Authentifizierung`,totpPrompt:`Geben Sie den 6-stelligen dynamischen Code aus Ihrer Authentifikator-App ein`,recoveryPrompt:`Geben Sie Ihren 30-stelligen Wiederherstellungsschlüssel ein (5 Gruppen mit je 6 Ziffern)`,recoveryChecksumError:`Prüfsummenfehler: Diese Gruppe ist nicht durch 11 teilbar`,recoveryChecksumErrorDesc:`Prüfsummenfehler in Gruppe {{groups}}, bitte überprüfen und erneut versuchen`,backToPasskey:`Zurück zur Passkey-Verifizierung`,recoveryKeyRequired:`Bitte geben Sie Ihren Wiederherstellungsschlüssel ein`,totpFormatError:`Bitte geben Sie einen gültigen 6-stelligen Code ein`,registrationDisabledTitle:`Registrierung deaktiviert`,registrationDisabledDesc:`Die Registrierung neuer Benutzer ist derzeit deaktiviert. Bitte wenden Sie sich an den Systemadministrator.`,backToLogin:`Zurück zur Anmeldung`,jwtSecretPreset:`Standard-JWT_SECRET erkannt. Bitte ändern Sie das voreingestellte JWT_SECRET in den Umgebungsvariablen vor der Bereitstellung.`,jwtSecretMissing:`JWT_SECRET fehlt. Bitte konfigurieren Sie einen sicheren Schlüssel in den Umgebungsvariablen vor der Bereitstellung.`,jwtSecretInvalid:`Ungültiges JWT_SECRET-Format, bitte überprüfen Sie die Konfiguration.`,keepLoggedIn:`{{days}} Tage lang angemeldet bleiben`,orUseOtherMfa:`oder eine andere Methode verwenden`,totpUseRecovery:`Wiederherstellungsschlüssel verwenden`,totpUseApp:`Authenticator-App verwenden`,mfaMethodTotp:`Authenticator-App (TOTP)`,invalidTotp:`Ungültiger TOTP-Bestätigungscode.`,sessionExpiredNotice:`Sitzung abgelaufen oder ungültig. Bitte erneut anmelden.`,tooManyAttemptsTerminate:`Zu viele fehlgeschlagene Versuche. Sitzung beendet.`},i={title:`Installationsanleitung`,subtitle:`Konfigurieren Sie Ihre Geräte, um Ihre Internet-Sicherheit mit DNS Worker zu verwalten.`,regionOptimization:`Optimierung der Verbindungsregion (Windows)`,otherRegion:`Andere Regionen`,copied:`In die Zwischenablage kopiert`,verifyConnection:`Verbindung überprüfen`,verifying:`Wird überprüft...`,connected:`Verbunden`,notConnected:`Nicht verbunden`,profileMatch:`Die Filterung ist für dieses Profil aktiv.`,profileMismatch:`Sie verwenden Obex, aber die Profil-ID stimmt nicht überein.`,verifyHint:`Klicken Sie nach Abschluss der folgenden Konfiguration auf die Schaltfläche, um die Verbindung zu überprüfen.`,refreshStatus:`Status aktualisieren`,egressIp:`Ausgehende IP-Adresse`,currentLocation:`Aktueller Standort`,edgeServer:`Edge-Server`,serverLocation:`Server-Standort`,traceDetails:`Cloudflare Trace (/cdn-cgi/trace)`,noTraceData:`Keine Trace-Daten verfügbar`,dohUrlTitle:`DoH-URL des aktuellen Profils`,accessPointTitle:`DoH-Zugangs-URL`,defaultAccessPointName:`Gerät-1`,moreAccessPoints:`Mehr Zugangspunkte ↗`,accessPointName:`Name des Zugangspunkts`,accessPointToken:`Zugriffsschlüssel`,addAccessPoint:`Zugangspunkt hinzufügen`,renameAccessPoint:`Umbenennen`,rotateToken:`Schlüssel rotieren`,rotateTokenConfirmDesc:`Die Rotation des Schlüssels trennt sofort alle Geräte, die den alten Schlüssel verwenden. Möchten Sie fortfahren?`,deleteAccessPoint:`Löschen`,deleteAccessPointConfirm:`Sind Sie sicher, dass Sie diesen Zugangspunkt löschen möchten?`,manageAccessPoints:`Zugangspunkte verwalten`,searchAccessPoints:`Zugangspunkte suchen...`,accessPointNameExists:`Name des Zugangspunkts existiert bereits`,accessPointCreated:`Zugangspunkt erfolgreich erstellt`,accessPointRenamed:`Zugangspunkt erfolgreich umbenannt`,accessPointDeleted:`Zugangspunkt erfolgreich gelöscht`,accessPointNameFormatTip:`Hinweis zum Zugangspunktnamen: 1-30 Zeichen. Nur Buchstaben, Zahlen, Unterstriche und Bindestriche sind erlaubt`,accessPointLimitExceeded:`Maximale Anzahl an Zugangspunkten erreicht (max. {{max}})`,tokenRotated:`Zugriffsschlüssel erfolgreich rotiert`,whatIsDoh:`Was ist DoH?`,dohDesc:`DNS over HTTPS (DoH) ist ein Protokoll zur Durchführung von DNS-Abfragen über eine verschlüsselte HTTPS-Verbindung.`,dohBenefit1:`Verhindert Manipulation und Abfangen von DNS-Verkehr durch Dritte`,dohBenefit2:`Erhöht die Sicherheit bei der DNS-Auflösung und beim Surfen im Internet`,learnMore:`Mehr erfahren`,copyUrl:`URL kopieren`,browsers:`Browser`,browserTitle:`Browser-Konfiguration (Chrome/Edge)`,browserSteps:`Einstellungen > Datenschutz und Sicherheit > Sicherheit > Sicheres DNS verwenden > Benutzerdefiniert > URL einfügen.`,browserTips:`Oder kopieren Sie diese Adresse in Ihre Adressleiste:`,apple:`Apple`,appleTitle:`macOS / iOS / iPadOS / tvOS`,appleDesc:`Apple-Geräte unterstützen die schnelle Konfiguration über Konfigurationsprofile.`,appleWarning:`Profile können nicht im "Blockierungsmodus (Lockdown Mode)" installiert werden. Bitte stellen Sie sicher, dass dieser deaktiviert ist.`,downloadConfig:`Konfigurationsprofil herunterladen`,appleInstallHint:`Gehen Sie nach dem Download zu "Einstellungen" > "Profil geladen", um das Profil zu installieren`,windows:`MS Windows`,windowsTitle:`Windows 11 Konfiguration`,windowsStep0:`Einstellungen > Netzwerk und Internet`,windowsStep1:`Eigenschaften > DNS-Serverzuweisung > Bearbeiten > Manuell.`,windowsStep2:`Wählen und tragen Sie die DNS-IPs ein:`,windowsStep3:`Aktivieren Sie DoH (Manuelle Vorlage) und fügen Sie die URL ein.`,windowsStep4:`Deaktivieren Sie das Fallback auf unverschlüsselte Verbindungen.`,android:`Android`,androidTitle:`Android / Privates DNS (DoT & DoQ)`,androidDesc:`Unterstützt natives 'Privates DNS' (DoT) des Systems oder Drittanbieter-Apps für DoH.`,androidDotTitle:`Privates DNS (DoT / DoQ)`,androidDotDesc:`Einstellungen > Netzwerk & Internet > Privates DNS > Hostname des privaten DNS-Anbieters (unterstützt auch DoQ-Clients):`,androidWildcardHint:`(Wildcard-Zertifikat, leitet zu diesem Profil weiter)`,androidSingleDomainHint:`(Einzel-Domain-Zertifikat, leitet zum Standardprofil weiter)`,androidIpNotice:`Zugriff über IP oder lokale Adresse erkannt. Android Privates DNS akzeptiert nur Domainnamen. Bitte konfigurieren Sie SERVERFULL_DOT_DOMAIN in .env (z. B. dns.example.com).`,androidWarning:`Hinweis: Das native 'Privates DNS' von Android verwendet das DoT-Protokoll. Bei Bereitstellung auf Cloudflare Workers verwenden Sie Apps wie Intra für DoH. Im Serverfull-Modus mit konfiguriertem TLS können Sie direkt den obigen DoT-Hostnamen verwenden.`,dynamicFromDomain:`Dynamisch (von "{{domain}}")`,dynamicFromDomainV6:`Dynamisch IPv6 (von "{{domain}}")`,linux:`Linux`,linuxTitle:`Linux (Cloudflared DoH-Proxy)`,linuxDesc:`Führen Sie einen lokalen DNS-Proxy aus, um DNS-Anfragen verschlüsselt über DoH an Obex weiterzuleiten.`,linuxStep1:`Führen Sie das folgende Skript aus, um cloudflared zu installieren und einen systemd-Dienst zu erstellen (hört auf 127.0.0.1:53).`,linuxStep2:`Ändern Sie die System-DNS-Adresse auf 127.0.0.1.`,routeros:`MikroTik`,routerosTitle:`MikroTik RouterOS`,routerosDesc:`Verwenden Sie diesen Resolver für alle Geräte in Ihrem Netzwerk, indem Sie ihn als DoH-Server des Routers festlegen.`,routerosStep1:`Im RouterOS-Terminal ausführen (RouterOS 7):`,routerosNote:`Vom Router weitergeleitete Anfragen erscheinen in den Protokollen als der Router, nicht als einzelne Geräte. Richten Sie Geräte direkt ein, wenn Sie Protokolle pro Gerät benötigen.`,routerosDocs:`MikroTik-DNS-Dokumentation`,accessPointsCardTitle:`Zugangspunkte`,currentAccessPoint:`Aktueller Zugangspunkt`,selectAccessPointToConfigure:`Zugangspunkt zum Konfigurieren auswählen`,quic:`QUIC & HTTP/3`,quicTitle:`DNS over QUIC (DoQ) & HTTP/3 (DoH3)`,quicDesc:`Native Unterstützung für RFC 9250 (DNS over QUIC) und RFC 9460 (HTTP/3 & Encrypted Client Hello) mit 0-RTT-Handshake und Schutz vor SNI-Inspektion.`,doqTitle:`DNS over QUIC (DoQ - RFC 9250)`,doqAppHint:`Kompatibel mit modernen Clients wie AdGuard, Clash Meta (Mihomo), Sing-box usw.:`,doqWildcardHint:`(Wildcard-Zertifikat, leitet zu diesem Profil weiter)`,doqSingleDomainHint:`(Einzeldomänen-Zertifikat, leitet zum Standardprofil weiter)`,doqIpNotice:`DoQ erfordert ein TLS-Zertifikat und einen gültigen Domänennamen. Bitte SERVERFULL_DOT_DOMAIN in .env festlegen und neu laden.`,h3Title:`HTTP/3 (DoH3) & ECH (Encrypted Client Hello)`,h3Desc:`Moderne Browser (Chrome/Firefox/Safari) verhandeln HTTP/3 und ECH-Verschlüsselung automatisch über Alt-Svc und RFC 9460 HTTPS-Einträge:`,ddrHint:`RFC 9460 Abschnitt 8 DDR (Discovery of Designated Resolvers) integriert: Clients können über _dns-Abfragen automatisch DoQ/DoT und ECH aushandeln und upgraden.`,e2eeDesc:`Verschlüsselt DNS-Protokolle direkt am Edge mit Ihrem Post-Quanten-Hybridschlüssel (P256-MLKEM768). Die Cloud kann Ihre Daten nicht einsehen; Entschlüsselung erfolgt nur lokal über Ihren Passkey.`,detecting:`Wird ermittelt...`,dotUnavailableCfTitle:`DoT / DoQ im Cloudflare Worker-Modus nicht verfügbar`,dotUnavailableCfDesc:`Wird derzeit im Cloudflare Worker-Modus ausgeführt. Aufgrund von Laufzeitbeschränkungen wird das Abhören von TCP/UDP-Port 853 nicht unterstützt. Verwenden Sie für DoT oder DoQ den Serverfull-Modus; nutzen Sie ansonsten DoH.`,privateNetwork:`Privates Netzwerk`},a={title:`Benutzerdefinierte Regeln`,subtitle:`Steuern Sie manuell die Auflösung bestimmter Domains (blockieren, zulassen oder umleiten).`,addSelfRedirectTag:`Website-Weiterleitung hinzufügen?`,addSelfRedirectPrompt:`Möchten Sie eine CNAME-Regel für diese Website zur regionalen Netzwerkoptimierung hinzufügen (empfohlen für Benutzer in Festlandchina)?`,action:`Aktion`,typeBlock:`Blockieren (BLOCK)`,typeAllow:`Zulassen (ALLOW)`,typeRedirect:`Umleiten (REDIRECT)`,pattern:`Domain-Muster (Pattern)`,patternPlaceholder:`example.com oder *.test.com`,addRule:`Regel hinzufügen`,redirectSettings:`Umleitungseinstellungen`,aRecord:`A-Eintrag (IPv4)`,aaaaRecord:`AAAA-Eintrag (IPv6)`,cnameRecord:`CNAME-Eintrag`,txtRecord:`TXT-Eintrag`,optional:`(optional)`,ipv4Placeholder:`z. B. 1.2.3.4`,ipv6Placeholder:`z. B. 2001:db8::1`,cnamePlaceholder:`z. B. ziel.com`,txtPlaceholder:`Geben Sie den Textinhalt ein...`,saveRedirectRule:`Umleitungsregel speichern und hinzufügen`,noRulesTitle:`Keine benutzerdefinierten Regeln`,noRulesDesc:`Sie haben noch keine manuellen Regeln hinzugefügt.`,tableAction:`Aktion`,tablePattern:`Muster`,tableDetails:`Auflösungsdetails`,tableOps:`Aktion`,labelBlock:`Blockieren`,labelAllow:`Zulassen`,labelRedirect:`Umleiten`,detailBlock:`Auflösen nach: `,detailAllow:`An Upstream-Server weiterleiten`,patternEmpty:`Domain-Muster darf nicht leer sein`,duplicatePattern:`Es existiert bereits eine Regel für diese Domain`,addSuccess:`Regel erfolgreich hinzugefügt`,addFailed:`Regel konnte nicht hinzugefügt werden`,updateSuccess:`Regel erfolgreich aktualisiert`,updateFailed:`Regel konnte nicht aktualisiert werden`,tableCreatedAt:`Hinzugefügt am`,clickToSort:`Klicken zum Sortieren`,editRule:`Regel bearbeiten`,cancel:`Abbrechen`,yes:`Ja`,no:`Nein`,saveChanges:`Änderungen speichern`,delete:`Löschen`,close:`Schließen`},o={customRange:`Benutzerdefinierter Zeitraum`,startTime:`Startzeit`,endTime:`Endzeit`,apply:`Anwenden`,custom:`Benutzerdefiniert`,totalQueries:`Anfragen insgesamt`,blocked:`Blockiert`,redirected:`Umgeleitet`,blockRate:`Blockierungsrate`,activeDevices:`Aktive Geräte`,activeIPs:`Aktive IP-Adressen`,queryTrend:`Abfragetrend`,noRecords:`Keine Datensätze in diesem Zeitraum`,topAllowed:`Häufen zugelassene Domains (Allowed)`,topBlocked:`Häufig blockierte Domains (Blocked)`,noData:`Keine Daten`,clientActivity:`Client-Aktivität`,ipAddress:`IP-Adresse`,location:`Standort`,queries:`Anfragen`,destinationDistribution:`Verteilung der Datenziele`,requests:`Anfragen`,topIsps:`Haupt-ISPs`,pressToShowMore:`Klicken, um mehr anzuzeigen`,maximize:`Vergrößern`,minimize:`Verkleinern`,loading:`Laden...`},s={title:`Abfrageprotokolle`,subtitle:`Überprüfen Sie die DNS-Auflösungsprotokolle und Blockierungsdatensätze für dieses Profil.`,realtime:`Echtzeit`,allStatus:`Alle Status`,onlyPass:`Zugelassen`,onlyBlock:`Blockiert`,onlyRedirect:`Umgeleitet`,searchPlaceholder:`Domains suchen...`,noResults:`Keine Ergebnisse gefunden`,noRecords:`Keine Protokolle vorhanden`,noResultsDesc:`Keine Domain-Datensätze gefunden, die "{{query}}" entsprechen.`,noRecordsDesc:`Keine DNS-Anfragen im ausgewählten Zeitraum empfangen.`,tableTime:`Zeit`,tableDomain:`Domain`,tableAnswer:`Ergebnis`,tableSource:`Quelle`,tableType:`Typ`,tableStatus:`Status`,tableReason:`Grund`,loadedAll:`Alle {{count}} Datensätze geladen`,realtimeLoadMoreTip:`Deaktivieren Sie den Echtzeitmodus, um mehr zu laden`,filterAccessPoint:`Zugangspunkt`,allAccessPoint:`Alle Zugangspunkte`,allCountry:`Alle Länder`,filterCountry:`Zielland`,allIsp:`Alle ISPs`,filterIsp:`ISP`,timeRange:`Zeitbereich`,clearFilters:`Filter löschen`,details:`Details zur Abfrage`,detailAccessPoint:`Zugangspunkt`,basicInfo:`Basisinformationen`,detailDomain:`Domain`,detailType:`Typ`,detailTime:`Zeit`,detailLatency:`Latenz`,detailProfile:`Verwendetes Profil`,detailStatus:`Status`,detailUpstream:`Upstream-Server`,detailReason:`Grund`,detailNoReason:`Keine (Zugelassen)`,detailECS:`ECS`,resolutionResult:`Auflösungsergebnis`,noResult:`Kein Ergebnis`,networkDetails:`Netzwerkdetails`,clientSource:`Client (Quelle)`,destination:`Ziel`,quickActions:`Schnellaktionen`,actionAllow:`Zulassen`,actionBlock:`Blockieren`,actionRedirect:`Umleiten`,statusPass:`Zugelassen`,statusBlock:`Blockiert`,statusRedirect:`Umgeleitet`,export:`Protokolle exportieren`,rewritten:`Umgeschrieben`,logDetails:`Protokolldetails`,searchCountry:`Länder suchen...`,noMatchingCountries:`Keine passenden Länder gefunden`,searchIsp:`ISP suchen...`,noMatchingIsps:`Keine passenden ISPs gefunden`,loadingIsps:`ISPs werden geladen...`,loggingDisabledTitle:`Protokollierung deaktiviert`,loggingDisabledDesc:`Die Protokollaufbewahrung für dieses Profil ist auf „Deaktiviert“ gesetzt. Es werden keine Protokolle aufgezeichnet. Aktivieren Sie die Protokollaufbewahrung in den Einstellungen, um Protokolle anzuzeigen.`,detailIsClientEncrypted:`Clientseitig verschlüsselt`,encryptedLocked:`Ja (Gesperrt)`,encryptedDecrypted:`Ja (Lokal entschlüsselt)`,encryptedYes:`Ja`,notEncrypted:`Nein`,encryptedRecord:`[Verschlüsselter Eintrag]`,exportSuccess:`Protokolle erfolgreich exportiert`,exportError:`Fehler beim Exportieren der Protokolle`,e2eeLockedExportWarning:`Einige Protokolle sind verschlüsselt und derzeit gesperrt; die exportierte Datei enthält möglicherweise verschlüsselte Platzhalter.`,scrollToTop:`Nach oben`},c={title:`Externe Blockierlisten`,subtitle:`Abonnieren Sie von Drittanbietern gepflegte Domain-Sperrlisten (wie AdGuard usw.).`,formatDisclaimer:`Dieses System unterstützt nur grundlegende AdGuard-Formate und reine Domain-Listen. Nur grundlegende Blockierungsregeln (z. B. ||example.com^) werden unterstützt; "@@"-Ausnahmen, "$"-Umschreibungen und "*"-Wildcards werden ignoriert. Subdomains werden automatisch zugeordnet.`,syncAll:`Alle Listen synchronisieren`,urlPlaceholder:`Listen-URL eingeben...`,addSubscription:`Abonnement hinzufügen`,supportedFormats:`Unterstützte Listenformate:`,formatAdGuard:`Kompatibel mit ||domain.com^ Filterregeln.`,formatHosts:`Kompatibel mit standardmäßigen hosts-Dateien (z. B. 0.0.0.0 domain.com).`,noListsTitle:`Keine Listen hinzugefügt`,noListsDesc:`Sie haben noch keine externen Blockierlisten abonniert.`,tableUrl:`Listen-URL`,tableLastSync:`Letzte Synchronisierung`,tableStatus:`Status`,tableOps:`Aktion`,neverSynced:`Nie`,enabled:`Aktiv`,disabled:`Synchronisierung fehlgeschlagen`,statusNormal:`Normal`,statusDisabled:`Deaktiviert`,statusOutdated:`Veraltet`,statusMissing:`Fehlend`,presetOisdBig:`OISD Big (Werbung/Malware-Blockierung)`,presetOisdNsfw:`OISD NSFW (Pornografie/Erwachseneninhalte)`,presetAdGuard:`AdGuard AdServers (Werbeserver)`,presetStevenBlack:`StevenBlack Hosts (All-in-One-Blocker)`,syncTaskStarted:`Synchronisierungsaufgabe gestartet`,syncCheckComplete:`Synchronisierungsprüfung abgeschlossen`,syncTaskFailed:`Synchronisierung fehlgeschlagen`,syncing:`Wird synchronisiert...`,syncSuccess:`Synchronisierung erfolgreich`,syncError:`Synchronisierung fehlgeschlagen`,syncErrorDesc:`Die Blockierliste konnte nicht heruntergeladen oder analysiert werden. Bitte überprüfen Sie den Link und die Erreichbarkeit.`,deleteConfirm:`Abonnement wirklich löschen?`,deleteSuccess:`Liste erfolgreich gelöscht`,deleteError:`Liste konnte nicht gelöscht werden`,addSuccess:`Liste erfolgreich hinzugefügt`,addError:`Liste konnte nicht hinzugefügt werden`,listEnabled:`Liste aktiv`,listEnabledHint:`Deaktivieren, um die Filterung mit dieser Liste zu stoppen, ohne sie zu löschen. Abonnement und Synchronisierungsverlauf bleiben erhalten.`,listEnabledToast:`Liste aktiviert - Filter wird neu erstellt`,listDisabledToast:`Liste deaktiviert - Filter wird neu erstellt`,checkDomain:`Domain prüfen`,checkDomainHint:`Listen werden als kompakte Filter gespeichert, ihre Einträge können daher nicht durchsucht werden. Sie können jede Domain sofort gegen diese Liste testen.`,check:`Prüfen`,checkBlocked:`Von dieser Liste blockiert`,checkNotBlocked:`Nicht von dieser Liste blockiert`,checkViaParent:`(Treffer über eine übergeordnete Domain)`,checkNotSynced:`Diese Liste ist noch nicht fertig synchronisiert, es gibt daher nichts zu prüfen.`,checkListDisabled:`Diese Liste ist derzeit deaktiviert und filtert daher gerade nichts.`,checkProbabilisticRate:`Filter sind probabilistisch: etwa 1 von {{odds}} Treffern ist ein Fehlalarm. Eine Ausnahme deckt auch alle Subdomains ab.`,checkProbabilistic:`Filter sind probabilistisch, ein kleiner Teil der Treffer ist daher ein Fehlalarm. Eine Ausnahme deckt auch alle Subdomains ab.`,checkAllowAction:`Trotzdem zulassen`,checkAllowed:`Ausnahme hinzugefügt - diese Domain wird jetzt aufgelöst`,allowRuleAdded:`Ausnahme für {{domain}} hinzugefügt`,listDetails:`Listen-Details`},l={title:`Profileinstellungen`,subtitle:`Verwalten Sie Ihre DNS-Auflösungsstrategie und erweiterte Optionen.`,saveChanges:`Alle Änderungen speichern`,saveSuccess:`Einstellungen erfolgreich gespeichert`,saveError:`Speichern der Einstellungen fehlgeschlagen. Bitte versuchen Sie es später noch einmal`,upstreamTitle:`Upstream-Server`,dohUrl:`DoH-URL`,dnsIP:`DNS-IP`,classicDns:`Klassisches DNS`,httpsOnly:`Nur HTTPS unterstützen`,upstreamDesc:`Alle nicht blockierten Anfragen werden an diesen Server weitergeleitet. Unterstützt DoH (HTTPS), DoT (tls://), DNS Stamp (sdns://) oder klassisches DNS. Klassisches DNS wird über TCP weitergeleitet.`,defaultPolicyTitle:`Standard-Filterverhalten`,onNoMatch:`Wenn keine Regel zutrifft`,allowAll:`Alle Abfragen zulassen`,blockAll:`Alle Abfragen blockieren`,logRetentionTitle:`Protokollaufbewahrung`,retentionDuration:`Aufbewahrungsdauer`,retentionDesc:`Protokolle werden automatisch bereinigt. `,skipLogOnPass:`Erlaubte Abfragen nicht protokollieren`,skipLogOnPassDesc:`Wenn aktiviert, werden normal erlaubte Abfragen nicht protokolliert. Nur blockierte, umgeleitete oder fehlgeschlagene Abfragen werden gespeichert.`,ecsTitle:`EDNS Client Subnet (ECS)`,ecsUpstreamHint:`Nicht alle vorgelagerten DNS-Server unterstützen ECS. Bei rekursiven Resolvern wie ControlD beeinflusst ECS nur das interne Routing und wird nicht an den autoritativen Server weitergegeben.`,sendEcs:`ECS mitsenden`,customSubnet:`Benutzerdefiniertes Subnetz`,customIpv4:`Benutzerdefiniertes IPv4-Subnetz`,customIpv6:`Benutzerdefiniertes IPv6-Subnetz`,ipv4Hint:`(z. B. 1.2.3.0/24)`,ipv6Hint:`(z. B. 2001:db8::/32)`,testToolTitle:`Echtzeit-Auflösungstest-Tool`,testDomain:`Test-Domain`,recordType:`Eintragstyp`,runTest:`Test ausführen`,domainPlaceholder:`z. B. google.com`,hitRule:`Getroffene Regel / Grund`,defaultAllow:`Standard-Zulassungsrichtlinie`,parseLatency:`Auflösungslatenz`,sourceIp:`Quell-IP-Adresse`,answerSection:`Antwortbereich (Answer Section)`,noRecordsReturned:`Diese Abfrage hat keine Datensätze zurückgegeben.`,diagnostics:`Diagnoseinformationen`,errorDetail:`Fehlerdetails`,upstreamResponse:`Upstream-Antwort`,presetCloudflareSecurity:`Cloudflare Security (Schnell/Schutz vor Schadsoftware/Phishing)`,presetCloudflareFamilies:`Cloudflare Families (Schnell/Schutz vor Schadsoftware/Erwachseneninhalten)`,presetQuad9:`Quad9 (Schutz vor Schadsoftware/Keine Protokolle/Ohne ECS)`,presetQuad9Ecs:`Quad9 ECS (Schutz vor Schadsoftware/Keine Protokolle/Mit ECS)`,presetControlDFree:`ControlD Free (Schutz vor Werbung/Trackern/Schadsoftware/Phishing)`,presetControlDUncensored:`ControlD Uncensored (Gegen Zensur)`,presetAdGuard:`AdGuard (Werbe- und Tracker-Blocker)`,presetAdGuardFamily:`AdGuard Family protection (Werbung/Tracker/Erwachseneninhalte/Sichere Suche)`,retention10m:`10 Minuten`,retention1h:`1 Stunde`,retention24h:`24 Stunden`,retention7d:`7 Tage`,retention30d:`30 Tage`,retention90d:`90 Tage`,retention180d:`180 Tage`,retention360d:`360 Tage`,retentionMaxSuffix:`(Maximum)`,daysUnit:`Tage`,blockModeTitle:`Blockierungs-Antwortmodus`,blockModeDesc:`Rückgabeinhalt bei Blockierung einer Domain`,default:`Standard`,NXDOMAIN:`NXDOMAIN (Domain existiert nicht)`,NODATA:`NODATA (Keine Daten)`,customIP:`Benutzerdefinierte IP`,export:`Konfiguration exportieren`,exportSuccess:`Konfiguration erfolgreich exportiert`,exportError:`Konfigurationsexport fehlgeschlagen. Bitte versuchen Sie es später noch einmal`,nameUpdateSuccess:`Profilname aktualisiert`,saving:`Speichern...`,echTitle:`ECH umschreiben`,enableEch:`ECH-Umschreibung aktivieren`,echDesc:`Für über Cloudflare geleitete Domains werden ECH-Parameter und äußere SNI bei HTTPS- (Typ 65) / SVCB- (Typ 64) Abfragen automatisch umgeschrieben, um die Privatsphäre zu schützen.`,echFrontingTitle:`Äußerer SNI (ECH Fronting)`,echFrontingDesc:`Im Klartext sichtbarer Domainname im äußeren TLS-Handshake`,echFrontingCustomPlaceholder:`Benutzerdefinierte Fronting-Domain eingeben, z.B. crypto.cloudflare.com`,echPreferred:`Empfohlen`,whatIsEch:`Was ist ECH (Encrypted Client Hello)?`,echHelpDesc:`ECH ist eine wichtige TLS 1.3-Datenschutzerweiterung, die die eigentliche Domain (Inner SNI) vollständig verschlüsselt und nach außen nur eine Tarn-Domain (Outer SNI) anzeigt.`,echHelpBenefit1:`Verhindert, dass ISPs und Dritte die aufgerufene Domain oder Subdomain mitlesen`,echHelpBenefit2:`Eliminiert zusammen mit DoH das Risiko von Klartext-SNI-Blockaden`,retentionDisabled:`Deaktiviert (Datenschutz erforderlich)`,retentionDisabledDesc:`Protokollierung ist deaktiviert. Das System zeichnet keine DNS-Abfrageprotokolle auf und löscht historische Protokolle sofort.`,localRetentionTitle:`Lokale Speicherung & Aufbewahrung`,localRetentionDuration:`Lokale Aufbewahrungsdauer`,localRetentionDesc:`Protokolle werden persistent in der lokalen SQLite-Datenbank Ihres Browsers (OPFS) gespeichert, um sekundenschnelle lokale Suchläufe zu ermöglichen und Cloud-Speicherkosten zu sparen. Ältere lokale Protokolle werden automatisch gelöscht.`,localRetention30d:`30 Tage`,localRetention90d:`90 Tage (Empfohlen)`,localRetention180d:`180 Tage`,localRetention365d:`365 Tage (1 Jahr)`,localRetentionUnlimited:`Unbegrenzt (Bis manuell gelöscht)`,localEngineStorage:`Speicher-Engine`,localEngineOpfs:`OPFS Persistent`,localEngineMemory:`Arbeitsspeicher temporär (Privater Modus)`,localCachedCount:`Lokal zwischengespeicherte Protokolle`,localCachedCountUnit:`{{count}} Einträge`,clearLocalData:`Lokale Protokolle leeren`,clearLocalDataConfirm:`Möchten Sie wirklich alle lokal gespeicherten Protokolle für dieses Profil löschen? (Cloud-Protokolle bleiben unberührt)`,clearLocalDataSuccess:`Lokale Protokolle wurden erfolgreich gelöscht`,clearLocalDataError:`Löschen der lokalen Protokolle fehlgeschlagen`,e2eeTitle:`Ende-zu-Ende-Verschlüsselung (E2EE)`,e2eeEnabled:`Aktiviert`,e2eeDisabled:`Deaktiviert`,e2eeDesc:`Verschlüsselt DNS-Protokolle direkt am Edge mit Ihrem Post-Quanten-Hybridschlüssel (P256-MLKEM768). Die Cloud kann Ihre Daten nicht einsehen; Entschlüsselung erfolgt nur lokal über Ihren Passkey.`,e2eePasskeyRequired:`E2EE erfordert einen Hardware-Passkey (WebAuthn). Bitte fügen Sie zuerst einen Passkey in den Kontoeinstellungen hinzu.`,e2eeGoToAccount:`Zu den Kontoeinstellungen`,e2eeEnableSwitch:`Protokoll-E2EE aktivieren`,e2eeKeyType:`Verschlüsselungsalgorithmus`,e2eeDeviceState:`Gerätestatus`,e2eeUnlocked:`Auf diesem Gerät entsperrt`,e2eeUnlockButton:`Mit Passkey entsperren`,e2eeProtectedPasskeys:`Autorisierte Passkeys`,e2eeDevicesUnit:`Gerät(e)`,e2eeEnableSuccess:`E2EE erfolgreich aktiviert`,e2eeEnableError:`Aktivierung von E2EE fehlgeschlagen`,e2eeDisableSuccess:`E2EE deaktiviert`,e2eeDisableError:`Deaktivierung von E2EE fehlgeschlagen`,e2eeUnlockSuccess:`Schlüssel auf diesem Gerät entsperrt`,e2eeUnlockError:`Entsperrung mit Passkey fehlgeschlagen`,e2eeDisableConfirm:`Möchten Sie E2EE wirklich deaktivieren? Zukünftige Protokolle werden im Klartext gespeichert.`,e2eeUnlockPrompt:`Dieses Profil ist Ende-zu-Ende verschlüsselt. Entsperren Sie es mit Ihrem Passkey.`,e2eeUnlockNow:`Protokolle entsperren`,e2eeUnlockRecovery:`Mit Wiederherstellungsschlüssel entsperren`,securityTitle:`Sicherheit & Zugriff`,rotateKeyTitle:`Zugriffs-URL`,rotateKeyDesc:`Generiert eine neue Zugriffs-URL für dieses Profil. Alle Geräte, die die alte URL verwenden, verlieren sofort die Verbindung zu DNS Worker und müssen mit der neuen URL neu konfiguriert werden.`,rotateKeyBtn:`URL rotieren`,copied:`In die Zwischenablage kopiert`,nameUpdateFailed:`Aktualisierung fehlgeschlagen`},u=JSON.parse(`{"title":"Kontoeinstellungen","subtitle":"Verwalten Sie Ihre Sicherheitsanmeldedaten und Systembenutzer.","e2ee":{"title":"Ende-zu-Ende-Verschlüsselung (E2EE)","desc":"Sichert Ihre sensiblen Daten mit Post-Quanten-Hybrid-Umschlagverschlüsselung (P256-MLKEM768 + AES-256-GCM / NIST FIPS 203) über Hardware-Passkeys. Am Edge verschlüsselt; nur autorisierte Geräte können lokal entschlüsseln.","pqcTag":"PQC / NIST FIPS 203","upgradePqcBtn":"Auf Post-Quanten (PQC) aktualisieren","upgradePqcSuccess":"Erfolgreich auf Post-Quanten-Hybridverschlüsselung (P256-MLKEM768) aktualisiert","upgradePqcError":"Upgrade auf Post-Quanten-Verschlüsselung fehlgeschlagen","enabled":"Aktiviert","disabled":"Deaktiviert","passkeyRequired":"Ende-zu-Ende-Verschlüsselung erfordert mindestens einen Hardware-Passkey (WebAuthn). Bitte fügen Sie zuerst einen Passkey in den MFA-Einstellungen hinzu.","scopesTitle":"Verschlüsselte Datenkategorien","scopesSubtitle":"Wählen Sie, welche Datenkategorien mit Ihrem Hardware-Passkey Ende-zu-Ende verschlüsselt werden sollen.","scopeLogsTitle":"DNS-Abfrageprotokolle","scopeLogsDesc":"Verschlüsselt Domainnamen, Client-IPs, Antworteinträge und Upstream-Latenzen am Edge vor dem Speichern in D1.","scopeRulesTitle":"Benutzerdefinierte Regeln & Weiterleitungen","scopeRulesDesc":"Clientseitig verschlüsselte benutzerdefinierte Blockier-/Erlaubnisregeln und Weiterleitungskonfigurationen.","scopeClientsTitle":"Client- & Gerätemetadaten","scopeClientsDesc":"Gerätealiase, Zugangspunktbezeichner und Netzwerktopologie-Metadaten.","statusActive":"Geschützt","statusPlanned":"Geplant","profileSelect":"Profil konfigurieren","keyType":"Verschlüsselungsalgorithmus","deviceState":"Aktueller Gerätestatus","unlocked":"Auf diesem Gerät entsperrt","unlockButton":"Mit Passkey entsperren","protectedPasskeys":"Autorisierte Passkey-Anmeldedaten","devicesUnit":"Anmeldedaten","enableSuccess":"Ende-zu-Ende-Verschlüsselung erfolgreich aktiviert","enableError":"Aktivierung der Ende-zu-Ende-Verschlüsselung fehlgeschlagen","disableSuccess":"Ende-zu-Ende-Verschlüsselung deaktiviert","disableError":"Deaktivierung der Ende-zu-Ende-Verschlüsselung fehlgeschlagen","unlockSuccess":"Privater Schlüssel auf diesem Gerät erfolgreich entsperrt","unlockError":"Entsperrung mit Passkey fehlgeschlagen","disableConfirm":"Möchten Sie die Ende-zu-Ende-Verschlüsselung für dieses Profil wirklich deaktivieren? Zukünftige Protokolle werden im Klartext gespeichert. (Historische verschlüsselte Protokolle erfordern weiterhin den privaten Schlüssel)","noKeypairTitle":"Ende-zu-Ende-Schlüsselpaar nicht initialisiert","noKeypairDesc":"Ende-zu-Ende-Verschlüsselung erfordert die Erstellung eines Post-Quanten-Schlüsselpaars (P256-MLKEM768) für Ihr Konto. Der private Schlüssel wird über Ihren Passkey oder Wiederherstellungsschlüssel geschützt.","initPasskeyBtn":"Vorhandenen Passkey bestätigen, um Schlüsselpaar zu generieren","addPasskeyBtn":"Passkey hinzufügen, um Hardware-Verschlüsselung zu unterstützen","initRecoveryBtn":"Schlüsselpaar mit Wiederherstellungsschlüssel generieren","initWithRecoveryTitle":"Schlüsselpaar mit Wiederherstellungsschlüssel generieren","initWithRecoveryDesc":"Geben Sie Ihren aktuellen 30-stelligen Wiederherstellungsschlüssel ein. Das System erzeugt lokal ein Post-Quanten-Schlüsselpaar (P256-MLKEM768) und verschlüsselt es. Der Wiederherstellungsschlüssel wird sofort automatisch erneuert.","keypairGenSuccess":"Ende-zu-Ende-Schlüsselpaar erfolgreich generiert!","keypairGenError":"Generierung des Schlüsselpaars fehlgeschlagen","unlockRecoveryButton":"Mit Wiederherstellungsschlüssel entsperren","unlockWithRecoveryTitle":"Mit Wiederherstellungsschlüssel entsperren","unlockWithRecoveryDesc":"Geben Sie Ihren 30-stelligen Notfallschlüssel ein. Hinweis: Nach erfolgreicher Verifizierung wird der Schlüssel sofort automatisch erneuert.","recoveryKeyInputLabel":"Wiederherstellungsschlüssel","unlockConfirm":"Privaten Schlüssel entsperren","recoveryUnlockFailed":"Ungültiger Wiederherstellungsschlüssel oder Entschlüsselung fehlgeschlagen","generateKeypairBtn":"Schlüsselpaar generieren","enableSwitch":"Ende-zu-Ende-Verschlüsselung für Abfrageprotokolle aktivieren","enableSwitchDesc":"Verschlüsselt Domainnamen, Client-IPs, Antwortdatensätze und Upstream-Latenzen am Edge vor dem Speichern in der Cloud.","trustBoundaryTitle":"Sicherheits- und Vertrauensgrenzenhinweis","trustBoundaryDesc":"Der gesamte DNS-Abfrageverkehr läuft während der Auflösung zwangsläufig über den Hosting-Server (Cloudflare Workers Edge-Knoten oder Server-Runtime), wo Abfragen im Speicher verarbeitet und anschließend verschlüsselt gespeichert werden. Diese Funktion schützt ruhende Daten in der Cloud-Datenbank (D1 / Persistenzspeicher) vor Datenlecks; sie verbirgt den aktiven Netzwerkverkehr nicht vor dem verarbeitenden Hosting-Server.","initFailed":"Initialisierung der Ende-zu-Ende-Verschlüsselung fehlgeschlagen","lockDevice":"Dieses Gerät sperren","lockSuccess":"Gesperrt, privater Schlüssel wurde aus dem lokalen Speicher gelöscht","enrollPasskeyBtn":"Aktuellen Passkey verknüpfen","enrollPasskeySuccess":"Passkey erfolgreich mit E2EE verknüpft!","enrollPasskeyFailed":"Passkey-Verknüpfung fehlgeschlagen","resetKeypairBtn":"Schlüsselpaar zurücksetzen","confirmResetBtn":"Zurücksetzen & neu generieren bestätigen","resetKeypairTitle":"E2EE-Schlüsselpaar zurücksetzen","resetKeypairDesc":"Wenn Ihr Wiederherstellungsschlüssel nicht übereinstimmt oder nicht entschlüsselt werden kann und kein Passkey verknüpft ist, löscht das Zurücksetzen alte Schlüssel vom Server und generiert ein brandneues Post-Quanten-Schlüsselpaar (P256-MLKEM768).","resetKeypairPasskeyNotice":"Nach Bestätigung wird Ihr konfigurierter Passkey sofort aufgerufen, um das neue Schlüsselpaar zu verschlüsseln und zu autorisieren.","resetKeypairRecoveryNotice":"Nach Bestätigung werden Sie aufgefordert, Ihren aktuellen Wiederherstellungsschlüssel einzugeben, um das neue Schlüsselpaar zu generieren und zu verschlüsseln.","resetAndInitPasskeySuccess":"Schlüsselpaar erfolgreich zurückgesetzt und mit Passkey neu verschlüsselt!","resetSuccessEnterRecovery":"Alte Schlüssel gelöscht. Bitte initialisieren Sie ein neues Schlüsselpaar mit Ihrem Wiederherstellungsschlüssel.","resetFailed":"Zurücksetzen des Schlüsselpaars fehlgeschlagen"},"jwtSecretWarningTitle":"Sicherheitshinweis: Schwaches JWT-Secret","jwtSecretWarningDesc":"Das aktuelle JWT_SECRET ist kürzer als 32 Zeichen, was potenzielle Sicherheitsrisiken birgt. Bitte konfigurieren Sie die Umgebungsvariable KEK_v1, bevor Sie JWT_SECRET rotieren, um sicherzustellen, dass vorhandene Umschlag-verschlüsselte TOTP- und Wiederherstellungsschlüssel entschlüsselbar bleiben.","roleAdmin":"Systemadministrator","roleUser":"Benutzer","personalInfo":"Persönliche Informationen","username":"Benutzername","userId":"Benutzer-ID","changePassword":"Kennwort ändern","currentPassword":"Aktuelles Kennwort","newPassword":"Neues Kennwort","updatePassword":"Kennwort aktualisieren","userManagement":"Benutzerverwaltung (nur Admins)","createUser":"Benutzer erstellen","role":"Rolle","createdAt":"Erstellt am","lastActive":"Zuletzt aktiv am","lastResolve":"Letzte DNS-Auflösung am","actions":"Aktionen","dangerZone":"Gefahrenbereich","clearLogs":"Alle Protokolle löschen","clearLogsDesc":"Dadurch werden alle DNS-Abfrageprotokolle gelöscht, die unter Ihren Profilen generiert wurden. Diese Aktion ist unumkehrbar.","clearLogsBtn":"Protokolle jetzt löschen","deleteAccount":"Konto löschen","deleteAccountDesc":"Löschen Sie Ihr Konto und alle damit verbundenen Daten dauerhaft. Sie verlieren den Zugriff auf alle Ihre DNS-Konfigurationen.","deleteAccountBtn":"Konto dauerhaft löschen","createNewUser":"Neuen Benutzer erstellen","initialPassword":"Initiales Passwort","userRole":"Benutzerrolle","cancel":"Abbrechen","yes":"Ja","no":"Nein","createNow":"Jetzt erstellen","formatTipUsername":"Hinweis zum Benutzernamen: Nur 5 bis 32 Zeichen, Unix-Benutzername-Format","formatTipPassword":"Hinweis zum Passwort: 12-100 Zeichen.","passwordSuccess":"Passwort erfolgreich geändert","updateFailed":"Aktualisierung fehlgeschlagen","confirmDeleteUser":"Sind Sie sicher, dass Sie diesen Benutzer löschen möchten? Alle dem Benutzer gehörenden Profile werden ebenfalls entfernt.","confirmClearLogs":"Sind Sie sicher, dass Sie alle Abfrageprotokolle unter Ihren Profilen löschen möchten? Dies kann nicht rückgängig gemacht werden.","clearLogsSuccess":"Protokolle erfolgreich gelöscht","confirmDeleteAccount":"WARNUNG: Sind Sie sicher, dass Sie Ihr Konto löschen möchten?\\n\\nAlle Ihre DNS-Konfigurationen, benutzerdefinierten Regeln und Abfrageprotokolle werden dauerhaft gelöscht. Diese Aktion kann nicht rückgängig gemacht werden!","inactivityPolicy":"Inaktivitätsrichtlinie","inactivityDesc":"Zum Schutz der Privatsphäre und zur Ressourcenschonung werden alle Abfrageprotokolle und DNS-Konfigurationen von Konten, die seit 30 Tagen keine DNS-Auflösung durchgeführt haben, automatisch gelöscht. Das Konto selbst wird nach 90 Tagen ohne Anmeldung gelöscht.","systemSettings":"Systemeinstellungen (nur Admins)","adminOnlyView":"Nur für Administratoren sichtbar","featureToggle":"Funktionsschalter","enableTurnstileSignup":"Captcha auf Registrierungsseite aktivieren","enableTurnstileLogin":"Captcha auf Anmeldeseite aktivieren","totp":{"title":"Authentifikator-App (TOTP)","enabled":"Aktiviert","disabled":"Deaktiviert","setupDesc":"Fügen Sie Ihrem Konto eine zusätzliche Sicherheitsebene hinzu. Verwenden Sie Google Authenticator, Authy oder eine andere TOTP-kompatible App.","setupBtn":"Authentifikator-App (TOTP) einrichten","scanQR":"Scannen Sie diesen QR-Code mit Ihrer Authentifikator-App:","orEnterManually":"Oder geben Sie den Schlüssel manuell ein:","enterCode":"Geben Sie den Code aus Ihrer App zur Bestätigung ein:","enterCodeHint":"Geben Sie den 6-stelligen Code ein, um die korrekte Einrichtung des Schlüssels zu bestätigen.","activate":"TOTP aktivieren","skipPassword":"Passwortloses Anmelden – Nur TOTP-Code bei der Anmeldung anfordern (Passworteingabe überspringen)","disable":"Authentifikator-App (TOTP) deaktivieren","disableTitle":"Authentifikator-App (TOTP) deaktivieren","disableWarning":"Nach dem Deaktivieren von TOTP wird Ihr Konto, sofern keine Passkeys eingerichtet sind, nur noch durch ein Passwort geschützt.","confirmDisable":"TOTP deaktivieren","recoveryKeysTitle":"Bitte speichern Sie Ihre Wiederherstellungsschlüssel","recoveryKeysWarning":"Bitte bewahren Sie den Wiederherstellungsschlüssel an einem sicheren Ort auf (z. B. Passwort-Manager). Jeder Schlüssel kann nur einmal verwendet werden.","copyKeys":"Alle Schlüssel kopieren","copied":"Kopiert!","done":"Fertig, ich habe die Schlüssel gespeichert","activeDesc":"Die Authentifikator-App (TOTP) ist aktiv und generiert 6-stellige Bestätigungscodes.","invalidCode":"Bitte geben Sie einen 6-stelligen Code ein","testBtn":"Code testen","testTitle":"Authentifikator-App testen (TOTP)","testDesc":"Geben Sie den 6-stelligen Bestätigungscode aus Ihrer Authentifikator-App ein, um zu prüfen, ob sie ordnungsgemäß synchronisiert ist und gültige Codes generiert.","testSuccess":"Verifizierung erfolgreich! Ihre Authentifikator-App ist ordnungsgemäß konfiguriert.","testFailed":"Ungültiger Bestätigungscode oder nicht synchronisierte Uhrzeit","verificationCode":"6-stelliger Bestätigungscode","verifyBtn":"Jetzt bestätigen","enterPassword":"Geben Sie zur Bestätigung Ihr Kennwort ein:","passwordPlaceholder":"Kontokennwort"},"activity":{"title":"Aktivitätsprotokoll des Kontos","action":"Ereignis","time":"Zeit","ip":"IP-Adresse","session":"Sitzung","empty":"Keine Aktivitäten aufgezeichnet.","loadMore":"Mehr laden","signup":"Registrieren","loginSuccess":"Anmeldung erfolgreich","loginFail":"Anmeldung fehlgeschlagen","logout":"Abmelden","pwChangeSuccess":"Passwort geändert","pwChangeFail":"Passwortänderung fehlgeschlagen","totpVerifySuccess":"TOTP-Verifizierung erfolgreich","totpVerifyFail":"TOTP-Verifizierung fehlgeschlagen","totpSetup":"TOTP-Authentifikator eingerichtet","totpRemoved":"TOTP-Authentifikator entfernt","recoveryKeyUsed":"Wiederherstellungsschlüssel verwendet","sessionRevoked":"Sitzung widerrufen","reasons":{"user_active":"Aktive Abmeldung","user_revoke":"Sitzung widerrufen","expired":"Sitzung abgelaufen","geolocation_mismatch":"Geografische Abweichung (Zugriffsbeschränkung)","geolocation_missing":"Fehlende geografische Informationen","token_reuse":"Wiederverwendung von Tokens (Sicherheitswarnung)"},"passkeyRegistered":"Passkey registriert","passkeyDeleted":"Passkey gelöscht","passkeyVerifySuccess":"Passkey verifiziert","passkeyVerifyFail":"Passkey-Verifizierung fehlgeschlagen","recoveryKeyRotated":"Wiederherstellungsschlüssel erneuert","device":"Gerät"},"sessions":{"title":"Aktive Sitzungen","session":"Sitzung","device":"Gerät","ip":"IP-Adresse","loginTime":"Anmeldezeit","expires":"Gültig bis","action":"Aktion","current":"Aktuell","revoke":"Widerrufen","revokeFailed":"Sitzung konnte nicht widerrufen werden.","empty":"Keine aktiven Sitzungen gefunden.","unknownDevice":"Unbekanntes Gerät","revokeOthers":"Andere Sitzungen widerrufen","confirmRevokeOthers":"Andere Sitzungen widerrufen","revokeOthersConfirmText":"Möchten Sie wirklich alle anderen aktiven Sitzungen widerrufen? Alle anderen angemeldeten Geräte werden sofort abgemeldet."},"passkey":{"title":"Passkeys","addBtn":"Passkey hinzufügen","desc":"Verwenden Sie Biometrie (Touch ID, Face ID, Windows Hello) oder Sicherheitsschlüssel (YubiKey) für schnelle, phishing-resistente MFA.","empty":"Noch keine Passkeys hinzugefügt.","addTitle":"Passkey hinzufügen","nameLabel":"Passkey-Name","namePlaceholder":"z. B. my_passkey","promptNotice":"Nach dem Klick auf Weiter fordert Ihr Browser Sie auf, die Registrierung per Biometrie oder Sicherheitsschlüssel abzuschließen.","continue":"Weiter","renameTitle":"Passkey umbenennen","deleteTitle":"Passkey löschen","deleteConfirm":"Sind Sie sicher, dass Sie den Passkey \\"{{name}}\\" löschen möchten? Sie können ihn danach nicht mehr zur Authentifizierung verwenden.","defaultName":"Passkey","notSupported":"Ihr Browser oder Ihre aktuelle Umgebung unterstützt keine Passkeys (WebAuthn).","regFailed":"Passkey-Registrierung fehlgeschlagen","count":"{{count}} konfiguriert","none":"Nicht konfiguriert","created":"Erstellt","lastUsed":"Zuletzt verwendet","neverUsed":"Noch nie verwendet","updated":"Passkey erfolgreich aktualisiert","registered":"Passkey erfolgreich registriert","deleted":"Passkey gelöscht","appNameLabel":"Domain","appNameHelper":"Der Passkey wird an diese Domain gebunden","formatTip":"Hinweis zum Passkey-Namen: 1-30 Zeichen, nur Buchstaben, Zahlen, Unterstriche und Bindestriche erlaubt","verifyPrompt":"Bestätigen Sie mit Biometrie (Touch ID, Face ID, Windows Hello) oder Sicherheitsschlüssel.","changePwNotice":"Beim Absenden werden Sie zur Bestätigung über Passkey aufgefordert.","submitNotice":"Beim Absenden werden Sie zur Bestätigung über Passkey aufgefordert.","testBtn":"Passkey testen","testThis":"Diesen Passkey testen","testSuccess":"Passkey erfolgreich verifiziert: {{name}}","testCancelled":"Passkey-Verifizierung abgebrochen","testFailed":"Passkey-Verifizierung fehlgeschlagen"},"mfaNone":"Keine","resetUserPassword":"Passwort zurücksetzen","resetPasswordTitle":"Benutzerpasswort zurücksetzen","resetPasswordWarning":"Nach dem Zurücksetzen werden alle aktiven Sitzungen dieses Benutzers sofort beendet.","resetPasswordSuccess":"Passwort erfolgreich zurückgesetzt. Alle aktiven Sitzungen wurden beendet.","confirmReset":"Zurücksetzen bestätigen","mfa":{"title":"Multi-Faktor-Authentifizierung (MFA)","enabled":"Konfiguriert","notConfigured":"Nicht konfiguriert","desc":"Passkeys und Authentifikator-Apps (TOTP) dienen als MFA-Methoden. Die Konfiguration mindestens eines Faktors schützt Ihr Konto und ermöglicht passwortlose Anmeldung.","passwordlessTitle":"Passwortlose Anmeldung","passwordlessDesc":"Bei Aktivierung wird die Passworteingabe übersprungen und Ihre Identität direkt per Passkey oder TOTP geprüft.","unconfiguredHint":"Noch keine MFA konfiguriert. Richten Sie unten einen Passkey oder eine Authentifikator-App ein.","password":"Passwort","passkey":"Passkey","totp":"TOTP"},"recoveryKey":{"title":"Notfall-Wiederherstellungsschlüssel","desc":"Ein Notfall-Wiederherstellungsschlüssel ermöglicht Ihnen den Zugriff oder das Zurücksetzen Ihres Passworts, falls Sie alle registrierten Passkeys oder Authentifikatoren verlieren. Aus Zero-Knowledge-Sicherheitsgründen wird der Schlüssel als kryptografischer Einweg-Hash gespeichert und kann im Web nicht im Klartext angezeigt werden. Nach jeder Verwendung wird er automatisch sofort erneuert.","configured":"Konfiguriert","notConfigured":"Nicht konfiguriert","rotateBtn":"Wiederherstellungsschlüssel erneuern","yourKey":"Ihr 30-stelliger Wiederherstellungsschlüssel","securityTip":"Halten Sie diesen Schlüssel geheim. Jeder mit Zugriff darauf kann Zugriff auf Ihr Konto erlangen.","rotateConfirm":"Das Erneuern macht den aktuellen Schlüssel sofort ungültig. Die Verifizierung ist nur über vorhandene Passkeys oder den Originalschlüssel möglich. Fortfahren?","confirmRotateBtn":"Mit Erneuerung fortfahren","rotateVerifyTitle":"Identität zur Erneuerung bestätigen","rotateSuccess":"Wiederherstellungsschlüssel erfolgreich erneuert! Bitte sichern Sie den neuen Schlüssel sofort offline.","oneWayHash":"Kryptografischer Einweg-Hash","oneWayTooltip":"Geschützt mit SHA-256-Einweg-Hash. Der Server speichert keinen Klartext und kann ihn nicht entschlüsseln.","newKeyGenerated":"Neuer 30-stelliger Wiederherstellungsschlüssel generiert (Jetzt sichern)","oneWayWarning":"Hinweis: Dieser Schlüssel wird NUR EINMAL angezeigt. Der Server speichert nur einen irreversiblen Hash. Bitte kopieren und offline sicher aufbewahren!","autoRotatedTitle":"Wiederherstellungsschlüssel automatisch erneuert","autoRotatedNotice":"Gemäß der Einmalverwendungsregel wurde Ihr bisheriger Schlüssel ungültig und ein neuer 30-stelliger Schlüssel generiert. Bitte sofort kopieren und sicher aufbewahren!","savedAndClose":"Ich habe ihn gesichert und fortfahren","savedAndContinue":"Ich habe ihn gesichert und weiter zum Dashboard","descOneWay":"Der Notfall-Wiederherstellungsschlüssel ist der einzige Nachweis zur Wiederherstellung des Kontozugriffs und zur Entschlüsselung von E2EE-Daten bei Verlust aller Passkeys oder Authentifikatoren. Zur Gewährleistung von Zero-Knowledge-Sicherheit wird er als irreversibler Einweghash gespeichert und kann im Web nicht im Klartext eingesehen werden. Eine Rotation ist nur mit dem bisherigen Schlüssel oder einem Passkey möglich. Nach der Verwendung wird er automatisch rotiert.","keyRequired":"Wiederherstellungsschlüssel ist erforderlich","verifyBtn":"Wiederherstellungsschlüssel","verifyPromptLabel":"Bisheriger Wiederherstellungsschlüssel","rotateSuccessE2eeWarning":"Wiederherstellungsschlüssel erfolgreich rotiert! Hinweis: Da E2EE zuvor gesperrt war und nicht entschlüsselt werden konnte, erfordern alte E2EE-Daten weiterhin den vorherigen Schlüssel, oder Sie können unten auf „Schlüsselpaar zurücksetzen“ klicken."},"verifyIdentity":"Sicherheitsbestätigung","verifyIdentityDesc":"Um Ihr Konto zu schützen, bestätigen Sie bitte Ihre Identität.","usePasskeyInstead":"Mit Passkey bestätigen","changePasswordWithPasskey":"Mit Passkey bestätigen & ändern","enableRegistration":"Benutzerregistrierung aktivieren","timezone":"Zeitzone","timezoneAuto":"Automatisch (Browser-Standard)","totpCode":"Authenticator-Code"}`),d={item1Title:`DNS Worker Schützendes DNS`,item1Desc:`Ein DNS-Resolver auf Basis von Cloudflare Workers & D1, optimiert für Geschwindigkeit und Sicherheit.`,item2Title:`DoH-Privatsphäre`,item2Desc:`Verhindert DNS-Abfangen und schützt Ihre Privatsphäre durch verschlüsselte DNS over HTTPS (RFC 8484) Tunnel.`,item3Title:`Globales Edge-Netzwerk`,item3Desc:`Nutzt das riesige Edge-Netzwerk von Cloudflare für extrem schnelle Auflösung und minimale Latenzzeiten.`,item4Title:`Granulare Filterung`,item4Desc:`Volle Unterstützung für Sperr- und Zulassungslisten, AdGuard-Regeln sowie benutzerdefinierte DNS-Eintrags-Umleitungen.`,item5Title:`Echtzeit-Statistiken`,item5Desc:`Visualisieren Sie den Netzwerkstatus durch detaillierte Abfrageprotokolle und ein umfassendes Dashboard.`,item6Title:`Moderne UI & Darkmode`,item6Desc:`Ein hochdichtes Dashboard für Entwickler und Heimanwender, entwickelt auf Basis von Palantir's Blueprint UI.`,item7Title:`Cloud-native Infrastruktur`,item7Desc:`Die serverlose Architektur garantiert Wartungsfreiheit und unbegrenzte Skalierbarkeit für Ihr privates DNS.`,item8Title:`Mehrere Profile verwalten`,item8Desc:`Erstellen und verwalten Sie separate DNS-Profile für verschiedene Geräte oder Netzwerkumgebungen.`,item9Title:`Mehrere Zugangspunkte`,item9Desc:`Konfigurieren Sie dedizierte Zugangspunkte für verschiedene Geräte, um Protokolle und Statistiken getrennt zu analysieren.`,item10Title:`Zero-Knowledge-Protokolle`,item10Desc:`Ende-zu-Ende-Verschlüsselung mit Post-Quanten-Hybrid-KEM (P256-MLKEM768). Schlüssel verbleiben lokal, der Server hat null Einblick.`,item11Title:`D1 / Turso / File Multi-DB-Unterstützung`,item11Desc:`Unterstützt Cloudflare D1, verteilte Turso Cloud-SQLite und lokale Dateidatenbanken, um Quotenlimits flexibel zu überwinden.`},f={title:`DNS Worker Einrichtungs- und Bereitstellungshandbuch`,subtitle:`Ihre Instanz ist noch nicht vollständig konfiguriert. Bitte führen Sie die folgenden Schritte aus, um DNS Worker zu aktivieren.`,dbStatus:`D1-Datenbankbindung (env.DB)`,jwtStatus:`JWT-Geheimschlüssel (env.JWT_SECRET)`,configured:`Konfiguriert`,missing:`Fehlt / Nicht konfiguriert`,refresh:`Aktualisieren & Überprüfen`,methodCli:`CLI-Bereitstellung`,methodDash:`Cloudflare Dashboard-Bereitstellung`,copy:`Kopieren`,copied:`Kopiert!`,stepDbTitle:`1. D1-Datenbank binden`,stepDbDesc:`Erstellen Sie eine D1-Datenbank und binden Sie diese an Ihren Worker. Führen Sie im Terminal Folgendes aus:`,stepDbCommand1:`wrangler d1 create dns_worker_db`,stepDbDesc2:`Kopieren Sie die ausgegebenen Details und fügen Sie diese in Ihre wrangler.toml unter [[d1_databases]] ein:`,stepDbCommand2:`[[d1_databases]]
2
+ binding = "DB"
3
+ database_name = "dns_worker_db"
4
+ database_id = "<IHRE_D1_DATABASE_ID>"
5
+ migrations_dir = "migrations"`,stepDbDashDesc:`1. Gehen Sie zu Cloudflare Dashboard -> Workers & Pages -> D1 -> Datenbank erstellen -> Nennen Sie sie 'dns_worker_db'.
6
+ 2. Gehen Sie zu Ihrem Worker -> Einstellungen -> Variablen -> D1-Datenbankbindungen -> Bindung hinzufügen.
7
+ 3. Setzen Sie den Bindungsnamen auf 'DB' und wählen Sie 'dns_worker_db' als D1-Datenbank aus. Speichern.
8
+ 4. Gehen Sie zu Ihrer D1-Datenbank -> Konsole, kopieren Sie das SQL-Tabellenschema-Skript aus dem Migrationsordner und führen Sie es aus.`,stepJwtTitle:`2. JWT-Geheimschlüssel festlegen`,stepJwtDesc:`DNS Worker erfordert ein JWT-Geheimnis zum Signieren von Sitzungstoken. Konfigurieren Sie es als Cloudflare Secret:`,stepJwtCommand1:`wrangler secret put JWT_SECRET`,stepJwtDashDesc:`1. Gehen Sie zu Ihrem Worker -> Einstellungen -> Variablen -> Umgebungsvariablen -> Variable hinzufügen.
9
+ 2. Setzen Sie den Namen auf 'JWT_SECRET', wählen Sie den Typ 'Secret' und geben Sie eine sichere Zufallszeichenkette ein.
10
+ 3. Speichern und bereitstellen.`,stepJwtDesc2:`Cloudflare Dashboard`,stepJwtCommand2:`https://dash.cloudflare.com/`,stepDeployTitle:`3. Bereitstellen & Migrationen anwenden`,stepDeployDesc:`Führen Sie den Bereitstellungsbefehl aus, um das Frontend zu kompilieren, D1-Datenbankmigrationen automatisch anzuwenden und live zu gehen:`,stepDeployCommand:`npm run deploy`,stepDeployDashDesc:`Wenn Sie alle Konfigurationen über das Cloudflare-Dashboard abgeschlossen haben, gehen Sie zur Registerkarte 'Bereitstellungen' Ihres Workers und klicken Sie auf 'Bereitstellen' oder 'Neu bereitstellen'.`,jwtGeneratorTitle:`Sicherer JWT_SECRET-Generator`,jwtGeneratorDesc:`Verwenden Sie diesen kryptografisch sicheren Schlüsselgenerator, um ein zufälliges 64-stelliges alphanumerisches Geheimnis für env.JWT_SECRET zu generieren.`,regenerate:`Neu generieren`,serverfullTitle:`DNS Worker Serverfull Einrichtungsleitfaden`,serverfullSubtitle:`Ihre Instanz läuft im Serverfull-Modus (Eigenständig). Befolgen Sie diese Schritte, um die Datenbank und Konfiguration zu initialisieren.`,serverfullDbStatus:`SQLite-Datenbank (Lokales Datenverzeichnis)`,serverfullDbConfigured:`Bereit & Initialisiert`,serverfullDbMissing:`Datenbankdatei fehlt`,serverfullDbMissingHint:`Die Datenbank wird normalerweise bei der Installation automatisch initialisiert. Falls sie fehlt, installieren Sie das Paket erneut oder starten Sie den Dienst neu.`,serverfullJwtStatus:`JWT-Geheimnis (.env-Konfiguration)`,serverfullJwtConfigured:`Konfiguriert`,serverfullJwtMissing:`Nicht konfiguriert`,serverfullJwtMissingHint:`JWT_SECRET kann in .env (oder /etc/dns-worker/.env) angepasst werden. Fügen Sie das unten generierte Geheimnis ein und starten Sie den Dienst neu.`,serverfullStepInstallTitle:`1. Prüfen oder Neuinstallieren (Datenbank initialisieren)`,serverfullStepInstallDesc:`Falls die SQLite-Datenbank fehlt, führen Sie eine globale Neuinstallation durch:`,serverfullStepInstallCmd:`sudo npm install -g dns-worker@latest`,serverfullStepEnvTitle:`2. JWT_SECRET in .env konfigurieren`,serverfullStepEnvDesc:`Bearbeiten Sie /etc/dns-worker/.env und tragen Sie das unten generierte Geheimnis ein:`,serverfullStepEnvCmd:`sudo nano /etc/dns-worker/.env
11
+ # Setzen Sie JWT_SECRET=<unten generiertes Geheimnis>`,serverfullStepServiceTitle:`3. Dienst neu starten und überprüfen`,serverfullStepServiceDesc:`Starten Sie den Hintergrunddienst neu und prüfen Sie den Status:`,serverfullStepServiceCmd:`sudo dns-worker service restart
12
+ sudo dns-worker status`},p={defaultDesc:`Sichere, schnelle und anpassbare DNS-Auflösung für alle Ihre Geräte. Basiert auf Cloudflare Workers, quelloffen und datenschutzorientiert.`,setupDesc:`Konfigurieren Sie Ihre Geräte für die Verwendung von DNS Worker.`};var m={common:e,nav:t,theme:n,auth:r,setup:i,rules:a,analytics:o,logs:s,filtering:c,settings:l,account:u,intro:d,deploymentGuide:f,meta:p};export{u as account,o as analytics,r as auth,e as common,m as default,f as deploymentGuide,c as filtering,d as intro,s as logs,p as meta,t as nav,a as rules,l as settings,i as setup,n as theme};