dns-worker 1.1.2 → 1.1.3-canary.eba4e13

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.
@@ -1,2 +1,2 @@
1
- import{i as e}from"./rolldown-runtime-C4Xdq4VV.js";import{$ as t,Ct as n,E as r,Q as i,Qt as a,gt as o,j as s,lt as c}from"./vendor-react-BmoHsW1x.js";import{S as l,b as u}from"./vendor-icons-other-Bme3ywH9.js";import"./vendor-i18next-BKUzkAKP.js";import{A as d,B as f,H as p,L as m,N as h,O as g,R as _,S as v,V as y,f as b,m as x,p as S,r as C,v as w,x as T,z as E}from"./vendor-ui-core-CY_WyMIf.js";import{_t as D}from"./vendor-utils-BWSB0jGn.js";import{$t as O,C as k,Ft as A,Jt as ee,Mt as j,O as M,Qt as N,S as P,Vt as F,Xt as I,Zt as te,_ as L,an as R,b as z,d as B,en as V,f as H,g as ne,h as U,i as W,j as G,m as K,r as q,rn as J,sn as re,u as Y,wt as ie,x as ae,y as oe}from"./index-dXN_pYn1.js";import{t as X}from"./QRCodeCanvas-DQ-xNuwF.js";var Z=e(l(),1),Q=e(u(),1);const $=({username:e,setUsername:t,isTurnstileEnabled:n,turnstileRef:r,loading:i,turnstileStatus:o,onSubmit:s})=>{let{t:c}=a();return(0,Q.jsxs)(`form`,{onSubmit:s,className:`space-y-4`,children:[(0,Q.jsx)(S,{label:c(`auth.username`),labelFor:`username`,children:(0,Q.jsx)(b,{id:`username`,leftIcon:`user`,placeholder:c(`auth.usernamePlaceholder`),size:`large`,className:`rounded-xl w-full`,value:e,onChange:e=>t(e.target.value),autoFocus:!0,required:!0})}),n&&(0,Q.jsx)(`div`,{className:`py-2 flex justify-center min-h-16.25`,children:(0,Q.jsx)(`div`,{ref:r})}),(0,Q.jsx)(h,{fill:!0,size:`large`,intent:y.PRIMARY,type:`submit`,loading:i||o===`verifying`,disabled:!!n&&o!==`success`,className:`mt-6 font-bold py-6 rounded-xl shadow-lg shadow-blue-500/20`,children:o===`verifying`?c(`auth.verifying`):c(`auth.next`,`Next`)})]})},se=({password:e,setPassword:t,hasMfa:n,onSwitchToMfa:r,loading:i,onSubmit:o,keepLoggedIn:s,setKeepLoggedIn:c,optionalSessionExpirationDays:l})=>{let[u,d]=Z.useState(!1),{t:f}=a();return(0,Q.jsxs)(`form`,{onSubmit:o,className:`space-y-4`,children:[(0,Q.jsx)(S,{label:f(`auth.password`),labelFor:`password`,children:(0,Q.jsx)(b,{id:`password`,leftIcon:`lock`,placeholder:f(`auth.passwordPlaceholder`),type:u?`text`:`password`,size:`large`,className:`rounded-xl`,value:e,onChange:e=>t(e.target.value),rightElement:(()=>(0,Q.jsxs)(`div`,{className:`flex items-center`,children:[e&&(0,Q.jsx)(h,{minimal:!0,icon:`cross`,onClick:()=>t(``)}),(0,Q.jsx)(h,{minimal:!0,icon:u?`eye-open`:`eye-off`,onClick:()=>d(!u),title:u?f(`auth.hidePassword`,`Hide password`):f(`auth.showPassword`,`Show password`)})]}))(),autoFocus:!0,required:!0})}),(0,Q.jsx)(x,{checked:s,onChange:e=>c(e.currentTarget.checked),label:f(`auth.keepLoggedIn`,`Keep me logged in for {{days}} days`,{days:l}),className:`mt-4 text-left`}),(0,Q.jsxs)(`div`,{className:`pt-2 space-y-3`,children:[(0,Q.jsx)(h,{fill:!0,size:`large`,intent:y.PRIMARY,type:`submit`,loading:i,className:`font-bold py-6 rounded-xl shadow-lg shadow-blue-500/20`,children:n?f(`auth.next`,`Next`):f(`auth.loginBtn`,`Login`)}),n&&r&&(0,Q.jsx)(h,{fill:!0,minimal:!0,size:`large`,type:`button`,disabled:i,onClick:r,className:`font-medium text-blue-600 dark:text-blue-400 py-2.5 rounded-xl transition-colors hover:bg-blue-50 dark:hover:bg-blue-950/30`,children:f(`auth.otherOptions`,`其他选项`)})]})]})},ce=({value:e,onChange:t,disabled:n=!1,autoFocus:r=!0,className:i=``})=>{let{t:o}=a(),s=(0,Z.useRef)([]),c=(e=>{let t=e.replace(/\D/g,``).slice(0,30),n=[];for(let e=0;e<5;e++)n.push(t.slice(e*6,(e+1)*6));return n})(e);(0,Z.useEffect)(()=>{r&&s.current[0]&&s.current[0].focus()},[r]);let l=(e,n)=>{let r=n.replace(/\D/g,``).slice(0,6),i=[...c];i[e]=r,t(i.join(`-`)),r.length===6&&e<4&&s.current[e+1]?.focus()},u=(e,t)=>{if(t.key===`Backspace`&&c[e].length===0&&e>0){t.preventDefault();let n=s.current[e-1];n&&n.focus()}else t.key===`ArrowLeft`&&(t.currentTarget.selectionStart??0)===0&&e>0?(t.preventDefault(),s.current[e-1]?.focus()):t.key===`ArrowRight`&&(t.currentTarget.selectionStart??0)===c[e].length&&e<4&&(t.preventDefault(),s.current[e+1]?.focus())},d=(e,n)=>{let r=n.clipboardData.getData(`text`).replace(/\D/g,``);if(r.length>6){n.preventDefault();let i=[...c],a=0;for(let t=e;t<5&&a<r.length;t++){let e=r.slice(a,a+6);i[t]=e,a+=e.length}t(i.join(`-`));let o=Math.min(4,e+Math.ceil(r.length/6)-1);s.current[o]?.focus()}},f=c.map((e,t)=>e.length===6&&!z(e)?t:-1).filter(e=>e!==-1);return(0,Q.jsxs)(`div`,{className:`space-y-2 ${i}`,children:[(0,Q.jsx)(`div`,{className:`flex items-center justify-between gap-1 sm:gap-2`,children:c.map((e,t)=>{let r=e.length===6,i=r&&!z(e),a=r&&!i,c=`border-gray-300 dark:border-gray-600 focus:border-blue-500 focus:ring-2 focus:ring-blue-500/20`;return i?c=`border-red-500 ring-2 ring-red-500/30 bg-red-50/40 dark:bg-red-950/20 text-red-600 dark:text-red-400`:a&&(c=`border-green-500/80 dark:border-green-500/60 bg-green-50/20 dark:bg-green-950/10 text-gray-900 dark:text-gray-100`),(0,Q.jsxs)(Z.Fragment,{children:[(0,Q.jsx)(`input`,{ref:e=>{s.current[t]=e},type:`text`,inputMode:`numeric`,pattern:`[0-9]*`,maxLength:6,value:e,disabled:n,autoComplete:`off`,autoCorrect:`off`,autoCapitalize:`off`,spellCheck:!1,"data-1p-ignore":`true`,"data-lpignore":`true`,"data-bwignore":`true`,onChange:e=>l(t,e.target.value),onKeyDown:e=>u(t,e),onPaste:e=>d(t,e),className:`w-full min-w-0 text-center font-mono text-xs sm:text-sm tracking-wider py-2 sm:py-2.5 px-1 rounded-lg border transition-all duration-150 outline-none ${c}`,title:i?o(`auth.recoveryChecksumError`,{defaultValue:`校验码错误:该组 6 位数无法被 11 整除`,group:t+1}):void 0}),t<4&&(0,Q.jsx)(`span`,{className:`text-gray-400 dark:text-gray-500 font-bold select-none text-xs`,children:`-`})]},t)})}),f.length>0&&(0,Q.jsx)(`p`,{className:`text-xs text-red-500 dark:text-red-400 text-center font-medium mt-1`,children:o(`auth.recoveryChecksumErrorDesc`,{defaultValue:`第 {{groups}} 组校验码错误,请核对后重试`,groups:f.map(e=>e+1).join(`、`)})})]})},le=({hasPasskey:e,requiresTotp:n,mfaMethod:r,setMfaMethod:o,passkeyLoading:s,onPasskeyLogin:c,totpToken:l,setTotpToken:u,recoveryKey:d,setRecoveryKey:f,loading:p,onClearError:m,onSubmit:g,keepLoggedIn:_,setKeepLoggedIn:v,optionalSessionExpirationDays:b})=>{let{t:C}=a(),w=e=>{o(e),m()};return(0,Q.jsxs)(`form`,{onSubmit:e=>{if(e.preventDefault(),r===`passkey`){c();return}g(e)},className:`space-y-4`,children:[r===`passkey`&&(0,Q.jsxs)(`div`,{className:`space-y-5 text-center py-2`,children:[(0,Q.jsx)(`div`,{className:`mx-auto w-16 h-16 rounded-2xl bg-blue-50 dark:bg-blue-950/40 flex items-center justify-center text-blue-600 dark:text-blue-400`,children:(0,Q.jsx)(i,{size:36})}),(0,Q.jsxs)(`div`,{className:`space-y-1`,children:[(0,Q.jsx)(`h4`,{className:`text-base font-semibold text-gray-900 dark:text-gray-100 m-0`,children:C(`auth.passkeyVerification`,`Passkey Verification`)}),(0,Q.jsx)(`p`,{className:`text-xs text-gray-500 dark:text-gray-400 max-w-xs mx-auto leading-relaxed`,children:C(`auth.passkeyPromptDesc`,`Use your registered device's biometric or hardware security key to verify`)})]}),(0,Q.jsx)(x,{checked:_,onChange:e=>v(e.currentTarget.checked),label:C(`auth.keepLoggedIn`,`Keep me logged in for {{days}} days`,{days:b}),className:`text-left inline-block mt-2`}),(0,Q.jsxs)(`div`,{className:`pt-2 space-y-3`,children:[(0,Q.jsxs)(h,{fill:!0,size:`large`,intent:y.PRIMARY,type:`button`,loading:s,disabled:p,onClick:c,className:`font-semibold py-6 rounded-xl shadow-lg shadow-blue-500/20 flex items-center justify-center space-x-2`,children:[(0,Q.jsx)(i,{size:20,className:`inline mr-1.5`}),(0,Q.jsx)(`span`,{children:C(`auth.verifyWithPasskey`,`Verify with Passkey`)})]}),n&&(0,Q.jsx)(h,{fill:!0,minimal:!0,size:`large`,type:`button`,disabled:s||p,onClick:()=>w(`totp`),className:`font-medium text-blue-600 dark:text-blue-400 py-2.5 rounded-xl transition-colors hover:bg-blue-50 dark:hover:bg-blue-950/30`,children:C(`auth.otherOptions`,`Other Options`)}),(0,Q.jsx)(`div`,{className:`pt-1`,children:(0,Q.jsxs)(`button`,{type:`button`,onClick:()=>w(`recovery`),className:`text-xs text-gray-500 hover:text-blue-600 dark:hover:text-blue-400 hover:underline bg-transparent border-none cursor-pointer p-0 font-normal inline-flex items-center gap-1`,children:[(0,Q.jsx)(t,{size:12}),(0,Q.jsx)(`span`,{children:C(`auth.totpUseRecovery`,`Use Recovery Key`)})]})})]})]}),r===`totp`&&(0,Q.jsxs)(`div`,{className:`space-y-4`,children:[(0,Q.jsx)(S,{label:C(`account.totp.title`,`Time-based One-time Password (TOTP)`),helperText:C(`auth.totpPrompt`,`Please enter the 6-digit code from your authentication app`),children:(0,Q.jsx)(`div`,{className:`pt-2`,children:(0,Q.jsx)(W,{length:6,value:l,onChange:u,disabled:p,autoFocus:!0})})}),(0,Q.jsx)(x,{checked:_,onChange:e=>v(e.currentTarget.checked),label:C(`auth.keepLoggedIn`,`Keep me logged in for {{days}} days`,{days:b}),className:`mt-4 text-left`}),(0,Q.jsxs)(`div`,{className:`pt-2 space-y-3`,children:[(0,Q.jsx)(h,{fill:!0,size:`large`,intent:y.PRIMARY,type:`submit`,loading:p,className:`font-bold py-6 rounded-xl shadow-lg shadow-blue-500/20`,children:C(`auth.loginBtn`,`Login`)}),e&&(0,Q.jsx)(h,{fill:!0,minimal:!0,size:`large`,type:`button`,disabled:p,onClick:()=>w(`passkey`),className:`font-medium text-blue-600 dark:text-blue-400 py-2.5 rounded-xl transition-colors hover:bg-blue-50 dark:hover:bg-blue-950/30`,children:C(`auth.otherOptions`,`Other Options`)}),(0,Q.jsx)(`div`,{className:`text-center pt-1`,children:(0,Q.jsxs)(`button`,{type:`button`,onClick:()=>w(`recovery`),className:`text-xs text-gray-500 hover:text-blue-600 dark:hover:text-blue-400 hover:underline bg-transparent border-none cursor-pointer p-0 font-normal inline-flex items-center gap-1`,children:[(0,Q.jsx)(t,{size:12}),(0,Q.jsx)(`span`,{children:C(`auth.totpUseRecovery`,`Use Recovery Key`)})]})})]})]}),r===`recovery`&&(0,Q.jsxs)(`div`,{className:`space-y-4`,children:[(0,Q.jsx)(S,{label:C(`account.totp.recoveryKeysTitle`,`Recovery Keys`),helperText:C(`auth.recoveryPrompt`,`Please enter your 30-character recovery key (5 groups of 6 digits)`),children:(0,Q.jsx)(`div`,{className:`pt-2`,children:(0,Q.jsx)(ce,{value:d,onChange:f,disabled:p,autoFocus:!0})})}),(0,Q.jsx)(x,{checked:_,onChange:e=>v(e.currentTarget.checked),label:C(`auth.keepLoggedIn`,`Keep me logged in for {{days}} days`,{days:b}),className:`mt-4 text-left`}),(0,Q.jsxs)(`div`,{className:`pt-2 space-y-3`,children:[(0,Q.jsx)(h,{fill:!0,size:`large`,intent:y.PRIMARY,type:`submit`,loading:p,className:`font-bold py-6 rounded-xl shadow-lg shadow-blue-500/20`,children:C(`auth.loginBtn`,`Login`)}),(0,Q.jsx)(`div`,{className:`text-center pt-1`,children:(0,Q.jsx)(`button`,{type:`button`,onClick:()=>w(e?`passkey`:`totp`),className:`text-xs text-blue-600 dark:text-blue-400 hover:underline bg-transparent border-none cursor-pointer p-0 font-normal`,children:e?C(`auth.backToPasskey`,`Back to Passkey Verification`):C(`auth.totpUseApp`,`Use Authentication App`)})})]})]})]})};function ue({siteKey:e,enabled:t,turnstileReady:n,isActive:r,onError:i,onClearError:o}){let[s,c]=(0,Z.useState)(null),[l,u]=(0,Z.useState)(`idle`),d=(0,Z.useRef)(null),f=(0,Z.useRef)(null),{t:p}=a();return(0,Z.useEffect)(()=>{if(r&&t&&e&&(n||window.turnstile)&&d.current)try{f.current&&window.turnstile&&(window.turnstile.remove(f.current),f.current=null),u(`verifying`),d.current.innerHTML=``,f.current=window.turnstile.render(d.current,{sitekey:e,callback:e=>{c(e),u(`success`),o()},"expired-callback":()=>{c(null),u(`idle`)},"error-callback":e=>{console.error(`Turnstile error:`,e),u(`error`),i(p(`auth.turnstileError`,`Verification service failed to load. Please reload and try again.`)),c(null)}})}catch(e){console.error(`Turnstile render error:`,e),u(`error`)}return()=>{f.current&&window.turnstile&&(window.turnstile.remove(f.current),f.current=null)}},[r,t,e,n,p,i,o]),{turnstileToken:s,setTurnstileToken:c,turnstileStatus:l,turnstileRef:d,resetTurnstile:()=>{window.turnstile&&f.current&&window.turnstile.reset(f.current),c(null),u(`idle`)}}}function de({username:e,password:t,passwordVersion:n,nonce:r,serverSalt:i,keepLoggedIn:o,onSuccess:s}){let[c,l]=(0,Z.useState)(!1),[u,d]=(0,Z.useState)(``),[f,p]=(0,Z.useState)(null),{t:m}=a();return{loading:c,error:u,setError:d,rotatedRecoveryKey:f,setRotatedRecoveryKey:p,executeLogin:async a=>{l(!0),d(``);try{let c={keepLoggedIn:o,passkeyAssertion:a.passkeyAssertion,totpTokenHash:a.totpTokenHash,totpSalt:a.totpSalt,recoveryKey:a.recoveryKey};if(a.useEnteredPassword&&t)if(n===2){if(!r||!i)throw Error(m(`auth.sessionExpired`,`Session expired, please start over`));c.password=await U(await Y(await H(t,e),i),r)}else c.password=t;let l=await J(c);if(l.accessToken&&M(l.accessToken),l.needsMigration&&t&&await A(await H(t,e),t),l.rotatedRecoveryKey&&a.recoveryKey){try{await G.unlockWithRecoveryKey(a.recoveryKey),await G.wrapCurrentKeyForRecovery(l.rotatedRecoveryKey)}catch(e){console.warn(`[Login] Could not auto re-wrap E2EE key with rotated recovery key:`,e)}p(l.rotatedRecoveryKey);return}s()}catch(e){e instanceof N&&ne({status:e.status},e.bodyText)?d(m(`auth.passwordLeaked`)):d(B(e,m))}finally{l(!1)}}}}function fe({hasPasswordEntered:e,passkeyOptions:t,executeLogin:n,onError:r}){let[i,o]=(0,Z.useState)(`passkey`),[s,c]=(0,Z.useState)(``),[l,u]=(0,Z.useState)(``),[d,f]=(0,Z.useState)(!1),{t:p}=a();return{mfaMethod:i,setMfaMethod:o,totpToken:s,setTotpToken:c,recoveryKey:l,setRecoveryKey:u,passkeyLoading:d,setPasskeyLoading:f,handlePasskeyLogin:async()=>{if(t){f(!0),r(``);try{await n({useEnteredPassword:e,passkeyAssertion:await I(t)})}catch(e){console.error(`Passkey authentication error:`,e),r(B(e,p))}finally{f(!1)}}},handleStep3Submit:async t=>{if(t.preventDefault(),i===`totp`){let t=s.replace(/\s/g,``);if(t.length!==6){r(p(`auth.totpFormatError`,`Please enter a valid 6-digit code`));return}let i=crypto.randomUUID();await n({useEnteredPassword:e,totpTokenHash:await K(t,i),totpSalt:i})}else if(i===`recovery`){let t=l.replace(/[-\s]/g,``);if(!t){r(p(`auth.recoveryKeyRequired`,`Please enter your recovery key`));return}await n({useEnteredPassword:e,recoveryKey:t})}},resetMfaFields:()=>{c(``),u(``),f(!1),o(`passkey`)}}}const pe=({authConfig:e,turnstileReady:t,onSuccess:n})=>{let{t:r}=a(),[i,o]=(0,Z.useState)(1),[s,c]=(0,Z.useState)(``),[l,u]=(0,Z.useState)(``),[d,f]=(0,Z.useState)(!1),[p,m]=(0,Z.useState)(1),[h,g]=(0,Z.useState)(void 0),[_,v]=(0,Z.useState)(void 0),[y,b]=(0,Z.useState)(!0),[x,S]=(0,Z.useState)(!1),[C,w]=(0,Z.useState)(!1),[T,E]=(0,Z.useState)(null),{loading:D,error:O,setError:k,rotatedRecoveryKey:A,setRotatedRecoveryKey:ee,executeLogin:j}=de({username:s,password:l,passwordVersion:p,nonce:h,serverSalt:_,keepLoggedIn:d,onSuccess:n}),[M,N]=(0,Z.useState)(!1),P=D||M,F=e?.turnstile_enabled_login,{turnstileToken:I,turnstileStatus:te,turnstileRef:L,resetTurnstile:z}=ue({siteKey:e?.turnstile_site_key,enabled:F,turnstileReady:t,isActive:i===1,onError:k,onClearError:()=>k(``)}),{mfaMethod:V,setMfaMethod:H,totpToken:ne,setTotpToken:U,recoveryKey:W,setRecoveryKey:G,passkeyLoading:K,handlePasskeyLogin:q,handleStep3Submit:J,resetMfaFields:re}=fe({hasPasswordEntered:!!l,passkeyOptions:T,executeLogin:j,onError:k}),Y=async t=>{if(t.preventDefault(),!ae(s)){k(r(`auth.formatTipUsername`));return}if(F&&e?.turnstile_site_key&&!I){k(r(`auth.turnstileRequired`));return}N(!0),k(``);try{let e=await R({username:s,turnstileToken:I});b(e.requires_password),S(e.requires_totp),w(!!e.has_passkey),E(e.passkey_options||null),m(e.password_version??1),g(e.nonce),v(e.serverSalt),H(e.has_passkey?`passkey`:`totp`),e.requires_password?o(2):o(3)}catch(e){k(B(e,r)),z()}finally{N(!1)}},ie=async e=>{if(e.preventDefault(),!l){k(r(`auth.passwordRequiredFirst`,`Please enter your password first`));return}C||x?(k(``),o(3),H(C?`passkey`:`totp`)):await j({useEnteredPassword:!0})},oe=()=>{u(``),k(``),o(3),H(C?`passkey`:`totp`)},X=()=>{o(1),u(``),k(``),g(void 0),v(void 0),w(!1),E(null),re(),z()};return{loginStep:i,username:s,setUsername:c,password:l,setPassword:u,totpToken:ne,setTotpToken:U,recoveryKey:W,setRecoveryKey:G,requiresPassword:y,requiresTotp:x,hasPasskey:C,mfaMethod:V,setMfaMethod:H,passkeyLoading:K,loading:P,error:O,setError:k,turnstileStatus:te,turnstileRef:L,isTurnstileEnabled:F,keepLoggedIn:d,setKeepLoggedIn:f,handleStep1Submit:Y,handleStep2Submit:ie,handleStep3Submit:J,handleSwitchToMfa:oe,handlePasskeyLogin:q,handleBack:()=>{k(``),i===2?X():i===3&&(y?o(2):X())},resetToStep1:X,rotatedRecoveryKey:A,handleAcknowledgeRotatedKey:()=>{ee(null),n()}}},me=({authConfig:e,turnstileReady:t,onSuccess:r,onToggleMode:i})=>{let{t:l}=a(),{loginStep:u,username:f,setUsername:p,password:b,setPassword:x,totpToken:S,setTotpToken:C,recoveryKey:w,setRecoveryKey:T,requiresTotp:D,hasPasskey:O,mfaMethod:k,setMfaMethod:A,passkeyLoading:ee,loading:j,error:M,setError:N,turnstileStatus:F,turnstileRef:I,isTurnstileEnabled:te,keepLoggedIn:L,setKeepLoggedIn:R,handleStep1Submit:z,handleStep2Submit:B,handleStep3Submit:V,handleSwitchToMfa:H,handlePasskeyLogin:ne,handleBack:U,rotatedRecoveryKey:W,handleAcknowledgeRotatedKey:G}=pe({authConfig:e,turnstileReady:t,onSuccess:r}),[K,q]=(0,Z.useState)(!1),J=e=>{navigator.clipboard.writeText(e),q(!0),setTimeout(()=>q(!1),2e3)};return(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsxs)(`div`,{className:`flex flex-col items-center mb-8 relative`,children:[u!==1&&(0,Q.jsx)(`button`,{type:`button`,onClick:U,className:`absolute left-0 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-700 dark:hover:text-gray-200 bg-transparent border-none cursor-pointer p-1 rounded-lg transition-colors`,title:l(`common.back`,`返回`),children:(0,Q.jsx)(n,{size:24})}),(0,Q.jsx)(`img`,{src:P,alt:`DNS Worker Logo`,className:`w-20 h-20 object-contain`}),(0,Q.jsx)(d,{className:`font-bold tracking-tight text-2xl mt-4`,children:(()=>{switch(u){case 1:return l(`auth.login`);case 2:return l(`auth.password`);case 3:return l(`auth.mfaVerification`,`多因素认证`)}})()}),(0,Q.jsx)(`p`,{className:`text-gray-500 mt-2 text-center text-sm leading-relaxed`,children:u===1?l(`auth.protectInternet`):f})]}),e?.has_users===!1&&(0,Q.jsx)(v,{intent:y.PRIMARY,icon:`info-sign`,className:`mb-6 rounded-xl`,children:(0,Q.jsxs)(`div`,{className:`flex flex-col sm:flex-row items-start sm:items-center justify-between gap-3`,children:[(0,Q.jsx)(`span`,{className:`text-sm font-medium`,children:l(`auth.noUsersRegistered`,`系统尚无账号,请注册成为管理员。`)}),(0,Q.jsx)(`button`,{type:`button`,onClick:i,className:`text-xs bg-blue-600 hover:bg-blue-700 text-white font-semibold py-1.5 px-3 rounded-lg border-none cursor-pointer whitespace-nowrap transition-colors`,children:l(`auth.goToRegisterAdmin`,`注册管理员`)})]})}),M&&(0,Q.jsx)(v,{intent:y.DANGER,className:`mb-6 rounded-xl`,title:l(`auth.error`),children:M}),u===1&&(0,Q.jsx)($,{username:f,setUsername:p,isTurnstileEnabled:te,turnstileRef:I,loading:j,turnstileStatus:F,onSubmit:z}),u===2&&(0,Q.jsx)(se,{password:b,setPassword:x,hasMfa:O||D,onSwitchToMfa:H,loading:j,onSubmit:B,keepLoggedIn:L,setKeepLoggedIn:R,optionalSessionExpirationDays:e?.optional_session_expiration_days??7}),u===3&&(0,Q.jsx)(le,{hasPasskey:O,requiresTotp:D,mfaMethod:k,setMfaMethod:A,passkeyLoading:ee,onPasskeyLogin:ne,totpToken:S,setTotpToken:C,recoveryKey:w,setRecoveryKey:T,loading:j,onClearError:()=>N(``),onSubmit:V,keepLoggedIn:L,setKeepLoggedIn:R,optionalSessionExpirationDays:e?.optional_session_expiration_days??7}),u===1&&(e?.has_users===!1||e?.registration_enabled!==!1)&&(0,Q.jsx)(`div`,{className:`mt-8 pt-6 border-t border-gray-100 dark:border-gray-800 flex justify-center items-center text-sm`,children:(0,Q.jsx)(`button`,{onClick:i,className:`text-blue-600 dark:text-blue-400 font-semibold hover:underline bg-transparent border-none cursor-pointer`,children:l(`auth.noAccount`)})}),(0,Q.jsxs)(g,{isOpen:!!W,onClose:G,title:l(`account.recoveryKey.autoRotatedTitle`,`恢复密钥已自动轮换`),icon:`warning-sign`,isCloseButtonShown:!1,canOutsideClickClose:!1,className:`dark:bg-gray-900`,children:[(0,Q.jsxs)(`div`,{className:m,children:[(0,Q.jsx)(v,{intent:y.WARNING,icon:(0,Q.jsx)(s,{size:16}),className:`mb-4 text-xs`,children:l(`account.recoveryKey.autoRotatedNotice`,`根据恢复密钥单次使用规则,您的原恢复密钥已失效,系统已为您生成全新 30 位紧急恢复密钥。请务必立即复制并妥善离线保存,关闭后将无法再次查看!`)}),W&&(0,Q.jsxs)(`div`,{className:`space-y-3`,children:[(0,Q.jsx)(`div`,{className:`p-3 bg-gray-100 dark:bg-gray-800 rounded border border-gray-200 dark:border-gray-700 font-mono text-center text-lg font-bold tracking-widest select-all text-gray-900 dark:text-gray-100`,children:W}),(0,Q.jsx)(`div`,{className:`flex justify-center`,children:(0,Q.jsx)(h,{intent:y.PRIMARY,icon:K?(0,Q.jsx)(o,{size:14,className:`text-green-400`}):(0,Q.jsx)(c,{size:14}),text:K?l(`common.copied`,`已复制`):l(`common.copyKey`,`复制新恢复密钥`),onClick:()=>J(W)})})]})]}),(0,Q.jsx)(`div`,{className:_,children:(0,Q.jsx)(`div`,{className:E,children:(0,Q.jsx)(h,{intent:y.SUCCESS,onClick:G,text:l(`account.recoveryKey.savedAndContinue`,`我已妥善保存并进入控制台`)})})})]})]})},he=({username:e,setUsername:t,usernameFocused:n,setUsernameFocused:r,checkUsernameDuplicate:i,loading:o,onSubmit:s,onClearError:c})=>{let{t:l}=a();return(0,Q.jsxs)(`form`,{onSubmit:s,className:`space-y-4`,children:[(0,Q.jsx)(S,{label:l(`auth.username`),labelFor:`username`,children:(0,Q.jsx)(w,{content:l(`auth.formatTipUsername`),isOpen:n,position:f.TOP,intent:y.PRIMARY,className:`w-full`,children:(0,Q.jsx)(`div`,{className:`w-full block`,children:(0,Q.jsx)(b,{id:`username`,leftIcon:`user`,placeholder:l(`auth.usernamePlaceholder`),size:`large`,className:`rounded-xl w-full`,value:e,onChange:e=>{t(e.target.value),c()},onFocus:()=>r(!0),onBlur:()=>{r(!1),i(e)},autoFocus:!0,required:!0})})})}),(0,Q.jsx)(h,{fill:!0,size:`large`,intent:y.PRIMARY,type:`submit`,loading:o,className:`mt-6 font-bold py-6 rounded-xl shadow-lg shadow-blue-500/20`,children:l(`auth.next`,`Next`)})]})},ge=({password:e,setPassword:t,passwordFocused:n,setPasswordFocused:r,loading:i,onSubmit:o,isTurnstileEnabled:s,turnstileRef:c,turnstileStatus:l})=>{let[u,d]=Z.useState(!1),{t:p}=a();return(0,Q.jsxs)(`form`,{onSubmit:o,className:`space-y-4`,children:[(0,Q.jsx)(S,{label:p(`auth.password`),labelFor:`password`,children:(0,Q.jsx)(w,{content:p(`auth.formatTipPassword`),isOpen:n,position:f.TOP,intent:y.PRIMARY,className:`w-full`,children:(0,Q.jsx)(`div`,{className:`w-full block`,children:(0,Q.jsx)(b,{id:`password`,leftIcon:`lock`,placeholder:p(`auth.passwordPlaceholder`),type:u?`text`:`password`,size:`large`,className:`rounded-xl w-full`,value:e,onChange:e=>t(e.target.value),onFocus:()=>r(!0),onBlur:()=>r(!1),rightElement:(()=>(0,Q.jsxs)(`div`,{className:`flex items-center`,children:[e&&(0,Q.jsx)(h,{minimal:!0,icon:`cross`,onClick:()=>t(``)}),(0,Q.jsx)(h,{minimal:!0,icon:u?`eye-open`:`eye-off`,onClick:()=>d(!u),title:u?p(`auth.hidePassword`,`Hide password`):p(`auth.showPassword`,`Show password`)})]}))(),required:!0,autoFocus:!0})})})}),s&&(0,Q.jsx)(`div`,{className:`py-2 flex justify-center min-h-16.25`,children:(0,Q.jsx)(`div`,{ref:c})}),(0,Q.jsx)(h,{fill:!0,size:`large`,intent:y.PRIMARY,type:`submit`,loading:i||l===`verifying`,disabled:!!s&&l!==`success`,className:`mt-6 font-bold py-6 rounded-xl shadow-lg shadow-blue-500/20`,children:p(l===`verifying`?`auth.verifying`:`auth.signupBtn`)})]})},_e=({mfaChoice:e,setMfaChoice:t,onRegisterPasskey:o,passkeyRegLoading:s,passkeyRegError:c,onStartTotp:l,totpSetupData:u,totpSetupToken:d,setTotpSetupToken:f,totpSetupError:m,totpSetupLoading:g,onTotpSubmit:_,onSkip:b})=>{let{t:x}=a();return e===`choose`?(0,Q.jsxs)(`div`,{className:`space-y-4`,children:[c&&(0,Q.jsx)(v,{intent:y.DANGER,className:`rounded-xl`,children:c}),(0,Q.jsxs)(`div`,{className:`space-y-3`,children:[(0,Q.jsxs)(T,{elevation:p.ONE,className:`p-4 rounded-xl border border-blue-100 dark:border-blue-900/40 hover:border-blue-300 dark:hover:border-blue-700 transition-colors cursor-pointer`,onClick:s?void 0:o,children:[(0,Q.jsx)(`div`,{className:`flex items-start justify-between`,children:(0,Q.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,Q.jsx)(`div`,{className:`p-2.5 bg-blue-50 dark:bg-blue-950/40 text-blue-600 dark:text-blue-400 rounded-xl`,children:(0,Q.jsx)(i,{size:24})}),(0,Q.jsxs)(`div`,{children:[(0,Q.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,Q.jsx)(`h4`,{className:`text-sm font-bold text-gray-800 dark:text-gray-100 m-0`,children:x(`account.passkey.title`,`通行密钥 (Passkey)`)}),(0,Q.jsx)(C,{intent:y.PRIMARY,minimal:!0,round:!0,children:x(`auth.mfaRecommended`,`推荐 · 无密码`)})]}),(0,Q.jsx)(`div`,{className:`text-xs text-blue-600 dark:text-blue-400 font-mono mt-0.5`,children:window.location.hostname}),(0,Q.jsx)(`p`,{className:`text-xs text-gray-500 dark:text-gray-400 mt-1 mb-0 leading-relaxed`,children:x(`auth.passkeySignupDesc`,`使用本设备生物识别 (Touch ID / Face ID / Windows Hello) 或硬件密钥 (YubiKey),一键快捷且防钓鱼。`)})]})]})}),(0,Q.jsx)(`div`,{className:`mt-3 text-right`,children:(0,Q.jsx)(h,{intent:y.PRIMARY,loading:s,text:x(`auth.bindPasskeyNow`,`绑定通行密钥`),className:`rounded-lg font-medium`})})]}),(0,Q.jsxs)(T,{elevation:p.ONE,className:`p-4 rounded-xl border border-gray-100 dark:border-gray-800 hover:border-gray-300 dark:hover:border-gray-700 transition-colors cursor-pointer`,onClick:l,children:[(0,Q.jsx)(`div`,{className:`flex items-start justify-between`,children:(0,Q.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,Q.jsx)(`div`,{className:`p-2.5 bg-purple-50 dark:bg-purple-950/40 text-purple-600 dark:text-purple-400 rounded-xl`,children:(0,Q.jsx)(r,{size:24})}),(0,Q.jsxs)(`div`,{children:[(0,Q.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,Q.jsx)(`h4`,{className:`text-sm font-bold text-gray-800 dark:text-gray-100 m-0`,children:x(`auth.mfaMethodTotp`,`数字验证器 (TOTP)`)}),(0,Q.jsx)(C,{intent:y.NONE,minimal:!0,round:!0,children:x(`auth.mfaUniversal`,`通用应用`)})]}),(0,Q.jsx)(`p`,{className:`text-xs text-gray-500 dark:text-gray-400 mt-1 mb-0 leading-relaxed`,children:x(`account.totp.setupDesc`,`使用 Google Authenticator、1Password 等验证器应用扫码绑定 6 位动态验证码。`)})]})]})}),(0,Q.jsx)(`div`,{className:`mt-3 text-right`,children:(0,Q.jsx)(h,{minimal:!0,text:x(`auth.setupTotpBtn`,`扫码配置验证器`),className:`rounded-lg font-medium text-gray-700 dark:text-gray-200`})})]})]}),(0,Q.jsx)(`div`,{className:`text-center pt-2`,children:(0,Q.jsx)(h,{minimal:!0,text:x(`auth.skipMfaSetup`,`跳过多因素认证配置,直接进入系统`),onClick:b,className:`text-xs text-gray-400 hover:text-gray-600 dark:hover:text-gray-200`})})]}):(0,Q.jsxs)(`div`,{className:`space-y-4`,children:[(0,Q.jsx)(`div`,{className:`flex items-center justify-between`,children:(0,Q.jsxs)(`button`,{type:`button`,onClick:()=>t(`choose`),className:`text-xs text-blue-600 hover:underline flex items-center gap-1 bg-transparent border-none cursor-pointer p-0`,children:[(0,Q.jsx)(n,{size:14}),(0,Q.jsx)(`span`,{children:x(`auth.backToMfaOptions`,`选择其他认证方式`)})]})}),u&&(0,Q.jsxs)(`div`,{className:`flex flex-col items-center gap-3`,children:[(0,Q.jsx)(X,{uri:u.uri}),(0,Q.jsxs)(`div`,{className:`text-center`,children:[(0,Q.jsx)(`p`,{className:`text-xs text-gray-500 mb-1`,children:x(`account.totp.orEnterManually`,`Or enter the key manually:`)}),(0,Q.jsx)(`code`,{className:`text-xs font-mono bg-gray-100 dark:bg-gray-800 px-2 py-1 rounded select-all`,children:u.secret})]})]}),m&&(0,Q.jsx)(v,{intent:y.DANGER,className:`rounded-xl`,children:m}),(0,Q.jsxs)(`form`,{onSubmit:_,className:`space-y-4`,children:[(0,Q.jsx)(S,{label:x(`account.totp.enterCode`,`Enter the 6-digit code:`),helperText:x(`account.totp.enterCodeHint`,`Enter the 6-digit code to confirm.`),children:(0,Q.jsx)(W,{length:6,value:d,onChange:f,disabled:g,autoFocus:!0})}),(0,Q.jsx)(h,{fill:!0,size:`large`,intent:y.PRIMARY,type:`submit`,loading:g,disabled:d.length!==6,className:`rounded-xl font-bold py-3`,children:x(`account.totp.activate`,`Activate`)})]})]})},ve=({totpRecoveryKeys:e,copiedRecovery:t,onCopy:n,onSuccess:r})=>{let{t:i}=a();return Z.useEffect(()=>{let e=e=>{e.key===`Enter`&&r()};return window.addEventListener(`keydown`,e),()=>{window.removeEventListener(`keydown`,e)}},[r]),(0,Q.jsxs)(`div`,{className:`space-y-4`,children:[(0,Q.jsx)(`div`,{className:e.length===1?`space-y-2 mb-4`:`grid grid-cols-2 gap-2 mb-4`,children:e.map((e,t)=>(0,Q.jsx)(`code`,{className:`block font-mono text-sm sm:text-base font-semibold bg-gray-100 dark:bg-gray-800 text-blue-600 dark:text-blue-400 px-4 py-3 rounded-xl text-center tracking-widest break-all select-all border border-gray-200 dark:border-gray-700`,children:e},t))}),(0,Q.jsxs)(`div`,{className:`flex gap-2`,children:[(0,Q.jsx)(h,{fill:!0,icon:(0,Q.jsx)(c,{size:14}),text:t?i(`account.totp.copied`,`Copied!`):i(`account.totp.copyKeys`,`Copy All Keys`),intent:t?y.SUCCESS:y.NONE,onClick:n}),(0,Q.jsx)(h,{fill:!0,intent:y.PRIMARY,text:i(`account.totp.done`,`Done`),onClick:r})]})]})},ye=({authConfig:e,turnstileReady:t,onSuccess:n})=>{let[r,i]=(0,Z.useState)(`username`),[o,s]=(0,Z.useState)(``),[c,l]=(0,Z.useState)(``),[u,d]=(0,Z.useState)(``),[f,p]=(0,Z.useState)(null),[m,h]=(0,Z.useState)(null),[g,_]=(0,Z.useState)(!1),[v,y]=(0,Z.useState)(``),[b,x]=(0,Z.useState)(!1),[S,C]=(0,Z.useState)(!1),[w,T]=(0,Z.useState)(!1),[E,D]=(0,Z.useState)(!1),[k,A]=(0,Z.useState)(``),[P,I]=(0,Z.useState)(`choose`),[L,R]=(0,Z.useState)(!1),[z,V]=(0,Z.useState)(``),[U,W]=(0,Z.useState)(null),[q,J]=(0,Z.useState)(`idle`),Y=(0,Z.useRef)(null),X=(0,Z.useRef)(null),{t:Q}=a(),$=e?.turnstile_enabled_signup;(0,Z.useEffect)(()=>{if(r===`password`&&$&&e?.turnstile_site_key&&(t||window.turnstile)&&Y.current)try{X.current&&window.turnstile&&(window.turnstile.remove(X.current),X.current=null),J(`verifying`),Y.current.innerHTML=``,X.current=window.turnstile.render(Y.current,{sitekey:e.turnstile_site_key,callback:e=>{W(e),J(`success`),y(``)},"expired-callback":()=>{W(null),J(`idle`)},"error-callback":e=>{console.error(`Turnstile error:`,e),J(`error`),y(Q(`auth.turnstileError`,`Verification service failed to load. Please reload and try again.`)),W(null)}})}catch(e){console.error(`Turnstile render error:`,e),J(`error`)}return()=>{X.current&&window.turnstile&&(window.turnstile.remove(X.current),X.current=null)}},[$,e,r,t,Q]);let se=async e=>{if(!(!e||!ae(e)))try{await O(e)?y(Q(`auth.usernameExists`)):y(e=>e===Q(`auth.usernameExists`)?``:e)}catch(e){console.error(`Failed to check username duplicate`,e)}},ce=async e=>{if(e.preventDefault(),!ae(o)){y(Q(`auth.formatTipUsername`));return}_(!0),y(``);try{await O(o)?y(Q(`auth.usernameExists`)):i(`password`)}catch{y(Q(`auth.networkError`))}finally{_(!1)}},le=async()=>{D(!0),A(``);try{p(await F()),i(`totp`)}catch(e){console.error(`Network error during signup TOTP setup:`,e),n()}finally{D(!1)}};return{signupStep:r,setSignupStep:i,username:o,setUsername:s,password:c,setPassword:l,mfaChoice:P,setMfaChoice:I,passkeyRegLoading:L,passkeyRegError:z,handleRegisterPasskey:async()=>{R(!0),V(``);try{let e=await ee({name:`primary_passkey`,credential:await te(await j())}),t=e?.passkey?.id||e?.id;if(t&&G.isUnlocked())try{await G.wrapCurrentKeyForPasskey(t)}catch(e){console.warn(`Failed to wrap key for new passkey:`,e)}e.recovery_keys&&e.recovery_keys.length>0&&h(e.recovery_keys),i(`recovery`)}catch(e){console.error(`Passkey registration failed:`,e),V(B(e,Q))}finally{R(!1)}},handleChooseTotp:async()=>{I(`totp`),await le()},totpSetupToken:u,setTotpSetupToken:d,totpSetupData:f,setTotpSetupData:p,totpRecoveryKeys:m,setTotpRecoveryKeys:h,loading:g,error:v,setError:y,usernameFocused:b,setUsernameFocused:x,passwordFocused:S,setPasswordFocused:C,copiedRecovery:w,totpSetupLoading:E,totpSetupError:k,turnstileStatus:q,turnstileRef:Y,isTurnstileEnabled:$,checkUsernameDuplicate:se,handleSignupUsernameSubmit:ce,handleSignupTotpConfirm:async e=>{if(e.preventDefault(),f){D(!0),A(``);try{let e=u.replace(/\s/g,``),t=crypto.randomUUID(),n=await K(e,t),r=await ie({secret:f.secret,totpTokenHash:n,salt:t});r.recovery_keys&&r.recovery_keys.length>0&&h(r.recovery_keys),i(`recovery`)}catch(e){A(e.message||Q(`common.errorNetwork`))}finally{D(!1)}}},handleCopySignupRecoveryKeys:()=>{m&&navigator.clipboard.writeText(m.join(`
1
+ import{i as e}from"./rolldown-runtime-C4Xdq4VV.js";import{$ as t,Ct as n,E as r,Q as i,Qt as a,gt as o,j as s,lt as c}from"./vendor-react-BmoHsW1x.js";import{S as l,b as u}from"./vendor-icons-other-Bme3ywH9.js";import"./vendor-i18next-BKUzkAKP.js";import{A as d,B as f,H as p,L as m,N as h,O as g,R as _,S as v,V as y,f as b,m as x,p as S,r as C,v as w,x as T,z as E}from"./vendor-ui-core-CY_WyMIf.js";import{_t as D}from"./vendor-utils-BWSB0jGn.js";import{$t as O,C as k,Ft as A,Jt as ee,Mt as j,O as M,Qt as N,S as P,Vt as F,Xt as I,Zt as te,_ as L,an as R,b as z,d as B,en as V,f as H,g as ne,h as U,i as W,j as G,m as K,r as q,rn as J,sn as re,u as Y,wt as ie,x as ae,y as oe}from"./index-CP2FJpkF.js";import{t as X}from"./QRCodeCanvas-DQ-xNuwF.js";var Z=e(l(),1),Q=e(u(),1);const $=({username:e,setUsername:t,isTurnstileEnabled:n,turnstileRef:r,loading:i,turnstileStatus:o,onSubmit:s})=>{let{t:c}=a();return(0,Q.jsxs)(`form`,{onSubmit:s,className:`space-y-4`,children:[(0,Q.jsx)(S,{label:c(`auth.username`),labelFor:`username`,children:(0,Q.jsx)(b,{id:`username`,leftIcon:`user`,placeholder:c(`auth.usernamePlaceholder`),size:`large`,className:`rounded-xl w-full`,value:e,onChange:e=>t(e.target.value),autoFocus:!0,required:!0})}),n&&(0,Q.jsx)(`div`,{className:`py-2 flex justify-center min-h-16.25`,children:(0,Q.jsx)(`div`,{ref:r})}),(0,Q.jsx)(h,{fill:!0,size:`large`,intent:y.PRIMARY,type:`submit`,loading:i||o===`verifying`,disabled:!!n&&o!==`success`,className:`mt-6 font-bold py-6 rounded-xl shadow-lg shadow-blue-500/20`,children:o===`verifying`?c(`auth.verifying`):c(`auth.next`,`Next`)})]})},se=({password:e,setPassword:t,hasMfa:n,onSwitchToMfa:r,loading:i,onSubmit:o,keepLoggedIn:s,setKeepLoggedIn:c,optionalSessionExpirationDays:l})=>{let[u,d]=Z.useState(!1),{t:f}=a();return(0,Q.jsxs)(`form`,{onSubmit:o,className:`space-y-4`,children:[(0,Q.jsx)(S,{label:f(`auth.password`),labelFor:`password`,children:(0,Q.jsx)(b,{id:`password`,leftIcon:`lock`,placeholder:f(`auth.passwordPlaceholder`),type:u?`text`:`password`,size:`large`,className:`rounded-xl`,value:e,onChange:e=>t(e.target.value),rightElement:(()=>(0,Q.jsxs)(`div`,{className:`flex items-center`,children:[e&&(0,Q.jsx)(h,{minimal:!0,icon:`cross`,onClick:()=>t(``)}),(0,Q.jsx)(h,{minimal:!0,icon:u?`eye-open`:`eye-off`,onClick:()=>d(!u),title:u?f(`auth.hidePassword`,`Hide password`):f(`auth.showPassword`,`Show password`)})]}))(),autoFocus:!0,required:!0})}),(0,Q.jsx)(x,{checked:s,onChange:e=>c(e.currentTarget.checked),label:f(`auth.keepLoggedIn`,`Keep me logged in for {{days}} days`,{days:l}),className:`mt-4 text-left`}),(0,Q.jsxs)(`div`,{className:`pt-2 space-y-3`,children:[(0,Q.jsx)(h,{fill:!0,size:`large`,intent:y.PRIMARY,type:`submit`,loading:i,className:`font-bold py-6 rounded-xl shadow-lg shadow-blue-500/20`,children:n?f(`auth.next`,`Next`):f(`auth.loginBtn`,`Login`)}),n&&r&&(0,Q.jsx)(h,{fill:!0,minimal:!0,size:`large`,type:`button`,disabled:i,onClick:r,className:`font-medium text-blue-600 dark:text-blue-400 py-2.5 rounded-xl transition-colors hover:bg-blue-50 dark:hover:bg-blue-950/30`,children:f(`auth.otherOptions`,`其他选项`)})]})]})},ce=({value:e,onChange:t,disabled:n=!1,autoFocus:r=!0,className:i=``})=>{let{t:o}=a(),s=(0,Z.useRef)([]),c=(e=>{let t=e.replace(/\D/g,``).slice(0,30),n=[];for(let e=0;e<5;e++)n.push(t.slice(e*6,(e+1)*6));return n})(e);(0,Z.useEffect)(()=>{r&&s.current[0]&&s.current[0].focus()},[r]);let l=(e,n)=>{let r=n.replace(/\D/g,``).slice(0,6),i=[...c];i[e]=r,t(i.join(`-`)),r.length===6&&e<4&&s.current[e+1]?.focus()},u=(e,t)=>{if(t.key===`Backspace`&&c[e].length===0&&e>0){t.preventDefault();let n=s.current[e-1];n&&n.focus()}else t.key===`ArrowLeft`&&(t.currentTarget.selectionStart??0)===0&&e>0?(t.preventDefault(),s.current[e-1]?.focus()):t.key===`ArrowRight`&&(t.currentTarget.selectionStart??0)===c[e].length&&e<4&&(t.preventDefault(),s.current[e+1]?.focus())},d=(e,n)=>{let r=n.clipboardData.getData(`text`).replace(/\D/g,``);if(r.length>6){n.preventDefault();let i=[...c],a=0;for(let t=e;t<5&&a<r.length;t++){let e=r.slice(a,a+6);i[t]=e,a+=e.length}t(i.join(`-`));let o=Math.min(4,e+Math.ceil(r.length/6)-1);s.current[o]?.focus()}},f=c.map((e,t)=>e.length===6&&!z(e)?t:-1).filter(e=>e!==-1);return(0,Q.jsxs)(`div`,{className:`space-y-2 ${i}`,children:[(0,Q.jsx)(`div`,{className:`flex items-center justify-between gap-1 sm:gap-2`,children:c.map((e,t)=>{let r=e.length===6,i=r&&!z(e),a=r&&!i,c=`border-gray-300 dark:border-gray-600 focus:border-blue-500 focus:ring-2 focus:ring-blue-500/20`;return i?c=`border-red-500 ring-2 ring-red-500/30 bg-red-50/40 dark:bg-red-950/20 text-red-600 dark:text-red-400`:a&&(c=`border-green-500/80 dark:border-green-500/60 bg-green-50/20 dark:bg-green-950/10 text-gray-900 dark:text-gray-100`),(0,Q.jsxs)(Z.Fragment,{children:[(0,Q.jsx)(`input`,{ref:e=>{s.current[t]=e},type:`text`,inputMode:`numeric`,pattern:`[0-9]*`,maxLength:6,value:e,disabled:n,autoComplete:`off`,autoCorrect:`off`,autoCapitalize:`off`,spellCheck:!1,"data-1p-ignore":`true`,"data-lpignore":`true`,"data-bwignore":`true`,onChange:e=>l(t,e.target.value),onKeyDown:e=>u(t,e),onPaste:e=>d(t,e),className:`w-full min-w-0 text-center font-mono text-xs sm:text-sm tracking-wider py-2 sm:py-2.5 px-1 rounded-lg border transition-all duration-150 outline-none ${c}`,title:i?o(`auth.recoveryChecksumError`,{defaultValue:`校验码错误:该组 6 位数无法被 11 整除`,group:t+1}):void 0}),t<4&&(0,Q.jsx)(`span`,{className:`text-gray-400 dark:text-gray-500 font-bold select-none text-xs`,children:`-`})]},t)})}),f.length>0&&(0,Q.jsx)(`p`,{className:`text-xs text-red-500 dark:text-red-400 text-center font-medium mt-1`,children:o(`auth.recoveryChecksumErrorDesc`,{defaultValue:`第 {{groups}} 组校验码错误,请核对后重试`,groups:f.map(e=>e+1).join(`、`)})})]})},le=({hasPasskey:e,requiresTotp:n,mfaMethod:r,setMfaMethod:o,passkeyLoading:s,onPasskeyLogin:c,totpToken:l,setTotpToken:u,recoveryKey:d,setRecoveryKey:f,loading:p,onClearError:m,onSubmit:g,keepLoggedIn:_,setKeepLoggedIn:v,optionalSessionExpirationDays:b})=>{let{t:C}=a(),w=e=>{o(e),m()};return(0,Q.jsxs)(`form`,{onSubmit:e=>{if(e.preventDefault(),r===`passkey`){c();return}g(e)},className:`space-y-4`,children:[r===`passkey`&&(0,Q.jsxs)(`div`,{className:`space-y-5 text-center py-2`,children:[(0,Q.jsx)(`div`,{className:`mx-auto w-16 h-16 rounded-2xl bg-blue-50 dark:bg-blue-950/40 flex items-center justify-center text-blue-600 dark:text-blue-400`,children:(0,Q.jsx)(i,{size:36})}),(0,Q.jsxs)(`div`,{className:`space-y-1`,children:[(0,Q.jsx)(`h4`,{className:`text-base font-semibold text-gray-900 dark:text-gray-100 m-0`,children:C(`auth.passkeyVerification`,`Passkey Verification`)}),(0,Q.jsx)(`p`,{className:`text-xs text-gray-500 dark:text-gray-400 max-w-xs mx-auto leading-relaxed`,children:C(`auth.passkeyPromptDesc`,`Use your registered device's biometric or hardware security key to verify`)})]}),(0,Q.jsx)(x,{checked:_,onChange:e=>v(e.currentTarget.checked),label:C(`auth.keepLoggedIn`,`Keep me logged in for {{days}} days`,{days:b}),className:`text-left inline-block mt-2`}),(0,Q.jsxs)(`div`,{className:`pt-2 space-y-3`,children:[(0,Q.jsxs)(h,{fill:!0,size:`large`,intent:y.PRIMARY,type:`button`,loading:s,disabled:p,onClick:c,className:`font-semibold py-6 rounded-xl shadow-lg shadow-blue-500/20 flex items-center justify-center space-x-2`,children:[(0,Q.jsx)(i,{size:20,className:`inline mr-1.5`}),(0,Q.jsx)(`span`,{children:C(`auth.verifyWithPasskey`,`Verify with Passkey`)})]}),n&&(0,Q.jsx)(h,{fill:!0,minimal:!0,size:`large`,type:`button`,disabled:s||p,onClick:()=>w(`totp`),className:`font-medium text-blue-600 dark:text-blue-400 py-2.5 rounded-xl transition-colors hover:bg-blue-50 dark:hover:bg-blue-950/30`,children:C(`auth.otherOptions`,`Other Options`)}),(0,Q.jsx)(`div`,{className:`pt-1`,children:(0,Q.jsxs)(`button`,{type:`button`,onClick:()=>w(`recovery`),className:`text-xs text-gray-500 hover:text-blue-600 dark:hover:text-blue-400 hover:underline bg-transparent border-none cursor-pointer p-0 font-normal inline-flex items-center gap-1`,children:[(0,Q.jsx)(t,{size:12}),(0,Q.jsx)(`span`,{children:C(`auth.totpUseRecovery`,`Use Recovery Key`)})]})})]})]}),r===`totp`&&(0,Q.jsxs)(`div`,{className:`space-y-4`,children:[(0,Q.jsx)(S,{label:C(`account.totp.title`,`Time-based One-time Password (TOTP)`),helperText:C(`auth.totpPrompt`,`Please enter the 6-digit code from your authentication app`),children:(0,Q.jsx)(`div`,{className:`pt-2`,children:(0,Q.jsx)(W,{length:6,value:l,onChange:u,disabled:p,autoFocus:!0})})}),(0,Q.jsx)(x,{checked:_,onChange:e=>v(e.currentTarget.checked),label:C(`auth.keepLoggedIn`,`Keep me logged in for {{days}} days`,{days:b}),className:`mt-4 text-left`}),(0,Q.jsxs)(`div`,{className:`pt-2 space-y-3`,children:[(0,Q.jsx)(h,{fill:!0,size:`large`,intent:y.PRIMARY,type:`submit`,loading:p,className:`font-bold py-6 rounded-xl shadow-lg shadow-blue-500/20`,children:C(`auth.loginBtn`,`Login`)}),e&&(0,Q.jsx)(h,{fill:!0,minimal:!0,size:`large`,type:`button`,disabled:p,onClick:()=>w(`passkey`),className:`font-medium text-blue-600 dark:text-blue-400 py-2.5 rounded-xl transition-colors hover:bg-blue-50 dark:hover:bg-blue-950/30`,children:C(`auth.otherOptions`,`Other Options`)}),(0,Q.jsx)(`div`,{className:`text-center pt-1`,children:(0,Q.jsxs)(`button`,{type:`button`,onClick:()=>w(`recovery`),className:`text-xs text-gray-500 hover:text-blue-600 dark:hover:text-blue-400 hover:underline bg-transparent border-none cursor-pointer p-0 font-normal inline-flex items-center gap-1`,children:[(0,Q.jsx)(t,{size:12}),(0,Q.jsx)(`span`,{children:C(`auth.totpUseRecovery`,`Use Recovery Key`)})]})})]})]}),r===`recovery`&&(0,Q.jsxs)(`div`,{className:`space-y-4`,children:[(0,Q.jsx)(S,{label:C(`account.totp.recoveryKeysTitle`,`Recovery Keys`),helperText:C(`auth.recoveryPrompt`,`Please enter your 30-character recovery key (5 groups of 6 digits)`),children:(0,Q.jsx)(`div`,{className:`pt-2`,children:(0,Q.jsx)(ce,{value:d,onChange:f,disabled:p,autoFocus:!0})})}),(0,Q.jsx)(x,{checked:_,onChange:e=>v(e.currentTarget.checked),label:C(`auth.keepLoggedIn`,`Keep me logged in for {{days}} days`,{days:b}),className:`mt-4 text-left`}),(0,Q.jsxs)(`div`,{className:`pt-2 space-y-3`,children:[(0,Q.jsx)(h,{fill:!0,size:`large`,intent:y.PRIMARY,type:`submit`,loading:p,className:`font-bold py-6 rounded-xl shadow-lg shadow-blue-500/20`,children:C(`auth.loginBtn`,`Login`)}),(0,Q.jsx)(`div`,{className:`text-center pt-1`,children:(0,Q.jsx)(`button`,{type:`button`,onClick:()=>w(e?`passkey`:`totp`),className:`text-xs text-blue-600 dark:text-blue-400 hover:underline bg-transparent border-none cursor-pointer p-0 font-normal`,children:e?C(`auth.backToPasskey`,`Back to Passkey Verification`):C(`auth.totpUseApp`,`Use Authentication App`)})})]})]})]})};function ue({siteKey:e,enabled:t,turnstileReady:n,isActive:r,onError:i,onClearError:o}){let[s,c]=(0,Z.useState)(null),[l,u]=(0,Z.useState)(`idle`),d=(0,Z.useRef)(null),f=(0,Z.useRef)(null),{t:p}=a();return(0,Z.useEffect)(()=>{if(r&&t&&e&&(n||window.turnstile)&&d.current)try{f.current&&window.turnstile&&(window.turnstile.remove(f.current),f.current=null),u(`verifying`),d.current.innerHTML=``,f.current=window.turnstile.render(d.current,{sitekey:e,callback:e=>{c(e),u(`success`),o()},"expired-callback":()=>{c(null),u(`idle`)},"error-callback":e=>{console.error(`Turnstile error:`,e),u(`error`),i(p(`auth.turnstileError`,`Verification service failed to load. Please reload and try again.`)),c(null)}})}catch(e){console.error(`Turnstile render error:`,e),u(`error`)}return()=>{f.current&&window.turnstile&&(window.turnstile.remove(f.current),f.current=null)}},[r,t,e,n,p,i,o]),{turnstileToken:s,setTurnstileToken:c,turnstileStatus:l,turnstileRef:d,resetTurnstile:()=>{window.turnstile&&f.current&&window.turnstile.reset(f.current),c(null),u(`idle`)}}}function de({username:e,password:t,passwordVersion:n,nonce:r,serverSalt:i,keepLoggedIn:o,onSuccess:s}){let[c,l]=(0,Z.useState)(!1),[u,d]=(0,Z.useState)(``),[f,p]=(0,Z.useState)(null),{t:m}=a();return{loading:c,error:u,setError:d,rotatedRecoveryKey:f,setRotatedRecoveryKey:p,executeLogin:async a=>{l(!0),d(``);try{let c={keepLoggedIn:o,passkeyAssertion:a.passkeyAssertion,totpTokenHash:a.totpTokenHash,totpSalt:a.totpSalt,recoveryKey:a.recoveryKey};if(a.useEnteredPassword&&t)if(n===2){if(!r||!i)throw Error(m(`auth.sessionExpired`,`Session expired, please start over`));c.password=await U(await Y(await H(t,e),i),r)}else c.password=t;let l=await J(c);if(l.accessToken&&M(l.accessToken),l.needsMigration&&t&&await A(await H(t,e),t),l.rotatedRecoveryKey&&a.recoveryKey){try{await G.unlockWithRecoveryKey(a.recoveryKey),await G.wrapCurrentKeyForRecovery(l.rotatedRecoveryKey)}catch(e){console.warn(`[Login] Could not auto re-wrap E2EE key with rotated recovery key:`,e)}p(l.rotatedRecoveryKey);return}s()}catch(e){e instanceof N&&ne({status:e.status},e.bodyText)?d(m(`auth.passwordLeaked`)):d(B(e,m))}finally{l(!1)}}}}function fe({hasPasswordEntered:e,passkeyOptions:t,executeLogin:n,onError:r}){let[i,o]=(0,Z.useState)(`passkey`),[s,c]=(0,Z.useState)(``),[l,u]=(0,Z.useState)(``),[d,f]=(0,Z.useState)(!1),{t:p}=a();return{mfaMethod:i,setMfaMethod:o,totpToken:s,setTotpToken:c,recoveryKey:l,setRecoveryKey:u,passkeyLoading:d,setPasskeyLoading:f,handlePasskeyLogin:async()=>{if(t){f(!0),r(``);try{await n({useEnteredPassword:e,passkeyAssertion:await I(t)})}catch(e){console.error(`Passkey authentication error:`,e),r(B(e,p))}finally{f(!1)}}},handleStep3Submit:async t=>{if(t.preventDefault(),i===`totp`){let t=s.replace(/\s/g,``);if(t.length!==6){r(p(`auth.totpFormatError`,`Please enter a valid 6-digit code`));return}let i=crypto.randomUUID();await n({useEnteredPassword:e,totpTokenHash:await K(t,i),totpSalt:i})}else if(i===`recovery`){let t=l.replace(/[-\s]/g,``);if(!t){r(p(`auth.recoveryKeyRequired`,`Please enter your recovery key`));return}await n({useEnteredPassword:e,recoveryKey:t})}},resetMfaFields:()=>{c(``),u(``),f(!1),o(`passkey`)}}}const pe=({authConfig:e,turnstileReady:t,onSuccess:n})=>{let{t:r}=a(),[i,o]=(0,Z.useState)(1),[s,c]=(0,Z.useState)(``),[l,u]=(0,Z.useState)(``),[d,f]=(0,Z.useState)(!1),[p,m]=(0,Z.useState)(1),[h,g]=(0,Z.useState)(void 0),[_,v]=(0,Z.useState)(void 0),[y,b]=(0,Z.useState)(!0),[x,S]=(0,Z.useState)(!1),[C,w]=(0,Z.useState)(!1),[T,E]=(0,Z.useState)(null),{loading:D,error:O,setError:k,rotatedRecoveryKey:A,setRotatedRecoveryKey:ee,executeLogin:j}=de({username:s,password:l,passwordVersion:p,nonce:h,serverSalt:_,keepLoggedIn:d,onSuccess:n}),[M,N]=(0,Z.useState)(!1),P=D||M,F=e?.turnstile_enabled_login,{turnstileToken:I,turnstileStatus:te,turnstileRef:L,resetTurnstile:z}=ue({siteKey:e?.turnstile_site_key,enabled:F,turnstileReady:t,isActive:i===1,onError:k,onClearError:()=>k(``)}),{mfaMethod:V,setMfaMethod:H,totpToken:ne,setTotpToken:U,recoveryKey:W,setRecoveryKey:G,passkeyLoading:K,handlePasskeyLogin:q,handleStep3Submit:J,resetMfaFields:re}=fe({hasPasswordEntered:!!l,passkeyOptions:T,executeLogin:j,onError:k}),Y=async t=>{if(t.preventDefault(),!ae(s)){k(r(`auth.formatTipUsername`));return}if(F&&e?.turnstile_site_key&&!I){k(r(`auth.turnstileRequired`));return}N(!0),k(``);try{let e=await R({username:s,turnstileToken:I});b(e.requires_password),S(e.requires_totp),w(!!e.has_passkey),E(e.passkey_options||null),m(e.password_version??1),g(e.nonce),v(e.serverSalt),H(e.has_passkey?`passkey`:`totp`),e.requires_password?o(2):o(3)}catch(e){k(B(e,r)),z()}finally{N(!1)}},ie=async e=>{if(e.preventDefault(),!l){k(r(`auth.passwordRequiredFirst`,`Please enter your password first`));return}C||x?(k(``),o(3),H(C?`passkey`:`totp`)):await j({useEnteredPassword:!0})},oe=()=>{u(``),k(``),o(3),H(C?`passkey`:`totp`)},X=()=>{o(1),u(``),k(``),g(void 0),v(void 0),w(!1),E(null),re(),z()};return{loginStep:i,username:s,setUsername:c,password:l,setPassword:u,totpToken:ne,setTotpToken:U,recoveryKey:W,setRecoveryKey:G,requiresPassword:y,requiresTotp:x,hasPasskey:C,mfaMethod:V,setMfaMethod:H,passkeyLoading:K,loading:P,error:O,setError:k,turnstileStatus:te,turnstileRef:L,isTurnstileEnabled:F,keepLoggedIn:d,setKeepLoggedIn:f,handleStep1Submit:Y,handleStep2Submit:ie,handleStep3Submit:J,handleSwitchToMfa:oe,handlePasskeyLogin:q,handleBack:()=>{k(``),i===2?X():i===3&&(y?o(2):X())},resetToStep1:X,rotatedRecoveryKey:A,handleAcknowledgeRotatedKey:()=>{ee(null),n()}}},me=({authConfig:e,turnstileReady:t,onSuccess:r,onToggleMode:i})=>{let{t:l}=a(),{loginStep:u,username:f,setUsername:p,password:b,setPassword:x,totpToken:S,setTotpToken:C,recoveryKey:w,setRecoveryKey:T,requiresTotp:D,hasPasskey:O,mfaMethod:k,setMfaMethod:A,passkeyLoading:ee,loading:j,error:M,setError:N,turnstileStatus:F,turnstileRef:I,isTurnstileEnabled:te,keepLoggedIn:L,setKeepLoggedIn:R,handleStep1Submit:z,handleStep2Submit:B,handleStep3Submit:V,handleSwitchToMfa:H,handlePasskeyLogin:ne,handleBack:U,rotatedRecoveryKey:W,handleAcknowledgeRotatedKey:G}=pe({authConfig:e,turnstileReady:t,onSuccess:r}),[K,q]=(0,Z.useState)(!1),J=e=>{navigator.clipboard.writeText(e),q(!0),setTimeout(()=>q(!1),2e3)};return(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsxs)(`div`,{className:`flex flex-col items-center mb-8 relative`,children:[u!==1&&(0,Q.jsx)(`button`,{type:`button`,onClick:U,className:`absolute left-0 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-700 dark:hover:text-gray-200 bg-transparent border-none cursor-pointer p-1 rounded-lg transition-colors`,title:l(`common.back`,`返回`),children:(0,Q.jsx)(n,{size:24})}),(0,Q.jsx)(`img`,{src:P,alt:`DNS Worker Logo`,className:`w-20 h-20 object-contain`}),(0,Q.jsx)(d,{className:`font-bold tracking-tight text-2xl mt-4`,children:(()=>{switch(u){case 1:return l(`auth.login`);case 2:return l(`auth.password`);case 3:return l(`auth.mfaVerification`,`多因素认证`)}})()}),(0,Q.jsx)(`p`,{className:`text-gray-500 mt-2 text-center text-sm leading-relaxed`,children:u===1?l(`auth.protectInternet`):f})]}),e?.has_users===!1&&(0,Q.jsx)(v,{intent:y.PRIMARY,icon:`info-sign`,className:`mb-6 rounded-xl`,children:(0,Q.jsxs)(`div`,{className:`flex flex-col sm:flex-row items-start sm:items-center justify-between gap-3`,children:[(0,Q.jsx)(`span`,{className:`text-sm font-medium`,children:l(`auth.noUsersRegistered`,`系统尚无账号,请注册成为管理员。`)}),(0,Q.jsx)(`button`,{type:`button`,onClick:i,className:`text-xs bg-blue-600 hover:bg-blue-700 text-white font-semibold py-1.5 px-3 rounded-lg border-none cursor-pointer whitespace-nowrap transition-colors`,children:l(`auth.goToRegisterAdmin`,`注册管理员`)})]})}),M&&(0,Q.jsx)(v,{intent:y.DANGER,className:`mb-6 rounded-xl`,title:l(`auth.error`),children:M}),u===1&&(0,Q.jsx)($,{username:f,setUsername:p,isTurnstileEnabled:te,turnstileRef:I,loading:j,turnstileStatus:F,onSubmit:z}),u===2&&(0,Q.jsx)(se,{password:b,setPassword:x,hasMfa:O||D,onSwitchToMfa:H,loading:j,onSubmit:B,keepLoggedIn:L,setKeepLoggedIn:R,optionalSessionExpirationDays:e?.optional_session_expiration_days??7}),u===3&&(0,Q.jsx)(le,{hasPasskey:O,requiresTotp:D,mfaMethod:k,setMfaMethod:A,passkeyLoading:ee,onPasskeyLogin:ne,totpToken:S,setTotpToken:C,recoveryKey:w,setRecoveryKey:T,loading:j,onClearError:()=>N(``),onSubmit:V,keepLoggedIn:L,setKeepLoggedIn:R,optionalSessionExpirationDays:e?.optional_session_expiration_days??7}),u===1&&(e?.has_users===!1||e?.registration_enabled!==!1)&&(0,Q.jsx)(`div`,{className:`mt-8 pt-6 border-t border-gray-100 dark:border-gray-800 flex justify-center items-center text-sm`,children:(0,Q.jsx)(`button`,{onClick:i,className:`text-blue-600 dark:text-blue-400 font-semibold hover:underline bg-transparent border-none cursor-pointer`,children:l(`auth.noAccount`)})}),(0,Q.jsxs)(g,{isOpen:!!W,onClose:G,title:l(`account.recoveryKey.autoRotatedTitle`,`恢复密钥已自动轮换`),icon:`warning-sign`,isCloseButtonShown:!1,canOutsideClickClose:!1,className:`dark:bg-gray-900`,children:[(0,Q.jsxs)(`div`,{className:m,children:[(0,Q.jsx)(v,{intent:y.WARNING,icon:(0,Q.jsx)(s,{size:16}),className:`mb-4 text-xs`,children:l(`account.recoveryKey.autoRotatedNotice`,`根据恢复密钥单次使用规则,您的原恢复密钥已失效,系统已为您生成全新 30 位紧急恢复密钥。请务必立即复制并妥善离线保存,关闭后将无法再次查看!`)}),W&&(0,Q.jsxs)(`div`,{className:`space-y-3`,children:[(0,Q.jsx)(`div`,{className:`p-3 bg-gray-100 dark:bg-gray-800 rounded border border-gray-200 dark:border-gray-700 font-mono text-center text-lg font-bold tracking-widest select-all text-gray-900 dark:text-gray-100`,children:W}),(0,Q.jsx)(`div`,{className:`flex justify-center`,children:(0,Q.jsx)(h,{intent:y.PRIMARY,icon:K?(0,Q.jsx)(o,{size:14,className:`text-green-400`}):(0,Q.jsx)(c,{size:14}),text:K?l(`common.copied`,`已复制`):l(`common.copyKey`,`复制新恢复密钥`),onClick:()=>J(W)})})]})]}),(0,Q.jsx)(`div`,{className:_,children:(0,Q.jsx)(`div`,{className:E,children:(0,Q.jsx)(h,{intent:y.SUCCESS,onClick:G,text:l(`account.recoveryKey.savedAndContinue`,`我已妥善保存并进入控制台`)})})})]})]})},he=({username:e,setUsername:t,usernameFocused:n,setUsernameFocused:r,checkUsernameDuplicate:i,loading:o,onSubmit:s,onClearError:c})=>{let{t:l}=a();return(0,Q.jsxs)(`form`,{onSubmit:s,className:`space-y-4`,children:[(0,Q.jsx)(S,{label:l(`auth.username`),labelFor:`username`,children:(0,Q.jsx)(w,{content:l(`auth.formatTipUsername`),isOpen:n,position:f.TOP,intent:y.PRIMARY,className:`w-full`,children:(0,Q.jsx)(`div`,{className:`w-full block`,children:(0,Q.jsx)(b,{id:`username`,leftIcon:`user`,placeholder:l(`auth.usernamePlaceholder`),size:`large`,className:`rounded-xl w-full`,value:e,onChange:e=>{t(e.target.value),c()},onFocus:()=>r(!0),onBlur:()=>{r(!1),i(e)},autoFocus:!0,required:!0})})})}),(0,Q.jsx)(h,{fill:!0,size:`large`,intent:y.PRIMARY,type:`submit`,loading:o,className:`mt-6 font-bold py-6 rounded-xl shadow-lg shadow-blue-500/20`,children:l(`auth.next`,`Next`)})]})},ge=({password:e,setPassword:t,passwordFocused:n,setPasswordFocused:r,loading:i,onSubmit:o,isTurnstileEnabled:s,turnstileRef:c,turnstileStatus:l})=>{let[u,d]=Z.useState(!1),{t:p}=a();return(0,Q.jsxs)(`form`,{onSubmit:o,className:`space-y-4`,children:[(0,Q.jsx)(S,{label:p(`auth.password`),labelFor:`password`,children:(0,Q.jsx)(w,{content:p(`auth.formatTipPassword`),isOpen:n,position:f.TOP,intent:y.PRIMARY,className:`w-full`,children:(0,Q.jsx)(`div`,{className:`w-full block`,children:(0,Q.jsx)(b,{id:`password`,leftIcon:`lock`,placeholder:p(`auth.passwordPlaceholder`),type:u?`text`:`password`,size:`large`,className:`rounded-xl w-full`,value:e,onChange:e=>t(e.target.value),onFocus:()=>r(!0),onBlur:()=>r(!1),rightElement:(()=>(0,Q.jsxs)(`div`,{className:`flex items-center`,children:[e&&(0,Q.jsx)(h,{minimal:!0,icon:`cross`,onClick:()=>t(``)}),(0,Q.jsx)(h,{minimal:!0,icon:u?`eye-open`:`eye-off`,onClick:()=>d(!u),title:u?p(`auth.hidePassword`,`Hide password`):p(`auth.showPassword`,`Show password`)})]}))(),required:!0,autoFocus:!0})})})}),s&&(0,Q.jsx)(`div`,{className:`py-2 flex justify-center min-h-16.25`,children:(0,Q.jsx)(`div`,{ref:c})}),(0,Q.jsx)(h,{fill:!0,size:`large`,intent:y.PRIMARY,type:`submit`,loading:i||l===`verifying`,disabled:!!s&&l!==`success`,className:`mt-6 font-bold py-6 rounded-xl shadow-lg shadow-blue-500/20`,children:p(l===`verifying`?`auth.verifying`:`auth.signupBtn`)})]})},_e=({mfaChoice:e,setMfaChoice:t,onRegisterPasskey:o,passkeyRegLoading:s,passkeyRegError:c,onStartTotp:l,totpSetupData:u,totpSetupToken:d,setTotpSetupToken:f,totpSetupError:m,totpSetupLoading:g,onTotpSubmit:_,onSkip:b})=>{let{t:x}=a();return e===`choose`?(0,Q.jsxs)(`div`,{className:`space-y-4`,children:[c&&(0,Q.jsx)(v,{intent:y.DANGER,className:`rounded-xl`,children:c}),(0,Q.jsxs)(`div`,{className:`space-y-3`,children:[(0,Q.jsxs)(T,{elevation:p.ONE,className:`p-4 rounded-xl border border-blue-100 dark:border-blue-900/40 hover:border-blue-300 dark:hover:border-blue-700 transition-colors cursor-pointer`,onClick:s?void 0:o,children:[(0,Q.jsx)(`div`,{className:`flex items-start justify-between`,children:(0,Q.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,Q.jsx)(`div`,{className:`p-2.5 bg-blue-50 dark:bg-blue-950/40 text-blue-600 dark:text-blue-400 rounded-xl`,children:(0,Q.jsx)(i,{size:24})}),(0,Q.jsxs)(`div`,{children:[(0,Q.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,Q.jsx)(`h4`,{className:`text-sm font-bold text-gray-800 dark:text-gray-100 m-0`,children:x(`account.passkey.title`,`通行密钥 (Passkey)`)}),(0,Q.jsx)(C,{intent:y.PRIMARY,minimal:!0,round:!0,children:x(`auth.mfaRecommended`,`推荐 · 无密码`)})]}),(0,Q.jsx)(`div`,{className:`text-xs text-blue-600 dark:text-blue-400 font-mono mt-0.5`,children:window.location.hostname}),(0,Q.jsx)(`p`,{className:`text-xs text-gray-500 dark:text-gray-400 mt-1 mb-0 leading-relaxed`,children:x(`auth.passkeySignupDesc`,`使用本设备生物识别 (Touch ID / Face ID / Windows Hello) 或硬件密钥 (YubiKey),一键快捷且防钓鱼。`)})]})]})}),(0,Q.jsx)(`div`,{className:`mt-3 text-right`,children:(0,Q.jsx)(h,{intent:y.PRIMARY,loading:s,text:x(`auth.bindPasskeyNow`,`绑定通行密钥`),className:`rounded-lg font-medium`})})]}),(0,Q.jsxs)(T,{elevation:p.ONE,className:`p-4 rounded-xl border border-gray-100 dark:border-gray-800 hover:border-gray-300 dark:hover:border-gray-700 transition-colors cursor-pointer`,onClick:l,children:[(0,Q.jsx)(`div`,{className:`flex items-start justify-between`,children:(0,Q.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,Q.jsx)(`div`,{className:`p-2.5 bg-purple-50 dark:bg-purple-950/40 text-purple-600 dark:text-purple-400 rounded-xl`,children:(0,Q.jsx)(r,{size:24})}),(0,Q.jsxs)(`div`,{children:[(0,Q.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,Q.jsx)(`h4`,{className:`text-sm font-bold text-gray-800 dark:text-gray-100 m-0`,children:x(`auth.mfaMethodTotp`,`数字验证器 (TOTP)`)}),(0,Q.jsx)(C,{intent:y.NONE,minimal:!0,round:!0,children:x(`auth.mfaUniversal`,`通用应用`)})]}),(0,Q.jsx)(`p`,{className:`text-xs text-gray-500 dark:text-gray-400 mt-1 mb-0 leading-relaxed`,children:x(`account.totp.setupDesc`,`使用 Google Authenticator、1Password 等验证器应用扫码绑定 6 位动态验证码。`)})]})]})}),(0,Q.jsx)(`div`,{className:`mt-3 text-right`,children:(0,Q.jsx)(h,{minimal:!0,text:x(`auth.setupTotpBtn`,`扫码配置验证器`),className:`rounded-lg font-medium text-gray-700 dark:text-gray-200`})})]})]}),(0,Q.jsx)(`div`,{className:`text-center pt-2`,children:(0,Q.jsx)(h,{minimal:!0,text:x(`auth.skipMfaSetup`,`跳过多因素认证配置,直接进入系统`),onClick:b,className:`text-xs text-gray-400 hover:text-gray-600 dark:hover:text-gray-200`})})]}):(0,Q.jsxs)(`div`,{className:`space-y-4`,children:[(0,Q.jsx)(`div`,{className:`flex items-center justify-between`,children:(0,Q.jsxs)(`button`,{type:`button`,onClick:()=>t(`choose`),className:`text-xs text-blue-600 hover:underline flex items-center gap-1 bg-transparent border-none cursor-pointer p-0`,children:[(0,Q.jsx)(n,{size:14}),(0,Q.jsx)(`span`,{children:x(`auth.backToMfaOptions`,`选择其他认证方式`)})]})}),u&&(0,Q.jsxs)(`div`,{className:`flex flex-col items-center gap-3`,children:[(0,Q.jsx)(X,{uri:u.uri}),(0,Q.jsxs)(`div`,{className:`text-center`,children:[(0,Q.jsx)(`p`,{className:`text-xs text-gray-500 mb-1`,children:x(`account.totp.orEnterManually`,`Or enter the key manually:`)}),(0,Q.jsx)(`code`,{className:`text-xs font-mono bg-gray-100 dark:bg-gray-800 px-2 py-1 rounded select-all`,children:u.secret})]})]}),m&&(0,Q.jsx)(v,{intent:y.DANGER,className:`rounded-xl`,children:m}),(0,Q.jsxs)(`form`,{onSubmit:_,className:`space-y-4`,children:[(0,Q.jsx)(S,{label:x(`account.totp.enterCode`,`Enter the 6-digit code:`),helperText:x(`account.totp.enterCodeHint`,`Enter the 6-digit code to confirm.`),children:(0,Q.jsx)(W,{length:6,value:d,onChange:f,disabled:g,autoFocus:!0})}),(0,Q.jsx)(h,{fill:!0,size:`large`,intent:y.PRIMARY,type:`submit`,loading:g,disabled:d.length!==6,className:`rounded-xl font-bold py-3`,children:x(`account.totp.activate`,`Activate`)})]})]})},ve=({totpRecoveryKeys:e,copiedRecovery:t,onCopy:n,onSuccess:r})=>{let{t:i}=a();return Z.useEffect(()=>{let e=e=>{e.key===`Enter`&&r()};return window.addEventListener(`keydown`,e),()=>{window.removeEventListener(`keydown`,e)}},[r]),(0,Q.jsxs)(`div`,{className:`space-y-4`,children:[(0,Q.jsx)(`div`,{className:e.length===1?`space-y-2 mb-4`:`grid grid-cols-2 gap-2 mb-4`,children:e.map((e,t)=>(0,Q.jsx)(`code`,{className:`block font-mono text-sm sm:text-base font-semibold bg-gray-100 dark:bg-gray-800 text-blue-600 dark:text-blue-400 px-4 py-3 rounded-xl text-center tracking-widest break-all select-all border border-gray-200 dark:border-gray-700`,children:e},t))}),(0,Q.jsxs)(`div`,{className:`flex gap-2`,children:[(0,Q.jsx)(h,{fill:!0,icon:(0,Q.jsx)(c,{size:14}),text:t?i(`account.totp.copied`,`Copied!`):i(`account.totp.copyKeys`,`Copy All Keys`),intent:t?y.SUCCESS:y.NONE,onClick:n}),(0,Q.jsx)(h,{fill:!0,intent:y.PRIMARY,text:i(`account.totp.done`,`Done`),onClick:r})]})]})},ye=({authConfig:e,turnstileReady:t,onSuccess:n})=>{let[r,i]=(0,Z.useState)(`username`),[o,s]=(0,Z.useState)(``),[c,l]=(0,Z.useState)(``),[u,d]=(0,Z.useState)(``),[f,p]=(0,Z.useState)(null),[m,h]=(0,Z.useState)(null),[g,_]=(0,Z.useState)(!1),[v,y]=(0,Z.useState)(``),[b,x]=(0,Z.useState)(!1),[S,C]=(0,Z.useState)(!1),[w,T]=(0,Z.useState)(!1),[E,D]=(0,Z.useState)(!1),[k,A]=(0,Z.useState)(``),[P,I]=(0,Z.useState)(`choose`),[L,R]=(0,Z.useState)(!1),[z,V]=(0,Z.useState)(``),[U,W]=(0,Z.useState)(null),[q,J]=(0,Z.useState)(`idle`),Y=(0,Z.useRef)(null),X=(0,Z.useRef)(null),{t:Q}=a(),$=e?.turnstile_enabled_signup;(0,Z.useEffect)(()=>{if(r===`password`&&$&&e?.turnstile_site_key&&(t||window.turnstile)&&Y.current)try{X.current&&window.turnstile&&(window.turnstile.remove(X.current),X.current=null),J(`verifying`),Y.current.innerHTML=``,X.current=window.turnstile.render(Y.current,{sitekey:e.turnstile_site_key,callback:e=>{W(e),J(`success`),y(``)},"expired-callback":()=>{W(null),J(`idle`)},"error-callback":e=>{console.error(`Turnstile error:`,e),J(`error`),y(Q(`auth.turnstileError`,`Verification service failed to load. Please reload and try again.`)),W(null)}})}catch(e){console.error(`Turnstile render error:`,e),J(`error`)}return()=>{X.current&&window.turnstile&&(window.turnstile.remove(X.current),X.current=null)}},[$,e,r,t,Q]);let se=async e=>{if(!(!e||!ae(e)))try{await O(e)?y(Q(`auth.usernameExists`)):y(e=>e===Q(`auth.usernameExists`)?``:e)}catch(e){console.error(`Failed to check username duplicate`,e)}},ce=async e=>{if(e.preventDefault(),!ae(o)){y(Q(`auth.formatTipUsername`));return}_(!0),y(``);try{await O(o)?y(Q(`auth.usernameExists`)):i(`password`)}catch{y(Q(`auth.networkError`))}finally{_(!1)}},le=async()=>{D(!0),A(``);try{p(await F()),i(`totp`)}catch(e){console.error(`Network error during signup TOTP setup:`,e),n()}finally{D(!1)}};return{signupStep:r,setSignupStep:i,username:o,setUsername:s,password:c,setPassword:l,mfaChoice:P,setMfaChoice:I,passkeyRegLoading:L,passkeyRegError:z,handleRegisterPasskey:async()=>{R(!0),V(``);try{let e=await ee({name:`primary_passkey`,credential:await te(await j())}),t=e?.passkey?.id||e?.id;if(t&&G.isUnlocked())try{await G.wrapCurrentKeyForPasskey(t)}catch(e){console.warn(`Failed to wrap key for new passkey:`,e)}e.recovery_keys&&e.recovery_keys.length>0&&h(e.recovery_keys),i(`recovery`)}catch(e){console.error(`Passkey registration failed:`,e),V(B(e,Q))}finally{R(!1)}},handleChooseTotp:async()=>{I(`totp`),await le()},totpSetupToken:u,setTotpSetupToken:d,totpSetupData:f,setTotpSetupData:p,totpRecoveryKeys:m,setTotpRecoveryKeys:h,loading:g,error:v,setError:y,usernameFocused:b,setUsernameFocused:x,passwordFocused:S,setPasswordFocused:C,copiedRecovery:w,totpSetupLoading:E,totpSetupError:k,turnstileStatus:q,turnstileRef:Y,isTurnstileEnabled:$,checkUsernameDuplicate:se,handleSignupUsernameSubmit:ce,handleSignupTotpConfirm:async e=>{if(e.preventDefault(),f){D(!0),A(``);try{let e=u.replace(/\s/g,``),t=crypto.randomUUID(),n=await K(e,t),r=await ie({secret:f.secret,totpTokenHash:n,salt:t});r.recovery_keys&&r.recovery_keys.length>0&&h(r.recovery_keys),i(`recovery`)}catch(e){A(e.message||Q(`common.errorNetwork`))}finally{D(!1)}}},handleCopySignupRecoveryKeys:()=>{m&&navigator.clipboard.writeText(m.join(`
2
2
  `)).then(()=>{T(!0),setTimeout(()=>T(!1),2e3)})},handleSignupSubmit:async t=>{if(t.preventDefault(),!ae(o)){y(Q(`auth.formatTipUsername`));return}if(!oe(c)){y(Q(`auth.formatTipPassword`));return}if($&&e?.turnstile_site_key&&!U){y(Q(`auth.turnstileRequired`));return}_(!0),y(``);try{let e=await re({username:o,password:await H(c,o),turnstileToken:U});e.accessToken&&M(e.accessToken),e.recoveryKey&&h([e.recoveryKey]),I(`choose`),i(`totp`)}catch(e){e instanceof N&&ne({status:e.status},e.bodyText)?y(Q(`auth.passwordLeaked`)):y(B(e,Q)),window.turnstile&&window.turnstile.reset(),W(null)}finally{_(!1)}}}},be=({authConfig:e,turnstileReady:t,onSuccess:r,onToggleMode:i})=>{let{t:o}=a(),{signupStep:s,setSignupStep:c,username:l,setUsername:u,password:f,setPassword:p,mfaChoice:m,setMfaChoice:h,passkeyRegLoading:g,passkeyRegError:_,handleRegisterPasskey:b,handleChooseTotp:x,totpSetupToken:S,setTotpSetupToken:C,totpSetupData:w,totpRecoveryKeys:T,loading:E,error:D,setError:O,usernameFocused:k,setUsernameFocused:A,passwordFocused:ee,setPasswordFocused:j,copiedRecovery:M,totpSetupLoading:N,totpSetupError:F,turnstileStatus:I,turnstileRef:te,isTurnstileEnabled:L,checkUsernameDuplicate:R,handleSignupUsernameSubmit:z,handleSignupTotpConfirm:B,handleCopySignupRecoveryKeys:V,handleSignupSubmit:H}=ye({authConfig:e,turnstileReady:t,onSuccess:r});return e&&e.has_users!==!1&&e.registration_enabled===!1?(0,Q.jsxs)(`div`,{className:`space-y-6 text-center`,children:[(0,Q.jsxs)(`div`,{className:`flex flex-col items-center`,children:[(0,Q.jsx)(`img`,{src:P,alt:`DNS Worker Logo`,className:`w-20 h-20 object-contain`}),(0,Q.jsx)(d,{className:`font-bold tracking-tight text-2xl mt-4`,children:o(`auth.signup`)})]}),(0,Q.jsx)(v,{intent:y.WARNING,icon:`lock`,title:o(`auth.registrationDisabledTitle`,`注册已停用`),children:o(`auth.registrationDisabledDesc`,`当前系统已暂停开放新用户注册,请联系系统管理员分配账号。`)}),(0,Q.jsx)(`div`,{className:`pt-4 border-t border-gray-100 dark:border-gray-800 flex justify-center items-center text-sm`,children:(0,Q.jsxs)(`button`,{onClick:i,className:`text-blue-600 dark:text-blue-400 font-semibold hover:underline bg-transparent border-none cursor-pointer flex items-center gap-1`,children:[(0,Q.jsx)(n,{size:16}),o(`auth.backToLogin`,`返回登录`)]})})]}):(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsxs)(`div`,{className:`flex flex-col items-center mb-8 relative`,children:[s===`password`&&(0,Q.jsx)(`button`,{onClick:()=>{c(`username`),O(``)},className:`absolute left-0 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-700 dark:hover:text-gray-200 bg-transparent border-none cursor-pointer`,title:`Back to username`,children:(0,Q.jsx)(n,{size:24})}),(0,Q.jsx)(`img`,{src:P,alt:`DNS Worker Logo`,className:`w-20 h-20 object-contain`}),(0,Q.jsx)(d,{className:`font-bold tracking-tight text-2xl mt-4`,children:s===`username`||s===`password`?e?.has_users===!1?o(`auth.registerAdminTitle`,`注册管理员账号`):o(`auth.signup`):s===`totp`?o(`auth.mfaSetupTitle`,`配置多因素认证 (MFA)`):o(`account.totp.recoveryKeysTitle`,`Save Recovery Keys`)}),(0,Q.jsx)(`p`,{className:`text-gray-500 mt-2 text-center text-sm leading-relaxed`,children:s===`username`||s===`password`?s===`password`?l:e?.has_users===!1?o(`auth.registerAdminDesc`,`系统尚无账号,首位注册用户将自动成为系统管理员。`):o(`auth.protectInternet`):s===`totp`?o(`auth.mfaSetupDesc`,`任选一种认证方式即可完成配置,保障账号安全。`):o(`account.totp.recoveryKeysWarning`,`Store keys safely.`)})]}),D&&(0,Q.jsx)(v,{intent:y.DANGER,className:`mb-6 rounded-xl`,title:o(`auth.error`),children:D}),s===`username`&&(0,Q.jsx)(he,{username:l,setUsername:u,usernameFocused:k,setUsernameFocused:A,checkUsernameDuplicate:R,loading:E,onSubmit:z,onClearError:()=>O(e=>e===o(`auth.usernameExists`)?``:e)}),s===`password`&&(0,Q.jsx)(ge,{password:f,setPassword:p,passwordFocused:ee,setPasswordFocused:j,loading:E,onSubmit:H,isTurnstileEnabled:L,turnstileRef:te,turnstileStatus:I}),s===`totp`&&(0,Q.jsx)(_e,{mfaChoice:m,setMfaChoice:h,onRegisterPasskey:b,passkeyRegLoading:g,passkeyRegError:_,onStartTotp:x,totpSetupData:w,totpSetupToken:S,setTotpSetupToken:C,totpSetupError:F,totpSetupLoading:N,onTotpSubmit:B,onSkip:()=>{T&&T.length>0?c(`recovery`):r()}}),s===`recovery`&&T&&(0,Q.jsx)(ve,{totpRecoveryKeys:T,copiedRecovery:M,onCopy:V,onSuccess:r}),s===`username`&&(0,Q.jsx)(`div`,{className:`mt-8 pt-6 border-t border-gray-100 dark:border-gray-800 text-center`,children:(0,Q.jsx)(`button`,{onClick:i,className:`text-blue-600 dark:text-blue-400 font-semibold hover:underline bg-transparent border-none cursor-pointer text-sm`,children:o(`auth.haveAccount`)})})]})},xe=({onSuccess:e})=>{let[t,n]=(0,Z.useState)(!0),[r,i]=(0,Z.useState)(!0),[o,s]=(0,Z.useState)(!1),{t:c}=a(),l=()=>{s(!0),setTimeout(()=>{n(e=>!e),s(!1)},300)},[u,d]=(0,Z.useState)(null),[f,m]=(0,Z.useState)(!1);(0,Z.useEffect)(()=>{(async()=>{try{let e=await V();d(e),e&&e.has_users===!1&&n(!1)}catch(e){console.error(`Failed to load auth config`,e)}})()},[]);let g=t?u?.turnstile_enabled_login:u?.turnstile_enabled_signup;return(0,Z.useEffect)(()=>{g&&u?.turnstile_site_key&&L(()=>{m(!0)})},[g,u]),(0,Q.jsxs)(`div`,{className:`flex flex-row min-h-screen bg-white dark:bg-gray-950 overflow-hidden relative`,children:[(0,Q.jsx)(`div`,{className:`hidden lg:block w-1/2 h-screen overflow-hidden border-r border-gray-100 dark:border-gray-900`,children:(0,Q.jsx)(q,{})}),(0,Q.jsx)(`div`,{className:`lg:hidden absolute inset-0 z-0 transition-opacity duration-500 cursor-pointer ${r?`opacity-25`:`opacity-70`}`,onClick:()=>i(!0),children:(0,Q.jsx)(q,{})}),!r&&(0,Q.jsx)(`div`,{className:`lg:hidden fixed bottom-12 left-1/2 -translate-x-1/2 z-50 animate-bounce`,children:(0,Q.jsx)(h,{large:!0,intent:`primary`,icon:`log-in`,text:c(`auth.loginBtn`),onClick:()=>i(!0),className:`shadow-2xl px-8 py-4 rounded-full`})}),(0,Q.jsxs)(`div`,{className:`flex-1 flex items-center justify-center p-4 relative z-10 bg-gray-50/50 dark:bg-gray-900/30 lg:bg-gray-50 lg:dark:bg-gray-900/50 transition-all duration-500 ease-in-out ${r?`translate-x-0 opacity-100`:`max-lg:translate-x-full max-lg:opacity-0 max-lg:pointer-events-none`}`,onClick:e=>{window.innerWidth<1024&&e.target===e.currentTarget&&i(!1)},children:[(0,Q.jsx)(`div`,{className:`absolute top-4 right-4 z-50`,children:(0,Q.jsx)(k,{})}),(0,Q.jsx)(`div`,{className:D(`w-full max-w-md transition-all duration-200 ease-in-out transform-gpu`,o?`blur-lg opacity-20 scale-95`:`blur-0 opacity-100 scale-100`),children:(0,Q.jsx)(T,{elevation:p.FOUR,className:`w-full p-8 rounded-2xl shadow-none! z-10 dark:bg-gray-900 border border-gray-100 dark:border-gray-800`,onClick:e=>e.stopPropagation(),children:t?(0,Q.jsx)(me,{authConfig:u,turnstileReady:f,onSuccess:e,onToggleMode:l}):(0,Q.jsx)(be,{authConfig:u,turnstileReady:f,onSuccess:e,onToggleMode:l})})})]})]})};export{xe as AuthView};
@@ -1 +1 @@
1
- import{i as e}from"./rolldown-runtime-C4Xdq4VV.js";import{L as t,Qt as n,_ as r,d as i,f as a,g as o,i as s,m as c,p as l,r as u,u as d,y as f}from"./vendor-react-BmoHsW1x.js";import{S as p,b as m}from"./vendor-icons-other-Bme3ywH9.js";import"./vendor-utils-BWSB0jGn.js";import{k as h,ot as g,z as _}from"./index-dXN_pYn1.js";import{n as v,t as y}from"./formatCountryName-CSBD8pP8.js";import{t as b}from"./getFlagEmoji-DRubsb7D.js";var x=e(p(),1);function S(e){let[t,n]=(0,x.useState)(null);(0,x.useEffect)(()=>{_().then(e=>{if(e&&e.objects){let t={};e.objects.countries&&(t.countries=e.objects.countries),e.objects.land&&(t.land=e.objects.land),e.objects=t}e&&e.objects&&e.objects.countries&&Array.isArray(e.objects.countries.geometries)&&e.objects.countries.geometries.forEach(e=>{e.id!==void 0&&e.id!==null&&(e.id=String(e.id).padStart(3,`0`))}),n(e)}).catch(e=>console.error(`Failed to load map topology`,e))},[]);let r=(0,x.useMemo)(()=>e.reduce((e,t)=>e+t.count,0),[e]),i=(0,x.useMemo)(()=>{if(r<=0)return{maxThreshold:10,step:1};if(r<=1e3)return{maxThreshold:100,step:10};let e=10**Math.floor(Math.log10(r));return{maxThreshold:e,step:e/10}},[r]);return{geographyData:t,destinationMap:(0,x.useMemo)(()=>{let t={};return e.forEach(e=>{if(e.country_code){let n=e.country_code.toUpperCase();t[n]={count:e.count,name:e.country,countryCode:n}}}),t},[e]),scaleConfig:i,getLevel:e=>!e||e<=0?0:Math.min(10,Math.floor(e/i.step)+1),formatNumber:e=>{if(e>=1e6){let t=e/1e6;return Number.isInteger(t)?`${t}M`:`${t.toFixed(1)}M`}if(e>=1e3){let t=e/1e3;return Number.isInteger(t)?`${t}K`:`${t.toFixed(1)}K`}return e.toString()}}}var C=e(m(),1);const w=({onZoomIn:e,onZoomOut:n,onReset:i})=>(0,C.jsxs)(`div`,{className:`absolute top-3 right-3 flex flex-col gap-1.5 bg-white/80 dark:bg-slate-950/80 backdrop-blur-md p-1.5 rounded-lg border border-gray-200/50 dark:border-slate-800/50 shadow-sm z-10`,children:[(0,C.jsx)(`button`,{type:`button`,onClick:e,className:`p-1.5 hover:bg-gray-100 dark:hover:bg-slate-800 rounded text-gray-600 dark:text-gray-300 transition-colors cursor-pointer`,title:`Zoom In`,children:(0,C.jsx)(r,{size:16})}),(0,C.jsx)(`button`,{type:`button`,onClick:n,className:`p-1.5 hover:bg-gray-100 dark:hover:bg-slate-800 rounded text-gray-600 dark:text-gray-300 transition-colors cursor-pointer`,title:`Zoom Out`,children:(0,C.jsx)(o,{size:16})}),(0,C.jsx)(`button`,{type:`button`,onClick:i,className:`p-1.5 hover:bg-gray-100 dark:hover:bg-slate-800 rounded text-gray-600 dark:text-gray-300 transition-colors cursor-pointer`,title:`Reset Zoom`,children:(0,C.jsx)(t,{size:16})})]}),T=({maxThreshold:e,formatNumber:t})=>{let{t:r}=n();return(0,C.jsxs)(`div`,{className:`sm:absolute sm:bottom-3 sm:left-3 relative m-3 sm:m-0 flex flex-col shrink-0 gap-1.5 bg-white/80 dark:bg-slate-950/80 backdrop-blur-md p-2 rounded-lg border border-gray-200/50 dark:border-slate-800/50 shadow-sm z-10 max-w-70`,children:[(0,C.jsx)(`span`,{className:`text-[9px] font-bold text-gray-500 dark:text-gray-400 uppercase tracking-wider`,children:r(`analytics.queries`)}),(0,C.jsx)(`div`,{className:`flex items-center gap-0.5`,children:Array.from({length:11}).map((e,t)=>(0,C.jsx)(`div`,{className:`w-4 h-2.5 rounded-sm border border-black/5 dark:border-white/5`,style:{backgroundColor:`var(--map-color-${t})`}},t))}),(0,C.jsxs)(`div`,{className:`flex justify-between text-[9px] text-gray-500 dark:text-gray-400 font-semibold px-0.5`,children:[(0,C.jsx)(`span`,{children:`0`}),(0,C.jsx)(`span`,{children:t(e/2)}),(0,C.jsxs)(`span`,{children:[t(e),`+`]})]})]})},E=({name:e,count:t,flag:r,x:i,y:a,countryCode:o,profileId:s,range:c,customRange:l,accessPointId:u,ispCache:d,onCacheIsp:p,isPinned:m,onClose:_})=>{let{t:v}=n(),y=(0,x.useRef)(null),[b,S]=(0,x.useState)({left:i,top:a-10,alignBottom:!1}),[w,T]=(0,x.useState)([]),[E,D]=(0,x.useState)(!1),O=(0,x.useRef)(d);O.current=d;let k=(0,x.useRef)(p);return k.current=p,(0,x.useEffect)(()=>{if(!o||!s)return;if(t<=0){T([]),D(!1);return}let e=O.current[o];if(e){T(e),D(!1);return}D(!0);let n=Math.floor(Date.now()/1e3),r,i=n,a=`?country_code=${o}&range=${c}`;if(c===`custom`&&l.start&&l.end)r=Math.floor(new Date(l.start).getTime()/1e3),i=Math.floor(new Date(l.end).getTime()/1e3),a+=`&start=${r}&end=${i}`;else switch(c){case`10m`:r=n-600;break;case`1h`:r=n-3600;break;case`24h`:r=n-86400;break;case`7d`:r=n-604800;break;case`30d`:r=n-2592e3;break;default:r=n-86400;break}u&&(a+=`&access_point_id=${u}`);let d=!0,f=setTimeout(async()=>{try{let e=await h.queryISPs({profileId:s,countryCode:o,since:r,until:i,accessPointId:u||void 0});if(e&&e.length>0){k.current(o,e),d&&(T(e),D(!1));return}}catch(e){console.warn(`[MapTooltip] Local SQLite ISP query failed, falling back to server:`,e)}g(s,`isps`,a).then(e=>{let t=Array.isArray(e)?e:[];k.current(o,t),d&&T(t)}).catch(e=>{console.error(`Failed to fetch ISPs`,e)}).finally(()=>{d&&D(!1)})},200);return()=>{d=!1,clearTimeout(f)}},[o,s,c,l,u,t]),(0,x.useEffect)(()=>{if(!m)return;let e=e=>{if(y.current&&!y.current.contains(e.target)){let t=e.target,n=t.classList.contains(`rsm-geography`)||t.closest(`.rsm-geography`),r=t.classList.contains(`map-marker-circle`)||t.closest(`.map-marker-circle`);!n&&!r&&_()}},t=setTimeout(()=>{document.addEventListener(`click`,e,!0)},0);return()=>{clearTimeout(t),document.removeEventListener(`click`,e,!0)}},[m,_]),(0,x.useLayoutEffect)(()=>{if(!y.current)return;let e=y.current.getBoundingClientRect(),t=y.current.parentElement;if(!t)return;let n=t.getBoundingClientRect(),r=i,o=e.width/2;i-o<4?r=o+4:i+o>n.width-4&&(r=n.width-o-4);let s=a-10,c=!1;a-e.height-15<4&&(s=a+15,c=!0),S({left:r,top:s,alignBottom:c})},[i,a,w]),(0,C.jsxs)(`div`,{ref:y,onMouseLeave:m?_:void 0,className:`absolute bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm px-3 py-2 rounded-lg shadow-xl border border-gray-200/50 dark:border-slate-800/50 text-xs z-50 flex flex-col gap-1 transition-all duration-75 text-gray-900 dark:text-gray-100 ${m?`pointer-events-auto cursor-default`:`pointer-events-none`}`,style:{left:`${b.left}px`,top:`${b.top}px`,transform:b.alignBottom?`translate(-50%, 0)`:`translate(-50%, -100%)`},children:[(0,C.jsxs)(`div`,{className:`flex items-center justify-between gap-4`,children:[(0,C.jsxs)(`div`,{className:`flex flex-col gap-0.5`,children:[(0,C.jsxs)(`div`,{className:`flex items-center gap-1.5 font-semibold whitespace-nowrap`,children:[(0,C.jsx)(`span`,{className:`text-sm`,children:r}),(0,C.jsx)(`span`,{children:e})]}),(0,C.jsxs)(`div`,{className:`text-gray-500 dark:text-gray-400 whitespace-nowrap`,children:[t.toLocaleString(),` `,v(`analytics.queries`)]})]}),m&&(0,C.jsx)(`button`,{onClick:e=>{e.stopPropagation(),_()},className:`flex items-center justify-center p-2 rounded-lg border border-gray-200 dark:border-slate-800 text-gray-500 hover:text-red-500 hover:bg-red-50 dark:hover:bg-red-950/20 hover:border-red-200 dark:hover:border-red-900/50 transition-colors cursor-pointer self-stretch aspect-square`,title:v(`common.close`,`Close`),children:(0,C.jsx)(f,{size:18})})]}),E?(0,C.jsxs)(`div`,{className:`mt-1.5 pt-1.5 border-t border-gray-150 dark:border-slate-850 flex flex-col gap-1 min-w-36`,children:[(0,C.jsx)(`div`,{className:`text-[10px] uppercase font-bold text-gray-400 dark:text-gray-500 tracking-wider`,children:v(`analytics.topIsps`,`Top ISPs`)}),(0,C.jsx)(`div`,{className:`text-[11px] text-gray-400 dark:text-gray-500 italic`,children:v(`analytics.loading`,`Loading...`)})]}):w.length>0&&(0,C.jsxs)(`div`,{className:`mt-1.5 pt-1.5 border-t border-gray-150 dark:border-slate-800 flex flex-col gap-1`,children:[(0,C.jsx)(`div`,{className:`text-[10px] uppercase font-bold text-gray-400 dark:text-gray-500 tracking-wider`,children:v(`analytics.topIsps`,`Top ISPs`)}),(0,C.jsxs)(`div`,{className:`flex flex-col gap-0.5 min-w-36 max-w-48 ${m?`max-h-36 overflow-y-auto pr-1`:``}`,children:[(m?w:w.slice(0,5)).map(e=>(0,C.jsxs)(`div`,{className:`flex justify-between gap-3 text-[11px] text-gray-600 dark:text-gray-300`,children:[(0,C.jsx)(`span`,{className:`truncate`,title:e.name,children:e.name}),(0,C.jsx)(`span`,{className:`font-mono text-gray-400 dark:text-gray-500`,children:e.count.toLocaleString()})]},e.name)),!m&&w.length>5&&(0,C.jsxs)(C.Fragment,{children:[(0,C.jsx)(`div`,{className:`text-center text-gray-400 dark:text-gray-500 leading-none py-0.5 font-bold`,children:`...`}),(0,C.jsx)(`div`,{className:`text-[10px] text-center text-blue-500 dark:text-blue-400 font-medium whitespace-nowrap mt-0.5`,children:v(`analytics.pressToShowMore`,`Click to show more`)})]})]})]})]})},D=({geographyData:e,destinationMap:t,getLevel:r,containerRef:a,hoveredCountry:o,setHoveredCountry:s})=>{let{i18n:c}=n();return e?(0,C.jsx)(i,{geography:e,children:({geographies:e})=>e.map(e=>{let n=e.id==null?void 0:v[String(e.id)],i=n?t[n]:null,l=i?.count||0,u=r(l);return(0,C.jsx)(d,{geography:e,onMouseEnter:e=>{if(!n||o?.isPinned)return;let t=y(n,c.language)||i?.name||n,r=b(n),u=a.current?.getBoundingClientRect();s({name:t,code:n,count:l,flag:r,x:e.clientX-(u?.left||0),y:e.clientY-(u?.top||0)-15})},onMouseMove:e=>{s(t=>{if(t?.isPinned)return t;let n=a.current?.getBoundingClientRect(),r=e.clientX-(n?.left||0),i=e.clientY-(n?.top||0)-15;return t?{...t,x:r,y:i}:null})},onMouseLeave:()=>{s(e=>e?.isPinned?e:null)},onClick:e=>{if(e.stopPropagation(),!n)return;let t=y(n,c.language)||i?.name||n,r=b(n),o=a.current?.getBoundingClientRect(),u=e.clientX-(o?.left||0),d=e.clientY-(o?.top||0)-15;s(e=>e?.code===n&&e?.isPinned?null:{name:t,code:n,count:l,flag:r,x:u,y:d,isPinned:!0})},style:{default:{fill:`var(--map-color-${u})`,stroke:`var(--map-stroke)`,strokeWidth:.5,outline:`none`,transition:`fill 250ms, stroke 250ms`},hover:{fill:`var(--map-hover)`,stroke:`var(--map-stroke)`,strokeWidth:.5,outline:`none`,cursor:`pointer`},pressed:{fill:`var(--map-hover)`,stroke:`var(--map-stroke)`,strokeWidth:.5,outline:`none`}}},e.rsmKey)})}):null},O={SG:{name:`Singapore`,coordinates:[103.8198,1.3521]},HK:{name:`Hong Kong`,coordinates:[114.1694,22.3193]},MO:{name:`Macau`,coordinates:[113.5439,22.1987]},VA:{name:`Vatican City`,coordinates:[12.4534,41.9029]},MC:{name:`Monaco`,coordinates:[7.4246,43.7384]},SM:{name:`San Marino`,coordinates:[12.4578,43.9424]},LI:{name:`Liechtenstein`,coordinates:[9.5209,47.141]},AD:{name:`Andorra`,coordinates:[1.5218,42.5063]},MT:{name:`Malta`,coordinates:[14.3754,35.9375]},GI:{name:`Gibraltar`,coordinates:[-5.3536,36.1408]},BM:{name:`Bermuda`,coordinates:[-64.7505,32.3078]},MV:{name:`Maldives`,coordinates:[73.5089,4.1755]},MU:{name:`Mauritius`,coordinates:[57.5522,-20.3484]}},k=({destinationMap:e,getLevel:t,containerRef:r,hoveredCountry:i,setHoveredCountry:a})=>{let{i18n:o}=n();return(0,C.jsx)(C.Fragment,{children:Object.entries(O).map(([n,s])=>{let l=e[n],d=l?.count||0,f=t(d),p=d>0,m=p?4:1.5;return(0,C.jsx)(u,{coordinates:c(s.coordinates[0],s.coordinates[1]),onMouseEnter:e=>{if(i?.isPinned)return;let t=y(n,o.language)||l?.name||n,s=b(n),c=r.current?.getBoundingClientRect();a({name:t,code:n,count:d,flag:s,x:e.clientX-(c?.left||0),y:e.clientY-(c?.top||0)-15})},onMouseMove:e=>{a(t=>{if(t?.isPinned)return t;let n=r.current?.getBoundingClientRect(),i=e.clientX-(n?.left||0),a=e.clientY-(n?.top||0)-15;return t?{...t,x:i,y:a}:null})},onMouseLeave:()=>{a(e=>e?.isPinned?e:null)},onClick:e=>{e.stopPropagation();let t=y(n,o.language)||l?.name||n,i=b(n),s=r.current?.getBoundingClientRect(),c=e.clientX-(s?.left||0),u=e.clientY-(s?.top||0)-15;a(e=>e?.code===n&&e?.isPinned?null:{name:t,code:n,count:d,flag:i,x:c,y:u,isPinned:!0})},children:p?(0,C.jsxs)(C.Fragment,{children:[(0,C.jsx)(`circle`,{r:m+3,fill:`var(--map-color-${f})`,opacity:.4,className:`animate-ping map-marker-circle`}),(0,C.jsx)(`circle`,{r:m,fill:`var(--map-color-${f})`,stroke:`var(--map-stroke)`,strokeWidth:.75,style:{cursor:`pointer`},className:`map-marker-circle`})]}):(0,C.jsx)(`circle`,{r:m,fill:`var(--text-color)`,opacity:.25,style:{pointerEvents:`none`}})},n)})})},A=({destinations:e,profileId:t,range:n,customRange:r,accessPointId:i})=>{let{geographyData:o,destinationMap:u,scaleConfig:d,getLevel:f,formatNumber:p}=S(e),[m,h]=(0,x.useState)({coordinates:c(0,0),zoom:1.2}),[g,_]=(0,x.useState)(null),[v,y]=(0,x.useState)(null),[b,O]=(0,x.useState)({}),A=(0,x.useRef)(null);A.current=g,(0,x.useEffect)(()=>{if(!g){y(null);return}if(g.isPinned){y(g);return}if(v&&v.code===g.code)return;let e=setTimeout(()=>{A.current&&A.current.code===g.code&&y(A.current)},100);return()=>clearTimeout(e)},[g?.code,g?.isPinned,v?.code]),(0,x.useEffect)(()=>{g&&v&&g.code===v.code&&(g.x!==v.x||g.y!==v.y||g.isPinned!==v.isPinned)&&y(g)},[g?.x,g?.y,g?.isPinned,v]);let j=(0,x.useRef)(null);x.useEffect(()=>{O({})},[t,n,r,i]);let M=x.useCallback((e,t)=>{O(n=>({...n,[e]:t}))},[]),N=x.useMemo(()=>l(c(-100,-50),c(900,600)),[]);return(0,C.jsxs)(`div`,{className:`relative w-full min-h-85 max-h-120 aspect-800/566 bg-gray-50 dark:bg-slate-950 rounded-xl overflow-hidden border border-gray-100 dark:border-slate-800 flex flex-col justify-between shadow-sm`,children:[(0,C.jsxs)(`div`,{ref:j,className:`relative w-full flex-1 min-h-0 overflow-hidden select-none cursor-grab active:cursor-grabbing`,onClick:e=>{(e.target===e.currentTarget||e.target.tagName===`svg`)&&_(null)},children:[(0,C.jsx)(a,{projection:`geoEqualEarth`,width:800,height:566,style:{width:`100%`,height:`100%`},children:(0,C.jsxs)(s,{zoom:m.zoom,center:m.coordinates,onMoveEnd:e=>h({coordinates:c(e.coordinates[0],e.coordinates[1]),zoom:e.zoom}),maxZoom:8,minZoom:1,enablePan:!0,translateExtent:N,children:[(0,C.jsx)(D,{geographyData:o,destinationMap:u,getLevel:f,containerRef:j,hoveredCountry:g,setHoveredCountry:_}),(0,C.jsx)(k,{destinationMap:u,getLevel:f,containerRef:j,hoveredCountry:g,setHoveredCountry:_})]})}),v&&(0,C.jsx)(E,{name:v.name,count:v.count,flag:v.flag,x:v.x,y:v.y,countryCode:v.code,profileId:t,range:n,customRange:r,accessPointId:i,ispCache:b,onCacheIsp:M,isPinned:v.isPinned||!1,onClose:()=>_(null)})]}),(0,C.jsx)(w,{onZoomIn:()=>{m.zoom>=8||h(e=>({...e,zoom:e.zoom*1.5}))},onZoomOut:()=>{m.zoom<=1||h(e=>({...e,zoom:e.zoom/1.5}))},onReset:()=>{h({coordinates:c(0,0),zoom:1.2})}}),(0,C.jsx)(T,{maxThreshold:d.maxThreshold,formatNumber:p})]})};export{A as DestinationMap};
1
+ import{i as e}from"./rolldown-runtime-C4Xdq4VV.js";import{L as t,Qt as n,_ as r,d as i,f as a,g as o,i as s,m as c,p as l,r as u,u as d,y as f}from"./vendor-react-BmoHsW1x.js";import{S as p,b as m}from"./vendor-icons-other-Bme3ywH9.js";import"./vendor-utils-BWSB0jGn.js";import{k as h,ot as g,z as _}from"./index-CP2FJpkF.js";import{n as v,t as y}from"./formatCountryName-CSBD8pP8.js";import{t as b}from"./getFlagEmoji-sHq5YwT3.js";var x=e(p(),1);function S(e){let[t,n]=(0,x.useState)(null);(0,x.useEffect)(()=>{_().then(e=>{if(e&&e.objects){let t={};e.objects.countries&&(t.countries=e.objects.countries),e.objects.land&&(t.land=e.objects.land),e.objects=t}e&&e.objects&&e.objects.countries&&Array.isArray(e.objects.countries.geometries)&&e.objects.countries.geometries.forEach(e=>{e.id!==void 0&&e.id!==null&&(e.id=String(e.id).padStart(3,`0`))}),n(e)}).catch(e=>console.error(`Failed to load map topology`,e))},[]);let r=(0,x.useMemo)(()=>e.reduce((e,t)=>e+t.count,0),[e]),i=(0,x.useMemo)(()=>{if(r<=0)return{maxThreshold:10,step:1};if(r<=1e3)return{maxThreshold:100,step:10};let e=10**Math.floor(Math.log10(r));return{maxThreshold:e,step:e/10}},[r]);return{geographyData:t,destinationMap:(0,x.useMemo)(()=>{let t={};return e.forEach(e=>{if(e.country_code){let n=e.country_code.toUpperCase();t[n]={count:e.count,name:e.country,countryCode:n}}}),t},[e]),scaleConfig:i,getLevel:e=>!e||e<=0?0:Math.min(10,Math.floor(e/i.step)+1),formatNumber:e=>{if(e>=1e6){let t=e/1e6;return Number.isInteger(t)?`${t}M`:`${t.toFixed(1)}M`}if(e>=1e3){let t=e/1e3;return Number.isInteger(t)?`${t}K`:`${t.toFixed(1)}K`}return e.toString()}}}var C=e(m(),1);const w=({onZoomIn:e,onZoomOut:n,onReset:i})=>(0,C.jsxs)(`div`,{className:`absolute top-3 right-3 flex flex-col gap-1.5 bg-white/80 dark:bg-slate-950/80 backdrop-blur-md p-1.5 rounded-lg border border-gray-200/50 dark:border-slate-800/50 shadow-sm z-10`,children:[(0,C.jsx)(`button`,{type:`button`,onClick:e,className:`p-1.5 hover:bg-gray-100 dark:hover:bg-slate-800 rounded text-gray-600 dark:text-gray-300 transition-colors cursor-pointer`,title:`Zoom In`,children:(0,C.jsx)(r,{size:16})}),(0,C.jsx)(`button`,{type:`button`,onClick:n,className:`p-1.5 hover:bg-gray-100 dark:hover:bg-slate-800 rounded text-gray-600 dark:text-gray-300 transition-colors cursor-pointer`,title:`Zoom Out`,children:(0,C.jsx)(o,{size:16})}),(0,C.jsx)(`button`,{type:`button`,onClick:i,className:`p-1.5 hover:bg-gray-100 dark:hover:bg-slate-800 rounded text-gray-600 dark:text-gray-300 transition-colors cursor-pointer`,title:`Reset Zoom`,children:(0,C.jsx)(t,{size:16})})]}),T=({maxThreshold:e,formatNumber:t})=>{let{t:r}=n();return(0,C.jsxs)(`div`,{className:`sm:absolute sm:bottom-3 sm:left-3 relative m-3 sm:m-0 flex flex-col shrink-0 gap-1.5 bg-white/80 dark:bg-slate-950/80 backdrop-blur-md p-2 rounded-lg border border-gray-200/50 dark:border-slate-800/50 shadow-sm z-10 max-w-70`,children:[(0,C.jsx)(`span`,{className:`text-[9px] font-bold text-gray-500 dark:text-gray-400 uppercase tracking-wider`,children:r(`analytics.queries`)}),(0,C.jsx)(`div`,{className:`flex items-center gap-0.5`,children:Array.from({length:11}).map((e,t)=>(0,C.jsx)(`div`,{className:`w-4 h-2.5 rounded-sm border border-black/5 dark:border-white/5`,style:{backgroundColor:`var(--map-color-${t})`}},t))}),(0,C.jsxs)(`div`,{className:`flex justify-between text-[9px] text-gray-500 dark:text-gray-400 font-semibold px-0.5`,children:[(0,C.jsx)(`span`,{children:`0`}),(0,C.jsx)(`span`,{children:t(e/2)}),(0,C.jsxs)(`span`,{children:[t(e),`+`]})]})]})},E=({name:e,count:t,flag:r,x:i,y:a,countryCode:o,profileId:s,range:c,customRange:l,accessPointId:u,ispCache:d,onCacheIsp:p,isPinned:m,onClose:_})=>{let{t:v}=n(),y=(0,x.useRef)(null),[b,S]=(0,x.useState)({left:i,top:a-10,alignBottom:!1}),[w,T]=(0,x.useState)([]),[E,D]=(0,x.useState)(!1),O=(0,x.useRef)(d);O.current=d;let k=(0,x.useRef)(p);return k.current=p,(0,x.useEffect)(()=>{if(!o||!s)return;if(t<=0){T([]),D(!1);return}let e=O.current[o];if(e){T(e),D(!1);return}D(!0);let n=Math.floor(Date.now()/1e3),r,i=n,a=`?country_code=${o}&range=${c}`;if(c===`custom`&&l.start&&l.end)r=Math.floor(new Date(l.start).getTime()/1e3),i=Math.floor(new Date(l.end).getTime()/1e3),a+=`&start=${r}&end=${i}`;else switch(c){case`10m`:r=n-600;break;case`1h`:r=n-3600;break;case`24h`:r=n-86400;break;case`7d`:r=n-604800;break;case`30d`:r=n-2592e3;break;default:r=n-86400;break}u&&(a+=`&access_point_id=${u}`);let d=!0,f=setTimeout(async()=>{try{let e=await h.queryISPs({profileId:s,countryCode:o,since:r,until:i,accessPointId:u||void 0});if(e&&e.length>0){k.current(o,e),d&&(T(e),D(!1));return}}catch(e){console.warn(`[MapTooltip] Local SQLite ISP query failed, falling back to server:`,e)}g(s,`isps`,a).then(e=>{let t=Array.isArray(e)?e:[];k.current(o,t),d&&T(t)}).catch(e=>{console.error(`Failed to fetch ISPs`,e)}).finally(()=>{d&&D(!1)})},200);return()=>{d=!1,clearTimeout(f)}},[o,s,c,l,u,t]),(0,x.useEffect)(()=>{if(!m)return;let e=e=>{if(y.current&&!y.current.contains(e.target)){let t=e.target,n=t.classList.contains(`rsm-geography`)||t.closest(`.rsm-geography`),r=t.classList.contains(`map-marker-circle`)||t.closest(`.map-marker-circle`);!n&&!r&&_()}},t=setTimeout(()=>{document.addEventListener(`click`,e,!0)},0);return()=>{clearTimeout(t),document.removeEventListener(`click`,e,!0)}},[m,_]),(0,x.useLayoutEffect)(()=>{if(!y.current)return;let e=y.current.getBoundingClientRect(),t=y.current.parentElement;if(!t)return;let n=t.getBoundingClientRect(),r=i,o=e.width/2;i-o<4?r=o+4:i+o>n.width-4&&(r=n.width-o-4);let s=a-10,c=!1;a-e.height-15<4&&(s=a+15,c=!0),S({left:r,top:s,alignBottom:c})},[i,a,w]),(0,C.jsxs)(`div`,{ref:y,onMouseLeave:m?_:void 0,className:`absolute bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm px-3 py-2 rounded-lg shadow-xl border border-gray-200/50 dark:border-slate-800/50 text-xs z-50 flex flex-col gap-1 transition-all duration-75 text-gray-900 dark:text-gray-100 ${m?`pointer-events-auto cursor-default`:`pointer-events-none`}`,style:{left:`${b.left}px`,top:`${b.top}px`,transform:b.alignBottom?`translate(-50%, 0)`:`translate(-50%, -100%)`},children:[(0,C.jsxs)(`div`,{className:`flex items-center justify-between gap-4`,children:[(0,C.jsxs)(`div`,{className:`flex flex-col gap-0.5`,children:[(0,C.jsxs)(`div`,{className:`flex items-center gap-1.5 font-semibold whitespace-nowrap`,children:[(0,C.jsx)(`span`,{className:`text-sm`,children:r}),(0,C.jsx)(`span`,{children:e})]}),(0,C.jsxs)(`div`,{className:`text-gray-500 dark:text-gray-400 whitespace-nowrap`,children:[t.toLocaleString(),` `,v(`analytics.queries`)]})]}),m&&(0,C.jsx)(`button`,{onClick:e=>{e.stopPropagation(),_()},className:`flex items-center justify-center p-2 rounded-lg border border-gray-200 dark:border-slate-800 text-gray-500 hover:text-red-500 hover:bg-red-50 dark:hover:bg-red-950/20 hover:border-red-200 dark:hover:border-red-900/50 transition-colors cursor-pointer self-stretch aspect-square`,title:v(`common.close`,`Close`),children:(0,C.jsx)(f,{size:18})})]}),E?(0,C.jsxs)(`div`,{className:`mt-1.5 pt-1.5 border-t border-gray-150 dark:border-slate-850 flex flex-col gap-1 min-w-36`,children:[(0,C.jsx)(`div`,{className:`text-[10px] uppercase font-bold text-gray-400 dark:text-gray-500 tracking-wider`,children:v(`analytics.topIsps`,`Top ISPs`)}),(0,C.jsx)(`div`,{className:`text-[11px] text-gray-400 dark:text-gray-500 italic`,children:v(`analytics.loading`,`Loading...`)})]}):w.length>0&&(0,C.jsxs)(`div`,{className:`mt-1.5 pt-1.5 border-t border-gray-150 dark:border-slate-800 flex flex-col gap-1`,children:[(0,C.jsx)(`div`,{className:`text-[10px] uppercase font-bold text-gray-400 dark:text-gray-500 tracking-wider`,children:v(`analytics.topIsps`,`Top ISPs`)}),(0,C.jsxs)(`div`,{className:`flex flex-col gap-0.5 min-w-36 max-w-48 ${m?`max-h-36 overflow-y-auto pr-1`:``}`,children:[(m?w:w.slice(0,5)).map(e=>(0,C.jsxs)(`div`,{className:`flex justify-between gap-3 text-[11px] text-gray-600 dark:text-gray-300`,children:[(0,C.jsx)(`span`,{className:`truncate`,title:e.name,children:e.name}),(0,C.jsx)(`span`,{className:`font-mono text-gray-400 dark:text-gray-500`,children:e.count.toLocaleString()})]},e.name)),!m&&w.length>5&&(0,C.jsxs)(C.Fragment,{children:[(0,C.jsx)(`div`,{className:`text-center text-gray-400 dark:text-gray-500 leading-none py-0.5 font-bold`,children:`...`}),(0,C.jsx)(`div`,{className:`text-[10px] text-center text-blue-500 dark:text-blue-400 font-medium whitespace-nowrap mt-0.5`,children:v(`analytics.pressToShowMore`,`Click to show more`)})]})]})]})]})},D=({geographyData:e,destinationMap:t,getLevel:r,containerRef:a,hoveredCountry:o,setHoveredCountry:s})=>{let{i18n:c}=n();return e?(0,C.jsx)(i,{geography:e,children:({geographies:e})=>e.map(e=>{let n=e.id==null?void 0:v[String(e.id)],i=n?t[n]:null,l=i?.count||0,u=r(l);return(0,C.jsx)(d,{geography:e,onMouseEnter:e=>{if(!n||o?.isPinned)return;let t=y(n,c.language)||i?.name||n,r=b(n),u=a.current?.getBoundingClientRect();s({name:t,code:n,count:l,flag:r,x:e.clientX-(u?.left||0),y:e.clientY-(u?.top||0)-15})},onMouseMove:e=>{s(t=>{if(t?.isPinned)return t;let n=a.current?.getBoundingClientRect(),r=e.clientX-(n?.left||0),i=e.clientY-(n?.top||0)-15;return t?{...t,x:r,y:i}:null})},onMouseLeave:()=>{s(e=>e?.isPinned?e:null)},onClick:e=>{if(e.stopPropagation(),!n)return;let t=y(n,c.language)||i?.name||n,r=b(n),o=a.current?.getBoundingClientRect(),u=e.clientX-(o?.left||0),d=e.clientY-(o?.top||0)-15;s(e=>e?.code===n&&e?.isPinned?null:{name:t,code:n,count:l,flag:r,x:u,y:d,isPinned:!0})},style:{default:{fill:`var(--map-color-${u})`,stroke:`var(--map-stroke)`,strokeWidth:.5,outline:`none`,transition:`fill 250ms, stroke 250ms`},hover:{fill:`var(--map-hover)`,stroke:`var(--map-stroke)`,strokeWidth:.5,outline:`none`,cursor:`pointer`},pressed:{fill:`var(--map-hover)`,stroke:`var(--map-stroke)`,strokeWidth:.5,outline:`none`}}},e.rsmKey)})}):null},O={SG:{name:`Singapore`,coordinates:[103.8198,1.3521]},HK:{name:`Hong Kong`,coordinates:[114.1694,22.3193]},MO:{name:`Macau`,coordinates:[113.5439,22.1987]},VA:{name:`Vatican City`,coordinates:[12.4534,41.9029]},MC:{name:`Monaco`,coordinates:[7.4246,43.7384]},SM:{name:`San Marino`,coordinates:[12.4578,43.9424]},LI:{name:`Liechtenstein`,coordinates:[9.5209,47.141]},AD:{name:`Andorra`,coordinates:[1.5218,42.5063]},MT:{name:`Malta`,coordinates:[14.3754,35.9375]},GI:{name:`Gibraltar`,coordinates:[-5.3536,36.1408]},BM:{name:`Bermuda`,coordinates:[-64.7505,32.3078]},MV:{name:`Maldives`,coordinates:[73.5089,4.1755]},MU:{name:`Mauritius`,coordinates:[57.5522,-20.3484]}},k=({destinationMap:e,getLevel:t,containerRef:r,hoveredCountry:i,setHoveredCountry:a})=>{let{i18n:o}=n();return(0,C.jsx)(C.Fragment,{children:Object.entries(O).map(([n,s])=>{let l=e[n],d=l?.count||0,f=t(d),p=d>0,m=p?4:1.5;return(0,C.jsx)(u,{coordinates:c(s.coordinates[0],s.coordinates[1]),onMouseEnter:e=>{if(i?.isPinned)return;let t=y(n,o.language)||l?.name||n,s=b(n),c=r.current?.getBoundingClientRect();a({name:t,code:n,count:d,flag:s,x:e.clientX-(c?.left||0),y:e.clientY-(c?.top||0)-15})},onMouseMove:e=>{a(t=>{if(t?.isPinned)return t;let n=r.current?.getBoundingClientRect(),i=e.clientX-(n?.left||0),a=e.clientY-(n?.top||0)-15;return t?{...t,x:i,y:a}:null})},onMouseLeave:()=>{a(e=>e?.isPinned?e:null)},onClick:e=>{e.stopPropagation();let t=y(n,o.language)||l?.name||n,i=b(n),s=r.current?.getBoundingClientRect(),c=e.clientX-(s?.left||0),u=e.clientY-(s?.top||0)-15;a(e=>e?.code===n&&e?.isPinned?null:{name:t,code:n,count:d,flag:i,x:c,y:u,isPinned:!0})},children:p?(0,C.jsxs)(C.Fragment,{children:[(0,C.jsx)(`circle`,{r:m+3,fill:`var(--map-color-${f})`,opacity:.4,className:`animate-ping map-marker-circle`}),(0,C.jsx)(`circle`,{r:m,fill:`var(--map-color-${f})`,stroke:`var(--map-stroke)`,strokeWidth:.75,style:{cursor:`pointer`},className:`map-marker-circle`})]}):(0,C.jsx)(`circle`,{r:m,fill:`var(--text-color)`,opacity:.25,style:{pointerEvents:`none`}})},n)})})},A=({destinations:e,profileId:t,range:n,customRange:r,accessPointId:i})=>{let{geographyData:o,destinationMap:u,scaleConfig:d,getLevel:f,formatNumber:p}=S(e),[m,h]=(0,x.useState)({coordinates:c(0,0),zoom:1.2}),[g,_]=(0,x.useState)(null),[v,y]=(0,x.useState)(null),[b,O]=(0,x.useState)({}),A=(0,x.useRef)(null);A.current=g,(0,x.useEffect)(()=>{if(!g){y(null);return}if(g.isPinned){y(g);return}if(v&&v.code===g.code)return;let e=setTimeout(()=>{A.current&&A.current.code===g.code&&y(A.current)},100);return()=>clearTimeout(e)},[g?.code,g?.isPinned,v?.code]),(0,x.useEffect)(()=>{g&&v&&g.code===v.code&&(g.x!==v.x||g.y!==v.y||g.isPinned!==v.isPinned)&&y(g)},[g?.x,g?.y,g?.isPinned,v]);let j=(0,x.useRef)(null);x.useEffect(()=>{O({})},[t,n,r,i]);let M=x.useCallback((e,t)=>{O(n=>({...n,[e]:t}))},[]),N=x.useMemo(()=>l(c(-100,-50),c(900,600)),[]);return(0,C.jsxs)(`div`,{className:`relative w-full min-h-85 max-h-120 aspect-800/566 bg-gray-50 dark:bg-slate-950 rounded-xl overflow-hidden border border-gray-100 dark:border-slate-800 flex flex-col justify-between shadow-sm`,children:[(0,C.jsxs)(`div`,{ref:j,className:`relative w-full flex-1 min-h-0 overflow-hidden select-none cursor-grab active:cursor-grabbing`,onClick:e=>{(e.target===e.currentTarget||e.target.tagName===`svg`)&&_(null)},children:[(0,C.jsx)(a,{projection:`geoEqualEarth`,width:800,height:566,style:{width:`100%`,height:`100%`},children:(0,C.jsxs)(s,{zoom:m.zoom,center:m.coordinates,onMoveEnd:e=>h({coordinates:c(e.coordinates[0],e.coordinates[1]),zoom:e.zoom}),maxZoom:8,minZoom:1,enablePan:!0,translateExtent:N,children:[(0,C.jsx)(D,{geographyData:o,destinationMap:u,getLevel:f,containerRef:j,hoveredCountry:g,setHoveredCountry:_}),(0,C.jsx)(k,{destinationMap:u,getLevel:f,containerRef:j,hoveredCountry:g,setHoveredCountry:_})]})}),v&&(0,C.jsx)(E,{name:v.name,count:v.count,flag:v.flag,x:v.x,y:v.y,countryCode:v.code,profileId:t,range:n,customRange:r,accessPointId:i,ispCache:b,onCacheIsp:M,isPinned:v.isPinned||!1,onClose:()=>_(null)})]}),(0,C.jsx)(w,{onZoomIn:()=>{m.zoom>=8||h(e=>({...e,zoom:e.zoom*1.5}))},onZoomOut:()=>{m.zoom<=1||h(e=>({...e,zoom:e.zoom/1.5}))},onReset:()=>{h({coordinates:c(0,0),zoom:1.2})}}),(0,C.jsx)(T,{maxThreshold:d.maxThreshold,formatNumber:p})]})};export{A as DestinationMap};
@@ -1 +1 @@
1
- import{i as e}from"./rolldown-runtime-C4Xdq4VV.js";import{C as t,F as n,Mt as r,Qt as i,R as a,at as o,k as s,lt as c}from"./vendor-react-BmoHsW1x.js";import{S as l,b as u}from"./vendor-icons-other-Bme3ywH9.js";import{C as d,E as f,H as p,N as m,O as h,S as g,T as _,V as v,f as y,h as b,r as x,u as S,w as C,x as w}from"./vendor-ui-core-CY_WyMIf.js";import{_t as T}from"./vendor-utils-BWSB0jGn.js";import{Q as E,V as D,X as O,_t as k,ct as A,et as j,ln as M,q as N,w as P,yt as F}from"./index-dXN_pYn1.js";var I=e(l(),1);const L=()=>{let{t:e}=i(),[t,n]=(0,I.useState)([]);return(0,I.useEffect)(()=>{D().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 filters from API`,e))},[e]),t};var R=e(u(),1);const z=({newUrl:e,setNewUrl:t,onAddList:n,syncing:r,loading:a,lists:o})=>{let{t:s}=i(),c=(0,R.jsx)(f,{className:`min-w-96`,children:L().map((e,t)=>(0,R.jsx)(C,{text:e.label,onClick:()=>n(e.url),disabled:o.some(t=>t.url===e.url),labelElement:(0,R.jsx)(`div`,{className:`flex flex-col items-end text-right`,children:(0,R.jsx)(`span`,{className:`text-[9px] opacity-85 max-w-xl truncate`,title:e.url,children:e.url})})},t))});return(0,R.jsx)(w,{elevation:p.ONE,className:`mb-6`,children:(0,R.jsxs)(`div`,{className:`flex gap-2 flex-col sm:flex-row`,children:[(0,R.jsx)(y,{fill:!0,size:`large`,placeholder:s(`filtering.urlPlaceholder`),value:e,onChange:e=>t(e.target.value),leftIcon:`globe`,rightElement:(0,R.jsx)(_,{content:c,placement:`bottom-end`,animation:`minimal`,arrow:!1,usePortal:!0,children:(0,R.jsx)(m,{variant:`minimal`,icon:`chevron-down`})})}),(0,R.jsx)(m,{intent:v.PRIMARY,size:`large`,icon:`plus`,onClick:()=>n(),className:`shrink-0`,loading:r||a,disabled:r||a,children:s(`filtering.addSubscription`)})]})})},B=({lists:e,onSelect:t})=>{let{t:n}=i(),r=[{key:`url`,header:n(`filtering.tableUrl`),cellClassName:`font-mono text-sm max-w-md truncate`,render:e=>e.url},{key:`lastSync`,header:n(`filtering.tableLastSync`),cellClassName:`text-xs opacity-60`,render:e=>e.last_synced_at?P(new Date(e.last_synced_at*1e3)):n(`filtering.neverSynced`)},{key:`status`,header:n(`filtering.tableStatus`),render:e=>{if(!e.enabled)return(0,R.jsx)(x,{intent:v.NONE,minimal:!0,children:n(`filtering.statusDisabled`,`Disabled`)});let t=!!e.sync_error,r=!!e.last_synced_at,i=n(`filtering.statusNormal`,`Active`),a=v.SUCCESS;return t&&(r?(i=n(`filtering.statusOutdated`,`Outdated`),a=v.WARNING):(i=n(`filtering.statusMissing`,`Missing`),a=v.DANGER)),(0,R.jsx)(x,{intent:a,minimal:!0,children:i})}}];return(0,R.jsx)(`div`,{className:`w-full max-w-full overflow-x-auto pb-4`,children:(0,R.jsxs)(S,{interactive:!0,striped:!0,className:`w-full min-w-max whitespace-nowrap`,children:[(0,R.jsx)(`thead`,{children:(0,R.jsx)(`tr`,{children:r.map(e=>(0,R.jsx)(`th`,{className:e.headerClassName,children:e.header},e.key))})}),(0,R.jsx)(`tbody`,{children:e.map(e=>(0,R.jsx)(`tr`,{onClick:()=>t(e),className:`cursor-pointer`,children:r.map(t=>(0,R.jsx)(`td`,{className:t.cellClassName,children:t.render(e)},t.key))},e.id))})]})})},V=({profileId:e,selectedList:r,onClose:a,onCopy:l,onDelete:u,onToggleEnabled:d,onAllowDomain:f})=>{let{t:p}=i(),[_,S]=(0,I.useState)(``),[C,w]=(0,I.useState)(!1),[T,D]=(0,I.useState)(null),[O,k]=(0,I.useState)(null),[A,j]=(0,I.useState)(!1),[M,N]=(0,I.useState)(!1),[F,L]=(0,I.useState)(!1),z=(0,I.useRef)(0),B=()=>{z.current++,w(!1),S(``),D(null),k(null),N(!1)},V=async()=>{let t=_.trim().toLowerCase();if(!t||!r||(t=t.replace(/^https?:\/\//,``).split(`/`)[0].split(`:`)[0].replace(/\.+$/,``),!t))return;S(t);let n=++z.current,i=r.id;w(!0),k(null),D(null),N(!1);try{let r=await E(e,i,t);z.current===n&&D(r)}catch(e){z.current===n&&k(e instanceof Error?e.message:String(e))}finally{z.current===n&&w(!1)}},H=async e=>{if(r){L(!0);try{await d(r.id,e)}finally{L(!1)}}},U=async()=>{if(T?.matchedEntry){j(!0);try{await f(T.domain),N(!0)}catch(e){k(e instanceof Error?e.message:String(e))}finally{j(!1)}}};return(0,R.jsxs)(h,{isOpen:r!==null,onClose:()=>{B(),a()},title:p(`filtering.listDetails`,`List Details`),icon:`info-sign`,children:[(0,R.jsxs)(`div`,{className:`p-6 space-y-4`,children:[r?.sync_error&&(0,R.jsx)(g,{intent:v.WARNING,title:p(`filtering.syncError`),icon:`warning-sign`,children:r.sync_error}),(0,R.jsx)(`div`,{className:`bg-gray-50 dark:bg-gray-800 p-4 rounded-lg border border-gray-200 dark:border-gray-700 break-all font-mono text-sm`,children:r?.url}),(0,R.jsxs)(`div`,{className:`flex items-center justify-between border border-gray-200 dark:border-gray-700 rounded-lg p-3`,children:[(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`div`,{className:`text-sm font-bold`,children:p(`filtering.listEnabled`,`List active`)}),(0,R.jsx)(`div`,{className:`text-xs opacity-60`,children:p(`filtering.listEnabledHint`,`Disable to stop filtering with this list without deleting it. Its subscription and sync history are kept.`)})]}),(0,R.jsx)(b,{large:!0,checked:!!r?.enabled,disabled:F,onChange:e=>H(e.target.checked)})]}),(0,R.jsxs)(`div`,{className:`border border-gray-200 dark:border-gray-700 rounded-lg p-3 space-y-3`,children:[(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`div`,{className:`text-sm font-bold`,children:p(`filtering.checkDomain`,`Check a domain`)}),(0,R.jsx)(`div`,{className:`text-xs opacity-60`,children:p(`filtering.checkDomainHint`,`Lists are stored as compact filters, so their entries cannot be browsed. You can test any domain against this list instantly.`)})]}),(0,R.jsxs)(`div`,{className:`flex gap-2`,children:[(0,R.jsx)(y,{fill:!0,placeholder:`example.com`,value:_,disabled:C,leftIcon:`globe-network`,onChange:e=>{S(e.target.value),D(null)},onKeyDown:e=>{e.key===`Enter`&&V()}}),(0,R.jsx)(m,{icon:(0,R.jsx)(n,{size:14}),text:p(`filtering.check`,`Check`),loading:C,disabled:!_.trim(),onClick:()=>void V()})]}),O&&(0,R.jsx)(g,{intent:v.DANGER,className:`text-xs`,children:O}),T&&!T.synced&&(0,R.jsx)(g,{intent:v.WARNING,className:`text-xs`,children:p(`filtering.checkNotSynced`,`This list has not finished syncing yet, so there is nothing to check against.`)}),T?.synced&&T.enabled===!1&&(0,R.jsx)(g,{intent:v.NONE,className:`text-xs`,children:p(`filtering.checkListDisabled`,`This list is currently disabled, so it is not filtering anything right now.`)}),T?.synced&&(0,R.jsx)(g,{intent:T.blocked?v.WARNING:v.SUCCESS,className:`text-xs`,icon:T.blocked?`ban-circle`:`tick-circle`,children:T.blocked?(0,R.jsxs)(`div`,{className:`space-y-2`,children:[(0,R.jsxs)(`div`,{children:[p(`filtering.checkBlocked`,`Blocked by this list`),T.matchedEntry&&T.matchedEntry!==T.domain&&(0,R.jsxs)(R.Fragment,{children:[` `,(0,R.jsx)(x,{minimal:!0,className:`font-mono`,children:T.matchedEntry}),` `,p(`filtering.checkViaParent`,`(matched a parent domain)`)]})]}),(0,R.jsx)(`div`,{className:`opacity-75`,children:T.falsePositiveRate?p(`filtering.checkProbabilisticRate`,{defaultValue:`Filters are probabilistic: roughly 1 match in {{odds}} is a false positive. Adding an exception also covers every subdomain of it.`,odds:Math.round(1/T.falsePositiveRate).toLocaleString()}):p(`filtering.checkProbabilistic`,`Filters are probabilistic, so a small share of matches are false positives. Adding an exception also covers every subdomain of it.`)}),M?(0,R.jsx)(x,{intent:v.SUCCESS,minimal:!0,children:p(`filtering.checkAllowed`,`Exception added - this domain now resolves`)}):(0,R.jsx)(m,{small:!0,icon:(0,R.jsx)(s,{size:12}),intent:v.PRIMARY,loading:A,text:p(`filtering.checkAllowAction`,`Allow anyway`),onClick:()=>void U()})]}):p(`filtering.checkNotBlocked`,`Not blocked by this list`)})]}),(0,R.jsxs)(`div`,{className:`flex justify-between items-center`,children:[(0,R.jsxs)(`span`,{className:`text-xs opacity-50`,children:[p(`filtering.tableLastSync`),`:`,` `,r?.last_synced_at?P(new Date(r.last_synced_at*1e3)):`-`]}),(0,R.jsxs)(`div`,{className:`flex gap-2`,children:[(0,R.jsx)(m,{icon:(0,R.jsx)(c,{size:14}),text:p(`setup.copyUrl`,`Copy link`),onClick:()=>{r&&l(r.url)}}),(0,R.jsx)(m,{icon:(0,R.jsx)(o,{size:14}),text:p(`setup.learnMore`,`Open link`),onClick:()=>{r&&window.open(r.url,`_blank`)}})]})]})]}),(0,R.jsxs)(`div`,{className:`p-4 border-t border-gray-100 dark:border-gray-800 flex justify-between`,children:[(0,R.jsx)(m,{icon:(0,R.jsx)(t,{size:14}),intent:v.DANGER,text:p(`rules.delete`,`Delete`),onClick:()=>{if(!r)return;let e=r.id;B(),u(e)}}),(0,R.jsx)(m,{onClick:()=>{B(),a()},text:p(`rules.close`,`Close`)})]})]})},H=({profileId:e,toasterRef:t})=>{let n=r(),o=M(),[s,c]=(0,I.useState)([]),[l,u]=(0,I.useState)(``),[f,p]=(0,I.useState)(!0),[h,_]=(0,I.useState)(!1),{t:y}=i(),[b,x]=(0,I.useState)(null),S=async()=>{p(!0);try{c(await A(e))}catch(e){console.error(`Failed to fetch filters`,e)}finally{p(!1)}},C=e=>{navigator.clipboard.writeText(e),t?.current?.show({message:y(`setup.copied`,`已复制到剪贴板`),intent:v.SUCCESS,icon:`duplicate`})},w=async t=>{let n=new Map(t.map(e=>[e.id,e.last_synced_at])),r=0;for(;r<15;){await new Promise(e=>setTimeout(e,2e3));try{let t=await A(e),r=!0;for(let e of t){if(n.has(e.id)&&e.last_synced_at===n.get(e.id)){r=!1;break}if(!n.has(e.id)&&!e.last_synced_at){r=!1;break}}if(r&&t.length>0)return c(t),!0}catch{}r++}return await S(),!1};return(0,I.useEffect)(()=>{S()},[e]),(0,R.jsxs)(`div`,{className:T(`md:px-8 w-full min-w-0 max-w-5xl mx-auto`,o?`p-1`:`px-8`),children:[(0,R.jsxs)(`div`,{className:`mb-8 flex flex-col md:flex-row justify-between items-start md:items-end gap-4`,children:[(0,R.jsxs)(`div`,{className:`w-full md:w-auto flex-1`,children:[o?(0,R.jsxs)(d,{minimal:!0,fill:o,children:[(0,R.jsx)(m,{active:!1,onClick:()=>n(`/dash/${e}/rules`),text:y(`rules.title`),large:!0}),(0,R.jsx)(m,{active:!0,onClick:()=>n(`/dash/${e}/filter`),text:y(`filtering.title`),large:!0})]}):(0,R.jsx)(`h1`,{className:`bp6-heading`,children:y(`rules.title`)}),(0,R.jsx)(`p`,{className:`bp6-text-muted mt-2!`,children:y(`filtering.subtitle`)})]}),(0,R.jsx)(m,{icon:(0,R.jsx)(a,{size:16}),text:y(`filtering.syncAll`),onClick:async()=>{_(!0);try{await k(e),t?.current?.show({message:y(`filtering.syncTaskStarted`),intent:v.PRIMARY,icon:`cloud-download`}),await w(s)&&t?.current?.show({message:y(`filtering.syncCheckComplete`),intent:v.SUCCESS,icon:`tick`})}catch(e){console.error(e)}finally{_(!1)}},loading:h||f,disabled:h||f||s.length===0,className:o?`w-full`:``})]}),(0,R.jsx)(g,{intent:v.WARNING,icon:`info-sign`,className:`mb-6`,children:(0,R.jsx)(`p`,{children:y(`filtering.formatDisclaimer`,`本系统只支持有限的 AdGuard 格式列表和纯域名列表。仅支持基础的拦截规则(如 ||example.com^),会绕过 "@@" 白名单,暂不支持 "$" 重写规则以及 "*" 省略规则。系统会自动匹配域名的所有子域名。`)})}),(0,R.jsx)(z,{newUrl:l,setNewUrl:u,onAddList:async n=>{let r=n||l;if(r){_(!0);try{await N(e,r),t?.current?.show({message:y(`filtering.addSuccess`),intent:v.SUCCESS,icon:`tick`}),u(``),t?.current?.show({message:y(`filtering.syncTaskStarted`),intent:v.PRIMARY,icon:`cloud-download`}),await w(s)&&t?.current?.show({message:y(`filtering.syncCheckComplete`),intent:v.SUCCESS,icon:`tick`})}catch(e){console.error(e)}finally{_(!1)}}},syncing:h,loading:f,lists:s}),(0,R.jsx)(B,{lists:s,onSelect:x}),(0,R.jsx)(V,{profileId:e,selectedList:b,onClose:()=>x(null),onCopy:C,onDelete:async n=>{try{await j(e,n),t?.current?.show({message:y(`filtering.deleteSuccess`),intent:v.PRIMARY,icon:`trash`}),x(null),await S()}catch(e){console.error(e)}},onToggleEnabled:async(n,r)=>{try{await F(e,n,r),x(e=>e&&e.id===n?{...e,enabled:r}:e),t?.current?.show({message:r?y(`filtering.listEnabledToast`,`List enabled - rebuilding filter`):y(`filtering.listDisabledToast`,`List disabled - rebuilding filter`),intent:v.PRIMARY,icon:r?`tick`:`disable`}),await S()}catch(e){console.error(e),t?.current?.show({message:e instanceof Error?e.message:String(e),intent:v.DANGER,icon:`error`})}},onAllowDomain:async n=>{await O(e,{type:`ALLOW`,pattern:n}),t?.current?.show({message:y(`filtering.allowRuleAdded`,`Exception added for {{domain}}`,{domain:n}),intent:v.SUCCESS,icon:`tick`})}})]})};export{H as FilteringView};
1
+ import{i as e}from"./rolldown-runtime-C4Xdq4VV.js";import{C as t,F as n,Mt as r,Qt as i,R as a,at as o,k as s,lt as c}from"./vendor-react-BmoHsW1x.js";import{S as l,b as u}from"./vendor-icons-other-Bme3ywH9.js";import{C as d,E as f,H as p,N as m,O as h,S as g,T as _,V as v,f as y,h as b,r as x,u as S,w as C,x as w}from"./vendor-ui-core-CY_WyMIf.js";import{_t as T}from"./vendor-utils-BWSB0jGn.js";import{Q as E,V as D,X as O,_t as k,ct as A,et as j,ln as M,q as N,w as P,yt as F}from"./index-CP2FJpkF.js";var I=e(l(),1);const L=()=>{let{t:e}=i(),[t,n]=(0,I.useState)([]);return(0,I.useEffect)(()=>{D().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 filters from API`,e))},[e]),t};var R=e(u(),1);const z=({newUrl:e,setNewUrl:t,onAddList:n,syncing:r,loading:a,lists:o})=>{let{t:s}=i(),c=(0,R.jsx)(f,{className:`min-w-96`,children:L().map((e,t)=>(0,R.jsx)(C,{text:e.label,onClick:()=>n(e.url),disabled:o.some(t=>t.url===e.url),labelElement:(0,R.jsx)(`div`,{className:`flex flex-col items-end text-right`,children:(0,R.jsx)(`span`,{className:`text-[9px] opacity-85 max-w-xl truncate`,title:e.url,children:e.url})})},t))});return(0,R.jsx)(w,{elevation:p.ONE,className:`mb-6`,children:(0,R.jsxs)(`div`,{className:`flex gap-2 flex-col sm:flex-row`,children:[(0,R.jsx)(y,{fill:!0,size:`large`,placeholder:s(`filtering.urlPlaceholder`),value:e,onChange:e=>t(e.target.value),leftIcon:`globe`,rightElement:(0,R.jsx)(_,{content:c,placement:`bottom-end`,animation:`minimal`,arrow:!1,usePortal:!0,children:(0,R.jsx)(m,{variant:`minimal`,icon:`chevron-down`})})}),(0,R.jsx)(m,{intent:v.PRIMARY,size:`large`,icon:`plus`,onClick:()=>n(),className:`shrink-0`,loading:r||a,disabled:r||a,children:s(`filtering.addSubscription`)})]})})},B=({lists:e,onSelect:t})=>{let{t:n}=i(),r=[{key:`url`,header:n(`filtering.tableUrl`),cellClassName:`font-mono text-sm max-w-md truncate`,render:e=>e.url},{key:`lastSync`,header:n(`filtering.tableLastSync`),cellClassName:`text-xs opacity-60`,render:e=>e.last_synced_at?P(new Date(e.last_synced_at*1e3)):n(`filtering.neverSynced`)},{key:`status`,header:n(`filtering.tableStatus`),render:e=>{if(!e.enabled)return(0,R.jsx)(x,{intent:v.NONE,minimal:!0,children:n(`filtering.statusDisabled`,`Disabled`)});let t=!!e.sync_error,r=!!e.last_synced_at,i=n(`filtering.statusNormal`,`Active`),a=v.SUCCESS;return t&&(r?(i=n(`filtering.statusOutdated`,`Outdated`),a=v.WARNING):(i=n(`filtering.statusMissing`,`Missing`),a=v.DANGER)),(0,R.jsx)(x,{intent:a,minimal:!0,children:i})}}];return(0,R.jsx)(`div`,{className:`w-full max-w-full overflow-x-auto pb-4`,children:(0,R.jsxs)(S,{interactive:!0,striped:!0,className:`w-full min-w-max whitespace-nowrap`,children:[(0,R.jsx)(`thead`,{children:(0,R.jsx)(`tr`,{children:r.map(e=>(0,R.jsx)(`th`,{className:e.headerClassName,children:e.header},e.key))})}),(0,R.jsx)(`tbody`,{children:e.map(e=>(0,R.jsx)(`tr`,{onClick:()=>t(e),className:`cursor-pointer`,children:r.map(t=>(0,R.jsx)(`td`,{className:t.cellClassName,children:t.render(e)},t.key))},e.id))})]})})},V=({profileId:e,selectedList:r,onClose:a,onCopy:l,onDelete:u,onToggleEnabled:d,onAllowDomain:f})=>{let{t:p}=i(),[_,S]=(0,I.useState)(``),[C,w]=(0,I.useState)(!1),[T,D]=(0,I.useState)(null),[O,k]=(0,I.useState)(null),[A,j]=(0,I.useState)(!1),[M,N]=(0,I.useState)(!1),[F,L]=(0,I.useState)(!1),z=(0,I.useRef)(0),B=()=>{z.current++,w(!1),S(``),D(null),k(null),N(!1)},V=async()=>{let t=_.trim().toLowerCase();if(!t||!r||(t=t.replace(/^https?:\/\//,``).split(`/`)[0].split(`:`)[0].replace(/\.+$/,``),!t))return;S(t);let n=++z.current,i=r.id;w(!0),k(null),D(null),N(!1);try{let r=await E(e,i,t);z.current===n&&D(r)}catch(e){z.current===n&&k(e instanceof Error?e.message:String(e))}finally{z.current===n&&w(!1)}},H=async e=>{if(r){L(!0);try{await d(r.id,e)}finally{L(!1)}}},U=async()=>{if(T?.matchedEntry){j(!0);try{await f(T.domain),N(!0)}catch(e){k(e instanceof Error?e.message:String(e))}finally{j(!1)}}};return(0,R.jsxs)(h,{isOpen:r!==null,onClose:()=>{B(),a()},title:p(`filtering.listDetails`,`List Details`),icon:`info-sign`,children:[(0,R.jsxs)(`div`,{className:`p-6 space-y-4`,children:[r?.sync_error&&(0,R.jsx)(g,{intent:v.WARNING,title:p(`filtering.syncError`),icon:`warning-sign`,children:r.sync_error}),(0,R.jsx)(`div`,{className:`bg-gray-50 dark:bg-gray-800 p-4 rounded-lg border border-gray-200 dark:border-gray-700 break-all font-mono text-sm`,children:r?.url}),(0,R.jsxs)(`div`,{className:`flex items-center justify-between border border-gray-200 dark:border-gray-700 rounded-lg p-3`,children:[(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`div`,{className:`text-sm font-bold`,children:p(`filtering.listEnabled`,`List active`)}),(0,R.jsx)(`div`,{className:`text-xs opacity-60`,children:p(`filtering.listEnabledHint`,`Disable to stop filtering with this list without deleting it. Its subscription and sync history are kept.`)})]}),(0,R.jsx)(b,{large:!0,checked:!!r?.enabled,disabled:F,onChange:e=>H(e.target.checked)})]}),(0,R.jsxs)(`div`,{className:`border border-gray-200 dark:border-gray-700 rounded-lg p-3 space-y-3`,children:[(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`div`,{className:`text-sm font-bold`,children:p(`filtering.checkDomain`,`Check a domain`)}),(0,R.jsx)(`div`,{className:`text-xs opacity-60`,children:p(`filtering.checkDomainHint`,`Lists are stored as compact filters, so their entries cannot be browsed. You can test any domain against this list instantly.`)})]}),(0,R.jsxs)(`div`,{className:`flex gap-2`,children:[(0,R.jsx)(y,{fill:!0,placeholder:`example.com`,value:_,disabled:C,leftIcon:`globe-network`,onChange:e=>{S(e.target.value),D(null)},onKeyDown:e=>{e.key===`Enter`&&V()}}),(0,R.jsx)(m,{icon:(0,R.jsx)(n,{size:14}),text:p(`filtering.check`,`Check`),loading:C,disabled:!_.trim(),onClick:()=>void V()})]}),O&&(0,R.jsx)(g,{intent:v.DANGER,className:`text-xs`,children:O}),T&&!T.synced&&(0,R.jsx)(g,{intent:v.WARNING,className:`text-xs`,children:p(`filtering.checkNotSynced`,`This list has not finished syncing yet, so there is nothing to check against.`)}),T?.synced&&T.enabled===!1&&(0,R.jsx)(g,{intent:v.NONE,className:`text-xs`,children:p(`filtering.checkListDisabled`,`This list is currently disabled, so it is not filtering anything right now.`)}),T?.synced&&(0,R.jsx)(g,{intent:T.blocked?v.WARNING:v.SUCCESS,className:`text-xs`,icon:T.blocked?`ban-circle`:`tick-circle`,children:T.blocked?(0,R.jsxs)(`div`,{className:`space-y-2`,children:[(0,R.jsxs)(`div`,{children:[p(`filtering.checkBlocked`,`Blocked by this list`),T.matchedEntry&&T.matchedEntry!==T.domain&&(0,R.jsxs)(R.Fragment,{children:[` `,(0,R.jsx)(x,{minimal:!0,className:`font-mono`,children:T.matchedEntry}),` `,p(`filtering.checkViaParent`,`(matched a parent domain)`)]})]}),(0,R.jsx)(`div`,{className:`opacity-75`,children:T.falsePositiveRate?p(`filtering.checkProbabilisticRate`,{defaultValue:`Filters are probabilistic: roughly 1 match in {{odds}} is a false positive. Adding an exception also covers every subdomain of it.`,odds:Math.round(1/T.falsePositiveRate).toLocaleString()}):p(`filtering.checkProbabilistic`,`Filters are probabilistic, so a small share of matches are false positives. Adding an exception also covers every subdomain of it.`)}),M?(0,R.jsx)(x,{intent:v.SUCCESS,minimal:!0,children:p(`filtering.checkAllowed`,`Exception added - this domain now resolves`)}):(0,R.jsx)(m,{small:!0,icon:(0,R.jsx)(s,{size:12}),intent:v.PRIMARY,loading:A,text:p(`filtering.checkAllowAction`,`Allow anyway`),onClick:()=>void U()})]}):p(`filtering.checkNotBlocked`,`Not blocked by this list`)})]}),(0,R.jsxs)(`div`,{className:`flex justify-between items-center`,children:[(0,R.jsxs)(`span`,{className:`text-xs opacity-50`,children:[p(`filtering.tableLastSync`),`:`,` `,r?.last_synced_at?P(new Date(r.last_synced_at*1e3)):`-`]}),(0,R.jsxs)(`div`,{className:`flex gap-2`,children:[(0,R.jsx)(m,{icon:(0,R.jsx)(c,{size:14}),text:p(`setup.copyUrl`,`Copy link`),onClick:()=>{r&&l(r.url)}}),(0,R.jsx)(m,{icon:(0,R.jsx)(o,{size:14}),text:p(`setup.learnMore`,`Open link`),onClick:()=>{r&&window.open(r.url,`_blank`)}})]})]})]}),(0,R.jsxs)(`div`,{className:`p-4 border-t border-gray-100 dark:border-gray-800 flex justify-between`,children:[(0,R.jsx)(m,{icon:(0,R.jsx)(t,{size:14}),intent:v.DANGER,text:p(`rules.delete`,`Delete`),onClick:()=>{if(!r)return;let e=r.id;B(),u(e)}}),(0,R.jsx)(m,{onClick:()=>{B(),a()},text:p(`rules.close`,`Close`)})]})]})},H=({profileId:e,toasterRef:t})=>{let n=r(),o=M(),[s,c]=(0,I.useState)([]),[l,u]=(0,I.useState)(``),[f,p]=(0,I.useState)(!0),[h,_]=(0,I.useState)(!1),{t:y}=i(),[b,x]=(0,I.useState)(null),S=async()=>{p(!0);try{c(await A(e))}catch(e){console.error(`Failed to fetch filters`,e)}finally{p(!1)}},C=e=>{navigator.clipboard.writeText(e),t?.current?.show({message:y(`setup.copied`,`已复制到剪贴板`),intent:v.SUCCESS,icon:`duplicate`})},w=async t=>{let n=new Map(t.map(e=>[e.id,e.last_synced_at])),r=0;for(;r<15;){await new Promise(e=>setTimeout(e,2e3));try{let t=await A(e),r=!0;for(let e of t){if(n.has(e.id)&&e.last_synced_at===n.get(e.id)){r=!1;break}if(!n.has(e.id)&&!e.last_synced_at){r=!1;break}}if(r&&t.length>0)return c(t),!0}catch{}r++}return await S(),!1};return(0,I.useEffect)(()=>{S()},[e]),(0,R.jsxs)(`div`,{className:T(`md:px-8 w-full min-w-0 max-w-5xl mx-auto`,o?`p-1`:`px-8`),children:[(0,R.jsxs)(`div`,{className:`mb-8 flex flex-col md:flex-row justify-between items-start md:items-end gap-4`,children:[(0,R.jsxs)(`div`,{className:`w-full md:w-auto flex-1`,children:[o?(0,R.jsxs)(d,{minimal:!0,fill:o,children:[(0,R.jsx)(m,{active:!1,onClick:()=>n(`/dash/${e}/rules`),text:y(`rules.title`),large:!0}),(0,R.jsx)(m,{active:!0,onClick:()=>n(`/dash/${e}/filter`),text:y(`filtering.title`),large:!0})]}):(0,R.jsx)(`h1`,{className:`bp6-heading`,children:y(`rules.title`)}),(0,R.jsx)(`p`,{className:`bp6-text-muted mt-2!`,children:y(`filtering.subtitle`)})]}),(0,R.jsx)(m,{icon:(0,R.jsx)(a,{size:16}),text:y(`filtering.syncAll`),onClick:async()=>{_(!0);try{await k(e),t?.current?.show({message:y(`filtering.syncTaskStarted`),intent:v.PRIMARY,icon:`cloud-download`}),await w(s)&&t?.current?.show({message:y(`filtering.syncCheckComplete`),intent:v.SUCCESS,icon:`tick`})}catch(e){console.error(e)}finally{_(!1)}},loading:h||f,disabled:h||f||s.length===0,className:o?`w-full`:``})]}),(0,R.jsx)(g,{intent:v.WARNING,icon:`info-sign`,className:`mb-6`,children:(0,R.jsx)(`p`,{children:y(`filtering.formatDisclaimer`,`本系统只支持有限的 AdGuard 格式列表和纯域名列表。仅支持基础的拦截规则(如 ||example.com^),会绕过 "@@" 白名单,暂不支持 "$" 重写规则以及 "*" 省略规则。系统会自动匹配域名的所有子域名。`)})}),(0,R.jsx)(z,{newUrl:l,setNewUrl:u,onAddList:async n=>{let r=n||l;if(r){_(!0);try{await N(e,r),t?.current?.show({message:y(`filtering.addSuccess`),intent:v.SUCCESS,icon:`tick`}),u(``),t?.current?.show({message:y(`filtering.syncTaskStarted`),intent:v.PRIMARY,icon:`cloud-download`}),await w(s)&&t?.current?.show({message:y(`filtering.syncCheckComplete`),intent:v.SUCCESS,icon:`tick`})}catch(e){console.error(e)}finally{_(!1)}}},syncing:h,loading:f,lists:s}),(0,R.jsx)(B,{lists:s,onSelect:x}),(0,R.jsx)(V,{profileId:e,selectedList:b,onClose:()=>x(null),onCopy:C,onDelete:async n=>{try{await j(e,n),t?.current?.show({message:y(`filtering.deleteSuccess`),intent:v.PRIMARY,icon:`trash`}),x(null),await S()}catch(e){console.error(e)}},onToggleEnabled:async(n,r)=>{try{await F(e,n,r),x(e=>e&&e.id===n?{...e,enabled:r}:e),t?.current?.show({message:r?y(`filtering.listEnabledToast`,`List enabled - rebuilding filter`):y(`filtering.listDisabledToast`,`List disabled - rebuilding filter`),intent:v.PRIMARY,icon:r?`tick`:`disable`}),await S()}catch(e){console.error(e),t?.current?.show({message:e instanceof Error?e.message:String(e),intent:v.DANGER,icon:`error`})}},onAllowDomain:async n=>{await O(e,{type:`ALLOW`,pattern:n}),t?.current?.show({message:y(`filtering.allowRuleAdded`,`Exception added for {{domain}}`,{domain:n}),intent:v.SUCCESS,icon:`tick`})}})]})};export{H as FilteringView};
@@ -0,0 +1,5 @@
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/services-DM_tzwVp.js","assets/index-CP2FJpkF.js","assets/vendor-icons-other-Bme3ywH9.js","assets/vendor-icons-16-BgwRBCeU.js","assets/rolldown-runtime-C4Xdq4VV.js","assets/vendor-icons-20-X5NPN60g.js","assets/vendor-react-BmoHsW1x.js","assets/vendor-ui-core-CY_WyMIf.js","assets/vendor-utils-BWSB0jGn.js","assets/vendor-i18next-BKUzkAKP.js","assets/index-Bheo8y3N.css"])))=>i.map(i=>d[i]);
2
+ import{i as e}from"./rolldown-runtime-C4Xdq4VV.js";import{A as t,Et as n,G as r,H as i,Q as a,Qt as o,V as s,X as c,b as l,gt as u,j as d,lt as f,nt as p,q as m,tt as h,vt as g,xt as _}from"./vendor-react-BmoHsW1x.js";import{S as v,b as y,x as b}from"./vendor-icons-other-Bme3ywH9.js";import{C as x,E as S,L as C,M as w,N as T,O as E,P as D,R as O,S as k,T as A,V as j,a as M,f as N,h as ee,l as P,o as F,p as I,r as L,u as te,w as R,x as z,z as B}from"./vendor-ui-core-CY_WyMIf.js";import{_t as V}from"./vendor-utils-BWSB0jGn.js";import{D as H,at as U,j as W,k as G,ln as ne,lt as re,ot as K,st as ie,ut as q,w as ae,zt as oe}from"./index-CP2FJpkF.js";import{n as se,t as J}from"./formatCountryName-CSBD8pP8.js";import{t as Y}from"./getFlagEmoji-sHq5YwT3.js";import{t as ce}from"./SwipeableDrawer-B81ANpsc.js";var X=e(v(),1),Z=e(y(),1);const le=({range:e,setRange:t,customRange:n,setCustomRange:r,nowStr:i,fetchLogs:a,isMobile:s,logRetentionDays:c})=>{let{t:l}=o(),u=[{key:`10m`,days:.007},{key:`1h`,days:.0416},{key:`24h`,days:1},{key:`7d`,days:7},{key:`30d`,days:30}].filter(e=>e.days<=c).map(e=>e.key);return(0,Z.jsx)(`div`,{className:`overflow-x-auto pb-1 -mx-4 px-4 md:mx-0 md:px-0`,children:(0,Z.jsxs)(x,{minimal:s,variant:s?void 0:`minimal`,children:[u.map(n=>(0,Z.jsx)(T,{active:e===n,onClick:()=>t(n),text:n.toUpperCase(),small:s},n)),(0,Z.jsx)(A,{content:(0,Z.jsxs)(`div`,{className:`p-4 space-y-2 w-64`,children:[(0,Z.jsx)(w,{children:l(`analytics.customRange`)}),(0,Z.jsx)(I,{label:l(`analytics.startTime`),children:(0,Z.jsx)(N,{type:`datetime-local`,max:n.end||i,value:n.start,onChange:e=>r({...n,start:e.target.value})})}),(0,Z.jsx)(I,{label:l(`analytics.endTime`),children:(0,Z.jsx)(N,{type:`datetime-local`,min:n.start,max:i,value:n.end,onChange:e=>r({...n,end:e.target.value})})}),(0,Z.jsx)(T,{fill:!0,intent:j.PRIMARY,text:l(`analytics.apply`),onClick:()=>{t(`custom`),a(`custom`,!0)}})]}),children:(0,Z.jsx)(T,{active:e===`custom`,icon:(0,Z.jsx)(g,{size:14}),text:s?``:l(`analytics.custom`),small:s})})]})})},ue=({statusFilter:e,setStatusFilter:t,isMobile:n})=>{let{t:r}=o(),i=(0,Z.jsxs)(S,{children:[(0,Z.jsx)(R,{icon:e===null?`tick`:void 0,text:r(`logs.allStatus`),onClick:()=>t(null)}),(0,Z.jsx)(P,{}),(0,Z.jsx)(R,{icon:e===`PASS`?`tick`:void 0,intent:j.SUCCESS,text:r(`logs.onlyPass`),onClick:()=>t(`PASS`)}),(0,Z.jsx)(R,{icon:e===`BLOCK`?`tick`:void 0,intent:j.DANGER,text:r(`logs.onlyBlock`),onClick:()=>t(`BLOCK`)}),(0,Z.jsx)(R,{icon:e===`REDIRECT`?`tick`:void 0,intent:j.WARNING,text:r(`logs.onlyRedirect`),onClick:()=>t(`REDIRECT`)})]}),a=(()=>{switch(e){case`PASS`:return{text:r(`logs.statusPass`),intent:j.SUCCESS};case`BLOCK`:return{text:r(`logs.statusBlock`),intent:j.DANGER};case`REDIRECT`:return{text:r(`logs.statusRedirect`),intent:j.WARNING};default:return{text:r(`logs.allStatus`),intent:j.NONE}}})();return(0,Z.jsx)(A,{content:i,placement:`bottom-start`,children:(0,Z.jsx)(T,{icon:(0,Z.jsx)(p,{size:14}),rightIcon:`caret-down`,intent:a.intent,text:a.text,variant:`outlined`,fill:n})})},de=({accessPointIdFilter:e,setAccessPointIdFilter:t,accessPoints:n,isMobile:i})=>{let{t:a}=o(),s=(0,Z.jsxs)(S,{children:[(0,Z.jsx)(R,{icon:e===null?`tick`:void 0,text:a(`logs.allAccessPoint`),onClick:()=>t(null)}),(0,Z.jsx)(P,{}),n.map(n=>(0,Z.jsx)(R,{icon:e===n.id?`tick`:void 0,text:n.name,onClick:()=>t(n.id)},n.id))]}),c=e&&n.find(t=>t.id===e)?.name||a(`logs.allAccessPoint`);return(0,Z.jsx)(A,{content:s,placement:`bottom-start`,children:(0,Z.jsx)(T,{icon:(0,Z.jsx)(r,{size:14}),rightIcon:`caret-down`,intent:e?j.PRIMARY:j.NONE,text:c,variant:`outlined`,fill:i})})},fe=Array.from(new Set(Object.values(se))).sort((e,t)=>e.localeCompare(t)),pe=({destCountryFilter:e,setDestCountryFilter:t,isMobile:n})=>{let{t:r,i18n:i}=o(),[a,s]=(0,X.useState)(!1),[c,l]=(0,X.useState)(``),u=(0,X.useMemo)(()=>{let e=i.language;return fe.map(t=>{let n=J(t,e),r=J(t,`en`);return{code:t,name:n||r||t,searchStr:`${t} ${n} ${r}`.toLowerCase()}})},[i.language]),d=(0,X.useMemo)(()=>{let e=c.trim().toLowerCase();return e?u.filter(t=>t.searchStr.includes(e)):u},[u,c]),f=(0,Z.jsxs)(`div`,{className:`w-72 flex flex-col p-1.5`,children:[(0,Z.jsx)(`div`,{className:`pb-1.5`,children:(0,Z.jsx)(N,{leftIcon:`search`,placeholder:r(`logs.searchCountry`,`Search country...`),value:c,onChange:e=>l(e.target.value),small:!0,autoFocus:!0,rightElement:c?(0,Z.jsx)(T,{icon:`cross`,variant:`minimal`,small:!0,onClick:()=>l(``)}):void 0})}),(0,Z.jsxs)(S,{className:`max-h-64 overflow-y-auto`,children:[!c&&(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsx)(R,{icon:e===null?`tick`:void 0,text:r(`logs.allCountry`),onClick:()=>{t(null),s(!1)}}),(0,Z.jsx)(P,{})]}),d.length===0?(0,Z.jsx)(R,{disabled:!0,text:r(`logs.noMatchingCountries`,`No matching countries found`)}):d.map(n=>(0,Z.jsx)(R,{icon:e===n.code?`tick`:void 0,text:(0,Z.jsxs)(`span`,{className:`flex items-center justify-between gap-2 w-full`,children:[(0,Z.jsxs)(`span`,{className:`truncate`,children:[Y(n.code),` `,n.name]}),(0,Z.jsx)(`span`,{className:`text-xs text-gray-400 shrink-0 font-mono`,children:n.code})]}),onClick:()=>{t(n.code),s(!1)}},n.code))]})]}),p=e?`${Y(e)} ${J(e,i.language)||e} (${e})`:r(`logs.allCountry`);return(0,Z.jsx)(A,{content:f,placement:`bottom-start`,isOpen:a,onInteraction:e=>{s(e),e||l(``)},children:(0,Z.jsx)(T,{icon:(0,Z.jsx)(h,{size:14}),rightIcon:`caret-down`,intent:e?j.PRIMARY:j.NONE,text:p,variant:`outlined`,fill:n})})},me=({profileId:e,range:t,customRange:n,destCountryFilter:r,accessPointIdFilter:a,ispFilter:s,setIspFilter:c,isMobile:l})=>{let{t:u}=o(),[d,f]=(0,X.useState)(!1),[p,m]=(0,X.useState)([]),[h,g]=(0,X.useState)(!1),[_,v]=(0,X.useState)(``),y=(0,X.useRef)(``),b=`${e}:${t}:${n.start?Math.floor(new Date(n.start).getTime()/1e3):``}:${n.end?Math.floor(new Date(n.end).getTime()/1e3):``}:${r||``}:${a||``}`,x=async()=>{g(!0);try{let i=Math.floor(Date.now()/1e3),o,s=i,c=new URLSearchParams;if(t===`custom`&&n.start&&n.end)o=Math.floor(new Date(n.start).getTime()/1e3),s=Math.floor(new Date(n.end).getTime()/1e3),c.set(`range`,`custom`),c.set(`start`,String(o)),c.set(`end`,String(s));else{switch(t){case`10m`:o=i-600;break;case`1h`:o=i-3600;break;case`24h`:o=i-86400;break;case`7d`:o=i-604800;break;case`30d`:o=i-2592e3;break;default:o=i-86400;break}c.set(`range`,t)}r&&c.set(`country_code`,r),a&&c.set(`access_point_id`,a);try{let t=await G.queryISPs({profileId:e,countryCode:r||void 0,since:o,until:s,accessPointId:a||void 0});if(t&&t.length>0){m(t),y.current=b,g(!1);return}}catch(e){console.warn(`[IspFilter] Local SQLite query failed, falling back to server:`,e)}let l=await K(e,`isps`,c.toString());m(Array.isArray(l)?l:[]),y.current=b}catch(e){console.error(`Failed to fetch ISPs for filter`,e)}finally{g(!1)}},C=e=>{f(e),e?y.current!==b&&x():v(``)},w=(0,X.useMemo)(()=>{let e=_.trim().toLowerCase();return e?p.filter(t=>t.name.toLowerCase().includes(e)):p},[p,_]),E=(0,Z.jsxs)(`div`,{className:`w-72 flex flex-col p-1.5`,children:[(0,Z.jsx)(`div`,{className:`pb-1.5`,children:(0,Z.jsx)(N,{leftIcon:`search`,placeholder:u(`logs.searchIsp`,`Search ISP...`),value:_,onChange:e=>v(e.target.value),small:!0,autoFocus:!0,rightElement:_?(0,Z.jsx)(T,{icon:`cross`,variant:`minimal`,small:!0,onClick:()=>v(``)}):void 0})}),(0,Z.jsx)(S,{className:`max-h-64 overflow-y-auto`,children:h?(0,Z.jsxs)(`div`,{className:`flex items-center justify-center p-6 text-gray-500 gap-2`,children:[(0,Z.jsx)(D,{size:16}),(0,Z.jsx)(`span`,{className:`text-xs`,children:u(`logs.loadingIsps`,`Loading ISPs...`)})]}):(0,Z.jsxs)(Z.Fragment,{children:[!_&&(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsx)(R,{icon:s===null?`tick`:void 0,text:u(`logs.allIsp`),onClick:()=>{c(null),f(!1)}}),(0,Z.jsx)(P,{})]}),w.length===0?(0,Z.jsx)(R,{disabled:!0,text:u(`logs.noMatchingIsps`,`No matching ISPs found`)}):w.map(e=>(0,Z.jsx)(R,{icon:s===e.name?`tick`:void 0,text:(0,Z.jsxs)(`span`,{className:`flex items-center justify-between gap-2 w-full`,children:[(0,Z.jsx)(`span`,{className:`truncate`,title:e.name,children:e.name}),(0,Z.jsx)(`span`,{className:`text-xs text-gray-400 shrink-0 font-mono`,children:e.count.toLocaleString()})]}),onClick:()=>{c(e.name),f(!1)}},e.name))]})})]}),O=s||u(`logs.allIsp`);return(0,Z.jsx)(A,{content:E,placement:`bottom-start`,isOpen:d,onInteraction:C,children:(0,Z.jsx)(T,{icon:(0,Z.jsx)(i,{size:14}),rightIcon:`caret-down`,intent:s?j.PRIMARY:j.NONE,text:O,variant:`outlined`,fill:l})})},he=({profileId:e,range:t,setRange:n,customRange:r,setCustomRange:i,nowStr:a,fetchLogs:s,isMobile:c,realtimeRefresh:l,setRealtimeRefresh:u,statusFilter:d,setStatusFilter:f,accessPointIdFilter:p,setAccessPointIdFilter:m,accessPoints:h,destCountryFilter:g,setDestCountryFilter:_,ispFilter:v,setIspFilter:y,searchQuery:b,setSearchQuery:x,stats:S,logRetentionDays:C,onExport:w,exporting:E,loading:D=!1,syncing:O=!1})=>{let{t:k}=o(),[A,M]=(0,X.useState)(!0),P=d!==null||p!==null||g!==null||v!==null;return(0,Z.jsxs)(`div`,{className:`p-4 ${c&&A?`space-y-0`:`space-y-4`} shrink-0 bg-white/50 dark:bg-gray-900/50 backdrop-blur-sm border-b border-gray-100 dark:border-gray-800`,children:[(0,Z.jsxs)(`div`,{className:`flex flex-col md:flex-row md:items-center justify-between gap-4`,children:[(0,Z.jsxs)(`div`,{className:`flex items-center justify-between w-full md:w-auto`,children:[(0,Z.jsxs)(`div`,{children:[(0,Z.jsxs)(`h2`,{className:`bp6-heading flex flex-wrap items-center gap-2 text-xl md:text-2xl m-0`,children:[k(`logs.title`),` `,(!c||!A)&&(0,Z.jsx)(L,{minimal:!0,round:!0,children:t===`custom`?k(`analytics.custom`):t.toUpperCase()}),S&&(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsx)(L,{minimal:!0,round:!0,children:S.total.toLocaleString()}),(0,Z.jsx)(L,{minimal:!0,round:!0,intent:j.SUCCESS,children:S.pass.toLocaleString()}),(0,Z.jsx)(L,{minimal:!0,round:!0,intent:j.DANGER,children:S.block.toLocaleString()}),(0,Z.jsx)(L,{minimal:!0,round:!0,intent:j.WARNING,children:S.redirect.toLocaleString()})]})]}),!c&&(0,Z.jsx)(`p`,{className:`bp6-text-muted mt-1`,children:k(`logs.subtitle`)})]}),c&&(0,Z.jsx)(T,{icon:A?`chevron-down`:`chevron-up`,variant:`minimal`,onClick:()=>M(!A)})]}),(!c||!A)&&(0,Z.jsxs)(`div`,{className:`flex flex-col items-stretch md:items-end gap-2`,children:[(0,Z.jsx)(le,{range:t,setRange:n,customRange:r,setCustomRange:i,nowStr:a,fetchLogs:s,isMobile:c,logRetentionDays:C}),(0,Z.jsxs)(`div`,{className:`flex items-center justify-end gap-4`,children:[(0,Z.jsx)(T,{icon:`download`,onClick:w,loading:E,title:k(`logs.export`,`Export Logs`),text:c?void 0:k(`logs.export`,`Export Logs`)}),(0,Z.jsx)(ee,{label:k(`logs.realtime`),checked:l,onChange:e=>u(e.target.checked),className:`mb-0!`}),(0,Z.jsx)(T,{icon:`refresh`,onClick:()=>s(t,!0,!1,!0),loading:D||O,variant:`minimal`,small:c})]})]})]}),(!c||!A)&&(0,Z.jsxs)(`div`,{className:`flex flex-col md:flex-row items-stretch md:items-center justify-between gap-3`,children:[(0,Z.jsxs)(`div`,{className:`grid grid-cols-2 md:flex md:items-center gap-2`,children:[P&&(0,Z.jsx)(`div`,{className:`col-span-2 md:contents`,children:(0,Z.jsx)(T,{icon:`filter-remove`,onClick:()=>{f(null),m(null),_(null),y(null)},variant:`minimal`,title:k(`logs.clearFilters`),text:c?k(`logs.clearFilters`):void 0,fill:c})}),(0,Z.jsx)(ue,{statusFilter:d,setStatusFilter:f,isMobile:c}),h.length>0&&(0,Z.jsx)(de,{accessPointIdFilter:p,setAccessPointIdFilter:m,accessPoints:h,isMobile:c}),(0,Z.jsx)(pe,{destCountryFilter:g,setDestCountryFilter:_,isMobile:c}),(0,Z.jsx)(me,{profileId:e,range:t,customRange:r,destCountryFilter:g,accessPointIdFilter:p,ispFilter:v,setIspFilter:y,isMobile:c})]}),(0,Z.jsx)(`div`,{className:`flex items-center gap-2 flex-1 md:max-w-md justify-end`,children:(0,Z.jsx)(`div`,{className:`flex-1 md:max-w-xs`,children:(0,Z.jsx)(N,{leftIcon:`search`,placeholder:k(`logs.searchPlaceholder`),value:b,onChange:e=>x(e.target.value),rightElement:b?(0,Z.jsx)(T,{icon:`cross`,minimal:!0,onClick:()=>x(``)}):void 0,fill:!0})})})]})]})},ge=({logs:e,setSelectedLog:t,setIsDrawerOpen:n,lastLogElementRef:r,prevLatestTimestamp:i,realtimeRefresh:a})=>{let{t:s}=o();return(0,Z.jsx)(`div`,{className:`space-y-3 py-4`,children:e.map((o,l)=>{let u=a&&i!==null&&o.timestamp>i,d=(o.encrypt_version??0)>0||!!(o.kem_key_id||o.encrypted_payload),f=d&&(!o.domain||o.domain===`[Encrypted]`),p=d&&!!(o.domain&&o.domain!==`[Encrypted]`);return(0,Z.jsxs)(z,{interactive:!0,onClick:()=>{t(o),n(!0)},className:V(`p-3 dark:bg-gray-900 rounded-xl border border-gray-200 dark:border-gray-800 shadow-sm overflow-hidden`,{"animate-row-glow":u}),ref:l===e.length-1?r:null,children:[(0,Z.jsxs)(`div`,{className:`flex justify-between items-start mb-2`,children:[(0,Z.jsxs)(`div`,{className:`flex items-center gap-2 min-w-0`,children:[f?(0,Z.jsx)(c,{size:14,className:`text-amber-500 shrink-0`}):(0,Z.jsx)(`img`,{src:`/api/icon/${o.domain.replace(/^\*\./,``)}.ico`,className:`w-4 h-4 rounded-sm shrink-0`,alt:``,referrerPolicy:`no-referrer`,onError:e=>e.currentTarget.style.opacity=`0`}),(0,Z.jsx)(`span`,{className:V(`font-bold text-sm truncate`,{"italic text-gray-400 dark:text-gray-500":f}),children:f?s(`logs.encryptedRecord`,`[加密记录]`):o.domain}),p&&(0,Z.jsx)(c,{size:12,className:`text-emerald-500 shrink-0 opacity-80`})]}),(0,Z.jsx)(L,{minimal:!0,round:!0,intent:o.action===`PASS`?j.SUCCESS:o.action===`BLOCK`?j.DANGER:j.WARNING,className:`text-[10px] shrink-0`,children:o.action})]}),(0,Z.jsxs)(`div`,{className:`flex justify-between items-center`,children:[(0,Z.jsxs)(`div`,{className:`flex gap-2 items-center`,children:[(0,Z.jsx)(`span`,{className:`text-[10px] font-mono opacity-50`,children:new Date(o.timestamp*1e3).toLocaleTimeString([],{hour12:!1})}),(0,Z.jsx)(`span`,{className:`text-[10px] bg-gray-100 dark:bg-gray-800 px-1 rounded opacity-60`,children:o.record_type}),o.access_point_name&&(0,Z.jsx)(`span`,{className:`text-[10px] opacity-50 truncate max-w-25`,children:o.access_point_name})]}),(0,Z.jsx)(`div`,{className:`text-[10px] opacity-40 font-mono italic`,children:o.latency?`${o.latency}ms`:``})]})]},o.id)})})},_e=({logs:e,setSelectedLog:t,setIsDrawerOpen:n,lastLogElementRef:r,prevLatestTimestamp:i,realtimeRefresh:a})=>{let{t:s}=o(),l=[{key:`time`,header:s(`logs.tableTime`),headerClassName:`w-24 rounded-tl-xl`,cellClassName:`font-mono text-[11px] opacity-60`,render:e=>new Date(e.timestamp*1e3).toLocaleTimeString([],{hour12:!1})},{key:`domain`,header:s(`logs.tableDomain`),headerClassName:`w-1/4`,render:e=>{let t=(e.encrypt_version??0)>0||!!(e.kem_key_id||e.encrypted_payload),n=t&&(!e.domain||e.domain===`[Encrypted]`),r=t&&!!(e.domain&&e.domain!==`[Encrypted]`);return(0,Z.jsxs)(`div`,{className:`flex items-center gap-2 truncate`,children:[n?(0,Z.jsx)(c,{size:14,className:`text-amber-500 shrink-0`}):(0,Z.jsx)(`img`,{src:`/api/icon/${e.domain.replace(/^\*\./,``)}.ico`,className:`w-4 h-4 rounded-sm shrink-0`,alt:``,referrerPolicy:`no-referrer`}),(0,Z.jsx)(`span`,{className:V(`font-bold text-sm truncate`,{"italic text-gray-400 dark:text-gray-500":n}),children:n?s(`logs.encryptedRecord`,`[加密记录]`):e.domain}),r&&(0,Z.jsx)(`span`,{title:s(`settings.e2eeEnabled`,`已加密`),className:`inline-flex items-center`,children:(0,Z.jsx)(c,{size:12,className:`text-emerald-500 shrink-0 opacity-80`})})]})}},{key:`answer`,header:s(`logs.tableAnswer`),headerClassName:`w-1/4`,cellClassName:`truncate font-mono text-[11px] opacity-70`,render:e=>e.answer||`-`},{key:`source`,header:s(`logs.tableSource`),headerClassName:`w-32`,render:e=>(0,Z.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,Z.jsx)(L,{minimal:!0,className:`font-mono text-[10px]`,title:e.geo_country||`Unknown`,children:Y(e.geo_country)}),e.access_point_name&&(0,Z.jsx)(`span`,{className:`text-xs opacity-70 truncate max-w-20`,title:e.access_point_name,children:e.access_point_name})]})},{key:`type`,header:s(`logs.tableType`),headerClassName:`w-20`,cellClassName:`text-center`,render:e=>(0,Z.jsx)(`code`,{className:`text-[10px]`,children:e.record_type})},{key:`status`,header:s(`logs.tableStatus`),headerClassName:`w-28`,cellClassName:`text-center`,render:e=>(0,Z.jsx)(`span`,{className:V(`bp6-tag`,`bp6-fill`,`bp6-minimal`,`bp6-round`,{"bp6-intent-success":e.action===`PASS`,"bp6-intent-danger":e.action===`BLOCK`,"bp6-intent-warning":e.action===`REDIRECT`}),children:(0,Z.jsx)(`span`,{className:`bp6-text-overflow-ellipsis bp6-fill text-center`,children:e.action})})},{key:`reason`,header:s(`logs.tableReason`),headerClassName:`rounded-tr-xl`,cellClassName:`text-xs text-gray-500 italic truncate`,render:e=>e.reason||`-`}];return(0,Z.jsx)(`div`,{className:`min-w-full inline-block align-middle py-0`,children:(0,Z.jsx)(`div`,{className:`bg-white dark:bg-gray-900 rounded-xl border border-gray-200 dark:border-gray-800 shadow-sm overflow-visible`,children:(0,Z.jsxs)(te,{interactive:!0,striped:!0,className:`w-full table-fixed`,children:[(0,Z.jsx)(`thead`,{className:`sticky top-0 z-20 backdrop-blur-md`,children:(0,Z.jsx)(`tr`,{children:l.map(e=>(0,Z.jsx)(`th`,{className:V(`px-4 py-3 text-xs font-bold uppercase text-gray-500 bg-white/80 dark:bg-gray-900/80 border-b border-gray-100 dark:border-gray-800`,e.headerClassName),children:e.header},e.key))})}),(0,Z.jsx)(`tbody`,{className:`divide-y divide-gray-100 dark:divide-gray-800`,children:e.map((o,s)=>{let c=a&&i!==null&&o.timestamp>i;return(0,Z.jsx)(`tr`,{onClick:()=>{t(o),n(!0)},className:V(`cursor-pointer`,{"animate-row-glow":c}),ref:s===e.length-1?r:null,children:l.map(e=>(0,Z.jsx)(`td`,{className:V(`px-4 py-3`,e.cellClassName),children:e.render(o,s)},e.key))},o.id)})})]})})})},ve=({logs:e,loading:t,loadingMore:n,hasMore:r,realtimeRefresh:i,isMobile:a,searchQuery:s,scrollContainerRef:c,lastLogElementRef:l,prevLatestTimestamp:u,setSelectedLog:d,setIsDrawerOpen:f,logRetentionDays:p})=>{let{t:m}=o();return(0,Z.jsxs)(`div`,{ref:c,className:V(`flex-1 overflow-y-auto relative`,a?`px-1`:`px-4`),children:[e.length===0&&!t?(0,Z.jsx)(`div`,{className:`py-20`,children:(0,Z.jsx)(k,{title:p===0?m(`logs.loggingDisabledTitle`,`日志记录已关闭`):m(s?`logs.noResults`:`logs.noRecords`),icon:p===0?`disable`:s?`search`:`outdated`,intent:p===0?j.WARNING:j.NONE,children:p===0?m(`logs.loggingDisabledDesc`,`当前配置的日志留存已设置为“关闭”,系统不记录任何查询日志。如需查看,请在设置中启用日志留存。`):s?m(`logs.noResultsDesc`,{query:s}):m(`logs.noRecordsDesc`)})}):a?(0,Z.jsx)(ge,{logs:e,setSelectedLog:d,setIsDrawerOpen:f,lastLogElementRef:l,prevLatestTimestamp:u,realtimeRefresh:i}):(0,Z.jsx)(_e,{logs:e,setSelectedLog:d,setIsDrawerOpen:f,lastLogElementRef:l,prevLatestTimestamp:u,realtimeRefresh:i}),(0,Z.jsx)(`div`,{className:`p-6 flex flex-col items-center`,children:n?(0,Z.jsx)(D,{size:16}):i?e.length>0&&(0,Z.jsx)(`span`,{className:`text-[10px] opacity-30 italic`,children:m(`logs.realtimeLoadMoreTip`)}):!r&&e.length>0&&(0,Z.jsx)(`span`,{className:`text-[10px] opacity-30 italic`,children:m(`logs.loadedAll`,{count:e.length})})})]})};function ye(e,t,n){let[r,i]=(0,X.useState)(null),[a,o]=(0,X.useState)(!1);return(0,X.useEffect)(()=>{if(e&&t?.id){o(!0),i(t);let e=new AbortController;return re(n,t.id,t.timestamp,{signal:e.signal}).then(async r=>{if(!e.signal.aborted)try{let e=r?.encrypt_version??t.encrypt_version,a=await W.decryptLogEntry(n,r);i(n=>({...n||t,...a,encrypt_version:e??a.encrypt_version}))}catch{i(e=>({...e||t,...r}))}}).catch(e=>{e.name!==`AbortError`&&(console.error(e),i(e=>e||t))}).finally(()=>{e.signal.aborted||o(!1)}),()=>{e.abort()}}else i(null)},[e,t?.id,n]),{detailedLog:r,loading:a}}const Q=({label:e,value:t,bold:n,italic:r})=>(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:e}),(0,Z.jsx)(`span`,{className:V(`text-sm text-right`,n&&`font-bold`,r&&`italic`),children:t})]}),be=({selectedLog:e,detailedLog:t,loading:r})=>{let{t:i}=o(),a=t?.encrypt_version??e.encrypt_version??(t?.kem_key_id||e.kem_key_id?2:0),s=a>0||!!(e.kem_key_id||e.encrypted_payload||t?.kem_key_id||t?.encrypted_payload),l=a===2||!!(e.kem_key_id||t?.kem_key_id),u=s&&(!e.domain||e.domain===`[Encrypted]`);return(0,Z.jsx)(F,{title:i(`logs.basicInfo`),icon:(0,Z.jsx)(n,{size:16}),className:`shadow-none! rounded-lg!`,children:(0,Z.jsx)(M,{children:(0,Z.jsxs)(`div`,{className:`space-y-3`,children:[(0,Z.jsx)(Q,{label:i(`logs.detailDomain`),value:(0,Z.jsxs)(`div`,{className:`flex items-center gap-2 justify-end font-bold`,children:[u?(0,Z.jsx)(c,{size:14,className:`text-amber-500`}):(0,Z.jsx)(`img`,{src:`/api/icon/${e.domain.replace(/^\*\./,``)}.ico`,className:`w-4 h-4 rounded-sm`,alt:``,referrerPolicy:`no-referrer`,onError:e=>e.currentTarget.style.display=`none`}),(0,Z.jsx)(`span`,{className:V({"italic text-gray-400 dark:text-gray-500":u}),children:u?i(`logs.encryptedRecord`,`[加密记录]`):e.domain})]}),bold:!0}),(0,Z.jsx)(Q,{label:i(`logs.detailType`),value:e.record_type}),(0,Z.jsx)(Q,{label:i(`logs.detailLatency`),value:e.latency?`${e.latency} ms`:`-`}),(0,Z.jsx)(Q,{label:i(`logs.detailAccessPoint`),value:(()=>{let n=t?.access_point_name||e.access_point_name,i=t?.access_point_id||e.access_point_id;return n?i&&i!==n?(0,Z.jsx)(`span`,{title:i,className:`cursor-help`,children:n}):n:i?(0,Z.jsx)(`span`,{className:`font-mono text-xs`,children:i}):r?(0,Z.jsx)(D,{size:12}):`-`})()}),(0,Z.jsx)(Q,{label:i(`logs.detailProfile`),value:t?.profile_name||t?.client_ip||e.client_ip||(r?(0,Z.jsx)(D,{size:12}):`-`)}),(0,Z.jsx)(Q,{label:i(`logs.detailTime`),value:ae(new Date(e.timestamp*1e3))}),(0,Z.jsx)(Q,{label:i(`logs.detailStatus`),value:(0,Z.jsx)(L,{minimal:!0,intent:e.action===`PASS`?j.SUCCESS:e.action===`BLOCK`?j.DANGER:j.WARNING,children:e.action})}),(0,Z.jsx)(Q,{label:i(`logs.detailUpstream`),value:t?.upstream||e.upstream||(r?(0,Z.jsx)(D,{size:12}):`-`)}),(0,Z.jsx)(Q,{label:i(`logs.detailReason`),value:e.reason||i(`logs.detailNoReason`),italic:!0}),(0,Z.jsx)(Q,{label:i(`logs.detailECS`),value:t?.ecs||e.ecs||(r?(0,Z.jsx)(D,{size:12}):`-`),italic:!0}),(0,Z.jsx)(Q,{label:i(`logs.detailIsClientEncrypted`,`是否用户端加密`),value:s?(0,Z.jsxs)(`div`,{className:`flex items-center gap-1.5 justify-end`,children:[(0,Z.jsx)(c,{size:13,className:u?`text-amber-500`:`text-emerald-500`}),(0,Z.jsxs)(`span`,{className:V(`text-xs font-medium`,u?`text-amber-600 dark:text-amber-400`:`text-emerald-600 dark:text-emerald-400`),children:[u?i(`logs.encryptedLocked`,`是 (未解锁)`):i(`logs.encryptedYes`,`是`),l?` (PQC)`:``]})]}):(0,Z.jsx)(`span`,{className:`text-xs text-gray-400 dark:text-gray-500`,children:i(`logs.notEncrypted`,`否`)})})]})})})},xe=({selectedLog:e})=>{let{t}=o(),n=e.record_type===`HTTPS`||e.record_type===`SVCB`||e.record_type===`TYPE65`||e.record_type===`TYPE64`,r=n&&(e.reason===`ECH Rewritten`||(e.reason?.toLowerCase().includes(`rewritten`)??!1));return(0,Z.jsx)(F,{title:(0,Z.jsxs)(`div`,{className:`flex items-center justify-between w-full pr-2`,children:[(0,Z.jsx)(`span`,{children:t(`logs.resolutionResult`)}),r&&(0,Z.jsx)(L,{minimal:!0,intent:j.PRIMARY,className:`text-xs`,children:t(`logs.rewritten`,`已重写`)})]}),icon:(0,Z.jsx)(h,{size:16}),className:`shadow-none! rounded-lg!`,children:(0,Z.jsx)(M,{children:(0,Z.jsx)(`div`,{className:`bg-gray-50 dark:bg-gray-800 p-3 font-mono text-xs break-all leading-relaxed rounded-lg`,children:(()=>{if(!e.answer)return t(`logs.noResult`);let r=e.answer.split(`
3
+ `).map(e=>e.trim()).filter(Boolean);return r.length===0?t(`logs.noResult`):(0,Z.jsx)(`div`,{className:`space-y-2`,children:r.map((e,t)=>{let r=e.match(/^(\d+)\s+([^\s]+)(?:\s+(.*))?$/);if(r&&(n||e.includes(`alpn=`)||e.includes(`ech=`)||e.includes(`ipv4hint=`))){let e=r[1],n=r[2],i=(r[3]||``).split(/\s+/).filter(Boolean);return(0,Z.jsxs)(`div`,{className:`bg-white dark:bg-gray-900 p-2.5 rounded-md space-y-2 border border-gray-200 dark:border-gray-700`,children:[(0,Z.jsxs)(`div`,{className:`flex items-center gap-2 text-xs`,children:[(0,Z.jsxs)(L,{minimal:!0,intent:j.PRIMARY,children:[`Priority `,e]}),(0,Z.jsxs)(`span`,{className:`font-semibold text-gray-700 dark:text-gray-300`,children:[`Target: `,n]})]}),i.length>0&&(0,Z.jsx)(`div`,{className:`flex flex-wrap gap-1.5 pt-1 border-t border-gray-100 dark:border-gray-800 text-xs`,children:i.map((e,t)=>{let n=e.indexOf(`=`);if(n===-1)return(0,Z.jsx)(L,{minimal:!0,className:`font-mono`,children:e},t);let r=e.substring(0,n),i=e.substring(n+1);return r===`ech`?(0,Z.jsxs)(L,{minimal:!0,intent:j.SUCCESS,className:`font-mono break-all max-w-full select-all text-left whitespace-normal h-auto py-1 inline-block`,title:i,children:[(0,Z.jsx)(`span`,{className:`font-bold`,children:`ech:`}),` `,i]},t):r===`alpn`?(0,Z.jsxs)(L,{minimal:!0,intent:j.WARNING,className:`font-mono`,children:[(0,Z.jsx)(`span`,{className:`font-bold`,children:`alpn:`}),` `,i]},t):(0,Z.jsxs)(L,{minimal:!0,className:`font-mono`,children:[(0,Z.jsxs)(`span`,{className:`font-bold`,children:[r,`:`]}),` `,i]},t)})})]},t)}return(0,Z.jsx)(`div`,{className:`space-y-1`,children:e.split(`,`).map(e=>e.trim()).filter(Boolean).map((e,t)=>(0,Z.jsx)(`div`,{className:`text-xs font-mono text-gray-800 dark:text-gray-200 select-all`,children:e},t))},t)})})})()})})})},Se=({selectedLog:e,detailedLog:t,loading:n})=>{let{t:r,i18n:i}=o(),a=t?.client_ip||e.client_ip,s=t?.geo_country||e.geo_country,c=`Unknown`;if(s){let e=s.toUpperCase().trim();c=e===`LAN`||e===`LOCAL`||e===`PRIVATE`||e===`PRIVATE NETWORK`?r(`setup.privateNetwork`,`Private Network`):e===`UN`||e===`UNKNOWN`||e===`XX`?r(`common.unknown`,`Unknown`):J(s,i.language)||s}let u=t?.dest_country_code||e.dest_country_code,d=t?.dest_country||e.dest_country,f=t?.dest_isp||e.dest_isp,p=null,h=t?.dest_geoip||e.dest_geoip;if(h)try{let e=JSON.parse(h);!u&&e.country_code&&(u=e.country_code);let t=[e.city,e.region,e.country].filter(Boolean),n=d||u||void 0;p={locationTitle:t.length>0?t.join(`, `):n,isp:e.isp||f||void 0,as:e.as||void 0}}catch{}return!p&&(d||u||f)&&(p={locationTitle:d||u||void 0,isp:f||void 0}),(0,Z.jsx)(F,{title:r(`logs.networkDetails`),icon:(0,Z.jsx)(l,{size:16}),className:`shadow-none! rounded-lg!`,children:(0,Z.jsx)(M,{children:(0,Z.jsxs)(`div`,{className:`space-y-4`,children:[(0,Z.jsxs)(`div`,{children:[(0,Z.jsx)(`div`,{className:`text-[10px] uppercase font-bold opacity-50 mb-1`,children:r(`logs.clientSource`)}),(0,Z.jsxs)(`div`,{className:`flex justify-between items-center`,children:[(0,Z.jsx)(`span`,{className:`font-mono`,children:a||(n?(0,Z.jsx)(D,{size:12}):`-`)}),(s||n)&&(0,Z.jsx)(L,{minimal:!0,title:c,children:s?Y(s):`-`})]})]}),(0,Z.jsxs)(`div`,{children:[(0,Z.jsxs)(`div`,{className:`flex justify-between items-center mb-1`,children:[(0,Z.jsx)(`div`,{className:`text-[10px] uppercase font-bold opacity-50`,children:r(`logs.destination`)}),(u||n)&&(0,Z.jsx)(L,{minimal:!0,title:d||u||`Unknown`,children:u?Y(u):`-`})]}),n&&!p?(0,Z.jsx)(`div`,{className:`flex items-center justify-center py-2`,children:(0,Z.jsx)(D,{size:16})}):p?(0,Z.jsx)(`div`,{className:`bg-gray-50 dark:bg-gray-800 p-3 rounded-lg mt-1`,children:(0,Z.jsxs)(`div`,{className:`flex items-start gap-3`,children:[(0,Z.jsx)(m,{size:16,className:`oklch(60.9% 0.126 221.723) mt-1 shrink-0`}),(0,Z.jsxs)(`div`,{children:[p.locationTitle&&(0,Z.jsx)(`div`,{className:`font-bold text-sm`,children:p.locationTitle}),(p.isp||p.as)&&(0,Z.jsxs)(`div`,{className:`text-xs opacity-70 mt-1`,children:[p.isp,p.as&&(0,Z.jsx)(`span`,{className:`opacity-60 block mt-0.5`,children:p.as})]})]})]})}):(0,Z.jsx)(`div`,{className:`text-xs opacity-50 py-1`,children:`-`})]})]})})})},Ce=({selectedLog:e,onQuickAction:n})=>{let{t:r}=o(),i=(e.encrypt_version??0)>0&&(!e.domain||e.domain===`[Encrypted]`);return(0,Z.jsx)(F,{title:r(`logs.quickActions`),icon:(0,Z.jsx)(s,{size:16}),className:`shadow-none! rounded-lg!`,children:(0,Z.jsx)(M,{children:i?(0,Z.jsx)(`p`,{className:`text-xs text-center text-gray-500 italic py-2 m-0`,children:r(`settings.e2eeUnlockPrompt`,`此记录已加密,请先解锁私钥后再进行操作。`)}):(0,Z.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,Z.jsx)(T,{fill:!0,intent:j.SUCCESS,icon:(0,Z.jsx)(t,{size:16}),text:r(`logs.actionAllow`),onClick:()=>n?.(e.domain,`ALLOW`)}),(0,Z.jsx)(T,{fill:!0,intent:j.DANGER,icon:(0,Z.jsx)(d,{size:16}),text:r(`logs.actionBlock`),onClick:()=>n?.(e.domain,`BLOCK`)}),(0,Z.jsx)(T,{fill:!0,icon:(0,Z.jsx)(_,{size:16}),text:r(`logs.actionRedirect`),onClick:()=>n?.(e.domain,`REDIRECT`,e.record_type)})]})})})},we=({isDrawerOpen:e,setIsDrawerOpen:t,selectedLog:r,profileId:i,isMobile:a,onQuickAction:s})=>{let{t:c}=o(),{detailedLog:l,loading:u}=ye(e,r,i);return(0,Z.jsx)(ce,{isOpen:e&&r!==null,onClose:()=>t(!1),title:(0,Z.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,Z.jsx)(n,{size:18}),(0,Z.jsx)(`span`,{children:c(`logs.logDetails`)})]}),icon:`info-sign`,size:a?`100%`:`450px`,children:r&&(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsx)(be,{selectedLog:r,detailedLog:l,loading:u}),(0,Z.jsx)(xe,{selectedLog:r}),(0,Z.jsx)(Se,{selectedLog:r,detailedLog:l,loading:u}),(0,Z.jsx)(Ce,{selectedLog:r,onQuickAction:s})]})})},Te=({isMobile:e,unlocking:t,onUnlockPasskey:n,onOpenRecoveryDialog:r})=>{let{t:i}=o();return(0,Z.jsx)(`div`,{className:V(`mb-2 shrink-0`,e?`px-2`:`px-4`),children:(0,Z.jsx)(k,{intent:j.PRIMARY,icon:`lock`,title:i(`settings.e2eeTitle`,`端到端加密日志`),children:(0,Z.jsxs)(`div`,{className:`flex flex-col sm:flex-row sm:items-center justify-between gap-3 mt-1`,children:[(0,Z.jsx)(`p`,{className:`text-xs opacity-80 m-0`,children:i(`settings.e2eeUnlockPrompt`,`日志已通过端到端加密保护。请验证已授权的硬件 Passkey 或输入紧急恢复密钥以在本地解密。`)}),(0,Z.jsxs)(`div`,{className:`flex items-center gap-2 flex-wrap shrink-0`,children:[(0,Z.jsx)(T,{intent:j.PRIMARY,icon:`key`,small:!0,loading:t,onClick:n,className:`font-medium`,children:i(`settings.e2eeUnlockNow`,`验证 Passkey 解锁`)}),(0,Z.jsx)(T,{intent:j.NONE,icon:(0,Z.jsx)(a,{size:14}),small:!0,disabled:t,onClick:r,className:`font-medium`,children:i(`settings.e2eeUnlockRecovery`,`使用恢复密钥解锁`)})]})]})})})},Ee=({isOpen:e,onClose:t,recoveryKeyInput:n,setRecoveryKeyInput:r,recoveryError:i,unlocking:a,onSubmit:s})=>{let{t:c}=o();return(0,Z.jsx)(E,{isOpen:e,onClose:t,title:c(`account.e2ee.unlockWithRecoveryTitle`,`使用恢复密钥解锁`),icon:`key`,className:`dark:bg-gray-900`,children:(0,Z.jsxs)(`form`,{onSubmit:s,autoComplete:`off`,children:[(0,Z.jsxs)(`div`,{className:C,children:[(0,Z.jsx)(`p`,{className:`text-xs text-gray-500 dark:text-gray-400 mb-3`,children:c(`account.e2ee.unlockWithRecoveryDesc`,`请输入 30 位紧急恢复密钥。注意:根据单次使用规则,恢复密钥验证成功后将立即自动轮换。`)}),i&&(0,Z.jsx)(k,{intent:j.DANGER,className:`mb-3 text-xs`,children:i}),(0,Z.jsx)(I,{label:c(`account.e2ee.recoveryKeyInputLabel`,`恢复密钥`),labelFor:`recovery-key-input-logs`,children:(0,Z.jsx)(N,{id:`recovery-key-input-logs`,name:`recovery_key_input_logs`,autoComplete:`off`,autoCorrect:`off`,autoCapitalize:`off`,spellCheck:!1,"data-1p-ignore":`true`,"data-lpignore":`true`,"data-bwignore":`true`,placeholder:`123456-789012-345678-901234-567890`,value:n,onChange:e=>r(e.target.value),leftIcon:`key`,className:`font-mono text-xs`,autoFocus:!0})})]}),(0,Z.jsx)(`div`,{className:O,children:(0,Z.jsxs)(`div`,{className:B,children:[(0,Z.jsx)(T,{onClick:t,text:c(`common.cancel`,`取消`)}),(0,Z.jsx)(T,{type:`submit`,intent:j.PRIMARY,loading:a,disabled:!n.trim(),text:c(`account.e2ee.unlockConfirm`,`解锁日志`)})]})})]})})},De=({rotatedKey:e,onClose:t,copiedKey:n,onCopyKey:r})=>{let{t:i}=o();return(0,Z.jsxs)(E,{isOpen:!!e,onClose:t,title:i(`account.recoveryKey.autoRotatedTitle`,`恢复密钥已自动轮换`),icon:`warning-sign`,isCloseButtonShown:!1,canOutsideClickClose:!1,className:`dark:bg-gray-900`,children:[(0,Z.jsxs)(`div`,{className:C,children:[(0,Z.jsx)(k,{intent:j.WARNING,icon:(0,Z.jsx)(d,{size:16}),className:`mb-4 text-xs`,children:i(`account.recoveryKey.autoRotatedNotice`,`根据恢复密钥单次使用规则,您的原恢复密钥已失效,系统已为您生成全新 30 位紧急恢复密钥。请务必立即复制并妥善离线保存,关闭后将无法再次查看!`)}),e&&(0,Z.jsxs)(`div`,{className:`space-y-3`,children:[(0,Z.jsx)(`div`,{className:`p-3 bg-gray-100 dark:bg-gray-800 rounded border border-gray-200 dark:border-gray-700 font-mono text-center text-lg font-bold tracking-widest select-all text-gray-900 dark:text-gray-100`,children:e}),(0,Z.jsx)(`div`,{className:`flex justify-center`,children:(0,Z.jsx)(T,{intent:j.PRIMARY,icon:n?(0,Z.jsx)(u,{size:14,className:`text-green-400`}):(0,Z.jsx)(f,{size:14}),text:n?i(`common.copied`,`已复制`):i(`common.copyKey`,`复制新恢复密钥`),onClick:()=>r(e)})})]})]}),(0,Z.jsx)(`div`,{className:O,children:(0,Z.jsx)(`div`,{className:B,children:(0,Z.jsx)(T,{intent:j.SUCCESS,onClick:t,text:i(`account.recoveryKey.savedAndClose`,`我已妥善保存并继续`)})})})]})};function Oe(e){let[t,n]=(0,X.useState)(`24h`),[r,i]=(0,X.useState)({start:``,end:``}),[a,o]=(0,X.useState)(null),[s,c]=(0,X.useState)(null),[l,u]=(0,X.useState)([]),[d,f]=(0,X.useState)(null),[p,m]=(0,X.useState)(null),[h,g]=(0,X.useState)(``);return(0,X.useEffect)(()=>{U(e).then(u).catch(console.error)},[e]),(0,X.useEffect)(()=>{m(null)},[d]),{range:t,setRange:n,customRange:r,setCustomRange:i,statusFilter:a,setStatusFilter:o,accessPointIdFilter:s,setAccessPointIdFilter:c,accessPoints:l,destCountryFilter:d,setDestCountryFilter:f,ispFilter:p,setIspFilter:m,searchQuery:h,setSearchQuery:g}}function ke(e){let[t,n]=(0,X.useState)(30);return(0,X.useEffect)(()=>{ie(e).then(e=>{try{let t=JSON.parse(e.settings||`{}`);n(t.log_retention_days===void 0?30:Number(t.log_retention_days))}catch(e){console.error(`[useProfileRetention] Failed to parse settings:`,e)}}).catch(e=>console.error(`[useProfileRetention] Failed to fetch profile details:`,e))},[e]),t}function Ae(e,t){let n=Math.floor(Date.now()/1e3);if(e===`custom`&&t.start&&t.end)return{since:Math.floor(new Date(t.start).getTime()/1e3),until:Math.floor(new Date(t.end).getTime()/1e3)};let r;switch(e){case`10m`:r=n-600;break;case`1h`:r=n-3600;break;case`24h`:r=n-86400;break;case`7d`:r=n-604800;break;case`30d`:r=n-2592e3;break;default:r=n-86400;break}return{since:r,until:n}}function je({profileId:e,range:t,customRange:n,statusFilter:r,accessPointIdFilter:i,destCountryFilter:a,ispFilter:o,searchQuery:s,realtimeRefresh:c}){let[l,u]=(0,X.useState)([]),[d,f]=(0,X.useState)(!0),[p,m]=(0,X.useState)(!1),[h,g]=(0,X.useState)(!1),[_,v]=(0,X.useState)(!0),[y,b]=(0,X.useState)(null),[x,S]=(0,X.useState)(null),C=(0,X.useRef)([]);(0,X.useEffect)(()=>{C.current=l},[l]);let w=(0,X.useRef)(null),T=(0,X.useRef)(!1);return(0,X.useEffect)(()=>()=>{w.current&&w.current.abort()},[]),{logs:l,setLogs:u,loading:d,loadingMore:p,syncing:h,hasMore:_,setHasMore:v,stats:y,setStats:b,prevLatestTimestamp:x,setPrevLatestTimestamp:S,fetchLogs:(0,X.useCallback)(async(t,l=!0,d=!1,p=!1)=>{w.current&&w.current.abort();let h=new AbortController;w.current=h,T.current=!0,l?f(!0):m(!0);try{let _=c?25:50,{since:y,until:x}=Ae(t,n),E=!1;try{if(await G.init()&&!h.signal.aborted){let t=!l&&C.current.length>0?C.current[C.current.length-1].timestamp:void 0;if(l){let t=await G.queryLogs({profileId:e,search:s||void 0,action:r||void 0,accessPointId:i||void 0,destCountry:a||void 0,isp:o||void 0,since:y,until:x,before:void 0,limit:_,offset:0});if(h.signal.aborted)return;t.rows.length>0&&(E=!0,S(d&&C.current.length>0?C.current[0].timestamp:null),u(t.rows),v(c?!1:t.rows.length>=_),c&&t.rows.length>0&&H.updateCursor(t.rows[0].timestamp,t.rows[0].id),t.stats&&b(t.stats),f(!1)),d||g(!0);try{let n=await G.syncProfileLogs(e,void 0,y,h.signal,p);if(!h.signal.aborted&&(n>0||t.rows.length===0)){if(t=await G.queryLogs({profileId:e,search:s||void 0,action:r||void 0,accessPointId:i||void 0,destCountry:a||void 0,isp:o||void 0,since:y,until:x,before:void 0,limit:_,offset:0}),h.signal.aborted)return;E=!0,S(d&&C.current.length>0?C.current[0].timestamp:null),u(t.rows),v(c?!1:t.rows.length>=_),c&&t.rows.length>0&&H.updateCursor(t.rows[0].timestamp,t.rows[0].id),t.stats&&b(t.stats)}else !h.signal.aborted&&t.rows.length>0&&(E=!0)}catch(e){e.name!==`AbortError`&&console.warn(`[useLogsFetcher] Incremental sync error:`,e)}finally{w.current===h&&g(!1)}}else if(t!==void 0){let n=await G.queryLogs({profileId:e,search:s||void 0,action:r||void 0,accessPointId:i||void 0,destCountry:a||void 0,isp:o||void 0,since:y,until:x,before:t,limit:_,offset:0});if(h.signal.aborted)return;if(n.rows.length>=_)E=!0,u(e=>[...e,...n.rows]),v(c?!1:n.rows.length>=_);else if(t>y)try{let l=await G.backfillLogs(e,t,y,_,h.signal);if(h.signal.aborted)return;if(E=!0,l.length>0){let n=await G.queryLogs({profileId:e,search:s||void 0,action:r||void 0,accessPointId:i||void 0,destCountry:a||void 0,isp:o||void 0,since:y,until:x,before:t,limit:_,offset:0});if(h.signal.aborted)return;u(e=>[...e,...n.rows]),v(c?!1:n.rows.length>=_&&l.length>=_)}else n.rows.length>0&&u(e=>[...e,...n.rows]),v(!1)}catch(e){e.name!==`AbortError`&&console.warn(`[useLogsFetcher] Backfill error:`,e),n.rows.length>0&&u(e=>[...e,...n.rows]),E=!0,v(!1)}else E=!0,n.rows.length>0&&u(e=>[...e,...n.rows]),v(!1)}else E=!0,v(!1);if(E&&C.current.length>0){let e=Array.from(new Set(C.current.map(e=>e.domain)));`serviceWorker`in navigator&&navigator.serviceWorker.controller&&navigator.serviceWorker.controller.postMessage({type:`PREFETCH_ICONS`,domains:e})}}}catch(e){console.warn(`[useLogsFetcher] Local SQLite failed, falling back to server:`,e),E=!1}if(E){w.current===h&&(f(!1),m(!1),g(!1),T.current=!1);return}let D=new URLSearchParams({range:t,limit:String(_)});t===`custom`&&n.start&&n.end&&(D.set(`start`,String(y)),D.set(`end`,String(x))),r&&D.set(`status`,r),i&&D.set(`access_point_id`,i),a&&D.set(`dest_country`,a),o&&D.set(`isp`,o),s&&D.set(`search`,s),!l&&C.current.length>0&&D.set(`before`,String(C.current[C.current.length-1].timestamp));let O=q(e,D.toString(),{signal:h.signal}),k=Promise.resolve(null);if(l){let r=new URLSearchParams({range:t});t===`custom`&&n.start&&n.end&&(r.set(`start`,String(y)),r.set(`end`,String(x))),s&&r.set(`search`,s),k=K(e,`summary`,r.toString(),{signal:h.signal})}let[A,j]=await Promise.all([O,k]);if(l){if(S(d&&C.current.length>0?C.current[0].timestamp:null),u(A),v(c?!1:A.length>=_),j){let e={total:0,pass:0,block:0,redirect:0};j.forEach(t=>{let n=t.count;e.total+=n,t.action===`PASS`?e.pass=n:t.action===`BLOCK`?e.block=n:t.action===`REDIRECT`&&(e.redirect=n)}),b(e)}}else u(e=>[...e,...A]),v(c?!1:A.length>=_);if(A&&A.length>0){c&&H.updateCursor(A[0].timestamp,A[0].id);let e=Array.from(new Set(A.map(e=>e.domain)));`serviceWorker`in navigator&&navigator.serviceWorker.controller&&navigator.serviceWorker.controller.postMessage({type:`PREFETCH_ICONS`,domains:e})}}catch(e){e.name!==`AbortError`&&console.error(e)}finally{w.current===h&&(f(!1),m(!1),g(!1),T.current=!1)}},[e,c,n,s,r,i,a,o]),isFetchingRef:T,logsRef:C}}function Me({realtimeRefresh:e,statusFilter:t,accessPointIdFilter:n,destCountryFilter:r,ispFilter:i,searchQuery:a,pageSize:o,logsRef:s,setLogs:c,setStats:l,setPrevLatestTimestamp:u}){(0,X.useEffect)(()=>{if(e)return H.onNewLogs(e=>{if(!e||e.length===0)return;let d=e.filter(e=>{if(t&&e.action!==t||n&&e.access_point_id!==n||r&&(e.dest_country_code||e.dest_country)!==r||i&&e.dest_isp!==i)return!1;if(a){let t=a.toLowerCase(),n=e.domain?.toLowerCase().includes(t),r=e.client_ip?.toLowerCase().includes(t),i=e.reason?.toLowerCase().includes(t);if(!n&&!r&&!i)return!1}return!0});d.length!==0&&(u(s.current.length>0?s.current[0].timestamp:null),c(e=>{let t=new Set(e.map(e=>`${e.timestamp}-${e.id}`)),n=d.filter(e=>!t.has(`${e.timestamp}-${e.id}`));return n.length===0?e:[...n,...e].slice(0,o)}),l(t=>{if(!t)return t;let n=0,r=0,i=0;for(let t of e)t.action===`PASS`?n++:t.action===`BLOCK`?r++:t.action===`REDIRECT`&&i++;return{total:t.total+e.length,pass:t.pass+n,block:t.block+r,redirect:t.redirect+i}}))})},[e,t,n,r,i,a,o,s,c,l,u])}function Ne({profileId:e,range:t,customRange:n,statusFilter:r,accessPointIdFilter:i,destCountryFilter:a,ispFilter:o,searchQuery:s,realtimeRefresh:c}){let l=ke(e),{logs:u,setLogs:d,loading:f,loadingMore:p,syncing:m,hasMore:h,stats:g,setStats:_,prevLatestTimestamp:v,setPrevLatestTimestamp:y,fetchLogs:b,isFetchingRef:x,logsRef:S}=je({profileId:e,range:t,customRange:n,statusFilter:r,accessPointIdFilter:i,destCountryFilter:a,ispFilter:o,searchQuery:s,realtimeRefresh:c});Me({realtimeRefresh:c,statusFilter:r,accessPointIdFilter:i,destCountryFilter:a,ispFilter:o,searchQuery:s,pageSize:25,logsRef:S,setLogs:d,setStats:_,setPrevLatestTimestamp:y});let C=(0,X.useRef)(null),w=(0,X.useRef)(null),T=(0,X.useCallback)(()=>{c||x.current||f||p||!h||b(t,!1)},[f,p,h,t,c,b,x]),E=(0,X.useCallback)(e=>{w.current&&w.current.disconnect(),!(f||p||c||!h)&&(w.current=new IntersectionObserver(e=>{e[0]?.isIntersecting&&h&&!x.current&&T()},{root:C.current,rootMargin:`100px`}),e&&w.current.observe(e))},[f,p,h,T,c,x]);return(0,X.useEffect)(()=>{if(t===`custom`&&(!n.start||!n.end))return;let e=setTimeout(()=>{b(t,!0)},s?500:0);return()=>clearTimeout(e)},[t,n.start,n.end,s,b]),{logs:u,loading:f,loadingMore:p,syncing:m,hasMore:h,stats:g,logRetentionDays:l,prevLatestTimestamp:v,scrollContainerRef:C,lastLogElementRef:E,fetchLogs:b,isFetchingRef:x,logsRef:S}}function Pe({profileId:e,range:t,searchQuery:n,realtimeRefresh:r,scrollContainerRef:i,isFetchingRef:a,fetchLogs:o,logsRef:s}){let c=(0,X.useRef)({range:t,searchQuery:n,fetchLogs:o,logsRef:s});(0,X.useEffect)(()=>{c.current={range:t,searchQuery:n,fetchLogs:o,logsRef:s}}),(0,X.useEffect)(()=>{if(!r){H.disconnect();return}let t=!1,n=null,o=()=>{n||=setInterval(()=>{let{range:e,searchQuery:n,fetchLogs:r}=c.current;!t&&document.visibilityState===`visible`&&i.current&&i.current.scrollTop<50&&!a.current&&!n&&e!==`custom`&&r(e,!0,!0)},8e3)},s=()=>{n&&=(clearInterval(n),null)},l=H.onStatusChange(e=>{t=e,e?s():o()}),u=c.current.logsRef.current,d=u.length>0?u[0]:null,f=d?d.timestamp:Math.floor(Date.now()/1e3)-60,p=d?d.id:0;H.connect(e,f,p);let m=setTimeout(()=>{t||o()},2500),h=()=>{if(document.visibilityState===`visible`)if(t){let e=c.current.logsRef.current,t=e.length>0?e[0]:null;t&&H.updateCursor(t.timestamp,t.id)}else{let{range:e,fetchLogs:t}=c.current;t(e,!0,!0)}};return document.addEventListener(`visibilitychange`,h),()=>{clearTimeout(m),s(),l(),H.disconnect(),document.removeEventListener(`visibilitychange`,h)}},[e,r])}function $(e){let t=new Date(e*1e3),n=-t.getTimezoneOffset(),r=n>=0?`+`:`-`,i=e=>String(e).padStart(2,`0`);return t.getFullYear()+`-`+i(t.getMonth()+1)+`-`+i(t.getDate())+`T`+i(t.getHours())+`:`+i(t.getMinutes())+`:`+i(t.getSeconds())+`.`+(e=>String(e).padStart(3,`0`))(t.getMilliseconds())+(n===0?`Z`:r+i(Math.floor(Math.abs(n)/60))+`:`+i(Math.abs(n)%60))}function Fe(e){let t=[`profile_id`,`access_point_id`,`time`,`client_ip`,`geo_country`,`domain`,`record_type`,`action`,`reason`,`answer`,`dest_geoip`,`ecs`,`upstream`,`latency`],n=[t.join(`,`)];for(let r of e){let e=t.map(e=>{let t=``;t=e===`time`?$(r.timestamp):r[e]!==null&&r[e]!==void 0?String(r[e]):``;let n=t.replace(/"/g,`""`);return n.includes(`,`)||n.includes(`
4
+ `)||n.includes(`\r`)||n.includes(`"`)?`"${n}"`:n});n.push(e.join(`,`))}return n.join(`
5
+ `)}function Ie(e,t){let n=new Blob([e],{type:`text/csv;charset=utf-8;`}),r=URL.createObjectURL(n),i=document.createElement(`a`);i.setAttribute(`href`,r),i.setAttribute(`download`,t),document.body.appendChild(i),i.click(),document.body.removeChild(i),URL.revokeObjectURL(r)}function Le(e,t,n,r){return`query_logs_${e}_${$(t)}_${$(n)}_${r.toString()}.csv`}function Re({profileId:e,range:t,customRange:n,statusFilter:r,accessPointIdFilter:i,destCountryFilter:a,ispFilter:s,searchQuery:c,toasterRef:l}){let{t:u}=o(),[d,f]=(0,X.useState)(!1);return{exporting:d,handleExportLogs:async()=>{f(!0);try{let o=new URLSearchParams({range:t});if(t===`custom`&&n.start&&n.end){let e=Math.floor(new Date(n.start).getTime()/1e3),t=Math.floor(new Date(n.end).getTime()/1e3);o.set(`start`,String(e)),o.set(`end`,String(t))}r&&o.set(`status`,r),i&&o.set(`access_point_id`,i),a&&o.set(`dest_country`,a),s&&o.set(`isp`,s),c&&o.set(`search`,c);let{exportProfileLogs:d}=await b(async()=>{let{exportProfileLogs:e}=await import(`./services-DM_tzwVp.js`);return{exportProfileLogs:e}},__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10])),f=await d(e,o.toString());if(!f||f.length===0){l?.current?.show({message:u(`logs.noResults`,`No logs found to export`),intent:j.WARNING});return}Ie(Fe(f),Le(e,f[0].timestamp,f[f.length-1].timestamp,o)),l?.current?.show({message:u(`logs.exportSuccess`,`Logs exported successfully`),intent:j.SUCCESS})}catch(e){console.error(`Failed to export logs`,e),l?.current?.show({message:u(`logs.exportError`,`Failed to export logs`),intent:j.DANGER})}finally{f(!1)}}}}function ze({profileId:e,toasterRef:t}){let[n,r]=(0,X.useState)(!1),i=Oe(e),a=Ne({profileId:e,realtimeRefresh:n,range:i.range,customRange:i.customRange,statusFilter:i.statusFilter,accessPointIdFilter:i.accessPointIdFilter,destCountryFilter:i.destCountryFilter,ispFilter:i.ispFilter,searchQuery:i.searchQuery});Pe({profileId:e,realtimeRefresh:n,range:i.range,searchQuery:i.searchQuery,scrollContainerRef:a.scrollContainerRef,isFetchingRef:a.isFetchingRef,fetchLogs:a.fetchLogs,logsRef:a.logsRef});let o=Re({profileId:e,range:i.range,customRange:i.customRange,statusFilter:i.statusFilter,accessPointIdFilter:i.accessPointIdFilter,destCountryFilter:i.destCountryFilter,ispFilter:i.ispFilter,searchQuery:i.searchQuery,toasterRef:t});return{realtimeRefresh:n,setRealtimeRefresh:r,...i,...a,...o}}function Be({profileId:e,range:t,fetchLogs:n,toasterRef:r}){let{t:i}=o(),[a,s]=(0,X.useState)(!1),[c,l]=(0,X.useState)(!1),[u,d]=(0,X.useState)(!1),[f,p]=(0,X.useState)(!1),[m,h]=(0,X.useState)(``),[g,_]=(0,X.useState)(``),[v,y]=(0,X.useState)(null),[b,x]=(0,X.useState)(!1),S=(0,X.useRef)(!1),C=(0,X.useRef)(e);C.current!==e&&(C.current=e,S.current=!1);let w=(0,X.useCallback)(async()=>{try{let r=await W.getStatus(e),i=!!r.enabled;s(i);let a=W.isProfileUnlocked(e);if(l(a),i&&!a&&r.wrappedPasskeys&&r.wrappedPasskeys.length>0&&!S.current){S.current=!0;try{await W.unlockProfile(e)&&(l(!0),await G.reDecryptLocalLogs(e),n(t,!0))}catch(e){console.debug(`[useLogsE2ee] Silent auto-unlock skipped or cancelled:`,e)}}}catch{s(!1)}},[e,n,t]);return(0,X.useEffect)(()=>{w()},[w]),{isE2eeEnabled:a,isE2eeUnlocked:c,unlocking:u,recoveryDialogOpen:f,setRecoveryDialogOpen:p,recoveryKeyInput:m,setRecoveryKeyInput:h,recoveryError:g,setRecoveryError:_,rotatedKey:v,setRotatedKey:y,copiedKey:b,handleCopyRotatedKey:e=>{navigator.clipboard.writeText(e),x(!0),setTimeout(()=>x(!1),2e3)},handleUnlockPasskey:async()=>{try{d(!0),await W.unlockProfile(e)&&(l(!0),await G.reDecryptLocalLogs(e),r?.current?.show({message:i(`settings.e2eeUnlockSuccess`,`私钥已成功在此设备解锁`),intent:j.SUCCESS}),n(t,!0))}catch(e){console.error(`Failed to unlock E2EE via Passkey:`,e),r?.current?.show({message:e.message||i(`settings.e2eeUnlockError`,`验证 Passkey 解锁失败`),intent:j.DANGER})}finally{d(!1)}},handleUnlockRecoveryKey:async a=>{a.preventDefault();let o=m.trim();if(o){d(!0),_(``);try{await W.unlockWithRecoveryKey(o);try{let e=await oe({recoveryKey:o});await W.wrapCurrentKeyForRecovery(e.recovery_key),y(e.recovery_key)}catch(e){console.warn(`[useLogsE2ee] Recovery key auto-rotation failed:`,e)}l(!0),p(!1),h(``),await G.reDecryptLocalLogs(e),r?.current?.show({message:i(`settings.e2eeUnlockSuccess`,`私钥已成功在此设备解锁`),intent:j.SUCCESS}),n(t,!0)}catch(e){console.error(`Failed to unlock E2EE via recovery key:`,e),_(e.message||i(`account.e2ee.recoveryUnlockFailed`,`恢复密钥无效或解析失败`))}finally{d(!1)}}}}}const Ve=({profileId:e,onQuickAction:t,toasterRef:n})=>{let r=ne(),[i,a]=(0,X.useState)(null),[o,s]=(0,X.useState)(!1),{realtimeRefresh:c,setRealtimeRefresh:l,range:u,setRange:d,customRange:f,setCustomRange:p,statusFilter:m,setStatusFilter:h,accessPointIdFilter:g,setAccessPointIdFilter:_,accessPoints:v,destCountryFilter:y,setDestCountryFilter:b,ispFilter:x,setIspFilter:S,searchQuery:C,setSearchQuery:w,logs:T,loading:E,loadingMore:O,syncing:k,hasMore:A,stats:j,logRetentionDays:M,prevLatestTimestamp:N,scrollContainerRef:ee,lastLogElementRef:P,fetchLogs:F,exporting:I,handleExportLogs:L}=ze({profileId:e,toasterRef:n}),{isE2eeEnabled:te,isE2eeUnlocked:R,unlocking:z,recoveryDialogOpen:B,setRecoveryDialogOpen:V,recoveryKeyInput:H,setRecoveryKeyInput:U,recoveryError:W,setRecoveryError:G,rotatedKey:re,setRotatedKey:K,copiedKey:ie,handleCopyRotatedKey:q,handleUnlockPasskey:ae,handleUnlockRecoveryKey:oe}=Be({profileId:e,range:u,fetchLogs:F,toasterRef:n}),se=new Date().toLocaleString(`sv-SE`).replace(` `,`T`).slice(0,16);return E&&T.length===0?(0,Z.jsx)(`div`,{className:`h-full flex items-center justify-center`,children:(0,Z.jsx)(D,{})}):(0,Z.jsxs)(`div`,{className:`h-full flex flex-col overflow-hidden bg-gray-50/30 dark:bg-gray-950/10 max-w-7xl mx-auto w-full pt-14`,children:[(0,Z.jsx)(he,{profileId:e,range:u,setRange:d,customRange:f,setCustomRange:p,nowStr:se,fetchLogs:F,isMobile:r,realtimeRefresh:c,setRealtimeRefresh:l,statusFilter:m,setStatusFilter:h,accessPointIdFilter:g,setAccessPointIdFilter:_,accessPoints:v,destCountryFilter:y,setDestCountryFilter:b,ispFilter:x,setIspFilter:S,searchQuery:C,setSearchQuery:w,stats:j,logRetentionDays:M,onExport:L,exporting:I,loading:E,syncing:k}),te&&!R&&(0,Z.jsx)(Te,{isMobile:r,unlocking:z,onUnlockPasskey:ae,onOpenRecoveryDialog:()=>{G(``),U(``),V(!0)}}),(0,Z.jsx)(ve,{logs:T,loading:E,loadingMore:O,hasMore:A,realtimeRefresh:c,isMobile:r,searchQuery:C,scrollContainerRef:ee,lastLogElementRef:P,prevLatestTimestamp:N,setSelectedLog:a,setIsDrawerOpen:s,logRetentionDays:M}),(0,Z.jsx)(we,{isDrawerOpen:o,setIsDrawerOpen:s,selectedLog:i,profileId:e,isMobile:r,onQuickAction:t}),(0,Z.jsx)(Ee,{isOpen:B,onClose:()=>V(!1),recoveryKeyInput:H,setRecoveryKeyInput:U,recoveryError:W,unlocking:z,onSubmit:oe}),(0,Z.jsx)(De,{rotatedKey:re,onClose:()=>K(null),copiedKey:ie,onCopyKey:q})]})};export{Ve as LogsView};
@@ -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-BmoHsW1x.js";import{S as f,b as p}from"./vendor-icons-other-Bme3ywH9.js";import{C as m,H as h,N as g,O as _,S as v,V as y,b,d as x,f as S,p as C,r as w,u as T,x as E,y as D}from"./vendor-ui-core-CY_WyMIf.js";import{_t as O}from"./vendor-utils-BWSB0jGn.js";import{X as k,bt as A,dt as j,ln as M,rt as N,st as P,w as F}from"./index-dXN_pYn1.js";var I=e(f(),1),L=e(p(),1);const R=({newRule:e,setNewRule:t,addRule:n})=>{let{t:r}=i();return(0,L.jsx)(E,{elevation:h.ONE,className:`mb-8 p-6`,children:(0,L.jsxs)(`div`,{className:`flex flex-col gap-6`,children:[(0,L.jsxs)(`div`,{className:`flex flex-col lg:flex-row justify-between gap-4 items-start lg:items-end`,children:[(0,L.jsx)(`div`,{className:`w-full lg:w-48`,children:(0,L.jsx)(C,{label:r(`rules.action`),labelFor:`rule-type`,children:(0,L.jsx)(x,{id:`rule-type`,fill:!0,large:!0,value:e.type,onChange:n=>t({...e,type:n.target.value}),options:[{label:r(`rules.typeBlock`),value:`BLOCK`},{label:r(`rules.typeAllow`),value:`ALLOW`},{label:r(`rules.typeRedirect`),value:`REDIRECT`}]})})}),(0,L.jsx)(`div`,{className:`flex-1 w-full lg:w-48`,children:(0,L.jsx)(C,{label:r(`rules.pattern`),labelFor:`rule-pattern`,children:(0,L.jsx)(S,{id:`rule-pattern`,size:`large`,placeholder:r(`rules.patternPlaceholder`),value:e.pattern,onChange:n=>t({...e,pattern:n.target.value})})})}),e.type!==`REDIRECT`&&(0,L.jsx)(C,{label:``,labelFor:``,children:(0,L.jsx)(g,{intent:y.PRIMARY,size:`large`,icon:(0,L.jsx)(d,{size:18}),onClick:n,children:r(`rules.addRule`)})})]}),e.type===`REDIRECT`&&(0,L.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,L.jsxs)(`div`,{className:`flex items-center gap-2 mb-4 text-blue-600 dark:text-blue-400`,children:[(0,L.jsx)(c,{size:16}),(0,L.jsx)(`span`,{className:`text-xs font-bold uppercase tracking-wider`,children:r(`rules.redirectSettings`)})]}),(0,L.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-x-8 gap-y-4`,children:[(0,L.jsx)(C,{label:r(`rules.aRecord`),labelInfo:r(`rules.optional`),children:(0,L.jsx)(S,{placeholder:r(`rules.ipv4Placeholder`),value:e.v_a,onChange:n=>t({...e,v_a:n.target.value})})}),(0,L.jsx)(C,{label:r(`rules.aaaaRecord`),labelInfo:r(`rules.optional`),children:(0,L.jsx)(S,{placeholder:r(`rules.ipv6Placeholder`),value:e.v_aaaa,onChange:n=>t({...e,v_aaaa:n.target.value})})}),(0,L.jsx)(C,{label:r(`rules.cnameRecord`),labelInfo:r(`rules.optional`),children:(0,L.jsx)(S,{placeholder:r(`rules.cnamePlaceholder`),value:e.v_cname,onChange:n=>t({...e,v_cname:n.target.value})})}),(0,L.jsx)(C,{label:r(`rules.txtRecord`),labelInfo:r(`rules.optional`),children:(0,L.jsx)(S,{placeholder:r(`rules.txtPlaceholder`),value:e.v_txt,onChange:n=>t({...e,v_txt:n.target.value})})})]}),(0,L.jsx)(`div`,{className:`mt-6 pt-4 border-t border-gray-200 dark:border-gray-700 flex justify-end`,children:(0,L.jsx)(g,{intent:y.PRIMARY,large:!0,icon:(0,L.jsx)(d,{size:18}),onClick:n,text:r(`rules.saveRedirectRule`)})})]})]})})},z=({rules:e,startEdit:t,getBlockDetail:n})=>{let{t:c}=i(),[d,f]=(0,I.useState)(`created_at`),[p,m]=(0,I.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,I.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,L.jsxs)(L.Fragment,{children:[e.type===`BLOCK`&&(0,L.jsx)(w,{intent:y.DANGER,minimal:!0,icon:(0,L.jsx)(r,{size:12,className:`mr-1`}),children:c(`rules.labelBlock`)}),e.type===`ALLOW`&&(0,L.jsx)(w,{intent:y.SUCCESS,minimal:!0,icon:(0,L.jsx)(s,{size:12,className:`mr-1`}),children:c(`rules.labelAllow`)}),e.type===`REDIRECT`&&(0,L.jsx)(w,{intent:y.WARNING,minimal:!0,icon:(0,L.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,L.jsx)(L.Fragment,{children:e.type===`REDIRECT`?(0,L.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[e.v_a&&(0,L.jsxs)(w,{minimal:!0,className:`font-mono text-[10px]`,children:[`A: `,e.v_a]}),e.v_aaaa&&(0,L.jsxs)(w,{minimal:!0,className:`font-mono text-[10px]`,children:[`AAAA: `,e.v_aaaa]}),e.v_cname&&(0,L.jsxs)(w,{minimal:!0,className:`font-mono text-[10px]`,children:[`CNAME: `,e.v_cname]}),e.v_txt&&(0,L.jsxs)(w,{minimal:!0,className:`font-mono text-[10px]`,children:[`TXT: `,e.v_txt]})]}):e.type===`BLOCK`?(0,L.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,L.jsx)(`span`,{className:`text-gray-400 text-xs italic`,children:c(`rules.detailBlock`)}),(0,L.jsx)(w,{minimal:!0,round:!0,className:`text-[9px] px-1.5 opacity-70`,children:n()})]}):(0,L.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?F(new Date(e.created_at*1e3)):`—`}];return(0,L.jsx)(`div`,{className:`w-full max-w-full overflow-x-auto pb-4`,children:(0,L.jsxs)(T,{interactive:!0,striped:!0,className:`w-full min-w-max whitespace-nowrap`,children:[(0,L.jsx)(`thead`,{children:(0,L.jsx)(`tr`,{children:v.map(e=>(0,L.jsx)(`th`,{onClick:()=>h(e.key),className:O(e.headerClassName,`cursor-pointer select-none transition-colors hover:text-blue-500`),title:c(`rules.clickToSort`,`点击排序`),children:(0,L.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,L.jsx)(`span`,{children:e.header}),d===e.key?p===`asc`?(0,L.jsx)(u,{size:13,className:`text-blue-500 shrink-0`}):(0,L.jsx)(l,{size:13,className:`text-blue-500 shrink-0`}):(0,L.jsx)(o,{size:12,className:`opacity-30 hover:opacity-75 shrink-0`})]})},e.key))})}),(0,L.jsx)(`tbody`,{children:_.map(e=>(0,L.jsx)(`tr`,{onClick:()=>t(e),className:`cursor-pointer`,children:v.map(t=>(0,L.jsx)(`td`,{className:t.cellClassName,children:t.render(e)},t.key))},e.id))})]})})},B=({editRule:e,setEditRule:n,saveEditRule:r,cancelEdit:a,deleteRule:o})=>{let{t:s}=i();return(0,L.jsxs)(_,{isOpen:!!e,onClose:a,title:s(`rules.editRule`,`Edit Rule`),style:{width:`600px`},children:[(0,L.jsx)(b,{children:e&&(0,L.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,L.jsxs)(`div`,{className:`flex gap-4`,children:[(0,L.jsx)(C,{label:s(`rules.action`),className:`w-40 mb-0`,children:(0,L.jsx)(x,{fill:!0,value:e.type,onChange:t=>n({...e,type:t.target.value}),options:[{label:s(`rules.typeBlock`),value:`BLOCK`},{label:s(`rules.typeAllow`),value:`ALLOW`},{label:s(`rules.typeRedirect`),value:`REDIRECT`}]})}),(0,L.jsx)(C,{label:s(`rules.pattern`),className:`flex-1 mb-0`,children:(0,L.jsx)(S,{placeholder:s(`rules.patternPlaceholder`),value:e.pattern,onChange:t=>n({...e,pattern:t.target.value})})})]}),e.type===`REDIRECT`&&(0,L.jsxs)(`div`,{className:`bg-gray-50 dark:bg-gray-800 p-4 rounded-lg border border-gray-200 dark:border-gray-700`,children:[(0,L.jsxs)(`div`,{className:`flex items-center gap-2 mb-4 text-blue-600 dark:text-blue-400`,children:[(0,L.jsx)(c,{size:14}),(0,L.jsx)(`span`,{className:`text-xs font-bold uppercase tracking-wider`,children:s(`rules.redirectSettings`)})]}),(0,L.jsxs)(`div`,{className:`grid grid-cols-2 gap-4`,children:[(0,L.jsx)(C,{label:s(`rules.aRecord`),className:`mb-0`,children:(0,L.jsx)(S,{placeholder:s(`rules.ipv4Placeholder`),value:e.v_a||``,onChange:t=>n({...e,v_a:t.target.value})})}),(0,L.jsx)(C,{label:s(`rules.aaaaRecord`),className:`mb-0`,children:(0,L.jsx)(S,{placeholder:s(`rules.ipv6Placeholder`),value:e.v_aaaa||``,onChange:t=>n({...e,v_aaaa:t.target.value})})}),(0,L.jsx)(C,{label:s(`rules.cnameRecord`),className:`mb-0`,children:(0,L.jsx)(S,{placeholder:s(`rules.cnamePlaceholder`),value:e.v_cname||``,onChange:t=>n({...e,v_cname:t.target.value})})}),(0,L.jsx)(C,{label:s(`rules.txtRecord`),className:`mb-0`,children:(0,L.jsx)(S,{placeholder:s(`rules.txtPlaceholder`),value:e.v_txt||``,onChange:t=>n({...e,v_txt:t.target.value})})})]})]})]})}),(0,L.jsx)(D,{actions:(0,L.jsxs)(`div`,{className:`flex gap-2`,children:[(0,L.jsx)(g,{onClick:a,children:s(`rules.cancel`,`Cancel`)}),(0,L.jsx)(g,{intent:y.PRIMARY,onClick:r,children:s(`rules.saveChanges`,`Save Changes`)})]}),children:(0,L.jsx)(g,{icon:(0,L.jsx)(t,{size:14}),intent:y.DANGER,text:s(`rules.delete`,`Delete`),onClick:()=>{e&&o(e.id)}})})]})},V=({profileId:e,prefill:t,onPrefillUsed:r,toasterRef:a})=>{let o=n(),[s,c]=(0,I.useState)([]),[l,u]=(0,I.useState)(null),[,d]=(0,I.useState)(!0),{t:f}=i(),p=M(),[h,_]=(0,I.useState)({type:`BLOCK`,pattern:``,v_a:``,v_aaaa:``,v_txt:``,v_cname:``}),[b,x]=(0,I.useState)(null);(0,I.useEffect)(()=>{t&&(_({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 S=async()=>{d(!0);try{let[t,n]=await Promise.all([j(e),P(e)]);c(t),u(JSON.parse(n.settings||`{}`))}catch(e){console.error(`Failed to fetch data`,e)}finally{d(!1)}};return(0,I.useEffect)(()=>{S()},[e]),(0,L.jsxs)(`div`,{className:O(`md:px-8 w-full min-w-0 max-w-5xl mx-auto`,p?`p-1`:`px-8`),children:[(0,L.jsx)(`div`,{className:`mb-8`,children:(0,L.jsx)(`div`,{className:`flex flex-col md:flex-row justify-between items-start gap-4`,children:(0,L.jsxs)(`div`,{className:`w-full md:w-auto flex-1`,children:[p?(0,L.jsxs)(m,{minimal:!0,fill:p,children:[(0,L.jsx)(g,{active:!0,onClick:()=>o(`/dash/${e}/rules`),text:f(`rules.title`),large:!0}),(0,L.jsx)(g,{active:!1,onClick:()=>o(`/dash/${e}/filter`),text:f(`filtering.title`),large:!0})]}):(0,L.jsx)(`h1`,{className:`bp6-heading`,children:f(`rules.title`)}),(0,L.jsx)(`p`,{className:`bp6-text-muted mt-2!`,children:f(`rules.subtitle`)})]})})}),(0,L.jsx)(R,{newRule:h,setNewRule:_,addRule:async()=>{let t=h.pattern.trim();if(!t){a?.current?.show({message:f(`rules.patternEmpty`,`Domain pattern cannot be empty`),intent:y.DANGER});return}let n=t.toLowerCase();if(s.some(e=>e.pattern.trim().toLowerCase()===n)){a?.current?.show({message:f(`rules.duplicatePattern`,`Rule for this domain already exists`),intent:y.DANGER});return}try{await k(e,{...h,pattern:t}),a?.current?.show({message:f(`rules.addSuccess`,`Rule added successfully`),intent:y.SUCCESS}),_({type:`BLOCK`,pattern:``,v_a:``,v_aaaa:``,v_txt:``,v_cname:``}),S()}catch(e){a?.current?.show({message:e.message||f(`rules.addFailed`,`Failed to add rule`),intent:y.DANGER})}}}),s.length===0?(0,L.jsx)(v,{title:f(`rules.noRulesTitle`),children:f(`rules.noRulesDesc`)}):(0,L.jsx)(z,{rules:s,startEdit:e=>{x({...e})},getBlockDetail:()=>{if(!l)return f(`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,L.jsx)(B,{editRule:b,setEditRule:x,saveEditRule:async()=>{if(!b)return;let t=b.pattern.trim();if(!t){a?.current?.show({message:f(`rules.patternEmpty`,`Domain pattern cannot be empty`),intent:y.DANGER});return}let n=t.toLowerCase();if(s.some(e=>e.id!==b.id&&e.pattern.trim().toLowerCase()===n)){a?.current?.show({message:f(`rules.duplicatePattern`,`Rule for this domain already exists`),intent:y.DANGER});return}try{await A(e,{...b,pattern:t}),a?.current?.show({message:f(`rules.updateSuccess`,`Rule updated successfully`),intent:y.SUCCESS}),x(null),S()}catch(e){a?.current?.show({message:e.message||f(`rules.updateFailed`,`Failed to update rule`),intent:y.DANGER})}},cancelEdit:()=>{x(null)},deleteRule:async t=>{try{await N(e,t)}catch(e){console.error(e)}x(null),S()}})]})};export{V 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-BmoHsW1x.js";import{S as f,b as p}from"./vendor-icons-other-Bme3ywH9.js";import{C as m,H as h,N as g,O as _,S as v,V as y,b,d as x,f as S,p as C,r as w,u as T,x as E,y as D}from"./vendor-ui-core-CY_WyMIf.js";import{_t as O}from"./vendor-utils-BWSB0jGn.js";import{X as k,bt as A,dt as j,ln as M,rt as N,st as P,w as F}from"./index-CP2FJpkF.js";var I=e(f(),1),L=e(p(),1);const R=({newRule:e,setNewRule:t,addRule:n})=>{let{t:r}=i();return(0,L.jsx)(E,{elevation:h.ONE,className:`mb-8 p-6`,children:(0,L.jsxs)(`div`,{className:`flex flex-col gap-6`,children:[(0,L.jsxs)(`div`,{className:`flex flex-col lg:flex-row justify-between gap-4 items-start lg:items-end`,children:[(0,L.jsx)(`div`,{className:`w-full lg:w-48`,children:(0,L.jsx)(C,{label:r(`rules.action`),labelFor:`rule-type`,children:(0,L.jsx)(x,{id:`rule-type`,fill:!0,large:!0,value:e.type,onChange:n=>t({...e,type:n.target.value}),options:[{label:r(`rules.typeBlock`),value:`BLOCK`},{label:r(`rules.typeAllow`),value:`ALLOW`},{label:r(`rules.typeRedirect`),value:`REDIRECT`}]})})}),(0,L.jsx)(`div`,{className:`flex-1 w-full lg:w-48`,children:(0,L.jsx)(C,{label:r(`rules.pattern`),labelFor:`rule-pattern`,children:(0,L.jsx)(S,{id:`rule-pattern`,size:`large`,placeholder:r(`rules.patternPlaceholder`),value:e.pattern,onChange:n=>t({...e,pattern:n.target.value})})})}),e.type!==`REDIRECT`&&(0,L.jsx)(C,{label:``,labelFor:``,children:(0,L.jsx)(g,{intent:y.PRIMARY,size:`large`,icon:(0,L.jsx)(d,{size:18}),onClick:n,children:r(`rules.addRule`)})})]}),e.type===`REDIRECT`&&(0,L.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,L.jsxs)(`div`,{className:`flex items-center gap-2 mb-4 text-blue-600 dark:text-blue-400`,children:[(0,L.jsx)(c,{size:16}),(0,L.jsx)(`span`,{className:`text-xs font-bold uppercase tracking-wider`,children:r(`rules.redirectSettings`)})]}),(0,L.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-x-8 gap-y-4`,children:[(0,L.jsx)(C,{label:r(`rules.aRecord`),labelInfo:r(`rules.optional`),children:(0,L.jsx)(S,{placeholder:r(`rules.ipv4Placeholder`),value:e.v_a,onChange:n=>t({...e,v_a:n.target.value})})}),(0,L.jsx)(C,{label:r(`rules.aaaaRecord`),labelInfo:r(`rules.optional`),children:(0,L.jsx)(S,{placeholder:r(`rules.ipv6Placeholder`),value:e.v_aaaa,onChange:n=>t({...e,v_aaaa:n.target.value})})}),(0,L.jsx)(C,{label:r(`rules.cnameRecord`),labelInfo:r(`rules.optional`),children:(0,L.jsx)(S,{placeholder:r(`rules.cnamePlaceholder`),value:e.v_cname,onChange:n=>t({...e,v_cname:n.target.value})})}),(0,L.jsx)(C,{label:r(`rules.txtRecord`),labelInfo:r(`rules.optional`),children:(0,L.jsx)(S,{placeholder:r(`rules.txtPlaceholder`),value:e.v_txt,onChange:n=>t({...e,v_txt:n.target.value})})})]}),(0,L.jsx)(`div`,{className:`mt-6 pt-4 border-t border-gray-200 dark:border-gray-700 flex justify-end`,children:(0,L.jsx)(g,{intent:y.PRIMARY,large:!0,icon:(0,L.jsx)(d,{size:18}),onClick:n,text:r(`rules.saveRedirectRule`)})})]})]})})},z=({rules:e,startEdit:t,getBlockDetail:n})=>{let{t:c}=i(),[d,f]=(0,I.useState)(`created_at`),[p,m]=(0,I.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,I.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,L.jsxs)(L.Fragment,{children:[e.type===`BLOCK`&&(0,L.jsx)(w,{intent:y.DANGER,minimal:!0,icon:(0,L.jsx)(r,{size:12,className:`mr-1`}),children:c(`rules.labelBlock`)}),e.type===`ALLOW`&&(0,L.jsx)(w,{intent:y.SUCCESS,minimal:!0,icon:(0,L.jsx)(s,{size:12,className:`mr-1`}),children:c(`rules.labelAllow`)}),e.type===`REDIRECT`&&(0,L.jsx)(w,{intent:y.WARNING,minimal:!0,icon:(0,L.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,L.jsx)(L.Fragment,{children:e.type===`REDIRECT`?(0,L.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[e.v_a&&(0,L.jsxs)(w,{minimal:!0,className:`font-mono text-[10px]`,children:[`A: `,e.v_a]}),e.v_aaaa&&(0,L.jsxs)(w,{minimal:!0,className:`font-mono text-[10px]`,children:[`AAAA: `,e.v_aaaa]}),e.v_cname&&(0,L.jsxs)(w,{minimal:!0,className:`font-mono text-[10px]`,children:[`CNAME: `,e.v_cname]}),e.v_txt&&(0,L.jsxs)(w,{minimal:!0,className:`font-mono text-[10px]`,children:[`TXT: `,e.v_txt]})]}):e.type===`BLOCK`?(0,L.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,L.jsx)(`span`,{className:`text-gray-400 text-xs italic`,children:c(`rules.detailBlock`)}),(0,L.jsx)(w,{minimal:!0,round:!0,className:`text-[9px] px-1.5 opacity-70`,children:n()})]}):(0,L.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?F(new Date(e.created_at*1e3)):`—`}];return(0,L.jsx)(`div`,{className:`w-full max-w-full overflow-x-auto pb-4`,children:(0,L.jsxs)(T,{interactive:!0,striped:!0,className:`w-full min-w-max whitespace-nowrap`,children:[(0,L.jsx)(`thead`,{children:(0,L.jsx)(`tr`,{children:v.map(e=>(0,L.jsx)(`th`,{onClick:()=>h(e.key),className:O(e.headerClassName,`cursor-pointer select-none transition-colors hover:text-blue-500`),title:c(`rules.clickToSort`,`点击排序`),children:(0,L.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,L.jsx)(`span`,{children:e.header}),d===e.key?p===`asc`?(0,L.jsx)(u,{size:13,className:`text-blue-500 shrink-0`}):(0,L.jsx)(l,{size:13,className:`text-blue-500 shrink-0`}):(0,L.jsx)(o,{size:12,className:`opacity-30 hover:opacity-75 shrink-0`})]})},e.key))})}),(0,L.jsx)(`tbody`,{children:_.map(e=>(0,L.jsx)(`tr`,{onClick:()=>t(e),className:`cursor-pointer`,children:v.map(t=>(0,L.jsx)(`td`,{className:t.cellClassName,children:t.render(e)},t.key))},e.id))})]})})},B=({editRule:e,setEditRule:n,saveEditRule:r,cancelEdit:a,deleteRule:o})=>{let{t:s}=i();return(0,L.jsxs)(_,{isOpen:!!e,onClose:a,title:s(`rules.editRule`,`Edit Rule`),style:{width:`600px`},children:[(0,L.jsx)(b,{children:e&&(0,L.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,L.jsxs)(`div`,{className:`flex gap-4`,children:[(0,L.jsx)(C,{label:s(`rules.action`),className:`w-40 mb-0`,children:(0,L.jsx)(x,{fill:!0,value:e.type,onChange:t=>n({...e,type:t.target.value}),options:[{label:s(`rules.typeBlock`),value:`BLOCK`},{label:s(`rules.typeAllow`),value:`ALLOW`},{label:s(`rules.typeRedirect`),value:`REDIRECT`}]})}),(0,L.jsx)(C,{label:s(`rules.pattern`),className:`flex-1 mb-0`,children:(0,L.jsx)(S,{placeholder:s(`rules.patternPlaceholder`),value:e.pattern,onChange:t=>n({...e,pattern:t.target.value})})})]}),e.type===`REDIRECT`&&(0,L.jsxs)(`div`,{className:`bg-gray-50 dark:bg-gray-800 p-4 rounded-lg border border-gray-200 dark:border-gray-700`,children:[(0,L.jsxs)(`div`,{className:`flex items-center gap-2 mb-4 text-blue-600 dark:text-blue-400`,children:[(0,L.jsx)(c,{size:14}),(0,L.jsx)(`span`,{className:`text-xs font-bold uppercase tracking-wider`,children:s(`rules.redirectSettings`)})]}),(0,L.jsxs)(`div`,{className:`grid grid-cols-2 gap-4`,children:[(0,L.jsx)(C,{label:s(`rules.aRecord`),className:`mb-0`,children:(0,L.jsx)(S,{placeholder:s(`rules.ipv4Placeholder`),value:e.v_a||``,onChange:t=>n({...e,v_a:t.target.value})})}),(0,L.jsx)(C,{label:s(`rules.aaaaRecord`),className:`mb-0`,children:(0,L.jsx)(S,{placeholder:s(`rules.ipv6Placeholder`),value:e.v_aaaa||``,onChange:t=>n({...e,v_aaaa:t.target.value})})}),(0,L.jsx)(C,{label:s(`rules.cnameRecord`),className:`mb-0`,children:(0,L.jsx)(S,{placeholder:s(`rules.cnamePlaceholder`),value:e.v_cname||``,onChange:t=>n({...e,v_cname:t.target.value})})}),(0,L.jsx)(C,{label:s(`rules.txtRecord`),className:`mb-0`,children:(0,L.jsx)(S,{placeholder:s(`rules.txtPlaceholder`),value:e.v_txt||``,onChange:t=>n({...e,v_txt:t.target.value})})})]})]})]})}),(0,L.jsx)(D,{actions:(0,L.jsxs)(`div`,{className:`flex gap-2`,children:[(0,L.jsx)(g,{onClick:a,children:s(`rules.cancel`,`Cancel`)}),(0,L.jsx)(g,{intent:y.PRIMARY,onClick:r,children:s(`rules.saveChanges`,`Save Changes`)})]}),children:(0,L.jsx)(g,{icon:(0,L.jsx)(t,{size:14}),intent:y.DANGER,text:s(`rules.delete`,`Delete`),onClick:()=>{e&&o(e.id)}})})]})},V=({profileId:e,prefill:t,onPrefillUsed:r,toasterRef:a})=>{let o=n(),[s,c]=(0,I.useState)([]),[l,u]=(0,I.useState)(null),[,d]=(0,I.useState)(!0),{t:f}=i(),p=M(),[h,_]=(0,I.useState)({type:`BLOCK`,pattern:``,v_a:``,v_aaaa:``,v_txt:``,v_cname:``}),[b,x]=(0,I.useState)(null);(0,I.useEffect)(()=>{t&&(_({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 S=async()=>{d(!0);try{let[t,n]=await Promise.all([j(e),P(e)]);c(t),u(JSON.parse(n.settings||`{}`))}catch(e){console.error(`Failed to fetch data`,e)}finally{d(!1)}};return(0,I.useEffect)(()=>{S()},[e]),(0,L.jsxs)(`div`,{className:O(`md:px-8 w-full min-w-0 max-w-5xl mx-auto`,p?`p-1`:`px-8`),children:[(0,L.jsx)(`div`,{className:`mb-8`,children:(0,L.jsx)(`div`,{className:`flex flex-col md:flex-row justify-between items-start gap-4`,children:(0,L.jsxs)(`div`,{className:`w-full md:w-auto flex-1`,children:[p?(0,L.jsxs)(m,{minimal:!0,fill:p,children:[(0,L.jsx)(g,{active:!0,onClick:()=>o(`/dash/${e}/rules`),text:f(`rules.title`),large:!0}),(0,L.jsx)(g,{active:!1,onClick:()=>o(`/dash/${e}/filter`),text:f(`filtering.title`),large:!0})]}):(0,L.jsx)(`h1`,{className:`bp6-heading`,children:f(`rules.title`)}),(0,L.jsx)(`p`,{className:`bp6-text-muted mt-2!`,children:f(`rules.subtitle`)})]})})}),(0,L.jsx)(R,{newRule:h,setNewRule:_,addRule:async()=>{let t=h.pattern.trim();if(!t){a?.current?.show({message:f(`rules.patternEmpty`,`Domain pattern cannot be empty`),intent:y.DANGER});return}let n=t.toLowerCase();if(s.some(e=>e.pattern.trim().toLowerCase()===n)){a?.current?.show({message:f(`rules.duplicatePattern`,`Rule for this domain already exists`),intent:y.DANGER});return}try{await k(e,{...h,pattern:t}),a?.current?.show({message:f(`rules.addSuccess`,`Rule added successfully`),intent:y.SUCCESS}),_({type:`BLOCK`,pattern:``,v_a:``,v_aaaa:``,v_txt:``,v_cname:``}),S()}catch(e){a?.current?.show({message:e.message||f(`rules.addFailed`,`Failed to add rule`),intent:y.DANGER})}}}),s.length===0?(0,L.jsx)(v,{title:f(`rules.noRulesTitle`),children:f(`rules.noRulesDesc`)}):(0,L.jsx)(z,{rules:s,startEdit:e=>{x({...e})},getBlockDetail:()=>{if(!l)return f(`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,L.jsx)(B,{editRule:b,setEditRule:x,saveEditRule:async()=>{if(!b)return;let t=b.pattern.trim();if(!t){a?.current?.show({message:f(`rules.patternEmpty`,`Domain pattern cannot be empty`),intent:y.DANGER});return}let n=t.toLowerCase();if(s.some(e=>e.id!==b.id&&e.pattern.trim().toLowerCase()===n)){a?.current?.show({message:f(`rules.duplicatePattern`,`Rule for this domain already exists`),intent:y.DANGER});return}try{await A(e,{...b,pattern:t}),a?.current?.show({message:f(`rules.updateSuccess`,`Rule updated successfully`),intent:y.SUCCESS}),x(null),S()}catch(e){a?.current?.show({message:e.message||f(`rules.updateFailed`,`Failed to update rule`),intent:y.DANGER})}},cancelEdit:()=>{x(null)},deleteRule:async t=>{try{await N(e,t)}catch(e){console.error(e)}x(null),S()}})]})};export{V as RulesView};