@mmmbuto/nexuscrew 0.8.44 → 0.8.45

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.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,35 @@ All notable changes to NexusCrew are tracked here.
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ ## 0.8.45 — 2026-07-30 — "Resilient Directory"
8
+
9
+ - Fleet cell-directory reads no longer wait for external model catalog discovery.
10
+ A stalled optional engine binary therefore cannot make the MCP bridge present
11
+ a reachable local Fleet as unavailable.
12
+ - External model discovery has a bounded five-second budget and caches failures
13
+ as well as successful results, preventing repeated hung subprocess calls.
14
+ - The MCP cell directory now marks a local timeout explicitly, so a degraded
15
+ bridge can be distinguished from an unreachable remote node.
16
+ - Share activation now performs an authenticated, non-scanning preflight on
17
+ the hub-assigned reverse port. A listener owned by the same verified peer is
18
+ accepted; an unverified occupied port returns an actionable conflict without
19
+ restarting or publishing the private tunnel.
20
+ - Peer health reports a reverse listener that remains active while Share is
21
+ disabled, while `nexuscrew status` now states Share enabled or disabled for
22
+ inbound peers. These diagnostics never terminate a peer tunnel automatically.
23
+ - Shared peers can use an operator-preauthorized three-port reverse pool. The
24
+ product never writes `authorized_keys`; legacy or incompletely granted peers
25
+ remain private/usable and are diagnosed as not rotatable instead of guessing
26
+ another SSH port.
27
+ - A peer proposes a pool slot over its existing private channel and the hub
28
+ assigns a bounded lease and generation. Rotation runs only after all slots
29
+ have been independently verified, tries one candidate per ten-minute window,
30
+ and quarantines failures rather than killing unknown listeners.
31
+ - Slot ownership now uses a per-slot HMAC proof with a fresh challenge. The
32
+ hub never sends a peer bearer credential to a listener it is investigating;
33
+ a relayed proof from a different slot is rejected. Retired pool bases are
34
+ never reused automatically, protecting against stale `permitlisten` grants.
35
+
7
36
  ## 0.8.44 — 2026-07-28 — "Deliberate Switch"
8
37
 
9
38
  - The mobile cell quick rail now separates selection from switching: choose a
package/README.md CHANGED
@@ -101,6 +101,12 @@ Remote access is intentionally carried through SSH or a VPN you control:
101
101
  ssh -L 41820:127.0.0.1:41820 user@your-host
