mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-10-26 18:12:51 +08:00
2 lines
33 KiB
JavaScript
2 lines
33 KiB
JavaScript
import{r as b,a as qe,j as t}from"./vendor-react-Bf71BWbF.js";import{W as ie,ag as ce,A as we,u as O,du as We,co as Fe,dv as Be,n as be,dw as ve,b0 as C,dx as $e,d as Pe,dy as Je,w as Qe,aJ as Xe,dz as Ye,$ as pe,aq as Ze,dA as es,dB as ss,r as ts,dC as as,a as W,dD as ns,dE as rs,X as _e,_ as Se,dr as He,V as os,dn as is,ax as ae,E as $,b as ue,I as ls,aT as G,T as re,at as Ne,B as I,an as ds,a1 as xe,a4 as cs,cW as us,dF as gs,b3 as ps,ar as fs,dG as Ge,b6 as ms,ba as Le,av as De,ae as hs,dH as bs,dI as vs,a3 as xs,U as js,cl as Me,cv as ys,au as ws,cK as ge,dJ as Ae,dK as Ns,b9 as ks,dL as _s}from"./index-zQjLFfuj.js";import{d as Ss,c as Cs}from"./auth-CPB25VPp.js";import{c as Ps,a as ne,g as Oe}from"./nav-BIpfWn6-.js";import{D as Ls}from"./Table-DLlwyNFJ.js";import{T as Ds}from"./TimeCell-DxlzlVpw.js";import{A as As}from"./ActionGroup-C-LVMOvQ.js";import{c as Rs}from"./dns-BoPCaePc.js";import{g as le,m as Ts,v as Is}from"./geodata-DprMPspn.js";import"./useGridSelectionCheckbox-BK6qtlfZ.js";import"./Virtualizer-CTh266-x.js";import"./ListLayout-DU_9AgrU.js";const Re=["record_flows","record_logs","record_dns_log"],ke={record_flows:{state:"flows",label:"settings.recordFlows"},record_logs:{state:"logs",label:"settings.recordLogs"},record_dns_log:{state:"dns_log",label:"settings.recordDnsLog"}},Es={auto:"settings.record.auto",on:"settings.record.on",off:"settings.record.off"},Us=s=>s==="auto"?"auto":s==="on";function Fs(s,e,a,n){const r=a?!a.allowed:!1;return{id:s,label:n(ke[s].label),value:e,items:["auto","on","off"].map(l=>({id:l,label:n(Es[l])})),disabled:r,tone:r?"muted":a?.active?"ok":"neutral",status:n(r?"settings.recordingForbidden":a?.active?"settings.recordingActive":"settings.recordingIdle")}}function Bs(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 Hs=["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 Gs(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 Ms(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 Os(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 zs(s,e){return s.flatMap(a=>a.items).find(a=>a.id===e)?.label??e}function Ks(s,e,a,n,r=""){return e.aborted&&e.reason?.name==="TimeoutError"?{key:"settings.timeout"}:e.aborted?null:s instanceof we?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"}}function Te(s){const e=new URLSearchParams(s),a=e.get("api");return a?{api:a,token:e.get("token")??""}:null}function Vs(s){const e=O(),[a]=b.useState(We),[n,r]=b.useState(a.api??""),[l,i]=b.useState(a.token),[c,w]=b.useState(!1),[v,x]=b.useState(null),[N,p]=b.useState(!1),k=n!==(a.api??"")||l!==a.token,E=Fe(k,()=>{r(a.api??""),i(a.token),w(!1)}),[P,_]=b.useState(null);if(P!==s){_(s);const o=Te(s);o&&(w(!0),r(o.api),i(o.token),p(!1),x(null))}b.useEffect(()=>{const o=new URLSearchParams(s);o.has("api")&&(o.delete("api"),o.delete("token"),history.replaceState(history.state,"",location.pathname+location.search+Be("settings",o.toString())));const f=o.get("card");f&&document.getElementById(Ps(f))?.scrollIntoView({block:"start"})},[s]);const j=a.profiles.find(o=>o.id===a.activeId),[L,S]=b.useState(!1),[B,u]=b.useState(!1),g=b.useRef(!1),y=b.useRef(0),h=b.useRef(null);b.useEffect(()=>()=>{const o=h.current;h.current=null,o?.abort()},[]);const D=b.useCallback(()=>{const o=h.current;h.current=null,o?.abort(),p(!1),x(null)},[]);b.useLayoutEffect(()=>{if(!Te(s))return;const o=h.current;h.current=null,o?.abort()},[s]);const[A,z]=b.useState(null);b.useEffect(()=>{let o;try{o=be(a.api??"")}catch{return}if(ve(o))return;const f=new AbortController;return Ss(o,f.signal).then(M=>z({base:o,password:M?.mode==="password"}),()=>{}),()=>f.abort()},[a.api]);const K=ve(n.trim()),R=(()=>{try{return A!==null&&A.password&&A.base===be(n)}catch{return!1}})(),J=o=>{try{const f=be(o);return S(!1),f}catch{return S(!0),null}},F=o=>{r(o),J(o),D()},d=o=>{i(o),D()},m=(o,f)=>{if(!g.current){g.current=!0,qe.flushSync(()=>u(!0));try{Qe({profiles:o,activeId:f})}catch{x({key:"settings.saveError",error:!0,id:++y.current}),g.current=!1,u(!1),ee||C("negative",e("settings.saveError"));return}try{E.clear(),sessionStorage.setItem(Xe.saved,"1")}catch{}location.reload()}},U=()=>{const o=J(n);if(o===null)return null;const f={...j??{id:Pe(),name:e("settings.backend")},api:o,token:l};return j?a.profiles.map(M=>M.id===j.id?f:M):[f]},V=()=>{const o=U();o?m(o,j?.id??o[0].id):C("negative",e("settings.invalidUrl"))},[Q,Y]=b.useState(null),X=o=>{o===a.activeId||!a.profiles.some(f=>f.id===o)||(k?Y(o):m(a.profiles,o))},H=()=>{Q!==null&&m(a.profiles,Q)},T=async()=>{if(h.current)return;D();const o=J(n);if(o===null)return;if(ve(o)){x({key:"settings.demo"}),C("neutral",e("settings.demo"));return}const f=new AbortController;h.current=f;const M=setTimeout(()=>f.abort(new DOMException("Connection timeout","TimeoutError")),5e3);p(!0);try{const q=await $e(o,l).discovery(f.signal);if(!q||!Number.isInteger(q.api_major)||q.api_major<1)throw new we(200,"invalid_discovery","Missing API version");if(h.current===f){z({base:o,password:q.auth?.mode==="password"});const Z=String(q.api_major);x({key:"settings.reachable",params:{version:Z}}),C("positive",e("settings.reachable",{version:Z}))}}catch(q){if(h.current!==f)return;const Z=Ks(q,f.signal,o,location.origin,l);if(!Z)return;x({...Z,error:!0,requestId:q instanceof we?q.requestId:null}),C("negative",e(Z.key,Z.params))}finally{clearTimeout(M),h.current===f&&(h.current=null,p(!1))}},[ee,fe]=b.useState(null),me=o=>{o&&D(),fe(o)},[se,he]=b.useState("");return{dialog:ee,setDialog:me,name:se,setName:he,confirmProfile:()=>{if(ee==="delete"){const o=a.profiles.filter(f=>f.id!==j?.id);m(o,o[0]?.id??"");return}if(se.trim())if(ee==="add"){const o={id:Pe(),name:se.trim(),api:Je,token:""};m([...a.profiles,o],o.id)}else m(a.profiles.map(o=>o.id===j?.id?{...o,name:se.trim()}:o),a.activeId)},saved:a,active:j,api:n,changeApi:F,token:l,changeToken:d,demo:K,passwordMode:R,paired:c,dirty:k,invalid:L,result:v,pending:N,saving:B,save:V,switchProfile:X,confirmSwitch:H,switchPending:Q!==null,cancelSwitch:()=>Y(null),testConnection:T}}function qs(s){const e=O(),a=Ye(),n=pe(),r=Ze(),l=b.useContext(es),i=Vs(s),[c,w]=b.useState(!1);if(!l)throw new Error("Settings requires shell controls");const{lang:v,pickLang:x,ap:N,paletteSections:p}=l,k=Os(i.saved.profiles,i.result,e),E=a?()=>{a().then(_=>{_&&C("positive",e("settings.installed"))})}:null,P=a?null:ss();return{...i,lang:v,pickLang:x,ap:N,paletteSections:p,profile:k,palette:zs(p,N.palette),error:n.error,retry:n.refetch,firstRun:i.saved.api===null,activeId:i.saved.activeId,hasActive:!!i.active,invalidText:i.invalid?e("settings.invalidUrl"):void 0,tokenType:c?"text":"password",tokenToggleText:e(c?"settings.hideToken":"settings.showToken"),toggleToken:()=>w(_=>!_),versionWarning:r.data&&r.data.api.major!==1?e("settings.apiMajor",{major:String(r.data.api.major)}):null,install:E,installHint:P&&e(P==="ios"?"settings.installHintIos":"settings.installHintMac"),addProfile:()=>{i.setName(""),i.setDialog("add")},dialogDiscards:i.dirty,renameProfile:()=>{i.setName(i.active?.name??""),i.setDialog("rename")},dialogTitle:e(i.dialog==="add"?"settings.addProfile":i.dialog==="rename"?"settings.renameProfile":"settings.deleteProfile"),dialogBlocked:i.dialog!=="delete"&&!i.name.trim(),deleteHelp:e("settings.deleteProfileHelp",{name:i.active?.name??""})}}function Ws(){const s=O(),[e,a]=b.useState(!1),{profiles:n,activeId:r}=ts(),l=n.find(c=>c.id===r),i=l?.api?as(l.id,l.api):null;return!l||!i?null:{busy:e,signOut:async()=>{a(!0);try{await Cs(l.api,i)}catch(c){a(!1),C("negative",s("settings.signOutFailed"),{detail:W(c,s)});return}ns(),history.replaceState(history.state,"",Be(rs)),location.reload()}}}function $s(){const s=O(),e=_e[Se()],a=pe(),n=a.data?.resources,r=n?.runtime_settings.available??!1,l=new Set(n?.runtime_settings.fields??[]),i=He(r),c=i.data,w=u=>c?.recording?.[ke[u].state].mode??"auto",v=c?JSON.stringify([c.log,c.dns_log,c.flows,Re.map(w)]):"",[x,N]=b.useState(null),p=x??{at:v,values:{},modes:{}},k=p.level??c?.log.level??"",E=!!x&&(x.level!==void 0||Object.keys(x.values).length>0||Object.keys(x.modes).length>0),P=Fe(E,()=>N(null)),_={"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},j=Hs.filter(u=>l.has(u)).map(u=>({...Gs(u,p.values[u]??(c?String(de[u].read(c)):""),_[u],e,s),change:g=>{i.busy||N({...p,values:{...p.values,[u]:g.trim()}})}})),L=Re.filter(u=>l.has(u)).map(u=>({...Fs(u,p.modes[u]??w(u),c?.recording?.[ke[u].state],s),change:g=>{i.busy||N({...p,modes:{...p.modes,[u]:g}})}})),S={};if(c){for(const u of L)u.value!==w(u.id)&&(S[u.id]=Us(u.value));l.has("log.level")&&k!==c.log.level&&(S.log={level:k});for(const u of j)!u.invalid&&Number(u.value)!==de[u.id].read(c)&&de[u.id].write(S,Number(u.value))}const B=()=>{if(i.busy)return;const u=x;i.save(S).then(g=>{g!==void 0&&(N(y=>y===u?null:y),C("positive",s("settings.runtimeSaved")))},g=>C("negative",s("settings.runtimeFailed"),{detail:W(g,s)}))};return{numeric:j,recorders:L,recordingNote:Bs(c?.recording,s),level:k,setLevel:u=>{i.busy||N({...p,level:u})},levels:(n?.logs.levels??["trace","debug","info","warn","error"]).map(u=>({id:u,label:os(is,u,s)})),hasLevel:l.has("log.level"),hasBaseline:!!c,source:c?s(c.source==="runtime"?"settings.sourceRuntime":"settings.sourceConfig"):null,sourceTone:c?.source==="runtime"?"info":"neutral",capsError:a.error,retryCaps:a.refetch,waiting:!n,available:r,note:s(r?"settings.runtimeNote":"settings.runtimeUnavailable"),error:i.error,retry:i.refetch,loading:i.loading&&!c,busy:i.busy,conflict:E&&x.at!==v?s("settings.runtimeConflict"):null,discard:()=>{P.clear(),N(null)},dirty:E,blocked:!Object.keys(S).length||j.some(u=>u.invalid),apply:B}}const Ie=ne("runtime");function Js(){const s=O(),e=$s();return t.jsxs(ae,{level:2,title:s(Ie.titleKey),titleId:Ie.headingId,aside:t.jsx(t.Fragment,{children:e.source&&t.jsx(Ne,{tone:e.sourceTone,children:e.source})}),children:[e.waiting&&e.capsError?t.jsx($,{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($,{error:e.error,onRetry:e.retry}),e.conflict&&t.jsx(ls,{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(re,{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(Ne,{tone:a.tone,small:!0,children:a.status})]},a.id)),e.recordingNote&&t.jsx("span",{className:"rp-label",children:e.recordingNote})]}),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 Qs(){const s=O(),e=_e[Se()],a=pe(),n=a.data?.resources,r=ds(xe(n,"runtime",{whileLoading:!1})),l=cs(xe(n,"providers",{whileLoading:!1})),i=us(l.refetch),c=gs(xe(n,"connections",{whileLoading:!1})&&n?.connections.can_close===!0),w=ps(c.refetch),v=Rs(),x=fs(r.data,a.data,r.refetch),N=!!n?.geodata.available&&!Oe(n),p=Ge(N),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||N&&!!n?.geodata.can_update,P=(l.data?.providers??[]).filter(g=>g.kind==="subscription"),_=!!l.data&&!l.error&&!l.loading,j=!!c.data&&!c.error&&!c.loading,L=j?c.data.total_tcp+c.data.total_udp:null,S=i.busy==="*",B=()=>{const g=[];let y=!1;return i.refreshMany(P.map(h=>h.id),(h,D)=>g.push(D),()=>y=!0).then(h=>{if(h===void 0)return;const D={n:h,total:P.length},A=h===P.length?"positive":h?"info":"negative";g.length?C(A,s("settings.refreshedAllFailed",{...D,failed:g.length}),{detail:W(g[0],s)}):C(A,s("settings.refreshedAll",D)),y&&C("info",s("settings.refreshedDegraded"))},h=>C("negative",s("settings.refreshAllFailed"),{detail:W(h,s)}))},u=()=>w.closeAll({ids:[],query:{all:!0}}).then(g=>{g&&C(ms(g),s("conn.closedAll",{closed:g.closed,skipped:g.skipped}))},g=>s("ui.valuePair",{label:s("conn.closeFailed"),value:W(g,s)}));return{runtimeError:r.error,retryRuntime:r.refetch,lifecycle:x.actions,flush:{confirmationText:s("dns.flushConfirmAll"),isPending:v.busy,isDisabled:v.busy,onAbort:v.cancel,onConfirm:()=>v.flush().then(g=>{g&&C("positive",s("dns.flushed",{matched:g.matched,deleted:g.deleted}))},g=>s("dns.flushFailed",{error:W(g,s)}))},closeAll:{confirmationText:L===null?"":s("settings.closeAllHelp",{n:L}),isDisabled:!j||!L||!!w.busy,isPending:w.busy==="all"||c.loading&&!c.data,onConfirm:u,onAbort:w.cancel},geodataBusy:p.busy,geodataBlocked:p.busy||!p.data,geodataLoading:p.loading&&!p.data,geodataError:p.error,retryGeodata:p.refetch,providersError:l.error,providersLoading:l.loading&&!l.data,retryProviders:l.refetch,connectionsError:c.error,retryConnections:c.refetch,waiting:!n&&!a.error,note:s(E?"settings.actionsNote":"settings.actionsNone"),refreshingAll:S,refreshAll:B,refreshDisabled:!_||!!i.busy||!P.length,refreshLabel:s("settings.refreshAll",{n:_?P.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:N,rows:Ms(p.data?.assets??[],e),update:()=>void p.update().then(g=>{g&&C("positive",s("settings.geodataUpdated"))},g=>C("negative",s("settings.geodataFailed"),{detail:W(g,s)}))}}const Ee=ne("actions");function Xs(){const s=O(),{runtimeError:e,retryRuntime:a,lifecycle:n,flush:r,closeAll:l,geodataBusy:i,geodataBlocked:c,geodataLoading:w,geodataError:v,retryGeodata:x,providersError:N,providersLoading:p,retryProviders:k,connectionsError:E,retryConnections:P,note:_,refreshingAll:j,refreshAll:L,refreshDisabled:S,refreshLabel:B,canFlush:u,canRefresh:g,canClose:y,canUpdate:h,hasGeodata:D,rows:A,update:z,waiting:K}=Qs();return t.jsxs(ae,{level:2,title:s(Ee.titleKey),titleId:Ee.headingId,children:[t.jsx("span",{className:"rp-label",children:K?" ":_}),t.jsx($,{error:e,onRetry:a}),t.jsxs("div",{className:"rp-ops",children:[K&&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(As,{overflowMode:"wrap",actions:n})})]}),u&&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})})]}),g&&t.jsxs("div",{className:"rp-ops-group",children:[t.jsx("span",{className:"rp-label",children:s("nav.nodes")}),t.jsx($,{error:N,onRetry:k}),t.jsx("div",{className:"rp-cluster",children:t.jsx(I,{isPending:j||p,isDisabled:j||S,onPress:()=>void L(),children:B})})]}),y&&t.jsxs("div",{className:"rp-ops-group",children:[t.jsx("span",{className:"rp-label",children:s("nav.connections")}),t.jsx($,{error:E,onRetry:P}),t.jsx("div",{className:"rp-cluster",children:t.jsx(Le,{label:s("conn.closeAll"),...l})})]})]}),D&&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("div",{className:"rp-cluster",children:h&&t.jsx(I,{isPending:i,isDisabled:c,onPress:z,children:s("settings.geodataUpdate")})})]}),t.jsx("span",{className:"rp-label",children:s("settings.geodataNote")}),t.jsx($,{error:v,onRetry:x}),t.jsx(Ls,{label:s("settings.geodata"),loading:w,rows:A,height:160,fit:!0,cols:[{id:"kind",label:s("settings.geodataAsset"),minWidth:100,grow:0,isRowHeader:!0,render:R=>R.kind},{id:"size",label:s("settings.geodataSize"),minWidth:100,grow:0,align:"end",render:R=>R.size},{id:"modified",label:s("nodes.updated"),minWidth:140,grow:0,render:R=>t.jsx(Ds,{at:R.modifiedAt})},{id:"sha",label:"SHA-256",minWidth:160,drop:2,render:R=>t.jsx(De,{text:R.shaTitle,children:t.jsx("span",{className:"rp-code",children:R.sha})})},{id:"source",label:s("settings.geodataSource"),minWidth:240,grow:2,render:R=>t.jsx(De,{className:"rp-code",children:R.source})}]})]})]})}const oe=["geosite","geoip"],je={metacubex:"settings.geodataPreset.metacubex","metacubex-lite":"settings.geodataPreset.metacubexLite",loyalsoldier:"settings.geodataPreset.loyalsoldier"};function Ys(s){return le.find(e=>oe.every(a=>s[a].length>0&&s[a].every(n=>e.urls[a].includes(n)||e.mirrors[a].includes(n))))??null}const ze=s=>{try{return new URL(s).host}catch{return s}};function Zs(s,e){if(!s?.categories||!e)return null;const a={};for(const n of oe){const r=new Set(s.categories[n]),l=(e[n]??[]).filter(i=>!r.has(i));l.length&&(a[n]=l)}return Object.keys(a).length?a:null}function Ke(s,e){const a=s.trim();return a?Is(a)?e.filter(n=>n.trim()===a).length>1?"settings.geodataUrlDuplicate":null:"settings.geodataUrlInvalid":null}function et(s){return s.length<Ts&&s.every(e=>e.trim())?[...s,""]:s}const st=s=>oe.some(e=>!s[e].some(a=>a.trim())||s[e].some(a=>Ke(a,s[e]))),tt=s=>({geosite:s.geosite.map(e=>e.trim()).filter(Boolean),geoip:s.geoip.map(e=>e.trim()).filter(Boolean)});function Ve(s,e,a){const n=Zs(s,e);return n&&oe.flatMap(r=>(n[r]??[]).map(l=>`${r}:${l}`)).join(a("ui.separator"))}function at(s,e,a,n){const r=Ve(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 ye=[6,12,24,72,168];function nt(s,e){return(ye.includes(s)?ye:[...ye,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 rt(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 ot(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:hs(s.last_error.code,s.last_error.message,r)}),error:!0};const l=s?.last_updated_at,i=s?l?bs(l,n,a):r("settings.geodataNever"):"—",w=s?.assets.length&&s.assets.every(v=>v.verified!==void 0)?r(s.assets.every(v=>v.verified)?"settings.geodataVerifiedYes":"settings.geodataVerifiedNo"):null;return{text:r("ui.valuePair",{label:r("settings.geodataLastUpdated"),value:w?i+r("ui.separator")+w:i}),error:!1}}function it(s,e,a,n){return(s?.assets??[]).map(r=>{const l=r.fetched_url_redacted??r.source_redacted??"",i=[ce(r.size_bytes,a),l?ze(l):null,r.download_route?rt(r.download_route,e,n):null];return[r.kind,i.filter(Boolean).join(n("ui.separator")),l]})}function lt(){const s=O(),e=Se(),a=_e[e],n=vs(),r=pe(),l=Oe(r.data?.resources),i=He(l),c=Ge(l),w=xs(l),v=i.data?.geodata,[x,N]=b.useState(null),[p,k]=b.useState(null),[E,P]=b.useState(null),[_,j]=b.useState(null),L=i.busy||c.busy,S=!!r.data?.resources.geodata.can_update,B=()=>c.update().then(d=>{d&&C("positive",s("settings.geodataUpdated"))},d=>C("negative",s("settings.geodataFailed"),{detail:W(d,s)})),u=b.useRef(!1),g=d=>u.current||L?Promise.resolve(!1):(u.current=!0,N(d),i.save({geodata:d}).then(m=>(u.current=!1,N(null),m===void 0?!1:(c.refetch(),d.geosite&&S?B():C("positive",s(d.geosite?"settings.geodataSaved":d.download?"settings.geodataRouteSaved":"settings.geodataAutoSaved")),!0)),m=>(u.current=!1,N(null),C("negative",s("settings.geodataSaveFailed"),{detail:W(m,s)}),!1))),y=x?.geosite&&x.geoip?{geosite:x.geosite.urls,geoip:x.geoip.urls}:v?{geosite:v.geosite.urls,geoip:v.geoip.urls}:null,h=y?Ys(y):null,D={...v?.auto_update,...x?.auto_update},A=v?.download&&(x?.download??v.download),z=E??A?.route??"routing",K=d=>at(le.find(m=>m.id===d),c.data?.required_codes,a,s),R=d=>void g({geosite:{urls:[...d.urls.geosite]},geoip:{urls:[...d.urls.geoip]}}),J=s(S?"settings.geodataSaveUpdate":"settings.geodataSaveSources"),F=ot(c.data,c.busy||S&&!!x?.geosite,n,a,s);return{available:l,loading:i.loading&&!v,error:i.error,retry:i.refetch,ready:!!v,busy:L,seededFromConfig:v?.source==="config",note:s(S?"settings.geodataSourcesNote":"settings.geodataSourcesNoteStored"),source:{value:y?h?.id??"custom":"",items:[...le.map(d=>({id:d.id,label:s(je[d.id]),desc:K(d.id).text})),{id:"custom",label:s("settings.geodataCustom")}],note:h?K(h.id):null,change:d=>{if(d==="custom")k(y?{geosite:[...y.geosite],geoip:[...y.geoip]}:null);else if(d!==h?.id){const m=le.find(V=>V.id===d),U=Ve(m,c.data?.required_codes,s);U?j({preset:m,codes:U}):R(m)}}},lacking:_&&{title:s("settings.geodataLackingTitle",{preset:s(je[_.preset.id])}),text:s("settings.geodataLackingHelp",{preset:s(je[_.preset.id]),codes:_.codes}),confirm:J,cancel:()=>j(null),save:()=>{j(null),R(_.preset)}},customHosts:y&&!h?js(e,[...new Set([...y.geosite,...y.geoip].map(ze))]):null,editCustom:()=>y&&k({geosite:[...y.geosite],geoip:[...y.geoip]}),dialog:p?{lists:oe.map(d=>({kind:d,fields:et(p[d]).map((m,U,V)=>{const Q=Ke(m,V),Y=H=>H>=0&&H<p[d].length&&U<p[d].length?()=>{if(i.busy)return;const T=[...p[d]];[T[U],T[H]]=[T[H],T[U]],k({...p,[d]:T})}:void 0,X=s("settings.geodataUrlLabel",{kind:d,n:ie(U+1,a)});return{up:Y(U-1),down:Y(U+1),upLabel:s("settings.geodataMoveUp",{url:X}),downLabel:s("settings.geodataMoveDown",{url:X}),id:`${d}-${U}`,label:X,value:m,error:Q?s(Q):void 0,change:H=>{if(i.busy)return;const T=[...V];for(T[U]=H;T.length&&!T[T.length-1].trim();)T.pop();k({...p,[d]:T})}}}),empty:!p[d].some(m=>m.trim())})),blocked:st(p),confirm:J,pending:i.busy,cancel:()=>k(null),save:()=>{const d=tt(p);g({geosite:{urls:d.geosite},geoip:{urls:d.geoip}}).then(m=>m&&k(null))}}:null,route:A&&{value:z,items:["routing","direct","group"].map(d=>({id:d,label:s(d==="routing"?"settings.geodataRouteRouting":d==="direct"?"settings.geodataRouteDirect":"settings.geodataRouteGroup")})),change:d=>{if(d==="group")return P("group");P(null),d!==A?.route&&g({download:{route:d}})},group:z==="group"?A?.route==="group"?A.group_id??"":"":null,groups:(w.data??[]).map(d=>({id:d.id,label:d.name})),pickGroup:d=>{d!==(A?.route==="group"?A.group_id:null)&&g({download:{route:"group",group_id:d}}).then(m=>m&&P(null))}},auto:{enabled:!!D.enabled,toggle:d=>void g({auto_update:{enabled:d}}),interval:String(D.interval_hours??""),intervals:D.interval_hours?nt(D.interval_hours,a):[],pick:d=>{Number(d)!==v?.auto_update.interval_hours&&g({auto_update:{interval_hours:Number(d)}})}},status:{...F,details:it(c.data,w.data,a,s)},statusError:c.error,retryStatus:c.refetch,canUpdate:S,updating:c.busy,updateBlocked:L||!c.data,update:()=>void B()}}const Ue=ne("geodata");function dt(){const s=O(),e=lt();return e.available?t.jsxs(ae,{level:2,title:s(Ue.titleKey),titleId:Ue.headingId,children:[t.jsx("span",{className:"rp-label",children:e.note}),t.jsx($,{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.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.canUpdate&&t.jsx(I,{isPending:e.updating,isDisabled:e.updateBlocked,onPress:e.update,children:s("settings.geodataUpdateNow")})]})]}),t.jsx($,{error:e.statusError,onRetry:e.retryStatus}),e.status.details.length>0&&t.jsx(ys,{title:s("settings.geodataDetails"),children:t.jsx("div",{className:"rp-geodata-details",children:t.jsx(ws,{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(re,{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(Ae,{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(Ae,{})})]})},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 te={backend:ne("backend"),appearance:ne("appearance"),about:ne("about")};function wt({query:s}){const e=O(),a=Ws(),{activeId:n,hasActive:r,firstRun:l,error:i,retry:c,api:w,changeApi:v,token:x,changeToken:N,demo:p,passwordMode:k,paired:E,invalidText:P,pending:_,saving:j,dialog:L,setDialog:S,name:B,setName:u,confirmProfile:g,save:y,switchProfile:h,confirmSwitch:D,switchPending:A,cancelSwitch:z,testConnection:K,lang:R,pickLang:J,ap:F,paletteSections:d,profile:m,palette:U,tokenType:V,tokenToggleText:Q,toggleToken:Y,versionWarning:X,install:H,installHint:T,addProfile:ee,renameProfile:fe,dialogTitle:me,dialogBlocked:se,dialogDiscards:he,deleteHelp:Ce}=qs(s),o=b.useId();return t.jsxs("div",{className:"rp-page",children:[l&&t.jsx("p",{className:"rp-note",children:e("settings.firstRun")}),E&&t.jsx("p",{className:"rp-note",children:e("settings.paired")}),t.jsxs(ae,{level:2,title:e(te.backend.titleKey),titleId:te.backend.headingId,children:[t.jsx($,{error:i,onRetry:c}),t.jsxs("div",{className:"rp-toolbar",children:[t.jsx(G,{label:e("settings.profile"),side:!0,value:n,isDisabled:!r||j,items:m.choices,onChange:h}),t.jsx(I,{onPress:ee,children:e("settings.addProfile")}),t.jsx(I,{isDisabled:!r,onPress:fe,children:e("settings.renameProfile")}),t.jsx(I,{isDisabled:!r,onPress:()=>S("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:f=>{f.preventDefault(),y()},children:[t.jsx(re,{label:e("settings.api"),autoComplete:"url",spellCheck:!1,description:e("settings.apiHelp"),error:P,name:"api",value:w,onChange:v}),p?null:k?t.jsx("p",{className:"rp-label",children:e("settings.passwordMode")}):t.jsx(re,{label:e("settings.token"),autoComplete:"off",spellCheck:!1,reveal:{shown:V==="text",label:Q,onToggle:Y},name:"token",type:V,value:x,onChange:N}),t.jsxs("div",{className:"rp-toolbar",children:[t.jsx(I,{onPress:()=>void K(),isPending:_,isDisabled:j,children:e("settings.test")}),t.jsx(I,{type:"submit",accent:!0,isPending:j,children:e("settings.save")})]}),t.jsx("div",{className:"rp-label",children:e("settings.saveHelp")}),_&&t.jsx("div",{role:"status",children:e("settings.testing")}),m.result&&t.jsxs("div",{role:m.result.role,children:[m.result.text,m.result.request&&t.jsx("span",{className:"rp-code",children:m.result.request})]})]})]}),t.jsx(Js,{}),t.jsx(dt,{}),t.jsx(Xs,{}),t.jsxs(ae,{level:2,title:e(te.appearance.titleKey),titleId:te.appearance.headingId,children:[t.jsxs("div",{className:"rp-toolbar",children:[t.jsx(G,{label:e("lang"),value:R,onChange:f=>J(f),items:Ns.map(([f,M])=>({id:f,label:M}))}),t.jsxs("div",{className:"rp-field",children:[t.jsx("span",{className:"lbl",children:e("palette")}),t.jsx(ks,{label:e("palette"),sections:d.map(f=>({...f,value:F.palette,onChange:M=>F.pickPalette(M)})),children:U})]}),t.jsx(G,{label:e("settings.scheme"),value:F.scheme,onChange:f=>F.pickScheme(f),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:F.wordmark,onChange:f=>F.pickWordmark(f),items:[{id:"gradient",label:e("wordmark.gradient")},{id:"plain",label:e("wordmark.plain")}]}),t.jsx(G,{label:e("settings.toastPlacement"),value:F.toastPlacement,onChange:f=>F.pickToastPlacement(f),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:F.mirrored,onChange:F.pickMirrored,"aria-describedby":o,children:e("settings.mirror")}),t.jsx("span",{id:o,className:"rp-label",children:e("settings.mirrorHelp")})]})]}),t.jsxs(ae,{level:2,title:e(te.about.titleKey),titleId:te.about.headingId,children:[X&&t.jsx(Ne,{small:!0,tone:"warn",children:X}),t.jsxs("div",{className:"rp-cluster",children:[t.jsx(_s,{trigger:t.jsx(I,{children:e("about.title")})}),H&&t.jsx(I,{onPress:H,children:e("settings.install")}),T&&t.jsx("p",{className:"rp-note",children:T})]})]}),t.jsx(ge,{title:e("config.discardTitle"),isOpen:A,onCancel:z,confirmLabel:e("config.discard"),isPending:j,onConfirm:D,children:t.jsx("p",{className:"rp-label",children:e("settings.switchProfileHelp")})}),L&&t.jsxs(ge,{title:me,isOpen:!0,onCancel:()=>S(null),tone:L==="delete"?"negative":"accent",confirmLabel:e(L==="delete"?"settings.deleteProfile":"settings.save"),isDisabled:se,isPending:j,error:m.result?.error?{id:m.result.id,text:m.result.text}:null,onConfirm:g,children:[L==="delete"?t.jsx("p",{className:"rp-label",children:Ce}):t.jsx(re,{label:e("settings.profileName"),value:B,onChange:u}),he&&t.jsx("p",{className:"rp-label",children:e("settings.profileDiscardHelp")})]})]})}export{wt as Settings};
|