Files
op-packages/luci-app-honk/root/etc/honk/dashboard/assets/Settings-Ajzo2fTI.js
T

2 lines
35 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import{r as b,a as Je,j as t}from"./vendor-react-Bf71BWbF.js";import{a1 as ie,ap as ce,A as Ne,dK as Ye,u as M,dL as Xe,cA as He,dM as Be,n as ve,i as xe,bb as L,o as Re,dN as Ze,w as es,aU as ss,dO as ts,a5 as pe,ay as as,dP as ns,dQ as rs,r as os,dR as is,b as J,dS as ls,dT as ds,a2 as Se,a as Ce,cQ as Ge,a0 as cs,dF as us,aG as se,E as q,j as ue,I as gs,b2 as G,T as ae,aC as ke,bx as ne,B as I,av as ps,a7 as je,aa as fs,d7 as ms,dU as hs,bd as bs,az as vs,dV as Oe,bg as xs,bk as Le,aE as Ae,am as js,an as ys,dW as ws,dX as Ns,a9 as ks,$ as _s,cO as Ss,cw as Me,du as Cs,cG as Ps,aD as Rs,cW as ge,dY as De,dZ as Ls,bj as As,d_ as Ds}from"./index-CXHBmSa5.js";import{d as Ts,c as Is}from"./auth-BGnwk8Hi.js";import{c as Es,a as te,g as ze}from"./nav-BIpfWn6-.js";import{D as Us}from"./Table-D0NFHHNQ.js";import{T as Fs}from"./TimeCell-gSIuLEFc.js";import{A as Hs}from"./ActionGroup-90AzAQje.js";import{c as Bs}from"./dns-DQrpG8y_.js";import{g as le,m as Gs,v as Os}from"./geodata-DprMPspn.js";import"./useGridSelectionCheckbox-BV96yL-N.js";import"./Virtualizer--Vfl8O3n.js";import"./ListLayout-CPapuywx.js";const Te=["record_flows","record_logs","record_dns_log"],_e={record_flows:{state:"flows",label:"settings.recordFlows"},record_logs:{state:"logs",label:"settings.recordLogs"},record_dns_log:{state:"dns_log",label:"settings.recordDnsLog"}},Ms={auto:"settings.record.auto",on:"settings.record.on",off:"settings.record.off"},zs=s=>s==="auto"?"auto":s==="on";function Vs(s,e,a,n){const r=a?!a.allowed:!1;return{id:s,label:n(_e[s].label),value:e,items:["auto","on","off"].map(l=>({id:l,label:n(Ms[l])})),disabled:r,tone:r?"muted":a?.active?"ok":"neutral",status:n(r?"settings.recordingForbidden":a?.active?"settings.recordingActive":"settings.recordingIdle")}}function qs(s,e){return s?s.grace_remaining_seconds>0?e("settings.recordingGrace",{n:s.grace_remaining_seconds}):e(s.events.active?"settings.recordingEvents":"settings.recordingDetached"):null}const Ks=["log.buffered_records","dns_log.max_records","flows.max_flows","flows.retention_seconds"],de={"log.buffered_records":{read:s=>s.log.buffered_records,write:(s,e)=>{(s.log??={}).buffered_records=e},floor:64,label:"settings.logBuffer"},"dns_log.max_records":{read:s=>s.dns_log.max_records,write:(s,e)=>{(s.dns_log??={}).max_records=e},floor:64,label:"settings.dnsLogSize"},"flows.max_flows":{read:s=>s.flows.max_flows,write:(s,e)=>{(s.flows??={}).max_flows=e},floor:64,label:"settings.flowsMax"},"flows.retention_seconds":{read:s=>s.flows.retention_seconds,write:(s,e)=>{(s.flows??={}).retention_seconds=e},floor:1,label:"settings.flowsRetention"}};function Ws(s,e,a,n,r){const l=de[s];return{id:s,value:e,label:r(l.label),invalid:!/^\d+$/.test(e)||Number(e)<l.floor||a!==void 0&&Number(e)>a,description:a===void 0?r("settings.rangeMin",{min:ie(l.floor,n)}):r("settings.range",{min:ie(l.floor,n),max:ie(a,n)})}}function $s(s,e){return s.map(a=>({id:a.kind,kind:a.kind,size:ce(a.size_bytes,e),modifiedAt:a.modified_at,sha:a.sha256.slice(0,12),shaTitle:a.sha256,source:a.source_redacted??"—",fetched:a.fetched_url_redacted??"—",verified:a.verified===!0}))}function Qs(s,e,a){return{choices:s.map(n=>({id:n.id,label:n.name})),result:e?{text:a(e.key,e.params),role:e.error?"alert":"status",request:e.requestId?a("ui.requestNote",{id:e.requestId}):"",error:!!e.error,id:e.id??0}:null}}function Js(s,e){return s?null:e("settings.noProfile")}function Ys({busy:s,invalid:e,changed:a},n){return s?null:e?n("settings.runtimeInvalid",{field:e}):a?null:n("config.noChanges")}function Xs({ready:s,busy:e,count:a},n){return s&&!e&&!a?n("settings.noSubscriptions"):null}function Ve({busy:s,loaded:e,failed:a},n){return!s&&!e&&a?n("settings.geodataUnread"):null}function Zs(s,e){return s.flatMap(a=>a.items).find(a=>a.id===e)?.label??e}function et(s,e,a,n,r=""){return e.aborted&&e.reason?.name==="TimeoutError"?{key:"settings.timeout"}:e.aborted?null:s instanceof Ne?s.status===401?{key:r?"settings.tokenRejected":"settings.unauthorized"}:s.code==="empty_response"?{key:"settings.nonJson"}:s.code==="invalid_discovery"?{key:"settings.invalidResponse"}:{key:"settings.httpError",params:{status:s.status}}:s instanceof SyntaxError?{key:"settings.nonJson"}:s instanceof TypeError&&new URL(a).origin!==n?{key:"settings.cors"}:{key:"settings.network"}}async function st(s,e,a,n){try{const r=await Ye(s,e).discovery(a);if(!r||!Number.isInteger(r.api_major)||r.api_major<1)throw new Ne(200,"invalid_discovery","Missing API version");return{version:String(r.api_major),password:r.auth?.mode==="password"}}catch(r){const l=et(r,a,s,n,e);return l&&{failure:l,requestId:r instanceof Ne?r.requestId:null}}}function tt(){const[s,e]=b.useState(!1),a=b.useRef(null),n=b.useCallback(()=>{const o=a.current;a.current=null,o?.abort()},[]);b.useEffect(()=>n,[n]);const r=b.useCallback(()=>{n(),e(!1)},[n]);return{pending:s,running:()=>a.current!==null,cancel:r,run:async(o,d,y)=>{const m=new AbortController;a.current=m;const f=setTimeout(()=>m.abort(new DOMException("Connection timeout","TimeoutError")),5e3);e(!0);try{const j=await st(o,d,m.signal,location.origin);j&&a.current===m&&y(j)}finally{clearTimeout(f),a.current===m&&(a.current=null,e(!1))}}}}function Ie(s){const e=new URLSearchParams(s),a=e.get("api");return a?{api:a,token:e.get("token")??""}:null}function at(s){const e=M(),[a]=b.useState(Xe),[n,r]=b.useState(a.api??""),[l,o]=b.useState(a.token),[d,y]=b.useState(!1),[m,f]=b.useState(null),{pending:j,running:p,cancel:_,run:E}=tt(),N=n!==(a.api??"")||l!==a.token,P=He(N,()=>{r(a.api??""),o(a.token),y(!1)}),[A,S]=b.useState(null);if(A!==s){S(s);const c=Ie(s);c&&(y(!0),r(c.api),o(c.token),f(null))}b.useEffect(()=>{const c=new URLSearchParams(s);c.has("api")&&(c.delete("api"),c.delete("token"),history.replaceState(history.state,"",location.pathname+location.search+Be("settings",c.toString())));const h=c.get("card");h&&document.getElementById(Es(h))?.scrollIntoView({block:"start"})},[s]);const v=a.profiles.find(c=>c.id===a.activeId),[F,u]=b.useState(!1),[g,w]=b.useState(!1),k=b.useRef(!1),U=b.useRef(0),R=b.useCallback(()=>{_(),f(null)},[_]);b.useLayoutEffect(()=>{Ie(s)&&_()},[s,_]);const[O,z]=b.useState(null);b.useEffect(()=>{let c;try{c=ve(a.api??"")}catch{return}if(xe(c))return;const h=new AbortController;return Ts(c,h.signal).then(B=>z({base:c,password:B?.mode==="password"}),()=>{}),()=>h.abort()},[a.api]);const K=xe(n.trim()),V=(()=>{try{return O!==null&&O.password&&O.base===ve(n)}catch{return!1}})(),D=c=>{try{const h=ve(c);return u(!1),h}catch{return u(!0),null}},i=c=>{r(c),D(c),R()},C=c=>{o(c),R()},x=(c,h)=>{if(!k.current){k.current=!0,Je.flushSync(()=>w(!0));try{es({profiles:c,activeId:h})}catch{f({key:"settings.saveError",error:!0,id:++U.current}),k.current=!1,w(!1),X||L("negative",e("settings.saveError"));return}try{P.clear(),sessionStorage.setItem(ss.saved,"1")}catch{}location.reload()}},W=()=>{const c=D(n);if(c===null)return null;const h={...v??{id:Re(),name:e("settings.backend")},api:c,token:l};return v?a.profiles.map(B=>B.id===v.id?h:B):[h]},Y=()=>{const c=W();c?x(c,v?.id??c[0].id):L("negative",e("settings.invalidUrl"))},[$,Q]=b.useState(null),H=c=>{c===a.activeId||!a.profiles.some(h=>h.id===c)||(N?Q(c):x(a.profiles,c))},T=()=>{$!==null&&x(a.profiles,$)},oe=async()=>{if(p())return;R();const c=D(n);if(c!==null){if(xe(c)){f({key:"settings.demo"}),L("neutral",e("settings.demo"));return}await E(c,l,h=>{if("failure"in h){const{failure:be,requestId:Qe}=h;f({...be,error:!0,requestId:Qe}),L("negative",e(be.key,be.params));return}const{version:B,password:$e}=h;z({base:c,password:$e}),f({key:"settings.reachable",params:{version:B}}),L("positive",e("settings.reachable",{version:B}))})}},[X,fe]=b.useState(null),me=c=>{c&&R(),fe(c)},[Z,he]=b.useState("");return{dialog:X,setDialog:me,name:Z,setName:he,confirmProfile:()=>{if(X==="delete"){const c=a.profiles.filter(h=>h.id!==v?.id);x(c,c[0]?.id??"");return}if(Z.trim())if(X==="add"){const c={id:Re(),name:Z.trim(),api:Ze,token:""};x([...a.profiles,c],c.id)}else x(a.profiles.map(c=>c.id===v?.id?{...c,name:Z.trim()}:c),a.activeId)},saved:a,active:v,api:n,changeApi:i,token:l,changeToken:C,demo:K,passwordMode:V,paired:d,dirty:N,invalid:F,result:m,pending:j,saving:g,save:Y,switchProfile:H,confirmSwitch:T,switchPending:$!==null,cancelSwitch:()=>Q(null),testConnection:oe}}function nt(s){const e=M(),a=ts(),n=pe(),r=as(),l=b.useContext(ns),o=at(s),[d,y]=b.useState(!1);if(!l)throw new Error("Settings requires shell controls");const{lang:m,pickLang:f,ap:j,paletteSections:p}=l,_=Qs(o.saved.profiles,o.result,e),E=a?()=>{a().then(P=>{P&&L("positive",e("settings.installed"))})}:null,N=a?null:rs();return{...o,lang:m,pickLang:f,ap:j,paletteSections:p,profile:_,palette:Zs(p,j.palette),error:n.error,retry:n.refetch,firstRun:o.saved.api===null,activeId:o.saved.activeId,hasActive:!!o.active,profileReason:Js(!!o.active,e),invalidText:o.invalid?e("settings.invalidUrl"):void 0,tokenType:d?"text":"password",tokenToggleText:e(d?"settings.hideToken":"settings.showToken"),toggleToken:()=>y(P=>!P),versionWarning:r.data&&r.data.api.major!==1?e("settings.apiMajor",{major:String(r.data.api.major)}):null,install:E,installHint:N&&e(N==="ios"?"settings.installHintIos":"settings.installHintMac"),addProfile:()=>{o.setName(""),o.setDialog("add")},dialogDiscards:o.dirty,renameProfile:()=>{o.setName(o.active?.name??""),o.setDialog("rename")},dialogTitle:e(o.dialog==="add"?"settings.addProfile":o.dialog==="rename"?"settings.renameProfile":"settings.deleteProfile"),dialogBlocked:o.dialog!=="delete"&&!o.name.trim(),deleteHelp:e("settings.deleteProfileHelp",{name:o.active?.name??""})}}function rt(){const s=M(),[e,a]=b.useState(!1),{profiles:n,activeId:r}=os(),l=n.find(d=>d.id===r),o=l?.api?is(l.id,l.api):null;return!l||!o?null:{busy:e,signOut:async()=>{a(!0);try{await Is(l.api,o)}catch(d){a(!1),L("negative",s("settings.signOutFailed"),{detail:J(d,s)});return}ls(),history.replaceState(history.state,"",Be(ds)),location.reload()}}}function ot(){const s=M(),e=Se[Ce()],a=pe(),n=a.data?.resources,r=n?.runtime_settings.available??!1,l=new Set(n?.runtime_settings.fields??[]),o=Ge(r),d=o.data,y=u=>d?.recording?.[_e[u].state].mode??"auto",m=d?JSON.stringify([d.log,d.dns_log,d.flows,Te.map(y)]):"",[f,j]=b.useState(null),p=f??{at:m,values:{},modes:{}},_=p.level??d?.log.level??"",E=!!f&&(f.level!==void 0||Object.keys(f.values).length>0||Object.keys(f.modes).length>0),N=He(E,()=>j(null)),P={"log.buffered_records":n?.logs.max_buffered_records,"dns_log.max_records":n?.dns_log.max_records,"flows.max_flows":n?.flows.max_flows,"flows.retention_seconds":n?.flows.retention_seconds},A=Ks.filter(u=>l.has(u)).map(u=>({...Ws(u,p.values[u]??(d?String(de[u].read(d)):""),P[u],e,s),change:g=>{o.busy||j({...p,values:{...p.values,[u]:g.trim()}})}})),S=Te.filter(u=>l.has(u)).map(u=>({...Vs(u,p.modes[u]??y(u),d?.recording?.[_e[u].state],s),change:g=>{o.busy||j({...p,modes:{...p.modes,[u]:g}})}})),v={};if(d){for(const u of S)u.value!==y(u.id)&&(v[u.id]=zs(u.value));l.has("log.level")&&_!==d.log.level&&(v.log={level:_});for(const u of A)!u.invalid&&Number(u.value)!==de[u.id].read(d)&&de[u.id].write(v,Number(u.value))}const F=()=>{if(o.busy)return;const u=f;o.save(v).then(g=>{g!==void 0&&(j(w=>w===u?null:w),L("positive",s("settings.runtimeSaved")))},g=>L("negative",s("settings.runtimeFailed"),{detail:J(g,s)}))};return{numeric:A,recorders:S,recordingNote:qs(d?.recording,s),level:_,setLevel:u=>{o.busy||j({...p,level:u})},levels:(n?.logs.levels??["trace","debug","info","warn","error"]).map(u=>({id:u,label:cs(us,u,s)})),hasLevel:l.has("log.level"),hasBaseline:!!d,source:d?s(d.source==="runtime"?"settings.sourceRuntime":"settings.sourceConfig"):null,sourceTone:d?.source==="runtime"?"info":"neutral",capsError:a.error,retryCaps:a.refetch,waiting:!n,available:r,note:s(r?"settings.runtimeNote":"settings.runtimeUnavailable"),error:o.error,retry:o.refetch,loading:o.loading&&!d,busy:o.busy,conflict:E&&f.at!==m?s("settings.runtimeConflict"):null,discard:()=>{N.clear(),j(null)},dirty:E,blocked:!Object.keys(v).length||A.some(u=>u.invalid),reason:Ys({busy:o.busy,invalid:A.find(u=>u.invalid)?.label??null,changed:Object.keys(v).length>0},s),apply:F}}const Ee=te("runtime");function it(){const s=M(),e=ot();return t.jsxs(se,{level:2,title:s(Ee.titleKey),titleId:Ee.headingId,aside:t.jsx(t.Fragment,{children:e.source&&t.jsx(ke,{tone:e.sourceTone,children:e.source})}),children:[e.waiting&&e.capsError?t.jsx(q,{error:e.capsError,onRetry:e.retryCaps}):t.jsx("span",{className:"rp-label",children:e.waiting?" ":e.note}),e.waiting&&!e.capsError&&t.jsx("div",{className:"rp-chart-wait form",children:t.jsx(ue,{})}),!e.waiting&&e.available&&t.jsxs(t.Fragment,{children:[t.jsx(q,{error:e.error,onRetry:e.retry}),e.conflict&&t.jsx(gs,{children:e.conflict}),e.loading&&t.jsx("div",{className:"rp-chart-wait form",children:t.jsx(ue,{})}),e.hasBaseline&&t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"rp-toolbar top rp-fieldgrid",children:[e.hasLevel&&t.jsx(G,{label:s("settings.logLevel"),value:e.level,onChange:e.setLevel,items:e.levels,isDisabled:e.busy}),e.numeric.map(a=>t.jsx(ae,{width:180,type:"text",label:a.label,value:a.value,isDisabled:e.busy,isInvalid:a.invalid,onChange:a.change,description:a.description},a.id))]}),e.recorders.length>0&&t.jsxs("div",{className:"rp-toolbar rp-fieldgrid",role:"group","aria-label":s("settings.recording"),children:[e.recorders.map(a=>t.jsxs("div",{className:"rp-field",children:[t.jsx(G,{label:a.label,value:a.value,onChange:a.change,items:a.items,isDisabled:e.busy||a.disabled}),t.jsx(ke,{tone:a.tone,small:!0,children:a.status})]},a.id)),e.recordingNote&&t.jsx("span",{className:"rp-label",children:e.recordingNote})]}),t.jsx(ne,{reason:e.reason,children:t.jsxs("div",{className:"rp-toolbar",children:[t.jsx(I,{accent:!0,isPending:e.busy,isDisabled:e.blocked,onPress:e.apply,children:s("settings.apply")}),e.dirty&&t.jsx(I,{isDisabled:e.busy,onPress:e.discard,children:s("config.discard")})]})})]})]})]})}function lt(){const s=M(),e=Se[Ce()],a=pe(),n=a.data?.resources,r=ps(je(n,"runtime",{whileLoading:!1})),l=fs(je(n,"providers",{whileLoading:!1})),o=ms(l.refetch),d=hs(je(n,"connections",{whileLoading:!1})&&n?.connections.can_close===!0),y=bs(d.refetch),m=Bs(),f=vs(r.data,a.data,r.refetch),j=!!n?.geodata.available&&!ze(n),p=Oe(j),E=!!n?.operations.available&&["reload","suspend","resume"].some(g=>n[g].available)||!!(n?.dns_cache.available&&n.dns_cache.flush)||!!n?.providers.can_refresh||!!n?.connections.can_close||j&&!!n?.geodata.can_update,N=(l.data?.providers??[]).filter(g=>g.kind==="subscription"),P=!!l.data&&!l.error&&!l.loading,A=!!d.data&&!d.error&&!d.loading,S=A?d.data.total_tcp+d.data.total_udp:null,v=o.busy==="*",F=()=>{const g=[];let w=!1;return o.refreshMany(N.map(k=>k.id),(k,U)=>g.push(U),()=>w=!0).then(k=>{if(k===void 0)return;const U={n:k,total:N.length},R=k===N.length?"positive":k?"info":"negative";g.length?L(R,s("settings.refreshedAllFailed",{...U,failed:g.length}),{detail:J(g[0],s)}):L(R,s("settings.refreshedAll",U)),w&&L("info",s("settings.refreshedDegraded"))},k=>L("negative",s("settings.refreshAllFailed"),{detail:J(k,s)}))},u=()=>y.closeAll({ids:[],query:{all:!0}}).then(g=>{g&&L(xs(g),s("conn.closedAll",{closed:g.closed,skipped:g.skipped}))},g=>s("ui.valuePair",{label:s("conn.closeFailed"),value:J(g,s)}));return{runtimeError:r.error,retryRuntime:r.refetch,lifecycle:f.actions,flush:{confirmationText:s("dns.flushConfirmAll"),isPending:m.busy,isDisabled:m.busy,onAbort:m.cancel,onConfirm:()=>m.flush().then(g=>{g&&L("positive",s("dns.flushed",{matched:g.matched,deleted:g.deleted}))},g=>s("dns.flushFailed",{error:J(g,s)}))},closeAll:{confirmationText:S===null?"":s("settings.closeAllHelp",{n:S}),isDisabled:!A||!S||!!y.busy,isPending:y.busy==="all"||d.loading&&!d.data,onConfirm:u,onAbort:y.cancel},geodataBusy:p.busy,geodataBlocked:p.busy||!p.data,geodataReason:Ve({busy:p.busy,loaded:!!p.data,failed:!!p.error},s),geodataLoading:p.loading&&!p.data,geodataError:p.error,retryGeodata:p.refetch,providersError:l.error,providersLoading:l.loading&&!l.data,retryProviders:l.refetch,connectionsError:d.error,retryConnections:d.refetch,waiting:!n&&!a.error,note:s(E?"settings.actionsNote":"settings.actionsNone"),refreshingAll:v,refreshAll:F,refreshDisabled:!P||!!o.busy||!N.length,refreshReason:Xs({ready:P,busy:!!o.busy,count:N.length},s),refreshLabel:s("settings.refreshAll",{n:P?N.length:"—"}),canFlush:!!(n?.dns_cache.available&&n.dns_cache.flush),canRefresh:!!n?.providers.can_refresh,canClose:!!n?.connections.can_close,canUpdate:!!n?.geodata.can_update,hasGeodata:j,rows:$s(p.data?.assets??[],e),update:()=>void p.update().then(g=>{g&&L("positive",s("settings.geodataUpdated"))},g=>L("negative",s("settings.geodataFailed"),{detail:J(g,s)}))}}const Ue=te("actions");function dt(){const s=M(),{runtimeError:e,retryRuntime:a,lifecycle:n,flush:r,closeAll:l,geodataBusy:o,geodataBlocked:d,geodataReason:y,geodataLoading:m,geodataError:f,retryGeodata:j,providersError:p,providersLoading:_,retryProviders:E,connectionsError:N,retryConnections:P,note:A,refreshingAll:S,refreshAll:v,refreshDisabled:F,refreshReason:u,refreshLabel:g,canFlush:w,canRefresh:k,canClose:U,canUpdate:R,hasGeodata:O,rows:z,update:K,waiting:V}=lt();return t.jsxs(se,{level:2,title:s(Ue.titleKey),titleId:Ue.headingId,children:[t.jsx("span",{className:"rp-label",children:V?" ":A}),t.jsx(q,{error:e,onRetry:a}),t.jsxs("div",{className:"rp-ops",children:[V&&t.jsx("div",{className:"rp-chart-wait ops",children:t.jsx(ue,{})}),n.length>0&&t.jsxs("div",{className:"rp-ops-group",children:[t.jsx("span",{className:"rp-label",children:s("settings.groupLifecycle")}),t.jsx("div",{className:"rp-cluster",children:t.jsx(Hs,{overflowMode:"wrap",actions:n})})]}),w&&t.jsxs("div",{className:"rp-ops-group",children:[t.jsx("span",{className:"rp-label",children:s("nav.dns")}),t.jsx("div",{className:"rp-cluster",children:t.jsx(Le,{label:s("dns.flushAll"),...r})})]}),k&&t.jsxs("div",{className:"rp-ops-group",children:[t.jsx("span",{className:"rp-label",children:s("nav.nodes")}),t.jsx(q,{error:p,onRetry:E}),t.jsx(ne,{reason:u,children:t.jsx("div",{className:"rp-cluster",children:t.jsx(I,{isPending:S||_,isDisabled:S||F,onPress:()=>void v(),children:g})})})]}),U&&t.jsxs("div",{className:"rp-ops-group",children:[t.jsx("span",{className:"rp-label",children:s("nav.connections")}),t.jsx(q,{error:N,onRetry:P}),t.jsx("div",{className:"rp-cluster",children:t.jsx(Le,{label:s("conn.closeAll"),...l})})]})]}),O&&t.jsxs("div",{className:"rp-geodata",children:[t.jsxs("div",{className:"rp-ops-group",children:[t.jsx("span",{className:"rp-label",children:s("settings.geodata")}),t.jsx(ne,{reason:R?y:null,children:t.jsx("div",{className:"rp-cluster",children:R&&t.jsx(I,{isPending:o,isDisabled:d,onPress:K,children:s("settings.geodataUpdate")})})})]}),t.jsx("span",{className:"rp-label",children:s("settings.geodataNote")}),t.jsx(q,{error:f,onRetry:j}),t.jsx(Us,{label:s("settings.geodata"),loading:m,rows:z,height:160,fit:!0,cols:[{id:"kind",label:s("settings.geodataAsset"),minWidth:100,grow:0,isRowHeader:!0,render:D=>D.kind},{id:"size",label:s("settings.geodataSize"),minWidth:100,grow:0,align:"end",render:D=>D.size},{id:"modified",label:s("nodes.updated"),minWidth:140,grow:0,render:D=>t.jsx(Fs,{at:D.modifiedAt})},{id:"sha",label:"SHA-256",minWidth:160,drop:2,render:D=>t.jsx(Ae,{text:D.shaTitle,children:t.jsx("span",{className:"rp-code",children:D.sha})})},{id:"source",label:s("settings.geodataSource"),minWidth:240,grow:2,render:D=>t.jsx(Ae,{className:"rp-code",children:D.source})}]})]})]})}const re=["geosite","geoip"],ye={metacubex:"settings.geodataPreset.metacubex","metacubex-lite":"settings.geodataPreset.metacubexLite",loyalsoldier:"settings.geodataPreset.loyalsoldier"};function ct(s){return le.find(e=>re.every(a=>s[a].length>0&&s[a].every(n=>e.urls[a].includes(n)||e.mirrors[a].includes(n))))??null}const qe=s=>{try{return new URL(s).host}catch{return s}};function ut(s,e){if(!s?.categories||!e)return null;const a={};for(const n of re){const r=new Set(s.categories[n]),l=(e[n]??[]).filter(o=>!r.has(o));l.length&&(a[n]=l)}return Object.keys(a).length?a:null}function Ke(s,e){const a=s.trim();return a?Os(a)?e.filter(n=>n.trim()===a).length>1?"settings.geodataUrlDuplicate":null:"settings.geodataUrlInvalid":null}function gt(s){return s.length<Gs&&s.every(e=>e.trim())?[...s,""]:s}const pt=s=>re.some(e=>!s[e].some(a=>a.trim())||s[e].some(a=>Ke(a,s[e]))),ft=s=>({geosite:s.geosite.map(e=>e.trim()).filter(Boolean),geoip:s.geoip.map(e=>e.trim()).filter(Boolean)});function We(s,e,a){const n=ut(s,e);return n&&re.flatMap(r=>(n[r]??[]).map(l=>`${r}:${l}`)).join(a("ui.separator"))}function mt(s,e,a,n){const r=We(s,e,n);return r?{text:n("settings.geodataMissing",{codes:r}),notice:!0}:{text:n("settings.geodataPresetSize",{geosite:ce(s.sizes.geosite,a),geoip:ce(s.sizes.geoip,a)}),notice:!1}}const we=[6,12,24,72,168];function ht(s,e){return(we.includes(s)?we:[...we,s].sort((n,r)=>n-r)).map(n=>{const r=n%24===0,l=new Intl.NumberFormat(e,{style:"unit",unit:r?"day":"hour",unitDisplay:"long"}).format(r?n/24:n);return{id:String(n),label:l}})}function bt(s,e,a){if(s.route==="direct")return a("settings.geodataRouteDirect");const n=s.group_id?e?.find(r=>r.id===s.group_id)?.name??s.group_id:null;return s.route==="routing"?n?a("settings.geodataRouteRoutingVia",{group:n}):a("settings.geodataRouteRouting"):n??a("settings.geodataRouteGroupGone")}function vt(s,e,a,n,r){if(e)return{text:r("settings.geodataUpdating"),error:!1};if(s?.last_error)return{text:r("ui.valuePair",{label:r("settings.geodataLastError"),value:js(ys(s.last_error.code,s.last_error.message,r),r)}),error:!0};const l=s?.last_updated_at,o=s?l?ws(l,n,a):r("settings.geodataNever"):"—",d=s?.assets.length&&s.assets.every(f=>f.verified!==void 0),y=d&&!s.assets.every(f=>f.verified),m=d?r(y?"settings.geodataVerifiedNo":"settings.geodataVerifiedYes"):null;return{text:r("ui.valuePair",{label:r("settings.geodataLastUpdated"),value:m?o+r("ui.separator")+m:o}),error:!1,help:y?{title:r("settings.geodataVerifiedNo"),text:r("settings.geodataUnverifiedHelp")}:void 0}}function xt(s,e,a,n){return(s?.assets??[]).map(r=>{const l=r.fetched_url_redacted??r.source_redacted??"",o=[ce(r.size_bytes,a),l?qe(l):null,r.download_route?bt(r.download_route,e,n):null];return{label:r.kind,value:o.filter(Boolean).join(n("ui.separator")),full:l}})}function jt(){const s=M(),e=Ce(),a=Se[e],n=Ns(),r=pe(),l=ze(r.data?.resources),o=Ge(l),d=Oe(l),y=ks(l),m=o.data?.geodata,[f,j]=b.useState(null),[p,_]=b.useState(null),[E,N]=b.useState(null),[P,A]=b.useState(null),S=o.busy||d.busy,v=!!r.data?.resources.geodata.can_update,F=()=>d.update().then(i=>{i&&L("positive",s("settings.geodataUpdated"))},i=>Ss(i,s,s("settings.geodataFailed"))),u=b.useRef(!1),g=i=>u.current||S?Promise.resolve(!1):(u.current=!0,j(i),o.save({geodata:i}).then(C=>(u.current=!1,j(null),C===void 0?!1:(d.refetch(),i.geosite&&v?F():L("positive",s(i.geosite?"settings.geodataSaved":i.download?"settings.geodataRouteSaved":"settings.geodataAutoSaved")),!0)),C=>(u.current=!1,j(null),L("negative",s("settings.geodataSaveFailed"),{detail:J(C,s)}),!1))),w=f?.geosite&&f.geoip?{geosite:f.geosite.urls,geoip:f.geoip.urls}:m?{geosite:m.geosite.urls,geoip:m.geoip.urls}:null,k=w?ct(w):null,U={...m?.auto_update,...f?.auto_update},R=m?.download&&(f?.download??m.download),O=E??R?.route??"routing",z=i=>mt(le.find(C=>C.id===i),d.data?.required_codes,a,s),K=i=>void g({geosite:{urls:[...i.urls.geosite]},geoip:{urls:[...i.urls.geoip]}}),V=s(v?"settings.geodataSaveUpdate":"settings.geodataSaveSources"),D=vt(d.data,d.busy||v&&!!f?.geosite,n,a,s);return{available:l,loading:o.loading&&!m,error:o.error,retry:o.refetch,ready:!!m,busy:S,seededFromConfig:m?.source==="config",note:s(v?"settings.geodataSourcesNote":"settings.geodataSourcesNoteStored"),source:{value:w?k?.id??"custom":"",items:[...le.map(i=>({id:i.id,label:s(ye[i.id]),desc:z(i.id).text})),{id:"custom",label:s("settings.geodataCustom")}],note:k?z(k.id):null,change:i=>{if(i==="custom")_(w?{geosite:[...w.geosite],geoip:[...w.geoip]}:null);else if(i!==k?.id){const C=le.find(W=>W.id===i),x=We(C,d.data?.required_codes,s);x?A({preset:C,codes:x}):K(C)}}},lacking:P&&{title:s("settings.geodataLackingTitle",{preset:s(ye[P.preset.id])}),text:s("settings.geodataLackingHelp",{preset:s(ye[P.preset.id]),codes:P.codes}),confirm:V,cancel:()=>A(null),save:()=>{A(null),K(P.preset)}},customHosts:w&&!k?_s(e,[...new Set([...w.geosite,...w.geoip].map(qe))]):null,editCustom:()=>w&&_({geosite:[...w.geosite],geoip:[...w.geoip]}),dialog:p?{lists:re.map(i=>({kind:i,fields:gt(p[i]).map((C,x,W)=>{const Y=Ke(C,W),$=H=>H>=0&&H<p[i].length&&x<p[i].length?()=>{if(o.busy)return;const T=[...p[i]];[T[x],T[H]]=[T[H],T[x]],_({...p,[i]:T})}:void 0,Q=s("settings.geodataUrlLabel",{kind:i,n:ie(x+1,a)});return{up:$(x-1),down:$(x+1),upLabel:s("settings.geodataMoveUp",{url:Q}),downLabel:s("settings.geodataMoveDown",{url:Q}),id:`${i}-${x}`,label:Q,value:C,error:Y?s(Y):void 0,change:H=>{if(o.busy)return;const T=[...W];for(T[x]=H;T.length&&!T[T.length-1].trim();)T.pop();_({...p,[i]:T})}}}),empty:!p[i].some(C=>C.trim())})),blocked:pt(p),confirm:V,pending:o.busy,cancel:()=>_(null),save:()=>{const i=ft(p);g({geosite:{urls:i.geosite},geoip:{urls:i.geoip}}).then(C=>C&&_(null))}}:null,route:R&&{value:O,items:["routing","direct","group"].map(i=>({id:i,label:s(i==="routing"?"settings.geodataRouteRouting":i==="direct"?"settings.geodataRouteDirect":"settings.geodataRouteGroup")})),change:i=>{if(i==="group")return N("group");N(null),i!==R?.route&&g({download:{route:i}})},group:O==="group"?R?.route==="group"?R.group_id??"":"":null,groups:(y.data??[]).map(i=>({id:i.id,label:i.name})),pickGroup:i=>{i!==(R?.route==="group"?R.group_id:null)&&g({download:{route:"group",group_id:i}}).then(C=>C&&N(null))}},auto:{enabled:!!U.enabled,toggle:i=>void g({auto_update:{enabled:i}}),interval:String(U.interval_hours??""),intervals:U.interval_hours?ht(U.interval_hours,a):[],pick:i=>{Number(i)!==m?.auto_update.interval_hours&&g({auto_update:{interval_hours:Number(i)}})}},status:{...D,details:xt(d.data,y.data,a,s)},statusError:d.error,retryStatus:d.refetch,canUpdate:v,updating:d.busy,updateBlocked:S||!d.data,updateReason:Ve({busy:S,loaded:!!d.data,failed:!!d.error},s),update:()=>void F()}}const Fe=te("geodata");function yt(){const s=M(),e=jt();return e.available?t.jsxs(se,{level:2,title:s(Fe.titleKey),titleId:Fe.headingId,children:[t.jsx("span",{className:"rp-label",children:e.note}),t.jsx(q,{error:e.error,onRetry:e.retry}),e.loading&&t.jsx("div",{className:"rp-chart-wait ops",children:t.jsx(ue,{})}),e.ready&&t.jsxs("div",{className:"rp-ops",children:[t.jsxs("div",{className:"rp-ops-group",children:[t.jsx("span",{className:"rp-label",children:s("settings.geodataSource")}),t.jsxs("div",{className:"rp-cluster",children:[t.jsx(G,{bare:!0,label:s("settings.geodataSource"),value:e.source.value,onChange:e.source.change,items:e.source.items,isDisabled:e.busy}),e.source.note&&t.jsx("span",{className:e.source.note.notice?"rp-label rp-geodata-note notice":"rp-label",children:e.source.note.text})]})]}),e.customHosts&&t.jsxs("div",{className:"rp-ops-group",children:[t.jsx("span",{className:"rp-label",children:s("settings.geodataCustomUrls")}),t.jsxs("div",{className:"rp-cluster",children:[t.jsx(I,{isDisabled:e.busy,onPress:e.editCustom,children:s("settings.geodataEdit")}),t.jsx("span",{className:"rp-label",children:e.customHosts})]})]}),e.route&&t.jsxs("div",{className:"rp-ops-group",children:[t.jsx("span",{className:"rp-label",children:s("settings.geodataRoute")}),t.jsxs("div",{className:"rp-cluster",children:[t.jsx(G,{bare:!0,label:s("settings.geodataRoute"),value:e.route.value,onChange:e.route.change,items:e.route.items,isDisabled:e.busy}),e.route.group!==null&&t.jsx(G,{bare:!0,label:s("settings.geodataRouteGroup"),value:e.route.group,onChange:e.route.pickGroup,items:e.route.groups,isDisabled:e.busy})]})]}),t.jsxs("div",{className:"rp-ops-group",children:[t.jsx("span",{className:"rp-label",children:s("settings.geodataAutoUpdate")}),t.jsxs("div",{className:"rp-cluster",children:[t.jsx(Me,{"aria-label":s("settings.geodataAutoUpdate"),isSelected:e.auto.enabled,isDisabled:e.busy,onChange:e.auto.toggle}),e.auto.enabled&&t.jsx(G,{bare:!0,label:s("settings.geodataInterval"),value:e.auto.interval,onChange:e.auto.pick,items:e.auto.intervals,isDisabled:e.busy})]})]}),t.jsxs("div",{className:"rp-ops-group",children:[t.jsx("span",{className:"rp-label",children:s("settings.geodataStatus")}),t.jsx(ne,{reason:e.canUpdate?e.updateReason:null,children:t.jsxs("div",{className:"rp-cluster",children:[t.jsx("span",{role:"status",className:e.status.error?"rp-geodata-note negative":void 0,children:e.status.text}),e.status.help&&t.jsx(Cs,{...e.status.help}),e.canUpdate&&t.jsx(I,{isPending:e.updating,isDisabled:e.updateBlocked,onPress:e.update,children:s("settings.geodataUpdateNow")})]})})]}),t.jsx(q,{error:e.statusError,onRetry:e.retryStatus}),e.status.details.length>0&&t.jsx(Ps,{title:s("settings.geodataDetails"),children:t.jsx("div",{className:"rp-geodata-details",children:t.jsx(Rs,{items:e.status.details})})}),e.seededFromConfig&&t.jsx("span",{className:"rp-label",children:s("settings.geodataConfigSeeded")})]}),e.lacking&&t.jsx(ge,{title:e.lacking.title,tone:"accent",isOpen:!0,onCancel:e.lacking.cancel,confirmLabel:e.lacking.confirm,onConfirm:e.lacking.save,children:t.jsx("p",{className:"rp-label",children:e.lacking.text})}),e.dialog&&t.jsxs(ge,{title:s("settings.geodataCustomUrls"),tone:"accent",isOpen:!0,onCancel:e.dialog.cancel,confirmLabel:e.dialog.confirm,onConfirm:e.dialog.save,isPending:e.dialog.pending,isDisabled:e.dialog.blocked,children:[e.dialog.lists.map(a=>t.jsxs("div",{className:"rp-field",role:"group","aria-label":a.kind,children:[a.fields.map(n=>t.jsx(ae,{type:"url",className:"rp-url-field",spellCheck:!1,autoComplete:"off",label:n.label,value:n.value,error:n.error,isDisabled:e.dialog?.pending,onChange:n.change,action:t.jsxs(t.Fragment,{children:[t.jsx(I,{quiet:!0,icon:!0,small:!0,label:n.upLabel,isDisabled:e.dialog?.pending||!n.up,onPress:n.up,children:t.jsx(De,{className:"rp-up"})}),t.jsx(I,{quiet:!0,icon:!0,small:!0,label:n.downLabel,isDisabled:e.dialog?.pending||!n.down,onPress:n.down,children:t.jsx(De,{})})]})},n.id)),a.empty&&t.jsx("span",{className:"rp-label",children:s("settings.geodataUrlRequired")})]},a.kind)),t.jsx("span",{className:"rp-label",children:s("settings.geodataUrlHelp")})]})]}):null}const ee={backend:te("backend"),appearance:te("appearance"),about:te("about")};function It({query:s}){const e=M(),a=rt(),{activeId:n,hasActive:r,profileReason:l,firstRun:o,error:d,retry:y,api:m,changeApi:f,token:j,changeToken:p,demo:_,passwordMode:E,paired:N,invalidText:P,pending:A,saving:S,dialog:v,setDialog:F,name:u,setName:g,confirmProfile:w,save:k,switchProfile:U,confirmSwitch:R,switchPending:O,cancelSwitch:z,testConnection:K,lang:V,pickLang:D,ap:i,paletteSections:C,profile:x,palette:W,tokenType:Y,tokenToggleText:$,toggleToken:Q,versionWarning:H,install:T,installHint:oe,addProfile:X,renameProfile:fe,dialogTitle:me,dialogBlocked:Z,dialogDiscards:he,deleteHelp:Pe}=nt(s),c=b.useId();return t.jsxs("div",{className:"rp-page",children:[o&&t.jsx("p",{className:"rp-note",children:e("settings.firstRun")}),N&&t.jsx("p",{className:"rp-note",children:e("settings.paired")}),t.jsxs(se,{level:2,title:e(ee.backend.titleKey),titleId:ee.backend.headingId,children:[t.jsx(q,{error:d,onRetry:y}),t.jsx(ne,{reason:l,children:t.jsxs("div",{className:"rp-toolbar",children:[t.jsx(G,{label:e("settings.profile"),side:!0,value:n,isDisabled:!r||S,items:x.choices,onChange:U}),t.jsx(I,{onPress:X,children:e("settings.addProfile")}),t.jsx(I,{isDisabled:!r,onPress:fe,children:e("settings.renameProfile")}),t.jsx(I,{isDisabled:!r,onPress:()=>F("delete"),children:e("settings.deleteProfile")}),a&&t.jsx(I,{isPending:a.busy,onPress:()=>void a.signOut(),children:e("settings.signOut")})]})}),t.jsxs("form",{className:"rp-form",noValidate:!0,onSubmit:h=>{h.preventDefault(),k()},children:[t.jsx(ae,{label:e("ui.backendUrl"),autoComplete:"url",spellCheck:!1,description:e("settings.apiHelp"),error:P,name:"api",value:m,onChange:f}),_?null:E?t.jsx("p",{className:"rp-label",children:e("settings.passwordMode")}):t.jsx(ae,{label:e("settings.token"),autoComplete:"off",spellCheck:!1,reveal:{shown:Y==="text",label:$,onToggle:Q},name:"token",type:Y,value:j,onChange:p}),t.jsxs("div",{className:"rp-toolbar",children:[t.jsx(I,{onPress:()=>void K(),isPending:A,isDisabled:S,children:e("settings.test")}),t.jsx(I,{type:"submit",accent:!0,isPending:S,children:e("settings.save")})]}),t.jsx("div",{className:"rp-label",children:e("settings.saveHelp")}),A&&t.jsx("div",{role:"status",children:e("settings.testing")}),x.result&&t.jsxs("div",{role:x.result.role,children:[x.result.text,x.result.request&&t.jsx("span",{className:"rp-code",children:x.result.request})]})]})]}),t.jsx(it,{}),t.jsx(yt,{}),t.jsx(dt,{}),t.jsxs(se,{level:2,title:e(ee.appearance.titleKey),titleId:ee.appearance.headingId,children:[t.jsxs("div",{className:"rp-toolbar",children:[t.jsx(G,{label:e("lang"),value:V,onChange:h=>D(h),items:Ls.map(([h,B])=>({id:h,label:B}))}),t.jsxs("div",{className:"rp-field",children:[t.jsx("span",{className:"lbl",children:e("palette")}),t.jsx(As,{label:e("palette"),sections:C.map(h=>({...h,value:i.palette,onChange:B=>i.pickPalette(B)})),children:W})]}),t.jsx(G,{label:e("settings.scheme"),value:i.scheme,onChange:h=>i.pickScheme(h),items:[{id:"system",label:e("theme.system")},{id:"light",label:e("theme.light")},{id:"dark",label:e("theme.dark")}]}),t.jsx(G,{label:e("wordmark"),value:i.wordmark,onChange:h=>i.pickWordmark(h),items:[{id:"gradient",label:e("wordmark.gradient")},{id:"plain",label:e("wordmark.plain")}]}),t.jsx(G,{label:e("settings.toastPlacement"),value:i.toastPlacement,onChange:h=>i.pickToastPlacement(h),items:[{id:"top",label:e("settings.toastTop")},{id:"top end",label:e("settings.toastTopEnd")},{id:"bottom",label:e("settings.toastBottom")},{id:"bottom end",label:e("settings.toastBottomEnd")}]})]}),t.jsxs("div",{className:"rp-field",children:[t.jsx(Me,{isSelected:i.mirrored,onChange:i.pickMirrored,"aria-describedby":c,children:e("settings.mirror")}),t.jsx("span",{id:c,className:"rp-label",children:e("settings.mirrorHelp")})]})]}),t.jsxs(se,{level:2,title:e(ee.about.titleKey),titleId:ee.about.headingId,children:[H&&t.jsx(ke,{small:!0,tone:"warn",children:H}),t.jsxs("div",{className:"rp-cluster",children:[t.jsx(Ds,{trigger:t.jsx(I,{children:e("about.title")})}),T&&t.jsx(I,{onPress:T,children:e("settings.install")}),oe&&t.jsx("p",{className:"rp-note",children:oe})]})]}),t.jsx(ge,{title:e("config.discardTitle"),isOpen:O,onCancel:z,confirmLabel:e("config.discard"),isPending:S,onConfirm:R,children:t.jsx("p",{className:"rp-label",children:e("settings.switchProfileHelp")})}),v&&t.jsxs(ge,{title:me,isOpen:!0,onCancel:()=>F(null),tone:v==="delete"?"negative":"accent",confirmLabel:e(v==="delete"?"settings.deleteProfile":"settings.save"),isDisabled:Z,isPending:S,error:x.result?.error?{id:x.result.id,text:x.result.text}:null,onConfirm:w,children:[v==="delete"?t.jsx("p",{className:"rp-label",children:Pe}):t.jsx(ae,{label:e("settings.profileName"),value:u,onChange:g}),he&&t.jsx("p",{className:"rp-label",children:e("settings.profileDiscardHelp")})]})]})}export{It as Settings};