102
102
  ```
103
103
 
104
+ Shared mobile peers can use a small, pre-authorized reverse-port pool for
105
+ recovery from a real reverse-forward collision. NexusCrew never edits SSH
106
+ policy: the hub operator keeps `authorized_keys` authoritative, while the
107
+ product verifies a configured pool before it can rotate within it. See
108
+ [Connect nodes](docs/NODES.md#rotatable-reverse-port-pools).
109
+
104
110
  [Security model →](docs/SECURITY.md)
105
111
 
106
112
  ## Documentation
@@ -90,4 +90,4 @@ Minimum version required to store current data is: `+I+`.
90
90
  `).filter(o=>o!==""),promptMode:e.promptMode};return e.modelFlag&&(s.model={flag:e.modelFlag,value:e.modelValue||""}),e.promptMode==="flag"&&(s.promptFlag=e.promptFlag),t&&(s.env=Object.fromEntries(e.envRows.filter(o=>!o.remove&&o.key).map(o=>[o.key,o.value]))),s}function Ms({children:e,onClose:t,label:n,error:s=""}){const o=E.useRef(null),a=E.useRef(null),u=E.useRef(t);return u.current=t,E.useEffect(()=>{const h=document.activeElement,f=o.current,p=()=>Array.from((f==null?void 0:f.querySelectorAll('button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [href], [tabindex]:not([tabindex="-1"])'))||[]).filter(w=>w.offsetParent!==null),v=requestAnimationFrame(()=>{var w;return(w=p()[0]||f)==null?void 0:w.focus({preventScroll:!0})}),b=w=>{var C;if(w.key==="Escape"){w.preventDefault(),(C=u.current)==null||C.call(u);return}if(w.key!=="Tab")return;const S=p();if(!S.length){w.preventDefault(),f==null||f.focus();return}const y=S[0],x=S[S.length-1];w.shiftKey&&document.activeElement===y?(w.preventDefault(),x.focus()):!w.shiftKey&&document.activeElement===x&&(w.preventDefault(),y.focus())};return document.addEventListener("keydown",b),()=>{cancelAnimationFrame(v),document.removeEventListener("keydown",b),h&&h.isConnected&&typeof h.focus=="function"&&h.focus({preventScroll:!0})}},[]),E.useEffect(()=>{s&&requestAnimationFrame(()=>{var h;return(h=a.current)==null?void 0:h.scrollIntoView({block:"nearest"})})},[s]),c.jsx("div",{className:"nc-fleet-modal",role:"presentation",onMouseDown:h=>{h.target===h.currentTarget&&t()},children:c.jsxs("div",{ref:o,className:"nc-fleet-modal-dialog",role:"dialog","aria-modal":"true","aria-label":n||m("settings"),tabIndex:-1,children:[e,s&&c.jsx("div",{ref:a,className:"nc-err nc-fleet-modal-error",role:"alert","aria-live":"assertive",children:s})]})})}function Nd({token:e,targets:t=[],readonly:n=!1,onPower:s,onImport:o}){const[a,u]=E.useState([]),[h,f]=E.useState(0);E.useEffect(()=>{let C=!0;async function R(){const $=[{route:[],label:m("local")}].concat((t||[]).map(V=>({route:Array.isArray(V.route)?V.route:[],label:V.label||(V.route||[]).join(" › ")}))),O=await Promise.all($.map(async V=>{const Y={...V,available:!1,readonly:!1,capabilities:[],provider:null,cells:[],unmanaged:[],err:""};try{const z=await _s(e,V.route);Y.available=!!z.available,Y.capabilities=z.capabilities||[],Y.provider=z.provider||null,Y.cells=(z.cells||[]).map(ne=>({...ne,route:V.route}));try{Y.readonly=!!(await Fh(e,V.route)).readonlyDefault}catch{}try{const ne=await zh(e,V.route),H=new Set(Y.cells.map(X=>X.tmuxSession).filter(Boolean));Y.unmanaged=(ne.sessions||[]).filter(X=>X&&!H.has(X.name))}catch{}}catch(z){Y.err=String(z&&z.message||z)}return Y}));C&&u(O)}R();const k=setInterval(R,6e3);return()=>{C=!1,clearInterval(k)}},[e,t,h]);const p=(C,R)=>Array.isArray(C.capabilities)&&C.capabilities.includes(R)&&!n&&!C.readonly,v=()=>f(C=>C+1),b=(C,R)=>{s&&s({...C,route:R})},w=(C,R)=>{s&&s({...C,route:R})},S=async(C,R)=>{try{await jo(e,C.cell,R)}catch{}v()},y=async(C,R)=>{if(window.confirm(m("fleet-remove-cell").replace("{id}",C.cell))){try{await F_(e,C.cell,!0,R)}catch{}v()}},x=async(C,R)=>{if(window.confirm(m("terminate-confirm").replace("{name}",C.name))){try{await Bh(e,C.name,R)}catch{}v()}};return c.jsxs("div",{className:"nc-fleet-inventory",children:[c.jsxs("div",{className:"nc-fleet-section-head",children:[c.jsx("b",{children:m("fleet-inventory")}),c.jsx("small",{children:m("fleet-inventory-help")})]}),a.map(C=>{const R=C.route.length?C.route.join("/"):"local";return c.jsxs("div",{className:"nc-fleet-pos",children:[c.jsxs("div",{className:"nc-fleet-pos-title",children:[c.jsx("span",{className:`dot ${C.available?"on":"warn"}`}),c.jsx("b",{children:C.label}),c.jsx("small",{children:C.available?`${C.cells.length} ${m("fleet-cells")} · ${C.unmanaged.length} ${m("fleet-tmux")}`:C.err||m("fleet-not-available")})]}),C.cells.map(k=>c.jsxs("div",{className:"nc-fleet-item nc-fleet-cell",children:[c.jsxs("span",{children:[c.jsx("b",{children:k.cell}),c.jsx("small",{children:`${k.engine||""}${k.key?`·${k.key}`:""}${k.active?"":` · ${m("cell-off")}`}`})]}),c.jsxs("span",{className:"nc-fleet-cell-actions",children:[k.active&&p(C,"down")&&c.jsx("button",{className:"nc-btn ghost",title:m("power-off"),onClick:()=>w(k,C.route),children:m("stop")}),!k.active&&p(C,"up")&&c.jsx("button",{className:"nc-btn ghost",title:m("power-on"),onClick:()=>b(k,C.route),children:m("start")}),p(C,"restart")&&k.active&&c.jsx("button",{className:"nc-btn ghost",title:m("restart"),onClick:()=>S(k,C.route),children:m("restart")}),p(C,"remove")&&c.jsx("button",{className:"nc-btn danger",title:m("delete"),onClick:()=>y(k,C.route),children:"×"})]})]},`${R}:${k.cell}`)),C.unmanaged.map(k=>c.jsxs("div",{className:"nc-fleet-item nc-fleet-unmanaged",children:[c.jsxs("span",{children:[c.jsx("b",{children:k.name}),c.jsx("small",{children:m("fleet-tmux")})]}),c.jsxs("span",{className:"nc-fleet-cell-actions",children:[p(C,"import")&&o&&c.jsx("button",{className:"nc-btn ghost",title:m("import-as-cell"),onClick:()=>o(k,C.route),children:m("import-as-cell")}),c.jsx("button",{className:"nc-btn danger",title:m("terminate"),onClick:()=>x(k,C.route),children:"×"})]})]},`${R}:u:${k.name}`)),C.available&&C.cells.length===0&&C.unmanaged.length===0&&c.jsx("div",{className:"nc-empty",children:m("fleet-inventory-empty")})]},R)})]})}function mN({cells:e=[],engines:t=[],busy:n,canRestore:s=!1,onRestore:o,onClose:a}){const[u,h]=E.useState("export"),[f,p]=E.useState(()=>new Set(e.map(N=>N.id))),[v,b]=E.useState(()=>new Set(t.map(N=>N.id))),[w,S]=E.useState([]),[y,x]=E.useState([]),[C,R]=E.useState(""),k=new Set(t.map(N=>N.id)),$=new Set(e.map(N=>N.id)),O=(N,M)=>N(L=>{const P=new Set(L);return P.has(M)?P.delete(M):P.add(M),P}),V=()=>{const N=lN(e,f,t,v);if(N.ok===!1){R(m(`fleet-backup-${N.error}`));return}const M=e.filter(q=>f.has(q.id)).length,L=t.filter(q=>v.has(q.id)).length;if(N.cells.length!==M){R(m("fleet-backup-invalid-cell"));return}if(N.engines.length!==L){R(m("fleet-backup-invalid-engine"));return}if(!N.cells.length&&!N.engines.length){R(m("fleet-backup-select-one"));return}const P=new Blob([`${JSON.stringify(N,null,2)}
91
91
  `],{type:"application/json"}),F=URL.createObjectURL(P),T=document.createElement("a");T.href=F,T.download=`nexuscrew-fleet-${new Date().toISOString().slice(0,10)}.json`,document.body.appendChild(T),T.click(),T.remove(),setTimeout(()=>URL.revokeObjectURL(F),0),R("")},Y=async N=>{if(R(""),S([]),x([]),!!N){if(N.size>1024*1024){R(m("fleet-backup-too-large"));return}try{const M=cN(await N.text());if(!M.ok){R(m(`fleet-backup-${M.error}`));return}const L=new Set(M.engines.map(P=>P.id));x(M.engines.map(P=>({engine:P,exists:k.has(P.id),selected:!k.has(P.id)}))),S(M.cells.map(P=>{const F=k.has(P.engine)||L.has(P.engine),T=$.has(P.id);return{cell:P,engine:F?P.engine:"",selected:F&&!T,exists:T}}))}catch(M){R(String(M.message||M))}}},z=(N,M)=>S(L=>L.map((P,F)=>F===N?{...P,...M}:P)),ne=(N,M)=>x(L=>L.map((P,F)=>F===N?{...P,...M}:P)),H=new Set([...k,...y.filter(N=>N.selected).map(N=>N.engine.id)]),X=w.filter(N=>N.selected&&N.engine&&H.has(N.engine)),I=y.filter(N=>N.selected),A=[...new Map([...t.map(N=>[N.id,N.label||N.id]),...y.filter(N=>N.selected).map(N=>[N.engine.id,N.engine.label||N.engine.id])]).entries()];return c.jsxs("div",{className:"nc-set-form nc-fleet-form nc-backup-dialog",children:[c.jsx("b",{children:m("fleet-backup")}),c.jsx("small",{children:m("fleet-backup-help")}),c.jsxs("div",{className:"nc-set-tabs nc-backup-tabs",children:[c.jsx("button",{type:"button",className:`nc-set-tabbtn${u==="export"?" on":""}`,onClick:()=>{h("export"),R("")},children:m("fleet-backup-export")}),c.jsx("button",{type:"button",className:`nc-set-tabbtn${u==="import"?" on":""}`,disabled:!s,title:s?"":m("fleet-backup-restore-unavailable"),onClick:()=>{h("import"),R("")},children:m("fleet-backup-import")})]}),u==="export"?c.jsxs(c.Fragment,{children:[c.jsxs("div",{className:"nc-set-row",children:[c.jsx("button",{type:"button",className:"nc-btn ghost",onClick:()=>{p(new Set(e.map(N=>N.id))),b(new Set(t.map(N=>N.id)))},children:m("select-all")}),c.jsx("button",{type:"button",className:"nc-btn ghost",onClick:()=>{p(new Set),b(new Set)},children:m("select-none")})]}),c.jsxs("div",{className:"nc-backup-list",children:[c.jsx("b",{children:m("fleet-engines")}),t.map(N=>{var M;return c.jsxs("label",{className:"nc-check nc-backup-row",children:[c.jsx("input",{type:"checkbox",checked:v.has(N.id),onChange:()=>O(b,N.id)}),c.jsxs("span",{children:[c.jsx("b",{children:N.label||N.id}),c.jsxs("small",{children:[N.id,(M=N.envKeys)!=null&&M.length?` · ${N.envKeys.length} ${m("fleet-backup-env-names")}`:""]})]})]},N.id)}),c.jsx("b",{children:m("fleet-cells")}),e.map(N=>c.jsxs("label",{className:"nc-check nc-backup-row",children:[c.jsx("input",{type:"checkbox",checked:f.has(N.id),onChange:()=>O(p,N.id)}),c.jsxs("span",{children:[c.jsx("b",{children:N.id}),c.jsxs("small",{children:[N.engine," · ",m("fleet-system-prompt")," ",(N.prompt||"").length," ",m("characters")]})]})]},N.id)),!e.length&&!t.length&&c.jsx("div",{className:"nc-empty",children:m("fleet-backup-empty")})]}),c.jsxs("div",{className:"nc-sheet-actions",children:[c.jsx("button",{type:"button",className:"nc-btn ghost",onClick:a,children:m("cancel")}),c.jsx("button",{type:"button",className:"nc-btn primary",disabled:!f.size&&!v.size,onClick:V,children:m("fleet-backup-download")})]})]}):c.jsxs(c.Fragment,{children:[c.jsx("input",{type:"file",accept:"application/json,.json",disabled:n,onChange:N=>Y(N.target.files&&N.target.files[0])}),c.jsx("small",{children:m("fleet-backup-import-help")}),!!(w.length||y.length)&&c.jsxs("div",{className:"nc-set-row",children:[c.jsx("button",{type:"button",className:"nc-btn ghost",onClick:()=>{x(N=>N.map(M=>({...M,selected:!0}))),S(N=>N.map(M=>({...M,selected:!!M.engine})))},children:m("select-all")}),c.jsx("button",{type:"button",className:"nc-btn ghost",onClick:()=>{x(N=>N.map(M=>({...M,selected:!1}))),S(N=>N.map(M=>({...M,selected:!1})))},children:m("select-none")})]}),c.jsxs("div",{className:"nc-backup-list",children:[!!y.length&&c.jsx("b",{children:m("fleet-engines")}),y.map((N,M)=>{var L;return c.jsx("div",{className:"nc-backup-import-row",children:c.jsxs("label",{className:"nc-check",children:[c.jsx("input",{type:"checkbox",checked:N.selected,onChange:P=>ne(M,{selected:P.target.checked})}),c.jsxs("span",{children:[c.jsx("b",{children:N.engine.label||N.engine.id}),c.jsxs("small",{children:[N.engine.id," · ",N.exists?m("fleet-backup-overwrite"):m("fleet-backup-new"),(L=N.engine.envKeys)!=null&&L.length?` · ${m("fleet-backup-env-values-required")}`:""]})]})]})},N.engine.id)}),!!w.length&&c.jsx("b",{children:m("fleet-cells")}),w.map((N,M)=>c.jsxs("div",{className:"nc-backup-import-row",children:[c.jsxs("label",{className:"nc-check",children:[c.jsx("input",{type:"checkbox",checked:N.selected,disabled:!N.engine||!H.has(N.engine),onChange:L=>z(M,{selected:L.target.checked})}),c.jsxs("span",{children:[c.jsx("b",{children:N.cell.id}),c.jsxs("small",{children:[N.exists?m("fleet-backup-overwrite"):m("fleet-backup-new")," · ",m("fleet-system-prompt")," ",N.cell.systemPrompt.length," ",m("characters")]})]})]}),c.jsxs("select",{value:N.engine,onChange:L=>z(M,{engine:L.target.value,selected:!!L.target.value}),children:[c.jsx("option",{value:"",children:m("fleet-backup-engine-missing")}),A.map(([L,P])=>c.jsx("option",{value:L,children:P},L))]})]},N.cell.id))]}),c.jsxs("div",{className:"nc-sheet-actions",children:[c.jsx("button",{type:"button",className:"nc-btn ghost",onClick:a,children:m("cancel")}),c.jsx("button",{type:"button",className:"nc-btn primary",disabled:n||!X.length&&!I.length,onClick:()=>o({engineRows:y,cellRows:w}),children:m("fleet-backup-restore")})]})]}),C&&c.jsx("div",{className:"nc-err",children:C})]})}function gN({state:e,setState:t,busy:n,onSave:s,catalog:o}){var R;const a=e.form,u=k=>t({...e,form:{...a,...k}}),h=a.envRows||[],f=[...new Map(o.map(k=>[k.client,k.clientLabel||k.client])).entries()],p=o.filter(k=>k.client===a.client),v=$o(o,a),b=typeof(v==null?void 0:v.credentialEnv)=="string"?v.credentialEnv:"",w=Array.isArray(v==null?void 0:v.credentialUsedBy)?v.credentialUsedBy:[],S=(v==null?void 0:v.credentialSource)||"missing",y=!!(v!=null&&v.credentialEnv)||a.credentialProfile==="a"||a.credentialProfile==="p",x=!!b&&e.mode==="new"&&(v==null?void 0:v.authConfigured)!==!0&&!a.credentialValue&&!a.allowMissingCredential,C=k=>{k&&u({client:k.client,provider:k.provider,credentialProfile:k.credentialProfile||"",managedModel:k.model||"",protocol:k.protocol||"",permissionPolicy:k.permissionPolicyDefault||"standard",credentialSourcePolicy:"auto",rc:!!k.rc,displayName:k.custom?m("fleet-custom-provider-default"):"",baseUrl:k.custom?"":k.endpoint||"",envKey:k.defaultEnvKey||"",providerId:"nexuscrew-custom",credentialValue:"",credentialReveal:!1,allowMissingCredential:!1,...e.mode==="new"?{id:k.id,label:""}:{}})};return c.jsxs("div",{className:"nc-set-form nc-fleet-form",children:[c.jsx("b",{children:e.mode==="new"?m("fleet-new-engine"):`${m("edit")} ${a.id}`}),c.jsx("input",{value:a.id,disabled:e.mode!=="new",placeholder:"id",onChange:k=>u({id:k.target.value})}),c.jsx("input",{value:a.label,placeholder:m("label"),onChange:k=>u({label:k.target.value})}),c.jsxs("select",{value:a.kind,disabled:e.mode!=="new",onChange:k=>u({kind:k.target.value}),children:[c.jsx("option",{value:"managed",children:m("fleet-managed")}),c.jsx("option",{value:"custom",children:m("fleet-custom")})]}),a.kind==="managed"?c.jsxs(c.Fragment,{children:[c.jsxs("div",{className:"nc-fleet-pair",children:[c.jsx("select",{value:a.client,disabled:e.mode!=="new",onChange:k=>C(o.find($=>$.client===k.target.value&&$.default)||o.find($=>$.client===k.target.value)),children:f.map(([k,$])=>c.jsx("option",{value:k,children:$},k))}),c.jsx("select",{value:((R=$o(o,a))==null?void 0:R.id)||"",disabled:e.mode!=="new",onChange:k=>C(o.find($=>$.id===k.target.value)),children:p.map(k=>c.jsx("option",{value:k.id,children:k.label},k.id))})]}),a.client!=="shell"&&c.jsxs(c.Fragment,{children:[c.jsx("input",{value:a.managedModel,list:"nc-managed-models",placeholder:m(v!=null&&v.requiresModel?"fleet-model-required":"fleet-model-default"),onChange:k=>u({managedModel:k.target.value})}),c.jsx("datalist",{id:"nc-managed-models",children:[...(v==null?void 0:v.models)||[],...a.modelOptions||[]].filter((k,$,O)=>k&&O.indexOf(k)===$).map(k=>c.jsx("option",{value:k},k))})]}),v!=null&&v.supportsUnsafe?c.jsxs("select",{value:a.permissionPolicy,onChange:k=>u({permissionPolicy:k.target.value}),children:[c.jsx("option",{value:"standard",children:m("fleet-standard-permissions")}),c.jsx("option",{value:"unsafe",children:m("fleet-unsafe-permissions")})]}):c.jsx("small",{children:m("fleet-standard-permissions")}),(v==null?void 0:v.supportsUnsafe)&&a.permissionPolicy==="unsafe"&&c.jsx("small",{className:"nc-err",children:m("fleet-unsafe-warning")}),y&&c.jsxs("select",{"aria-label":m("fleet-credential-source-policy"),value:a.credentialSourcePolicy||"auto",onChange:k=>u({credentialSourcePolicy:k.target.value}),children:[c.jsx("option",{value:"auto",children:m("fleet-credential-source-policy-auto")}),c.jsx("option",{value:"nexuscrew-store",children:m("fleet-credential-source-policy-nexuscrew-store")}),c.jsx("option",{value:"environment",children:m("fleet-credential-source-policy-environment")})]}),(v==null?void 0:v.credentialEnv)===!0&&c.jsxs(c.Fragment,{children:[c.jsx("input",{value:a.envKey,placeholder:m("fleet-api-key-env"),onChange:k=>u({envKey:k.target.value})}),c.jsx("small",{children:m("fleet-custom-secret-help")})]}),b&&c.jsxs("section",{className:"nc-fleet-key","aria-label":m("fleet-key-section"),children:[c.jsxs("div",{className:"nc-fleet-key-head",children:[c.jsx("b",{children:m("fleet-key-section")}),c.jsx("span",{children:m(`fleet-credential-source-${S}`)})]}),c.jsxs("label",{className:"nc-field",children:[m("fleet-key-variable"),c.jsx("input",{value:b,readOnly:!0,"aria-label":m("fleet-key-variable")})]}),c.jsx("small",{children:w.length?m("fleet-key-used-by").replace("{engines}",w.join(", ")):m("fleet-key-used-by-none")}),w.length>0&&c.jsx("small",{children:m("fleet-key-shared-impact").replace("{key}",b).replace("{engines}",w.join(", "))}),c.jsxs("div",{className:"nc-fleet-key-input",children:[c.jsx("input",{type:a.credentialReveal?"text":"password",value:a.credentialValue||"","aria-label":m("fleet-key-value").replace("{key}",b),autoComplete:"new-password",spellCheck:!1,autoCapitalize:"none",autoCorrect:"off",placeholder:v!=null&&v.authConfigured||e.mode==="edit"?m("fleet-key-blank-keeps"):m("fleet-key-enter"),onChange:k=>u({credentialValue:k.target.value,allowMissingCredential:k.target.value?!1:a.allowMissingCredential})}),c.jsx("button",{type:"button",className:"nc-btn ghost","aria-label":m(a.credentialReveal?"fleet-key-hide":"fleet-key-reveal"),onClick:()=>u({credentialReveal:!a.credentialReveal}),children:m(a.credentialReveal?"fleet-key-hide":"fleet-key-reveal")})]}),c.jsx("small",{children:m("fleet-key-local-help")}),e.mode==="new"&&(v==null?void 0:v.authConfigured)!==!0&&!a.credentialValue&&c.jsxs("label",{className:"nc-check nc-fleet-key-missing",children:[c.jsx("input",{type:"checkbox",checked:!!a.allowMissingCredential,onChange:k=>u({allowMissingCredential:k.target.checked})}),m("fleet-key-create-missing")]}),(v==null?void 0:v.notice)&&c.jsx("small",{className:"nc-fleet-provider-notice",children:m(`fleet-provider-notice-${v.notice}`)})]}),a.provider==="custom"&&c.jsxs(c.Fragment,{children:[c.jsx("input",{value:a.displayName,placeholder:m("fleet-provider-display"),onChange:k=>u({displayName:k.target.value})}),c.jsx("input",{value:a.baseUrl,placeholder:"https://api.example.com/v1",onChange:k=>u({baseUrl:k.target.value})}),((v==null?void 0:v.protocols)||[]).length>1&&c.jsx("select",{value:a.protocol,onChange:k=>u({protocol:k.target.value}),children:v.protocols.map(k=>c.jsx("option",{value:k,children:k},k))}),c.jsxs("div",{className:"nc-fleet-pair",children:[c.jsx("input",{value:a.envKey,placeholder:m("fleet-api-key-env"),onChange:k=>u({envKey:k.target.value})}),c.jsx("input",{value:a.providerId,placeholder:m("fleet-provider-id"),onChange:k=>u({providerId:k.target.value})})]}),c.jsxs("small",{children:[a.protocol," · ",m("fleet-custom-secret-help")]})]}),c.jsx("small",{children:m(a.client==="shell"?"fleet-shell-engine-help":"fleet-managed-help")})]}):c.jsxs(c.Fragment,{children:[c.jsx("input",{value:a.command,placeholder:m("command-path"),onChange:k=>u({command:k.target.value})}),c.jsx("textarea",{value:a.argsText,placeholder:m("args-lines"),onChange:k=>u({argsText:k.target.value})}),c.jsxs("label",{className:"nc-check",children:[c.jsx("input",{type:"checkbox",checked:a.rc,onChange:k=>u({rc:k.target.checked})})," remote control"]}),c.jsxs("select",{value:a.promptMode,onChange:k=>u({promptMode:k.target.value}),children:[c.jsx("option",{value:"send-keys",children:"send-keys"}),c.jsx("option",{value:"flag",children:"flag"})]}),a.promptMode==="flag"&&c.jsx("input",{value:a.promptFlag,placeholder:"prompt flag",onChange:k=>u({promptFlag:k.target.value})}),c.jsxs("div",{className:"nc-fleet-pair",children:[c.jsx("input",{value:a.modelFlag,placeholder:"model flag",onChange:k=>u({modelFlag:k.target.value})}),c.jsx("input",{value:a.modelValue,placeholder:"model default",onChange:k=>u({modelValue:k.target.value})})]}),c.jsx("small",{children:m("env-write-only")}),h.map((k,$)=>c.jsxs("div",{className:"nc-fleet-env",children:[c.jsx("input",{value:k.key,disabled:k.configured,placeholder:"ENV_KEY",onChange:O=>{const V=h.slice();V[$]={...k,key:O.target.value},u({envRows:V})}}),c.jsx("input",{type:"password",value:k.value,placeholder:k.configured?"•••••• (unchanged)":"value",onChange:O=>{const V=h.slice();V[$]={...k,value:O.target.value},u({envRows:V})}}),c.jsx("button",{className:"nc-btn danger",onClick:()=>u({envRows:h.filter((O,V)=>V!==$)}),children:"×"})]},`${k.key}-${$}`)),c.jsx("button",{className:"nc-btn ghost",onClick:()=>u({envRows:[...h,{key:"",value:"",configured:!1}]}),children:"+ env"})]}),c.jsxs("div",{className:"nc-sheet-actions",children:[c.jsx("button",{className:"nc-btn ghost",onClick:()=>t(null),children:m("cancel")}),c.jsx("button",{className:"nc-btn primary",disabled:n||!a.id||x||a.kind==="custom"&&!a.command||a.kind==="managed"&&(v==null?void 0:v.requiresModel)&&!a.managedModel||a.kind==="managed"&&(v==null?void 0:v.credentialEnv)===!0&&!a.envKey||a.kind==="managed"&&a.provider==="custom"&&(!a.displayName||!a.baseUrl||!a.envKey||!a.providerId),onClick:s,children:m("save")})]})]})}function vN({token:e,route:t,targets:n=[],location:s,setLocation:o,state:a,setState:u,engines:h,busy:f,onSave:p}){var Y;const[v,b]=E.useState(null),[w,S]=E.useState(""),y=a.form,x=z=>u({...a,form:{...y,...z}}),C=h.find(z=>z.id===y.engine),R=((Y=C==null?void 0:C.managed)==null?void 0:Y.client)==="shell",k=z=>{var X,I,A,N;const ne=h.find(M=>M.id===z),H={...y.commands||{}};((X=C==null?void 0:C.managed)==null?void 0:X.client)==="shell"&&(y.command?H[y.engine]=y.command:delete H[y.engine]),x({engine:z,model:((I=y.models)==null?void 0:I[z])||((A=ne==null?void 0:ne.managed)==null?void 0:A.model)||((N=ne==null?void 0:ne.model)==null?void 0:N.value)||"",commands:H,command:H[z]||""})},$=z=>{const ne={...y.commands||{}};z?ne[y.engine]=z:delete ne[y.engine],x({command:z,commands:ne})},O=R&&/[|&;<>()`$*?{}\[\]~]/.test(y.command||""),V=async z=>{try{const ne=await Oh(e,z,t);b(ne),x({cwd:ne.path}),S("")}catch(ne){S(String(ne.message||ne))}};return c.jsxs("div",{className:"nc-set-form nc-fleet-form",children:[c.jsx("b",{children:a.mode==="new"?m("fleet-new-cell"):`${m("edit")} ${y.id}`}),a.mode==="new"&&c.jsxs("label",{className:"nc-field",children:[m("location"),c.jsx("span",{className:"nc-req",children:" *"}),c.jsxs("select",{value:s,onChange:z=>{o(z.target.value),x({engine:""})},children:[c.jsx("option",{value:"",children:m("local")}),n.map(z=>c.jsxs("option",{value:z.route.join("/"),disabled:z.status&&z.status!=="up",children:[z.label,z.status&&z.status!=="up"?` · ${m("node-offline")}`:""]},z.route.join("/")))]})]}),c.jsx("input",{value:y.id,disabled:a.mode!=="new",placeholder:"id",onChange:z=>x({id:z.target.value})}),c.jsxs("div",{className:"nc-fleet-pair",children:[c.jsx("input",{value:y.cwd,placeholder:m("cwd"),onChange:z=>x({cwd:z.target.value})}),c.jsx("button",{className:"nc-btn ghost",onClick:()=>v?b(null):V(y.cwd),children:m("browse")})]}),v&&c.jsxs("div",{className:"nc-fs",children:[c.jsx("div",{className:"nc-fs-path",children:v.path}),c.jsxs("div",{className:"nc-fs-list",children:[v.parent&&c.jsxs("button",{className:"nc-fs-item nc-fs-nav",onClick:()=>V(v.parent),children:["↑ ",m("fs-parent")]}),(v.dirs||[]).map(z=>c.jsxs("button",{className:"nc-fs-item",onClick:()=>V(`${v.path.replace(/\/$/,"")}/${z}`),children:["📁 ",z]},z))]})]}),w&&c.jsx("div",{className:"nc-err",children:w}),c.jsx("select",{value:y.engine,onChange:z=>k(z.target.value),children:h.map(z=>c.jsx("option",{value:z.id,children:z.label},z.id))}),c.jsxs("label",{className:"nc-check",children:[c.jsx("input",{type:"checkbox",checked:!!y.boot,onChange:z=>x({boot:z.target.checked})})," boot"]}),R?c.jsxs(c.Fragment,{children:[c.jsx("input",{value:y.command||"",maxLength:4096,placeholder:m("fleet-shell-command-placeholder"),onChange:z=>$(z.target.value)}),c.jsx("small",{children:y.command?m("fleet-shell-command-help"):m("fleet-shell-interactive")}),O&&c.jsx("small",{className:"nc-note",children:m("fleet-shell-command-metachar")})]}):c.jsxs(c.Fragment,{children:[c.jsx("input",{value:y.model||"",list:"nc-cell-models",placeholder:m("fleet-model-override"),onChange:z=>x({model:z.target.value})}),c.jsx("datalist",{id:"nc-cell-models",children:((C==null?void 0:C.availableModels)||[]).map(z=>c.jsx("option",{value:z},z))}),c.jsx("textarea",{value:y.prompt||"",placeholder:"prompt",onChange:z=>x({prompt:z.target.value})})]}),c.jsxs("div",{className:"nc-sheet-actions",children:[c.jsx("button",{className:"nc-btn ghost",onClick:()=>u(null),children:m("cancel")}),c.jsx("button",{className:"nc-btn primary",disabled:f||!y.id||!y.cwd||!y.engine,onClick:p,children:m("save")})]})]})}function C_({token:e,route:t=[],state:n,setState:s,busy:o,onSave:a}){const[u,h]=E.useState(null),[f,p]=E.useState([]),[v,b]=E.useState(""),w=Array.isArray(t)?t.join("/"):"";E.useEffect(()=>{let R=!0;return Ih(e,w?w.split("/"):[]).then(k=>{R&&(p(k.engines||[]),b(""))}).catch(k=>{R&&(p([]),b(String(k.message||k)))}),()=>{R=!1}},[e,w]);const S=n.form,y=R=>s({...n,form:{...S,...R}}),x=async R=>{try{const k=await Oh(e,R,t);h(k),y({cwd:k.path})}catch{}},C=!S.id&&S.tmuxSession?S.tmuxSession.replace(/[^A-Za-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"").slice(0,32):S.id;return c.jsxs("div",{className:"nc-set-form nc-fleet-form",children:[c.jsxs("b",{children:[m("import-as-cell")," · ",S.tmuxSession]}),c.jsx("small",{children:m("import-help")}),c.jsx("input",{value:S.tmuxSession,disabled:!0,placeholder:"tmux session",readOnly:!0}),c.jsx("input",{value:S.id,placeholder:m("name"),onChange:R=>y({id:R.target.value})}),c.jsxs("div",{className:"nc-fleet-pair",children:[c.jsx("input",{value:S.cwd,placeholder:m("cwd"),onChange:R=>y({cwd:R.target.value})}),c.jsx("button",{className:"nc-btn ghost",type:"button",onClick:()=>u?h(null):x(S.cwd),children:m("browse")})]}),u&&c.jsxs("div",{className:"nc-fs",children:[c.jsx("div",{className:"nc-fs-path",children:u.path}),c.jsxs("div",{className:"nc-fs-list",children:[u.parent&&c.jsxs("button",{className:"nc-fs-item nc-fs-nav",onClick:()=>x(u.parent),children:["↑ ",m("fs-parent")]}),(u.dirs||[]).map(R=>c.jsxs("button",{className:"nc-fs-item",onClick:()=>x(`${u.path.replace(/\/$/,"")}/${R}`),children:["📁 ",R]},R))]})]}),c.jsxs("select",{value:S.engine,onChange:R=>y({engine:R.target.value}),children:[c.jsx("option",{value:"",children:m("import-engine-required")}),f.map(R=>c.jsx("option",{value:R.id,children:R.label},R.id))]}),c.jsxs("label",{className:"nc-check",children:[c.jsx("input",{type:"checkbox",checked:!!S.boot,onChange:R=>y({boot:R.target.checked})})," boot"]}),(n.err||v)&&c.jsx("div",{className:"nc-err",children:n.err||v}),c.jsxs("div",{className:"nc-sheet-actions",children:[c.jsx("button",{className:"nc-btn ghost",onClick:()=>s(null),children:m("cancel")}),c.jsx("button",{className:"nc-btn primary",disabled:o||!S.tmuxSession||!S.engine||!f.length,onClick:a,children:m(C?"import-as-cell":"save")})]})]})}function ml(e){const t=Os(e);return t===null?`~/${e}`:t?`~/${t}`:"~"}function _N(e){if(!e||typeof e.path!="string"||typeof e.home!="string")return"";const{path:t,home:n}=e;return!n||t===n||!t.startsWith(n+"/")?"":t.slice(n.length+1).replace(/\/+$/,"")}function yN({token:e,route:t,cell:n,busy:s=!1,onSaved:o,onClose:a}){const[u,h]=E.useState(""),[f,p]=E.useState(null),[v,b]=E.useState(!1),[w,S]=E.useState(""),y=typeof(n==null?void 0:n.cwdSuggestion)=="string"&&Os(n.cwdSuggestion)!==null?Os(n.cwdSuggestion):null,[x,C]=E.useState(y),R=n==null?void 0:n.id,k=s||v,$=async H=>{const X=Os(H);if(X===null){p({rel:"",dirs:[],loading:!1,err:m("fleet-cwd-repair-invalid")});return}p({rel:X,dirs:[],loading:!0,err:""});try{const I=await Oh(e,X,t),A=_N(I);p({rel:A,dirs:Array.isArray(I.dirs)?I.dirs:[],loading:!1,err:""})}catch(I){p({rel:X,dirs:[],loading:!1,err:String(I&&I.message||I)})}},O=H=>{if(!f)return;const X=f.rel?`${f.rel}/${H}`:H;$(X)},V=()=>{f!=null&&f.rel&&$(f.rel.split("/").slice(0,-1).join("/"))},Y=()=>{f&&(h(f.rel||""),p(null),S(""),C(null))},z=()=>{x!==null&&(h(x),C(null),S(""))},ne=async()=>{if(k)return;const H=Os(u);if(H===null){S(m("fleet-cwd-repair-invalid"));return}const X=ml(H);let I=!0;try{I=window.confirm(m("fleet-cwd-repair-confirm").replace("{id}",String(R||"")).replace("{path}",X))}catch{I=!1}if(I){b(!0),S(""),C(null);try{const A=await z_(e,R,{cwdRel:H},t);o==null||o(A)}catch(A){const N=A&&A.data||{};if(N.code==="unportable-cwd"){S(m("fleet-cwd-repair-unportable"));const M=Array.isArray(N.cells)?N.cells.find(P=>P&&P.id===R):null,L=M&&typeof M.suggestion=="string"?M.suggestion:null;L!==null&&Os(L)!==null&&C(L)}else S(String(A&&A.message||A))}finally{b(!1)}}};return c.jsxs("div",{className:"nc-set-form nc-fleet-form nc-cwd-repair",children:[c.jsx("b",{children:m("fleet-cwd-repair-title").replace("{id}",String(R||""))}),c.jsx("small",{className:"nc-set-info",children:m("fleet-cwd-repair-help")}),c.jsx("small",{className:"nc-cwd-no-source",children:m("fleet-cwd-repair-no-source-path")}),c.jsxs("label",{className:"nc-field",children:[m("cwd"),c.jsxs("div",{className:"nc-cwd-rel-row",children:[c.jsx("span",{className:"nc-cwd-rel-prefix",children:"~/"}),c.jsx("input",{value:u,placeholder:m("fleet-cwd-repair-placeholder"),autoComplete:"off",spellCheck:"false",autoCapitalize:"none",onChange:H=>h(H.target.value)}),c.jsx("button",{type:"button",className:"nc-btn ghost",disabled:k,onClick:()=>f?p(null):$(""),children:m(f?"close":"fleet-cwd-repair-browse")})]})]}),c.jsx("div",{className:"nc-cwd-preview",children:m("fleet-cwd-repair-preview").replace("{path}",ml(u))}),f&&c.jsxs("div",{className:"nc-fs",children:[c.jsx("div",{className:"nc-fs-path",children:ml(f.rel)}),c.jsxs("div",{className:"nc-fs-list",children:[f.rel&&c.jsxs("button",{type:"button",className:"nc-fs-item nc-fs-nav",onClick:V,children:["↑ ",m("fs-parent")]}),f.loading&&c.jsx("div",{className:"nc-fs-empty",children:"…"}),!f.loading&&f.dirs.length===0&&c.jsx("div",{className:"nc-fs-empty",children:m("fleet-cwd-repair-fs-empty")}),!f.loading&&f.dirs.map(H=>c.jsxs("button",{type:"button",className:"nc-fs-item",onClick:()=>O(H),children:["📁 ",H]},H))]}),f.err&&c.jsx("div",{className:"nc-err",children:f.err}),c.jsx("div",{className:"nc-sheet-actions",children:c.jsx("button",{type:"button",className:"nc-btn primary",disabled:k||f.loading||!!f.err,onClick:Y,children:m("fleet-cwd-repair-use-current")})})]}),w&&c.jsx("div",{className:"nc-err",role:"alert",children:w}),x!==null&&c.jsxs("div",{className:"nc-cwd-suggestion",role:"status",children:[c.jsx("span",{children:m("fleet-cwd-repair-suggestion")}),c.jsx("button",{type:"button",className:"nc-btn ghost",onClick:z,children:m("fleet-cwd-repair-use-suggestion").replace("{path}",ml(x))})]}),c.jsxs("div",{className:"nc-sheet-actions",children:[c.jsx("button",{type:"button",className:"nc-btn ghost",disabled:v,onClick:a,children:m("cancel")}),c.jsx("button",{type:"button",className:"nc-btn primary",disabled:k,onClick:ne,children:v?"…":m("save")})]})]})}function wN({token:e,readonly:t,targets:n=[],startNewCell:s=!1,initialLocation:o=""}){const[a,u]=E.useState({engines:[],cells:[],managedCatalog:[]}),[h,f]=E.useState({available:!1,capabilities:[]}),[p,v]=E.useState(!1),[b,w]=E.useState(null),[S,y]=E.useState(null),[x,C]=E.useState(!1),[R,k]=E.useState(""),[$,O]=E.useState(""),[V,Y]=E.useState(o),[z,ne]=E.useState(!1),[H,X]=E.useState(null),[I,A]=E.useState(null),[N,M]=E.useState(null),[L,P]=E.useState(!1),[F,T]=E.useState([]),[q,B]=E.useState(null),[D,U]=E.useState("manage"),Z=E.useRef(!1),oe=V?V.split("/"):[],de=E.useCallback(async()=>{try{const le=await _s(e,oe);f(le);try{const xe=await Fh(e,oe);ne(!!xe.readonlyDefault)}catch{ne(!1)}if(le.provider==="builtin"&&(le.capabilities||[]).includes("definitions")){const xe=await Ih(e,oe),ze=new Map((le.engines||[]).map(Ie=>[Ie.id,Ie]));if(xe.engines=(xe.engines||[]).map(Ie=>{var ue;return{...Ie,availableModels:((ue=ze.get(Ie.id))==null?void 0:ue.models)||[]}}),u(xe),(le.capabilities||[]).includes("credentials"))try{T((await n0(e,oe)).credentials||[])}catch{T([])}else T([])}k("")}catch(le){k(String(le.message||le))}finally{v(!0)}},[e,V]);E.useEffect(()=>{de();const le=setInterval(de,5e3);return()=>clearInterval(le)},[de]);const fe=new Set((h.cells||[]).filter(le=>le.active).map(le=>le.cell)),J=h.provider==="builtin"&&(h.capabilities||[]).includes("edit"),ee=(h.capabilities||[]).includes("restore");E.useEffect(()=>{!s||Z.current||!J||!a.engines.length||(Z.current=!0,y({mode:"new",form:k_(a.engines[0].id)}))},[s,J,a.engines]);const pe=async le=>{C(!0),k(""),O("");try{await le(),await de()}catch(xe){k(String(xe.message||xe))}C(!1)},Se=()=>pe(async()=>{var Re;const le=b.mode==="new",xe=b.form,ze=a.managedCatalog||[],Ie=xe.kind==="managed"?$o(ze,xe):null,ue=typeof(Ie==null?void 0:Ie.credentialEnv)=="string"?Ie.credentialEnv:"",G=ue&&xe.credentialValue||"",ie=pN(xe,le,ze);!le&&b.form.kind==="custom"&&!b.form.modelFlag&&(ie.model=null),!le&&b.form.kind==="custom"&&b.form.promptMode!=="flag"&&(ie.promptFlag=null);let W;if(le)W=await s0(e,ie,oe);else{const we=b.original,je=new Set(b.form.envRows.filter(Oe=>!Oe.remove).map(Oe=>Oe.key)),st=(we.envKeys||[]).filter(Oe=>!je.has(Oe)),It=Object.fromEntries(b.form.envRows.filter(Oe=>!Oe.remove&&Oe.key&&(!Oe.configured||Oe.value!=="")).map(Oe=>[Oe.key,Oe.value]));W=await r0(e,we.id,ie,b.form.kind==="custom"?{set:It,remove:st}:void 0,oe)}let se=null;if(ue&&G)try{se=await og(e,ue,G,oe),T(se.credentials||[])}catch{throw await de(),le&&w({mode:"edit",original:{...ie,id:xe.id},form:{...xe,credentialReveal:!1}}),new Error(m(le?"fleet-key-partial-create":"fleet-key-partial-edit"))}await de(),w(null),O(m("fleet-saved"));const ve=((Re=((se==null?void 0:se.credentials)||[]).find(we=>we.envKey===ue))==null?void 0:Re.activeCells)||[],ke=[...new Set([...(W==null?void 0:W.activeCells)||[],...ve])];if(ke.length&&window.confirm(m("fleet-restart-confirm").replace("{cells}",ke.join(", "))))for(const we of ke)await jo(e,we,oe)}),Ze=()=>pe(async()=>{var W,se,ve,ke,Re,we;const le=S.mode==="new",xe=S.form,ze={...le?{id:xe.id}:{},cwd:xe.cwd,engine:xe.engine,boot:!!xe.boot},Ie={...xe.commands||{}},ue=a.engines.find(je=>je.id===xe.engine);((W=ue==null?void 0:ue.managed)==null?void 0:W.client)==="shell"&&typeof xe.command=="string"&&xe.command.length?Ie[xe.engine]=xe.command:((se=ue==null?void 0:ue.managed)==null?void 0:se.client)==="shell"&&delete Ie[xe.engine],(Object.keys(Ie).length||!le)&&(ze.commands=Ie),le?(((ve=ue==null?void 0:ue.managed)==null?void 0:ve.client)!=="shell"&&xe.model&&(ze.model=xe.model),((ke=ue==null?void 0:ue.managed)==null?void 0:ke.client)!=="shell"&&xe.prompt&&(ze.prompt=xe.prompt)):(ze.model=((Re=ue==null?void 0:ue.managed)==null?void 0:Re.client)==="shell"?null:xe.model||null,((we=ue==null?void 0:ue.managed)==null?void 0:we.client)!=="shell"&&(ze.prompt=xe.prompt||null));const G=le?await a0(e,ze,oe):await z_(e,S.original.id,ze,oe),ie=le?xe.id:S.original.id;y(null),O(m("fleet-saved")),!le&&(G!=null&&G.active)&&window.confirm(m("fleet-restart-confirm").replace("{cells}",ie))&&await jo(e,ie,oe)}),$e=t||z,He=le=>F.find(xe=>{var ze;return(ze=xe.engines)==null?void 0:ze.includes(le.id)})||null,vt=()=>pe(async()=>{var ze;const le=await og(e,q.envKey,q.value,oe);T(le.credentials||[]),B(null),O(m("fleet-credential-saved"));const xe=((ze=(le.credentials||[]).find(Ie=>Ie.envKey===q.envKey))==null?void 0:ze.activeCells)||[];if(xe.length&&window.confirm(m("fleet-restart-confirm").replace("{cells}",xe.join(", "))))for(const Ie of xe)await jo(e,Ie,oe)}),Xe=le=>pe(async()=>{if(!window.confirm(m("fleet-credential-remove-confirm").replace("{key}",le.envKey)))return;const xe=await i0(e,le.envKey,oe);T(xe.credentials||[]),O(m("fleet-credential-removed"))}),St=le=>X({...le,route:Array.isArray(le==null?void 0:le.route)?le.route:oe}),Et=async le=>{if(!H)return;const xe=H.cell||H.id,ze=Array.isArray(H.route)?H.route:oe;le.action==="up"?await Ah(e,{cell:xe,boot:!!le.boot,...le.engine?{engine:le.engine}:{},...le.model!==void 0?{model:le.model}:{},...le.permissionPolicy?{permissionPolicy:le.permissionPolicy}:{}},ze):await Cl(e,{cell:xe,boot:!!le.boot},ze)},rt=(le,xe)=>{k(""),A({mode:"new",route:Array.isArray(xe)?xe:oe,form:{tmuxSession:le.name,id:"",engine:"",cwd:"",boot:!1},err:""})},ct=()=>pe(async()=>{const le=I.form;if(!le.engine){A({...I,err:m("import-engine-required")});return}await l0(e,{tmuxSession:le.tmuxSession,id:le.id||void 0,engine:le.engine,cwd:le.cwd||void 0,boot:!!le.boot},le.route||oe),A(null),O(m("fleet-saved"))}),ot=({engineRows:le=[],cellRows:xe=[]})=>pe(async()=>{const ze=le.filter(Re=>Re.selected),Ie=ze.map(Re=>Fw(Re.engine));if(Ie.some(Re=>!Re))throw new Error(m("fleet-backup-invalid-engine"));const ue=ze.filter(Re=>Re.exists).map(Re=>Re.engine.id);if(ue.length&&!window.confirm(m("fleet-backup-confirm-engine-overwrite").replace("{engines}",ue.join(", "))))return;const G=[...new Set([...a.engines.map(Re=>Re.id),...Ie.map(Re=>Re.id)])],ie=[];for(const Re of xe.filter(we=>we.selected)){const we=uN(Re.cell,Re.engine,G);if(!we)throw new Error(`${Re.cell.id}: ${m("fleet-backup-engine-missing")}`);ie.push(we)}const W=xe.filter(Re=>Re.selected&&Re.exists).map(Re=>Re.cell.id);if(W.length&&!window.confirm(m("fleet-backup-confirm-overwrite").replace("{cells}",W.join(", "))))return;const se=Ie.length?await u0(e,Ie,ue.length>0,oe):{needsRestart:[]},ve=ie.length?await c0(e,ie,oe):{needsRestart:[]},ke=[...new Set([...se.needsRestart||[],...ve.needsRestart||[]])];P(!1),O(`${m("fleet-backup-restored").replace("{n}",String(ie.length))}${Ie.length?` · ${Ie.length} ${m("fleet-engines").toLowerCase()}`:""}${ke.length?` · ${m("fleet-backup-needs-restart").replace("{cells}",ke.join(", "))}`:""}`)}),ut=c.jsxs("label",{className:"nc-field",children:[m("location"),c.jsxs("select",{value:V,onChange:le=>{Y(le.target.value),w(null),y(null),k(""),O(""),ne(!1),v(!1),f({available:!1,capabilities:[]}),u({engines:[],cells:[],managedCatalog:[]}),T([]),B(null)},children:[c.jsx("option",{value:"",children:m("local")}),n.map(le=>c.jsxs("option",{value:le.route.join("/"),disabled:le.status&&le.status!=="up",children:[le.label,le.status&&le.status!=="up"?` · ${m("node-offline")}`:""]},le.route.join("/")))]})]}),dt=c.jsxs("div",{className:"nc-fleet-view-tabs",role:"tablist","aria-label":m("tab-fleet"),children:[c.jsx("button",{type:"button",role:"tab","aria-selected":D==="manage",className:`nc-set-tabbtn${D==="manage"?" on":""}`,onClick:()=>U("manage"),children:m("fleet-manage-location")}),c.jsx("button",{type:"button",role:"tab","aria-selected":D==="overview",className:`nc-set-tabbtn${D==="overview"?" on":""}`,onClick:()=>U("overview"),children:m("fleet-network-overview")})]});return p?J?c.jsxs("div",{className:"nc-set-tab nc-fleet-editor",children:[dt,D==="overview"?c.jsxs(c.Fragment,{children:[c.jsx("div",{className:"nc-set-info",children:m("fleet-overview-help")}),c.jsx(Nd,{token:e,targets:n,readonly:t,onPower:St,onImport:rt})]}):c.jsxs(c.Fragment,{children:[c.jsx("div",{className:"nc-set-info",children:m("fleet-manage-help")}),ut,c.jsxs("div",{className:"nc-set-row nc-fleet-backup-actions",children:[c.jsx("button",{className:"nc-btn ghost",disabled:$e||x,onClick:()=>{k(""),P(!0)},children:m("fleet-backup")}),c.jsx("small",{children:m("fleet-backup-help")})]}),c.jsxs("div",{className:"nc-fleet-section-head",children:[c.jsx("b",{children:m("fleet-cells")}),c.jsx("span",{className:"nc-fleet-head-actions",children:c.jsxs("button",{className:"nc-btn primary",disabled:$e||x||!a.engines.length,onClick:()=>{var le;k(""),y({mode:"new",form:k_((le=a.engines[0])==null?void 0:le.id)})},children:["+ ",m("add")]})})]}),a.cells.map(le=>{const xe=fe.has(le.id),ze=h.capabilities||[],Ie=le.needsRepair===!0;return c.jsxs("div",{className:"nc-fleet-item",children:[c.jsxs("span",{children:[c.jsx("b",{children:le.id}),c.jsxs("small",{children:[le.engine," · ",Ie?c.jsx("span",{className:"nc-fleet-tag nc-fleet-tag-warn",children:m("fleet-cwd-needs-repair")}):le.cwd,xe?` · ${m("service-active")}`:` · ${m("cell-off")}`]})]}),c.jsxs("span",{children:[xe&&ze.includes("down")&&c.jsx("button",{className:"nc-btn ghost",disabled:$e||x,onClick:()=>pe(()=>Cl(e,{cell:le.id},oe)),children:m("stop")}),!xe&&ze.includes("up")&&c.jsx("button",{className:"nc-btn primary",disabled:$e||x,onClick:()=>St({cell:le.id,id:le.id,engine:le.engine,model:le.model,models:le.models,permissionPolicies:le.permissionPolicies,active:!1,boot:le.boot}),children:m("start")}),xe&&ze.includes("restart")&&c.jsx("button",{className:"nc-btn ghost",disabled:$e||x,onClick:()=>pe(()=>jo(e,le.id,oe)),children:m("restart")}),Ie?c.jsx("button",{className:"nc-btn ghost",disabled:$e||x,onClick:()=>{k(""),M(le)},children:m("fleet-cwd-repair")}):c.jsx("button",{className:"nc-btn ghost",disabled:$e||x,onClick:()=>{var ue;k(""),y({mode:"edit",original:le,form:{...le,commands:{...le.commands||{}},command:((ue=le.commands)==null?void 0:ue[le.engine])||""}})},children:m("edit")}),c.jsx("button",{className:"nc-btn danger",disabled:$e||x,onClick:()=>pe(async()=>{window.confirm(m("fleet-remove-cell").replace("{id}",le.id))&&await F_(e,le.id,!0,oe)}),children:"×"})]})]},le.id)}),c.jsxs("div",{className:"nc-fleet-section-head",children:[c.jsx("b",{children:m("fleet-engines")}),c.jsxs("button",{className:"nc-btn primary",disabled:$e||x,onClick:()=>{k(""),w({mode:"new",form:dN()})},children:["+ ",m("add")]})]}),a.engines.map(le=>{var ze,Ie;const xe=He(le);return c.jsxs("div",{className:"nc-fleet-item",children:[c.jsxs("span",{children:[c.jsx("b",{children:le.label}),c.jsx("small",{children:le.managed?`${le.id} · ${le.managed.client} / ${le.managed.provider} · ${(ze=le.managedInfo)!=null&&ze.configured?m("fleet-ready"):((Ie=le.managedInfo)==null?void 0:Ie.reason)||m("fleet-not-ready")}`:`${le.id} · ${le.command}`}),xe&&c.jsxs("small",{children:[xe.envKey," · ",m(`fleet-credential-source-${xe.source||"missing"}`)]})]}),c.jsxs("span",{children:[xe&&c.jsx("button",{className:"nc-btn ghost",disabled:$e||x,onClick:()=>{k(""),B({envKey:xe.envKey,value:""})},children:xe.configured?m("fleet-credential-change"):m("fleet-credential-set")}),(xe==null?void 0:xe.source)==="local"&&c.jsx("button",{className:"nc-btn danger",disabled:$e||x,onClick:()=>Xe(xe),children:m("fleet-credential-forget")}),c.jsx("button",{className:"nc-btn ghost",disabled:$e||x,onClick:()=>{k(""),w({mode:"edit",original:le,form:fN(le)})},children:m("edit")}),c.jsx("button",{className:"nc-btn danger",disabled:$e||x,onClick:()=>pe(async()=>{window.confirm(m("fleet-remove-engine").replace("{id}",le.id))&&await o0(e,le.id,oe)}),children:"×"})]})]},le.id)})]}),b&&c.jsx(Ms,{onClose:()=>w(null),label:m("fleet-new-engine"),error:R,children:c.jsx(gN,{state:b,setState:w,busy:x,onSave:Se,catalog:a.managedCatalog||[]})}),S&&c.jsx(Ms,{onClose:()=>y(null),label:m("fleet-new-cell"),error:R,children:c.jsx(vN,{token:e,route:oe,targets:n,location:V,setLocation:Y,state:S,setState:y,engines:a.engines,busy:x,onSave:Ze})}),N&&c.jsx(Ms,{onClose:()=>M(null),label:m("fleet-cwd-repair-title").replace("{id}",N.id),error:"",children:c.jsx(yN,{token:e,route:oe,cell:N,busy:x,onSaved:async()=>{M(null),O(m("fleet-cwd-repaired")),await de()},onClose:()=>M(null)})}),$&&c.jsx("div",{className:"nc-set-note",children:$}),R&&c.jsx("div",{className:"nc-err",children:R}),L&&c.jsx(Ms,{onClose:()=>P(!1),label:m("fleet-backup"),error:R,children:c.jsx(mN,{cells:a.cells,engines:a.engines,busy:x,canRestore:ee,onRestore:ot,onClose:()=>P(!1)})}),q&&c.jsx(Ms,{onClose:()=>B(null),label:m("fleet-credential-title"),error:R,children:c.jsxs("div",{className:"nc-fleet-form nc-credential-form",children:[c.jsx("b",{children:m("fleet-credential-title")}),c.jsx("small",{children:m("fleet-credential-help")}),c.jsxs("label",{className:"nc-field",children:[q.envKey,c.jsx("input",{type:"password",autoComplete:"off",spellCheck:"false",autoCapitalize:"none",value:q.value,onChange:le=>B({...q,value:le.target.value})})]}),c.jsxs("div",{className:"nc-sheet-actions",children:[c.jsx("button",{className:"nc-btn ghost",onClick:()=>B(null),children:m("cancel")}),c.jsx("button",{className:"nc-btn primary",disabled:x||!q.value,onClick:vt,children:m("save")})]})]})}),I&&c.jsx(Ms,{onClose:()=>A(null),label:m("import-as-cell"),error:R,children:c.jsx(C_,{token:e,route:I.route||oe,state:I,setState:A,busy:x,onSave:ct})}),H&&c.jsx(Nl,{cell:H,token:e,route:Array.isArray(H.route)?H.route:oe,onConfirm:async le=>{try{await Et(le)}finally{await de()}},onClose:()=>X(null)})]}):c.jsxs("div",{className:"nc-set-tab",children:[dt,D==="overview"?c.jsxs(c.Fragment,{children:[c.jsx("div",{className:"nc-set-info",children:m("fleet-overview-help")}),c.jsx(Nd,{token:e,targets:n,readonly:t,onPower:St,onImport:rt})]}):c.jsxs(c.Fragment,{children:[ut,c.jsxs("div",{className:"nc-set-info",children:[m(R?"fleet-editor-load-error":"fleet-editor-unavailable"),!R&&h.reason?` ${h.reason}`:""]})]}),R&&c.jsx("div",{className:"nc-err",children:R}),I&&c.jsx(Ms,{onClose:()=>A(null),label:m("import-as-cell"),error:R,children:c.jsx(C_,{token:e,route:I.route||oe,state:I,setState:A,busy:x,onSave:ct})}),H&&c.jsx(Nl,{cell:H,token:e,route:Array.isArray(H.route)?H.route:oe,onConfirm:async le=>{try{await Et(le)}finally{await de()}},onClose:()=>X(null)})]}):c.jsxs("div",{className:"nc-set-tab",children:[dt,D==="overview"?c.jsxs(c.Fragment,{children:[c.jsx("div",{className:"nc-set-info",children:m("fleet-overview-help")}),c.jsx(Nd,{token:e,targets:n,readonly:t,onPower:St,onImport:rt})]}):c.jsxs(c.Fragment,{children:[ut,c.jsx("div",{className:"nc-set-info",children:m("fleet-editor-loading")})]})]})}const bf="nc_notification_speech_v1",gl="nc-notification-speech",Nh="nc-notification-speech-preview",SN=320,bN=2,xN=3e4,kN=1e4,CN=6e4,EN=64,E_=Object.freeze({enabled:!1}),NN=Object.freeze({it:"it-IT",en:"en-US",es:"es-ES"}),RN=Object.freeze({it:new Set(["che","con","correzione","della","delle","difetto","il","lavoro","nessun","non","per","pronto","pubblicata","pubblicato","rilascio","sono","stato","tutti","verificata","verificato","versione","completata","completato","riepilogo"]),en:new Set(["all","and","completed","fix","for","issue","no","published","ready","release","summary","the","verified","version","with","work"]),es:new Set(["con","correccion","defecto","el","esta","para","publicada","publicado","resumen","sin","todos","trabajo","verificada","verificado","version","y"])}),xf=new WeakSet;function kf(e){return{enabled:(e&&typeof e=="object"&&!Array.isArray(e)?e:{}).enabled===!0}}function Hw(){try{return typeof localStorage<"u"?localStorage:null}catch{return null}}function N_(e=Hw()){if(!e)return{...E_};try{return kf(JSON.parse(e.getItem(bf)||"null"))}catch{return{...E_}}}function jN(e,t=Hw()){const n=kf(e);if(t)try{t.setItem(bf,JSON.stringify(n))}catch{}return n}function Br(){try{return typeof window<"u"?window:null}catch{return null}}function Ho(e=Br()){try{return!!(e&&e.speechSynthesis&&typeof e.speechSynthesis.speak=="function"&&typeof e.SpeechSynthesisUtterance=="function")}catch{return!1}}function Ww(e=Br()){return!!(e&&(typeof e=="object"||typeof e=="function")&&xf.has(e))}function Rh(e=Br()){e&&(typeof e=="object"||typeof e=="function")&&xf.delete(e)}function Er(e){const t=String(e||"").trim().toLowerCase().split("-")[0];return NN[t]||""}function Zl(e){return String(e||"").normalize("NFC").replace(/[\p{Cc}\p{Cf}]+/gu," ").replace(/\s+/g," ").trim()}function PN(e){const t=Zl(e).normalize("NFD").replace(new RegExp("\\p{M}+","gu"),"").toLowerCase(),n=new Set(t.match(new RegExp("\\p{L}+","gu"))||[]);if(n.size<4)return"";const s=Object.entries(RN).map(([o,a])=>({lang:o,score:[...n].reduce((u,h)=>u+(a.has(h)?1:0),0)})).sort((o,a)=>a.score-o.score);return s[0].score>=3&&s[0].score-s[1].score>=2?s[0].lang:""}function LN(e,t){const n=Er(e&&e.lang);return n||Er(PN(e&&e.body))||Er(t)}function Uw(e){try{const t=e&&e.speechSynthesis&&e.speechSynthesis.getVoices;return typeof t=="function"?Array.from(t.call(e.speechSynthesis)||[]).filter(Boolean):[]}catch{return[]}}function Kw(e,t){const n=Er(t);if(!n)return null;const s=Array.from(e||[]).filter(h=>h&&typeof h.lang=="string"&&h.lang.trim()),o=s.filter(h=>h.lang.trim().toLowerCase()===n.toLowerCase()),a=n.slice(0,2).toLowerCase(),u=s.filter(h=>h.lang.trim().toLowerCase().split("-")[0]===a);return o.find(h=>h.default===!0)||o[0]||u.find(h=>h.default===!0)||u[0]||null}function R_(e){return Zl(e).replace(/\bBearer\s+\S+/gi,"Bearer [redacted]").replace(/\b(?:sk|hf|zai|xox[baprs]|gh[pousr]|npm)[_-][A-Za-z0-9._-]{8,}\b/gi,"[redacted]").replace(/\b(?:token|password|secret|credential|api[_-]?key)\s*[=:]\s*(?:"[^"]*"|'[^']*'|\S+)/gi,"[redacted]").replace(/\b[A-Z][A-Z0-9_]{2,}\s*=\s*(?:"[^"]*"|'[^']*'|\S+)/g,"[redacted]").replace(/(?:\/home\/[^/\s]+|\/Users\/[^/\s]+|\/data\/(?:data|user\/\d+)\/[^/\s]+)(?:\/[^\s]*)?/g,"[private path]").replace(/\b[A-Za-z]:\\Users\\[^\\\s]+(?:\\[^\s]*)?/g,"[private path]")}function TN(e,t=SN){const n=R_(e&&e.title),s=R_(e&&e.body),o=[n,s&&s!==n?s:""].filter(Boolean).join(". "),a=Array.from(o);return a.length<=t?o:`${a.slice(0,Math.max(0,t-1)).join("").trimEnd()}…`}function DN(e){try{return!!(e&&e.visibilityState==="visible"&&typeof e.hasFocus=="function"&&e.hasFocus())}catch{return!1}}function qw(e=Br()){if(!Ho(e))return!1;try{return e.speechSynthesis.cancel(),!0}catch{return!1}}function MN(e){try{e&&typeof e.dispatchEvent=="function"&&typeof e.Event=="function"&&e.dispatchEvent(new e.Event(Nh))}catch{}}function AN(e,t,n=Br(),s={}){var p;if(Rh(n),!Ho(n))return Promise.resolve(!1);const o=Zl(e);if(!o||(p=s.signal)!=null&&p.aborted)return Promise.resolve(!1);const a=Number.isFinite(s.timeoutMs)&&s.timeoutMs>0?s.timeoutMs:kN,u=s.setTimer||((v,b)=>setTimeout(v,b)),h=s.clearTimer||(v=>clearTimeout(v)),f=s.signal;return MN(n),new Promise(v=>{let b=!1,w=!1,S=null,y=null;const x=C=>{if(!b){if(b=!0,f&&y&&f.removeEventListener("abort",y),S!==null&&h(S),C)xf.add(n);else try{n.speechSynthesis.cancel()}catch{}v(C)}};y=()=>x(!1),f&&f.addEventListener("abort",y,{once:!0});try{n.speechSynthesis.cancel();const C=new n.SpeechSynthesisUtterance(o);C.lang=Er(t);const R=Kw(Uw(n),C.lang);R&&(C.voice=R),C.onstart=()=>{w=!0},C.onend=()=>x(w),C.onerror=()=>x(!1),S=u(()=>x(!1),a),n.speechSynthesis.speak(C)}catch{x(!1)}})}function IN(e={}){const t=e.scope||Br(),n=e.document||t&&t.document,s=Number.isInteger(e.maxPending)&&e.maxPending>=0?e.maxPending:bN,o=Number.isFinite(e.watchdogMs)&&e.watchdogMs>0?e.watchdogMs:xN,a=Number.isFinite(e.dedupWindowMs)&&e.dedupWindowMs>0?e.dedupWindowMs:CN,u=Number.isInteger(e.maxDedup)&&e.maxDedup>0?e.maxDedup:EN,h=e.now||Date.now,f=e.setTimer||((I,A)=>setTimeout(I,A)),p=e.clearTimer||(I=>clearTimeout(I)),v=e.isPrimed||(()=>Ww(t)),b=t&&t.speechSynthesis;let w=null,S=null,y=[],x=[],C=()=>{};const R=new Map,k=()=>{x=Uw(t)};if(k(),b&&typeof b.addEventListener=="function")b.addEventListener("voiceschanged",k),C=()=>b.removeEventListener("voiceschanged",k);else if(b&&"onvoiceschanged"in b){const I=b.onvoiceschanged,A=(...N)=>{k(),typeof I=="function"&&I.apply(b,N)};b.onvoiceschanged=A,C=()=>{b.onvoiceschanged===A&&(b.onvoiceschanged=I)}}const $=I=>{if(I&&typeof I.id=="string"&&I.id)return`id:${I.id}`;const A=Number(I&&I.ts),N=Zl(I&&I.title);return Number.isFinite(A)&&N?`frame:${A}:${N}`:""},O=I=>{if(!I)return!0;const A=h();for(const[N,M]of R)A-M>=a&&R.delete(N);if(R.has(I))return!1;for(R.set(I,A);R.size>u;)R.delete(R.keys().next().value);return!0},V=()=>{S!==null&&p(S),S=null},Y=()=>{V(),w&&(w.onend=null,w.onerror=null,w=null),qw(t)},z=I=>{if(!Ho(t))return y=[],"unsupported";let A;try{A=new t.SpeechSynthesisUtterance(I.text),A.lang=Er(I.lang);const M=Kw(x,A.lang);M&&(A.voice=M)}catch{return y=[],"error"}w=A;const N=()=>{if(w!==A)return;V(),w=null,A.onend=null,A.onerror=null;const M=y.shift();M&&z(M)};A.onend=N,A.onerror=N;try{return S=f(()=>{if(w!==A)return;w=null,A.onend=null,A.onerror=null;try{t.speechSynthesis.cancel()}catch{}V();const M=y.shift();M&&z(M)},o),t.speechSynthesis.speak(A),"speaking"}catch{return N(),"error"}},ne=(I,A)=>{if(!Ho(t))return"unsupported";const N=TN(I);if(!N)return"empty";if(!O($(I)))return"duplicate";if(!DN(n))return"inactive";if(!v())return"unprimed";const M={text:N,lang:A};return I&&I.urgency==="high"?(y=[],Y(),z(M)):w?s===0?"dropped":(y.length>=s&&y.shift(),y.push(M),"queued"):z(M)},H=()=>{y=[],Y()};return{enqueue:ne,stop:H,dispose:()=>{H(),C(),C=()=>{}}}}function Vw(){const[e,t]=E.useState(N_);E.useEffect(()=>{const s=o=>{if((o==null?void 0:o.type)==="storage"&&o.key!==bf&&o.key!==null)return;const a=(o==null?void 0:o.type)===gl?kf(o.detail):N_();t(a)};return window.addEventListener(gl,s),window.addEventListener("storage",s),()=>{window.removeEventListener(gl,s),window.removeEventListener("storage",s)}},[]);const n=E.useCallback(s=>{const o=jN({enabled:s===!0});return t(o),window.dispatchEvent(new CustomEvent(gl,{detail:o})),o.enabled},[]);return[e.enabled,n]}function BN({text:e}){const[t,n]=E.useState(!1),s=async()=>{try{await navigator.clipboard.writeText(e),n(!0),setTimeout(()=>n(!1),1500)}catch{}};return c.jsxs("div",{className:"nc-set-copyline",children:[c.jsx("code",{children:e}),c.jsxs("button",{type:"button",className:"nc-btn ghost",onClick:s,children:[c.jsx(it,{name:"copy",size:14})," ",m(t?"copied":"copy")]})]})}function ON({value:e}){const[t,n]=E.useState("");return E.useEffect(()=>{let s=!0;return M2.toDataURL(e,{margin:1,width:220}).then(o=>{s&&n(o)}).catch(()=>{}),()=>{s=!1}},[e]),t?c.jsx("img",{src:t,width:"220",height:"220",alt:"NexusCrew pairing QR"}):null}function zN({token:e,nodes:t,roster:n,settings:s,readonly:o,refresh:a,refreshAliases:u}){const[h,f]=E.useState(null),[p,v]=E.useState(null),[b,w]=E.useState({}),[S,y]=E.useState(null),[x,C]=E.useState({ssh:"",sshPort:"",name:""}),[R,k]=E.useState(""),[$,O]=E.useState(""),[V,Y]=E.useState(""),[z,ne]=E.useState(!1),[H,X]=E.useState(null),[I,A]=E.useState(null),N=Date.now(),M=s&&s.deviceName||"",L=(t||[]).filter(J=>J&&J.direction==="outbound"&&J.name&&J.ssh),P=L.find(J=>J.name===R)||L[0]||null,F=L.find(J=>J.name===$)||L[0]||null,T=F?Cg(F.tunnel,N):null,q=F!=null&&F.shared?T!=null&&T.up?"share-local-active":"share-local-pending":T!=null&&T.up?"share-local-private":"share-local-private-down",B=[{key:"peer-group-hubs",rows:(t||[]).filter(J=>J.kind!=="transitive"&&J.relation!=="client")},{key:"peer-group-clients",rows:(t||[]).filter(J=>J.kind!=="transitive"&&J.relation==="client")},{key:"peer-group-routed",rows:(t||[]).filter(J=>J.kind==="transitive")}],D=async(J,ee)=>{f(null),v(`${J}:${ee}`);try{const pe=await $h(e,J,ee);ee==="test"&&w(Se=>({...Se,[J]:pe})),await a()}catch(pe){f(`${J}: ${String(pe.message||pe)}`)}v(null)},U=async J=>{f(null),v(`${J}:remove`);try{await y0(e,J),A(null),await a()}catch(ee){f(`${J}: ${String(ee.message||ee)}`)}v(null)},Z=J=>X({name:J.name,direction:J.direction,label:J.label||J.name,ssh:J.ssh||"",sshPort:J.sshPort?String(J.sshPort):"",autostart:J.autostart===!0,visibility:J.visibility||"network",selected:[...J.selected||[]]}),oe=async()=>{if(!H||!jr(H.label)){f(m("err-label"));return}const J=H.direction==="inbound"?{label:H.label,visibility:H.visibility,selected:H.visibility==="selected"?H.selected:[]}:{label:H.label,ssh:H.ssh,autostart:H.autostart,...H.sshPort?{sshPort:Number(H.sshPort)}:{}};f(null),v(`${H.name}:edit`);try{await _0(e,H.name,J),X(null),await a()}catch(ee){f(`${H.name}: ${String(ee.message||ee)}`)}v(null)},de=async J=>{if(F){f(null),v(`${F.name}:share`);try{await w0(e,F.name,J),await a()}catch(ee){const pe=ee!=null&&ee.data&&ee.data.shared===!1?ee.data:null;if(pe)try{await a()}catch{}const Se=ee!=null&&ee.data&&typeof ee.data.hint=="string"?ee.data.hint:"",Ze=(pe==null?void 0:pe.revoked)===!0&&(pe==null?void 0:pe.localReconcilePending)===!0?m("share-off-local-reconcile-pending"):(pe==null?void 0:pe.revoked)===!1&&(pe==null?void 0:pe.reconcilePending)===!0?m("share-off-hub-reconcile-pending"):"";f(`${F.name}: ${String(ee.message||ee)}${Se?` — ${Se}`:""}${Ze?` — ${Ze}`:""}`)}v(null)}},fe=async()=>{if(f(null),P){const pe=kg({name:P.name,ssh:P.ssh,sshPort:P.sshPort||""});if(!pe.ok){f(m(pe.error));return}v("invite");try{y(await lg(e,{ssh:pe.value.ssh,...pe.value.sshPort?{sshPort:pe.value.sshPort}:{}},[P.name]))}catch(Se){f(String(Se.message||Se))}v(null);return}const J=ms(x.name||V||M||"NexusCrew"),ee=kg({name:J,ssh:x.ssh,sshPort:x.sshPort});if(!ee.ok){f(m(ee.error));return}v("invite");try{y(await lg(e,{...V||M?{label:V||M}:{},name:J,ssh:ee.value.ssh,...ee.value.sshPort?{sshPort:ee.value.sshPort}:{}}))}catch(pe){f(String(pe.message||pe))}v(null)};return c.jsxs("div",{className:"nc-set-tab",children:[c.jsx("div",{className:"nc-sheet-label",children:m("peer-inventory-title")}),(t||[]).length===0&&c.jsx("div",{className:"nc-empty",children:m("no-nodes")}),B.map(J=>J.rows.length>0&&c.jsxs("div",{className:"nc-peer-group",children:[c.jsxs("div",{className:"nc-peer-group-title",children:[m(J.key)," ",c.jsx("span",{children:J.rows.length})]}),J.rows.map(ee=>{var He,vt;const pe=ee.kind==="transitive",Se=pe?{up:ee.stale!==!0,label:ee.stale===!0?"peer-routed-stale":"peer-routed"}:Cg(ee.tunnel,N),Ze=b[ee.name],$e=ee.actions||{};return c.jsxs("div",{className:`nc-set-node${pe?" routed":""}`,children:[c.jsxs("div",{className:"nc-set-node-head",children:[c.jsx("span",{className:`nc-dot ${Se.up?"on":""}`}),c.jsx("b",{children:ee.label||ee.name}),c.jsxs("small",{children:[ee.name,pe?` · ${ee.route.join(" → ")}`:ee.direction==="outbound"?` · SSH ${ee.ssh||""}`:` · ${m("node-connected-client")}`,(He=ee.tunnel)!=null&&He.transport?` · ${ee.tunnel.transport} ${m("transport-used")}`:""]}),c.jsxs("span",{className:`nc-set-tunnel${Se.up?" up":""}`,children:[m(Se.label),Se.since?` · ${Se.since}`:""]})]}),!pe&&ee.direction==="inbound"&&c.jsx("div",{className:"nc-set-info",children:m(ee.shared?"peer-shared":"peer-private")}),$e.visibility&&ee.shared&&c.jsxs(c.Fragment,{children:[c.jsxs("select",{value:ee.visibility||"network",disabled:o||!!p,onChange:async Xe=>{v(`${ee.name}:visibility`);try{await ug(e,ee.name,Xe.target.value),await a()}catch(St){f(String(St.message||St))}v(null)},children:[c.jsx("option",{value:"network",children:m("visibility-network")}),c.jsx("option",{value:"relay-only",children:m("visibility-relay")}),c.jsx("option",{value:"selected",children:m("visibility-selected")})]}),ee.visibility==="selected"&&c.jsx("div",{className:"nc-set-row",children:(t||[]).filter(Xe=>Xe.name!==ee.name&&Xe.nodeId).map(Xe=>{const St=(ee.selected||[]).includes(Xe.nodeId);return c.jsxs("label",{className:"nc-check",children:[c.jsx("input",{type:"checkbox",checked:St,disabled:o||!!p,onChange:async Et=>{const rt=Et.target.checked?[...ee.selected||[],Xe.nodeId]:(ee.selected||[]).filter(ct=>ct!==Xe.nodeId);v(`${ee.name}:visibility`);try{await ug(e,ee.name,"selected",rt),await a()}catch(ct){f(String(ct.message||ct))}v(null)}})," ",Xe.label||Xe.name]},Xe.nodeId)})})]}),c.jsxs("div",{className:"nc-set-node-actions",children:[$e.edit&&c.jsx("button",{type:"button",className:"nc-btn ghost",disabled:o||!!p,onClick:()=>Z(ee),children:m("edit")}),$e.test&&c.jsx("button",{type:"button",className:"nc-btn ghost",disabled:!!p,onClick:()=>D(ee.name,"test"),children:m("node-test")}),$e.disconnect&&Se.up&&c.jsx("button",{type:"button",className:"nc-btn ghost",disabled:o||!!p,onClick:()=>D(ee.name,"down"),children:m("tunnel-stop")}),$e.connect&&!Se.up&&c.jsx("button",{type:"button",className:"nc-btn ghost",disabled:o||!!p,onClick:()=>D(ee.name,"up"),children:m("tunnel-start")}),$e.restart&&c.jsx("button",{type:"button",className:"nc-btn ghost",disabled:o||!!p,onClick:()=>D(ee.name,"restart"),children:m("tunnel-restart")}),$e.remove&&c.jsxs("button",{type:"button",className:"nc-btn danger",disabled:o||!!p,title:m(o?"settings-readonly":"delete"),onClick:()=>A(ee.name),children:[c.jsx(it,{name:"trash",size:14})," ",m("delete")]})]}),(H==null?void 0:H.name)===ee.name&&c.jsxs("div",{className:"nc-set-form nc-node-editor",children:[c.jsxs("label",{className:"nc-field",children:[m("node-display-label"),c.jsx("input",{value:H.label,disabled:!!p,onChange:Xe=>X({...H,label:Xe.target.value})})]}),H.direction==="outbound"?c.jsxs(c.Fragment,{children:[c.jsxs("label",{className:"nc-field",children:[m("node-ssh-label"),c.jsx("input",{value:H.ssh,disabled:!!p,onChange:Xe=>X({...H,ssh:Xe.target.value})})]}),c.jsxs("label",{className:"nc-field",children:[m("node-ssh-port-label"),c.jsx("input",{inputMode:"numeric",value:H.sshPort,disabled:!!p,onChange:Xe=>X({...H,sshPort:Xe.target.value.replace(/[^0-9]/g,"").slice(0,5)})})]}),c.jsxs("label",{className:"nc-check",children:[c.jsx("input",{type:"checkbox",checked:H.autostart,disabled:!!p,onChange:Xe=>X({...H,autostart:Xe.target.checked})})," ",m("boot-persist")]})]}):c.jsxs("label",{className:"nc-field",children:[m("peer-visibility"),c.jsxs("select",{value:H.visibility,disabled:!!p,onChange:Xe=>X({...H,visibility:Xe.target.value}),children:[c.jsx("option",{value:"network",children:m("visibility-network")}),c.jsx("option",{value:"relay-only",children:m("visibility-relay")}),c.jsx("option",{value:"selected",children:m("visibility-selected")})]})]}),c.jsxs("div",{className:"nc-set-row",children:[c.jsx("button",{type:"button",className:"nc-btn primary",disabled:!!p,onClick:oe,children:m("save")}),c.jsx("button",{type:"button",className:"nc-btn ghost",disabled:!!p,onClick:()=>X(null),children:m("cancel")})]})]}),I===ee.name&&c.jsxs("div",{className:"nc-set-confirm",children:[c.jsx("b",{children:m("node-remove-confirm").replace("{name}",ee.label||ee.name)}),c.jsx("small",{children:m("node-remove-warning")}),c.jsxs("div",{className:"nc-set-row",children:[c.jsx("button",{type:"button",className:"nc-btn danger",disabled:!!p,onClick:()=>U(ee.name),children:m("delete")}),c.jsx("button",{type:"button",className:"nc-btn ghost",disabled:!!p,onClick:()=>A(null),children:m("cancel")})]})]}),((vt=ee.health)==null?void 0:vt.detail)&&c.jsx("div",{className:`nc-set-test${ee.health.status==="healthy"?" ok":ee.health.status==="passive"?"":" ko"}`,children:ee.health.detail}),Ze&&c.jsxs("div",{className:`nc-set-test${Ze.ok?" ok":" ko"}`,children:[Ze.result,Ze.detail?` — ${Ze.detail}`:""]})]},`${ee.kind||"direct"}:${ee.nodeId||ee.name}`)})]},J.key)),(n||[]).some(J=>!J.direct&&J.instanceId)&&c.jsxs("div",{className:"nc-set-form",children:[c.jsx("div",{className:"nc-sheet-label",children:m("routed-node-aliases")}),c.jsx("small",{className:"nc-set-hint",children:m("routed-node-aliases-help")}),(n||[]).filter(J=>!J.direct&&J.instanceId).map(J=>c.jsxs("div",{className:"nc-set-node",children:[c.jsxs("div",{className:"nc-set-node-head",children:[c.jsx("span",{className:`nc-dot ${J.status==="up"?"on":""}`}),c.jsx("b",{children:J.label||J.name}),c.jsx("small",{children:(J.route||[]).join(" › ")})]}),c.jsxs("div",{className:"nc-set-node-actions",children:[c.jsx("button",{type:"button",className:"nc-btn ghost",disabled:o||!!p,onClick:async()=>{const ee=window.prompt(m("node-local-alias"),J.alias||"");if(ee!=null){if(ee.trim()&&!jr(ee.normalize("NFC"))){f(m("err-label"));return}v(`${J.instanceId}:alias`),f(null);try{ee.trim()?await v0(e,J.instanceId,ee):await cg(e,J.instanceId),u()}catch(pe){f(String(pe.message||pe))}v(null)}},children:m("alias-on-device")}),J.alias&&c.jsx("button",{type:"button",className:"nc-btn ghost",disabled:o||!!p,onClick:async()=>{v(`${J.instanceId}:alias-reset`),f(null);try{await cg(e,J.instanceId),u()}catch(ee){f(String(ee.message||ee))}v(null)},children:m("reset-alias")})]})]},J.instanceId))]}),F&&c.jsxs("div",{className:"nc-set-form nc-local-share",children:[c.jsx("div",{className:"nc-sheet-label",children:m("share-local-heading")}),L.length>1&&c.jsxs("label",{className:"nc-field",children:[m("share-local-hub"),c.jsx("select",{value:F.name,disabled:o||!!p,onChange:J=>O(J.target.value),children:L.map(J=>c.jsx("option",{value:J.name,children:J.label||J.name},J.name))})]}),c.jsxs("label",{className:"nc-check nc-node-share",children:[c.jsx("input",{type:"checkbox",checked:F.shared===!0,disabled:o||!!p,onChange:J=>de(J.target.checked)}),c.jsxs("span",{children:[c.jsx("b",{children:m("share-local-through").replace("{device}",M||m("local")).replace("{hub}",F.label||F.name)}),c.jsx("small",{children:m(F.shared?"share-node-on-desc":"share-node-off-desc")})]})]}),c.jsx("div",{className:`nc-set-test${F.shared&&(T!=null&&T.up)?" ok":T!=null&&T.up?"":" ko"}`,children:m(q)}),!(T!=null&&T.up)&&c.jsx("button",{type:"button",className:"nc-btn ghost",disabled:o||!!p,onClick:()=>de(F.shared===!0),children:m("share-local-reconnect")})]}),c.jsx(Tw,{token:e,deviceDefault:M,localNodeId:s&&s.nodeId||"",localNameDefault:s&&s.localName||"",readonly:o,onSuccess:a}),c.jsxs("div",{className:"nc-set-form",children:[c.jsx("div",{className:"nc-sheet-label",children:m("invite-node")}),c.jsx("small",{className:"nc-set-hint",children:m(P?"invite-network-hint":"invite-v2-hint")}),P?c.jsxs(c.Fragment,{children:[L.length>1&&c.jsxs("label",{className:"nc-field",children:[m("invite-network-label"),c.jsx("select",{value:P.name,disabled:o||!!p,onChange:J=>{k(J.target.value),y(null)},children:L.map(J=>c.jsx("option",{value:J.name,children:J.label||J.name},J.name))})]}),c.jsxs("div",{className:"nc-set-info nc-invite-endpoint",children:[m("invite-network-via"),": ",c.jsx("b",{children:P.label||P.name})," · ",P.ssh,P.sshPort?`:${P.sshPort}`:""]}),c.jsx("small",{className:"nc-set-hint",children:m("invite-network-route")})]}):c.jsxs("label",{className:"nc-field",children:[m("invite-endpoint-label"),c.jsx("input",{placeholder:"user@host",value:x.ssh,disabled:o,onChange:J=>C({...x,ssh:J.target.value})}),c.jsx("small",{className:"nc-set-hint",children:m("invite-endpoint-needed")})]}),!P&&z&&c.jsxs("div",{className:"nc-invite-advanced",children:[c.jsxs("label",{className:"nc-field",children:[m("node-ssh-port-label"),c.jsx("input",{inputMode:"numeric",placeholder:"22",value:x.sshPort,disabled:o,onChange:J=>C({...x,sshPort:J.target.value.replace(/[^0-9]/g,"").slice(0,5)})})]}),c.jsxs("label",{className:"nc-field",children:[m("device-name-label"),c.jsx("input",{placeholder:M||"NexusCrew",value:V,disabled:o,onChange:J=>Y(J.target.value)}),c.jsx("small",{className:"nc-set-hint",children:m("device-name-hint")})]}),c.jsxs("label",{className:"nc-field",children:[m("node-name-label"),c.jsx("input",{placeholder:ms(V||M||m("node-name-ph")),value:x.name,disabled:o,onChange:J=>C({...x,name:J.target.value?ms(J.target.value):""})})]})]}),c.jsxs("div",{className:"nc-set-row nc-invite-actions",children:[c.jsx("button",{type:"button",className:"nc-btn primary",disabled:o||!!p||!P&&!x.ssh.trim(),onClick:fe,children:m("create-pairing-link")}),!P&&c.jsxs("button",{type:"button",className:"nc-btn ghost",disabled:!!p,onClick:()=>ne(J=>!J),children:[z?"▾":"▸"," ",m("pair-advanced")]})]}),S&&c.jsxs(c.Fragment,{children:[c.jsx(ON,{value:S.pairingUrl}),c.jsx(BN,{text:S.pairingUrl}),c.jsx("div",{className:"nc-set-info",children:m("invite-next-steps")})]})]}),h&&c.jsx("div",{className:"nc-err",children:h})]})}function FN({token:e,readonly:t}){const[n,s]=E.useState("idle"),[o,a]=E.useState(!1),[u,h]=E.useState(null);E.useEffect(()=>{let p=!1;return q2().then(v=>{p||s(v)}),()=>{p=!0}},[]);const f=async()=>{h(null),a(!0);try{n==="subscribed"?(await Y2(e),s("idle")):(await V2(e),s("subscribed"))}catch(p){const v=String(p.message||p);v==="push-denied"?(s("denied"),h(m("push-denied"))):v==="push-unsupported"?(s("unsupported"),h(m("push-unsupported"))):h(v)}a(!1)};return n==="unsupported"?c.jsx("div",{className:"nc-set-info",children:m("push-unsupported")}):c.jsxs(c.Fragment,{children:[c.jsxs("div",{className:"nc-set-row",children:[c.jsx("button",{type:"button",className:"nc-btn ghost",disabled:t||o||n==="denied",title:t?m("settings-readonly"):"",onClick:f,children:m(n==="subscribed"?"push-disable":"push-enable")}),c.jsx("span",{className:"nc-set-info",children:m(n==="subscribed"?"push-on":n==="denied"?"push-denied":"push-off")})]}),u&&c.jsx("div",{className:"nc-err",children:u})]})}function $N(){const[e,t]=Vw(),[n,s]=E.useState(""),[o,a]=E.useState(""),[u,h]=E.useState(!1),[f,p]=E.useState(Ww),v=E.useRef(0),b=E.useRef(!1),w=E.useRef(null),S=Ho();E.useEffect(()=>()=>{var C;v.current+=1,b.current&&((C=w.current)==null||C.abort(),w.current=null,b.current=!1,Rh())},[]);const y=async()=>{const C=v.current+=1,R=typeof AbortController=="function"?new AbortController:null;s(""),a(""),h(!0),p(!1),b.current=!0,w.current=R;const k=await AN(m("notification-speech-preview"),El(),void 0,R?{signal:R.signal}:{});return C!==v.current||(w.current=null,b.current=!1,h(!1),p(k),k?a(m("notification-speech-preview-ok")):s(m("notification-speech-preview-failed"))),k},x=C=>{var R;if(t(C),s(""),a(""),C)y();else{v.current+=1;const k=b.current;(R=w.current)==null||R.abort(),w.current=null,b.current=!1,h(!1),p(!1),Rh(),k||qw()}};return c.jsxs("div",{className:"nc-set-form",children:[c.jsxs("label",{className:"nc-check",children:[c.jsx("input",{type:"checkbox","aria-label":m("notification-speech-enable"),checked:e,disabled:!S,onChange:C=>x(C.target.checked)}),c.jsxs("span",{children:[c.jsx("b",{children:m("notification-speech-enable")}),c.jsx("small",{children:m("notification-speech-help")})]})]}),S?c.jsx("div",{className:"nc-set-row",children:c.jsx("button",{type:"button",className:"nc-btn ghost",disabled:!e||u,onClick:()=>{y()},children:m(u?"notification-speech-testing":"notification-speech-test")})}):c.jsx("div",{className:"nc-set-info",children:m("notification-speech-unsupported")}),e&&!f&&!u&&!n&&c.jsx("div",{className:"nc-set-info",children:m("notification-speech-needs-test")}),o&&c.jsx("div",{className:"nc-set-info",role:"status",children:o}),n&&c.jsx("div",{className:"nc-err",children:n})]})}function HN({token:e,readonly:t,nodes:n=[],settings:s=null}){const[o,a]=E.useState(null),[u,h]=E.useState([]),[f,p]=E.useState({name:"",mode:"primary-failover",targets:[]}),[v,b]=E.useState(null),[w,S]=E.useState(!1),[y,x]=E.useState(null),[C,R]=E.useState(""),k=E.useCallback(async()=>{try{const[F,T]=await Promise.all([S0(e),C0(e)]);a(F),h(Array.isArray(T==null?void 0:T.groups)?T.groups:[]),R("")}catch(F){R(String(F.message||F))}},[e]);E.useEffect(()=>{k()},[k]);const $=async F=>{S(!0),x(null),R("");try{a(await b0(e,F))}catch(T){R(String(T.message||T))}S(!1)},O=async()=>{S(!0),x(null),R("");try{x({kind:"test",...await x0(e)})}catch(F){R(String(F.message||F))}S(!1)},V=async()=>{S(!0),x(null),R("");try{x({kind:"stop",...await k0(e)})}catch(F){R(String(F.message||F))}S(!1)},Y=[],z=new Set,ne=(F,T)=>{const q=typeof F=="string"?F.toLowerCase():"";!/^[a-f0-9]{32}$/.test(q)||z.has(q)||(z.add(q),Y.push({id:q,label:T||q}))};ne(s==null?void 0:s.nodeId,m("audio-group-local"));for(const F of n||[])ne((F==null?void 0:F.nodeId)||(F==null?void 0:F.instanceId),(F==null?void 0:F.label)||(F==null?void 0:F.name)||(F==null?void 0:F.nodeId));for(const F of f.targets)ne(F,`${F} (${m("audio-group-unavailable-target")})`);const H=(F=null)=>{R(""),F?(b(F.name),p({name:F.name,mode:F.mode,targets:[...F.targets||[]]})):(b(null),p({name:"",mode:"primary-failover",targets:[]}))},X=(F,T)=>p(q=>({...q,targets:T?[...new Set([...q.targets,F])]:q.targets.filter(B=>B!==F)})),I=async()=>{const F=f.name.trim().toLowerCase();if(!/^[a-z0-9][a-z0-9-]{0,31}$/.test(F)||f.targets.length<1){R(m("audio-group-invalid"));return}S(!0),R("");try{const T=await E0(e,F,{targets:f.targets,mode:f.mode}),q=T==null?void 0:T.group;if(!q||!q.name)throw new Error(m("audio-group-save-failed"));h(B=>[...B.filter(D=>D.name!==q.name),q].sort((D,U)=>D.name.localeCompare(U.name))),H(null)}catch(T){R(String(T.message||T))}S(!1)},A=async F=>{S(!0),R("");try{await N0(e,F),h(T=>T.filter(q=>q.name!==F)),v===F&&H(null)}catch(T){R(String(T.message||T))}S(!1)},N=(o==null?void 0:o.installed)===!0,M=(o==null?void 0:o.liveness)==="ready",L=(o==null?void 0:o.consent)===!0&&N&&M,P=y?y.kind==="stop"?m(y.stopped?"audio-stop-stopped":"audio-stop-idle"):y.status==="accepted"||y.status==="spoken"?m("audio-test-accepted"):y.status==="unknown"?m("audio-test-unknown"):`${m("audio-test-refused")}${y.reason?` (${y.reason})`:""}`:"";return c.jsxs("div",{className:"nc-set-tab nc-audio-settings",children:[c.jsxs("div",{className:"nc-set-info",children:[c.jsx("b",{children:m("audio-title")}),c.jsx("br",{}),m("audio-help")]}),o?c.jsxs(c.Fragment,{children:[c.jsxs("label",{className:"nc-check",children:[c.jsx("input",{type:"checkbox","aria-label":m("audio-consent"),checked:o.consent===!0,disabled:t||w,onChange:F=>{$(F.target.checked)}}),c.jsxs("span",{children:[c.jsx("b",{children:m("audio-consent")}),c.jsx("small",{children:m("audio-consent-help")})]})]}),c.jsxs("div",{className:"nc-set-form",children:[c.jsx("div",{className:"nc-sheet-label",children:m("audio-capability")}),c.jsxs("div",{className:"nc-set-info",children:[m("audio-adapter"),": ",o.adapter||m("audio-adapter-none"),c.jsx("br",{}),m("audio-installed"),": ",m(N?"audio-installed-yes":"audio-installed-no"),c.jsx("br",{}),m("audio-liveness"),": ",m(M?"audio-liveness-ready":"audio-liveness-unavailable"),Array.isArray(o.languages)&&o.languages.length>0&&c.jsxs(c.Fragment,{children:[c.jsx("br",{}),m("audio-languages"),": ",o.languages.join(", ")]})]}),o.limits&&c.jsxs("small",{className:"nc-set-hint",children:[m("audio-limits"),": ",o.limits]})]}),!o.consent&&c.jsx("div",{className:"nc-set-info",children:m("audio-test-needs-consent")}),!N&&c.jsx("div",{className:"nc-set-info",children:m("audio-unavailable")}),c.jsxs("div",{className:"nc-set-row",children:[c.jsx("button",{type:"button",className:"nc-btn primary",disabled:t||w||!L,title:t?m("settings-readonly"):"",onClick:()=>{O()},children:m(w?"audio-testing":"audio-test")}),c.jsx("button",{type:"button",className:"nc-btn ghost",disabled:w,onClick:()=>{V()},children:m(w?"audio-stopping":"audio-stop")}),c.jsx("button",{type:"button",className:"nc-btn ghost",disabled:w,onClick:()=>{k()},children:m("refresh")})]}),c.jsxs("div",{className:"nc-set-form",children:[c.jsx("div",{className:"nc-sheet-label",children:m("audio-groups-title")}),c.jsx("small",{className:"nc-set-hint",children:m("audio-groups-help")}),u.length===0&&c.jsx("div",{className:"nc-set-info",children:m("audio-groups-empty")}),u.map(F=>{var T;return c.jsxs("div",{className:"nc-set-row",children:[c.jsxs("span",{children:[c.jsx("b",{children:F.name})," ",c.jsxs("small",{children:["· ",F.mode==="fanout"?m("audio-group-fanout"):m("audio-group-primary")," · ",((T=F.targets)==null?void 0:T.length)||0]})]}),c.jsx("button",{type:"button",className:"nc-btn ghost",disabled:t||w,onClick:()=>H(F),children:m("audio-group-edit")}),c.jsx("button",{type:"button",className:"nc-btn ghost",disabled:t||w,onClick:()=>{A(F.name)},children:m("audio-group-delete")})]},F.name)}),c.jsx("div",{className:"nc-set-row",children:c.jsx("button",{type:"button",className:"nc-btn ghost",disabled:t||w,onClick:()=>H(null),children:m("audio-group-new")})}),c.jsxs("label",{className:"nc-field",children:[m("audio-group-name"),c.jsx("input",{"aria-label":m("audio-group-name"),value:f.name,maxLength:"32",disabled:t||w,onChange:F=>p(T=>({...T,name:F.target.value}))})]}),c.jsxs("label",{className:"nc-field",children:[m("audio-group-mode"),c.jsxs("select",{"aria-label":m("audio-group-mode"),value:f.mode,disabled:t||w,onChange:F=>p(T=>({...T,mode:F.target.value})),children:[c.jsx("option",{value:"primary-failover",children:m("audio-group-primary")}),c.jsx("option",{value:"fanout",children:m("audio-group-fanout")})]})]}),c.jsx("div",{className:"nc-set-info",children:m("audio-group-targets")}),Y.length===0?c.jsx("small",{className:"nc-set-hint",children:m("audio-group-no-targets")}):Y.map(F=>c.jsxs("label",{className:"nc-check",children:[c.jsx("input",{type:"checkbox",checked:f.targets.includes(F.id),disabled:t||w,onChange:T=>X(F.id,T.target.checked)}),c.jsxs("span",{children:[F.label,c.jsx("small",{children:F.id})]})]},F.id)),c.jsxs("div",{className:"nc-set-row",children:[c.jsx("button",{type:"button",className:"nc-btn primary",disabled:t||w,onClick:()=>{I()},children:m("audio-group-save")}),v&&c.jsx("button",{type:"button",className:"nc-btn ghost",disabled:w,onClick:()=>H(null),children:m("audio-group-cancel")})]})]})]}):c.jsx("div",{className:"nc-set-info",children:m("audio-loading")}),P&&c.jsx("div",{className:"nc-set-note",role:"status",children:P}),C&&c.jsx("div",{className:"nc-err",children:C})]})}function WN(){const[e,t]=uf();return c.jsxs("div",{className:"nc-set-tab nc-input-settings",children:[c.jsx("div",{className:"nc-set-info",children:m("input-settings-local")}),c.jsxs("div",{className:"nc-set-form",children:[c.jsxs("label",{className:"nc-field",children:[m("terminal-keyboard-gesture"),c.jsx("select",{"aria-label":m("terminal-keyboard-gesture"),value:e.terminalKeyboardGesture,onChange:n=>t({terminalKeyboardGesture:n.target.value}),children:uw.map(n=>c.jsx("option",{value:n,children:m(`terminal-keyboard-${n}`)},n))}),c.jsx("small",{children:m("terminal-keyboard-gesture-help")})]}),c.jsxs("label",{className:"nc-field",children:[m("keybar-layout"),c.jsx("select",{"aria-label":m("keybar-layout"),value:e.keybarLayout,onChange:n=>t({keybarLayout:n.target.value}),children:dw.map(n=>c.jsx("option",{value:n,children:m(`keybar-layout-${n}`)},n))}),c.jsx("small",{children:m("keybar-layout-help")})]})]}),c.jsxs("label",{className:"nc-check",children:[c.jsx("input",{type:"checkbox",checked:e.keybarKeepsKeyboardClosed,onChange:n=>t({keybarKeepsKeyboardClosed:n.target.checked})}),c.jsxs("span",{children:[c.jsx("b",{children:m("keybar-ime-lock")}),c.jsx("small",{children:m("keybar-ime-lock-help")})]})]}),c.jsxs("label",{className:"nc-check",children:[c.jsx("input",{type:"checkbox",checked:e.voiceKeepsKeyboardClosed,onChange:n=>t({voiceKeepsKeyboardClosed:n.target.checked})}),c.jsxs("span",{children:[c.jsx("b",{children:m("voice-ime-lock")}),c.jsx("small",{children:m("voice-ime-lock-help")})]})]}),c.jsxs("label",{className:"nc-check",children:[c.jsx("input",{type:"checkbox",checked:e.showKeybarEnter,onChange:n=>t({showKeybarEnter:n.target.checked})}),c.jsxs("span",{children:[c.jsx("b",{children:m("keybar-enter-show")}),c.jsx("small",{children:m("keybar-enter-show-help")})]})]}),c.jsx("div",{className:"nc-set-row",children:c.jsx("button",{type:"button",className:"nc-btn ghost",onClick:()=>t(hs),children:m("input-settings-reset")})})]})}function UN({token:e,roster:t=[],readonly:n}){const s=[{key:"local",route:[],label:m("diagnostics-local"),status:"up"},...t.filter(L=>Array.isArray(L.route)&&L.route.length).map(L=>({key:L.route.join("/"),route:L.route,label:L.label||L.name,status:L.status}))],[o,a]=E.useState("local"),u=s.find(L=>L.key===o)||s[0],[h,f]=E.useState(null),[p,v]=E.useState([]),[b,w]=E.useState(""),[S,y]=E.useState(!1),[x,C]=E.useState(!0),[R,k]=E.useState(900),[$,O]=E.useState("all"),[V,Y]=E.useState(""),z=E.useRef(0),ne=E.useRef(null),H=E.useCallback(async()=>{try{const L=await L0(e,u.route);if(f(L),w(""),!S){const P=await T0(e,{after:z.current,limit:200},u.route);Array.isArray(P.records)&&P.records.length&&(z.current=P.cursor,v(F=>[...F,...P.records].slice(-500)))}}catch(L){w(L&&L.status===404?m("diagnostics-unsupported"):String(L.message||L))}},[e,u.key,S]);E.useEffect(()=>{z.current=0,v([]),f(null),w("")},[u.key]),E.useEffect(()=>{let L=null,P=!0;const F=()=>{!P||document.visibilityState==="hidden"||H()},T=()=>{L&&clearInterval(L),L=document.visibilityState==="hidden"?null:setInterval(F,2e3),document.visibilityState!=="hidden"&&F()};return document.addEventListener("visibilitychange",T),T(),()=>{P=!1,L&&clearInterval(L),document.removeEventListener("visibilitychange",T)}},[H]),E.useEffect(()=>{x&&ne.current&&(ne.current.scrollTop=ne.current.scrollHeight)},[p,x]);const X=p.filter(L=>($==="all"||L.level===$)&&(!V||String(L.component||"").toLowerCase().includes(V.toLowerCase()))),I=X.map(L=>`${L.ts} ${L.level.toUpperCase()} ${L.component} ${L.code} ${L.message}${Object.keys(L.meta||{}).length?` ${JSON.stringify(L.meta)}`:""}`).join(`
92
92
  `),A=async L=>{w("");try{const P=await L();f(P),await H()}catch(P){w(String(P.message||P))}},N=async()=>{try{await navigator.clipboard.writeText(I)}catch{w(m("copy-manual"))}},M=()=>{try{const L=new Blob([`${JSON.stringify(X,null,2)}
93
- `],{type:"application/json"}),P=URL.createObjectURL(L),F=document.createElement("a");F.href=P,F.download="nexuscrew-diagnostics.json",F.click(),URL.revokeObjectURL(P)}catch{w(m("diagnostics-export-failed"))}};return c.jsxs("div",{className:"nc-set-tab nc-diagnostics",children:[c.jsxs("label",{className:"nc-field",children:[m("diagnostics-target"),c.jsx("select",{value:u.key,onChange:L=>a(L.target.value),children:s.map(L=>c.jsxs("option",{value:L.key,children:[L.label,L.status!=="up"?` · ${L.status}`:""]},L.key))})]}),c.jsxs("div",{className:"nc-set-form nc-diag-controls",children:[c.jsx("div",{className:"nc-sheet-label",children:m("diagnostics-verbose")}),c.jsxs("div",{className:"nc-set-row",children:[c.jsx("select",{"aria-label":m("diagnostics-duration"),value:R,onChange:L=>k(Number(L.target.value)),disabled:n,children:[300,900,1800,3600].map(L=>c.jsxs("option",{value:L,children:[L/60," min"]},L))}),c.jsx("button",{type:"button",className:"nc-btn primary",disabled:n||(h==null?void 0:h.verbose)===!0,onClick:()=>A(()=>dg(e,!0,R,u.route)),children:m("enable")}),c.jsx("button",{type:"button",className:"nc-btn ghost",disabled:n||(h==null?void 0:h.verbose)!==!0,onClick:()=>A(()=>dg(e,!1,R,u.route)),children:m("stop")})]}),c.jsx("small",{className:"nc-set-hint",children:h!=null&&h.verbose?m("diagnostics-expires").replace("{time}",new Date(h.expiresAt).toLocaleTimeString()):m("diagnostics-off")})]}),c.jsxs("div",{className:"nc-diag-filters",children:[c.jsxs("select",{"aria-label":m("diagnostics-level"),value:$,onChange:L=>O(L.target.value),children:[c.jsx("option",{value:"all",children:m("diagnostics-all-levels")}),["debug","info","warn","error"].map(L=>c.jsx("option",{value:L,children:L},L))]}),c.jsx("input",{"aria-label":m("diagnostics-component"),placeholder:m("diagnostics-component"),value:V,onChange:L=>Y(L.target.value)})]}),c.jsxs("div",{className:"nc-set-row",children:[c.jsxs("label",{className:"nc-check",children:[c.jsx("input",{type:"checkbox",checked:S,onChange:L=>y(L.target.checked)})," ",m("diagnostics-pause")]}),c.jsxs("label",{className:"nc-check",children:[c.jsx("input",{type:"checkbox",checked:x,onChange:L=>C(L.target.checked)})," ",m("diagnostics-autoscroll")]})]}),c.jsx("pre",{ref:ne,className:"nc-diag-log","aria-label":m("diagnostics-log"),children:I||m("diagnostics-empty")}),c.jsxs("div",{className:"nc-set-row",children:[c.jsx("button",{type:"button",className:"nc-btn ghost",onClick:N,children:m("copy")}),c.jsx("button",{type:"button",className:"nc-btn ghost",onClick:M,children:m("diagnostics-export")}),c.jsx("button",{type:"button",className:"nc-btn danger",disabled:n,onClick:()=>{window.confirm(m("diagnostics-clear-confirm"))&&A(async()=>{const L=await D0(e,u.route);return z.current=0,v([]),L})},children:m("diagnostics-clear")})]}),b&&c.jsx("div",{className:"nc-err",children:b})]})}function KN({token:e,settings:t,readonly:n,refresh:s,roster:o,section:a,setSection:u}){const[h,f]=E.useState(null),[p,v]=E.useState(null),[b,w]=E.useState(!1),[S,y]=E.useState(!1),[x,C]=E.useState(null),[R,k]=E.useState(!0),[$,O]=E.useState(!1);E.useEffect(()=>{C(t&&t.update||null),k(!t||t.autoUpdate!==!1),O(!!(t&&t.alternateScreen))},[t]);const V=async()=>{f(null),v(null),y(!0);try{const N=await p0(e);v(N.note||"ok"),w(!1)}catch(N){f(String(N.message||N))}y(!1)},Y=async()=>{f(null),v(null),y(!0);try{const N=await R0(e);v(`${N.note||"ok"}${N.target?` (${N.target})`:""}`)}catch(N){f(String(N.message||N))}y(!1)},z=async N=>{f(null),v(null),y(!0);try{await Ld(e,{autoUpdate:N}),k(N),s&&await s()}catch(M){f(String(M.message||M))}y(!1)},ne=async N=>{f(null),v(null),y(!0);try{await Ld(e,{alternateScreen:N}),O(N),s&&await s()}catch(M){f(String(M.message||M))}y(!1)},H=async()=>{f(null),v(null),y(!0);try{C(await j0(e))}catch(N){f(String(N.message||N))}y(!1)},X=async()=>{f(null),v(null),y(!0);try{const N=await P0(e);C(N),v(m("npm-update-restarting"))}catch(N){f(String(N.message||N))}y(!1)},I=()=>{window.confirm(m("composer-clear-confirm"))&&(f(null),xE()?(window.dispatchEvent(new Event(Sh)),v(m("composer-clear-done"))):f(m("composer-clear-failed")))},A=t&&t.service;return c.jsxs("div",{className:"nc-set-tab",children:[c.jsx("div",{className:"nc-system-tabs",role:"tablist","aria-label":m("tab-system"),children:["general","diagnostics"].map(N=>c.jsx("button",{type:"button",role:"tab","aria-selected":a===N,className:`nc-set-tabbtn${a===N?" on":""}`,onClick:()=>u(N),children:m(`system-${N}`)},N))}),a==="general"&&c.jsxs(c.Fragment,{children:[c.jsxs("section",{className:"nc-system-group",children:[c.jsx("h3",{children:m("system-this-node")}),t&&c.jsxs("div",{className:"nc-set-info",children:["v",t.version," · ",t.platform," · :",t.port,c.jsx("br",{}),A&&A.installed?m("service-installed"):m("service-missing"),A&&A.installed?` · ${A.active?m("service-active"):m("service-inactive")}`:"",A?` · boot ${A.boot?"on":"off"}`:""]}),c.jsx("div",{className:"nc-set-row",children:c.jsx("button",{type:"button",className:"nc-btn ghost",disabled:n||S,title:n?m("settings-readonly"):"",onClick:Y,children:m("service-regenerate")})}),c.jsx(FN,{token:e,readonly:n}),c.jsx($N,{})]}),c.jsxs("section",{className:"nc-system-group",children:[c.jsx("h3",{children:m("system-updates")}),c.jsxs("div",{className:"nc-set-form nc-update-settings",children:[c.jsxs("label",{className:"nc-check",children:[c.jsx("input",{type:"checkbox",checked:R,disabled:n||S||x&&!x.supported,onChange:N=>z(N.target.checked)}),c.jsxs("span",{children:[c.jsx("b",{children:m("npm-auto-update")}),c.jsx("small",{children:m("npm-auto-update-help")})]})]}),x&&c.jsxs("div",{className:"nc-set-info",children:[m("npm-update-current")," v",x.current,x.latest?` · ${m("npm-update-latest")} v${x.latest}`:""," · ",m(`npm-update-${x.supported?x.phase:"unsupported"}`)]}),c.jsxs("div",{className:"nc-set-row",children:[c.jsx("button",{type:"button",className:"nc-btn ghost",disabled:n||S||!x||!x.supported,onClick:H,children:m("npm-update-check")}),x&&x.available&&c.jsx("button",{type:"button",className:"nc-btn primary",disabled:n||S||x.phase==="installing",onClick:X,children:m("npm-update-install")})]}),x&&x.lastError&&c.jsx("div",{className:"nc-err",children:x.lastError})]})]}),c.jsxs("section",{className:"nc-system-group",children:[c.jsx("h3",{children:m("system-security")}),c.jsx("div",{className:"nc-set-row",children:c.jsx("button",{type:"button",className:"nc-btn ghost",disabled:n||S,title:n?m("settings-readonly"):"",onClick:()=>{f(null),v(null),w(!0)},children:m("token-rotate")})})]}),c.jsxs("section",{className:"nc-system-group",children:[c.jsx("h3",{children:m("system-local-data")}),c.jsxs("div",{className:"nc-set-form",children:[c.jsx("div",{className:"nc-sheet-label",children:m("composer-clear-data")}),c.jsx("small",{className:"nc-set-hint",children:m("composer-clear-data-help")}),c.jsx("div",{className:"nc-set-row",children:c.jsx("button",{type:"button",className:"nc-btn ghost",onClick:I,children:m("composer-clear-data")})})]})]})]}),a==="diagnostics"&&c.jsxs("section",{className:"nc-system-group nc-system-diagnostics",children:[c.jsx("h3",{children:m("system-diagnostics")}),c.jsxs("div",{className:"nc-set-form nc-alternate-screen-settings",children:[c.jsx("div",{className:"nc-sheet-label",children:m("system-terminal")}),c.jsxs("label",{className:"nc-check",children:[c.jsx("input",{type:"checkbox","aria-label":m("alternate-screen"),checked:$,disabled:n||S,onChange:N=>ne(N.target.checked)}),c.jsxs("span",{children:[c.jsx("b",{children:m("alternate-screen")}),c.jsx("small",{children:m("alternate-screen-help")})]})]})]}),c.jsx(UN,{token:e,roster:o,readonly:n})]}),b&&c.jsxs("div",{className:"nc-set-confirm",children:[c.jsx("div",{children:m("token-rotate-explain")}),c.jsxs("div",{className:"nc-sheet-actions",children:[c.jsx("button",{type:"button",className:"nc-btn ghost",disabled:S,onClick:()=>w(!1),children:m("cancel")}),c.jsx("button",{type:"button",className:"nc-btn primary",disabled:S,onClick:V,children:m("confirm")})]})]}),p&&c.jsx("div",{className:"nc-set-note",children:p}),h&&c.jsx("div",{className:"nc-err",children:h})]})}function qN({token:e,onClose:t,initialTab:n="nodes",initialLocation:s="",startNewCell:o=!1}){$n();const a=n==="diagnostics"?"diagnostics":"general",[u,h]=E.useState(n==="diagnostics"?"system":n),f=E.useRef(null),p=E.useRef(null),[v,b]=E.useState({start:!1,end:!1}),[w,S]=E.useState(a),[y,x]=E.useState(null),[C,R]=E.useState([]),[k,$]=E.useState(!1),[O,V]=E.useState(null),[Y,z]=E.useState(0),ne=Wh(e,!0,Y),H=E.useCallback(()=>{const I=f.current;if(!I)return;const A=I.scrollWidth>I.clientWidth+1,N={start:A&&I.scrollLeft>1,end:A&&I.scrollLeft+I.clientWidth<I.scrollWidth-1};b(M=>M.start===N.start&&M.end===N.end?M:N)},[]);E.useEffect(()=>{const I=f.current;if(!I)return;const A=typeof ResizeObserver=="function"?new ResizeObserver(H):null;return A==null||A.observe(I),window.addEventListener("resize",H),H(),()=>{A==null||A.disconnect(),window.removeEventListener("resize",H)}},[H]),E.useEffect(()=>{var A,N;(N=(A=p.current)==null?void 0:A.scrollIntoView)==null||N.call(A,{behavior:"smooth",block:"nearest",inline:"nearest"});const I=window.requestAnimationFrame?window.requestAnimationFrame(H):setTimeout(H,0);return()=>{window.cancelAnimationFrame?window.cancelAnimationFrame(I):clearTimeout(I)}},[u,H]);const X=E.useCallback(async()=>{try{const I=await H_(e);x(I),V(null)}catch(I){V(String(I.message||I))}try{const I=await h0(e);R(I.peers||[])}catch(I){V(String(I.message||I))}},[e]);return E.useEffect(()=>{X();const I=setInterval(X,5e3);return()=>clearInterval(I)},[X]),E.useEffect(()=>{let I=!1;return Vt("/api/config",e).then(A=>A.json()).then(A=>{I||$(!!A.readonlyDefault)}).catch(()=>{}),()=>{I=!0}},[e]),c.jsx("div",{className:"nc-set-overlay",onClick:t,children:c.jsxs("div",{className:"nc-set-panel",onClick:I=>I.stopPropagation(),children:[c.jsxs("div",{className:"nc-set-head",children:[c.jsx(it,{name:"gear",size:18}),c.jsx("b",{children:m("settings")}),c.jsx("button",{type:"button",className:"nc-set-close",onClick:t,title:m("close"),children:c.jsx(it,{name:"x",size:18})})]}),k&&c.jsx("div",{className:"nc-set-readonly",children:m("settings-readonly")}),O&&c.jsx("div",{className:"nc-err",children:O}),c.jsx("div",{className:`nc-set-tabs-wrap${v.start?" has-start-overflow":""}${v.end?" has-end-overflow":""}`,children:c.jsx("div",{className:"nc-set-tabs",ref:f,onScroll:H,children:["nodes","fleet","audio","input","system"].map(I=>c.jsx("button",{ref:u===I?p:null,type:"button",className:`nc-set-tabbtn${u===I?" on":""}`,onClick:()=>h(I),children:m(`tab-${I}`)},I))})}),c.jsxs("div",{className:"nc-set-body",children:[u==="nodes"&&c.jsx(zN,{token:e,nodes:C,roster:ne,settings:y,readonly:k,refresh:X,refreshAliases:()=>z(I=>I+1)}),u==="fleet"&&c.jsx(wN,{token:e,readonly:k,startNewCell:o,initialLocation:s,targets:ne.map(I=>({route:I.route,label:I.label||I.name,status:I.status}))}),u==="audio"&&c.jsx(HN,{token:e,readonly:k,nodes:C,settings:y}),u==="input"&&c.jsx(WN,{}),u==="system"&&c.jsx(KN,{token:e,settings:y,readonly:k,refresh:X,roster:ne,section:w,setSection:S})]})]})})}function VN({token:e,initialPair:t,deviceDefault:n="",localNodeId:s="",localNameDefault:o="",onPairDone:a,onDone:u}){$n();const[h,f]=E.useState(t?"pair":"welcome"),[p,v]=E.useState(!1),[b,w]=E.useState(null),S=async()=>{v(!0),w(null);try{await Ld(e,{wizardDone:!0}),a&&a(),u()}catch(y){w(String(y.message||y)),v(!1)}};return c.jsx("div",{className:"nc-wiz-overlay",children:c.jsxs("div",{className:"nc-wiz",children:[c.jsxs("div",{className:"nc-wiz-head",children:[c.jsx("b",{children:m("wizard-title")}),c.jsx("small",{children:m("hydra-simple")})]}),h==="welcome"&&c.jsxs("div",{className:"nc-wiz-body",children:[c.jsx("div",{className:"nc-wiz-done",children:m("local-ready")}),c.jsxs("div",{className:"nc-sheet-actions",children:[c.jsx("button",{className:"nc-btn ghost",disabled:p,onClick:S,children:m("local-only")}),c.jsx("button",{className:"nc-btn primary",disabled:p,onClick:()=>f("pair"),children:m("add-node")})]})]}),h==="pair"&&c.jsxs("div",{className:"nc-wiz-body",children:[c.jsx(Tw,{token:e,initial:t||"",autoStart:!!t,deviceDefault:n,localNodeId:s,localNameDefault:o,onBusyChange:v,onSuccess:async()=>{a&&a(),f("done")}}),c.jsx("div",{className:"nc-sheet-actions",children:c.jsx("button",{className:"nc-btn ghost",disabled:p,onClick:()=>{a&&a(),f("welcome")},children:m("back")})})]}),h==="done"&&c.jsxs("div",{className:"nc-wiz-body",children:[c.jsx("div",{className:"nc-wiz-done",children:m("node-connected")}),c.jsx("div",{className:"nc-sheet-actions",children:c.jsx("button",{className:"nc-btn primary",disabled:p,onClick:S,children:m("finish")})})]}),b&&c.jsx("div",{className:"nc-err",children:b})]})})}function YN(e,t){if(typeof EventSource>"u"||!e)return()=>{};const n=new EventSource(`/api/events?token=${encodeURIComponent(e)}`);return n.onmessage=s=>{try{const o=JSON.parse(s.data);o&&typeof o=="object"&&typeof o.type=="string"&&t(o)}catch{}},()=>{try{n.close()}catch{}}}const GN=6e3,XN=12e3;function JN({n:e,onClose:t}){return c.jsxs("div",{className:`nc-ntf-toast${e.urgency==="high"?" high":""}`,role:"status","aria-live":"polite",children:[c.jsxs("div",{className:"nc-ntf-toast-txt",children:[c.jsx("b",{children:e.title}),e.body&&c.jsx("small",{children:e.body}),e.session&&c.jsx("span",{className:"nc-ntf-from",children:e.session})]}),c.jsx("button",{type:"button",className:"nc-ntf-x",onClick:t,title:m("close"),children:c.jsx(it,{name:"x",size:14})})]})}function QN({ask:e,token:t,onAnswered:n}){const[s,o]=E.useState(""),[a,u]=E.useState(!1),[h,f]=E.useState(null),p=async v=>{const b=String(v||"").trim();if(!(!b||a)){f(null),u(!0);try{await A0(t,e.id,b),n(e.id)}catch(w){f(String(w.message||w))}u(!1)}};return c.jsxs("div",{className:"nc-ask-card",children:[c.jsxs("div",{className:"nc-ask-head",children:[c.jsx("span",{className:"nc-ntf-from",children:e.session}),c.jsxs("code",{className:"nc-ask-id",children:["#",e.id]})]}),c.jsx("div",{className:"nc-ask-q",children:e.question}),Array.isArray(e.options)&&e.options.length>0&&c.jsx("div",{className:"nc-ask-opts",children:e.options.map(v=>c.jsx("button",{type:"button",className:"nc-btn ghost",disabled:a,onClick:()=>p(v),children:v},v))}),c.jsxs("div",{className:"nc-ask-reply",children:[c.jsx("textarea",{rows:2,placeholder:m("ask-reply-ph"),value:s,disabled:a,onChange:v=>o(v.target.value)}),c.jsx("button",{type:"button",className:"nc-btn primary",disabled:a||!s.trim(),onClick:()=>p(s),children:m("send")})]}),h&&c.jsx("div",{className:"nc-err",children:h})]})}function ZN({token:e}){const[t]=$n(),[n]=Vw(),[s,o]=E.useState([]),[a,u]=E.useState([]),[h,f]=E.useState(()=>{try{return/(?:^|[#&])ask=/.test(location.hash)}catch{return!1}}),p=E.useRef(0),v=E.useRef(null);v.current||(v.current=IN());const b=E.useRef({enabled:n,lang:t});b.current={enabled:n,lang:t};const w=E.useCallback(x=>{o(C=>C.filter(R=>R.key!==x))},[]),S=E.useCallback(x=>{const C=`t${p.current+=1}`;o(k=>[...k.slice(-3),{...x,key:C}]),setTimeout(()=>w(C),x.urgency==="high"?XN:GN);const R=b.current;if(R.enabled)try{v.current.enqueue(x,LN(x,R.lang))}catch{}},[w]);E.useEffect(()=>{n||v.current.stop()},[n]),E.useEffect(()=>{const x=()=>{(document.visibilityState!=="visible"||!document.hasFocus())&&v.current.stop()},C=()=>v.current.stop();return document.addEventListener("visibilitychange",x),window.addEventListener("blur",x),window.addEventListener(Nh,C),()=>{document.removeEventListener("visibilitychange",x),window.removeEventListener("blur",x),window.removeEventListener(Nh,C),typeof v.current.dispose=="function"?v.current.dispose():v.current.stop()}},[]),E.useEffect(()=>{if(!e)return;let x=!1;M0(e).then(R=>{x||u(R.asks||[])}).catch(()=>{});const C=YN(e,R=>{R.type==="notify"?S(R):R.type==="ask"&&R.ask&&R.ask.id?u(k=>k.some($=>$.id===R.ask.id)?k:[...k,R.ask]):R.type==="ask-answered"&&R.id&&u(k=>k.filter($=>$.id!==R.id))});return()=>{x=!0,C()}},[e,S]);const y=x=>u(C=>C.filter(R=>R.id!==x));return c.jsxs(c.Fragment,{children:[s.length>0&&c.jsx("div",{className:"nc-ntf-toasts",children:s.map(x=>c.jsx(JN,{n:x,onClose:()=>w(x.key)},x.key))}),a.length>0&&!h&&c.jsxs("button",{type:"button",className:"nc-ask-badge",onClick:()=>f(!0),title:m("asks-title"),children:["? ",c.jsx("span",{className:"nc-ask-count",children:a.length})]}),a.length>0&&h&&c.jsxs("div",{className:"nc-ask-panel",children:[c.jsxs("div",{className:"nc-ask-panel-head",children:[c.jsx("b",{children:m("asks-title")}),c.jsx("span",{className:"nc-ask-count",children:a.length}),c.jsx("button",{type:"button",className:"nc-ntf-x",onClick:()=>f(!1),title:m("close"),children:c.jsx(it,{name:"x",size:16})})]}),c.jsx("div",{className:"nc-ask-panel-body",children:a.map(x=>c.jsx(QN,{ask:x,token:e,onAnswered:y},x.id))})]})]})}const eR=4e3;async function tR(e){const t=await Vt("/api/sessions",e);if((t==null?void 0:t.ok)===!1)throw new Error(`HTTP ${t.status}`);const n=await t.json();if(!Array.isArray(n==null?void 0:n.sessions))throw new Error("invalid sessions payload");return n.sessions}async function Rd(e,t=[]){var h;const[n,s]=await Promise.allSettled([t.length?zh(e,t):tR(e),_s(e,t)]),o=n.status==="fulfilled"&&Array.isArray((h=n.value)==null?void 0:h.sessions)?n.value.sessions:Array.isArray(n.value)?n.value:null,a=s.status==="fulfilled"?s.value:null,u=(a==null?void 0:a.available)===!0&&Array.isArray(a.cells)?a.cells:null;return{sessions:o,cells:u,fresh:Array.isArray(o)&&Array.isArray(u)}}function Yw(e,t,n){return n===!0&&(e==null?void 0:e.degraded)!==!0&&(e==null?void 0:e.active)===!0&&e.tmux!==!1&&!!e.tmuxSession&&(t||[]).some(s=>(s==null?void 0:s.name)===e.tmuxSession)}function nR(e){const t=new Map((e.sessions||[]).map(o=>[o.name,o])),n=[],s=(o,a,u,h=[],f="")=>{const p=new Map((a||[]).map(v=>[v.name,v]));for(const v of o||[]){const b=p.get(v.tmuxSession)||{},w=qh(v,b),S=Yw(v,a,u);n.push({key:Bo(h,v.tmuxSession||v.cell),session:v.tmuxSession,route:h,cellName:v.cell,label:v.cell,node:h.length?h.join("/"):"",nodeLabel:f,live:S,selectable:S,verified:u===!0,working:w.working,degraded:!!v.degraded,activity:b.activity||v.activity||0,subtitle:w.subtitle})}};s(e.cells,[...t.values()],e.localFresh===!0);for(const o of e.nodeGroups||[])s(o.cells,o.sessions,o.switcherFresh===!0,Array.isArray(o.route)?o.route:[],o.label||o.name||"");return n}function iR(e){const t=new Map,n=Array.isArray(e.sessions)?e.sessions:[],s=Array.isArray(e.cells)?e.cells:[],o=new Map(n.map(u=>[u.name,u])),a=new Set(s.map(u=>u.tmuxSession).filter(Boolean));t.set("local",Vh(s,n.filter(u=>!a.has(u.name)),o));for(const u of e.nodeGroups||[]){const h=Array.isArray(u.route)?u.route:[];if(!h.length)continue;const f=Array.isArray(u.cells)?u.cells:[],p=Array.isArray(u.sessions)?u.sessions:[],v=new Set(f.map(b=>b.tmuxSession).filter(Boolean));t.set(h.join("/"),Pl({...u,route:h,cells:f,sessions:p,unmanaged:p.filter(b=>!v.has(b.name))}).rawItems)}return t}function sR(e,t,n,s){return[...new Set(e.map(a=>a.node||"local"))].flatMap(a=>{const u=e.filter(v=>(v.node||"local")===a),h=new Map((t.get(a)||[]).map(v=>[v.key,v])),f=new Map(u.map(v=>[v.key,v])),p=u.map(v=>{const b=h.get(v.key);return{...v,label:(b==null?void 0:b.label)||v.label,live:(b==null?void 0:b.live)??v.live,fresh:(b==null?void 0:b.fresh)===!0,activity:(b==null?void 0:b.activity)??v.activity}});return ps(p,n,"all",Ai(s,a)).map(v=>f.get(v.key))})}function rR({token:e,current:t,onPick:n,onClose:s}){const[o,a]=E.useState(Eg),[u,h]=E.useState(!1),[f,p]=E.useState(!1),[v,b]=E.useState(""),[w,S]=E.useState(""),[y,x]=E.useState(""),C=E.useRef(null),R=E.useRef(null),k=E.useMemo(()=>nR(o),[o]),$=E.useMemo(()=>iR(o),[o]),{pins:O,orders:V,canMoveRoster:Y,moveRoster:z,stepRoster:ne}=Kh(),H=E.useMemo(()=>sR(k,$,O,V),[k,$,O,V]),X=E.useMemo(()=>u?H:H.filter(L=>L.selectable||L.degraded),[H,u]),I=E.useMemo(()=>k.find(L=>L.key===w&&L.selectable),[k,w]);E.useEffect(()=>{var F;const L=document.activeElement;(F=R.current)==null||F.focus();const P=T=>{T.key==="Escape"&&s()};return document.addEventListener("keydown",P),()=>{var T;document.removeEventListener("keydown",P),(T=L==null?void 0:L.focus)==null||T.call(L)}},[s]),E.useEffect(()=>{let L=!0,P=!1;const F=async()=>{if(P)return;P=!0;const q=Eg(),B=Array.isArray(q.nodeGroups)?q.nodeGroups:[],D=Rd(e),U=await Promise.all(B.map(async J=>{const ee=Array.isArray(J.route)?J.route:[];return ee.length?{group:J,result:await Rd(e,ee)}:{group:J,result:{fresh:!1,sessions:null,cells:null}}})),Z=await D;if(!L)return;const oe=new Map(U.map(({group:J,result:ee})=>[JSON.stringify(J.route||[]),ee])),de=B.map(J=>{const ee=oe.get(JSON.stringify(J.route||[]));return ee?{...J,sessions:ee.sessions||J.sessions||[],cells:ee.cells||J.cells||[],switcherFresh:ee.fresh}:{...J,switcherFresh:!1}}),fe=ry({...q,sessions:Z.sessions||q.sessions||[],cells:Z.cells||q.cells||[],localFresh:Z.fresh,nodeGroups:de,refreshedAt:Date.now()});a(fe),p(!0),P=!1};F();const T=setInterval(F,eR);return()=>{L=!1,clearInterval(T)}},[e]);const A=L=>L.degraded?m("cell-degraded"):L.verified?L.selectable?L.working?m("cell-working"):m("cell-idle"):m("cell-off"):m("cell-switcher-not-confirmed"),N=L=>{if(b(""),!L.selectable){b(m("cell-switcher-not-active"));return}S(L.key)},M=async()=>{const L=I;if(!L){b(m("cell-switcher-select"));return}b(""),x(L.key);try{const P=await Rd(e,L.route),F=(P.cells||[]).find(T=>(T==null?void 0:T.cell)===L.cellName&&(T==null?void 0:T.tmuxSession)===L.session);if(!Yw(F,P.sessions,P.fresh)){b(m("cell-switcher-not-active"));return}n({session:L.session,...L.node?{node:L.node}:{},cellName:L.cellName}),s()}catch{b(m("cell-switcher-not-active"))}finally{x("")}};return c.jsx("div",{className:"nc-cell-switcher-backdrop",onClick:s,children:c.jsxs("aside",{ref:C,className:"nc-cell-switcher",role:"dialog","aria-label":m("fleet-cells"),tabIndex:-1,onClick:L=>L.stopPropagation(),children:[c.jsxs("div",{className:"nc-cell-switcher-list",children:[!f&&c.jsx("div",{className:"nc-empty",role:"status",children:m("cell-switcher-refreshing")}),f&&X.length===0&&c.jsx("div",{className:"nc-empty",role:"status",children:m("cell-switcher-empty-active")}),X.map(L=>{const P=(t==null?void 0:t.session)===L.session&&((t==null?void 0:t.node)||"")===L.node,F=w===L.key,T=A(L),q=L.node||"local",B=$.get(q)||k.filter(D=>(D.node||"local")===q);return c.jsxs("div",{className:`nc-cell-switcher-row${P?" current":""}${F?" selected":""}${L.selectable?"":" off"}`,"data-roster-key":L.key,"data-position":q,children:[c.jsx(Di,{position:q,itemKey:L.key,label:L.cellName,canMove:Y,onMove:(D,U)=>z(q,D,U,B),onStep:D=>ne(q,L.key,D,B)}),c.jsxs("button",{type:"button",className:"nc-cell-switcher-row-select","aria-current":P?"true":void 0,"aria-pressed":F,"aria-disabled":!L.selectable,disabled:y===L.key,onClick:()=>N(L),children:[c.jsx("span",{className:`nc-cell-switcher-dot${L.degraded?" warn":L.live?` on${L.working?" working":""}`:""}`}),c.jsxs("span",{className:"nc-cell-switcher-copy",children:[c.jsx("b",{children:L.cellName}),c.jsx("small",{className:"nc-cell-switcher-state",children:T}),c.jsx("small",{children:[L.nodeLabel,L.subtitle].filter(Boolean).join(" · ")})]})]})]},L.key)})]}),v&&c.jsx("div",{className:"nc-cell-switcher-notice",role:"status",children:v}),c.jsx("div",{className:"nc-cell-switcher-actions",children:c.jsx("button",{type:"button",className:"nc-cell-switcher-open",disabled:!I||!!y,onClick:M,children:I?`${m("cell-switcher-open")}: ${I.cellName}`:m("cell-switcher-select")})}),c.jsxs("div",{className:"nc-cell-switcher-controls",children:[c.jsx("b",{children:m("fleet-cells")}),c.jsx("button",{type:"button",className:"nc-cell-switcher-filter","aria-pressed":u,onClick:()=>{b(""),h(L=>!L)},children:m(u?"cell-switcher-show-active":"cell-switcher-show-all")}),c.jsx("button",{ref:R,type:"button",className:"nc-cell-switcher-close","aria-label":m("cell-switcher-close"),title:m("cell-switcher-close"),onClick:s,children:"×"})]})]})})}const jd=e=>wi($s(e)).length===0,Pd=e=>Array.isArray(e)?e.join("/"):"";function oR(e){const t=new Set,n=[];for(const s of Array.isArray(e)?e:[])!s||!zn.test(String(s.instanceId||""))||!Array.isArray(s.route)||!s.route.length||t.has(s.instanceId)||(t.add(s.instanceId),n.push({instanceId:s.instanceId,route:[...s.route],label:String(s.label||s.name||s.route.join(" › ")),status:s.status||"offline"}));return n.sort((s,o)=>s.label.localeCompare(o.label))}function Ro(e){return{instanceId:e.ownerId,route:e.ownerRoute||[],label:e.ownerLabel,status:e.available===!1?"offline":"up"}}function As(e,t,n,s=!1,o=!0){const a=t.instanceId;return{...e,id:Cr(s?null:a,e.name),ownerId:a,ownerRoute:s?[]:[...t.route],ownerLabel:s?"Local":t.label,local:s,available:o,ownerTopology:Array.isArray(n)?n:[],layout:xh(e.layout,a,n)}}function aR(e,t,n,s,o=[]){const[a,u]=E.useState([]),[h,f]=E.useState(!1),[p,v]=E.useState("idle"),[b,w]=E.useState(""),[S,y]=E.useState(""),x=E.useRef([]),C=E.useRef([]),R=E.useRef(""),k=E.useRef(t),$=E.useRef(n),O=E.useRef(!1),V=E.useRef(!0),Y=E.useRef(""),z=E.useMemo(()=>oR(o),[o]),ne=z.map(B=>`${B.instanceId}:${Pd(B.route)}:${B.status}:${B.label}`).join("|");C.current=z,$.current=n,k.current=t,x.current=a;const H=E.useCallback(B=>kh(B.layout,R.current,C.current),[]),X=E.useCallback((B,D=!0,U=k.current)=>{const Z=Ov(B,hl()),oe=x.current.some(fe=>fe.id===U);x.current=Z,u(Z);const de=Z.find(fe=>fe.id===U);if(D&&de){V.current=!0;const fe=H(de);s(fe),de.local&&VE(de.name,fe)}else oe&&!de&&(V.current=!0,s(kr()),w("deck non più condiviso dal nodo owner"));WE(Z.filter(fe=>fe.local).map(fe=>fe.name))},[s,H]),I=E.useCallback(async B=>{let D=await il(e);const U=D.decks.find(Z=>Z.name==="main");if(D.decks.length===1&&U&&U.revision===0&&jd(U.layout)){const Z=HE(),oe=$s(Ch("main")||kr());if(!jd(oe)){const de=xh(oe,B,[]);D.decks[0]=await sl(e,"main",de,0,[])}for(const de of Z.filter(fe=>fe!=="main"))try{let fe=await hg(e,de,[]);const J=$s(Ch(de)||kr());jd(J)||(fe=await sl(e,de,xh(J,B,[]),fe.revision,[]))}catch{}D=await il(e)}return D},[e]),A=E.useCallback(async({migrate:B=!1}={})=>{const D=await Fh(e,[]),U=zn.test(String(D.instanceId||""))?D.instanceId:"";if(!U)throw new Error("instanceId locale non disponibile");R.current=U,y(U);const[Z,oe]=await Promise.all([B?I(U):il(e),ag(e,[]).catch(()=>({nodes:[]}))]),de={instanceId:U,route:[],label:"Local"},fe=Z.decks.map(ee=>As(ee,de,oe.nodes,!0,!0)),J=x.current;return await Promise.all(C.current.map(async ee=>{if(ee.status!=="up"){fe.push(...J.filter(pe=>!pe.local&&pe.ownerId===ee.instanceId).map(pe=>({...pe,ownerRoute:[...ee.route],ownerLabel:ee.label,available:!1})));return}try{const[pe,Se]=await Promise.all([il(e,ee.route),ag(e,ee.route).catch(()=>({nodes:[]}))]);fe.push(...pe.decks.map(Ze=>As(Ze,ee,Se.nodes,!1,!0)))}catch{fe.push(...J.filter(Se=>!Se.local&&Se.ownerId===ee.instanceId).map(Se=>({...Se,ownerRoute:[...ee.route],ownerLabel:ee.label,available:!1})))}})),fe.sort((ee,pe)=>ee.local===pe.local?ee.ownerLabel.localeCompare(pe.ownerLabel)||(ee.name==="main"?-1:pe.name==="main"?1:ee.name.localeCompare(pe.name)):ee.local?-1:1),fe},[e,I,ne]);E.useEffect(()=>{if(!e)return;let B=!1;const D=Y.current!==e;return Y.current=e,A({migrate:D}).then(U=>{if(B)return;const Z=x.current.find(fe=>fe.id===k.current),oe=U.find(fe=>fe.id===k.current),de=oe&&(!Z||oe.revision>Z.revision||Z.available!==oe.available||Pd(Z.ownerRoute)!==Pd(oe.ownerRoute));X(U,D||!!de&&!O.current),f(!0),oe&&w("")}).catch(U=>{B||(f(!0),w(String(U.message||U)))}),()=>{B=!0}},[X,A,ne,e]);const N=E.useCallback(async(B=k.current)=>{if(!h||!O.current)return!0;const D=x.current.find(U=>U.id===B);if(!D)return w(`deck inesistente: ${B}`),!1;if(D.available===!1)return w(`nodo owner offline: ${D.ownerLabel}`),!1;v("saving");try{const U=Iv($s($.current),D.ownerId,D.ownerTopology),Z=await sl(e,D.name,U,D.revision,D.ownerRoute),oe=As(Z,Ro(D),D.ownerTopology,D.local,!0);return X(x.current.map(de=>de.id===B?oe:de),!1),O.current=!1,v("saved"),w(""),setTimeout(()=>v("idle"),1500),!0}catch(U){if(v("error"),w(String(U.message||U)),U.status===409&&U.data&&U.data.current){const Z=x.current.find(de=>de.id===B),oe=As(U.data.current,Ro(Z),Z.ownerTopology,Z.local,!0);X(x.current.map(de=>de.id===B?oe:de),!1)}return!1}},[h,e,X]);return E.useEffect(()=>{if(!h)return;if(V.current){V.current=!1;return}O.current=!0,v("saving");const B=setTimeout(N,650);return()=>clearTimeout(B)},[n,h,N]),E.useEffect(()=>{if(!h)return;const B=setInterval(async()=>{try{const D=await A(),U=x.current.find(de=>de.id===k.current),Z=D.find(de=>de.id===k.current),oe=Z&&(!U||Z.revision>U.revision||U.available!==Z.available);X(D,oe&&!O.current)}catch{}},5e3);return()=>clearInterval(B)},[h,A,X]),{decks:a,records:a,localNodeId:S,ready:h,saveState:p,error:b,setError:w,saveNow:N,select:async B=>{if(O.current&&!await N(k.current))throw new Error("salvataggio del deck corrente fallito: cambio annullato");const D=x.current.find(U=>U.id===B);if(!D)throw new Error(`deck inesistente: ${B}`);return O.current=!1,V.current=!0,H(D)},add:async(B,D=null)=>{const U=D===_i?x.current.find(de=>de.local):D?x.current.find(de=>de.ownerId===D):null;if(!U||U.available===!1)throw new Error("nodo owner non disponibile");const Z=await hg(e,B,U.ownerRoute),oe=As(Z,Ro(U),U.ownerTopology,U.local,!0);return X([...x.current,oe],!1),oe},rename:async(B,D)=>{const U=x.current.find(J=>J.id===B);if(!U)throw new Error("deck inesistente");if(B===k.current&&O.current&&!await N(B))throw new Error(`salvataggio di "${U.name}" fallito: rinomina annullata`);const Z=x.current.find(J=>J.id===B);if(!Z)throw new Error("deck inesistente");const oe=await I0(e,Z.name,D,Z.revision,Z.ownerRoute),de=As(oe,Ro(Z),Z.ownerTopology,Z.local,!0),fe=Z.local?_i:Z.ownerId;return nd(KE(hl(),fe,B,de.id)),X(x.current.map(J=>J.id===B?de:J),!1),de},remove:async B=>{const D=x.current.find(Z=>Z.id===B);if(!D)throw new Error("deck inesistente");B===k.current&&(O.current=!1),await B0(e,D.name,D.revision,D.ownerRoute);const U=D.local?_i:D.ownerId;nd(qE(hl(),U,B)),X(x.current.filter(Z=>Z.id!==B),!1)},reorder:(B,D)=>{const U=x.current.find(ee=>ee.id===B),Z=x.current.find(ee=>ee.id===D);if(!U||!Z)return!1;const oe=U.local?_i:U.ownerId,de=Z.local?_i:Z.ownerId;if(oe!==de)return!1;const fe=x.current.filter(ee=>(ee.local?_i:ee.ownerId)===oe).map(ee=>ee.id),J=nd(UE(hl(),oe,B,D,fe));return X(Ov(x.current,J),!1),!0},addTileTo:async(B,D)=>{const U=x.current.find(ee=>ee.id===B);if(!U)throw new Error("deck inesistente");if(U.available===!1)throw new Error(`nodo owner offline: ${U.ownerLabel}`);const Z=pw(D,R.current,C.current);if(!Z)throw new Error("riferimento sessione non valido");const oe=H(U),de=Iv(ny(oe,Z),U.ownerId,U.ownerTopology),fe=await sl(e,U.name,de,U.revision,U.ownerRoute),J=As(fe,Ro(U),U.ownerTopology,U.local,!0);return X(x.current.map(ee=>ee.id===B?J:ee),!1),J},localMainId:Cr(null,"main"),parseDeckId:Yl}}const lR="/sw.js",jh="nc-sw-update";let Ph=null,Lh=!1,Th=null,Gw=Object.freeze({needed:!1,kind:null,version:""}),Xw=!1;function Jw(){typeof window<"u"&&window.dispatchEvent(new Event(jh))}function Qw(){const e=Th||(Lh?{kind:"reload",version:""}:null);Gw=Object.freeze({needed:!!e,kind:(e==null?void 0:e.kind)||null,version:(e==null?void 0:e.version)||""})}function j_(){return Gw}function cR(e){return typeof window>"u"?()=>{}:(window.addEventListener(jh,e),()=>window.removeEventListener(jh,e))}function Cf(e){Lh!==e&&(Lh=e,Qw(),Jw())}function uR(e,t,n){let s=null;e&&t&&e!==t?s={kind:"install",version:e}:t&&n&&t!==n&&(s={kind:"reload",version:t});const o=JSON.stringify(s)===JSON.stringify(Th);Th=s,Qw(),o||Jw()}function dR(e){e.addEventListener("statechange",()=>{e.state==="installed"&&navigator.serviceWorker.controller&&Cf(!0)})}function hR(){typeof navigator>"u"||!("serviceWorker"in navigator)||(navigator.serviceWorker.addEventListener("controllerchange",()=>{Xw&&location.reload()}),navigator.serviceWorker.register(lR).then(e=>{Ph=e,e.waiting&&Cf(!0),e.addEventListener("updatefound",()=>{const t=e.installing;t&&dR(t)}),setInterval(()=>{e.update().catch(()=>{})},3600*1e3)}).catch(()=>{}))}function fR(){Xw=!0,Cf(!1);const e=Ph&&Ph.waiting;e?(e.postMessage({type:"SKIP_WAITING"}),setTimeout(()=>location.reload(),4e3)):location.reload()}function pR({hash:e="",origin:t="",pathname:n="",search:s=""}={}){const o=String(e||"").replace(/^#/,""),a=`${n||""}${s||""}`;if(!o)return{token:"",pair:"",nextUrl:a};const u=new URLSearchParams(o),h=u.get("token")||"",f=u.get("pair")||"",p=f?`${t||""}${n||""}#pair=${f}`:"";return{token:h,pair:p,nextUrl:a}}const Zw=9,eS=24,tS="nc_side_w",P_="nc_side_min",mR=240,L_="(min-width:1024px) and (pointer:fine)";function gR(){const e=Number(localStorage.getItem(tS));return e>=180&&e<=480?e:mR}function vR(){const e=Number(localStorage.getItem("nc_fontsize"));return e>=Zw&&e<=eS?e:13}function _R(){const e={token:"",pair:""};try{const{token:t,pair:n,nextUrl:s}=pR({hash:location.hash,origin:location.origin,pathname:location.pathname,search:location.search});if(t){e.token=t;try{localStorage.setItem("nc_token",t)}catch{}}if(n){e.pair=n;try{sessionStorage.setItem("nc_pair",n)}catch{}}if(location.hash)try{history.replaceState(null,"",s)}catch{}}catch{}if(e.token||(e.token=sessionStorage.getItem("nc_token")||localStorage.getItem("nc_token")||""),!e.pair){const t=sessionStorage.getItem("nc_pair");t&&(e.pair=t)}return e}function yR(e){try{return $s(Ch(e))}catch{return kr()}}function T_(e){if(!e)return"";const t=Math.floor(Date.now()/1e3)-e;return t<0||t<60?"ora":t<3600?`${Math.floor(t/60)}m`:t<86400?`${Math.floor(t/3600)}h`:`${Math.floor(t/86400)}g`}function wR(){const[e,t]=E.useState(()=>window.matchMedia(L_).matches);return E.useEffect(()=>{const n=window.matchMedia(L_),s=o=>t(o.matches);return n.addEventListener("change",s),()=>n.removeEventListener("change",s)},[]),e}function D_({session:e,node:t,ownerId:n,cellName:s,token:o,readonly:a=!1,onBack:u,onCellSwitcher:h,cellSwitcherOpen:f=!1}){$n();const[p]=uf(),[v,b]=E.useState(!1),[w,S]=E.useState(()=>window.matchMedia("(pointer: coarse)").matches),[y,x]=E.useState(null),[C,R]=E.useState(vR),[k,$]=E.useState(s||e),[O,V]=E.useState(""),Y=P=>R(F=>{const T=Math.max(Zw,Math.min(eS,F+P));return localStorage.setItem("nc_fontsize",String(T)),T}),z=E.useRef(()=>{}),ne=E.useRef(()=>!1),H=E.useRef(()=>{}),X=E.useRef(!1),[I,A]=E.useState(!1),[N,M]=E.useState(!1),L=()=>{X.current=!X.current,A(X.current)};return E.useEffect(()=>{$(s||e)},[s,e]),E.useEffect(()=>{let P=!0;const F=t?t.split("/"):[],T=t?`/api/route/${t.split("/").map(encodeURIComponent).join("/")}/_`:"/api";async function q(){let D=null,U=null;try{const de=await(await Vt(`${T}/sessions`,o)).json();Array.isArray(de.sessions)&&(D=de.sessions.find(fe=>fe.name===e))}catch{}try{const oe=await _s(o,F);oe.available&&Array.isArray(oe.cells)&&(U=oe.cells.find(de=>de.tmuxSession===e))}catch{}if(!P)return;$(df({session:e,cell:U||(s?{cell:s}:null)}));let Z="";U?Z=`${U.engine}${U.key?`·${U.key}`:""}`:D&&(Z=D.attached?`attached · ${T_(D.activity)}`:D.activity?T_(D.activity):""),V(Z)}q();const B=setInterval(q,4e3);return()=>{P=!1,clearInterval(B)}},[e,t,o]),c.jsxs("div",{className:"nc-app",children:[c.jsxs("header",{className:"nc-bar nc-bar-single",children:[c.jsxs("button",{onClick:u,title:m("sessions"),children:[c.jsx(it,{name:"chevronLeft",size:18}),c.jsx("span",{className:"nc-bar-label",children:m("sessions")})]}),c.jsxs("span",{className:"nc-bar-center",children:[c.jsx("b",{title:t?`${k} · ${t}`:k,children:k}),O&&c.jsx("small",{className:"nc-bar-sub",children:O})]}),c.jsxs("span",{className:"nc-bar-right",children:[c.jsx("button",{onClick:()=>Y(-1),title:m("zoom-out"),children:c.jsx(it,{name:"zoomOut",size:18})}),c.jsx("button",{onClick:()=>Y(1),title:m("zoom-in"),children:c.jsx(it,{name:"zoomIn",size:18})}),c.jsx("button",{onClick:()=>S(P=>!P),title:m("composer"),children:c.jsx(it,{name:"keyboard",size:20})}),c.jsx("button",{onClick:()=>b(P=>!P),title:m("files"),children:c.jsx(it,{name:"folder",size:20})})]})]}),c.jsx("div",{className:"nc-termwrap",children:c.jsx(Zy,{session:e,node:t,token:o,readonly:a,takeSize:!0,sendRef:z,composerRef:ne,actionRef:H,ctrlRef:X,setCtrlArmed:A,onFiles:x,fontSize:C,selectionMode:N,onSelectionModeChange:M,keyboardGesture:p.terminalKeyboardGesture})}),c.jsx(hE,{onKeyboard:()=>S(P=>!P),onCellSwitcher:h,cellSwitcherOpen:f,send:P=>z.current(P),action:P=>H.current(P),ctrlArmed:I,onCtrl:L,selectionMode:N,onSelectionMode:M,keepKeyboardClosed:p.keybarKeepsKeyboardClosed,showEnter:p.showKeybarEnter,keybarLayout:p.keybarLayout}),w&&c.jsx(cw,{submitText:P=>ne.current(P),token:o,session:e,node:t,ownerId:n,keepKeyboardClosedOnVoice:p.voiceKeepsKeyboardClosed}),v&&c.jsx(ew,{session:e,node:t,token:o,filesEvent:y,onClose:()=>b(!1)})]})}function SR(){$n();const[e]=E.useState(_R),[t,n]=E.useState(e.token),[s,o]=E.useState(e.pair||""),a=E.useCallback(()=>{o("");try{sessionStorage.removeItem("nc_pair")}catch{}},[]),[u,h]=E.useState(!1),f=wR(),[p]=E.useState(()=>$E(typeof location<"u"?location.pathname:"/")),[v,b]=E.useState(p.id),w=v===Cr(null,Fn),[S,y]=E.useState(null),x=he=>{const Ne=vs(he);y(Ne?{...Ne,...typeof(he==null?void 0:he.cellName)=="string"&&he.cellName?{cellName:he.cellName}:{}}:null)},[C,R]=E.useState([]),[k,$]=E.useState([]),[O,V]=E.useState([]),[Y,z]=E.useState(()=>p.ownerId?kr():yR(p.name)),[ne,H]=E.useState(null),[X,I]=E.useState(null),A=he=>I(vs(he)),N=Wh(t,f),M=E.useMemo(()=>(N||[]).filter(he=>he.instanceId).map(he=>({instanceId:he.instanceId,route:he.route,label:he.label,status:he.status})),[N]),L=aR(t,v,Y,z,M),P=L.decks;E.useEffect(()=>{const he=new Map;for(const Ne of N||[]){const Ke=(Ne.route||[Ne.name]).join("/"),Nt=new Set((Ne.sessions||[]).map(pt=>pt.name));for(const pt of Ne.cells||[])!pt.cell||!pt.tmuxSession||pt.cell===pt.tmuxSession||Nt.has(pt.cell)||he.set(`${Ke}:${pt.cell}`,`${Ke}:${pt.tmuxSession}`)}z(Ne=>d1(Ne,he))},[N]),E.useEffect(()=>{L.localNodeId&&z(he=>{const Ne=kh(he,L.localNodeId,M);return JSON.stringify(Ne)===JSON.stringify(he)?he:Ne})},[M,L.localNodeId]);const[F,T]=E.useState(null),[q,B]=E.useState(null),D=E.useRef(0),[U,Z]=E.useState(!1),[oe,de]=E.useState(gR),[fe,J]=E.useState(!w),[ee,pe]=E.useState(()=>w?localStorage.getItem(P_)==="1":!0),[Se,Ze]=E.useState(!1),[$e,He]=E.useState("nodes"),[vt,Xe]=E.useState(!1),[St,Et]=E.useState(""),[rt,ct]=E.useState(!1),ot=(he="nodes",Ne=!1,Ke="")=>{He(he),Xe(Ne),Et(Ke),Ze(!0)},[ut,dt]=E.useState(!1),[le,xe]=E.useState({deviceDefault:"",localNodeId:"",localNameDefault:""}),[ze,Ie]=E.useState(!1);E.useEffect(()=>{try{localStorage.setItem(tS,String(oe))}catch{}},[oe]),E.useEffect(()=>{try{localStorage.setItem(P_,ee?"1":"")}catch{}},[ee]),E.useEffect(()=>{if(!t)return;let he=!1;return Promise.all([H_(t),Vt("/api/config",t).then(Ne=>Ne.json())]).then(([Ne,Ke])=>{he||(xe({deviceDefault:Ne.deviceName||"",localNodeId:Ne.nodeId||"",localNameDefault:Ne.localName||""}),Ie(!!Ke.readonlyDefault),(Ne.firstRun===!0&&!Ke.readonlyDefault||s)&&dt(!0))}).catch(()=>{}),()=>{he=!0}},[t,s]);const ue=E.useCallback(async()=>{try{const Ne=await(await Vt("/api/sessions",t)).json();Ne.error||R(Ne.sessions||[])}catch{}try{const he=await _s(t);$(he.available?he.cells||[]:[]),V(he.available?he.capabilities||[]:[])}catch{$([]),V([])}},[t]);E.useEffect(()=>{if(!f)return;ue();const he=setInterval(ue,4e3);return()=>clearInterval(he)},[f,ue]),E.useEffect(()=>{let he=!1;return Vt("/api/config",t).then(Ne=>Ne.json()).then(Ne=>{he||uR(Ne.version,Ne.uiVersion,"0.8.44")}).catch(()=>{}),()=>{he=!0}},[t]);const G=new Set([...C.map(he=>he.name),...N.flatMap(he=>he.sessions.map(Ne=>Ne.key))]),ie=wi(Y),W=he=>z(Ne=>{const Ke=pw(he,L.localNodeId,M)||he,Nt=ny(Ne,Ke);return Nt===Ne&&wi(Ne).length>=9&&L.setError(m("grid-full")),Nt}),se=async(he,Ne=[])=>{try{await Bh(t,he,Ne)}catch{return}const Ke=Ne.length?`${Ne.join("/")}:${he}`:he;z(Nt=>Tl(Nt,Ke)),ue()},ve=async(he,Ne,Ke=[])=>{try{await $_(t,he,Ne,Ke)}catch{return}ue()},ke=async(he,Ne,Ke=[])=>{await O_(t,{cell:he,enabled:!!Ne},Ke),ue()},Re=async he=>{if(!F)return;const{cell:Ne}=F,Ke=Array.isArray(F.route)?F.route:[];he.action==="up"?await Ah(t,{cell:Ne,boot:!!he.boot,...he.engine?{engine:he.engine}:{},...he.model!==void 0?{model:he.model}:{},...he.permissionPolicy?{permissionPolicy:he.permissionPolicy}:{}},Ke):await Cl(t,{cell:Ne,boot:!!he.boot},Ke);const Nt=he.action==="up"?!!he.boot:he.boot?!1:!!F.boot;B({id:++D.current,cell:Ne,route:Ke,enabled:Nt}),ue()},we=E.useCallback(he=>{B(Ne=>(Ne==null?void 0:Ne.id)===he?null:Ne)},[]),je=async he=>{if(!(!(he!=null&&he.direct)||U)){Z(!0);try{await $h(t,he.name,he.tunnelStatus==="up"?"down":"up")}finally{Z(!1)}}},st=async(he,Ne)=>{const Ke=String(Ne||"").trim();return!(he!=null&&he.direct)||!jr(Ke)?!1:(await W_(t,he.name,Ke),!0)},It=he=>{const Ne=P.find(Ke=>Ke.id===he);if(!Ne)return!1;try{const Ke=window.open(td(Ne,t),"_blank");return Ke&&(Ke.opener=null),!!Ke}catch{return!1}},Oe=async he=>{if(!he||he===v)return;const Ne=await L.select(he),Ke=L.records.find(Nt=>Nt.id===he);b(he),z(Ne),H(null),I(null);try{history.replaceState(null,"",td(Ke||he,null))}catch{}},_n=async(he,Ne)=>{const Ke=await L.add(he,Ne);await Oe(Ke.id)},bt=async(he,Ne)=>{const Ke=await L.rename(he,Ne);if(he===v){b(Ke.id),z(kh(Ke.layout,L.localNodeId,M)),H(null),I(null);try{history.replaceState(null,"",td(Ke,null))}catch{}}},Ye=async he=>{await L.remove(he),he===v&&await Oe(L.localMainId)},Gt=async(he,Ne)=>{!Ne||Ne===v||(await L.addTileTo(Ne,he),z(Ke=>Tl(Ke,he)))};if(!t)return c.jsxs("div",{className:"nc-auth",children:[c.jsx("p",{children:m("auth-prompt")}),c.jsx("input",{onChange:he=>n(he.target.value.trim()),placeholder:"token"}),c.jsxs("label",{children:[c.jsx("input",{type:"checkbox",checked:u,onChange:he=>h(he.target.checked)})," ",m("remember-device")]}),c.jsx("button",{onClick:()=>{(u?localStorage:sessionStorage).setItem("nc_token",t)},children:"ok"})]});const Hn=c.jsxs(c.Fragment,{children:[Se&&c.jsx(qN,{token:t,initialTab:$e,initialLocation:St,startNewCell:vt,onClose:()=>{Ze(!1),Xe(!1),Et("")}}),ut&&c.jsx(VN,{token:t,initialPair:s,...le,onPairDone:a,onDone:()=>dt(!1)}),c.jsx(ZN,{token:t})]});if(!f)return S?c.jsxs(c.Fragment,{children:[c.jsx(D_,{session:S.session,node:S.node,ownerId:S.ownerId,cellName:S.cellName,token:t,readonly:ze,onBack:()=>y(null),onCellSwitcher:()=>ct(!0),cellSwitcherOpen:rt}),rt&&c.jsx(rR,{token:t,current:S,onPick:he=>{x(he),ct(!1)},onClose:()=>ct(!1)}),Hn]}):c.jsxs(c.Fragment,{children:[c.jsx(E1,{onPick:x,token:t,onSettings:ot}),Hn]});const li=w||!fe;return c.jsxs("div",{className:"nc-workspace",children:[li&&c.jsx(jE,{sessions:C,cells:k,activeSessions:ie,nodeGroups:N,fleetCapabilities:O,bootSettlement:q,onBootSettlementApplied:we,localNodeId:L.localNodeId,onPick:A,onAddTile:W,onPower:T,onBoot:ke,onBootError:he=>L.setError(String((he==null?void 0:he.message)||he)),onNodePower:je,onNodeRename:st,onKill:se,onVisibility:ve,onNew:()=>ot("fleet",!0),onSettings:ot,width:oe,collapsed:ee,onResize:de,onToggleCollapse:()=>pe(he=>!he)}),c.jsxs("div",{className:"nc-workspace-main",children:[c.jsx(u2,{decks:P,currentDeck:v,onCreate:_n,onRename:bt,onDelete:Ye,onReorder:L.reorder,onOpenWindow:It,onNavigate:Oe,saveState:L.saveState,error:L.error,sidebarVisible:li,onToggleSidebar:w?null:()=>J(he=>!he)}),c.jsx(IE,{layout:Y,onLayoutChange:z,token:t,readonly:ze,sessionsAlive:G,focusSession:ne,onFocus:H,onOpenSingle:A,decks:P,currentDeck:v,onSendToDeck:Gt,cells:k,nodeGroups:N})]}),X&&c.jsx("div",{className:"nc-single-overlay",children:c.jsx(D_,{session:X.session,node:X.node,ownerId:X.ownerId,cellName:df({session:X.session,node:X.node,ownerId:X.ownerId,cells:k,nodeGroups:N}),token:t,readonly:ze,onBack:()=>I(null)})}),F&&c.jsx(Nl,{cell:F,token:t,route:Array.isArray(F.route)?F.route:[],onConfirm:Re,onClose:()=>T(null)}),Hn]})}function bR(){$n();const e=E.useSyncExternalStore(cR,j_,j_);if(!e.needed)return null;const t=e.kind==="install"?m("install-version-mismatch").replace("{v}",e.version):m("update-available").replace("{v}",e.version).replace(" "," ").trim();return c.jsxs("div",{className:"nc-update",role:"status","aria-live":"polite",children:[c.jsx("span",{className:"nc-update-msg",children:t}),e.kind==="reload"&&c.jsx("button",{className:"nc-update-btn",onClick:fR,children:m("reload")})]})}hR();t0.createRoot(document.getElementById("root")).render(c.jsxs(Yb.StrictMode,{children:[c.jsx(SR,{}),c.jsx(bR,{})]}));
93
+ `],{type:"application/json"}),P=URL.createObjectURL(L),F=document.createElement("a");F.href=P,F.download="nexuscrew-diagnostics.json",F.click(),URL.revokeObjectURL(P)}catch{w(m("diagnostics-export-failed"))}};return c.jsxs("div",{className:"nc-set-tab nc-diagnostics",children:[c.jsxs("label",{className:"nc-field",children:[m("diagnostics-target"),c.jsx("select",{value:u.key,onChange:L=>a(L.target.value),children:s.map(L=>c.jsxs("option",{value:L.key,children:[L.label,L.status!=="up"?` · ${L.status}`:""]},L.key))})]}),c.jsxs("div",{className:"nc-set-form nc-diag-controls",children:[c.jsx("div",{className:"nc-sheet-label",children:m("diagnostics-verbose")}),c.jsxs("div",{className:"nc-set-row",children:[c.jsx("select",{"aria-label":m("diagnostics-duration"),value:R,onChange:L=>k(Number(L.target.value)),disabled:n,children:[300,900,1800,3600].map(L=>c.jsxs("option",{value:L,children:[L/60," min"]},L))}),c.jsx("button",{type:"button",className:"nc-btn primary",disabled:n||(h==null?void 0:h.verbose)===!0,onClick:()=>A(()=>dg(e,!0,R,u.route)),children:m("enable")}),c.jsx("button",{type:"button",className:"nc-btn ghost",disabled:n||(h==null?void 0:h.verbose)!==!0,onClick:()=>A(()=>dg(e,!1,R,u.route)),children:m("stop")})]}),c.jsx("small",{className:"nc-set-hint",children:h!=null&&h.verbose?m("diagnostics-expires").replace("{time}",new Date(h.expiresAt).toLocaleTimeString()):m("diagnostics-off")})]}),c.jsxs("div",{className:"nc-diag-filters",children:[c.jsxs("select",{"aria-label":m("diagnostics-level"),value:$,onChange:L=>O(L.target.value),children:[c.jsx("option",{value:"all",children:m("diagnostics-all-levels")}),["debug","info","warn","error"].map(L=>c.jsx("option",{value:L,children:L},L))]}),c.jsx("input",{"aria-label":m("diagnostics-component"),placeholder:m("diagnostics-component"),value:V,onChange:L=>Y(L.target.value)})]}),c.jsxs("div",{className:"nc-set-row",children:[c.jsxs("label",{className:"nc-check",children:[c.jsx("input",{type:"checkbox",checked:S,onChange:L=>y(L.target.checked)})," ",m("diagnostics-pause")]}),c.jsxs("label",{className:"nc-check",children:[c.jsx("input",{type:"checkbox",checked:x,onChange:L=>C(L.target.checked)})," ",m("diagnostics-autoscroll")]})]}),c.jsx("pre",{ref:ne,className:"nc-diag-log","aria-label":m("diagnostics-log"),children:I||m("diagnostics-empty")}),c.jsxs("div",{className:"nc-set-row",children:[c.jsx("button",{type:"button",className:"nc-btn ghost",onClick:N,children:m("copy")}),c.jsx("button",{type:"button",className:"nc-btn ghost",onClick:M,children:m("diagnostics-export")}),c.jsx("button",{type:"button",className:"nc-btn danger",disabled:n,onClick:()=>{window.confirm(m("diagnostics-clear-confirm"))&&A(async()=>{const L=await D0(e,u.route);return z.current=0,v([]),L})},children:m("diagnostics-clear")})]}),b&&c.jsx("div",{className:"nc-err",children:b})]})}function KN({token:e,settings:t,readonly:n,refresh:s,roster:o,section:a,setSection:u}){const[h,f]=E.useState(null),[p,v]=E.useState(null),[b,w]=E.useState(!1),[S,y]=E.useState(!1),[x,C]=E.useState(null),[R,k]=E.useState(!0),[$,O]=E.useState(!1);E.useEffect(()=>{C(t&&t.update||null),k(!t||t.autoUpdate!==!1),O(!!(t&&t.alternateScreen))},[t]);const V=async()=>{f(null),v(null),y(!0);try{const N=await p0(e);v(N.note||"ok"),w(!1)}catch(N){f(String(N.message||N))}y(!1)},Y=async()=>{f(null),v(null),y(!0);try{const N=await R0(e);v(`${N.note||"ok"}${N.target?` (${N.target})`:""}`)}catch(N){f(String(N.message||N))}y(!1)},z=async N=>{f(null),v(null),y(!0);try{await Ld(e,{autoUpdate:N}),k(N),s&&await s()}catch(M){f(String(M.message||M))}y(!1)},ne=async N=>{f(null),v(null),y(!0);try{await Ld(e,{alternateScreen:N}),O(N),s&&await s()}catch(M){f(String(M.message||M))}y(!1)},H=async()=>{f(null),v(null),y(!0);try{C(await j0(e))}catch(N){f(String(N.message||N))}y(!1)},X=async()=>{f(null),v(null),y(!0);try{const N=await P0(e);C(N),v(m("npm-update-restarting"))}catch(N){f(String(N.message||N))}y(!1)},I=()=>{window.confirm(m("composer-clear-confirm"))&&(f(null),xE()?(window.dispatchEvent(new Event(Sh)),v(m("composer-clear-done"))):f(m("composer-clear-failed")))},A=t&&t.service;return c.jsxs("div",{className:"nc-set-tab",children:[c.jsx("div",{className:"nc-system-tabs",role:"tablist","aria-label":m("tab-system"),children:["general","diagnostics"].map(N=>c.jsx("button",{type:"button",role:"tab","aria-selected":a===N,className:`nc-set-tabbtn${a===N?" on":""}`,onClick:()=>u(N),children:m(`system-${N}`)},N))}),a==="general"&&c.jsxs(c.Fragment,{children:[c.jsxs("section",{className:"nc-system-group",children:[c.jsx("h3",{children:m("system-this-node")}),t&&c.jsxs("div",{className:"nc-set-info",children:["v",t.version," · ",t.platform," · :",t.port,c.jsx("br",{}),A&&A.installed?m("service-installed"):m("service-missing"),A&&A.installed?` · ${A.active?m("service-active"):m("service-inactive")}`:"",A?` · boot ${A.boot?"on":"off"}`:""]}),c.jsx("div",{className:"nc-set-row",children:c.jsx("button",{type:"button",className:"nc-btn ghost",disabled:n||S,title:n?m("settings-readonly"):"",onClick:Y,children:m("service-regenerate")})}),c.jsx(FN,{token:e,readonly:n}),c.jsx($N,{})]}),c.jsxs("section",{className:"nc-system-group",children:[c.jsx("h3",{children:m("system-updates")}),c.jsxs("div",{className:"nc-set-form nc-update-settings",children:[c.jsxs("label",{className:"nc-check",children:[c.jsx("input",{type:"checkbox",checked:R,disabled:n||S||x&&!x.supported,onChange:N=>z(N.target.checked)}),c.jsxs("span",{children:[c.jsx("b",{children:m("npm-auto-update")}),c.jsx("small",{children:m("npm-auto-update-help")})]})]}),x&&c.jsxs("div",{className:"nc-set-info",children:[m("npm-update-current")," v",x.current,x.latest?` · ${m("npm-update-latest")} v${x.latest}`:""," · ",m(`npm-update-${x.supported?x.phase:"unsupported"}`)]}),c.jsxs("div",{className:"nc-set-row",children:[c.jsx("button",{type:"button",className:"nc-btn ghost",disabled:n||S||!x||!x.supported,onClick:H,children:m("npm-update-check")}),x&&x.available&&c.jsx("button",{type:"button",className:"nc-btn primary",disabled:n||S||x.phase==="installing",onClick:X,children:m("npm-update-install")})]}),x&&x.lastError&&c.jsx("div",{className:"nc-err",children:x.lastError})]})]}),c.jsxs("section",{className:"nc-system-group",children:[c.jsx("h3",{children:m("system-security")}),c.jsx("div",{className:"nc-set-row",children:c.jsx("button",{type:"button",className:"nc-btn ghost",disabled:n||S,title:n?m("settings-readonly"):"",onClick:()=>{f(null),v(null),w(!0)},children:m("token-rotate")})})]}),c.jsxs("section",{className:"nc-system-group",children:[c.jsx("h3",{children:m("system-local-data")}),c.jsxs("div",{className:"nc-set-form",children:[c.jsx("div",{className:"nc-sheet-label",children:m("composer-clear-data")}),c.jsx("small",{className:"nc-set-hint",children:m("composer-clear-data-help")}),c.jsx("div",{className:"nc-set-row",children:c.jsx("button",{type:"button",className:"nc-btn ghost",onClick:I,children:m("composer-clear-data")})})]})]})]}),a==="diagnostics"&&c.jsxs("section",{className:"nc-system-group nc-system-diagnostics",children:[c.jsx("h3",{children:m("system-diagnostics")}),c.jsxs("div",{className:"nc-set-form nc-alternate-screen-settings",children:[c.jsx("div",{className:"nc-sheet-label",children:m("system-terminal")}),c.jsxs("label",{className:"nc-check",children:[c.jsx("input",{type:"checkbox","aria-label":m("alternate-screen"),checked:$,disabled:n||S,onChange:N=>ne(N.target.checked)}),c.jsxs("span",{children:[c.jsx("b",{children:m("alternate-screen")}),c.jsx("small",{children:m("alternate-screen-help")})]})]})]}),c.jsx(UN,{token:e,roster:o,readonly:n})]}),b&&c.jsxs("div",{className:"nc-set-confirm",children:[c.jsx("div",{children:m("token-rotate-explain")}),c.jsxs("div",{className:"nc-sheet-actions",children:[c.jsx("button",{type:"button",className:"nc-btn ghost",disabled:S,onClick:()=>w(!1),children:m("cancel")}),c.jsx("button",{type:"button",className:"nc-btn primary",disabled:S,onClick:V,children:m("confirm")})]})]}),p&&c.jsx("div",{className:"nc-set-note",children:p}),h&&c.jsx("div",{className:"nc-err",children:h})]})}function qN({token:e,onClose:t,initialTab:n="nodes",initialLocation:s="",startNewCell:o=!1}){$n();const a=n==="diagnostics"?"diagnostics":"general",[u,h]=E.useState(n==="diagnostics"?"system":n),f=E.useRef(null),p=E.useRef(null),[v,b]=E.useState({start:!1,end:!1}),[w,S]=E.useState(a),[y,x]=E.useState(null),[C,R]=E.useState([]),[k,$]=E.useState(!1),[O,V]=E.useState(null),[Y,z]=E.useState(0),ne=Wh(e,!0,Y),H=E.useCallback(()=>{const I=f.current;if(!I)return;const A=I.scrollWidth>I.clientWidth+1,N={start:A&&I.scrollLeft>1,end:A&&I.scrollLeft+I.clientWidth<I.scrollWidth-1};b(M=>M.start===N.start&&M.end===N.end?M:N)},[]);E.useEffect(()=>{const I=f.current;if(!I)return;const A=typeof ResizeObserver=="function"?new ResizeObserver(H):null;return A==null||A.observe(I),window.addEventListener("resize",H),H(),()=>{A==null||A.disconnect(),window.removeEventListener("resize",H)}},[H]),E.useEffect(()=>{var A,N;(N=(A=p.current)==null?void 0:A.scrollIntoView)==null||N.call(A,{behavior:"smooth",block:"nearest",inline:"nearest"});const I=window.requestAnimationFrame?window.requestAnimationFrame(H):setTimeout(H,0);return()=>{window.cancelAnimationFrame?window.cancelAnimationFrame(I):clearTimeout(I)}},[u,H]);const X=E.useCallback(async()=>{try{const I=await H_(e);x(I),V(null)}catch(I){V(String(I.message||I))}try{const I=await h0(e);R(I.peers||[])}catch(I){V(String(I.message||I))}},[e]);return E.useEffect(()=>{X();const I=setInterval(X,5e3);return()=>clearInterval(I)},[X]),E.useEffect(()=>{let I=!1;return Vt("/api/config",e).then(A=>A.json()).then(A=>{I||$(!!A.readonlyDefault)}).catch(()=>{}),()=>{I=!0}},[e]),c.jsx("div",{className:"nc-set-overlay",onClick:t,children:c.jsxs("div",{className:"nc-set-panel",onClick:I=>I.stopPropagation(),children:[c.jsxs("div",{className:"nc-set-head",children:[c.jsx(it,{name:"gear",size:18}),c.jsx("b",{children:m("settings")}),c.jsx("button",{type:"button",className:"nc-set-close",onClick:t,title:m("close"),children:c.jsx(it,{name:"x",size:18})})]}),k&&c.jsx("div",{className:"nc-set-readonly",children:m("settings-readonly")}),O&&c.jsx("div",{className:"nc-err",children:O}),c.jsx("div",{className:`nc-set-tabs-wrap${v.start?" has-start-overflow":""}${v.end?" has-end-overflow":""}`,children:c.jsx("div",{className:"nc-set-tabs",ref:f,onScroll:H,children:["nodes","fleet","audio","input","system"].map(I=>c.jsx("button",{ref:u===I?p:null,type:"button",className:`nc-set-tabbtn${u===I?" on":""}`,onClick:()=>h(I),children:m(`tab-${I}`)},I))})}),c.jsxs("div",{className:"nc-set-body",children:[u==="nodes"&&c.jsx(zN,{token:e,nodes:C,roster:ne,settings:y,readonly:k,refresh:X,refreshAliases:()=>z(I=>I+1)}),u==="fleet"&&c.jsx(wN,{token:e,readonly:k,startNewCell:o,initialLocation:s,targets:ne.map(I=>({route:I.route,label:I.label||I.name,status:I.status}))}),u==="audio"&&c.jsx(HN,{token:e,readonly:k,nodes:C,settings:y}),u==="input"&&c.jsx(WN,{}),u==="system"&&c.jsx(KN,{token:e,settings:y,readonly:k,refresh:X,roster:ne,section:w,setSection:S})]})]})})}function VN({token:e,initialPair:t,deviceDefault:n="",localNodeId:s="",localNameDefault:o="",onPairDone:a,onDone:u}){$n();const[h,f]=E.useState(t?"pair":"welcome"),[p,v]=E.useState(!1),[b,w]=E.useState(null),S=async()=>{v(!0),w(null);try{await Ld(e,{wizardDone:!0}),a&&a(),u()}catch(y){w(String(y.message||y)),v(!1)}};return c.jsx("div",{className:"nc-wiz-overlay",children:c.jsxs("div",{className:"nc-wiz",children:[c.jsxs("div",{className:"nc-wiz-head",children:[c.jsx("b",{children:m("wizard-title")}),c.jsx("small",{children:m("hydra-simple")})]}),h==="welcome"&&c.jsxs("div",{className:"nc-wiz-body",children:[c.jsx("div",{className:"nc-wiz-done",children:m("local-ready")}),c.jsxs("div",{className:"nc-sheet-actions",children:[c.jsx("button",{className:"nc-btn ghost",disabled:p,onClick:S,children:m("local-only")}),c.jsx("button",{className:"nc-btn primary",disabled:p,onClick:()=>f("pair"),children:m("add-node")})]})]}),h==="pair"&&c.jsxs("div",{className:"nc-wiz-body",children:[c.jsx(Tw,{token:e,initial:t||"",autoStart:!!t,deviceDefault:n,localNodeId:s,localNameDefault:o,onBusyChange:v,onSuccess:async()=>{a&&a(),f("done")}}),c.jsx("div",{className:"nc-sheet-actions",children:c.jsx("button",{className:"nc-btn ghost",disabled:p,onClick:()=>{a&&a(),f("welcome")},children:m("back")})})]}),h==="done"&&c.jsxs("div",{className:"nc-wiz-body",children:[c.jsx("div",{className:"nc-wiz-done",children:m("node-connected")}),c.jsx("div",{className:"nc-sheet-actions",children:c.jsx("button",{className:"nc-btn primary",disabled:p,onClick:S,children:m("finish")})})]}),b&&c.jsx("div",{className:"nc-err",children:b})]})})}function YN(e,t){if(typeof EventSource>"u"||!e)return()=>{};const n=new EventSource(`/api/events?token=${encodeURIComponent(e)}`);return n.onmessage=s=>{try{const o=JSON.parse(s.data);o&&typeof o=="object"&&typeof o.type=="string"&&t(o)}catch{}},()=>{try{n.close()}catch{}}}const GN=6e3,XN=12e3;function JN({n:e,onClose:t}){return c.jsxs("div",{className:`nc-ntf-toast${e.urgency==="high"?" high":""}`,role:"status","aria-live":"polite",children:[c.jsxs("div",{className:"nc-ntf-toast-txt",children:[c.jsx("b",{children:e.title}),e.body&&c.jsx("small",{children:e.body}),e.session&&c.jsx("span",{className:"nc-ntf-from",children:e.session})]}),c.jsx("button",{type:"button",className:"nc-ntf-x",onClick:t,title:m("close"),children:c.jsx(it,{name:"x",size:14})})]})}function QN({ask:e,token:t,onAnswered:n}){const[s,o]=E.useState(""),[a,u]=E.useState(!1),[h,f]=E.useState(null),p=async v=>{const b=String(v||"").trim();if(!(!b||a)){f(null),u(!0);try{await A0(t,e.id,b),n(e.id)}catch(w){f(String(w.message||w))}u(!1)}};return c.jsxs("div",{className:"nc-ask-card",children:[c.jsxs("div",{className:"nc-ask-head",children:[c.jsx("span",{className:"nc-ntf-from",children:e.session}),c.jsxs("code",{className:"nc-ask-id",children:["#",e.id]})]}),c.jsx("div",{className:"nc-ask-q",children:e.question}),Array.isArray(e.options)&&e.options.length>0&&c.jsx("div",{className:"nc-ask-opts",children:e.options.map(v=>c.jsx("button",{type:"button",className:"nc-btn ghost",disabled:a,onClick:()=>p(v),children:v},v))}),c.jsxs("div",{className:"nc-ask-reply",children:[c.jsx("textarea",{rows:2,placeholder:m("ask-reply-ph"),value:s,disabled:a,onChange:v=>o(v.target.value)}),c.jsx("button",{type:"button",className:"nc-btn primary",disabled:a||!s.trim(),onClick:()=>p(s),children:m("send")})]}),h&&c.jsx("div",{className:"nc-err",children:h})]})}function ZN({token:e}){const[t]=$n(),[n]=Vw(),[s,o]=E.useState([]),[a,u]=E.useState([]),[h,f]=E.useState(()=>{try{return/(?:^|[#&])ask=/.test(location.hash)}catch{return!1}}),p=E.useRef(0),v=E.useRef(null);v.current||(v.current=IN());const b=E.useRef({enabled:n,lang:t});b.current={enabled:n,lang:t};const w=E.useCallback(x=>{o(C=>C.filter(R=>R.key!==x))},[]),S=E.useCallback(x=>{const C=`t${p.current+=1}`;o(k=>[...k.slice(-3),{...x,key:C}]),setTimeout(()=>w(C),x.urgency==="high"?XN:GN);const R=b.current;if(R.enabled)try{v.current.enqueue(x,LN(x,R.lang))}catch{}},[w]);E.useEffect(()=>{n||v.current.stop()},[n]),E.useEffect(()=>{const x=()=>{(document.visibilityState!=="visible"||!document.hasFocus())&&v.current.stop()},C=()=>v.current.stop();return document.addEventListener("visibilitychange",x),window.addEventListener("blur",x),window.addEventListener(Nh,C),()=>{document.removeEventListener("visibilitychange",x),window.removeEventListener("blur",x),window.removeEventListener(Nh,C),typeof v.current.dispose=="function"?v.current.dispose():v.current.stop()}},[]),E.useEffect(()=>{if(!e)return;let x=!1;M0(e).then(R=>{x||u(R.asks||[])}).catch(()=>{});const C=YN(e,R=>{R.type==="notify"?S(R):R.type==="ask"&&R.ask&&R.ask.id?u(k=>k.some($=>$.id===R.ask.id)?k:[...k,R.ask]):R.type==="ask-answered"&&R.id&&u(k=>k.filter($=>$.id!==R.id))});return()=>{x=!0,C()}},[e,S]);const y=x=>u(C=>C.filter(R=>R.id!==x));return c.jsxs(c.Fragment,{children:[s.length>0&&c.jsx("div",{className:"nc-ntf-toasts",children:s.map(x=>c.jsx(JN,{n:x,onClose:()=>w(x.key)},x.key))}),a.length>0&&!h&&c.jsxs("button",{type:"button",className:"nc-ask-badge",onClick:()=>f(!0),title:m("asks-title"),children:["? ",c.jsx("span",{className:"nc-ask-count",children:a.length})]}),a.length>0&&h&&c.jsxs("div",{className:"nc-ask-panel",children:[c.jsxs("div",{className:"nc-ask-panel-head",children:[c.jsx("b",{children:m("asks-title")}),c.jsx("span",{className:"nc-ask-count",children:a.length}),c.jsx("button",{type:"button",className:"nc-ntf-x",onClick:()=>f(!1),title:m("close"),children:c.jsx(it,{name:"x",size:16})})]}),c.jsx("div",{className:"nc-ask-panel-body",children:a.map(x=>c.jsx(QN,{ask:x,token:e,onAnswered:y},x.id))})]})]})}const eR=4e3;async function tR(e){const t=await Vt("/api/sessions",e);if((t==null?void 0:t.ok)===!1)throw new Error(`HTTP ${t.status}`);const n=await t.json();if(!Array.isArray(n==null?void 0:n.sessions))throw new Error("invalid sessions payload");return n.sessions}async function Rd(e,t=[]){var h;const[n,s]=await Promise.allSettled([t.length?zh(e,t):tR(e),_s(e,t)]),o=n.status==="fulfilled"&&Array.isArray((h=n.value)==null?void 0:h.sessions)?n.value.sessions:Array.isArray(n.value)?n.value:null,a=s.status==="fulfilled"?s.value:null,u=(a==null?void 0:a.available)===!0&&Array.isArray(a.cells)?a.cells:null;return{sessions:o,cells:u,fresh:Array.isArray(o)&&Array.isArray(u)}}function Yw(e,t,n){return n===!0&&(e==null?void 0:e.degraded)!==!0&&(e==null?void 0:e.active)===!0&&e.tmux!==!1&&!!e.tmuxSession&&(t||[]).some(s=>(s==null?void 0:s.name)===e.tmuxSession)}function nR(e){const t=new Map((e.sessions||[]).map(o=>[o.name,o])),n=[],s=(o,a,u,h=[],f="")=>{const p=new Map((a||[]).map(v=>[v.name,v]));for(const v of o||[]){const b=p.get(v.tmuxSession)||{},w=qh(v,b),S=Yw(v,a,u);n.push({key:Bo(h,v.tmuxSession||v.cell),session:v.tmuxSession,route:h,cellName:v.cell,label:v.cell,node:h.length?h.join("/"):"",nodeLabel:f,live:S,selectable:S,verified:u===!0,working:w.working,degraded:!!v.degraded,activity:b.activity||v.activity||0,subtitle:w.subtitle})}};s(e.cells,[...t.values()],e.localFresh===!0);for(const o of e.nodeGroups||[])s(o.cells,o.sessions,o.switcherFresh===!0,Array.isArray(o.route)?o.route:[],o.label||o.name||"");return n}function iR(e){const t=new Map,n=Array.isArray(e.sessions)?e.sessions:[],s=Array.isArray(e.cells)?e.cells:[],o=new Map(n.map(u=>[u.name,u])),a=new Set(s.map(u=>u.tmuxSession).filter(Boolean));t.set("local",Vh(s,n.filter(u=>!a.has(u.name)),o));for(const u of e.nodeGroups||[]){const h=Array.isArray(u.route)?u.route:[];if(!h.length)continue;const f=Array.isArray(u.cells)?u.cells:[],p=Array.isArray(u.sessions)?u.sessions:[],v=new Set(f.map(b=>b.tmuxSession).filter(Boolean));t.set(h.join("/"),Pl({...u,route:h,cells:f,sessions:p,unmanaged:p.filter(b=>!v.has(b.name))}).rawItems)}return t}function sR(e,t,n,s){return[...new Set(e.map(a=>a.node||"local"))].flatMap(a=>{const u=e.filter(v=>(v.node||"local")===a),h=new Map((t.get(a)||[]).map(v=>[v.key,v])),f=new Map(u.map(v=>[v.key,v])),p=u.map(v=>{const b=h.get(v.key);return{...v,label:(b==null?void 0:b.label)||v.label,live:(b==null?void 0:b.live)??v.live,fresh:(b==null?void 0:b.fresh)===!0,activity:(b==null?void 0:b.activity)??v.activity}});return ps(p,n,"all",Ai(s,a)).map(v=>f.get(v.key))})}function rR({token:e,current:t,onPick:n,onClose:s}){const[o,a]=E.useState(Eg),[u,h]=E.useState(!1),[f,p]=E.useState(!1),[v,b]=E.useState(""),[w,S]=E.useState(""),[y,x]=E.useState(""),C=E.useRef(null),R=E.useRef(null),k=E.useMemo(()=>nR(o),[o]),$=E.useMemo(()=>iR(o),[o]),{pins:O,orders:V,canMoveRoster:Y,moveRoster:z,stepRoster:ne}=Kh(),H=E.useMemo(()=>sR(k,$,O,V),[k,$,O,V]),X=E.useMemo(()=>u?H:H.filter(L=>L.selectable||L.degraded),[H,u]),I=E.useMemo(()=>k.find(L=>L.key===w&&L.selectable),[k,w]);E.useEffect(()=>{var F;const L=document.activeElement;(F=R.current)==null||F.focus();const P=T=>{T.key==="Escape"&&s()};return document.addEventListener("keydown",P),()=>{var T;document.removeEventListener("keydown",P),(T=L==null?void 0:L.focus)==null||T.call(L)}},[s]),E.useEffect(()=>{let L=!0,P=!1;const F=async()=>{if(P)return;P=!0;const q=Eg(),B=Array.isArray(q.nodeGroups)?q.nodeGroups:[],D=Rd(e),U=await Promise.all(B.map(async J=>{const ee=Array.isArray(J.route)?J.route:[];return ee.length?{group:J,result:await Rd(e,ee)}:{group:J,result:{fresh:!1,sessions:null,cells:null}}})),Z=await D;if(!L)return;const oe=new Map(U.map(({group:J,result:ee})=>[JSON.stringify(J.route||[]),ee])),de=B.map(J=>{const ee=oe.get(JSON.stringify(J.route||[]));return ee?{...J,sessions:ee.sessions||J.sessions||[],cells:ee.cells||J.cells||[],switcherFresh:ee.fresh}:{...J,switcherFresh:!1}}),fe=ry({...q,sessions:Z.sessions||q.sessions||[],cells:Z.cells||q.cells||[],localFresh:Z.fresh,nodeGroups:de,refreshedAt:Date.now()});a(fe),p(!0),P=!1};F();const T=setInterval(F,eR);return()=>{L=!1,clearInterval(T)}},[e]);const A=L=>L.degraded?m("cell-degraded"):L.verified?L.selectable?L.working?m("cell-working"):m("cell-idle"):m("cell-off"):m("cell-switcher-not-confirmed"),N=L=>{if(b(""),!L.selectable){b(m("cell-switcher-not-active"));return}S(L.key)},M=async()=>{const L=I;if(!L){b(m("cell-switcher-select"));return}b(""),x(L.key);try{const P=await Rd(e,L.route),F=(P.cells||[]).find(T=>(T==null?void 0:T.cell)===L.cellName&&(T==null?void 0:T.tmuxSession)===L.session);if(!Yw(F,P.sessions,P.fresh)){b(m("cell-switcher-not-active"));return}n({session:L.session,...L.node?{node:L.node}:{},cellName:L.cellName}),s()}catch{b(m("cell-switcher-not-active"))}finally{x("")}};return c.jsx("div",{className:"nc-cell-switcher-backdrop",onClick:s,children:c.jsxs("aside",{ref:C,className:"nc-cell-switcher",role:"dialog","aria-label":m("fleet-cells"),tabIndex:-1,onClick:L=>L.stopPropagation(),children:[c.jsxs("div",{className:"nc-cell-switcher-list",children:[!f&&c.jsx("div",{className:"nc-empty",role:"status",children:m("cell-switcher-refreshing")}),f&&X.length===0&&c.jsx("div",{className:"nc-empty",role:"status",children:m("cell-switcher-empty-active")}),X.map(L=>{const P=(t==null?void 0:t.session)===L.session&&((t==null?void 0:t.node)||"")===L.node,F=w===L.key,T=A(L),q=L.node||"local",B=$.get(q)||k.filter(D=>(D.node||"local")===q);return c.jsxs("div",{className:`nc-cell-switcher-row${P?" current":""}${F?" selected":""}${L.selectable?"":" off"}`,"data-roster-key":L.key,"data-position":q,children:[c.jsx(Di,{position:q,itemKey:L.key,label:L.cellName,canMove:Y,onMove:(D,U)=>z(q,D,U,B),onStep:D=>ne(q,L.key,D,B)}),c.jsxs("button",{type:"button",className:"nc-cell-switcher-row-select","aria-current":P?"true":void 0,"aria-pressed":F,"aria-disabled":!L.selectable,disabled:y===L.key,onClick:()=>N(L),children:[c.jsx("span",{className:`nc-cell-switcher-dot${L.degraded?" warn":L.live?` on${L.working?" working":""}`:""}`}),c.jsxs("span",{className:"nc-cell-switcher-copy",children:[c.jsx("b",{children:L.cellName}),c.jsx("small",{className:"nc-cell-switcher-state",children:T}),c.jsx("small",{children:[L.nodeLabel,L.subtitle].filter(Boolean).join(" · ")})]})]})]},L.key)})]}),v&&c.jsx("div",{className:"nc-cell-switcher-notice",role:"status",children:v}),c.jsx("div",{className:"nc-cell-switcher-actions",children:c.jsx("button",{type:"button",className:"nc-cell-switcher-open",disabled:!I||!!y,onClick:M,children:I?`${m("cell-switcher-open")}: ${I.cellName}`:m("cell-switcher-select")})}),c.jsxs("div",{className:"nc-cell-switcher-controls",children:[c.jsx("b",{children:m("fleet-cells")}),c.jsx("button",{type:"button",className:"nc-cell-switcher-filter","aria-pressed":u,onClick:()=>{b(""),h(L=>!L)},children:m(u?"cell-switcher-show-active":"cell-switcher-show-all")}),c.jsx("button",{ref:R,type:"button",className:"nc-cell-switcher-close","aria-label":m("cell-switcher-close"),title:m("cell-switcher-close"),onClick:s,children:"×"})]})]})})}const jd=e=>wi($s(e)).length===0,Pd=e=>Array.isArray(e)?e.join("/"):"";function oR(e){const t=new Set,n=[];for(const s of Array.isArray(e)?e:[])!s||!zn.test(String(s.instanceId||""))||!Array.isArray(s.route)||!s.route.length||t.has(s.instanceId)||(t.add(s.instanceId),n.push({instanceId:s.instanceId,route:[...s.route],label:String(s.label||s.name||s.route.join(" › ")),status:s.status||"offline"}));return n.sort((s,o)=>s.label.localeCompare(o.label))}function Ro(e){return{instanceId:e.ownerId,route:e.ownerRoute||[],label:e.ownerLabel,status:e.available===!1?"offline":"up"}}function As(e,t,n,s=!1,o=!0){const a=t.instanceId;return{...e,id:Cr(s?null:a,e.name),ownerId:a,ownerRoute:s?[]:[...t.route],ownerLabel:s?"Local":t.label,local:s,available:o,ownerTopology:Array.isArray(n)?n:[],layout:xh(e.layout,a,n)}}function aR(e,t,n,s,o=[]){const[a,u]=E.useState([]),[h,f]=E.useState(!1),[p,v]=E.useState("idle"),[b,w]=E.useState(""),[S,y]=E.useState(""),x=E.useRef([]),C=E.useRef([]),R=E.useRef(""),k=E.useRef(t),$=E.useRef(n),O=E.useRef(!1),V=E.useRef(!0),Y=E.useRef(""),z=E.useMemo(()=>oR(o),[o]),ne=z.map(B=>`${B.instanceId}:${Pd(B.route)}:${B.status}:${B.label}`).join("|");C.current=z,$.current=n,k.current=t,x.current=a;const H=E.useCallback(B=>kh(B.layout,R.current,C.current),[]),X=E.useCallback((B,D=!0,U=k.current)=>{const Z=Ov(B,hl()),oe=x.current.some(fe=>fe.id===U);x.current=Z,u(Z);const de=Z.find(fe=>fe.id===U);if(D&&de){V.current=!0;const fe=H(de);s(fe),de.local&&VE(de.name,fe)}else oe&&!de&&(V.current=!0,s(kr()),w("deck non più condiviso dal nodo owner"));WE(Z.filter(fe=>fe.local).map(fe=>fe.name))},[s,H]),I=E.useCallback(async B=>{let D=await il(e);const U=D.decks.find(Z=>Z.name==="main");if(D.decks.length===1&&U&&U.revision===0&&jd(U.layout)){const Z=HE(),oe=$s(Ch("main")||kr());if(!jd(oe)){const de=xh(oe,B,[]);D.decks[0]=await sl(e,"main",de,0,[])}for(const de of Z.filter(fe=>fe!=="main"))try{let fe=await hg(e,de,[]);const J=$s(Ch(de)||kr());jd(J)||(fe=await sl(e,de,xh(J,B,[]),fe.revision,[]))}catch{}D=await il(e)}return D},[e]),A=E.useCallback(async({migrate:B=!1}={})=>{const D=await Fh(e,[]),U=zn.test(String(D.instanceId||""))?D.instanceId:"";if(!U)throw new Error("instanceId locale non disponibile");R.current=U,y(U);const[Z,oe]=await Promise.all([B?I(U):il(e),ag(e,[]).catch(()=>({nodes:[]}))]),de={instanceId:U,route:[],label:"Local"},fe=Z.decks.map(ee=>As(ee,de,oe.nodes,!0,!0)),J=x.current;return await Promise.all(C.current.map(async ee=>{if(ee.status!=="up"){fe.push(...J.filter(pe=>!pe.local&&pe.ownerId===ee.instanceId).map(pe=>({...pe,ownerRoute:[...ee.route],ownerLabel:ee.label,available:!1})));return}try{const[pe,Se]=await Promise.all([il(e,ee.route),ag(e,ee.route).catch(()=>({nodes:[]}))]);fe.push(...pe.decks.map(Ze=>As(Ze,ee,Se.nodes,!1,!0)))}catch{fe.push(...J.filter(Se=>!Se.local&&Se.ownerId===ee.instanceId).map(Se=>({...Se,ownerRoute:[...ee.route],ownerLabel:ee.label,available:!1})))}})),fe.sort((ee,pe)=>ee.local===pe.local?ee.ownerLabel.localeCompare(pe.ownerLabel)||(ee.name==="main"?-1:pe.name==="main"?1:ee.name.localeCompare(pe.name)):ee.local?-1:1),fe},[e,I,ne]);E.useEffect(()=>{if(!e)return;let B=!1;const D=Y.current!==e;return Y.current=e,A({migrate:D}).then(U=>{if(B)return;const Z=x.current.find(fe=>fe.id===k.current),oe=U.find(fe=>fe.id===k.current),de=oe&&(!Z||oe.revision>Z.revision||Z.available!==oe.available||Pd(Z.ownerRoute)!==Pd(oe.ownerRoute));X(U,D||!!de&&!O.current),f(!0),oe&&w("")}).catch(U=>{B||(f(!0),w(String(U.message||U)))}),()=>{B=!0}},[X,A,ne,e]);const N=E.useCallback(async(B=k.current)=>{if(!h||!O.current)return!0;const D=x.current.find(U=>U.id===B);if(!D)return w(`deck inesistente: ${B}`),!1;if(D.available===!1)return w(`nodo owner offline: ${D.ownerLabel}`),!1;v("saving");try{const U=Iv($s($.current),D.ownerId,D.ownerTopology),Z=await sl(e,D.name,U,D.revision,D.ownerRoute),oe=As(Z,Ro(D),D.ownerTopology,D.local,!0);return X(x.current.map(de=>de.id===B?oe:de),!1),O.current=!1,v("saved"),w(""),setTimeout(()=>v("idle"),1500),!0}catch(U){if(v("error"),w(String(U.message||U)),U.status===409&&U.data&&U.data.current){const Z=x.current.find(de=>de.id===B),oe=As(U.data.current,Ro(Z),Z.ownerTopology,Z.local,!0);X(x.current.map(de=>de.id===B?oe:de),!1)}return!1}},[h,e,X]);return E.useEffect(()=>{if(!h)return;if(V.current){V.current=!1;return}O.current=!0,v("saving");const B=setTimeout(N,650);return()=>clearTimeout(B)},[n,h,N]),E.useEffect(()=>{if(!h)return;const B=setInterval(async()=>{try{const D=await A(),U=x.current.find(de=>de.id===k.current),Z=D.find(de=>de.id===k.current),oe=Z&&(!U||Z.revision>U.revision||U.available!==Z.available);X(D,oe&&!O.current)}catch{}},5e3);return()=>clearInterval(B)},[h,A,X]),{decks:a,records:a,localNodeId:S,ready:h,saveState:p,error:b,setError:w,saveNow:N,select:async B=>{if(O.current&&!await N(k.current))throw new Error("salvataggio del deck corrente fallito: cambio annullato");const D=x.current.find(U=>U.id===B);if(!D)throw new Error(`deck inesistente: ${B}`);return O.current=!1,V.current=!0,H(D)},add:async(B,D=null)=>{const U=D===_i?x.current.find(de=>de.local):D?x.current.find(de=>de.ownerId===D):null;if(!U||U.available===!1)throw new Error("nodo owner non disponibile");const Z=await hg(e,B,U.ownerRoute),oe=As(Z,Ro(U),U.ownerTopology,U.local,!0);return X([...x.current,oe],!1),oe},rename:async(B,D)=>{const U=x.current.find(J=>J.id===B);if(!U)throw new Error("deck inesistente");if(B===k.current&&O.current&&!await N(B))throw new Error(`salvataggio di "${U.name}" fallito: rinomina annullata`);const Z=x.current.find(J=>J.id===B);if(!Z)throw new Error("deck inesistente");const oe=await I0(e,Z.name,D,Z.revision,Z.ownerRoute),de=As(oe,Ro(Z),Z.ownerTopology,Z.local,!0),fe=Z.local?_i:Z.ownerId;return nd(KE(hl(),fe,B,de.id)),X(x.current.map(J=>J.id===B?de:J),!1),de},remove:async B=>{const D=x.current.find(Z=>Z.id===B);if(!D)throw new Error("deck inesistente");B===k.current&&(O.current=!1),await B0(e,D.name,D.revision,D.ownerRoute);const U=D.local?_i:D.ownerId;nd(qE(hl(),U,B)),X(x.current.filter(Z=>Z.id!==B),!1)},reorder:(B,D)=>{const U=x.current.find(ee=>ee.id===B),Z=x.current.find(ee=>ee.id===D);if(!U||!Z)return!1;const oe=U.local?_i:U.ownerId,de=Z.local?_i:Z.ownerId;if(oe!==de)return!1;const fe=x.current.filter(ee=>(ee.local?_i:ee.ownerId)===oe).map(ee=>ee.id),J=nd(UE(hl(),oe,B,D,fe));return X(Ov(x.current,J),!1),!0},addTileTo:async(B,D)=>{const U=x.current.find(ee=>ee.id===B);if(!U)throw new Error("deck inesistente");if(U.available===!1)throw new Error(`nodo owner offline: ${U.ownerLabel}`);const Z=pw(D,R.current,C.current);if(!Z)throw new Error("riferimento sessione non valido");const oe=H(U),de=Iv(ny(oe,Z),U.ownerId,U.ownerTopology),fe=await sl(e,U.name,de,U.revision,U.ownerRoute),J=As(fe,Ro(U),U.ownerTopology,U.local,!0);return X(x.current.map(ee=>ee.id===B?J:ee),!1),J},localMainId:Cr(null,"main"),parseDeckId:Yl}}const lR="/sw.js",jh="nc-sw-update";let Ph=null,Lh=!1,Th=null,Gw=Object.freeze({needed:!1,kind:null,version:""}),Xw=!1;function Jw(){typeof window<"u"&&window.dispatchEvent(new Event(jh))}function Qw(){const e=Th||(Lh?{kind:"reload",version:""}:null);Gw=Object.freeze({needed:!!e,kind:(e==null?void 0:e.kind)||null,version:(e==null?void 0:e.version)||""})}function j_(){return Gw}function cR(e){return typeof window>"u"?()=>{}:(window.addEventListener(jh,e),()=>window.removeEventListener(jh,e))}function Cf(e){Lh!==e&&(Lh=e,Qw(),Jw())}function uR(e,t,n){let s=null;e&&t&&e!==t?s={kind:"install",version:e}:t&&n&&t!==n&&(s={kind:"reload",version:t});const o=JSON.stringify(s)===JSON.stringify(Th);Th=s,Qw(),o||Jw()}function dR(e){e.addEventListener("statechange",()=>{e.state==="installed"&&navigator.serviceWorker.controller&&Cf(!0)})}function hR(){typeof navigator>"u"||!("serviceWorker"in navigator)||(navigator.serviceWorker.addEventListener("controllerchange",()=>{Xw&&location.reload()}),navigator.serviceWorker.register(lR).then(e=>{Ph=e,e.waiting&&Cf(!0),e.addEventListener("updatefound",()=>{const t=e.installing;t&&dR(t)}),setInterval(()=>{e.update().catch(()=>{})},3600*1e3)}).catch(()=>{}))}function fR(){Xw=!0,Cf(!1);const e=Ph&&Ph.waiting;e?(e.postMessage({type:"SKIP_WAITING"}),setTimeout(()=>location.reload(),4e3)):location.reload()}function pR({hash:e="",origin:t="",pathname:n="",search:s=""}={}){const o=String(e||"").replace(/^#/,""),a=`${n||""}${s||""}`;if(!o)return{token:"",pair:"",nextUrl:a};const u=new URLSearchParams(o),h=u.get("token")||"",f=u.get("pair")||"",p=f?`${t||""}${n||""}#pair=${f}`:"";return{token:h,pair:p,nextUrl:a}}const Zw=9,eS=24,tS="nc_side_w",P_="nc_side_min",mR=240,L_="(min-width:1024px) and (pointer:fine)";function gR(){const e=Number(localStorage.getItem(tS));return e>=180&&e<=480?e:mR}function vR(){const e=Number(localStorage.getItem("nc_fontsize"));return e>=Zw&&e<=eS?e:13}function _R(){const e={token:"",pair:""};try{const{token:t,pair:n,nextUrl:s}=pR({hash:location.hash,origin:location.origin,pathname:location.pathname,search:location.search});if(t){e.token=t;try{localStorage.setItem("nc_token",t)}catch{}}if(n){e.pair=n;try{sessionStorage.setItem("nc_pair",n)}catch{}}if(location.hash)try{history.replaceState(null,"",s)}catch{}}catch{}if(e.token||(e.token=sessionStorage.getItem("nc_token")||localStorage.getItem("nc_token")||""),!e.pair){const t=sessionStorage.getItem("nc_pair");t&&(e.pair=t)}return e}function yR(e){try{return $s(Ch(e))}catch{return kr()}}function T_(e){if(!e)return"";const t=Math.floor(Date.now()/1e3)-e;return t<0||t<60?"ora":t<3600?`${Math.floor(t/60)}m`:t<86400?`${Math.floor(t/3600)}h`:`${Math.floor(t/86400)}g`}function wR(){const[e,t]=E.useState(()=>window.matchMedia(L_).matches);return E.useEffect(()=>{const n=window.matchMedia(L_),s=o=>t(o.matches);return n.addEventListener("change",s),()=>n.removeEventListener("change",s)},[]),e}function D_({session:e,node:t,ownerId:n,cellName:s,token:o,readonly:a=!1,onBack:u,onCellSwitcher:h,cellSwitcherOpen:f=!1}){$n();const[p]=uf(),[v,b]=E.useState(!1),[w,S]=E.useState(()=>window.matchMedia("(pointer: coarse)").matches),[y,x]=E.useState(null),[C,R]=E.useState(vR),[k,$]=E.useState(s||e),[O,V]=E.useState(""),Y=P=>R(F=>{const T=Math.max(Zw,Math.min(eS,F+P));return localStorage.setItem("nc_fontsize",String(T)),T}),z=E.useRef(()=>{}),ne=E.useRef(()=>!1),H=E.useRef(()=>{}),X=E.useRef(!1),[I,A]=E.useState(!1),[N,M]=E.useState(!1),L=()=>{X.current=!X.current,A(X.current)};return E.useEffect(()=>{$(s||e)},[s,e]),E.useEffect(()=>{let P=!0;const F=t?t.split("/"):[],T=t?`/api/route/${t.split("/").map(encodeURIComponent).join("/")}/_`:"/api";async function q(){let D=null,U=null;try{const de=await(await Vt(`${T}/sessions`,o)).json();Array.isArray(de.sessions)&&(D=de.sessions.find(fe=>fe.name===e))}catch{}try{const oe=await _s(o,F);oe.available&&Array.isArray(oe.cells)&&(U=oe.cells.find(de=>de.tmuxSession===e))}catch{}if(!P)return;$(df({session:e,cell:U||(s?{cell:s}:null)}));let Z="";U?Z=`${U.engine}${U.key?`·${U.key}`:""}`:D&&(Z=D.attached?`attached · ${T_(D.activity)}`:D.activity?T_(D.activity):""),V(Z)}q();const B=setInterval(q,4e3);return()=>{P=!1,clearInterval(B)}},[e,t,o]),c.jsxs("div",{className:"nc-app",children:[c.jsxs("header",{className:"nc-bar nc-bar-single",children:[c.jsxs("button",{onClick:u,title:m("sessions"),children:[c.jsx(it,{name:"chevronLeft",size:18}),c.jsx("span",{className:"nc-bar-label",children:m("sessions")})]}),c.jsxs("span",{className:"nc-bar-center",children:[c.jsx("b",{title:t?`${k} · ${t}`:k,children:k}),O&&c.jsx("small",{className:"nc-bar-sub",children:O})]}),c.jsxs("span",{className:"nc-bar-right",children:[c.jsx("button",{onClick:()=>Y(-1),title:m("zoom-out"),children:c.jsx(it,{name:"zoomOut",size:18})}),c.jsx("button",{onClick:()=>Y(1),title:m("zoom-in"),children:c.jsx(it,{name:"zoomIn",size:18})}),c.jsx("button",{onClick:()=>S(P=>!P),title:m("composer"),children:c.jsx(it,{name:"keyboard",size:20})}),c.jsx("button",{onClick:()=>b(P=>!P),title:m("files"),children:c.jsx(it,{name:"folder",size:20})})]})]}),c.jsx("div",{className:"nc-termwrap",children:c.jsx(Zy,{session:e,node:t,token:o,readonly:a,takeSize:!0,sendRef:z,composerRef:ne,actionRef:H,ctrlRef:X,setCtrlArmed:A,onFiles:x,fontSize:C,selectionMode:N,onSelectionModeChange:M,keyboardGesture:p.terminalKeyboardGesture})}),c.jsx(hE,{onKeyboard:()=>S(P=>!P),onCellSwitcher:h,cellSwitcherOpen:f,send:P=>z.current(P),action:P=>H.current(P),ctrlArmed:I,onCtrl:L,selectionMode:N,onSelectionMode:M,keepKeyboardClosed:p.keybarKeepsKeyboardClosed,showEnter:p.showKeybarEnter,keybarLayout:p.keybarLayout}),w&&c.jsx(cw,{submitText:P=>ne.current(P),token:o,session:e,node:t,ownerId:n,keepKeyboardClosedOnVoice:p.voiceKeepsKeyboardClosed}),v&&c.jsx(ew,{session:e,node:t,token:o,filesEvent:y,onClose:()=>b(!1)})]})}function SR(){$n();const[e]=E.useState(_R),[t,n]=E.useState(e.token),[s,o]=E.useState(e.pair||""),a=E.useCallback(()=>{o("");try{sessionStorage.removeItem("nc_pair")}catch{}},[]),[u,h]=E.useState(!1),f=wR(),[p]=E.useState(()=>$E(typeof location<"u"?location.pathname:"/")),[v,b]=E.useState(p.id),w=v===Cr(null,Fn),[S,y]=E.useState(null),x=he=>{const Ne=vs(he);y(Ne?{...Ne,...typeof(he==null?void 0:he.cellName)=="string"&&he.cellName?{cellName:he.cellName}:{}}:null)},[C,R]=E.useState([]),[k,$]=E.useState([]),[O,V]=E.useState([]),[Y,z]=E.useState(()=>p.ownerId?kr():yR(p.name)),[ne,H]=E.useState(null),[X,I]=E.useState(null),A=he=>I(vs(he)),N=Wh(t,f),M=E.useMemo(()=>(N||[]).filter(he=>he.instanceId).map(he=>({instanceId:he.instanceId,route:he.route,label:he.label,status:he.status})),[N]),L=aR(t,v,Y,z,M),P=L.decks;E.useEffect(()=>{const he=new Map;for(const Ne of N||[]){const Ke=(Ne.route||[Ne.name]).join("/"),Nt=new Set((Ne.sessions||[]).map(pt=>pt.name));for(const pt of Ne.cells||[])!pt.cell||!pt.tmuxSession||pt.cell===pt.tmuxSession||Nt.has(pt.cell)||he.set(`${Ke}:${pt.cell}`,`${Ke}:${pt.tmuxSession}`)}z(Ne=>d1(Ne,he))},[N]),E.useEffect(()=>{L.localNodeId&&z(he=>{const Ne=kh(he,L.localNodeId,M);return JSON.stringify(Ne)===JSON.stringify(he)?he:Ne})},[M,L.localNodeId]);const[F,T]=E.useState(null),[q,B]=E.useState(null),D=E.useRef(0),[U,Z]=E.useState(!1),[oe,de]=E.useState(gR),[fe,J]=E.useState(!w),[ee,pe]=E.useState(()=>w?localStorage.getItem(P_)==="1":!0),[Se,Ze]=E.useState(!1),[$e,He]=E.useState("nodes"),[vt,Xe]=E.useState(!1),[St,Et]=E.useState(""),[rt,ct]=E.useState(!1),ot=(he="nodes",Ne=!1,Ke="")=>{He(he),Xe(Ne),Et(Ke),Ze(!0)},[ut,dt]=E.useState(!1),[le,xe]=E.useState({deviceDefault:"",localNodeId:"",localNameDefault:""}),[ze,Ie]=E.useState(!1);E.useEffect(()=>{try{localStorage.setItem(tS,String(oe))}catch{}},[oe]),E.useEffect(()=>{try{localStorage.setItem(P_,ee?"1":"")}catch{}},[ee]),E.useEffect(()=>{if(!t)return;let he=!1;return Promise.all([H_(t),Vt("/api/config",t).then(Ne=>Ne.json())]).then(([Ne,Ke])=>{he||(xe({deviceDefault:Ne.deviceName||"",localNodeId:Ne.nodeId||"",localNameDefault:Ne.localName||""}),Ie(!!Ke.readonlyDefault),(Ne.firstRun===!0&&!Ke.readonlyDefault||s)&&dt(!0))}).catch(()=>{}),()=>{he=!0}},[t,s]);const ue=E.useCallback(async()=>{try{const Ne=await(await Vt("/api/sessions",t)).json();Ne.error||R(Ne.sessions||[])}catch{}try{const he=await _s(t);$(he.available?he.cells||[]:[]),V(he.available?he.capabilities||[]:[])}catch{$([]),V([])}},[t]);E.useEffect(()=>{if(!f)return;ue();const he=setInterval(ue,4e3);return()=>clearInterval(he)},[f,ue]),E.useEffect(()=>{let he=!1;return Vt("/api/config",t).then(Ne=>Ne.json()).then(Ne=>{he||uR(Ne.version,Ne.uiVersion,"0.8.45")}).catch(()=>{}),()=>{he=!0}},[t]);const G=new Set([...C.map(he=>he.name),...N.flatMap(he=>he.sessions.map(Ne=>Ne.key))]),ie=wi(Y),W=he=>z(Ne=>{const Ke=pw(he,L.localNodeId,M)||he,Nt=ny(Ne,Ke);return Nt===Ne&&wi(Ne).length>=9&&L.setError(m("grid-full")),Nt}),se=async(he,Ne=[])=>{try{await Bh(t,he,Ne)}catch{return}const Ke=Ne.length?`${Ne.join("/")}:${he}`:he;z(Nt=>Tl(Nt,Ke)),ue()},ve=async(he,Ne,Ke=[])=>{try{await $_(t,he,Ne,Ke)}catch{return}ue()},ke=async(he,Ne,Ke=[])=>{await O_(t,{cell:he,enabled:!!Ne},Ke),ue()},Re=async he=>{if(!F)return;const{cell:Ne}=F,Ke=Array.isArray(F.route)?F.route:[];he.action==="up"?await Ah(t,{cell:Ne,boot:!!he.boot,...he.engine?{engine:he.engine}:{},...he.model!==void 0?{model:he.model}:{},...he.permissionPolicy?{permissionPolicy:he.permissionPolicy}:{}},Ke):await Cl(t,{cell:Ne,boot:!!he.boot},Ke);const Nt=he.action==="up"?!!he.boot:he.boot?!1:!!F.boot;B({id:++D.current,cell:Ne,route:Ke,enabled:Nt}),ue()},we=E.useCallback(he=>{B(Ne=>(Ne==null?void 0:Ne.id)===he?null:Ne)},[]),je=async he=>{if(!(!(he!=null&&he.direct)||U)){Z(!0);try{await $h(t,he.name,he.tunnelStatus==="up"?"down":"up")}finally{Z(!1)}}},st=async(he,Ne)=>{const Ke=String(Ne||"").trim();return!(he!=null&&he.direct)||!jr(Ke)?!1:(await W_(t,he.name,Ke),!0)},It=he=>{const Ne=P.find(Ke=>Ke.id===he);if(!Ne)return!1;try{const Ke=window.open(td(Ne,t),"_blank");return Ke&&(Ke.opener=null),!!Ke}catch{return!1}},Oe=async he=>{if(!he||he===v)return;const Ne=await L.select(he),Ke=L.records.find(Nt=>Nt.id===he);b(he),z(Ne),H(null),I(null);try{history.replaceState(null,"",td(Ke||he,null))}catch{}},_n=async(he,Ne)=>{const Ke=await L.add(he,Ne);await Oe(Ke.id)},bt=async(he,Ne)=>{const Ke=await L.rename(he,Ne);if(he===v){b(Ke.id),z(kh(Ke.layout,L.localNodeId,M)),H(null),I(null);try{history.replaceState(null,"",td(Ke,null))}catch{}}},Ye=async he=>{await L.remove(he),he===v&&await Oe(L.localMainId)},Gt=async(he,Ne)=>{!Ne||Ne===v||(await L.addTileTo(Ne,he),z(Ke=>Tl(Ke,he)))};if(!t)return c.jsxs("div",{className:"nc-auth",children:[c.jsx("p",{children:m("auth-prompt")}),c.jsx("input",{onChange:he=>n(he.target.value.trim()),placeholder:"token"}),c.jsxs("label",{children:[c.jsx("input",{type:"checkbox",checked:u,onChange:he=>h(he.target.checked)})," ",m("remember-device")]}),c.jsx("button",{onClick:()=>{(u?localStorage:sessionStorage).setItem("nc_token",t)},children:"ok"})]});const Hn=c.jsxs(c.Fragment,{children:[Se&&c.jsx(qN,{token:t,initialTab:$e,initialLocation:St,startNewCell:vt,onClose:()=>{Ze(!1),Xe(!1),Et("")}}),ut&&c.jsx(VN,{token:t,initialPair:s,...le,onPairDone:a,onDone:()=>dt(!1)}),c.jsx(ZN,{token:t})]});if(!f)return S?c.jsxs(c.Fragment,{children:[c.jsx(D_,{session:S.session,node:S.node,ownerId:S.ownerId,cellName:S.cellName,token:t,readonly:ze,onBack:()=>y(null),onCellSwitcher:()=>ct(!0),cellSwitcherOpen:rt}),rt&&c.jsx(rR,{token:t,current:S,onPick:he=>{x(he),ct(!1)},onClose:()=>ct(!1)}),Hn]}):c.jsxs(c.Fragment,{children:[c.jsx(E1,{onPick:x,token:t,onSettings:ot}),Hn]});const li=w||!fe;return c.jsxs("div",{className:"nc-workspace",children:[li&&c.jsx(jE,{sessions:C,cells:k,activeSessions:ie,nodeGroups:N,fleetCapabilities:O,bootSettlement:q,onBootSettlementApplied:we,localNodeId:L.localNodeId,onPick:A,onAddTile:W,onPower:T,onBoot:ke,onBootError:he=>L.setError(String((he==null?void 0:he.message)||he)),onNodePower:je,onNodeRename:st,onKill:se,onVisibility:ve,onNew:()=>ot("fleet",!0),onSettings:ot,width:oe,collapsed:ee,onResize:de,onToggleCollapse:()=>pe(he=>!he)}),c.jsxs("div",{className:"nc-workspace-main",children:[c.jsx(u2,{decks:P,currentDeck:v,onCreate:_n,onRename:bt,onDelete:Ye,onReorder:L.reorder,onOpenWindow:It,onNavigate:Oe,saveState:L.saveState,error:L.error,sidebarVisible:li,onToggleSidebar:w?null:()=>J(he=>!he)}),c.jsx(IE,{layout:Y,onLayoutChange:z,token:t,readonly:ze,sessionsAlive:G,focusSession:ne,onFocus:H,onOpenSingle:A,decks:P,currentDeck:v,onSendToDeck:Gt,cells:k,nodeGroups:N})]}),X&&c.jsx("div",{className:"nc-single-overlay",children:c.jsx(D_,{session:X.session,node:X.node,ownerId:X.ownerId,cellName:df({session:X.session,node:X.node,ownerId:X.ownerId,cells:k,nodeGroups:N}),token:t,readonly:ze,onBack:()=>I(null)})}),F&&c.jsx(Nl,{cell:F,token:t,route:Array.isArray(F.route)?F.route:[],onConfirm:Re,onClose:()=>T(null)}),Hn]})}function bR(){$n();const e=E.useSyncExternalStore(cR,j_,j_);if(!e.needed)return null;const t=e.kind==="install"?m("install-version-mismatch").replace("{v}",e.version):m("update-available").replace("{v}",e.version).replace(" "," ").trim();return c.jsxs("div",{className:"nc-update",role:"status","aria-live":"polite",children:[c.jsx("span",{className:"nc-update-msg",children:t}),e.kind==="reload"&&c.jsx("button",{className:"nc-update-btn",onClick:fR,children:m("reload")})]})}hR();t0.createRoot(document.getElementById("root")).render(c.jsxs(Yb.StrictMode,{children:[c.jsx(SR,{}),c.jsx(bR,{})]}));
@@ -11,7 +11,7 @@
11
11
  <meta name="apple-mobile-web-app-title" content="NexusCrew" />
12
12
  <link rel="manifest" href="/manifest.json" />
13
13
  <title>NexusCrew</title>
14
- <script type="module" crossorigin src="/assets/index-CNI9gSN5.js"></script>
14
+ <script type="module" crossorigin src="/assets/index-DNFEGdog.js"></script>
15
15
  <link rel="stylesheet" crossorigin href="/assets/index-BAq6N1Md.css">
16
16
  </head>
17
17
  <body>
@@ -1 +1 @@
1
- {"version":"0.8.44"}
1
+ {"version":"0.8.45"}
@@ -56,10 +56,11 @@ function cellsRoutes({ fleetP, instanceId, submit, readonly = () => false, now =
56
56
 
57
57
  async function status() {
58
58
  const fleet = await fleetP;
59
- if (!fleet || fleet.available !== true || typeof fleet.status !== 'function') {
59
+ const statusFn = fleet && (typeof fleet.cellStatus === 'function' ? fleet.cellStatus : fleet.status);
60
+ if (!fleet || fleet.available !== true || typeof statusFn !== 'function') {
60
61
  return { available: false, cells: [] };
61
62
  }
62
- return fleet.status();
63
+ return statusFn.call(fleet);
63
64
  }
64
65
 
65
66
  r.get('/', async (_req, res) => {
@@ -264,7 +264,10 @@ function status(opts = {}) {
264
264
  remotePort: red.remotePort, localPort: red.localPort,
265
265
  direction: red.direction, shared: red.shared, hasToken: red.hasToken,
266
266
  tunnel: n.direction === 'inbound'
267
- ? { status: n.shared === true ? 'shared-peer' : 'private-peer', managed: false }
267
+ ? {
268
+ status: n.shared === true ? 'shared-peer' : 'private-peer', managed: false,
269
+ share: n.shared === true ? 'enabled' : 'disabled',
270
+ }
268
271
  : nodesTunnel.readTunnelState(home, n.name),
269
272
  };
270
273
  });
@@ -281,7 +284,7 @@ function status(opts = {}) {
281
284
  log(`port: ${out.port}`);
282
285
  log(`url: ${out.url}`);
283
286
  log(`roles: client=${out.roles.client} node=${out.roles.node}`);
284
- log(`nodes: ${out.nodes.length === 0 ? '(nessuno)' : out.nodes.map((n) => `${n.name}[${n.tunnel.status}]`).join(', ')}`);
287
+ log(`nodes: ${out.nodes.length === 0 ? '(nessuno)' : out.nodes.map((n) => `${n.name}[${n.tunnel.status}${n.tunnel.share ? `, Share ${n.tunnel.share}` : ''}]`).join(', ')}`);
285
288
  if (platform === 'termux') log(`boot: ${out.bootScriptInstalled ? 'boot-script installed' : 'no boot-script'}`);
286
289
  }
287
290
  return out;