@mmmbuto/nexuscrew 0.9.53 → 0.9.54

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
@@ -2,6 +2,13 @@
2
2
 
3
3
  All notable changes to NexusCrew are tracked here.
4
4
 
5
+ ## 0.9.54 — 2026-10-01
6
+
7
+ - **Il proxy federato non crolla più quando la porta del tunnel rifiuta la connessione.** Il listener degli errori sull'upstream federato viene registrato prima del connect: un rifiuto sulla porta del tunnel viene gestito come errore di connessione invece di propagarsi come eccezione non catturata e abbattere il processo.
8
+ - **Un config.json illeggibile non viene più riscritto.** Se la configurazione non si legge, il nodo non riparte da un oggetto vuoto: prima il fallback perdeva `autoUpdate` e `wizardDone` e il wizard si riapriva come al primo avvio. Ora la scrittura è fail-closed come quella di `fleet.json` e l'illeggibilità viene riportata per quello che è — una categoria di errore — invece del messaggio del parser.
9
+ - **Impostazioni, `autoupdate off` e identity rifiutano con un errore chiaro invece di perdere le chiavi.** Le tre operazioni verificano prima di scrivere: quando la configurazione non è in condizione di essere aggiornata rispondono con il motivo, senza cancellare o corrompere le chiavi esistenti.
10
+ - **L'avviso non riporta mai il contenuto del file.** Quando una scrittura fallisce, il messaggio nomina il file e il motivo, senza incollarne il contenuto.
11
+
5
12
  ## 0.9.53 — 2026-09-30
6
13
 
7
14
  - **Telefono: le preferenze non si perdono più quando il browser le dimentica.** Pin, ordine delle celle e viste si sincronizzano sul nodo, per dispositivo: un telefono ritrova la sua disposizione anche dopo che lo storage del browser è stato svuotato. Il link di `show` porta l'identificativo del dispositivo; al primo uso il nodo ne emette uno. Una copia vuota non sostituisce mai una copia piena, un ripristino fallito viene riportato per quello che è e il nodo conserva la sua versione per ritentare al giro successivo. In Impostazioni c'è il diario delle ultime scritture (con copia e pulizia) e lo stato della memoria; l'app chiede al browser la memoria persistente, registra l'esito e ritenta un rifiuto al massimo una volta al giorno. I file di esportazione e importazione contengono solo pin, ordine e viste, mai il token.
@@ -166,4 +166,4 @@ Minimum version required to store current data is: `+q+`.
166
166
  `).filter(i=>i!==""),promptMode:t.promptMode};return t.modelFlag&&(s.model={flag:t.modelFlag,value:t.modelValue||""}),t.promptMode==="flag"&&(s.promptFlag=t.promptFlag),e&&(s.env=Object.fromEntries(t.envRows.filter(i=>!i.remove&&i.key).map(i=>[i.key,i.value]))),PS(s,t,e)}function Qr({children:t,onClose:e,label:n,error:s=""}){const i=w.useRef(null),a=w.useRef(null),c=w.useRef(e);return c.current=e,w.useEffect(()=>{const u=document.activeElement,h=i.current,f=()=>Array.from((h==null?void 0:h.querySelectorAll('button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [href], [tabindex]:not([tabindex="-1"])'))||[]).filter(_=>_.offsetParent!==null),v=requestAnimationFrame(()=>{var _;return(_=f()[0]||h)==null?void 0:_.focus({preventScroll:!0})}),g=_=>{var C;if(_.key==="Escape"){_.preventDefault(),(C=c.current)==null||C.call(c);return}if(_.key!=="Tab")return;const b=f();if(!b.length){_.preventDefault(),h==null||h.focus();return}const S=b[0],E=b[b.length-1];_.shiftKey&&document.activeElement===S?(_.preventDefault(),E.focus()):!_.shiftKey&&document.activeElement===E&&(_.preventDefault(),S.focus())};return document.addEventListener("keydown",g),()=>{cancelAnimationFrame(v),document.removeEventListener("keydown",g),u&&u.isConnected&&typeof u.focus=="function"&&u.focus({preventScroll:!0})}},[]),w.useEffect(()=>{s&&requestAnimationFrame(()=>{var u;return(u=a.current)==null?void 0:u.scrollIntoView({block:"nearest"})})},[s]),l.jsx("div",{className:"nc-fleet-modal",role:"presentation",onMouseDown:u=>{u.target===u.currentTarget&&e()},children:l.jsxs("div",{ref:i,className:"nc-fleet-modal-dialog",role:"dialog","aria-modal":"true","aria-label":n||p("settings"),tabIndex:-1,children:[t,s&&l.jsx("div",{ref:a,className:"nc-err nc-fleet-modal-error",role:"alert","aria-live":"assertive",children:s})]})})}function Vp({token:t,targets:e=[],readonly:n=!1,onPower:s,onImport:i}){const[a,c]=w.useState([]),[u,h]=w.useState(0);w.useEffect(()=>{let C=!0;async function N(){const I=[{route:[],label:p("local")}].concat((e||[]).map(H=>({route:Array.isArray(H.route)?H.route:[],label:H.label||(H.route||[]).join(" › ")}))),L=await Promise.all(I.map(async H=>{const z={...H,available:!1,readonly:!1,capabilities:[],provider:null,cells:[],unmanaged:[],err:""};try{const V=await Cr(t,H.route);z.available=!!V.available,z.capabilities=V.capabilities||[],z.provider=V.provider||null,z.cells=(V.cells||[]).map(Y=>({...Y,route:H.route}));try{z.readonly=!!(await Hv(t,H.route)).readonlyDefault}catch{}try{const Y=await Fv(t,H.route),G=new Set(z.cells.map(Z=>Z.tmuxSession).filter(Boolean));z.unmanaged=(Y.sessions||[]).filter(Z=>Z&&!G.has(Z.name))}catch{}}catch(V){z.err=String(V&&V.message||V)}return z}));C&&c(L)}N();const k=setInterval(N,6e3);return()=>{C=!1,clearInterval(k)}},[t,e,u]);const f=(C,N)=>Array.isArray(C.capabilities)&&C.capabilities.includes(N)&&!n&&!C.readonly,v=()=>h(C=>C+1),g=(C,N)=>{s&&s({...C,route:N})},_=(C,N)=>{s&&s({...C,route:N})},b=async(C,N)=>{try{await Ql(t,C.cell,N)}catch{}v()},S=async(C,N)=>{if(window.confirm(p("fleet-remove-cell").replace("{id}",C.cell))){try{await m1(t,C.cell,!0,N)}catch{}v()}},E=async(C,N)=>{if(window.confirm(p("terminate-confirm").replace("{name}",C.name))){try{await $v(t,C.name,N)}catch{}v()}};return l.jsxs("div",{className:"nc-fleet-inventory",children:[l.jsxs("div",{className:"nc-fleet-section-head",children:[l.jsx("b",{children:p("fleet-inventory")}),l.jsx("small",{children:p("fleet-inventory-help")})]}),a.map(C=>{const N=C.route.length?C.route.join("/"):"local";return l.jsxs("div",{className:"nc-fleet-pos",children:[l.jsxs("div",{className:"nc-fleet-pos-title",children:[l.jsx("span",{className:`dot ${C.available?"on":"warn"}`}),l.jsx("b",{children:C.label}),l.jsx("small",{children:C.available?`${C.cells.length} ${p("fleet-cells")} · ${C.unmanaged.length} ${p("fleet-tmux")}`:C.err||p("fleet-not-available")})]}),C.cells.map(k=>l.jsxs("div",{className:"nc-fleet-item nc-fleet-cell",children:[l.jsxs("span",{children:[l.jsx("b",{children:k.cell}),l.jsx("small",{children:`${k.engine||""}${k.key?`·${k.key}`:""}${k.active?"":` · ${p("cell-off")}`}`})]}),l.jsxs("span",{className:"nc-fleet-cell-actions",children:[k.active&&f(C,"down")&&l.jsx("button",{className:"nc-btn ghost",title:p("power-off"),onClick:()=>_(k,C.route),children:p("stop")}),!k.active&&f(C,"up")&&l.jsx("button",{className:"nc-btn ghost",title:p("power-on"),onClick:()=>g(k,C.route),children:p("start")}),f(C,"restart")&&k.active&&l.jsx("button",{className:"nc-btn ghost",title:p("restart"),onClick:()=>b(k,C.route),children:p("restart")}),f(C,"remove")&&l.jsx("button",{className:"nc-btn danger",title:p("delete"),onClick:()=>S(k,C.route),children:"×"})]})]},`${N}:${k.cell}`)),C.unmanaged.map(k=>l.jsxs("div",{className:"nc-fleet-item nc-fleet-unmanaged",children:[l.jsxs("span",{children:[l.jsx("b",{children:k.name}),l.jsx("small",{children:p("fleet-tmux")})]}),l.jsxs("span",{className:"nc-fleet-cell-actions",children:[f(C,"import")&&i&&l.jsx("button",{className:"nc-btn ghost",title:p("import-as-cell"),onClick:()=>i(k,C.route),children:p("import-as-cell")}),l.jsx("button",{className:"nc-btn danger",title:p("terminate"),onClick:()=>E(k,C.route),children:"×"})]})]},`${N}:u:${k.name}`)),C.available&&C.cells.length===0&&C.unmanaged.length===0&&l.jsx("div",{className:"nc-empty",children:p("fleet-inventory-empty")})]},N)})]})}function hD({cells:t=[],engines:e=[],models:n=[],busy:s,canRestore:i=!1,onRestore:a,onClose:c}){const[u,h]=w.useState("export"),[f,v]=w.useState([]),[g,_]=w.useState(()=>new Set(t.map(O=>O.id))),[b,S]=w.useState(()=>new Set(e.map(O=>O.id))),[E,C]=w.useState([]),[N,k]=w.useState([]),[I,L]=w.useState(""),H=new Set(e.map(O=>O.id)),z=new Set(t.map(O=>O.id)),V=(O,A)=>O(M=>{const R=new Set(M);return R.has(A)?R.delete(A):R.add(A),R}),Y=()=>{const O=rD(t,g,e,b,new Date,n);if(O.ok===!1){L(p(`fleet-backup-${O.error}`));return}const A=t.filter(K=>g.has(K.id)).length,M=e.filter(K=>b.has(K.id)).length;if(O.cells.length!==A){L(p("fleet-backup-invalid-cell"));return}if(O.engines.length!==M){L(p("fleet-backup-invalid-engine"));return}if(!O.cells.length&&!O.engines.length){L(p("fleet-backup-select-one"));return}const R=new Blob([`${JSON.stringify(O,null,2)}
167
167
  `],{type:"application/json"}),F=URL.createObjectURL(R),$=document.createElement("a");$.href=F,$.download=`nexuscrew-fleet-${new Date().toISOString().slice(0,10)}.json`,document.body.appendChild($),$.click(),$.remove(),setTimeout(()=>URL.revokeObjectURL(F),0),L("")},G=async O=>{if(L(""),C([]),k([]),!!O){if(O.size>1024*1024){L(p("fleet-backup-too-large"));return}try{const A=oD(await O.text());if(!A.ok){L(p(`fleet-backup-${A.error}`));return}v(Array.isArray(A.models)?A.models:[]);const M=new Set(A.engines.map(R=>R.id));k(A.engines.map(R=>({engine:R,exists:H.has(R.id),selected:!H.has(R.id)}))),C(A.cells.map(R=>{const F=H.has(R.engine)||M.has(R.engine),$=z.has(R.id);return{cell:R,engine:F?R.engine:"",selected:F&&!$,exists:$}}))}catch(A){L(String(A.message||A))}}},Z=(O,A)=>C(M=>M.map((R,F)=>F===O?{...R,...A}:R)),q=(O,A)=>k(M=>M.map((R,F)=>F===O?{...R,...A}:R)),T=new Set([...H,...N.filter(O=>O.selected).map(O=>O.engine.id)]),P=E.filter(O=>O.selected&&O.engine&&T.has(O.engine)),D=N.filter(O=>O.selected),j=[...new Map([...e.map(O=>[O.id,O.label||O.id]),...N.filter(O=>O.selected).map(O=>[O.engine.id,O.engine.label||O.engine.id])]).entries()];return l.jsxs("div",{className:"nc-set-form nc-fleet-form nc-backup-dialog",children:[l.jsx("b",{children:p("fleet-backup")}),l.jsx("small",{children:p("fleet-backup-help")}),l.jsxs("div",{className:"nc-set-tabs nc-backup-tabs",children:[l.jsx("button",{type:"button",className:`nc-set-tabbtn${u==="export"?" on":""}`,onClick:()=>{h("export"),L("")},children:p("fleet-backup-export")}),l.jsx("button",{type:"button",className:`nc-set-tabbtn${u==="import"?" on":""}`,disabled:!i,title:i?"":p("fleet-backup-restore-unavailable"),onClick:()=>{h("import"),L("")},children:p("fleet-backup-import")})]}),u==="export"?l.jsxs(l.Fragment,{children:[l.jsxs("div",{className:"nc-set-row",children:[l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:()=>{_(new Set(t.map(O=>O.id))),S(new Set(e.map(O=>O.id)))},children:p("select-all")}),l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:()=>{_(new Set),S(new Set)},children:p("select-none")})]}),l.jsxs("div",{className:"nc-backup-list",children:[l.jsx("b",{children:p("fleet-engines")}),e.map(O=>{var A;return l.jsxs("label",{className:"nc-check nc-backup-row",children:[l.jsx("input",{type:"checkbox",checked:b.has(O.id),onChange:()=>V(S,O.id)}),l.jsxs("span",{children:[l.jsx("b",{children:O.label||O.id}),l.jsxs("small",{children:[O.id,(A=O.envKeys)!=null&&A.length?` · ${O.envKeys.length} ${p("fleet-backup-env-names")}`:""]})]})]},O.id)}),l.jsx("b",{children:p("fleet-cells")}),t.map(O=>l.jsxs("label",{className:"nc-check nc-backup-row",children:[l.jsx("input",{type:"checkbox",checked:g.has(O.id),onChange:()=>V(_,O.id)}),l.jsxs("span",{children:[l.jsx("b",{children:O.id}),l.jsxs("small",{children:[O.engine," · ",p("fleet-system-prompt")," ",(O.prompt||"").length," ",p("characters")]})]})]},O.id)),!t.length&&!e.length&&l.jsx("div",{className:"nc-empty",children:p("fleet-backup-empty")})]}),l.jsxs("div",{className:"nc-sheet-actions",children:[l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:c,children:p("cancel")}),l.jsx("button",{type:"button",className:"nc-btn primary",disabled:!g.size&&!b.size,onClick:Y,children:p("fleet-backup-download")})]})]}):l.jsxs(l.Fragment,{children:[l.jsx("input",{type:"file",accept:"application/json,.json",disabled:s,onChange:O=>G(O.target.files&&O.target.files[0])}),l.jsx("small",{children:p("fleet-backup-import-help")}),!!(E.length||N.length)&&l.jsxs("div",{className:"nc-set-row",children:[l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:()=>{k(O=>O.map(A=>({...A,selected:!0}))),C(O=>O.map(A=>({...A,selected:!!A.engine})))},children:p("select-all")}),l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:()=>{k(O=>O.map(A=>({...A,selected:!1}))),C(O=>O.map(A=>({...A,selected:!1})))},children:p("select-none")})]}),l.jsxs("div",{className:"nc-backup-list",children:[!!N.length&&l.jsx("b",{children:p("fleet-engines")}),N.map((O,A)=>{var M;return l.jsx("div",{className:"nc-backup-import-row",children:l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox",checked:O.selected,onChange:R=>q(A,{selected:R.target.checked})}),l.jsxs("span",{children:[l.jsx("b",{children:O.engine.label||O.engine.id}),l.jsxs("small",{children:[O.engine.id," · ",O.exists?p("fleet-backup-overwrite"):p("fleet-backup-new"),(M=O.engine.envKeys)!=null&&M.length?` · ${p("fleet-backup-env-values-required")}`:""]})]})]})},O.engine.id)}),!!E.length&&l.jsx("b",{children:p("fleet-cells")}),E.map((O,A)=>l.jsxs("div",{className:"nc-backup-import-row",children:[l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox",checked:O.selected,disabled:!O.engine||!T.has(O.engine),onChange:M=>Z(A,{selected:M.target.checked})}),l.jsxs("span",{children:[l.jsx("b",{children:O.cell.id}),l.jsxs("small",{children:[O.exists?p("fleet-backup-overwrite"):p("fleet-backup-new")," · ",p("fleet-system-prompt")," ",O.cell.systemPrompt.length," ",p("characters")]})]})]}),l.jsxs("select",{value:O.engine,onChange:M=>Z(A,{engine:M.target.value,selected:!!M.target.value}),children:[l.jsx("option",{value:"",children:p("fleet-backup-engine-missing")}),j.map(([M,R])=>l.jsx("option",{value:M,children:R},M))]})]},O.cell.id))]}),l.jsxs("div",{className:"nc-sheet-actions",children:[l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:c,children:p("cancel")}),l.jsx("button",{type:"button",className:"nc-btn primary",disabled:s||!P.length&&!D.length,onClick:()=>a({engineRows:N,cellRows:E,models:f}),children:p("fleet-backup-restore")})]})]}),I&&l.jsx("div",{className:"nc-err",children:I})]})}function fD({state:t,setState:e,busy:n,onSave:s,catalog:i}){var N;const a=t.form,c=k=>e({...t,form:{...a,...k}}),u=a.envRows||[],h=[...new Map(i.map(k=>[k.client,k.clientLabel||k.client])).entries()],f=i.filter(k=>k.client===a.client),v=Ec(i,a),g=typeof(v==null?void 0:v.credentialEnv)=="string"?v.credentialEnv:"",_=Array.isArray(v==null?void 0:v.credentialUsedBy)?v.credentialUsedBy:[],b=(v==null?void 0:v.credentialSource)||"missing",S=!!(v!=null&&v.credentialEnv)||a.credentialProfile==="a"||a.credentialProfile==="p",E=!!g&&t.mode==="new"&&(v==null?void 0:v.authConfigured)!==!0&&!a.credentialValue&&!a.allowMissingCredential,C=k=>{k&&c({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?p("fleet-custom-provider-default"):"",baseUrl:k.custom?"":k.endpoint||"",envKey:k.defaultEnvKey||"",providerId:"nexuscrew-custom",credentialValue:"",credentialReveal:!1,allowMissingCredential:!1,...t.mode==="new"?{id:k.id,label:""}:{}})};return l.jsxs("div",{className:"nc-set-form nc-fleet-form",children:[l.jsx("b",{children:t.mode==="new"?p("fleet-new-engine"):`${p("edit")} ${a.id}`}),l.jsx("input",{value:a.id,disabled:t.mode!=="new",placeholder:"id",onChange:k=>c({id:k.target.value})}),l.jsx("input",{value:a.label,placeholder:p("label"),onChange:k=>c({label:k.target.value})}),l.jsxs("select",{value:a.kind,disabled:t.mode!=="new",onChange:k=>c({kind:k.target.value}),children:[l.jsx("option",{value:"managed",children:p("fleet-managed")}),l.jsx("option",{value:"custom",children:p("fleet-custom")})]}),a.kind==="managed"?l.jsxs(l.Fragment,{children:[l.jsxs("div",{className:"nc-fleet-pair",children:[l.jsx("select",{value:a.client,disabled:t.mode!=="new",onChange:k=>C(i.find(I=>I.client===k.target.value&&I.default)||i.find(I=>I.client===k.target.value)),children:h.map(([k,I])=>l.jsx("option",{value:k,children:I},k))}),l.jsx("select",{value:((N=Ec(i,a))==null?void 0:N.id)||"",disabled:t.mode!=="new",onChange:k=>C(i.find(I=>I.id===k.target.value)),children:f.map(k=>l.jsx("option",{value:k.id,children:k.label},k.id))})]}),a.client!=="shell"&&l.jsxs(l.Fragment,{children:[l.jsx("input",{value:a.managedModel,list:"nc-managed-models",placeholder:p(v!=null&&v.requiresModel?"fleet-model-required":"fleet-model-default"),onChange:k=>c({managedModel:k.target.value})}),l.jsx("datalist",{id:"nc-managed-models",children:[...(v==null?void 0:v.models)||[],...a.modelOptions||[]].filter((k,I,L)=>k&&L.indexOf(k)===I).map(k=>l.jsx("option",{value:k},k))})]}),v!=null&&v.supportsUnsafe?l.jsxs("select",{value:a.permissionPolicy,onChange:k=>c({permissionPolicy:k.target.value}),children:[l.jsx("option",{value:"standard",children:p("fleet-standard-permissions")}),l.jsx("option",{value:"unsafe",children:p("fleet-unsafe-permissions")})]}):l.jsx("small",{children:p("fleet-standard-permissions")}),(v==null?void 0:v.supportsUnsafe)&&a.permissionPolicy==="unsafe"&&l.jsx("small",{className:"nc-err",children:p("fleet-unsafe-warning")}),S&&l.jsxs("select",{"aria-label":p("fleet-credential-source-policy"),value:a.credentialSourcePolicy||"auto",onChange:k=>c({credentialSourcePolicy:k.target.value}),children:[l.jsx("option",{value:"auto",children:p("fleet-credential-source-policy-auto")}),l.jsx("option",{value:"nexuscrew-store",children:p("fleet-credential-source-policy-nexuscrew-store")}),l.jsx("option",{value:"environment",children:p("fleet-credential-source-policy-environment")})]}),(v==null?void 0:v.credentialEnv)===!0&&l.jsxs(l.Fragment,{children:[l.jsx("input",{value:a.envKey,placeholder:p("fleet-api-key-env"),onChange:k=>c({envKey:k.target.value})}),l.jsx("small",{children:p("fleet-custom-secret-help")})]}),g&&l.jsxs("section",{className:"nc-fleet-key","aria-label":p("fleet-key-section"),children:[l.jsxs("div",{className:"nc-fleet-key-head",children:[l.jsx("b",{children:p("fleet-key-section")}),l.jsx("span",{children:p(`fleet-credential-source-${b}`)})]}),l.jsxs("label",{className:"nc-field",children:[p("fleet-key-variable"),l.jsx("input",{value:g,readOnly:!0,"aria-label":p("fleet-key-variable")})]}),l.jsx("small",{children:_.length?p("fleet-key-used-by").replace("{engines}",_.join(", ")):p("fleet-key-used-by-none")}),_.length>0&&l.jsx("small",{children:p("fleet-key-shared-impact").replace("{key}",g).replace("{engines}",_.join(", "))}),l.jsxs("div",{className:"nc-fleet-key-input",children:[l.jsx("input",{type:a.credentialReveal?"text":"password",value:a.credentialValue||"","aria-label":p("fleet-key-value").replace("{key}",g),autoComplete:"new-password",spellCheck:!1,autoCapitalize:"none",autoCorrect:"off",placeholder:v!=null&&v.authConfigured||t.mode==="edit"?p("fleet-key-blank-keeps"):p("fleet-key-enter"),onChange:k=>c({credentialValue:k.target.value,allowMissingCredential:k.target.value?!1:a.allowMissingCredential})}),l.jsx("button",{type:"button",className:"nc-btn ghost","aria-label":p(a.credentialReveal?"fleet-key-hide":"fleet-key-reveal"),onClick:()=>c({credentialReveal:!a.credentialReveal}),children:p(a.credentialReveal?"fleet-key-hide":"fleet-key-reveal")})]}),l.jsx("small",{children:p("fleet-key-local-help")}),t.mode==="new"&&(v==null?void 0:v.authConfigured)!==!0&&!a.credentialValue&&l.jsxs("label",{className:"nc-check nc-fleet-key-missing",children:[l.jsx("input",{type:"checkbox",checked:!!a.allowMissingCredential,onChange:k=>c({allowMissingCredential:k.target.checked})}),p("fleet-key-create-missing")]}),(v==null?void 0:v.notice)&&l.jsx("small",{className:"nc-fleet-provider-notice",children:p(`fleet-provider-notice-${v.notice}`)})]}),(v==null?void 0:v.notice)&&!g&&l.jsx("small",{className:"nc-fleet-provider-notice",children:p(`fleet-provider-notice-${v.notice}`)}),a.provider==="custom"&&l.jsxs(l.Fragment,{children:[l.jsx("input",{value:a.displayName,placeholder:p("fleet-provider-display"),onChange:k=>c({displayName:k.target.value})}),l.jsx("input",{value:a.baseUrl,placeholder:"https://api.example.com/v1",onChange:k=>c({baseUrl:k.target.value})}),((v==null?void 0:v.protocols)||[]).length>1&&l.jsx("select",{value:a.protocol,onChange:k=>c({protocol:k.target.value}),children:v.protocols.map(k=>l.jsx("option",{value:k,children:k},k))}),l.jsxs("div",{className:"nc-fleet-pair",children:[l.jsx("input",{value:a.envKey,placeholder:p("fleet-api-key-env"),onChange:k=>c({envKey:k.target.value})}),l.jsx("input",{value:a.providerId,placeholder:p("fleet-provider-id"),onChange:k=>c({providerId:k.target.value})})]}),l.jsxs("small",{children:[a.protocol," · ",p("fleet-custom-secret-help")]})]}),l.jsx("small",{children:p(a.client==="shell"?"fleet-shell-engine-help":"fleet-managed-help")})]}):l.jsxs(l.Fragment,{children:[l.jsx("input",{value:a.command,placeholder:p("command-path"),onChange:k=>c({command:k.target.value})}),l.jsx("textarea",{value:a.argsText,placeholder:p("args-lines"),onChange:k=>c({argsText:k.target.value})}),l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox",checked:a.rc,onChange:k=>c({rc:k.target.checked})})," ",p("fleet-remote-control")]}),l.jsxs("select",{value:a.promptMode,onChange:k=>c({promptMode:k.target.value}),children:[l.jsx("option",{value:"send-keys",children:"send-keys"}),l.jsx("option",{value:"flag",children:"flag"})]}),a.promptMode==="flag"&&l.jsx("input",{value:a.promptFlag,placeholder:"prompt flag",onChange:k=>c({promptFlag:k.target.value})}),l.jsxs("div",{className:"nc-fleet-pair",children:[l.jsx("input",{value:a.modelFlag,placeholder:"model flag",onChange:k=>c({modelFlag:k.target.value})}),l.jsx("input",{value:a.modelValue,placeholder:"model default",onChange:k=>c({modelValue:k.target.value})})]}),l.jsx("small",{children:p("env-write-only")}),u.map((k,I)=>l.jsxs("div",{className:"nc-fleet-env",children:[l.jsx("input",{value:k.key,disabled:k.configured,placeholder:"ENV_KEY",onChange:L=>{const H=u.slice();H[I]={...k,key:L.target.value},c({envRows:H})}}),l.jsx("input",{type:"password",value:k.value,placeholder:k.configured?"•••••• (unchanged)":"value",onChange:L=>{const H=u.slice();H[I]={...k,value:L.target.value},c({envRows:H})}}),l.jsx("button",{className:"nc-btn danger",onClick:()=>c({envRows:u.filter((L,H)=>H!==I)}),children:"×"})]},`${k.key}-${I}`)),l.jsx("button",{className:"nc-btn ghost",onClick:()=>c({envRows:[...u,{key:"",value:"",configured:!1}]}),children:"+ env"})]}),l.jsx("input",{value:a.panelUrl||"",maxLength:512,placeholder:p("fleet-panel-url"),onChange:k=>c({panelUrl:k.target.value})}),l.jsx("small",{children:p("fleet-panel-url-help")}),a.panelUrl&&!Og(a.panelUrl)&&l.jsx("small",{className:"nc-err",children:p("fleet-panel-url-invalid")}),l.jsxs("div",{className:"nc-sheet-actions",children:[l.jsx("button",{className:"nc-btn ghost",onClick:()=>e(null),children:p("cancel")}),l.jsx("button",{className:"nc-btn primary",disabled:n||!a.id||E||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:p("save")})]})]})}function pD({state:t,setState:e,busy:n,onSave:s,onTest:i,profiles:a=[],canTest:c=!0}){const[u,h]=w.useState(null),[f,v]=w.useState(!1),g=t.form,_=C=>e({...t,form:{...g,...C}}),b=/^[^\x00-\x1f\x7f]{1,128}$/.test(g.id||""),S=!!(g.id||"").trim()&&!!(g.engine||"").trim()&&b,E=async()=>{h(null),v(!0);try{h(await i(g.engine,g.id))}catch(C){h({outcome:"unverified",detail:String(C&&C.message||C)})}v(!1)};return l.jsxs("div",{className:"nc-fleet-form",children:[l.jsxs("label",{className:"nc-field",children:[p("model-editor-engine"),l.jsxs("select",{value:g.engine||"",disabled:n||t.mode==="edit",onChange:C=>{h(null),_({engine:C.target.value})},children:[l.jsx("option",{value:"",children:"—"}),a.map(C=>l.jsx("option",{value:C.id,children:C.label?`${C.id} · ${C.label}`:C.id},C.id))]})]}),l.jsxs("label",{className:"nc-field",children:[p("model-editor-id"),l.jsx("input",{value:g.id||"",disabled:n||t.mode==="edit",placeholder:"qwen3.9-max",onChange:C=>{h(null),_({id:C.target.value})}})]}),l.jsx("small",{className:"nc-set-hint",children:p("model-editor-id-help")}),l.jsxs("label",{className:"nc-field",children:[p("model-editor-context"),l.jsx("input",{inputMode:"numeric",value:g.contextWindow||"",disabled:n,onChange:C=>_({contextWindow:C.target.value.replace(/[^0-9]/g,"").slice(0,9)})})]}),l.jsxs("label",{className:"nc-field",children:[p("model-editor-max-tokens"),l.jsx("input",{inputMode:"numeric",value:g.maxTokens||"",disabled:n,onChange:C=>_({maxTokens:C.target.value.replace(/[^0-9]/g,"").slice(0,9)})})]}),l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox",checked:g.reasoning===!0,disabled:n,onChange:C=>_({reasoning:C.target.checked})})," ",p("model-editor-reasoning")]}),l.jsxs("div",{className:"nc-set-row",children:[c&&l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:n||f||!S,onClick:E,children:p(f?"model-test-running":"model-test")}),u&&l.jsxs("span",{className:`nc-model-test ${u.outcome}`,children:[p(`model-test-${u.outcome}`),u.outcome==="ok"&&Number.isInteger(u.latencyMs)?` · ${u.latencyMs}ms`:""]})]}),u&&u.detail&&l.jsx("small",{className:"nc-set-hint",children:u.detail}),u&&u.outcome==="unverified"&&l.jsx("small",{className:"nc-set-hint",children:p("model-test-unverified-help")}),l.jsxs("div",{className:"nc-sheet-actions",children:[l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:()=>e(null),children:p("cancel")}),l.jsx("button",{type:"button",className:"nc-btn primary",disabled:n||!S,onClick:()=>s(g),children:p("save")})]})]})}function mD({token:t,route:e,targets:n=[],location:s,setLocation:i,state:a,setState:c,engines:u,mcpServers:h=[],managedCatalog:f=[],busy:v,onSave:g}){var D,j,O;const[_,b]=w.useState(null),[S,E]=w.useState(""),C=a.form,N=A=>c({...a,form:{...C,...A}}),k=u.find(A=>A.id===C.engine),I=((D=k==null?void 0:k.managed)==null?void 0:D.client)==="shell",L=((j=k==null?void 0:k.managed)==null?void 0:j.client)||"",H=((O=f.find(A=>A.client===L))==null?void 0:O.mcpManaged)!==!1,z=A=>{var F,$,K,oe;const M=u.find(ce=>ce.id===A),R={...C.commands||{}};((F=k==null?void 0:k.managed)==null?void 0:F.client)==="shell"&&(C.command?R[C.engine]=C.command:delete R[C.engine]),N({engine:A,model:(($=C.models)==null?void 0:$[A])||((K=M==null?void 0:M.managed)==null?void 0:K.model)||((oe=M==null?void 0:M.model)==null?void 0:oe.value)||"",commands:R,command:R[A]||""})},V=A=>{const M={...C.commands||{}};A?M[C.engine]=A:delete M[C.engine],N({command:A,commands:M})},Y=I&&/[|&;<>()`$*?{}\[\]~]/.test(C.command||""),G=[...new Set([...h||[],...Array.isArray(C.mcp)?C.mcp:[]])].sort(),Z=Array.isArray(C.mcp)?C.mcp.length?"some":"none":"all",q=A=>{var M;return N({mcp:A==="all"?void 0:A==="none"?[]:(M=C.mcp)!=null&&M.length?C.mcp:[...G]})},T=A=>{const M=Array.isArray(C.mcp)?C.mcp:[];N({mcp:M.includes(A)?M.filter(R=>R!==A):[...M,A].sort()})},P=async A=>{try{const M=await zv(t,A,e);b(M),N({cwd:M.path}),E("")}catch(M){E(String(M.message||M))}};return l.jsxs("div",{className:"nc-set-form nc-fleet-form",children:[l.jsx("b",{children:a.mode==="new"?p("fleet-new-cell"):`${p("edit")} ${C.id}`}),a.mode==="new"&&l.jsxs("label",{className:"nc-field",children:[p("location"),l.jsx("span",{className:"nc-req",children:" *"}),l.jsxs("select",{value:s,onChange:A=>{i(A.target.value),N({engine:""})},children:[l.jsx("option",{value:"",children:p("local")}),n.map(A=>l.jsxs("option",{value:A.route.join("/"),disabled:A.status&&A.status!=="up",children:[A.label,A.status&&A.status!=="up"?` · ${p("node-offline")}`:""]},A.route.join("/")))]})]}),l.jsx("input",{value:C.id,disabled:a.mode!=="new",placeholder:"id",onChange:A=>N({id:A.target.value})}),l.jsx("input",{value:C.label||"",maxLength:64,placeholder:p("fleet-cell-label"),onChange:A=>N({label:A.target.value})}),l.jsxs("div",{className:"nc-fleet-pair",children:[l.jsx("input",{value:C.cwd,placeholder:p("cwd"),onChange:A=>N({cwd:A.target.value})}),l.jsx("button",{className:"nc-btn ghost",onClick:()=>_?b(null):P(C.cwd),children:p("browse")})]}),_&&l.jsxs("div",{className:"nc-fs",children:[l.jsx("div",{className:"nc-fs-path",children:_.path}),l.jsxs("div",{className:"nc-fs-list",children:[_.parent&&l.jsxs("button",{className:"nc-fs-item nc-fs-nav",onClick:()=>P(_.parent),children:["↑ ",p("fs-parent")]}),(_.dirs||[]).map(A=>l.jsxs("button",{className:"nc-fs-item",onClick:()=>P(`${_.path.replace(/\/$/,"")}/${A}`),children:["📁 ",A]},A))]})]}),S&&l.jsx("div",{className:"nc-err",children:S}),l.jsx("select",{value:C.engine,onChange:A=>z(A.target.value),children:u.map(A=>l.jsx("option",{value:A.id,children:A.label},A.id))}),l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox",checked:!!C.boot,onChange:A=>N({boot:A.target.checked})})," ",p("fleet-boot")]}),l.jsx("input",{value:C.panelUrl||"",maxLength:512,placeholder:p("fleet-panel-url"),onChange:A=>N({panelUrl:A.target.value})}),l.jsx("small",{children:p("fleet-panel-url-help")}),C.panelUrl&&!Og(C.panelUrl)&&l.jsx("small",{className:"nc-err",children:p("fleet-panel-url-invalid")}),I?l.jsxs(l.Fragment,{children:[l.jsx("input",{value:C.command||"",maxLength:4096,placeholder:p("fleet-shell-command-placeholder"),onChange:A=>V(A.target.value)}),l.jsx("small",{children:C.command?p("fleet-shell-command-help"):p("fleet-shell-interactive")}),Y&&l.jsx("small",{className:"nc-note",children:p("fleet-shell-command-metachar")})]}):l.jsxs(l.Fragment,{children:[l.jsx("input",{value:C.model||"",list:"nc-cell-models",placeholder:p("fleet-model-override"),onChange:A=>N({model:A.target.value})}),l.jsx("datalist",{id:"nc-cell-models",children:((k==null?void 0:k.availableModels)||[]).map(A=>l.jsx("option",{value:A},A))}),l.jsx("textarea",{value:C.prompt||"",placeholder:p("cell-prompt"),onChange:A=>N({prompt:A.target.value})}),l.jsx("small",{children:p("cell-prompt-help")}),l.jsxs("label",{className:"nc-field",children:[p("cell-mcp"),l.jsxs("select",{value:Z,onChange:A=>q(A.target.value),children:[l.jsx("option",{value:"all",children:p("cell-mcp-all")}),l.jsx("option",{value:"none",children:p("cell-mcp-none")}),l.jsx("option",{value:"some",children:p("cell-mcp-some")})]})]}),!H&&l.jsx("small",{className:"nc-note",children:p("cell-mcp-inert")}),Z==="some"&&l.jsx("div",{className:"nc-fleet-mcp-list",children:G.map(A=>l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox",checked:(C.mcp||[]).includes(A),onChange:()=>T(A)})," ",A]},A))}),l.jsx("small",{children:p("cell-mcp-help")})]}),l.jsxs("div",{className:"nc-sheet-actions",children:[l.jsx("button",{className:"nc-btn ghost",onClick:()=>c(null),children:p("cancel")}),l.jsx("button",{className:"nc-btn primary",disabled:v||!C.id||!C.cwd||!C.engine,onClick:g,children:p("save")})]})]})}function IS({token:t,route:e=[],state:n,setState:s,busy:i,onSave:a}){const[c,u]=w.useState(null),[h,f]=w.useState([]),[v,g]=w.useState(""),_=Array.isArray(e)?e.join("/"):"";w.useEffect(()=>{let N=!0;return Fd(t,_?_.split("/"):[]).then(k=>{N&&(f(k.engines||[]),g(""))}).catch(k=>{N&&(f([]),g(String(k.message||k)))}),()=>{N=!1}},[t,_]);const b=n.form,S=N=>s({...n,form:{...b,...N}}),E=async N=>{try{const k=await zv(t,N,e);u(k),S({cwd:k.path})}catch{}},C=!b.id&&b.tmuxSession?b.tmuxSession.replace(/[^A-Za-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"").slice(0,32):b.id;return l.jsxs("div",{className:"nc-set-form nc-fleet-form",children:[l.jsxs("b",{children:[p("import-as-cell")," · ",b.tmuxSession]}),l.jsx("small",{children:p("import-help")}),l.jsx("input",{value:b.tmuxSession,disabled:!0,placeholder:"tmux session",readOnly:!0}),l.jsx("input",{value:b.id,placeholder:p("name"),onChange:N=>S({id:N.target.value})}),l.jsxs("div",{className:"nc-fleet-pair",children:[l.jsx("input",{value:b.cwd,placeholder:p("cwd"),onChange:N=>S({cwd:N.target.value})}),l.jsx("button",{className:"nc-btn ghost",type:"button",onClick:()=>c?u(null):E(b.cwd),children:p("browse")})]}),c&&l.jsxs("div",{className:"nc-fs",children:[l.jsx("div",{className:"nc-fs-path",children:c.path}),l.jsxs("div",{className:"nc-fs-list",children:[c.parent&&l.jsxs("button",{className:"nc-fs-item nc-fs-nav",onClick:()=>E(c.parent),children:["↑ ",p("fs-parent")]}),(c.dirs||[]).map(N=>l.jsxs("button",{className:"nc-fs-item",onClick:()=>E(`${c.path.replace(/\/$/,"")}/${N}`),children:["📁 ",N]},N))]})]}),l.jsxs("select",{value:b.engine,onChange:N=>S({engine:N.target.value}),children:[l.jsx("option",{value:"",children:p("import-engine-required")}),h.map(N=>l.jsx("option",{value:N.id,children:N.label},N.id))]}),l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox",checked:!!b.boot,onChange:N=>S({boot:N.target.checked})})," ",p("fleet-boot")]}),(n.err||v)&&l.jsx("div",{className:"nc-err",children:n.err||v}),l.jsxs("div",{className:"nc-sheet-actions",children:[l.jsx("button",{className:"nc-btn ghost",onClick:()=>s(null),children:p("cancel")}),l.jsx("button",{className:"nc-btn primary",disabled:i||!b.tmuxSession||!b.engine||!h.length,onClick:a,children:p(C?"import-as-cell":"save")})]})]})}function Zu(t){const e=Oo(t);return e===null?`~/${t}`:e?`~/${e}`:"~"}function vD(t){if(!t||typeof t.path!="string"||typeof t.home!="string")return"";const{path:e,home:n}=t;return!n||e===n||!e.startsWith(n+"/")?"":e.slice(n.length+1).replace(/\/+$/,"")}function gD({token:t,route:e,cell:n,busy:s=!1,onSaved:i,onClose:a}){const[c,u]=w.useState(""),[h,f]=w.useState(null),[v,g]=w.useState(!1),[_,b]=w.useState(""),S=typeof(n==null?void 0:n.cwdSuggestion)=="string"&&Oo(n.cwdSuggestion)!==null?Oo(n.cwdSuggestion):null,[E,C]=w.useState(S),N=n==null?void 0:n.id,k=s||v,I=async G=>{const Z=Oo(G);if(Z===null){f({rel:"",dirs:[],loading:!1,err:p("fleet-cwd-repair-invalid")});return}f({rel:Z,dirs:[],loading:!0,err:""});try{const q=await zv(t,Z,e),T=vD(q);f({rel:T,dirs:Array.isArray(q.dirs)?q.dirs:[],loading:!1,err:""})}catch(q){f({rel:Z,dirs:[],loading:!1,err:String(q&&q.message||q)})}},L=G=>{if(!h)return;const Z=h.rel?`${h.rel}/${G}`:G;I(Z)},H=()=>{h!=null&&h.rel&&I(h.rel.split("/").slice(0,-1).join("/"))},z=()=>{h&&(u(h.rel||""),f(null),b(""),C(null))},V=()=>{E!==null&&(u(E),C(null),b(""))},Y=async()=>{if(k)return;const G=Oo(c);if(G===null){b(p("fleet-cwd-repair-invalid"));return}const Z=Zu(G);let q=!0;try{q=window.confirm(p("fleet-cwd-repair-confirm").replace("{id}",String(N||"")).replace("{path}",Z))}catch{q=!1}if(q){g(!0),b(""),C(null);try{const T=await p1(t,N,{cwdRel:G},e);i==null||i(T)}catch(T){const P=T&&T.data||{};if(P.code==="unportable-cwd"){b(p("fleet-cwd-repair-unportable"));const D=Array.isArray(P.cells)?P.cells.find(O=>O&&O.id===N):null,j=D&&typeof D.suggestion=="string"?D.suggestion:null;j!==null&&Oo(j)!==null&&C(j)}else b(String(T&&T.message||T))}finally{g(!1)}}};return l.jsxs("div",{className:"nc-set-form nc-fleet-form nc-cwd-repair",children:[l.jsx("b",{children:p("fleet-cwd-repair-title").replace("{id}",String(N||""))}),l.jsx("small",{className:"nc-set-info",children:p("fleet-cwd-repair-help")}),l.jsx("small",{className:"nc-cwd-no-source",children:p("fleet-cwd-repair-no-source-path")}),l.jsxs("label",{className:"nc-field",children:[p("cwd"),l.jsxs("div",{className:"nc-cwd-rel-row",children:[l.jsx("span",{className:"nc-cwd-rel-prefix",children:"~/"}),l.jsx("input",{value:c,placeholder:p("fleet-cwd-repair-placeholder"),autoComplete:"off",spellCheck:"false",autoCapitalize:"none",onChange:G=>u(G.target.value)}),l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:k,onClick:()=>h?f(null):I(""),children:p(h?"close":"fleet-cwd-repair-browse")})]})]}),l.jsx("div",{className:"nc-cwd-preview",children:p("fleet-cwd-repair-preview").replace("{path}",Zu(c))}),h&&l.jsxs("div",{className:"nc-fs",children:[l.jsx("div",{className:"nc-fs-path",children:Zu(h.rel)}),l.jsxs("div",{className:"nc-fs-list",children:[h.rel&&l.jsxs("button",{type:"button",className:"nc-fs-item nc-fs-nav",onClick:H,children:["↑ ",p("fs-parent")]}),h.loading&&l.jsx("div",{className:"nc-fs-empty",children:"…"}),!h.loading&&h.dirs.length===0&&l.jsx("div",{className:"nc-fs-empty",children:p("fleet-cwd-repair-fs-empty")}),!h.loading&&h.dirs.map(G=>l.jsxs("button",{type:"button",className:"nc-fs-item",onClick:()=>L(G),children:["📁 ",G]},G))]}),h.err&&l.jsx("div",{className:"nc-err",children:h.err}),l.jsx("div",{className:"nc-sheet-actions",children:l.jsx("button",{type:"button",className:"nc-btn primary",disabled:k||h.loading||!!h.err,onClick:z,children:p("fleet-cwd-repair-use-current")})})]}),_&&l.jsx("div",{className:"nc-err",role:"alert",children:_}),E!==null&&l.jsxs("div",{className:"nc-cwd-suggestion",role:"status",children:[l.jsx("span",{children:p("fleet-cwd-repair-suggestion")}),l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:V,children:p("fleet-cwd-repair-use-suggestion").replace("{path}",Zu(E))})]}),l.jsxs("div",{className:"nc-sheet-actions",children:[l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:v,onClick:a,children:p("cancel")}),l.jsx("button",{type:"button",className:"nc-btn primary",disabled:k,onClick:Y,children:v?"…":p("save")})]})]})}function _D({token:t,readonly:e,targets:n=[],startNewCell:s=!1,initialLocation:i=""}){const[a,c]=w.useState({engines:[],cells:[],managedCatalog:[]}),[u,h]=w.useState({available:!1,capabilities:[]}),[f,v]=w.useState(!1),[g,_]=w.useState(null),[b,S]=w.useState(null),[E,C]=w.useState({}),[N,k]=w.useState(null),[I,L]=w.useState(!1),[H,z]=w.useState(""),[V,Y]=w.useState(""),[G,Z]=w.useState(i),[q,T]=w.useState(!1),[P,D]=w.useState(null),[j,O]=w.useState(null),[A,M]=w.useState(null),[R,F]=w.useState(!1),[$,K]=w.useState([]),[oe,ce]=w.useState(null),[ne,Le]=w.useState("manage"),Ee=w.useRef(!1),pe=G?G.split("/"):[],Re=w.useCallback(async()=>{try{const U=await Cr(t,pe);h(U);try{const Q=await Hv(t,pe);T(!!Q.readonlyDefault)}catch{T(!1)}if(U.provider==="builtin"&&(U.capabilities||[]).includes("definitions")){const Q=await Fd(t,pe),X=new Map((U.engines||[]).map(_e=>[_e.id,_e]));if(Q.engines=(Q.engines||[]).map(_e=>{var me;return{..._e,availableModels:((me=X.get(_e.id))==null?void 0:me.models)||[]}}),c(Q),(U.capabilities||[]).includes("credentials"))try{K((await e5(t,pe)).credentials||[])}catch{K([])}else K([])}z("")}catch(U){z(String(U.message||U))}finally{v(!0)}},[t,G]);w.useEffect(()=>{Re();const U=setInterval(Re,5e3);return()=>clearInterval(U)},[Re]);const de=new Set((u.cells||[]).filter(U=>U.active).map(U=>U.cell)),fe=u.provider==="builtin"&&(u.capabilities||[]).includes("edit"),ke=(u.capabilities||[]).includes("restore");w.useEffect(()=>{!s||Ee.current||!fe||!a.engines.length||(Ee.current=!0,k({mode:"new",form:TS(a.engines[0].id)}))},[s,fe,a.engines]);const we=async U=>{L(!0),z(""),Y("");try{await U(),await Re()}catch(Q){z(String(Q.message||Q))}L(!1)},ge=async(U,Q)=>{const X=await a5(t,U,Q,pe);return C(_e=>({..._e,[`${U}::${Q}`]:X})),X},Ie=U=>we(async()=>{const Q={id:String(U.id||"").trim(),engine:String(U.engine||"").trim()};for(const X of["contextWindow","maxTokens"]){const _e=String(U[X]||"").trim();_e&&(Q[X]=Number(_e))}U.reasoning===!0&&(Q.reasoning=!0),await r5(t,Q,pe),S(null),await Re()}),Ae=()=>we(async()=>{var Pt;const U=g.mode==="new",Q=g.form,X=a.managedCatalog||[],_e=Q.kind==="managed"?Ec(X,Q):null,me=typeof(_e==null?void 0:_e.credentialEnv)=="string"?_e.credentialEnv:"",tt=me&&Q.credentialValue||"",ie=dD(Q,U,X);!U&&g.form.kind==="custom"&&!g.form.modelFlag&&(ie.model=null),!U&&g.form.kind==="custom"&&g.form.promptMode!=="flag"&&(ie.promptFlag=null);let Pe;if(U)Pe=await n5(t,ie,pe);else{const pt=g.original,mt=new Set(g.form.envRows.filter(Bt=>!Bt.remove).map(Bt=>Bt.key)),qt=(pt.envKeys||[]).filter(Bt=>!mt.has(Bt)),Kt=Object.fromEntries(g.form.envRows.filter(Bt=>!Bt.remove&&Bt.key&&(!Bt.configured||Bt.value!=="")).map(Bt=>[Bt.key,Bt.value]));Pe=await s5(t,pt.id,ie,g.form.kind==="custom"?{set:Kt,remove:qt}:void 0,pe)}let ut=null;if(me&&tt)try{ut=await ww(t,me,tt,pe),K(ut.credentials||[])}catch{throw await Re(),U&&_({mode:"edit",original:{...ie,id:Q.id},form:{...Q,credentialReveal:!1}}),new Error(p(U?"fleet-key-partial-create":"fleet-key-partial-edit"))}await Re(),_(null),Y(p("fleet-saved"));const yt=((Pt=((ut==null?void 0:ut.credentials)||[]).find(pt=>pt.envKey===me))==null?void 0:Pt.activeCells)||[],St=[...new Set([...(Pe==null?void 0:Pe.activeCells)||[],...yt])];if(St.length&&window.confirm(p("fleet-restart-confirm").replace("{cells}",St.join(", "))))for(const pt of St)await Ql(t,pt,pe)}),Te=()=>we(async()=>{var yt,St,Pt,pt,mt,qt;const U=N.mode==="new",Q=N.form,X={...U?{id:Q.id}:{},cwd:Q.cwd,engine:Q.engine,boot:!!Q.boot},_e={...Q.commands||{}},me=a.engines.find(Kt=>Kt.id===Q.engine);((yt=me==null?void 0:me.managed)==null?void 0:yt.client)==="shell"&&typeof Q.command=="string"&&Q.command.length?_e[Q.engine]=Q.command:((St=me==null?void 0:me.managed)==null?void 0:St.client)==="shell"&&delete _e[Q.engine],(Object.keys(_e).length||!U)&&(X.commands=_e);const tt=(Q.label||"").trim();U?tt&&(X.label=tt):X.label=tt||null;const ie=(Q.panelUrl||"").trim();U?ie&&(X.panelUrl=ie):X.panelUrl=ie||null,U?Array.isArray(Q.mcp)&&(X.mcp=Q.mcp):X.mcp=Array.isArray(Q.mcp)?Q.mcp:null,U?(((Pt=me==null?void 0:me.managed)==null?void 0:Pt.client)!=="shell"&&Q.model&&(X.model=Q.model),((pt=me==null?void 0:me.managed)==null?void 0:pt.client)!=="shell"&&Q.prompt&&(X.prompt=Q.prompt)):(X.model=((mt=me==null?void 0:me.managed)==null?void 0:mt.client)==="shell"?null:Q.model||null,((qt=me==null?void 0:me.managed)==null?void 0:qt.client)!=="shell"&&(X.prompt=Q.prompt||null));const Pe=U?await l5(t,X,pe):await p1(t,N.original.id,X,pe),ut=U?Q.id:N.original.id;k(null),Y(p("fleet-saved")),!U&&(Pe!=null&&Pe.active)&&window.confirm(p("fleet-restart-confirm").replace("{cells}",ut))&&await Ql(t,ut,pe)}),J=e||q,Se=u.capabilities||[],De=pe.length>0&&J,Me=U=>$.find(Q=>{var X;return(X=Q.engines)==null?void 0:X.includes(U.id)})||null,Ve=()=>we(async()=>{var X;const U=await ww(t,oe.envKey,oe.value,pe);K(U.credentials||[]),ce(null),Y(p("fleet-credential-saved"));const Q=((X=(U.credentials||[]).find(_e=>_e.envKey===oe.envKey))==null?void 0:X.activeCells)||[];if(Q.length&&window.confirm(p("fleet-restart-confirm").replace("{cells}",Q.join(", "))))for(const _e of Q)await Ql(t,_e,pe)}),Qe=U=>we(async()=>{if(!window.confirm(p("fleet-credential-remove-confirm").replace("{key}",U.envKey)))return;const Q=await t5(t,U.envKey,pe);K(Q.credentials||[]),Y(p("fleet-credential-removed"))}),dt=U=>D({...U,route:Array.isArray(U==null?void 0:U.route)?U.route:pe}),at=async U=>{if(!P)return;const Q={...P,cell:P.cell||P.id};try{await wg({token:t,powerCell:Q,payload:U,onNotice:Y})}catch(X){throw z(String(X&&X.message||X)),X}},bt=(U,Q)=>{z(""),O({mode:"new",route:Array.isArray(Q)?Q:pe,form:{tmuxSession:U.name,id:"",engine:"",cwd:"",boot:!1},err:""})},st=()=>we(async()=>{const U=j.form;if(!U.engine){O({...j,err:p("import-engine-required")});return}await c5(t,{tmuxSession:U.tmuxSession,id:U.id||void 0,engine:U.engine,cwd:U.cwd||void 0,boot:!!U.boot},U.route||pe),O(null),Y(p("fleet-saved"))}),ft=({engineRows:U=[],cellRows:Q=[],models:X=[]})=>we(async()=>{const _e=U.filter(pt=>pt.selected),me=_e.map(pt=>Pk(pt.engine));if(me.some(pt=>!pt))throw new Error(p("fleet-backup-invalid-engine"));const tt=_e.filter(pt=>pt.exists).map(pt=>pt.engine.id);if(tt.length&&!window.confirm(p("fleet-backup-confirm-engine-overwrite").replace("{engines}",tt.join(", "))))return;const ie=[...new Set([...a.engines.map(pt=>pt.id),...me.map(pt=>pt.id)])],Pe=[];for(const pt of Q.filter(mt=>mt.selected)){const mt=aD(pt.cell,pt.engine,ie);if(!mt)throw new Error(`${pt.cell.id}: ${p("fleet-backup-engine-missing")}`);Pe.push(mt)}const ut=Q.filter(pt=>pt.selected&&pt.exists).map(pt=>pt.cell.id);if(ut.length&&!window.confirm(p("fleet-backup-confirm-overwrite").replace("{cells}",ut.join(", "))))return;const yt=me.length?await d5(t,me,tt.length>0,pe,X):{needsRestart:[]},St=Pe.length?await u5(t,Pe,pe):{needsRestart:[]},Pt=[...new Set([...yt.needsRestart||[],...St.needsRestart||[]])];F(!1),Y(`${p("fleet-backup-restored").replace("{n}",String(Pe.length))}${me.length?` · ${me.length} ${p("fleet-engines").toLowerCase()}`:""}${Pt.length?` · ${p("fleet-backup-needs-restart").replace("{cells}",Pt.join(", "))}`:""}`)}),ot=l.jsxs("label",{className:"nc-field",children:[p("location"),l.jsxs("select",{value:G,onChange:U=>{Z(U.target.value),_(null),k(null),z(""),Y(""),T(!1),v(!1),h({available:!1,capabilities:[]}),c({engines:[],cells:[],managedCatalog:[]}),K([]),ce(null)},children:[l.jsx("option",{value:"",children:p("local")}),n.map(U=>l.jsxs("option",{value:U.route.join("/"),disabled:U.status&&U.status!=="up",children:[U.label,U.status&&U.status!=="up"?` · ${p("node-offline")}`:""]},U.route.join("/")))]})]}),Rt=l.jsxs("div",{className:"nc-fleet-view-tabs",role:"tablist","aria-label":p("tab-fleet"),children:[l.jsx("button",{type:"button",role:"tab","aria-selected":ne==="manage",className:`nc-set-tabbtn${ne==="manage"?" on":""}`,onClick:()=>Le("manage"),children:p("fleet-manage-location")}),l.jsx("button",{type:"button",role:"tab","aria-selected":ne==="overview",className:`nc-set-tabbtn${ne==="overview"?" on":""}`,onClick:()=>Le("overview"),children:p("fleet-network-overview")})]});return f?fe?l.jsxs("div",{className:"nc-set-tab nc-fleet-editor",children:[Rt,ne==="overview"?l.jsxs(l.Fragment,{children:[l.jsx("div",{className:"nc-set-info",children:p("fleet-overview-help")}),l.jsx(Vp,{token:t,targets:n,readonly:e,onPower:dt,onImport:bt})]}):l.jsxs(l.Fragment,{children:[l.jsx("div",{className:"nc-set-info",children:p("fleet-manage-help")}),ot,l.jsxs("div",{className:"nc-set-row nc-fleet-backup-actions",children:[l.jsx("button",{className:"nc-btn ghost",disabled:J||I,onClick:()=>{z(""),F(!0)},children:p("fleet-backup")}),l.jsx("small",{children:p("fleet-backup-help")})]}),l.jsxs("div",{className:"nc-fleet-section-head",children:[l.jsx("b",{children:p("fleet-cells")}),l.jsx("span",{className:"nc-fleet-head-actions",children:l.jsxs("button",{className:"nc-btn primary",disabled:J||I||!a.engines.length,onClick:()=>{var U;z(""),k({mode:"new",form:TS((U=a.engines[0])==null?void 0:U.id)})},children:["+ ",p("add")]})})]}),a.cells.map(U=>{const Q=de.has(U.id),X=U.needsRepair===!0;return l.jsxs("div",{className:"nc-fleet-item",children:[l.jsxs("span",{children:[l.jsx("b",{children:U.id}),U.label?l.jsxs("small",{className:"nc-fleet-label",children:[" ",U.label]}):null,l.jsxs("small",{children:[U.engine," · ",X?l.jsx("span",{className:"nc-fleet-tag nc-fleet-tag-warn",children:p("fleet-cwd-needs-repair")}):U.cwd,Q?` · ${p("service-active")}`:` · ${p("cell-off")}`]})]}),l.jsxs("span",{children:[Q&&Se.includes("down")&&l.jsx("button",{className:"nc-btn ghost",disabled:J||I,onClick:()=>we(()=>h1(t,{cell:U.id},pe)),children:p("stop")}),!Q&&Se.includes("up")&&l.jsx("button",{className:"nc-btn primary",disabled:J||I,onClick:()=>dt({cell:U.id,id:U.id,engine:U.engine,model:U.model,models:U.models,permissionPolicies:U.permissionPolicies,active:!1,boot:U.boot}),children:p("start")}),Q&&Se.includes("restart")&&l.jsx("button",{className:"nc-btn ghost",disabled:J||I,onClick:()=>we(()=>Ql(t,U.id,pe)),children:p("restart")}),X?l.jsx("button",{className:"nc-btn ghost",disabled:J||I,onClick:()=>{z(""),M(U)},children:p("fleet-cwd-repair")}):l.jsx("button",{className:"nc-btn ghost",disabled:J||I,onClick:()=>{var _e;z(""),k({mode:"edit",original:U,form:{...U,commands:{...U.commands||{}},command:((_e=U.commands)==null?void 0:_e[U.engine])||""}})},children:p("edit")}),l.jsx("button",{className:"nc-btn danger",disabled:J||I,onClick:()=>we(async()=>{window.confirm(p("fleet-remove-cell").replace("{id}",U.id))&&await m1(t,U.id,!0,pe)}),children:"×"})]})]},U.id)}),l.jsxs("div",{className:"nc-fleet-section-head",children:[l.jsx("b",{children:p("fleet-engines")}),l.jsxs("button",{className:"nc-btn primary",disabled:J||I,onClick:()=>{z(""),_({mode:"new",form:lD()})},children:["+ ",p("add")]})]}),a.engines.map(U=>{var X,_e;const Q=Me(U);return l.jsxs("div",{className:"nc-fleet-item",children:[l.jsxs("span",{children:[l.jsx("b",{children:U.label}),l.jsx("small",{children:U.managed?`${U.id} · ${U.managed.client} / ${U.managed.provider} · ${(X=U.managedInfo)!=null&&X.configured?p("fleet-ready"):((_e=U.managedInfo)==null?void 0:_e.reason)||p("fleet-not-ready")}`:`${U.id} · ${U.command}`}),Q&&l.jsxs("small",{children:[Q.envKey," · ",p(`fleet-credential-source-${Q.source||"missing"}`)]})]}),l.jsxs("span",{children:[Q&&l.jsx("button",{className:"nc-btn ghost",disabled:J||I,onClick:()=>{z(""),ce({envKey:Q.envKey,value:""})},children:Q.configured?p("fleet-credential-change"):p("fleet-credential-set")}),(Q==null?void 0:Q.source)==="local"&&l.jsx("button",{className:"nc-btn danger",disabled:J||I,onClick:()=>Qe(Q),children:p("fleet-credential-forget")}),l.jsx("button",{className:"nc-btn ghost",disabled:J||I,onClick:()=>{z(""),_({mode:"edit",original:U,form:uD(U)})},children:p("edit")}),l.jsx("button",{className:"nc-btn danger",disabled:J||I,onClick:()=>we(async()=>{window.confirm(p("fleet-remove-engine").replace("{id}",U.id))&&await i5(t,U.id,pe)}),children:"×"})]})]},U.id)}),l.jsxs("div",{className:"nc-fleet-section-head",children:[l.jsx("b",{children:p("fleet-models")}),l.jsxs("button",{className:"nc-btn primary",disabled:J||I,onClick:()=>{z(""),S({mode:"new",form:{id:"",engine:""}})},children:["+ ",p("add")]})]}),!(a.models||[]).length&&l.jsx("small",{className:"nc-set-hint",children:p("fleet-no-models")}),(a.models||[]).map(U=>{const Q=`${U.engine}::${U.id}`,X=E[Q],_e=(a.engines||[]).some(me=>me.managed&&me.managed.model===U.id);return l.jsxs("div",{className:"nc-fleet-item",children:[l.jsxs("span",{children:[l.jsx("b",{children:U.id}),l.jsxs("small",{children:[U.engine,U.contextWindow?` · ${U.contextWindow}`:"",_e?` · ${p("model-in-use")}`:""]}),X&&l.jsxs("small",{className:`nc-model-test ${X.outcome}`,children:[p(`model-test-${X.outcome}`),X.outcome==="ok"&&Number.isInteger(X.latencyMs)?` · ${X.latencyMs}ms`:""]})]}),l.jsxs("span",{children:[Se.includes("model-test")&&l.jsx("button",{className:"nc-btn ghost",disabled:I||De,onClick:()=>we(()=>ge(U.engine,U.id)),children:p("model-test")}),l.jsx("button",{className:"nc-btn danger",disabled:J||I,onClick:()=>we(()=>o5(t,U.id,U.engine,pe)),children:"×"})]})]},Q)})]}),b&&l.jsx(Qr,{onClose:()=>S(null),label:p("fleet-models"),error:H,children:l.jsx(pD,{state:b,setState:S,busy:I,onSave:Ie,onTest:ge,profiles:a.managedCatalog||[],canTest:Se.includes("model-test")&&!De})}),g&&l.jsx(Qr,{onClose:()=>_(null),label:p("fleet-new-engine"),error:H,children:l.jsx(fD,{state:g,setState:_,busy:I,onSave:Ae,catalog:a.managedCatalog||[]})}),N&&l.jsx(Qr,{onClose:()=>k(null),label:p("fleet-new-cell"),error:H,children:l.jsx(mD,{token:t,route:pe,targets:n,location:G,setLocation:Z,state:N,setState:k,engines:a.engines,mcpServers:a.mcpServers||[],managedCatalog:a.managedCatalog||[],busy:I,onSave:Te})}),A&&l.jsx(Qr,{onClose:()=>M(null),label:p("fleet-cwd-repair-title").replace("{id}",A.id),error:"",children:l.jsx(gD,{token:t,route:pe,cell:A,busy:I,onSaved:async()=>{M(null),Y(p("fleet-cwd-repaired")),await Re()},onClose:()=>M(null)})}),V&&l.jsx("div",{className:"nc-set-note",children:V}),H&&l.jsx("div",{className:"nc-err",children:H}),R&&l.jsx(Qr,{onClose:()=>F(!1),label:p("fleet-backup"),error:H,children:l.jsx(hD,{cells:a.cells,engines:a.engines,models:a.models||[],busy:I,canRestore:ke,onRestore:ft,onClose:()=>F(!1)})}),oe&&l.jsx(Qr,{onClose:()=>ce(null),label:p("fleet-credential-title"),error:H,children:l.jsxs("div",{className:"nc-fleet-form nc-credential-form",children:[l.jsx("b",{children:p("fleet-credential-title")}),l.jsx("small",{children:p("fleet-credential-help")}),l.jsxs("label",{className:"nc-field",children:[oe.envKey,l.jsx("input",{type:"password",autoComplete:"off",spellCheck:"false",autoCapitalize:"none",value:oe.value,onChange:U=>ce({...oe,value:U.target.value})})]}),l.jsxs("div",{className:"nc-sheet-actions",children:[l.jsx("button",{className:"nc-btn ghost",onClick:()=>ce(null),children:p("cancel")}),l.jsx("button",{className:"nc-btn primary",disabled:I||!oe.value,onClick:Ve,children:p("save")})]})]})}),j&&l.jsx(Qr,{onClose:()=>O(null),label:p("import-as-cell"),error:H,children:l.jsx(IS,{token:t,route:j.route||pe,state:j,setState:O,busy:I,onSave:st})}),P&&l.jsx(Nd,{cell:P,token:t,route:Array.isArray(P.route)?P.route:pe,onConfirm:async U=>{try{await at(U)}finally{Re()}},onClose:()=>D(null)})]}):l.jsxs("div",{className:"nc-set-tab",children:[Rt,ne==="overview"?l.jsxs(l.Fragment,{children:[l.jsx("div",{className:"nc-set-info",children:p("fleet-overview-help")}),l.jsx(Vp,{token:t,targets:n,readonly:e,onPower:dt,onImport:bt})]}):l.jsxs(l.Fragment,{children:[ot,l.jsxs("div",{className:"nc-set-info",children:[p(H?"fleet-editor-load-error":"fleet-editor-unavailable"),!H&&u.reason?` ${u.reason}`:""]})]}),H&&l.jsx("div",{className:"nc-err",children:H}),j&&l.jsx(Qr,{onClose:()=>O(null),label:p("import-as-cell"),error:H,children:l.jsx(IS,{token:t,route:j.route||pe,state:j,setState:O,busy:I,onSave:st})}),P&&l.jsx(Nd,{cell:P,token:t,route:Array.isArray(P.route)?P.route:pe,onConfirm:async U=>{try{await at(U)}finally{Re()}},onClose:()=>D(null)})]}):l.jsxs("div",{className:"nc-set-tab",children:[Rt,ne==="overview"?l.jsxs(l.Fragment,{children:[l.jsx("div",{className:"nc-set-info",children:p("fleet-overview-help")}),l.jsx(Vp,{token:t,targets:n,readonly:e,onPower:dt,onImport:bt})]}):l.jsxs(l.Fragment,{children:[ot,l.jsx("div",{className:"nc-set-info",children:p("fleet-editor-loading")})]})]})}const $g="nc_notification_speech_v1",ed="nc-notification-speech",Cv="nc-notification-speech-preview",yD=320,wD=2,bD=3e4,SD=1e4,xD=6e4,CD=64,DS=Object.freeze({enabled:!1}),kD=Object.freeze({it:"it-IT",en:"en-US",es:"es-ES"}),ED=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"])}),zg=new WeakSet;function Fg(t){return{enabled:(t&&typeof t=="object"&&!Array.isArray(t)?t:{}).enabled===!0}}function Dk(){try{return typeof localStorage<"u"?localStorage:null}catch{return null}}function OS(t=Dk()){if(!t)return{...DS};try{return Fg(JSON.parse(t.getItem($g)||"null"))}catch{return{...DS}}}function ND(t,e=Dk()){const n=Fg(t);if(e)try{e.setItem($g,JSON.stringify(n))}catch{}return n}function tl(){try{return typeof window<"u"?window:null}catch{return null}}function Nc(t=tl()){try{return!!(t&&t.speechSynthesis&&typeof t.speechSynthesis.speak=="function"&&typeof t.SpeechSynthesisUtterance=="function")}catch{return!1}}function Ok(t=tl()){return!!(t&&(typeof t=="object"||typeof t=="function")&&zg.has(t))}function kv(t=tl()){t&&(typeof t=="object"||typeof t=="function")&&zg.delete(t)}function Fa(t){const e=String(t||"").trim().toLowerCase().split("-")[0];return kD[e]||""}function ah(t){return String(t||"").normalize("NFC").replace(/[\p{Cc}\p{Cf}]+/gu," ").replace(/\s+/g," ").trim()}function LD(t){const e=ah(t).normalize("NFD").replace(new RegExp("\\p{M}+","gu"),"").toLowerCase(),n=new Set(e.match(new RegExp("\\p{L}+","gu"))||[]);if(n.size<4)return"";const s=Object.entries(ED).map(([i,a])=>({lang:i,score:[...n].reduce((c,u)=>c+(a.has(u)?1:0),0)})).sort((i,a)=>a.score-i.score);return s[0].score>=3&&s[0].score-s[1].score>=2?s[0].lang:""}function RD(t,e){const n=Fa(t&&t.lang);return n||Fa(LD(t&&t.body))||Fa(e)}function Bk(t){try{const e=t&&t.speechSynthesis&&t.speechSynthesis.getVoices;return typeof e=="function"?Array.from(e.call(t.speechSynthesis)||[]).filter(Boolean):[]}catch{return[]}}function $k(t,e){const n=Fa(e);if(!n)return null;const s=Array.from(t||[]).filter(u=>u&&typeof u.lang=="string"&&u.lang.trim()),i=s.filter(u=>u.lang.trim().toLowerCase()===n.toLowerCase()),a=n.slice(0,2).toLowerCase(),c=s.filter(u=>u.lang.trim().toLowerCase().split("-")[0]===a);return i.find(u=>u.default===!0)||i[0]||c.find(u=>u.default===!0)||c[0]||null}function BS(t){return ah(t).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 AD(t,e=yD){const n=BS(t&&t.title),s=BS(t&&t.body),i=[n,s&&s!==n?s:""].filter(Boolean).join(". "),a=Array.from(i);return a.length<=e?i:`${a.slice(0,Math.max(0,e-1)).join("").trimEnd()}…`}function jD(t){try{return!!(t&&t.visibilityState==="visible"&&typeof t.hasFocus=="function"&&t.hasFocus())}catch{return!1}}function zk(t=tl()){if(!Nc(t))return!1;try{return t.speechSynthesis.cancel(),!0}catch{return!1}}function MD(t){try{t&&typeof t.dispatchEvent=="function"&&typeof t.Event=="function"&&t.dispatchEvent(new t.Event(Cv))}catch{}}function TD(t,e,n=tl(),s={}){var f;if(kv(n),!Nc(n))return Promise.resolve(!1);const i=ah(t);if(!i||(f=s.signal)!=null&&f.aborted)return Promise.resolve(!1);const a=Number.isFinite(s.timeoutMs)&&s.timeoutMs>0?s.timeoutMs:SD,c=s.setTimer||((v,g)=>setTimeout(v,g)),u=s.clearTimer||(v=>clearTimeout(v)),h=s.signal;return MD(n),new Promise(v=>{let g=!1,_=!1,b=null,S=null;const E=C=>{if(!g){if(g=!0,h&&S&&h.removeEventListener("abort",S),b!==null&&u(b),C!==!0)try{n.speechSynthesis.cancel()}catch{}else zg.add(n);v(C)}};S=()=>E("no-activation"),h&&h.addEventListener("abort",S,{once:!0});try{n.speechSynthesis.cancel();const C=new n.SpeechSynthesisUtterance(i);C.lang=Fa(e);const N=$k(Bk(n),C.lang);N&&(C.voice=N),C.onstart=()=>{_=!0},C.onend=()=>E(_?!0:"no-activation"),C.onerror=()=>E("voice-error"),b=c(()=>E("timeout"),a),n.speechSynthesis.speak(C)}catch{E("no-activation")}})}function PD(t={}){const e=t.scope||tl(),n=t.document||e&&e.document,s=Number.isInteger(t.maxPending)&&t.maxPending>=0?t.maxPending:wD,i=Number.isFinite(t.watchdogMs)&&t.watchdogMs>0?t.watchdogMs:bD,a=Number.isFinite(t.dedupWindowMs)&&t.dedupWindowMs>0?t.dedupWindowMs:xD,c=Number.isInteger(t.maxDedup)&&t.maxDedup>0?t.maxDedup:CD,u=t.now||Date.now,h=t.setTimer||((q,T)=>setTimeout(q,T)),f=t.clearTimer||(q=>clearTimeout(q)),v=t.isPrimed||(()=>Ok(e)),g=e&&e.speechSynthesis;let _=null,b=null,S=[],E=[],C=()=>{};const N=new Map,k=()=>{E=Bk(e)};if(k(),g&&typeof g.addEventListener=="function")g.addEventListener("voiceschanged",k),C=()=>g.removeEventListener("voiceschanged",k);else if(g&&"onvoiceschanged"in g){const q=g.onvoiceschanged,T=(...P)=>{k(),typeof q=="function"&&q.apply(g,P)};g.onvoiceschanged=T,C=()=>{g.onvoiceschanged===T&&(g.onvoiceschanged=q)}}const I=q=>{if(q&&typeof q.id=="string"&&q.id)return`id:${q.id}`;const T=Number(q&&q.ts),P=ah(q&&q.title);return Number.isFinite(T)&&P?`frame:${T}:${P}`:""},L=q=>{if(!q)return!0;const T=u();for(const[P,D]of N)T-D>=a&&N.delete(P);if(N.has(q))return!1;for(N.set(q,T);N.size>c;)N.delete(N.keys().next().value);return!0},H=()=>{b!==null&&f(b),b=null},z=()=>{H(),_&&(_.onend=null,_.onerror=null,_=null),zk(e)},V=q=>{if(!Nc(e))return S=[],"unsupported";let T;try{T=new e.SpeechSynthesisUtterance(q.text),T.lang=Fa(q.lang);const D=$k(E,T.lang);D&&(T.voice=D)}catch{return S=[],"error"}_=T;const P=()=>{if(_!==T)return;H(),_=null,T.onend=null,T.onerror=null;const D=S.shift();D&&V(D)};T.onend=P,T.onerror=P;try{return b=h(()=>{if(_!==T)return;_=null,T.onend=null,T.onerror=null;try{e.speechSynthesis.cancel()}catch{}H();const D=S.shift();D&&V(D)},i),e.speechSynthesis.speak(T),"speaking"}catch{return P(),"error"}},Y=(q,T)=>{if(!Nc(e))return"unsupported";const P=AD(q);if(!P)return"empty";if(!L(I(q)))return"duplicate";if(!jD(n))return"inactive";if(!v())return"unprimed";const D={text:P,lang:T};return q&&q.urgency==="high"?(S=[],z(),V(D)):_?s===0?"dropped":(S.length>=s&&S.shift(),S.push(D),"queued"):V(D)},G=()=>{S=[],z()};return{enqueue:Y,stop:G,dispose:()=>{G(),C(),C=()=>{}}}}function Fk(){const[t,e]=w.useState(OS);w.useEffect(()=>{const s=i=>{if((i==null?void 0:i.type)==="storage"&&i.key!==$g&&i.key!==null)return;const a=(i==null?void 0:i.type)===ed?Fg(i.detail):OS();e(a)};return window.addEventListener(ed,s),window.addEventListener("storage",s),()=>{window.removeEventListener(ed,s),window.removeEventListener("storage",s)}},[]);const n=w.useCallback(s=>{const i=ND({enabled:s===!0});return e(i),window.dispatchEvent(new CustomEvent(ed,{detail:i})),i.enabled},[]);return[t.enabled,n]}const Hg="nc_storage_persist_v1",ID=1440*60*1e3;function Ev(t=globalThis.localStorage){return Lr(Hg,{storage:t,fallback:()=>null,parse:e=>e&&typeof e=="object"&&!Array.isArray(e)?e:void 0})}async function DD({manager:t=(s=>(s=globalThis.navigator)==null?void 0:s.storage)(),ls:e=globalThis.localStorage,now:n=Date.now}={}){const i=Ev(e),a=n();let c;try{if(!t||typeof t.persist!="function")c={at:a,status:"unsupported"};else if(typeof t.persisted=="function"&&await t.persisted())c={at:a,status:"persistent"};else{if(i&&i.status==="denied"&&a-i.at<ID)return i;c={at:a,status:await t.persist()?"persistent":"denied"}}}catch(u){c={at:a,status:"error",note:String((u==null?void 0:u.message)||u).slice(0,120)}}return(!i||i.status!==c.status)&&Ji({reason:"storage-persist",note:c.status}),_i(Hg,c,{storage:e}),c}const OD=t=>{try{return new Date(t).toLocaleString()}catch{return String(t)}},Yp=t=>Array.isArray(t)?t.join(", "):"";function BD(){qn();const[t,e]=w.useState(()=>nv()),[n,s]=w.useState(()=>Ev()),[i,a]=w.useState(!1);w.useEffect(()=>{const f=()=>{e(nv()),s(Ev())};return window.addEventListener("storage",f),window.addEventListener("nexuscrew-roster-preferences",f),()=>{window.removeEventListener("storage",f),window.removeEventListener("nexuscrew-roster-preferences",f)}},[]);const c=async()=>{try{await navigator.clipboard.writeText(JSON.stringify(t,null,2)),a(!0),setTimeout(()=>a(!1),1500)}catch{}},u=()=>{cT(),e([])},h=[...t].reverse();return l.jsxs("div",{className:"nc-set-form nc-prefs-journal",children:[l.jsx("div",{className:"nc-sheet-label",children:p("prefs-journal")}),l.jsxs("div",{"data-testid":"persist-status",className:"nc-set-hint","data-key":Hg,children:[p("prefs-persist"),": ",n?n.status:p("prefs-persist-unknown")]}),!h.length&&l.jsx("div",{className:"nc-set-hint",children:p("prefs-journal-empty")}),l.jsx("div",{className:"nc-journal-list",style:{maxHeight:220,overflow:"auto"},children:h.map((f,v)=>l.jsxs("div",{"data-testid":"journal-row",className:"nc-set-hint",style:{overflowWrap:"anywhere"},children:[l.jsx("b",{children:f.reason})," · ",OD(f.t),f.position?` · ${f.position}`:"",f.key?` · ${f.key}`:"",f.note?` · ${f.note}`:"",f.before?l.jsxs("div",{children:[p("prefs-before"),": ",Yp(f.before)]}):null,f.after?l.jsxs("div",{children:[p("prefs-after"),": ",Yp(f.after)]}):null,f.visible?l.jsxs("div",{children:[p("prefs-visible"),": ",Yp(f.visible)]}):null]},`${f.t}-${v}`))}),l.jsxs("div",{className:"nc-sheet-actions",children:[l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:c,disabled:!t.length,children:p(i?"copied":"prefs-journal-copy")}),l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:u,disabled:!t.length,children:p("prefs-journal-clear")})]})]})}const Ug="nc_device_id_v1",Hk="nc_prefs_sync_v1",$D="nexuscrew-roster-preferences",Wg=/^[a-f0-9]{32}$/,zD=192,FD=256,$S=128,Uk="nexuscrew-preferences",Fo=t=>t&&typeof t=="object"&&!Array.isArray(t),md=(t,e)=>typeof t=="string"&&t.length>0&&t.length<=e&&!/[\u0000-\u001f\u007f]/.test(t),Gp=(t,e=FD)=>Array.isArray(t)&&t.length<=e&&t.every(n=>md(n,zD));function nl(t){if(!Fo(t)||Object.keys(t).some(n=>!["pins","orders","views","nodeOrder"].includes(n)))return null;const e={pins:[],orders:{},views:{},nodeOrder:[]};if(t.pins!==void 0){if(!Gp(t.pins))return null;e.pins=[...new Set(t.pins)]}if(t.nodeOrder!==void 0){if(!Gp(t.nodeOrder,128))return null;e.nodeOrder=[...new Set(t.nodeOrder)]}if(t.orders!==void 0){if(!Fo(t.orders)||Object.keys(t.orders).length>$S)return null;for(const[n,s]of Object.entries(t.orders)){if(!md(n,96)||!Gp(s))return null;e.orders[n]=[...new Set(s)]}}if(t.views!==void 0){if(!Fo(t.views)||Object.keys(t.views).length>$S)return null;for(const[n,s]of Object.entries(t.views)){if(!md(n,96)||!Fo(s))return null;const i={};if(s.open!==void 0){if(typeof s.open!="boolean")return null;i.open=s.open}if(s.filter!==void 0){if(!md(s.filter,16))return null;i.filter=s.filter}e.views[n]=i}}return e}const Nv=t=>!t||!(t.pins||[]).length&&!(t.nodeOrder||[]).length&&!Object.keys(t.orders||{}).length&&!Object.keys(t.views||{}).length;function qg(t){const e={pins:to(),orders:oc(t),views:fd(t),nodeOrder:av(t)};return nl(e)||{pins:[],orders:{},views:{},nodeOrder:[]}}const Lv=t=>Array.isArray(t)?`[${t.map(Lv).join(",")}]`:Fo(t)?`{${Object.keys(t).sort().map(e=>`${JSON.stringify(e)}:${Lv(t[e])}`).join(",")}}`:JSON.stringify(t),vd=t=>{const e=Lv(nl(t)||{});let n=2166136261;for(let s=0;s<e.length;s+=1)n^=e.charCodeAt(s),n=Math.imul(n,16777619);return(n>>>0).toString(16)},Xp=["nc_pins",Xo,Go,Zd];function Kg(t,{storage:e,note:n="restore"}={}){const s=nl(t);if(!s)return new Error("preferenze non valide");let i=e;try{i=i||globalThis.localStorage}catch(u){return u}const a={};for(const u of Xp)try{a[u]=i.getItem(u)}catch{a[u]=null}const c={nc_pins:s.pins,[Xo]:s.orders,[Go]:s.views,[Zd]:s.nodeOrder};for(const u of Xp){const h=_i(u,c[u],{storage:e});if(h){for(const f of Xp)try{a[f]===null||a[f]===void 0?i.removeItem(f):i.setItem(f,a[f])}catch{}return Ji({reason:"prefs-restore-failed",key:u,note:String(h&&h.message||h).slice(0,120)}),h}}Ji({reason:"prefs-restore",note:n,after:s.pins});try{window.dispatchEvent(new Event($D))}catch{}return null}const Wk=t=>({status:"error",code:"storage-write-failed",note:String(t&&t.message||t).slice(0,120)}),Vg=t=>{try{return t||globalThis.localStorage}catch{return null}},lh=t=>{var e;try{const n=(e=Vg(t))==null?void 0:e.getItem(Ug);return Wg.test(n||"")?n:""}catch{return""}},qk=(t,e)=>{var n;try{(n=Vg(e))==null||n.setItem(Ug,t)}catch{}};function HD(t,e){Wg.test(t||"")&&!lh(e)&&qk(t,e)}const UD=lh,WD=t=>Lr(Hk,{storage:t,fallback:()=>null,parse:e=>Fo(e)?e:void 0}),Pd=(t,e,n)=>_i(Hk,{revision:t,hash:vd(e),at:Date.now()},{storage:n});function Kk(t){return async(e,n,{headers:s={},body:i}={})=>bn(n,t,{method:e,headers:{...i?{"content-type":"application/json"}:{},...s},body:i,timeoutMs:8e3})}async function zS(t,e){let n=lh(e);if(!n){const s=await t("POST","/api/prefs/devices");if(s.status!==201)throw Object.assign(new Error(`device ${s.status}`),{status:s.status});if(n=(await s.json()).deviceId,!Wg.test(n||""))throw new Error("device non valido");qk(n,e)}return n}async function Rv(t,e,n,s,i){const a=await t("PUT","/api/prefs",{headers:{"x-nc-device":e,"if-match":`"${s}"`},body:JSON.stringify({data:n})});if(a.status===200){const u=await a.json();return Pd(u.revision,n,i),{status:"uploaded",revision:u.revision}}const c=await a.json().catch(()=>({}));return a.status===409&&c.current?{status:"conflict",revision:c.current.revision,conflict:{local:n,server:nl(c.current.data)||null,revision:c.current.revision,deviceId:e}}:{status:"error",code:c.code||`http-${a.status}`}}async function qD({request:t,token:e,storage:n}={}){var i;const s=t||Kk(e);try{let a=await zS(s,n),c=await s("GET","/api/prefs",{headers:{"x-nc-device":a}});if(c.status===404){try{(i=Vg(n))==null||i.removeItem(Ug)}catch{}a=await zS(s,n),c=await s("GET","/api/prefs",{headers:{"x-nc-device":a}})}if(c.status!==200)return{status:"error",code:`http-${c.status}`};const u=await c.json(),h=qg(n),f=nl(u.data);if(!f)return Nv(h)?{status:"synced",revision:u.revision}:Rv(s,a,h,u.revision,n);if(Nv(h)){const g=Kg(f,{storage:n});return g?Wk(g):(Pd(u.revision,f,n),{status:"restored",revision:u.revision})}if(vd(h)===vd(f))return Pd(u.revision,h,n),{status:"synced",revision:u.revision};const v=WD(n);return v&&v.revision===u.revision&&v.hash!==vd(h)?Rv(s,a,h,u.revision,n):{status:"conflict",revision:u.revision,conflict:{local:h,server:f,revision:u.revision,deviceId:a}}}catch(a){return{status:"offline",note:String((a==null?void 0:a.message)||a).slice(0,120)}}}async function KD(t,e,{request:n,token:s,storage:i}={}){if(!e)return{status:"error",code:"no-conflict"};const a=n||Kk(s);try{if(t==="server"){if(!e.server)return{status:"error",code:"no-server-copy"};const c=Kg(e.server,{storage:i,note:"restore-from-server"});return c?Wk(c):(Pd(e.revision,e.server,i),{status:"restored",revision:e.revision})}return await Rv(a,e.deviceId||lh(i),e.local,e.revision,i)}catch(c){return{status:"offline",note:String((c==null?void 0:c.message)||c).slice(0,120)}}}function VD(t){return JSON.stringify({kind:Uk,version:1,exportedAt:new Date().toISOString(),data:qg(t)},null,2)}function YD(t,{storage:e}={}){let n;try{n=JSON.parse(t)}catch{return{ok:!1,reason:"not-json"}}if(!Fo(n)||n.kind!==Uk||n.version!==1)return{ok:!1,reason:"wrong-kind"};const s=nl(n.data);if(!s)return{ok:!1,reason:"bad-schema"};const i=Kg(s,{storage:e,note:"import"});return i?{ok:!1,reason:"storage-write-failed",note:String(i&&i.message||i).slice(0,120)}:{ok:!0,data:s}}const Id={status:"idle"};let xr=Id;const Av=new Set,Dd=t=>{xr=t,Av.forEach(e=>e(t))};let jv=null,Lc=0;const GD=t=>{const e=t||null;jv!==e&&(jv=e,Lc+=1,xr!==Id&&Dd(Id))},Vk=()=>{const[t,e]=w.useState(xr);return w.useEffect(()=>(Av.add(e),e(xr),()=>{Av.delete(e)}),[]),t};async function Yk(t,e){var i;if(xr.status!=="conflict")return;const n=Lc;if(jv!==(t||null)||((i=xr.conflict)==null?void 0:i.deviceId)!==UD()){Dd(Id);try{window.dispatchEvent(new Event("nexuscrew-roster-preferences"))}catch{}return}const s=await KD(e,xr.conflict,{token:t});n===Lc&&Dd({...s,at:Date.now()})}const XD=1500,JD=3e3,FS="nexuscrew-roster-preferences";function QD(t){w.useEffect(()=>{if(GD(t),!t)return;let n=null,s=!0;const i=async()=>{if(!s||xr.status==="conflict")return;const u=Lc,h=await qD({token:t});s&&u===Lc&&Dd({...h,at:Date.now()})},a=u=>{clearTimeout(n),n=setTimeout(i,u)},c=()=>{xr.status!=="conflict"&&a(JD)};return a(XD),window.addEventListener(FS,c),window.addEventListener("storage",c),()=>{s=!1,clearTimeout(n),window.removeEventListener(FS,c),window.removeEventListener("storage",c)}},[t]);const e=w.useCallback(n=>Yk(t,n),[t]);return{state:Vk(),resolve:e}}const ZD=t=>typeof t.text=="function"?t.text():new Promise((e,n)=>{const s=new FileReader;s.onload=()=>e(String(s.result||"")),s.onerror=()=>n(s.error),s.readAsText(t)});function e6({token:t=""}){qn();const e=Vk(),n=w.useRef(null),s=h=>Yk(t,h),[i,a]=w.useState(null),c=()=>{try{const h=URL.createObjectURL(new Blob([VD()],{type:"application/json"})),f=document.createElement("a");f.href=h,f.download="nexuscrew-preferences.json",document.body.appendChild(f),f.click(),f.remove(),setTimeout(()=>URL.revokeObjectURL(h),1e3),a({ok:!0,text:p("prefs-export-done")})}catch(h){a({ok:!1,text:String((h==null?void 0:h.message)||h)})}},u=async h=>{const f=h.target.files&&h.target.files[0];if(h.target.value="",!f)return;let v="";try{v=await ZD(f)}catch(_){a({ok:!1,text:String((_==null?void 0:_.message)||_)});return}if(!Nv(qg())&&!window.confirm(p("prefs-import-confirm")))return;const g=YD(v);a(g.ok?{ok:!0,text:p("prefs-import-done")}:{ok:!1,text:p(g.reason==="not-json"||g.reason==="wrong-kind"?"prefs-import-wrong":g.reason==="storage-write-failed"?"prefs-import-storage":"prefs-import-bad")})};return l.jsxs("div",{className:"nc-set-form nc-prefs-backup",children:[l.jsx("div",{className:"nc-sheet-label",children:p("prefs-backup")}),l.jsxs("div",{"data-testid":"sync-status",className:"nc-set-hint",children:[p("prefs-sync"),": ",e.status,e.revision!==void 0?` (r${e.revision})`:"",e.code?` · ${e.code}`:"",e.note?` · ${e.note}`:""]}),e.status==="conflict"&&l.jsxs("div",{className:"nc-set-confirm",role:"group","aria-label":p("prefs-conflict"),children:[l.jsx("div",{children:p("prefs-conflict")}),l.jsxs("div",{className:"nc-sheet-actions",children:[l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:()=>s("local"),children:p("prefs-keep-local")}),l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:()=>s("server"),children:p("prefs-use-server")})]})]}),l.jsxs("div",{className:"nc-sheet-actions",children:[l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:c,children:p("prefs-export")}),l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:()=>n.current&&n.current.click(),children:p("prefs-import")}),l.jsx("input",{ref:n,type:"file",accept:"application/json,.json","aria-label":p("prefs-import"),style:{display:"none"},onChange:u})]}),i&&l.jsx("div",{className:i.ok?"nc-set-note":"nc-err",role:i.ok?"status":"alert",children:i.text})]})}function t6({text:t}){const[e,n]=w.useState(!1),s=async()=>{try{await navigator.clipboard.writeText(t),n(!0),setTimeout(()=>n(!1),1500)}catch{}};return l.jsxs("div",{className:"nc-set-copyline",children:[l.jsx("code",{children:t}),l.jsxs("button",{type:"button",className:"nc-btn ghost",onClick:s,children:[l.jsx(Dt,{name:"copy",size:14})," ",p(e?"copied":"copy")]})]})}function n6({value:t}){const[e,n]=w.useState("");return w.useEffect(()=>{let s=!0;return r3.toDataURL(t,{margin:1,width:220}).then(i=>{s&&n(i)}).catch(()=>{}),()=>{s=!1}},[t]),e?l.jsx("img",{src:e,width:"220",height:"220",alt:"NexusCrew pairing QR"}):null}function s6({token:t,nodes:e,roster:n,settings:s,readonly:i,refresh:a,refreshAliases:c,vlUnavailable:u=[],accessRevision:h=null}){const[f,v]=w.useState(null),[g,_]=w.useState(null),[b,S]=w.useState(null),[E,C]=w.useState({ssh:"",sshPort:"",name:""}),[N,k]=w.useState(""),[I,L]=w.useState(""),[H,z]=w.useState(!1),[V,Y]=w.useState(null),G=Date.now(),Z=s&&s.deviceName||"",q=(e||[]).filter(R=>R&&R.direction==="outbound"&&R.name&&R.ssh),T=q.find(R=>R.name===N)||q[0]||null,P=T?mv(T.tunnel,G):null,D=T!=null&&T.shared?P!=null&&P.up?"share-local-active":"share-local-pending":P!=null&&P.up?"share-local-private":"share-local-private-down",j=[{key:"peer-group-hubs",rows:(e||[]).filter(R=>R.kind!=="transitive"&&R.kind!=="vl"&&R.relation!=="client")},{key:"peer-group-clients",rows:(e||[]).filter(R=>R.kind!=="transitive"&&R.kind!=="vl"&&R.relation==="client")},{key:"peer-group-routed",rows:(e||[]).filter(R=>R.kind==="transitive")},{key:"peer-group-vl",rows:(e||[]).filter(R=>R.kind==="vl")}],O=V&&(e||[]).find(R=>`${R.kind||"direct"}:${R.nodeId||R.name}`===V)||null,A=async R=>{if(T){v(null),_(`${T.name}:share`);try{const F=await S5(t,T.name,R);await a(),F&&F.reversePoolPending===!0&&v(`${T.name}: ${p("share-reverse-pool-pending")}`)}catch(F){const $=F!=null&&F.data&&F.data.shared===!1?F.data:null;if($)try{await a()}catch{}const K=F!=null&&F.data&&typeof F.data.hint=="string"?F.data.hint:"",oe=($==null?void 0:$.revoked)===!0&&($==null?void 0:$.localReconcilePending)===!0?p("share-off-local-reconcile-pending"):($==null?void 0:$.revoked)===!1&&($==null?void 0:$.reconcilePending)===!0?p("share-off-hub-reconcile-pending"):"",ce=F!=null&&F.data&&F.data.reversePoolPending===!0?p("share-reverse-pool-pending"):"",ne=F!=null&&F.data&&typeof F.data.code=="string"?F.data.code:"",Le=F!=null&&F.data&&typeof F.data.detail=="string"?F.data.detail.trim():"",Ee=Le&&Le!==String(F.message||"")?Le:"";v(`${T.name}: ${String(F.message||F)}${ne?` [${ne}]`:""}${Ee?` — ${Ee}`:""}${K?` — ${K}`:""}${oe?` — ${oe}`:""}${ce?` — ${ce}`:""}`)}_(null)}},M=async()=>{v(null);const R=ho(E.name||I||Z||"NexusCrew"),F=uP({name:R,ssh:E.ssh,sshPort:E.sshPort});if(!F.ok){v(p(F.error));return}_("invite");try{S(await _5(t,{...I||Z?{label:I||Z}:{},name:R,ssh:F.value.ssh,...F.value.sshPort?{sshPort:F.value.sshPort}:{}}))}catch($){v(String($.message||$))}_(null)};return l.jsxs("div",{className:"nc-set-tab",children:[l.jsx("div",{className:"nc-sheet-label",children:p("peer-inventory-title")}),(e||[]).length===0&&l.jsx("div",{className:"nc-empty",children:p("no-nodes")}),j.map(R=>R.rows.length>0&&l.jsxs("div",{className:"nc-peer-group",children:[l.jsxs("div",{className:"nc-peer-group-title",children:[p(R.key)," ",l.jsx("span",{children:R.rows.length})]}),R.rows.map(F=>{const $=g3(F);if(!$)return null;const K=`${F.kind||"direct"}:${F.nodeId||F.name}`,oe=$.routed?{up:$.reach.up,since:null}:mv(F.tunnel,G);return l.jsxs("button",{type:"button",className:`nc-set-node nc-node-row${$.routed?" routed":""}`,"aria-label":`${$.title} — ${p("node-detail-open")}`,onClick:()=>Y(K),children:[l.jsx("span",{className:`nc-dot ${$.reach.up?"on":""}`}),l.jsxs("span",{className:"nc-node-row-text",children:[l.jsx("b",{children:$.title}),l.jsxs("small",{children:[$.routed?$.routeLabel:`${$.subtitle} · ${p($.exposure.shortKey)}`,!$.routed&&$.exposure.shortKey==="visibility-selected"?` (${$.exposure.count})`:""]})]}),l.jsxs("span",{className:`nc-set-tunnel${$.reach.up?" up":""}`,children:[p($.reach.key),oe.since?` · ${oe.since}`:""]}),l.jsx("span",{className:"nc-node-row-more",children:l.jsx(Dt,{name:"chevronDown",size:14})})]},K)})]},R.key)),u.length>0&&l.jsxs("div",{className:"nc-err",children:[p("vl-owners-unavailable"),": ",u.map(R=>R.label||R.route.join("/")).join(", ")]}),O&&l.jsx(O3,{node:O,nodes:e||[],token:t,readonly:i,refresh:a,onClose:()=>Y(null),peerAccessRevision:h}),(n||[]).some(R=>!R.direct&&R.instanceId)&&l.jsxs("div",{className:"nc-set-form",children:[l.jsx("div",{className:"nc-sheet-label",children:p("routed-node-aliases")}),l.jsx("small",{className:"nc-set-hint",children:p("routed-node-aliases-help")}),(n||[]).filter(R=>!R.direct&&R.instanceId).map(R=>l.jsxs("div",{className:"nc-set-node",children:[l.jsxs("div",{className:"nc-set-node-head",children:[l.jsx("span",{className:`nc-dot ${R.status==="up"?"on":""}`}),l.jsx("b",{children:R.label||R.name}),l.jsx("small",{children:(R.route||[]).join(" › ")})]}),l.jsxs("div",{className:"nc-set-node-actions",children:[l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:i||!!g,onClick:async()=>{const F=window.prompt(p("node-local-alias"),R.alias||"");if(F!=null){if(F.trim()&&!Ya(F.normalize("NFC"))){v(p("err-label"));return}_(`${R.instanceId}:alias`),v(null);try{F.trim()?await w5(t,R.instanceId,F):await xw(t,R.instanceId),c()}catch($){v(String($.message||$))}_(null)}},children:p("alias-on-device")}),R.alias&&l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:i||!!g,onClick:async()=>{_(`${R.instanceId}:alias-reset`),v(null);try{await xw(t,R.instanceId),c()}catch(F){v(String(F.message||F))}_(null)},children:p("reset-alias")})]})]},R.instanceId))]}),T&&l.jsxs("div",{className:"nc-set-form nc-local-share",children:[l.jsx("div",{className:"nc-sheet-label",children:p("share-local-heading")}),q.length>1&&l.jsxs("label",{className:"nc-field",children:[p("share-local-hub"),l.jsx("select",{value:T.name,disabled:i||!!g,onChange:R=>k(R.target.value),children:q.map(R=>l.jsx("option",{value:R.name,children:R.label||R.name},R.name))})]}),l.jsxs("label",{className:"nc-check nc-node-share",children:[l.jsx("input",{type:"checkbox",checked:T.shared===!0,disabled:i||!!g,onChange:R=>A(R.target.checked)}),l.jsxs("span",{children:[l.jsx("b",{children:p("share-local-through").replace("{device}",Z||p("local")).replace("{hub}",T.label||T.name)}),l.jsx("small",{children:p(T.shared?"share-node-on-desc":"share-node-off-desc")})]})]}),l.jsx("div",{className:`nc-set-test${T.shared&&(P!=null&&P.up)?" ok":P!=null&&P.up?"":" ko"}`,children:p(D)}),!(P!=null&&P.up)&&l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:i||!!g,onClick:()=>A(T.shared===!0),children:p("share-local-reconnect")})]}),l.jsx(bk,{token:t,deviceDefault:Z,localNodeId:s&&s.nodeId||"",localNameDefault:s&&s.localName||"",readonly:i,onSuccess:a}),l.jsxs("div",{className:"nc-set-form",children:[l.jsx("div",{className:"nc-sheet-label",children:p("invite-node")}),l.jsx("small",{className:"nc-set-hint",children:p("invite-v2-hint")}),l.jsxs("div",{className:"nc-set-info nc-invite-endpoint",children:[p("invite-target-local"),": ",l.jsx("b",{children:Z||p("invite-target-this")})]}),l.jsxs("label",{className:"nc-field",children:[p("invite-endpoint-label"),l.jsx("input",{placeholder:"user@host",value:E.ssh,disabled:i,onChange:R=>C({...E,ssh:R.target.value})}),l.jsx("small",{className:"nc-set-hint",children:p("invite-endpoint-needed")})]}),q.length>0&&l.jsx("small",{className:"nc-set-hint nc-invite-hub-hint",children:p("invite-hub-only")}),H&&l.jsxs("div",{className:"nc-invite-advanced",children:[l.jsxs("label",{className:"nc-field",children:[p("node-ssh-port-label"),l.jsx("input",{inputMode:"numeric",placeholder:"22",value:E.sshPort,disabled:i,onChange:R=>C({...E,sshPort:R.target.value.replace(/[^0-9]/g,"").slice(0,5)})})]}),l.jsxs("label",{className:"nc-field",children:[p("device-name-label"),l.jsx("input",{placeholder:Z||"NexusCrew",value:I,disabled:i,onChange:R=>L(R.target.value)}),l.jsx("small",{className:"nc-set-hint",children:p("device-name-hint")})]}),l.jsxs("label",{className:"nc-field",children:[p("node-name-label"),l.jsx("input",{placeholder:ho(I||Z||p("node-name-ph")),value:E.name,disabled:i,onChange:R=>C({...E,name:R.target.value?ho(R.target.value):""})})]})]}),l.jsxs("div",{className:"nc-set-row nc-invite-actions",children:[l.jsx("button",{type:"button",className:"nc-btn primary",disabled:i||!!g||!E.ssh.trim(),onClick:M,children:p("create-pairing-link")}),l.jsxs("button",{type:"button",className:"nc-btn ghost",disabled:!!g,onClick:()=>z(R=>!R),children:[H?"▾":"▸"," ",p("pair-advanced")]})]}),b&&l.jsxs(l.Fragment,{children:[l.jsx(n6,{value:b.pairingUrl}),l.jsx(t6,{text:b.pairingUrl}),l.jsx("div",{className:"nc-set-info",children:p("invite-next-steps")})]})]}),f&&l.jsx("div",{className:"nc-err",children:f})]})}function i6({token:t,readonly:e}){const[n,s]=w.useState("idle"),[i,a]=w.useState(()=>Ek()),[c,u]=w.useState(!1),[h,f]=w.useState(null);w.useEffect(()=>{let _=!1;return F3().then(b=>{_||s(b)}),()=>{_=!0}},[]);const v=async()=>{f(null),u(!0);try{n==="subscribed"?(await MS(t),s("idle")):(await H3(t),s("subscribed"))}catch(_){const b=String(_.message||_);b==="push-denied"?(s("denied"),f(p("push-denied"))):b==="push-unsupported"?(s("unsupported"),f(p("push-unsupported"))):f(b==="push-disabled-local"?p("push-local-disabled"):b)}u(!1)},g=async()=>{const _=B3({enabled:i.enabled!==!1});if(a(_),f(null),_.enabled===!1&&n==="subscribed"){u(!0);try{await MS(t),s("idle")}catch{}u(!1)}};return n==="unsupported"?l.jsx("div",{className:"nc-set-info",children:p("push-unsupported")}):l.jsxs(l.Fragment,{children:[l.jsxs("div",{className:"nc-set-row",children:[l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:g,disabled:c,children:i.enabled===!1?p("push-local-on"):p("push-local-off")}),l.jsx("span",{className:"nc-set-info",children:i.enabled===!1?p("push-local-off-note"):p("push-local-help")})]}),l.jsxs("div",{className:"nc-set-row",children:[l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:e||c||n==="denied",title:e?p("settings-readonly"):"",onClick:v,children:p(n==="subscribed"?"push-disable":"push-enable")}),l.jsx("span",{className:"nc-set-info",children:p(n==="subscribed"?"push-on":n==="denied"?"push-denied":"push-off")})]}),h&&l.jsx("div",{className:"nc-err",children:h})]})}function r6(){const[t,e]=Fk(),[n,s]=w.useState(""),[i,a]=w.useState(""),[c,u]=w.useState(!1),[h,f]=w.useState(Ok),v=w.useRef(0),g=w.useRef(!1),_=w.useRef(null),b=Nc();w.useEffect(()=>()=>{var C;v.current+=1,g.current&&((C=_.current)==null||C.abort(),_.current=null,g.current=!1,kv())},[]);const S=async()=>{const C=v.current+=1,N=typeof AbortController=="function"?new AbortController:null;s(""),a(""),u(!0),f(!1),g.current=!0,_.current=N;const k=await TD(p("notification-speech-preview"),_d(),void 0,N?{signal:N.signal}:{});return C!==v.current||(_.current=null,g.current=!1,u(!1),f(k===!0),k===!0?a(p("notification-speech-preview-ok")):s(p(k==="voice-error"?"notification-speech-preview-voice-error":k==="timeout"?"notification-speech-preview-timeout":"notification-speech-preview-failed"))),k},E=C=>{var N;if(e(C),s(""),a(""),C)S();else{v.current+=1;const k=g.current;(N=_.current)==null||N.abort(),_.current=null,g.current=!1,u(!1),f(!1),kv(),k||zk()}};return l.jsxs("div",{className:"nc-set-form",children:[l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox","aria-label":p("notification-speech-enable"),checked:t,disabled:!b,onChange:C=>E(C.target.checked)}),l.jsxs("span",{children:[l.jsx("b",{children:p("notification-speech-enable")}),l.jsx("small",{children:p("notification-speech-help")})]})]}),b?l.jsx("div",{className:"nc-set-row",children:l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:!t||c,onClick:()=>{S()},children:p(c?"notification-speech-testing":"notification-speech-test")})}):l.jsx("div",{className:"nc-set-info",children:p("notification-speech-unsupported")}),t&&!h&&!c&&!n&&l.jsx("div",{className:"nc-set-info",children:p("notification-speech-needs-test")}),i&&l.jsx("div",{className:"nc-set-info",role:"status",children:i}),n&&l.jsx("div",{className:"nc-err",children:n})]})}function o6({token:t,readonly:e,nodes:n=[],settings:s=null}){const[i,a]=w.useState(null),[c,u]=w.useState([]),[h,f]=w.useState({name:"",mode:"primary-failover",targets:[]}),[v,g]=w.useState(null),[_,b]=w.useState(!1),[S,E]=w.useState(null),[C,N]=w.useState(""),k=w.useCallback(async()=>{try{const[A,M]=await Promise.all([C5(t),L5(t)]);a(A),u(Array.isArray(M==null?void 0:M.groups)?M.groups:[]),N("")}catch(A){N(String(A.message||A))}},[t]);w.useEffect(()=>{k()},[k]);const I=async A=>{b(!0),E(null),N("");try{a(await k5(t,A))}catch(M){N(String(M.message||M))}b(!1)},L=async()=>{b(!0),E(null),N("");try{E({kind:"test",...await E5(t)})}catch(A){N(String(A.message||A))}b(!1)},H=async()=>{b(!0),E(null),N("");try{E({kind:"stop",...await N5(t)})}catch(A){N(String(A.message||A))}b(!1)},z=[],V=new Set,Y=(A,M)=>{const R=typeof A=="string"?A.toLowerCase():"";!/^[a-f0-9]{32}$/.test(R)||V.has(R)||(V.add(R),z.push({id:R,label:M||R}))};Y(s==null?void 0:s.nodeId,p("audio-group-local"));for(const A of n||[])Y((A==null?void 0:A.nodeId)||(A==null?void 0:A.instanceId),(A==null?void 0:A.label)||(A==null?void 0:A.name)||(A==null?void 0:A.nodeId));for(const A of h.targets)Y(A,`${A} (${p("audio-group-unavailable-target")})`);const G=(A=null)=>{N(""),A?(g(A.name),f({name:A.name,mode:A.mode,targets:[...A.targets||[]]})):(g(null),f({name:"",mode:"primary-failover",targets:[]}))},Z=(A,M)=>f(R=>({...R,targets:M?[...new Set([...R.targets,A])]:R.targets.filter(F=>F!==A)})),q=async()=>{const A=h.name.trim().toLowerCase();if(!/^[a-z0-9][a-z0-9-]{0,31}$/.test(A)||h.targets.length<1){N(p("audio-group-invalid"));return}b(!0),N("");try{const M=await R5(t,A,{targets:h.targets,mode:h.mode}),R=M==null?void 0:M.group;if(!R||!R.name)throw new Error(p("audio-group-save-failed"));u(F=>[...F.filter($=>$.name!==R.name),R].sort(($,K)=>$.name.localeCompare(K.name))),G(null)}catch(M){N(String(M.message||M))}b(!1)},T=async A=>{b(!0),N("");try{await A5(t,A),u(M=>M.filter(R=>R.name!==A)),v===A&&G(null)}catch(M){N(String(M.message||M))}b(!1)},P=(i==null?void 0:i.installed)===!0,D=(i==null?void 0:i.liveness)==="ready",j=(i==null?void 0:i.consent)===!0&&P&&D,O=S?S.kind==="stop"?p(S.stopped?"audio-stop-stopped":"audio-stop-idle"):S.status==="accepted"||S.status==="spoken"?p("audio-test-accepted"):S.status==="unknown"?p("audio-test-unknown"):`${p("audio-test-refused")}${S.reason?` (${S.reason})`:""}`:"";return l.jsxs("div",{className:"nc-set-tab nc-audio-settings",children:[l.jsxs("div",{className:"nc-set-info",children:[l.jsx("b",{children:p("audio-title")}),l.jsx("br",{}),p("audio-help")]}),i?l.jsxs(l.Fragment,{children:[l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox","aria-label":p("audio-consent"),checked:i.consent===!0,disabled:e||_,onChange:A=>{I(A.target.checked)}}),l.jsxs("span",{children:[l.jsx("b",{children:p("audio-consent")}),l.jsx("small",{children:p("audio-consent-help")})]})]}),l.jsxs("div",{className:"nc-set-form",children:[l.jsx("div",{className:"nc-sheet-label",children:p("audio-capability")}),l.jsxs("div",{className:"nc-set-info",children:[p("audio-adapter"),": ",i.adapter||p("audio-adapter-none"),l.jsx("br",{}),p("audio-installed"),": ",p(P?"audio-installed-yes":"audio-installed-no"),l.jsx("br",{}),p("audio-liveness"),": ",p(D?"audio-liveness-ready":"audio-liveness-unavailable"),Array.isArray(i.languages)&&i.languages.length>0&&l.jsxs(l.Fragment,{children:[l.jsx("br",{}),p("audio-languages"),": ",i.languages.join(", ")]})]}),i.limits&&l.jsxs("small",{className:"nc-set-hint",children:[p("audio-limits"),": ",i.limits]})]}),!i.consent&&l.jsx("div",{className:"nc-set-info",children:p("audio-test-needs-consent")}),!P&&l.jsx("div",{className:"nc-set-info",children:p("audio-unavailable")}),l.jsxs("div",{className:"nc-set-row",children:[l.jsx("button",{type:"button",className:"nc-btn primary",disabled:e||_||!j,title:e?p("settings-readonly"):"",onClick:()=>{L()},children:p(_?"audio-testing":"audio-test")}),l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:_,onClick:()=>{H()},children:p(_?"audio-stopping":"audio-stop")}),l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:_,onClick:()=>{k()},children:p("refresh")})]}),l.jsxs("div",{className:"nc-set-form",children:[l.jsx("div",{className:"nc-sheet-label",children:p("audio-groups-title")}),l.jsx("small",{className:"nc-set-hint",children:p("audio-groups-help")}),c.length===0&&l.jsx("div",{className:"nc-set-info",children:p("audio-groups-empty")}),c.map(A=>{var M;return l.jsxs("div",{className:"nc-set-row",children:[l.jsxs("span",{children:[l.jsx("b",{children:A.name})," ",l.jsxs("small",{children:["· ",A.mode==="fanout"?p("audio-group-fanout"):p("audio-group-primary")," · ",((M=A.targets)==null?void 0:M.length)||0]})]}),l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:e||_,onClick:()=>G(A),children:p("audio-group-edit")}),l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:e||_,onClick:()=>{T(A.name)},children:p("audio-group-delete")})]},A.name)}),l.jsx("div",{className:"nc-set-row",children:l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:e||_,onClick:()=>G(null),children:p("audio-group-new")})}),l.jsxs("label",{className:"nc-field",children:[p("audio-group-name"),l.jsx("input",{"aria-label":p("audio-group-name"),value:h.name,maxLength:"32",disabled:e||_,onChange:A=>f(M=>({...M,name:A.target.value}))})]}),l.jsxs("label",{className:"nc-field",children:[p("audio-group-mode"),l.jsxs("select",{"aria-label":p("audio-group-mode"),value:h.mode,disabled:e||_,onChange:A=>f(M=>({...M,mode:A.target.value})),children:[l.jsx("option",{value:"primary-failover",children:p("audio-group-primary")}),l.jsx("option",{value:"fanout",children:p("audio-group-fanout")})]})]}),l.jsx("div",{className:"nc-set-info",children:p("audio-group-targets")}),z.length===0?l.jsx("small",{className:"nc-set-hint",children:p("audio-group-no-targets")}):z.map(A=>l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox",checked:h.targets.includes(A.id),disabled:e||_,onChange:M=>Z(A.id,M.target.checked)}),l.jsxs("span",{children:[A.label,l.jsx("small",{children:A.id})]})]},A.id)),l.jsxs("div",{className:"nc-set-row",children:[l.jsx("button",{type:"button",className:"nc-btn primary",disabled:e||_,onClick:()=>{q()},children:p("audio-group-save")}),v&&l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:_,onClick:()=>G(null),children:p("audio-group-cancel")})]})]})]}):l.jsx("div",{className:"nc-set-info",children:p("audio-loading")}),O&&l.jsx("div",{className:"nc-set-note",role:"status",children:O}),C&&l.jsx("div",{className:"nc-err",children:C})]})}function a6(){const[t,e]=Cg();return l.jsxs("div",{className:"nc-set-tab nc-input-settings",children:[l.jsx("div",{className:"nc-set-info",children:p("input-settings-local")}),l.jsxs("div",{className:"nc-set-form",children:[l.jsxs("label",{className:"nc-field",children:[p("terminal-keyboard-gesture"),l.jsx("select",{"aria-label":p("terminal-keyboard-gesture"),value:t.terminalKeyboardGesture,onChange:n=>e({terminalKeyboardGesture:n.target.value}),children:QC.map(n=>l.jsx("option",{value:n,children:p(`terminal-keyboard-${n}`)},n))}),l.jsx("small",{children:p("terminal-keyboard-gesture-help")})]}),l.jsxs("label",{className:"nc-field",children:[p("keybar-layout"),l.jsx("select",{"aria-label":p("keybar-layout"),value:t.keybarLayout,onChange:n=>e({keybarLayout:n.target.value}),children:ZC.map(n=>l.jsx("option",{value:n,children:p(`keybar-layout-${n}`)},n))}),l.jsx("small",{children:p("keybar-layout-help")})]})]}),l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox",checked:t.keybarKeepsKeyboardClosed,onChange:n=>e({keybarKeepsKeyboardClosed:n.target.checked})}),l.jsxs("span",{children:[l.jsx("b",{children:p("keybar-ime-lock")}),l.jsx("small",{children:p("keybar-ime-lock-help")})]})]}),l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox",checked:t.voiceKeepsKeyboardClosed,onChange:n=>e({voiceKeepsKeyboardClosed:n.target.checked})}),l.jsxs("span",{children:[l.jsx("b",{children:p("voice-ime-lock")}),l.jsx("small",{children:p("voice-ime-lock-help")})]})]}),l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox",checked:t.showKeybarEnter,onChange:n=>e({showKeybarEnter:n.target.checked})}),l.jsxs("span",{children:[l.jsx("b",{children:p("keybar-enter-show")}),l.jsx("small",{children:p("keybar-enter-show-help")})]})]}),l.jsx("div",{className:"nc-set-row",children:l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:()=>e(io),children:p("input-settings-reset")})})]})}function l6({token:t,roster:e=[],readonly:n}){const s=[{key:"local",route:[],label:p("diagnostics-local"),status:"up"},...e.filter(j=>Array.isArray(j.route)&&j.route.length).map(j=>({key:j.route.join("/"),route:j.route,label:j.label||j.name,status:j.status}))],[i,a]=w.useState("local"),c=s.find(j=>j.key===i)||s[0],[u,h]=w.useState(null),[f,v]=w.useState([]),[g,_]=w.useState(""),[b,S]=w.useState(!1),[E,C]=w.useState(!0),[N,k]=w.useState(900),[I,L]=w.useState("all"),[H,z]=w.useState(""),V=w.useRef(0),Y=w.useRef(null),G=w.useCallback(async()=>{try{const j=await P5(t,c.route);if(h(j),_(""),!b){const O=await I5(t,{after:V.current,limit:200},c.route);Array.isArray(O.records)&&O.records.length&&(V.current=O.cursor,v(A=>[...A,...O.records].slice(-500)))}}catch(j){_(j&&j.status===404?p("diagnostics-unsupported"):String(j.message||j))}},[t,c.key,b]);w.useEffect(()=>{V.current=0,v([]),h(null),_("")},[c.key]),w.useEffect(()=>{let j=null,O=!0;const A=()=>{!O||document.visibilityState==="hidden"||G()},M=()=>{j&&clearInterval(j),j=document.visibilityState==="hidden"?null:setInterval(A,2e3),document.visibilityState!=="hidden"&&A()};return document.addEventListener("visibilitychange",M),M(),()=>{O=!1,j&&clearInterval(j),document.removeEventListener("visibilitychange",M)}},[G]),w.useEffect(()=>{E&&Y.current&&(Y.current.scrollTop=Y.current.scrollHeight)},[f,E]);const Z=f.filter(j=>(I==="all"||j.level===I)&&(!H||String(j.component||"").toLowerCase().includes(H.toLowerCase()))),q=Z.map(j=>`${j.ts} ${j.level.toUpperCase()} ${j.component} ${j.code} ${j.message}${Object.keys(j.meta||{}).length?` ${JSON.stringify(j.meta)}`:""}`).join(`
168
168
  `),T=async j=>{_("");try{const O=await j();h(O),await G()}catch(O){_(String(O.message||O))}},P=async()=>{try{await navigator.clipboard.writeText(q)}catch{_(p("copy-manual"))}},D=()=>{try{const j=new Blob([`${JSON.stringify(Z,null,2)}
169
- `],{type:"application/json"}),O=URL.createObjectURL(j),A=document.createElement("a");A.href=O,A.download="nexuscrew-diagnostics.json",A.click(),URL.revokeObjectURL(O)}catch{_(p("diagnostics-export-failed"))}};return l.jsxs("div",{className:"nc-set-tab nc-diagnostics",children:[l.jsxs("label",{className:"nc-field",children:[p("diagnostics-target"),l.jsx("select",{value:c.key,onChange:j=>a(j.target.value),children:s.map(j=>l.jsxs("option",{value:j.key,children:[j.label,j.status!=="up"?` · ${j.status}`:""]},j.key))})]}),l.jsxs("div",{className:"nc-set-form nc-diag-controls",children:[l.jsx("div",{className:"nc-sheet-label",children:p("diagnostics-verbose")}),l.jsxs("div",{className:"nc-set-row",children:[l.jsx("select",{"aria-label":p("diagnostics-duration"),value:N,onChange:j=>k(Number(j.target.value)),disabled:n,children:[300,900,1800,3600].map(j=>l.jsxs("option",{value:j,children:[j/60," min"]},j))}),l.jsx("button",{type:"button",className:"nc-btn primary",disabled:n||(u==null?void 0:u.verbose)===!0,onClick:()=>T(()=>Cw(t,!0,N,c.route)),children:p("enable")}),l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:n||(u==null?void 0:u.verbose)!==!0,onClick:()=>T(()=>Cw(t,!1,N,c.route)),children:p("stop")})]}),l.jsx("small",{className:"nc-set-hint",children:u!=null&&u.verbose?p("diagnostics-expires").replace("{time}",new Date(u.expiresAt).toLocaleTimeString()):p("diagnostics-off")})]}),l.jsxs("div",{className:"nc-diag-filters",children:[l.jsxs("select",{"aria-label":p("diagnostics-level"),value:I,onChange:j=>L(j.target.value),children:[l.jsx("option",{value:"all",children:p("diagnostics-all-levels")}),["debug","info","warn","error"].map(j=>l.jsx("option",{value:j,children:j},j))]}),l.jsx("input",{"aria-label":p("diagnostics-component"),placeholder:p("diagnostics-component"),value:H,onChange:j=>z(j.target.value)})]}),l.jsxs("div",{className:"nc-set-row",children:[l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox",checked:b,onChange:j=>S(j.target.checked)})," ",p("diagnostics-pause")]}),l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox",checked:E,onChange:j=>C(j.target.checked)})," ",p("diagnostics-autoscroll")]})]}),l.jsx("pre",{ref:Y,className:"nc-diag-log","aria-label":p("diagnostics-log"),children:q||p("diagnostics-empty")}),l.jsxs("div",{className:"nc-set-row",children:[l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:P,children:p("copy")}),l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:D,children:p("diagnostics-export")}),l.jsx("button",{type:"button",className:"nc-btn danger",disabled:n,onClick:()=>{window.confirm(p("diagnostics-clear-confirm"))&&T(async()=>{const j=await D5(t,c.route);return V.current=0,v([]),j})},children:p("diagnostics-clear")})]}),g&&l.jsx("div",{className:"nc-err",children:g})]})}function c6({token:t,settings:e,readonly:n,refresh:s,roster:i,section:a,setSection:c}){const[u,h]=w.useState(null),[f,v]=w.useState(null),[g,_]=w.useState(!1),[b,S]=w.useState(!1),[E,C]=w.useState(null),[N,k]=w.useState(!0),[I,L]=w.useState(!1),[H,z]=w.useState(null);w.useEffect(()=>{C(e&&e.update||null),k(!e||e.autoUpdate!==!1),L(!!(e&&e.alternateScreen))},[e]);const V=async()=>{h(null),v(null),S(!0);try{const A=await v5(t);v(A.note||"ok"),_(!1)}catch(A){h(String(A.message||A))}S(!1)},Y=async()=>{h(null),v(null),S(!0);try{const A=await j5(t);v(`${A.note||"ok"}${A.target?` (${A.target})`:""}`)}catch(A){h(String(A.message||A))}S(!1)},G=async A=>{h(null),v(null),S(!0);try{await gd(t,{autoUpdate:A}),k(A),s&&await s()}catch(M){h(String(M.message||M))}S(!1)},Z=async A=>{h(null),v(null),S(!0);try{await gd(t,{alternateScreen:A}),L(A),s&&await s()}catch(M){h(String(M.message||M))}S(!1)},q=w.useCallback(async()=>{if(t)try{z(await m5(t))}catch{z(null)}},[t]);w.useEffect(()=>{q()},[q]);const T=async A=>{h(null),v(null),S(!0);try{if(!A&&H&&H.running&&!window.confirm(p("ai-desktop-confirm-stop"))){S(!1);return}const M=await w1(t,A);M&&M.ok===!1&&h(M.error||"comando fallito"),await q(),s&&await s()}catch(M){h(String(M.message||M))}S(!1)},P=async()=>{h(null),v(null),S(!0);try{C(await M5(t))}catch(A){h(String(A.message||A))}S(!1)},D=async()=>{h(null),v(null),S(!0);try{const A=await T5(t);C(A),v(p("npm-update-restarting"))}catch(A){h(String(A.message||A))}S(!1)},j=()=>{window.confirm(p("composer-clear-confirm"))&&(h(null),$P()?(window.dispatchEvent(new Event(_v)),v(p("composer-clear-done"))):h(p("composer-clear-failed")))},O=e&&e.service;return l.jsxs("div",{className:"nc-set-tab",children:[l.jsx("div",{className:"nc-system-tabs",role:"tablist","aria-label":p("tab-system"),children:["general","diagnostics"].map(A=>l.jsx("button",{type:"button",role:"tab","aria-selected":a===A,className:`nc-set-tabbtn${a===A?" on":""}`,onClick:()=>c(A),children:p(`system-${A}`)},A))}),a==="general"&&l.jsxs(l.Fragment,{children:[l.jsxs("section",{className:"nc-system-group",children:[l.jsx("h3",{children:p("system-this-node")}),e&&l.jsxs("div",{className:"nc-set-info",children:["v",e.version," · ",e.platform," · :",e.port,l.jsx("br",{}),O&&O.installed?p("service-installed"):p("service-missing"),O&&O.installed?` · ${O.active?p("service-active"):p("service-inactive")}`:"",O?` · boot ${O.boot?"on":"off"}`:""]}),l.jsx("div",{className:"nc-set-row",children:l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:n||b,title:n?p("settings-readonly"):"",onClick:Y,children:p("service-regenerate")})}),l.jsx(i6,{token:t,readonly:n}),l.jsx(r6,{})]}),l.jsxs("section",{className:"nc-system-group",children:[l.jsx("h3",{children:p("system-updates")}),l.jsxs("div",{className:"nc-set-form nc-update-settings",children:[l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox",checked:N,disabled:n||b||E&&!E.supported,onChange:A=>G(A.target.checked)}),l.jsxs("span",{children:[l.jsx("b",{children:p("npm-auto-update")}),l.jsx("small",{children:p("npm-auto-update-help")})]})]}),E&&l.jsxs("div",{className:"nc-set-info",children:[p("npm-update-current")," v",E.current,E.latest?` · ${p("npm-update-latest")} v${E.latest}`:""," · ",p(E.supported?E.phase==="idle"&&E.checked!==!0?"npm-update-never":`npm-update-${E.phase}`:"unsupported")]}),l.jsxs("div",{className:"nc-set-row",children:[l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:n||b||!E||!E.supported,onClick:P,children:p("npm-update-check")}),E&&E.available&&l.jsx("button",{type:"button",className:"nc-btn primary",disabled:n||b||E.phase==="installing",onClick:D,children:p("npm-update-install")})]}),E&&E.lastError&&l.jsx("div",{className:"nc-err",children:E.lastError})]})]}),l.jsxs("section",{className:"nc-system-group",children:[l.jsx("h3",{children:p("ai-desktop-title")}),l.jsxs("div",{className:"nc-set-form",children:[l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox","aria-label":p("ai-desktop"),disabled:n||b,checked:!!(H&&H.desired),onChange:A=>T(A.target.checked)}),l.jsxs("span",{children:[l.jsx("b",{children:p("ai-desktop")}),l.jsx("small",{children:p("ai-desktop-help")})]})]}),H&&!H.desired&&H.running&&l.jsx("div",{className:"nc-set-info",children:p("ai-desktop-stop-pending")})]})]}),l.jsxs("section",{className:"nc-system-group",children:[l.jsx("h3",{children:p("system-security")}),l.jsx("div",{className:"nc-set-row",children:l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:n||b,title:n?p("settings-readonly"):"",onClick:()=>{h(null),v(null),_(!0)},children:p("token-rotate")})})]}),l.jsxs("section",{className:"nc-system-group",children:[l.jsx("h3",{children:p("system-local-data")}),l.jsxs("div",{className:"nc-set-form",children:[l.jsx("div",{className:"nc-sheet-label",children:p("composer-clear-data")}),l.jsx("small",{className:"nc-set-hint",children:p("composer-clear-data-help")}),l.jsx("div",{className:"nc-set-row",children:l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:j,children:p("composer-clear-data")})})]})]})]}),a==="diagnostics"&&l.jsxs("section",{className:"nc-system-group nc-system-diagnostics",children:[l.jsx("h3",{children:p("system-diagnostics")}),l.jsxs("div",{className:"nc-set-form nc-alternate-screen-settings",children:[l.jsx("div",{className:"nc-sheet-label",children:p("system-terminal")}),l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox","aria-label":p("alternate-screen"),checked:I,disabled:n||b,onChange:A=>Z(A.target.checked)}),l.jsxs("span",{children:[l.jsx("b",{children:p("alternate-screen")}),l.jsx("small",{children:p("alternate-screen-help")})]})]})]}),l.jsx(e6,{token:t}),l.jsx(BD,{}),l.jsx(l6,{token:t,roster:i,readonly:n})]}),g&&l.jsxs("div",{className:"nc-set-confirm",children:[l.jsx("div",{children:p("token-rotate-explain")}),l.jsxs("div",{className:"nc-sheet-actions",children:[l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:b,onClick:()=>_(!1),children:p("cancel")}),l.jsx("button",{type:"button",className:"nc-btn primary",disabled:b,onClick:V,children:p("confirm")})]})]}),f&&l.jsx("div",{className:"nc-set-note",children:f}),u&&l.jsx("div",{className:"nc-err",children:u})]})}function u6({token:t,onClose:e,initialTab:n="nodes",initialLocation:s="",startNewCell:i=!1}){qn();const a=n==="diagnostics"?"diagnostics":"general",[c,u]=w.useState(n==="diagnostics"?"system":n),h=w.useRef(null),f=w.useRef(null),[v,g]=w.useState({start:!1,end:!1}),[_,b]=w.useState(a),[S,E]=w.useState(null),[C,N]=w.useState([]),[k,I]=w.useState(null),[L,H]=w.useState([]),[z,V]=w.useState(!1),[Y,G]=w.useState(null),[Z,q]=w.useState(0),T=dg(t,!0,Z),P=w.useCallback(()=>{const j=h.current;if(!j)return;const O=j.scrollWidth>j.clientWidth+1,A={start:O&&j.scrollLeft>1,end:O&&j.scrollLeft+j.clientWidth<j.scrollWidth-1};g(M=>M.start===A.start&&M.end===A.end?M:A)},[]);w.useEffect(()=>{const j=h.current;if(!j)return;const O=typeof ResizeObserver=="function"?new ResizeObserver(P):null;return O==null||O.observe(j),window.addEventListener("resize",P),P(),()=>{O==null||O.disconnect(),window.removeEventListener("resize",P)}},[P]),w.useEffect(()=>{var O,A;(A=(O=f.current)==null?void 0:O.scrollIntoView)==null||A.call(O,{behavior:"smooth",block:"nearest",inline:"nearest"});const j=window.requestAnimationFrame?window.requestAnimationFrame(P):setTimeout(P,0);return()=>{window.cancelAnimationFrame?window.cancelAnimationFrame(j):clearTimeout(j)}},[c,P]);const D=w.useCallback(async()=>{var j;try{const O=await g1(t);E(O),G(null)}catch(O){G(String(O.message||O))}try{const O=await f5(t),A=O.peers||[];I(Number.isInteger(O.accessRevision)?O.accessRevision:null);let M=[],R=[];try{const[F,$]=await Promise.all([bn("/api/config",t).then(ne=>ne.json()).catch(()=>null),y1(t).catch(()=>null)]),K=F&&typeof F.instanceId=="string"?F.instanceId:"",oe=[{instanceId:K||null,route:[],label:null},...uC($,K)],ce=await Promise.all(oe.map(async ne=>{try{return{ok:!0,peers:((await _1(t,ne.route)).nodes||[]).map(pe=>cC(pe,ne)).filter(Boolean)}}catch(Le){return{ok:!1,owner:ne,error:Le}}}));for(const ne of ce){if(ne.ok){M.push(...ne.peers);continue}ne.owner.route.length!==0&&R.push({instanceId:ne.owner.instanceId,label:ne.owner.label,route:ne.owner.route,failure:/timeout/i.test(String(((j=ne.error)==null?void 0:j.message)||ne.error))?"timeout":"unreachable"})}}catch{}H(R),N([...A,...M])}catch(O){G(String(O.message||O))}},[t]);return w.useEffect(()=>{D();const j=setInterval(D,5e3);return()=>clearInterval(j)},[D]),w.useEffect(()=>{let j=!1;return bn("/api/config",t).then(O=>O.json()).then(O=>{j||V(!!O.readonlyDefault)}).catch(()=>{}),()=>{j=!0}},[t]),l.jsx("div",{className:"nc-set-overlay",onClick:e,children:l.jsxs("div",{className:"nc-set-panel",onClick:j=>j.stopPropagation(),children:[l.jsxs("div",{className:"nc-set-head",children:[l.jsx(Dt,{name:"gear",size:18}),l.jsx("b",{children:p("settings")}),l.jsx("button",{type:"button",className:"nc-set-close",onClick:e,title:p("close"),children:l.jsx(Dt,{name:"x",size:18})})]}),z&&l.jsx("div",{className:"nc-set-readonly",children:p("settings-readonly")}),Y&&l.jsx("div",{className:"nc-err",children:Y}),l.jsx("div",{className:`nc-set-tabs-wrap${v.start?" has-start-overflow":""}${v.end?" has-end-overflow":""}`,children:l.jsx("div",{className:"nc-set-tabs",ref:h,onScroll:P,children:["nodes","fleet","audio","input","system"].map(j=>l.jsx("button",{ref:c===j?f:null,type:"button",className:`nc-set-tabbtn${c===j?" on":""}`,onClick:()=>u(j),children:p(`tab-${j}`)},j))})}),l.jsxs("div",{className:"nc-set-body",children:[c==="nodes"&&l.jsx(s6,{token:t,nodes:C,roster:T,settings:S,readonly:z,vlUnavailable:L,accessRevision:k,refresh:D,refreshAliases:()=>q(j=>j+1)}),c==="fleet"&&l.jsx(_D,{token:t,readonly:z,startNewCell:i,initialLocation:s,targets:T.map(j=>({route:j.route,label:j.label||j.name,status:j.status}))}),c==="audio"&&l.jsx(o6,{token:t,readonly:z,nodes:C,settings:S}),c==="input"&&l.jsx(a6,{}),c==="system"&&l.jsx(c6,{token:t,settings:S,readonly:z,refresh:D,roster:T,section:_,setSection:b})]})]})})}function d6({token:t,initialPair:e,deviceDefault:n="",localNodeId:s="",localNameDefault:i="",deviceNameNeeded:a=!1,deviceNameSuggestion:c="",onPairDone:u,onDone:h}){qn();const[f,v]=w.useState(e?"pair":"welcome"),[g,_]=w.useState(!1),[b,S]=w.useState(null),[E,C]=w.useState(c||""),[N,k]=w.useState(null),I=async()=>{_(!0),S(null);try{const L={wizardDone:!0};a&&E.trim()&&(L.deviceName=E.trim()),await gd(t,L),u&&u(),h()}catch(L){S(String(L.message||L)),_(!1)}};return l.jsx("div",{className:"nc-wiz-overlay",children:l.jsxs("div",{className:"nc-wiz",children:[l.jsxs("div",{className:"nc-wiz-head",children:[l.jsx("b",{children:p("wizard-title")}),l.jsx("small",{children:p("hydra-simple")})]}),f==="welcome"&&l.jsxs("div",{className:"nc-wiz-body",children:[l.jsx("div",{className:"nc-wiz-done",children:p("local-ready")}),a&&l.jsx("div",{className:"nc-wiz-done",children:p("wizard-device-name")}),a&&l.jsxs("label",{className:"nc-field",children:[l.jsx("span",{children:p("device-name-label")}),l.jsx("input",{value:E,onChange:L=>C(L.target.value),maxLength:64,"data-testid":"wizard-device-name-input"})]}),l.jsxs("div",{className:"nc-sheet-actions",children:[l.jsx("button",{className:"nc-btn ghost",disabled:g,onClick:I,children:p("local-only")}),l.jsx("button",{className:"nc-btn primary",disabled:g,onClick:()=>v("pair"),children:p("add-node")})]})]}),f==="pair"&&l.jsxs("div",{className:"nc-wiz-body",children:[l.jsx(bk,{token:t,initial:e||"",autoStart:!!e,deviceDefault:a&&E.trim()?E.trim():n,localNodeId:s,localNameDefault:i,onBusyChange:_,onSuccess:async L=>{k(L&&L.authorizedKeys?{line:L.authorizedKeys,note:L.authorizedKeysNote||""}:null),u&&u(),v("done")}}),l.jsx("div",{className:"nc-sheet-actions",children:l.jsx("button",{className:"nc-btn ghost",disabled:g,onClick:()=>{u&&u(),v("welcome")},children:p("back")})})]}),f==="done"&&l.jsxs("div",{className:"nc-wiz-body",children:[l.jsx("div",{className:"nc-wiz-done",children:p("node-connected")}),N&&l.jsx(Tg,{line:N.line,note:N.note}),l.jsx("div",{className:"nc-sheet-actions",children:l.jsx("button",{className:"nc-btn primary",disabled:g,onClick:I,children:p("finish")})})]}),b&&l.jsx("div",{className:"nc-err",children:b})]})})}function h6({token:t,suggestion:e="",onSaved:n,onLater:s}){qn();const[i,a]=w.useState(e||""),[c,u]=w.useState(!1),[h,f]=w.useState(null),v=async()=>{const g=i.trim();if(g){u(!0),f(null);try{await gd(t,{deviceName:g}),n&&n(g)}catch(_){f(String(_.message||_)),u(!1)}}};return l.jsx("div",{className:"nc-wiz-overlay",role:"dialog","aria-label":p("device-name-ask-title"),"data-testid":"device-name-ask",children:l.jsxs("div",{className:"nc-wiz",children:[l.jsx("div",{className:"nc-wiz-head",children:l.jsx("b",{children:p("device-name-ask-title")})}),l.jsxs("div",{className:"nc-wiz-body",children:[l.jsx("p",{className:"nc-wiz-done",children:p("device-name-ask-text")}),l.jsxs("label",{className:"nc-field",children:[l.jsx("span",{children:p("device-name-label")}),l.jsx("input",{value:i,onChange:g=>a(g.target.value),maxLength:64,"data-testid":"device-name-input"})]}),l.jsxs("div",{className:"nc-sheet-actions",children:[l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:c,onClick:s,children:p("device-name-later")}),l.jsx("button",{type:"button",className:"nc-btn primary",disabled:c||!i.trim(),onClick:v,children:p("device-name-save")})]})]}),h&&l.jsx("div",{className:"nc-err",children:h})]})})}const f6=50;function p6(t){if(Number.isFinite(t))return t;const e=typeof t=="string"?Date.parse(t):NaN;return Number.isFinite(e)?e:0}function m6(t,e){return`${String(t)}|${String(e)}`}function HS(t,e){if(!t||typeof t!="object"||t.type!=="notify"||!t.eventId)return null;const n=typeof t.title=="string"?t.title:"",s=typeof t.body=="string"?t.body:"";return!n&&!s?null:{key:m6(e,t.eventId),ownerId:String(e),eventId:String(t.eventId),title:n,body:s,urgency:t.urgency==="high"?"high":"normal",ts:p6(t.ts)}}function US(t){return[...t].sort((e,n)=>n.ts-e.ts).slice(0,f6)}function v6(t,e,n){const s=new Map;for(const i of t||[])s.set(i.key,i);for(const i of e||[])i&&s.set(i.key,i);return[...s.values()]}function g6(t,e){if(typeof EventSource>"u"||!t)return()=>{};const n=new EventSource(`/api/events?token=${encodeURIComponent(t)}`);return n.onmessage=s=>{try{const i=JSON.parse(s.data);i&&typeof i=="object"&&typeof i.type=="string"&&e(i)}catch{}},()=>{try{n.close()}catch{}}}const _6=6e3,y6=12e3,Pi=(t,e,n)=>`${e||""}:${n||t}`,w6=(t,e)=>{const n=t&&t[e];return n?n.stale===!0||n.error===!0?"degraded":"live":"missing"},b6=600*1e3,Mv=new Map;function S6(t){Mv.set(t,Date.now())}function Gk(t){const e=Pi(t.id,t.ownerId,t.ownerAskId),n=Mv.get(e);return n===void 0?!1:Date.now()-n>b6?(Mv.delete(e),!1):!0}function Xk(t,e){const n=new Set(t.map(i=>Pi(i.id,i.ownerId,i.ownerAskId))),s=(e||[]).filter(i=>i&&i.id&&!n.has(Pi(i.id,i.ownerId,i.ownerAskId))&&!Gk(i));return s.length?[...t,...s]:t}function x6(t,e){const n=Xk([],t.filter(a=>a.imported)),s=new Set(n.map(a=>Pi(a.id,a.ownerId,a.ownerAskId)));return[...(e||[]).filter(a=>a&&a.id&&!s.has(Pi(a.id,a.ownerId,a.ownerAskId))&&!Gk(a)),...n]}function C6({n:t,onClose:e}){return l.jsxs("div",{className:`nc-ntf-toast${t.urgency==="high"?" high":""}`,role:"status","aria-live":"polite",children:[l.jsxs("div",{className:"nc-ntf-toast-txt",children:[l.jsx("b",{children:t.title}),t.body&&l.jsx("small",{children:t.body}),t.session&&l.jsx("span",{className:"nc-ntf-from",children:t.session}),t.ownerId&&l.jsx("span",{className:"nc-ntf-from",children:p("feed-owner")})]}),l.jsx("button",{type:"button",className:"nc-ntf-x",onClick:e,title:p("close"),children:l.jsx(Dt,{name:"x",size:14})})]})}function k6({ask:t,token:e,onAnswered:n,onDismiss:s,askReplyAccess:i=!1,feedViewState:a="live",initialUncertainRid:c=null}){const[u,h]=w.useState(""),[f,v]=w.useState(!1),[g,_]=w.useState(null),[b,S]=w.useState(!1),[E,C]=w.useState(c),[N,k]=w.useState(!1),[I,L]=w.useState(!1),H=async Y=>{const G=String(Y||"").trim();if(!(!G||f)){_(null),v(!0);try{if(t.ownerId){const Z=t.ownerAskId||t.id,q=await z5(e,{ownerId:t.ownerId,askId:Z,text:G});if(q&&q.uncertain){C(q.originalRequestId||null),L(!q.originalRequestId);return}n(t.id,t.ownerId)}else await B5(e,t.id,G),n(t.id)}catch(Z){_(String(Z.message||Z))}v(!1)}},z=async()=>{if(!b&&!E){_(null),S(!0);try{t.ownerId?await U5(e,{ownerId:t.ownerId,askId:t.ownerAskId||t.id}):await $5(e,t.id),S6(Pi(t.id,t.ownerId,t.ownerAskId)),s(t.id,t.ownerId)}catch(Y){_(String(Y&&Y.message||Y))}S(!1)}},V=p(E?"ask-uncertain":a==="degraded"?"ask-dismiss-stale":"ask-dismiss");return l.jsxs("div",{className:"nc-ask-card",children:[l.jsxs("div",{className:"nc-ask-head",children:[l.jsx("span",{className:"nc-ntf-from",children:t.session}),t.ownerId&&l.jsx("span",{className:"nc-ntf-from",children:p("feed-owner")}),l.jsxs("code",{className:"nc-ask-id",children:["#",t.id]}),l.jsx("button",{type:"button",className:"nc-ask-dismiss",title:V,"aria-label":V,disabled:b||!!E||!!t.ownerId&&i===!1,onClick:z,children:l.jsx(Dt,{name:"x",size:14})})]}),l.jsx("div",{className:"nc-ask-q",children:t.question}),t.ownerId&&i===!1&&l.jsx("small",{className:"nc-set-hint",children:p(a==="live"?"ask-remote-readonly":"ask-remote-no-feed")}),t.ownerId&&i!==!1&&a==="degraded"&&l.jsx("small",{className:"nc-set-hint",children:p("ask-feed-stale")}),(E||I)&&l.jsxs(l.Fragment,{children:[l.jsx("div",{className:"nc-err",children:p("ask-uncertain")}),I&&!E&&l.jsx("div",{className:"nc-err",children:p("ask-reconcile")}),l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:N,onClick:async()=>{k(!0);try{const Y=await F5(e,{ownerId:t.ownerId,askId:t.ownerAskId||t.id,requestId:E});Y&&(Y.state==="committed"||Y.state==="failed")&&s(t.id,t.ownerId)}finally{k(!1)}},children:p("ask-verify")})]}),(!t.ownerId||i===!0)&&!E&&!I&&l.jsxs(l.Fragment,{children:[Array.isArray(t.options)&&t.options.length>0&&l.jsx("div",{className:"nc-ask-opts",children:t.options.map(Y=>l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:f,onClick:()=>H(Y),children:Y},Y))}),l.jsxs("div",{className:"nc-ask-reply",children:[l.jsx("textarea",{rows:2,placeholder:p("ask-reply-ph"),value:u,disabled:f,onChange:Y=>h(Y.target.value)}),l.jsx("button",{type:"button",className:"nc-btn primary",disabled:f||!u.trim(),onClick:()=>H(u),children:p("send")})]})]}),g&&l.jsx("div",{className:"nc-err",children:g})]})}function E6({token:t}){const[e]=qn(),[n]=Fk(),[s,i]=w.useState([]),[a,c]=w.useState([]),[u,h]=w.useState([]),[f,v]=w.useState(()=>{try{return/(?:^|[#&])ask=/.test(location.hash)}catch{return!1}}),g=w.useRef(0),_=w.useRef(null);_.current||(_.current=PD());const b=w.useRef({enabled:n,lang:e});b.current={enabled:n,lang:e};const S=w.useCallback(V=>{i(Y=>Y.filter(G=>G.key!==V))},[]),E=w.useCallback(V=>{const Y=`t${g.current+=1}`;i(Z=>[...Z.slice(-3),{...V,key:Y}]),setTimeout(()=>S(Y),V.urgency==="high"?y6:_6);const G=b.current;if(G.enabled)try{_.current.enqueue(V,RD(V,G.lang))}catch{}},[S]);w.useEffect(()=>{n||_.current.stop()},[n]),w.useEffect(()=>{const V=()=>{(document.visibilityState!=="visible"||!document.hasFocus())&&_.current.stop()},Y=()=>_.current.stop();return document.addEventListener("visibilitychange",V),window.addEventListener("blur",V),window.addEventListener(Cv,Y),()=>{document.removeEventListener("visibilitychange",V),window.removeEventListener("blur",V),window.removeEventListener(Cv,Y),typeof _.current.dispose=="function"?_.current.dispose():_.current.stop()}},[]);const C=(V,Y)=>c(G=>G.filter(Z=>Pi(Z.id,Z.ownerId)!==Pi(V,Y)));w.useEffect(()=>{if(!t)return;let V=!1;O5(t).then(G=>{V||c(Z=>x6(Z,G.asks))}).catch(()=>{});const Y=g6(t,G=>{if(G.type==="notify"&&G.ownerId&&G.eventId){const Z=HS(G,G.ownerId);if(!Z)return;h(q=>US(v6(q,[Z],null)))}if(G.type==="notify")E(G);else if(G.type==="ask"&&G.ask&&G.ask.id){const Z=Pi(G.ask.id,G.ask.ownerId);c(q=>q.some(T=>Pi(T.id,T.ownerId)===Z)?q:[...q,G.ask])}else(G.type==="ask-answered"&&G.id||G.type==="ask-dismissed"&&G.id)&&C(G.id,G.ownerId)});return()=>{V=!0,Y()}},[t,E]);const[N,k]=w.useState({});w.useEffect(()=>{if(!t)return;let V=!0;return H5(t).then(Y=>{if(!V)return;const G={};for(const Z of Y&&Y.attempts||[])Z&&Z.state==="uncertain"&&Z.ownerId&&Z.askId&&Z.requestId&&(G[Z.ownerId+"|"+Z.askId]=Z.requestId);k(G)}).catch(()=>{}),()=>{V=!1}},[t]);const[I,L]=w.useState({}),[H,z]=w.useState({});return w.useEffect(()=>{let V=!0;return W5(t).then(Y=>{if(!V)return;const G={},Z={},q=[],T=new Map,P=new Set;for(const D of Y&&Y.views||[]){G[D.ownerId]=D.askReplyAccess===!0,Z[D.ownerId]={stale:D.stale===!0,error:!!D.lastError},P.add(D.ownerId);for(const j of D.asks||[])j&&j.id&&q.push({...j,ownerId:D.ownerId,imported:!0});for(const j of D.notifications||[]){const O=HS(j,D.ownerId);O&&T.set(O.key,O)}}L(G),z(Z),q.length&&c(D=>Xk(D,q)),h(D=>{const j=[];for(const O of D)P.has(O.ownerId)&&j.push(O);for(const O of T.values())j.push({...O,key:O.key});return US(j)})}).catch(()=>{}),()=>{V=!1}},[t]),l.jsxs(l.Fragment,{children:[s.length>0&&l.jsx("div",{className:"nc-ntf-toasts",children:s.map(V=>l.jsx(C6,{n:V,onClose:()=>S(V.key)},V.key))}),(a.length>0||u.length>0)&&!f&&l.jsxs("button",{type:"button",className:"nc-ask-badge",onClick:()=>v(!0),title:p("asks-title"),children:["? ",l.jsx("span",{className:"nc-ask-count",children:a.length+u.length})]}),(a.length>0||u.length>0)&&f&&l.jsxs("div",{className:"nc-ask-panel",children:[l.jsxs("div",{className:"nc-ask-panel-head",children:[l.jsx("b",{children:p("asks-title")}),l.jsx("span",{className:"nc-ask-count",children:a.length}),l.jsx("button",{type:"button",className:"nc-ntf-x",onClick:()=>v(!1),title:p("close"),children:l.jsx(Dt,{name:"x",size:16})})]}),l.jsxs("div",{className:"nc-ask-panel-body",children:[a.map(V=>l.jsx(k6,{ask:V,token:t,askReplyAccess:!V.ownerId||I[V.ownerId]===!0,feedViewState:V.ownerId?w6(H,V.ownerId):"live",initialUncertainRid:V.ownerId&&N[V.ownerId+"|"+(V.ownerAskId||V.id)]||null,onAnswered:C,onDismiss:C},Pi(V.id,V.ownerId))),u.length>0&&l.jsxs("div",{className:"nc-remote-notices",children:[l.jsx("div",{className:"nc-remote-notices-head",children:l.jsx("b",{children:p("remote-notices-title")})}),u.map(V=>l.jsxs("div",{className:"nc-remote-notice"+(V.urgency==="high"?" nc-remote-notice-high":""),children:[V.title?l.jsx("b",{children:V.title}):null,V.body?l.jsx("div",{children:V.body}):null,l.jsxs("div",{className:"nc-remote-notice-meta",children:[V.ownerId.slice(0,8)," · ",new Date(V.ts||Date.now()).toLocaleString()]})]},V.key))]})]})]})]})}const Jk="nc_fontsize",Qk=9,Zk=24;function Tv(t=globalThis.localStorage){const e=Number(t.getItem(Jk));return e>=Qk&&e<=Zk?e:13}function e2(t,e=globalThis.localStorage){const n=Math.max(Qk,Math.min(Zk,t));return e.setItem(Jk,String(n)),n}const N6=4e3;async function L6(t){const e=await bn("/api/sessions",t);if((e==null?void 0:e.ok)===!1)throw new Error(`HTTP ${e.status}`);const n=await e.json();if(!Array.isArray(n==null?void 0:n.sessions))throw new Error("invalid sessions payload");return n.sessions}async function Jp(t,e=[]){var u;const[n,s]=await Promise.allSettled([e.length?Fv(t,e):L6(t),Cr(t,e)]),i=n.status==="fulfilled"&&Array.isArray((u=n.value)==null?void 0:u.sessions)?n.value.sessions:Array.isArray(n.value)?n.value:null,a=s.status==="fulfilled"?s.value:null,c=(a==null?void 0:a.available)===!0&&Array.isArray(a.cells)?a.cells:null;return{sessions:i,cells:c,fresh:Array.isArray(i)&&Array.isArray(c)}}function t2(t,e,n){return n===!0&&(t==null?void 0:t.degraded)!==!0&&(t==null?void 0:t.active)===!0&&t.tmux!==!1&&!!t.tmuxSession&&(e||[]).some(s=>(s==null?void 0:s.name)===t.tmuxSession)}function R6(t){const e=new Map((t.sessions||[]).map(i=>[i.name,i])),n=[],s=(i,a,c,u=[],h="")=>{const f=new Map((a||[]).map(v=>[v.name,v]));for(const v of i||[]){const g=f.get(v.tmuxSession)||{},_=th(v,g),b=t2(v,a,c);n.push({key:Wa(u,v.tmuxSession||v.cell),session:v.tmuxSession,route:u,cellName:v.cell,label:v.cell,node:u.length?u.join("/"):"",nodeLabel:h,live:b,selectable:b,verified:c===!0,working:_.working,degraded:!!v.degraded,active:v.active===!0,activity:g.activity||v.activity||0,subtitle:_.subtitle,preview:g.preview||v.preview||"",telemetry:g.telemetry||null,panelUrl:v.panelUrl||""})}};s(t.cells,[...e.values()],t.localFresh===!0);for(const i of t.nodeGroups||[]){const a=Array.isArray(i.route)?i.route:[];i.kind==="vl"||!a.length||s(i.cells,i.sessions,i.switcherFresh===!0,a,i.label||i.name||"")}return n}function A6(t){const e=new Map,n=Array.isArray(t.sessions)?t.sessions:[],s=Array.isArray(t.cells)?t.cells:[],i=new Map(n.map(c=>[c.name,c])),a=new Set(s.map(c=>c.tmuxSession).filter(Boolean));e.set("local",_g(s,n.filter(c=>!a.has(c.name)),i));for(const c of t.nodeGroups||[]){const u=Array.isArray(c.route)?c.route:[];if(c.kind==="vl"||!u.length)continue;const h=Array.isArray(c.cells)?c.cells:[],f=Array.isArray(c.sessions)?c.sessions:[],v=new Set(h.map(g=>g.tmuxSession).filter(Boolean));e.set(u.join("/"),hc({...c,route:u,cells:h,sessions:f,unmanaged:f.filter(g=>!v.has(g.name))}).rawItems)}return e}function j6(t,e,n,s){return[...new Set(t.map(a=>a.node||"local"))].flatMap(a=>{const c=t.filter(v=>(v.node||"local")===a),u=new Map((e.get(a)||[]).map(v=>[v.key,v])),h=new Map(c.map(v=>[v.key,v])),f=c.map(v=>{const g=u.get(v.key);return{...v,label:(g==null?void 0:g.label)||v.label,live:(g==null?void 0:g.live)??v.live,fresh:(g==null?void 0:g.fresh)===!0,activity:(g==null?void 0:g.activity)??v.activity}});return co(f,n,"all",Ii(s,a)).map(v=>h.get(v.key))})}function M6({token:t,current:e,onPick:n,onClose:s,panelPort:i=0,nodePanelPorts:a={},localNodeLabel:c="",hostByRoute:u={},onDesignateCell:h,onClearHostCell:f,onLiveHostApplied:v,sideKey:g=null,onToggleSide:_,pollMs:b=N6}){const[S,E]=w.useState(E0),[C,N]=w.useState(!1),[k,I]=w.useState(!1),[L,H]=w.useState(""),[z,V]=w.useState(null),Y="stream",[G,Z]=w.useState(Tv),q=U=>Z(Q=>e2(Q+U)),[T,P]=w.useState(null),[D,j]=w.useState(!1),[O,A]=w.useState(""),M=w.useRef(null),R=w.useRef(null),F=w.useMemo(()=>R6(S),[S]),$=w.useMemo(()=>A6(S),[S]),{pins:K,orders:oe,togglePin:ce,removePin:ne,pinError:Le,canMoveRoster:Ee,moveRoster:pe,stepRoster:Re}=fg(),de=w.useMemo(()=>j6(F,$,K,oe),[F,$,K,oe]),fe=w.useMemo(()=>C?de:de.filter(U=>U.selectable||U.degraded&&U.active),[de,C]),ke=w.useMemo(()=>z?fe.find(U=>U.key===z&&U.selectable):null,[fe,z]);w.useEffect(()=>{z&&!fe.some(U=>U.key===z&&U.selectable)&&V(null)},[fe,z]);const we=w.useMemo(()=>T?F.find(U=>U.key===T.key):null,[F,T]),ge=!!(T&&we);w.useEffect(()=>{Le&&Le.message&&H(Le.message)},[Le]),w.useEffect(()=>{var X;const U=document.activeElement;(X=R.current)==null||X.focus();const Q=_e=>{_e.key==="Escape"&&!ge&&s()};return document.addEventListener("keydown",Q),()=>{var _e;document.removeEventListener("keydown",Q),(_e=U==null?void 0:U.focus)==null||_e.call(U)}},[s,ge]),w.useEffect(()=>{let U=!0,Q=!1;const X=async()=>{if(Q)return;Q=!0;const me=E0(),tt=Array.isArray(me.nodeGroups)?me.nodeGroups:[],ie=Jp(t),Pe=mt=>mt.kind!=="vl"&&Array.isArray(mt.route)&&mt.route.length>0,ut=await Promise.all(tt.filter(Pe).map(async mt=>({group:mt,result:await Jp(t,mt.route)}))),yt=await ie;if(!U)return;const St=new Map(ut.map(({group:mt,result:qt})=>[JSON.stringify(mt.route||[]),qt])),Pt=tt.map(mt=>{if(!Pe(mt))return{...mt,switcherFresh:!1};const qt=St.get(JSON.stringify(mt.route||[]));return qt?{...mt,sessions:qt.sessions||mt.sessions||[],cells:qt.cells||mt.cells||[],switcherFresh:qt.fresh}:{...mt,switcherFresh:!1}}),pt=FC({...me,sessions:yt.sessions||me.sessions||[],cells:yt.cells||me.cells||[],localFresh:yt.fresh,nodeGroups:Pt,refreshedAt:Date.now()});E(pt),I(!0),Q=!1};X();const _e=setInterval(X,b);return()=>{U=!1,clearInterval(_e)}},[t,b]);const[Ie,Ae]=w.useState(""),Te={getLiveHost:U=>Ud(t,U),designateHostCell:(U,Q,X)=>Wd(t,U,Q,X),clearHostCell:(U,Q)=>qd(t,U,Q)},J=U=>(u[ks(U)]||{}).hostCell||null,Se=async(U,Q)=>{Ae(U.key);const X=await Kd({action:Q?"remove":"use",cellId:U.cellName,route:U.route||[],api:Te});Ae(""),H(p(X.messageKey).replace("{cell}",X.hostCell||U.cellName)),X.ok&&v&&v({route:U.route||[],hostCell:X.hostCell,revision:X.revision})},De=U=>U.degraded?p("cell-degraded"):U.verified?U.selectable?U.working?p("cell-working"):p("cell-idle"):p("cell-off"):p("cell-switcher-not-confirmed"),Me=async U=>{if(H(""),!U.selectable){H(U.verified?p("cell-switcher-not-active"):p("cell-switcher-not-confirmed"));return}A(U.key);try{const Q=await Jp(t,U.route),X=(Q.cells||[]).find(_e=>(_e==null?void 0:_e.cell)===U.cellName&&(_e==null?void 0:_e.tmuxSession)===U.session);if(Q.fresh!==!0){H(p("cell-switcher-verify-failed"));return}if(!t2(X,Q.sessions,Q.fresh)){H(p("cell-switcher-not-active"));return}n({session:U.session,...U.node?{node:U.node}:{},cellName:U.cellName}),s()}catch{H(p("cell-switcher-verify-failed"))}finally{A("")}},Ve=U=>{if(!U.selectable){Me(U);return}if(z===U.key){Me(U);return}V(U.key)},Qe=w.useRef(null),dt=8,at=U=>{const Q=Qe.current;if(U.isPrimary===!1){Q&&Q.state==="open"&&(Q.state="invalid");return}if(Q&&Q.state==="open"&&(Q.id!==U.pointerId||Q.row!==U.currentTarget)){Q.state="invalid";return}Qe.current={id:U.pointerId,row:U.currentTarget,x:U.clientX,y:U.clientY,maxDelta:0,state:"open"}},bt=U=>{const Q=Qe.current;!Q||Q.state!=="open"||Q.id!==U.pointerId||(Q.maxDelta=Math.max(Q.maxDelta,Math.hypot(U.clientX-Q.x,U.clientY-Q.y)),Q.maxDelta>dt&&(Q.state="invalid"))},st=U=>{const Q=Qe.current;!Q||Q.id!==U.pointerId||Q.state!=="open"||(Q.state=Q.maxDelta<=dt?"tap":"invalid")},ft=U=>{const Q=Qe.current;Q&&Q.id===U.pointerId&&(Q.state="invalid")},ot=U=>{const Q=Qe.current;return Qe.current=null,U.detail===0?!0:!Q||Q.state==="invalid"||Q.row!==U.currentTarget?!1:Math.hypot(U.clientX-Q.x,U.clientY-Q.y)<=dt},Rt=U=>({onToggleLive:()=>Se(U,J(U.route||[])===U.cellName),onTogglePin:()=>pg({view:eh({item:{key:U.key,value:{cell:U.cellName}},pins:K,hostByRoute:u,route:U.route||[]}),itemKey:U.key,togglePin:ce,removePin:ne})});return l.jsxs("div",{className:"nc-cell-switcher-backdrop",onClick:s,children:[ke&&l.jsxs("div",{className:"nc-cell-switcher-anteprima","data-testid":"cell-switcher-anteprima",onClick:U=>U.stopPropagation(),children:[l.jsxs("div",{className:"nc-cell-switcher-anteprima-testa",children:[l.jsxs("b",{children:[p("cell-switcher-preview-word")," ",ke.cellName]}),l.jsx("small",{children:p("cell-switcher-preview-readonly")}),l.jsxs("span",{className:"nc-cell-switcher-anteprima-zoom",children:[l.jsx("button",{type:"button",onClick:()=>q(-1),title:p("zoom-out"),"aria-label":p("zoom-out"),children:"−"}),l.jsxs("span",{"data-testid":"cell-switcher-fontsize",children:[G," px"]}),l.jsx("button",{type:"button",onClick:()=>q(1),title:p("zoom-in"),"aria-label":p("zoom-in"),children:"+"})]})]}),l.jsx(og,{row:ke,token:t,source:Y,chrome:!1,panelPort:wc(ke.route||[],a,i),liveHost:Ka({liveHost:u[ks(ke.route||[])],cells:S.cells||[]}),onLiveHostApplied:v,fontSize:G,readOnly:!0})]}),l.jsxs("aside",{ref:M,className:`nc-cell-switcher${ke?" with-anteprima":""}`,role:"dialog","aria-label":p("fleet-cells"),tabIndex:-1,onClick:U=>U.stopPropagation(),children:[l.jsxs("div",{className:"nc-cell-switcher-controls",children:[l.jsx("b",{children:p("cell-switcher-title")}),c&&l.jsx("small",{className:"nc-cell-switcher-node",children:c}),l.jsxs("div",{className:"nc-cell-switcher-filter",role:"group","aria-label":p("cell-switcher-filter"),children:[l.jsx("button",{type:"button",className:C?"":"on","aria-pressed":!C,onClick:()=>{H(""),N(!1)},children:p("cell-switcher-show-active")}),l.jsx("button",{type:"button",className:C?"on":"","aria-pressed":C,onClick:()=>{H(""),N(!0)},children:p("cell-switcher-show-all")})]}),l.jsx("button",{type:"button",className:`nc-cell-switcher-reorder${D?" on":""}`,"aria-pressed":D,title:p("reorder-help"),"aria-label":p("reorder"),onClick:()=>{H(""),j(U=>!U)},children:"↕"}),l.jsx("button",{ref:R,type:"button",className:"nc-cell-switcher-close","aria-label":p("cell-switcher-close"),title:p("cell-switcher-close"),onClick:s,children:"×"})]}),!ke&&l.jsx("div",{className:"nc-cell-switcher-hint",children:p("cell-switcher-tap-hint")}),l.jsxs("div",{className:"nc-cell-switcher-list",children:[(()=>{const U=Ka({liveHost:u[ks([])],cells:S.cells||[]});if(!U||!U.cell)return null;const{modeKey:Q}=HT(U);return l.jsx("div",{className:"nc-cell-switcher-live-strip","data-testid":"cell-switcher-live-strip",children:p("cell-switcher-live-strip").replace("{cell}",U.cell).replace("{mode}",p(Q||"live-host-mode-unknown"))})})(),!k&&l.jsx("div",{className:"nc-empty",role:"status",children:p("cell-switcher-refreshing")}),k&&fe.length===0&&l.jsx("div",{className:"nc-empty",role:"status",children:p("cell-switcher-empty-active")}),fe.map((U,Q)=>{const X=(e==null?void 0:e.session)===U.session&&((e==null?void 0:e.node)||"")===U.node,_e=!!T&&T.key===U.key,me=g!=null&&g===U.key,tt=De(U),ie=ev(p,U.activity),Pe=tv(p,U.telemetry),ut=[ie,Pe].filter(Boolean).join(" · "),yt=U.node||"local",St=Q>0?fe[Q-1].node||"local":null,Pt=yt!==St,pt=$.get(yt)||F.filter(mt=>(mt.node||"local")===yt);return l.jsxs(w.Fragment,{children:[Pt&&l.jsx("div",{className:"nc-cell-switcher-position",children:p("cell-switcher-group").replace("{node}",U.nodeLabel||c||p("cell-switcher-group-local"))}),l.jsxs("div",{className:`nc-cell-switcher-row${X?" current":""}${z===U.key?" selected":""}${me?" side":""}${U.selectable?"":" off"}`,"data-roster-key":U.key,"data-position":yt,children:[D&&l.jsx(Gi,{position:yt,itemKey:U.key,label:U.cellName,canMove:Ee,onMove:(mt,qt)=>pe(yt,mt,qt,pt),onStep:mt=>Re(yt,U.key,mt,pt)}),l.jsx("span",{className:"nc-cell-switcher-peek",children:l.jsx("span",{className:`nc-cell-switcher-dot${U.degraded?" warn":U.live?` on${U.working?" working":""}`:""}`})}),l.jsx("button",{type:"button",className:"nc-cell-switcher-row-select","aria-current":X?"true":void 0,"aria-disabled":!U.selectable,"data-selected":z===U.key?"true":void 0,disabled:O===U.key,onPointerDown:at,onPointerMove:bt,onPointerUp:st,onPointerCancel:ft,onClick:mt=>{ot(mt)&&Ve(U)},children:l.jsxs("span",{className:"nc-cell-switcher-copy",children:[l.jsxs("span",{className:"nc-cell-switcher-nameline",children:[l.jsx("b",{children:U.cellName}),X&&l.jsx("span",{className:"nc-cell-switcher-here",children:p("cell-switcher-here")}),z===U.key&&l.jsx("span",{className:"nc-cell-switcher-taptwo",children:p("cell-switcher-two-taps")})]}),l.jsxs("span",{className:"nc-cell-switcher-stateline",children:[l.jsx("small",{className:"nc-cell-switcher-state",children:tt}),ut&&l.jsx("small",{className:"nc-cell-switcher-telemetry",children:ut})]})]})}),_&&l.jsx("button",{type:"button",className:`nc-cell-switcher-side${me?" on":""}`,title:p(me?"cell-switcher-side-remove":"cell-switcher-side-add"),"aria-label":p(me?"cell-switcher-side-remove":"cell-switcher-side-add"),"aria-pressed":me?"true":"false",disabled:X||!U.selectable,onClick:mt=>{mt.stopPropagation(),!X&&U.selectable&&_(U)},children:l.jsxs("svg",{viewBox:"0 0 24 24",width:"20",height:"20","aria-hidden":"true",focusable:"false",children:[l.jsx("rect",{x:"3.5",y:"5.5",width:"17",height:"13",rx:"1.5"}),l.jsx("line",{x1:"3.5",y1:"12",x2:"20.5",y2:"12"})]})}),l.jsx("button",{type:"button",className:`nc-cell-switcher-menu${_e?" on":""}`,title:`${p("cell-actions-open")}: ${U.cellName}`,"aria-label":`${p("cell-actions-open")}: ${U.cellName}`,"aria-haspopup":"menu","aria-expanded":_e?"true":"false",onClick:mt=>{mt.stopPropagation(),P({key:U.key})},children:"⋯"})]})]},U.key)})]}),L&&l.jsx("div",{className:"nc-cell-switcher-notice",role:"status",children:L}),ge&&(()=>{const U=we,Q=mg({...oo({item:{key:U.key,value:{cell:U.cellName}},cellName:U.cellName,route:U.route||[],pins:K,hostByRoute:u}),canBoot:!1,alive:U.selectable,handlers:Rt(U)});return l.jsx(vg,{cellName:U.cellName,items:Q,busy:Ie===U.key,onClose:()=>P(null)})})()]})]})}function WS(){let t=0,e=!1;return{begin(){return e?null:(e=!0,t+=1,t)},end(n){n===t&&(e=!1)},reset(){t+=1,e=!1},isCurrent(n){return n!==null&&n===t}}}const T6=2e3;function P6(t){if(t.kind==="gap")return`${p("vl-events-gap")} ${t.count||"?"}`;if(t.kind==="truncate")return p("vl-events-truncated");if(t.kind==="turn_end")return p("vl-events-turn-end");if(t.kind==="done")return p("vl-events-done");if(t.kind==="writer_epoch")return p("vl-events-writer-epoch");if(t.kind==="tool_start")return`${p("vl-events-tool")} ${t.name||""}`.trim();if(t.kind==="tool_end"){const e=t.isError?p("vl-events-tool-failed"):p("vl-events-tool-ok");return`${p("vl-events-tool")} ${t.name||""} — ${e}`.trim()}return t.kind==="usage"?t.text||p("vl-events-usage"):t.text||""}function I6({token:t,nodeId:e,route:n=[]}){const[s,i]=w.useState([]),[a,c]=w.useState(!1),u=w.useRef(0),h=w.useRef(!1);return w.useEffect(()=>{let f=!0;u.current=0,h.current=!1,i([]);const v=async()=>{if(!h.current){h.current=!0;try{const b=await p5(t,e,u.current,n);if(!f)return;c(!1);const E=(Array.isArray(b==null?void 0:b.events)?b.events:[]).filter(C=>Number.isSafeInteger(C==null?void 0:C.seq)&&C.seq>u.current);E.length&&(i(C=>C.concat(E).slice(-500)),u.current=E[E.length-1].seq),Number.isSafeInteger(b==null?void 0:b.cursor)&&b.cursor>u.current&&(u.current=b.cursor)}catch{f&&c(!0)}finally{h.current=!1}}},g=()=>{v().catch(()=>{})};g();const _=setInterval(g,T6);return()=>{f=!1,clearInterval(_)}},[t,e,JSON.stringify(n)]),l.jsxs("div",{className:"nc-vl-events",children:[a&&l.jsx("div",{className:"nc-set-hint nc-vl-events-stale",children:p("vl-events-stale")}),s.length===0&&!a&&l.jsx("small",{className:"nc-set-hint","data-testid":"vl-events-empty",children:p("vl-events-empty")}),s.length>0&&l.jsx("ol",{className:"nc-vl-events-list",children:s.map(f=>l.jsx("li",{"data-testid":`vl-ev-${f.seq}`,className:`nc-vl-ev nc-vl-ev-${f.kind}${f.isError?" error":""}${f.kind==="gap"?" gap":""}`,children:P6(f)},`${f.seq}-${f.kind}`))})]})}function qS({peer:t,token:e,onBack:n}){var s;return qn(),t?l.jsxs("section",{className:"nc-vl-session-view",children:[l.jsxs("header",{className:"nc-bar nc-bar-single",children:[l.jsxs("button",{onClick:n,title:p("back"),children:[l.jsx(Dt,{name:"chevronLeft",size:18}),l.jsx("span",{className:"nc-bar-label",children:p("back")})]}),l.jsxs("span",{className:"nc-bar-center",children:[l.jsx("b",{title:t.label,children:t.label}),((s=t.session)==null?void 0:s.profile)&&l.jsxs("small",{className:"nc-bar-sub",children:[t.session.profile," · ",p("vl-events-title")]})]}),l.jsx("span",{className:"nc-bar-right"})]}),l.jsx("div",{className:"nc-vl-session-body",children:l.jsx(I6,{token:e,nodeId:t.nodeId,route:t.route||[]})})]}):null}const Od="nc_dual_side";function Pv(t,e){return!t||!e?!1:t.session===e.session&&(t.node||"")===(e.node||"")}function D6(t,e,n){return!n||!n.session||t&&Pv(t,n)?e:e&&Pv(e,n)?null:{session:n.session,...n.node?{node:n.node}:{},...n.ownerId?{ownerId:n.ownerId}:{}}}function O6(){try{const t=JSON.parse(localStorage.getItem(Od)||"null");return!t||!t.main||!t.side||!t.main.session||!t.side.session?null:t}catch{return null}}function B6(t,e){try{if(!t||!e||!t.session||!e.session){localStorage.removeItem(Od);return}const n=s=>({session:s.session,...s.node?{node:s.node}:{}});localStorage.setItem(Od,JSON.stringify({main:n(t),side:n(e)}))}catch{}}function KS(){try{localStorage.removeItem(Od)}catch{}}const $6=.2;function td(t){return Math.max($6,t)}function z6(){try{if(typeof matchMedia=="function"&&matchMedia("(pointer: coarse)").matches)return!0}catch{}try{return Number(globalThis.navigator&&globalThis.navigator.maxTouchPoints)>0}catch{return!1}}function F6({onSubmit:t,reason:e=""}){qn();const[n,s]=w.useState(""),[i,a]=w.useState(z6),c=n.trim(),u=h=>{h&&h.preventDefault&&h.preventDefault(),c&&t(c,i)};return l.jsxs("form",{className:"nc-auth",onSubmit:u,children:[l.jsx("p",{children:p("auth-prompt")}),e==="invalid"&&l.jsx("p",{className:"nc-auth-error",role:"alert",children:p("auth-invalid")}),l.jsx("input",{type:"text",value:n,placeholder:"token","aria-label":"token",autoComplete:"off",autoCapitalize:"off",autoCorrect:"off",spellCheck:!1,onChange:h=>s(h.target.value)}),l.jsxs("label",{children:[l.jsx("input",{type:"checkbox",checked:i,onChange:h=>a(h.target.checked)})," ",p("remember-device")]}),l.jsx("button",{type:"submit",disabled:!c,children:"ok"})]})}const Qp=t=>_s(Ti(t)).length===0;function Ba(t,e){return Array.isArray(t)?t.flatMap(n=>{var c;const s={session:n.session,height:1,fontSize:n.fontSize};n.node&&(s.node=n.node),n.ownerId&&(s.ownerId=n.ownerId);const i=(c=e({columns:[{width:1,tiles:[s]}]}).columns[0])==null?void 0:c.tiles[0];if(!i)return[];const a={session:i.session,x:n.x,y:n.y,w:n.w,h:n.h,fontSize:n.fontSize};return i.node&&(a.node=i.node),i.ownerId&&(a.ownerId=i.ownerId),[a]}):[]}function VS(t,e){return t.length?t:Array.isArray(e.floating)&&e.floating.length?[]:void 0}function H6(t,e,n,s,i){const a=c=>Ba(c&&c.floating,u=>za(u,s,i));return eP(a(t),a(e),n)}function YS(t,e,n,s,i,a){const c=g=>za(g,i,a),u=g=>Ba(g&&g.floating,c),{grid:h,floating:f}=Ad(n),v=tP(s(h),H6(t,e,f,i,a),{grid:t?c(t.layout):uo(),floating:u(t)},{grid:c(e.layout),floating:u(e)},{grid:h,floating:f});return fv(v.grid,v.floating)}const Zp=t=>Array.isArray(t)?t.join("/"):"",U6="nc-decks-cache-v1",n2=t=>`${U6}:${t}`;function W6(t){if(!t)return[];try{const e=localStorage.getItem(n2(t));if(!e)return[];const n=JSON.parse(e);return Array.isArray(n)&&n.every(s=>s&&typeof s.id=="string"&&typeof s.name=="string")?n:[]}catch{return[]}}function q6(t,e){if(t)try{localStorage.setItem(n2(t),JSON.stringify(e))}catch{}}function K6(t){const e=new Set,n=[];for(const s of Array.isArray(t)?t:[])!s||!Ks.test(String(s.instanceId||""))||!Array.isArray(s.route)||!s.route.length||e.has(s.instanceId)||(e.add(s.instanceId),n.push({instanceId:s.instanceId,route:[...s.route],label:String(s.label||s.name||s.route.join(" › ")),status:s.status||"offline",stale:s.stale===!0}));return n.sort((s,i)=>s.label.localeCompare(i.label))}function Jl(t){return{instanceId:t.ownerId,route:t.ownerRoute||[],label:t.ownerLabel,status:t.available===!1?"offline":"up"}}function Po(t,e,n,s=!1,i=!0){const a=e.instanceId;return{...t,id:qo(s?null:a,t.name),ownerId:a,ownerRoute:s?[]:[...e.route],ownerLabel:s?"Local":e.label,local:s,available:i,ownerTopology:Array.isArray(n)?n:[],layout:bv(t.layout,a,n)}}function V6(t,e,n,s,i=[]){const[a,c]=w.useState([]),[u,h]=w.useState(!1),[f,v]=w.useState("idle"),[g,_]=w.useState(""),[b,S]=w.useState(!1),[E,C]=w.useState(""),N=w.useRef([]),k=w.useRef([]),I=w.useRef(new Map),L=w.useRef(""),H=w.useRef(e),z=w.useRef(n),V=w.useRef(!1),Y=w.useRef(!0),G=w.useRef(""),Z=w.useMemo(()=>K6(i),[i]),q=Z.map(de=>`${de.instanceId}:${Zp(de.route)}`).join("|");k.current=Z,z.current=n,H.current=e,N.current=a;const T=w.useCallback(de=>za(de.layout,L.current,k.current),[]),P=w.useCallback(()=>Yl(H.current,L.current),[]),D=w.useCallback(de=>(Array.isArray(de)?de:[]).find(fe=>fe.id===P()),[P]),j=w.useCallback((de,fe=!0,ke)=>{const we=ke===void 0?P():Yl(ke,L.current),ge=H0(de,Gu()),Ie=N.current.some(Te=>Te.id===we);N.current=ge,c(ge),q6(L.current,ge.map(Te=>{if(!Te.refreshFailedAt)return Te;const J={...Te};return delete J.refreshFailedAt,J}));const Ae=ge.find(Te=>Te.id===we);if(fe&&Ae){Y.current=!0;const Te=fv(T(Ae),Ba(Ae.floating,J=>za(J,L.current,k.current)));s(Te),Ae.local&&_I(Ae.name,Ti(Te))}else Ie&&!Ae&&(Y.current=!0,s(uo()),_("deck non più condiviso dal nodo owner"));pI(ge.filter(Te=>Te.local).map(Te=>Te.name))},[s,T]),O=w.useCallback(async de=>{let fe=await Iu(t);const ke=fe.decks.find(we=>we.name==="main");if(fe.decks.length===1&&ke&&ke.revision===0&&Qp(ke.layout)){const we=fI(),ge=Ti(Sv("main")||uo());if(!Qp(ge)){const Ie=bv(ge,de,[]);fe.decks[0]=await Du(t,"main",Ie,0,[])}for(const Ie of we.filter(Ae=>Ae!=="main"))try{let Ae=await kw(t,Ie,[]);const Te=Ti(Sv(Ie)||uo());Qp(Te)||(Ae=await Du(t,Ie,bv(Te,de,[]),Ae.revision,[]))}catch{}fe=await Iu(t)}return fe},[t]),A=w.useCallback((de,fe)=>{const ke=new Map(fe.map(Ie=>[Ie.id,Ie])),we=new Set,ge=[];for(const Ie of N.current){if(Ie.local||Ie.ownerId!==de.instanceId){ge.push(Ie);continue}const Ae=ke.get(Ie.id);Ae&&(ge.push(Ae),we.add(Ie.id))}for(const Ie of fe)we.has(Ie.id)||ge.push(Ie);j(ge,!1)},[j]),M=w.useCallback(async de=>{try{const[fe,ke]=await Promise.all([Iu(t,de.route),Sw(t,de.route).catch(()=>({nodes:[]}))]);A(de,fe.decks.map(we=>Po(we,de,ke.nodes,!1,!0)))}catch(fe){if(fe&&(fe.status===403||fe.status===404)){A(de,[]);return}const ke=N.current.filter(we=>!we.local&&we.ownerId===de.instanceId).map(we=>({...we,available:!1,stale:!0,refreshFailedAt:Date.now(),ownerRoute:[...de.route],ownerLabel:de.label}));A(de,ke)}},[t,A]),R=w.useCallback(async({migrate:de=!1}={})=>{const fe=await Hv(t,[]),ke=Ks.test(String(fe.instanceId||""))?fe.instanceId:"";if(!ke)throw new Error("instanceId locale non disponibile");L.current=ke,C(ke);const[we,ge]=await Promise.all([de?O(ke):Iu(t),Sw(t,[]).catch(()=>({nodes:[]}))]),Ie={instanceId:ke,route:[],label:"Local"},Ae=we.decks.map(Ve=>Po(Ve,Ie,ge.nodes,!0,!0)),Te=new Map(k.current.map(Ve=>[Ve.instanceId,Ve])),J=N.current.length?N.current:W6(ke),Se=I.current,De=Date.now(),Me=J.filter(Ve=>!Ve.local).flatMap(Ve=>{const Qe=Te.get(Ve.ownerId);if(!Qe){const at=Se.get(Ve.ownerId);return at===void 0?(Se.set(Ve.ownerId,De),[{...Ve,available:!1,stale:!0}]):De-at>mC?[]:[{...Ve,available:!1,stale:!0}]}Se.delete(Ve.ownerId);const dt=Qe.status==="up";return[{...Ve,available:dt?Ve.available!==!1:!1,stale:Qe.stale===!0,ownerRoute:[...Qe.route],ownerLabel:Qe.label}]});return setTimeout(()=>{for(const Ve of Te.values())Ve.status==="up"&&M(Ve)},0),[...Ae,...Me]},[t,O,M,q]);w.useEffect(()=>{if(!t)return;let de=!1;const fe=G.current!==t;return G.current=t,R({migrate:fe}).then(ke=>{if(de)return;const we=D(N.current),ge=D(ke),Ie=ge&&(!we||ge.revision>we.revision||we.available!==ge.available||Zp(we.ownerRoute)!==Zp(ge.ownerRoute));j(ke,fe||!!Ie&&!V.current),h(!0),ge&&_("")}).catch(ke=>{de||(h(!0),_(String(ke.message||ke)))}),()=>{de=!0}},[j,R,q,t,D]);const F=w.useCallback(async(de,fe=!0)=>{if(!u||!V.current)return!0;const ke=de===void 0?P():Yl(de,L.current),we=N.current.find(ge=>ge.id===ke);if(!we)return _(`deck inesistente: ${ke}`),!1;if(we.available===!1)return _(`nodo owner offline: ${we.ownerLabel}`),!1;v("saving");try{const{grid:ge,floating:Ie}=Ad(z.current),Ae=Gl(Ti(ge),we.ownerId,we.ownerTopology),Te=Ba(Ie,De=>Gl(De,we.ownerId,we.ownerTopology)),J=await Du(t,we.name,Ae,we.revision,we.ownerRoute,VS(Te,we)),Se=Po(J,Jl(we),we.ownerTopology,we.local,!0);return j(N.current.map(De=>De.id===ke?Se:De),!1),V.current=!1,v("saved"),_(""),S(!1),setTimeout(()=>v("idle"),1500),!0}catch(ge){if(fe&&ge.status===409&&ge.data&&ge.data.current){const Ie=N.current.find(Ae=>Ae.id===ke);if(Ie){const Ae=Po(ge.data.current,Jl(Ie),Ie.ownerTopology,Ie.local,!0),Te=YS(Ie,Ae,z.current,J=>J,L.current,k.current);return nP(Te,z.current)||(z.current=Te,Y.current=!0,s(Te)),j(N.current.map(J=>J.id===ke?Ae:J),!1),V.current=!0,F(ke,!1)}}return v("error"),_(String(ge.message||ge)),ge.status===409&&S(!0),!1}},[u,t,j,s]),$=w.useCallback(async()=>{try{const de=await R();V.current=!1,S(!1),j(de,!0),_("")}catch(de){_(String(de.message||de))}},[R,j]);w.useEffect(()=>{if(!u)return;const de=Y.current&&!V.current;if(Y.current=!1,de)return;V.current=!0,v("saving");const fe=setTimeout(F,650);return()=>clearTimeout(fe)},[n,u,F]),w.useEffect(()=>{if(!u)return;const de=()=>{if(!V.current)return;const fe=N.current.find(Ae=>Ae.id===P());if(!fe||fe.available===!1)return;const{grid:ke,floating:we}=Ad(z.current),ge=Gl(Ti(ke),fe.ownerId,fe.ownerTopology),Ie=Ba(we,Ae=>Gl(Ae,fe.ownerId,fe.ownerTopology));q5(t,fe.name,ge,fe.revision,fe.ownerRoute,VS(Ie,fe))};return window.addEventListener("pagehide",de),window.addEventListener("beforeunload",de),()=>{window.removeEventListener("pagehide",de),window.removeEventListener("beforeunload",de)}},[u,t,P]),w.useEffect(()=>{if(!u)return;const de=setInterval(async()=>{try{const fe=await R(),ke=D(N.current),we=D(fe),ge=!!(we&&ke&&we.revision>ke.revision),Ie=!!(we&&(!ke||ge||ke.available!==we.available));if(ge&&V.current&&we){const Ae=YS(ke,we,z.current,Te=>rP(T(we),Te),L.current,k.current);j(fe,!1),s(Ae);return}j(fe,Ie&&!V.current)}catch{}},5e3);return()=>clearInterval(de)},[u,R,j,T,s]);const K=w.useCallback(de=>{s(fe=>{const ke=de(fe);return ke!==fe&&(Y.current=!0),ke})},[]),oe=async(de,fe=null)=>{const ke=fe===Xi?N.current.find(Ie=>Ie.local):fe?N.current.find(Ie=>Ie.ownerId===fe):null;if(!ke||ke.available===!1)throw new Error("nodo owner non disponibile");const we=await kw(t,de,ke.ownerRoute),ge=Po(we,Jl(ke),ke.ownerTopology,ke.local,!0);return j([...N.current,ge],!1),ge},ce=async(de,fe)=>{const ke=N.current.find(Te=>Te.id===de);if(!ke)throw new Error("deck inesistente");if(Yl(de,L.current)===P()&&V.current&&!await F(de))throw new Error(`salvataggio di "${ke.name}" fallito: rinomina annullata`);const we=N.current.find(Te=>Te.id===de);if(!we)throw new Error("deck inesistente");const ge=await K5(t,we.name,fe,we.revision,we.ownerRoute),Ie=Po(ge,Jl(we),we.ownerTopology,we.local,!0),Ae=we.local?Xi:we.ownerId;return Sp(vI(Gu(),Ae,de,Ie.id)),j(N.current.map(Te=>Te.id===de?Ie:Te),!1),Ie},ne=async de=>{const fe=N.current.find(we=>we.id===de);if(!fe)throw new Error("deck inesistente");Yl(de,L.current)===P()&&(V.current=!1),await V5(t,fe.name,fe.revision,fe.ownerRoute);const ke=fe.local?Xi:fe.ownerId;Sp(gI(Gu(),ke,de)),j(N.current.filter(we=>we.id!==de),!1)},Le=(de,fe)=>{const ke=N.current.find(J=>J.id===de),we=N.current.find(J=>J.id===fe);if(!ke||!we)return!1;const ge=ke.local?Xi:ke.ownerId,Ie=we.local?Xi:we.ownerId;if(ge!==Ie)return!1;const Ae=N.current.filter(J=>(J.local?Xi:J.ownerId)===ge).map(J=>J.id),Te=Sp(mI(Gu(),ge,de,fe,Ae));return j(H0(N.current,Te),!1),!0},Ee=async(de,fe)=>{const ke=N.current.find(J=>J.id===de);if(!ke)throw new Error("deck inesistente");if(ke.available===!1)throw new Error(`nodo owner offline: ${ke.ownerLabel}`);const we=sk(fe,L.current,k.current);if(!we)throw new Error("riferimento sessione non valido");const ge=T(ke),Ie=Gl(jC(ge,we),ke.ownerId,ke.ownerTopology),Ae=await Du(t,ke.name,Ie,ke.revision,ke.ownerRoute),Te=Po(Ae,Jl(ke),ke.ownerTopology,ke.local,!0);return j(N.current.map(J=>J.id===de?Te:J),!1),Te},pe=w.useCallback(de=>fv(T(de),Ba(de.floating,fe=>za(fe,L.current,k.current))),[T]);return{decks:a,records:a,localNodeId:E,ready:u,saveState:f,error:g,setError:_,conflict:b,reloadCurrent:$,saveNow:F,select:async de=>{if(V.current&&!await F(P()))throw new Error("salvataggio del deck corrente fallito: cambio annullato");const fe=N.current.find(ke=>ke.id===de);if(!fe)throw new Error(`deck inesistente: ${de}`);return V.current=!1,Y.current=!0,pe(fe)},add:oe,rename:ce,remove:ne,reorder:Le,addTileTo:Ee,viewUpdate:K,vistaMaterializzata:pe,localMainId:qo(null,"main"),parseDeckId:Oc}}const Y6="/sw.js",Iv="nc-sw-update";let Rc=null,Bd=!1,$d=null,s2=Object.freeze({needed:!1,kind:null,version:"",browserVersion:""}),i2=!1;function Yg(){typeof window<"u"&&window.dispatchEvent(new Event(Iv))}function Gg(){const t=$d||(Bd?{kind:"reload",version:"",browserVersion:""}:null);s2=Object.freeze({needed:!!t,kind:(t==null?void 0:t.kind)||null,version:(t==null?void 0:t.version)||"",browserVersion:(t==null?void 0:t.browserVersion)||""})}function GS(){return s2}function G6(t){return typeof window>"u"?()=>{}:(window.addEventListener(Iv,t),()=>window.removeEventListener(Iv,t))}function Xg(t){Bd!==t&&(Bd=t,Gg(),Yg())}const nd="nc-auto-reload",zd="nc-reload";function Jg(){try{return typeof location<"u"?location:null}catch{return null}}function r2(){try{return typeof history<"u"?history:null}catch{return null}}function X6(t){const e=t===void 0?Jg():t;if(!e||typeof e.search!="string")return null;try{return new URLSearchParams(e.search).get(zd)}catch{return null}}function J6(t,{location:e,history:n}={}){const s=e===void 0?Jg():e,i=n===void 0?r2():n;if(!s||!i||typeof i.replaceState!="function")return!1;try{const a=new URLSearchParams(s.search||"");return a.set(zd,t),i.replaceState(i.state??null,"",`${s.pathname||"/"}?${a.toString()}${s.hash||""}`),!0}catch{return!1}}function Q6({location:t,history:e}={}){const n=t===void 0?Jg():t,s=e===void 0?r2():e;if(!n||!s||typeof s.replaceState!="function")return!1;try{const i=new URLSearchParams(n.search||"");if(!i.has(zd))return!1;i.delete(zd);const a=i.toString();return s.replaceState(s.state??null,"",`${n.pathname||"/"}${a?`?${a}`:""}${n.hash||""}`),!0}catch{return!1}}const o2="nc-update-dismissed";function a2(){try{return typeof sessionStorage<"u"?sessionStorage:null}catch{return null}}function Z6(t,e,n){return[t,e,n].map(s=>s||"").join("|")}let Dv=null;function e4(t,e,n){const s=n;return t&&e&&t!==e&&t!==s?{kind:"install",version:t,browserVersion:s}:e&&s&&e!==s?{kind:"stale",version:e,browserVersion:s}:null}function t4(t,e){if(!t)return!1;try{return t.getItem(o2)===e}catch{return!1}}function n4(t={}){const e=t.storage===void 0?a2():t.storage;if(Dv&&e)try{e.setItem(o2,Dv)}catch{}Bd=!1,$d=null,Gg(),Yg()}function s4(t,e,n,s={}){const i=s.storage===void 0?a2():s.storage,a=n,c=Z6(t,e,a);Dv=c;const u=e4(t,e,a);let h=t4(i,c)?null:u;if(h&&h.kind==="stale"){const v=`${e}|${a}`,g=X6(s.location)===v;let _=!1;if(!g&&i&&i.getItem(nd)!==v){try{i.setItem(nd,v)}catch{}_=i.getItem(nd)===v}_&&(J6(v,{location:s.location,history:s.history}),(s.applyImpl||l2)(),h=null)}const f=JSON.stringify(h)===JSON.stringify($d);if($d=h,Gg(),f||Yg(),!u){try{i&&i.removeItem(nd)}catch{}Q6({location:s.location,history:s.history})}}const i4=1200;async function XS(t){if(typeof fetch=="function")try{await Promise.race([fetch(t,{cache:"reload"}),new Promise(e=>setTimeout(e,i4))])}catch{}}async function l2(){try{Rc&&await Rc.update()}catch{}typeof location<"u"&&(await XS(location.pathname),await XS("/version.json"),location.reload())}function r4(t){t.addEventListener("statechange",()=>{t.state==="installed"&&navigator.serviceWorker.controller&&Xg(!0)})}function o4(){typeof navigator>"u"||!("serviceWorker"in navigator)||(navigator.serviceWorker.addEventListener("controllerchange",()=>{i2&&location.reload()}),navigator.serviceWorker.register(Y6).then(t=>{Rc=t,t.waiting&&Xg(!0),t.addEventListener("updatefound",()=>{const e=t.installing;e&&r4(e)}),setInterval(()=>{t.update().catch(()=>{})},3600*1e3)}).catch(()=>{}))}function a4(){i2=!0,Xg(!1);const t=Rc&&Rc.waiting;t?(t.postMessage({type:"SKIP_WAITING"}),setTimeout(()=>location.reload(),4e3)):location.reload()}function l4({hash:t="",origin:e="",pathname:n="",search:s=""}={}){const i=String(t||"").replace(/^#/,""),a=`${n||""}${s||""}`;if(!i)return{token:"",pair:"",device:"",nextUrl:a};const c=new URLSearchParams(i),u=c.get("token")||"",h=c.get("device")||"",f=/^[a-f0-9]{32}$/.test(h)?h:"",v=c.get("pair")||"",g=v?`${e||""}${n||""}#pair=${v}`:"";return{token:u,pair:g,device:f,nextUrl:a}}const c2="nc_side_w",JS="nc_side_min",c4=240,QS=new Set(["absent","present","active","unknown"]);function u4(){const t=Number(localStorage.getItem(c2));return t>=180&&t<=480?t:c4}function d4(){const t={token:"",pair:""};try{const{token:e,pair:n,device:s,nextUrl:i}=l4({hash:location.hash,origin:location.origin,pathname:location.pathname,search:location.search});if(e&&(t.token=e,c1(e,{remember:!0})),s&&HD(s),n){t.pair=n;try{sessionStorage.setItem("nc_pair",n)}catch{}}if(location.hash)try{history.replaceState(null,"",i)}catch{}}catch{}if(t.token||(t.token=GE()),!t.pair){const e=sessionStorage.getItem("nc_pair");e&&(t.pair=e)}return t}function ZS(t){try{return Ti(Sv(t))}catch{return uo()}}function e1(t){if(!t)return"";const e=Math.floor(Date.now()/1e3)-t;return e<0||e<60?"ora":e<3600?`${Math.floor(e/60)}m`:e<86400?`${Math.floor(e/3600)}h`:`${Math.floor(e/86400)}g`}const u2="nc_bar_files_button";function h4(){try{return localStorage.getItem(u2)==="on"}catch{return!1}}function f4(t){try{localStorage.setItem(u2,t?"on":"off")}catch{}}function p4({showComposer:t,showFiles:e,showPanel:n,hasPanel:s,rendererKind:i,filesSetting:a=null,handlers:c={}}={}){const u=[];return typeof c.onToggleComposer=="function"&&u.push({id:"keyboard",kind:"switch",on:!!t,labelKey:"bar-menu-keyboard",descKey:"bar-menu-keyboard-desc",run:c.onToggleComposer}),typeof c.onToggleFiles=="function"&&u.push(a===null?{id:"files",kind:"switch",on:!!e,labelKey:"bar-menu-files",descKey:"bar-menu-files-desc",run:c.onToggleFiles}:{id:"files",kind:"switch",on:!!a,labelKey:"bar-menu-files",descKey:"bar-menu-files-setting-desc",run:c.onToggleFiles}),s&&typeof c.onTogglePanel=="function"&&u.push({id:"panel",kind:"switch",on:!!n,labelKey:"bar-menu-panel",descKey:"bar-menu-panel-desc",run:c.onTogglePanel}),typeof c.onSwitchRenderer=="function"&&u.push({id:"renderer",kind:"switch",on:i==="webgl",labelKey:"bar-menu-renderer",descKey:"bar-menu-renderer-desc",run:c.onSwitchRenderer}),u}function m4(t,e){if(!t||!t.tmux)return"";const n=th(t,e||{});return n.stato==="lavora"?p("cell-working"):n.stato==="attesa"?p("cell-permission"):n.stato==="ferma"?p("cell-idle"):""}function t1({session:t,node:e,ownerId:n,cellName:s,token:i,readonly:a=!1,panelPort:c=0,onBack:u,onCellSwitcher:h,cellSwitcherOpen:f=!1,liveHost:v=null,side:g=null,onSideClose:_=null,onSideGone:b=null}){var Ns;qn();const[S]=Cg(),E=tC(),[C,N]=w.useState(!1),[k,I]=w.useState(null),[L,H]=w.useState(()=>window.matchMedia("(pointer: coarse)").matches),[z,V]=w.useState(Tv),[Y,G]=w.useState(uc),[Z,q]=w.useState(()=>uc()),T=()=>{const Ke=aM(lM(uc()));G(Ke),typeof window<"u"&&window.location.reload()},[P,D]=w.useState(s||t),[j,O]=w.useState(""),[A,M]=w.useState(""),[R,F]=w.useState(""),[$,K]=w.useState(!1),[oe,ce]=w.useState(!1),ne=!!g&&oe,[Le,Ee]=w.useState(!1),[pe,Re]=w.useState({v:{main:1,side:1},h:{main:1,side:1}}),[de,fe]=w.useState(()=>window.matchMedia("(orientation: landscape)").matches);w.useEffect(()=>{const Ke=window.matchMedia("(orientation: landscape)"),Ze=sn=>fe(sn.matches);return Ke.addEventListener("change",Ze),()=>Ke.removeEventListener("change",Ze)},[]);const ke=de?pe.h:pe.v,we=w.useRef(ke);we.current=ke;const[ge,Ie]=w.useState(null),[Ae,Te]=w.useState(!0),J=w.useRef(()=>{}),Se=w.useRef(()=>!1),De=w.useRef(()=>{}),Me=w.useRef(!1),Ve=w.useRef(!1),Qe=w.useRef(null),dt=w.useRef(null),[at,bt]=w.useState(null),st=w.useCallback(Ke=>bt({source:"main",ev:Ke}),[]),ft=w.useCallback(Ke=>bt({source:"side",ev:Ke}),[]),ot=!!g&&(at==null?void 0:at.source)==="side",Rt=Ke=>{ce(Ke),pt((Ke?Me:St).current),Kt((Ke?Ve:mt).current)},U=g?`${g.node||""}:${g.session}`:"";w.useEffect(()=>{ce(!1),Ee(!1),Re({v:{main:1,side:1},h:{main:1,side:1}}),Ie(null),bt(Ke=>Ke&&Ke.source==="side"?null:Ke)},[U]);const Q=w.useMemo(()=>{const Ke=new Map;return Ze=>{if(Ke.has(Ze))return Ke.get(Ze);let sn=Ze*.6;try{const te=document.createElement("span");te.style.cssText="position:absolute;visibility:hidden;white-space:pre;font-family:courier-new,courier,monospace;",te.style.fontSize=`${Ze}px`,te.textContent="0".repeat(20),document.body.appendChild(te);const xe=te.getBoundingClientRect().width;document.body.removeChild(te),Number.isFinite(xe)&&xe>0&&(sn=xe/20)}catch{}return Ke.set(Ze,sn),sn}},[]),X=Math.max(.01,ke.main+ke.side),_e=((Ns=dt.current)==null?void 0:Ns.clientWidth)||window.innerWidth,me=Math.max(0,_e-12)*(Math.min(ke.main,ke.side)/X)-26,tt=!!g&&de&&me/Q(Math.max(1,z))<40,ie=Ke=>V(Ze=>e2(Ze+Ke));w.useEffect(()=>{f||V(Tv())},[f]);const Pe=w.useRef(()=>{}),ut=w.useRef(()=>!1),yt=w.useRef(()=>{}),St=w.useRef(!1),[Pt,pt]=w.useState(!1),mt=w.useRef(!1),[qt,Kt]=w.useState(!1),Bt=w.useRef(null),[ln,an]=w.useState(!1),tn=()=>{const Ke=ne?Me:St;Ke.current=!Ke.current,pt(Ke.current)},hn=()=>{const Ke=ne?Ve:mt;Ke.current=!Ke.current,Kt(Ke.current)};w.useEffect(()=>{D(s||t),K(!1)},[s,t]),w.useEffect(()=>{let Ke=!0;const Ze=e?e.split("/"):[],sn=e?`/api/route/${e.split("/").map(encodeURIComponent).join("/")}/_`:"/api";async function te(){let ze=null,qe=null;try{const se=await(await bn(`${sn}/sessions`,i)).json();Array.isArray(se.sessions)&&(ze=se.sessions.find(be=>be.name===t))}catch{}try{const W=await Cr(i,Ze);W.available&&Array.isArray(W.cells)&&(qe=W.cells.find(se=>se.tmuxSession===t))}catch{}if(!Ke)return;D(Cc({session:t,cell:qe||(s?{cell:s}:null)})),M(typeof(qe==null?void 0:qe.panelUrl)=="string"?qe.panelUrl.trim():""),F(typeof(qe==null?void 0:qe.cell)=="string"?qe.cell:"");let xt="";qe?xt=[`${qe.engine}${qe.key?`·${qe.key}`:""}`,m4(qe,ze)].filter(Boolean).join(" · "):ze&&(xt=ze.attached?`attached · ${e1(ze.activity)}`:ze.activity?e1(ze.activity):""),O(xt),Te(!!(ze||qe))}te();const xe=setInterval(te,4e3);return()=>{Ke=!1,clearInterval(xe)}},[t,e,i]);const fn=w.useRef(b);fn.current=b,w.useEffect(()=>{if(!g){Ie(null);return}let Ke=!0;const Ze=g.node?g.node.split("/"):[],sn=g.node?`/api/route/${g.node.split("/").map(encodeURIComponent).join("/")}/_`:"/api";async function te(){var se;let ze=null,qe=null,xt=!1,W=!1;try{const He=await(await bn(`${sn}/sessions`,i)).json();Array.isArray(He.sessions)&&(xt=!0,ze=He.sessions.find(Ne=>Ne.name===g.session))}catch{}try{const be=await Cr(i,Ze);be.available&&Array.isArray(be.cells)&&(W=!0,qe=be.cells.find(He=>He.tmuxSession===g.session))}catch{}Ke&&(Ie({title:Cc({session:g.session,cell:qe}),present:!!(ze||qe)}),(xt||W)&&!ze&&!qe&&((se=fn.current)==null||se.call(fn)))}te();const xe=setInterval(te,4e3);return()=>{Ke=!1,clearInterval(xe)}},[g==null?void 0:g.session,g==null?void 0:g.node,i]);const Vt=ne?"side":"main",[Xt,pn]=w.useState(h4),Jt=()=>bt(Ke=>Ke&&Ke.source===Vt?null:{source:Vt,ev:null}),Qt=p4({showComposer:L,showFiles:(at==null?void 0:at.source)===Vt,showPanel:$,hasPanel:!!A,rendererKind:Z,filesSetting:E?null:Xt,handlers:{onToggleComposer:()=>H(Ke=>!Ke),onToggleFiles:E?Jt:()=>pn(Ke=>(f4(!Ke),!Ke)),onTogglePanel:()=>K(Ke=>!Ke),onSwitchRenderer:T}}),Kn=Ke=>{Ke.preventDefault();const Ze=dt.current;if(!Ze)return;const sn=(se,be)=>Re(He=>({...He,[de?"h":"v"]:{main:se,side:be}}));if(de){const se=Ke.clientX,be=we.current,He=Ze.clientWidth||1,Ne=Le?-1:1,Nt=Ge=>{const Tt=be.main+be.side,nt=(Ge.clientX-se)/He*Tt*Ne,Be=td(be.main+nt);sn(Be,td(Tt-Be))},_t=()=>{window.removeEventListener("pointermove",Nt),window.removeEventListener("pointerup",_t),window.removeEventListener("pointercancel",_t),window.removeEventListener("blur",_t)};window.addEventListener("pointermove",Nt),window.addEventListener("pointerup",_t),window.addEventListener("pointercancel",_t),window.addEventListener("blur",_t);return}const te=Ke.clientY,xe=we.current,ze=Ze.clientHeight||1,qe=Le?-1:1,xt=se=>{const be=xe.main+xe.side,He=(se.clientY-te)/ze*be*qe,Ne=td(xe.main+He);sn(Ne,td(be-Ne))},W=()=>{window.removeEventListener("pointermove",xt),window.removeEventListener("pointerup",W),window.removeEventListener("pointercancel",W),window.removeEventListener("blur",W)};window.addEventListener("pointermove",xt),window.addEventListener("pointerup",W),window.addEventListener("pointercancel",W),window.addEventListener("blur",W)},$n=g&&l.jsxs("div",{className:`nc-dual-pane${ne?"":" foco"}${tt&&ne?" nascosto":""}`,"data-testid":"pane-main",style:{flexGrow:ke.main,flexBasis:de?0:void 0},onPointerDown:()=>Rt(!1),children:[l.jsxs("div",{className:"nc-dual-strip",children:[l.jsx("span",{className:`nc-dual-dot${Ae?" on":""}`,"aria-hidden":"true"}),l.jsx("b",{children:P}),!ne&&l.jsx("span",{className:"nc-dual-matita","aria-hidden":"true",title:p("dual-focus"),children:"✎"}),tt&&l.jsxs("button",{type:"button",className:"nc-dual-alt",title:p("dual-go-to").replace("{cell}",(ge==null?void 0:ge.title)||g.session),"aria-label":p("dual-go-to").replace("{cell}",(ge==null?void 0:ge.title)||g.session),onPointerDown:Ke=>Ke.stopPropagation(),onClick:Ke=>{Ke.stopPropagation(),Rt(!ne)},children:[l.jsxs("svg",{viewBox:"0 0 24 24",width:"14",height:"14","aria-hidden":"true",focusable:"false",children:[l.jsx("rect",{x:"3.5",y:"6",width:"17",height:"12",rx:"1.5",fill:"none",stroke:"currentColor",strokeWidth:"1.5"}),l.jsx("rect",{x:"3.5",y:"6",width:"8.5",height:"12",fill:"currentColor"})]}),l.jsx("span",{className:`nc-dual-dot${ge!=null&&ge.present?" on":""}`,"aria-hidden":"true"})]})]}),l.jsx("div",{className:"nc-dual-body",children:l.jsx(dc,{session:t,node:e,token:i,readonly:a,takeSize:!0,focused:!ne,sendRef:Pe,composerRef:ut,actionRef:yt,ctrlRef:St,setCtrlArmed:pt,altRef:mt,setAltArmed:Kt,keyboardRef:Bt,onFiles:st,fontSize:z,selectionMode:ln,onSelectionModeChange:an,keyboardGesture:S.terminalKeyboardGesture,onRendererChange:q})})]},"pane-main"),en=g&&l.jsxs("div",{className:`nc-dual-pane${ne?" foco":""}${tt&&!ne?" nascosto":""}`,"data-testid":"pane-side",style:{flexGrow:ke.side,flexBasis:de?0:void 0},onPointerDown:()=>Rt(!0),children:[l.jsxs("div",{className:"nc-dual-strip",children:[l.jsx("span",{className:`nc-dual-dot${ge!=null&&ge.present?" on":""}`,"aria-hidden":"true"}),l.jsx("b",{children:ge?ge.title:g.session}),ne&&l.jsx("span",{className:"nc-dual-matita","aria-hidden":"true",title:p("dual-focus"),children:"✎"}),l.jsxs("span",{className:"nc-dual-tasti",children:[l.jsx("button",{type:"button",title:p("dual-swap"),"aria-label":p("dual-swap"),onPointerDown:Ke=>Ke.stopPropagation(),onClick:Ke=>{Ke.stopPropagation(),Ee(Ze=>!Ze)},children:de?"⇆":"⇅"}),l.jsx("button",{type:"button",title:p("dual-close"),"aria-label":p("dual-close"),onPointerDown:Ke=>Ke.stopPropagation(),onClick:Ke=>{Ke.stopPropagation(),_==null||_()},children:"✕"})]}),tt&&l.jsxs("button",{type:"button",className:"nc-dual-alt",title:p("dual-go-to").replace("{cell}",P),"aria-label":p("dual-go-to").replace("{cell}",P),onPointerDown:Ke=>Ke.stopPropagation(),onClick:Ke=>{Ke.stopPropagation(),Rt(!ne)},children:[l.jsxs("svg",{viewBox:"0 0 24 24",width:"14",height:"14","aria-hidden":"true",focusable:"false",children:[l.jsx("rect",{x:"3.5",y:"6",width:"17",height:"12",rx:"1.5",fill:"none",stroke:"currentColor",strokeWidth:"1.5"}),l.jsx("rect",{x:"12",y:"6",width:"8.5",height:"12",fill:"currentColor"})]}),l.jsx("span",{className:`nc-dual-dot${Ae?" on":""}`,"aria-hidden":"true"})]})]}),l.jsx("div",{className:"nc-dual-body",children:l.jsx(dc,{session:g.session,node:g.node,token:i,readonly:a,takeSize:!1,focused:ne,sendRef:J,composerRef:Se,actionRef:De,ctrlRef:Me,setCtrlArmed:pt,altRef:Ve,setAltArmed:Kt,keyboardRef:Qe,onFiles:ft,fontSize:z,selectionMode:ln,onSelectionModeChange:an,keyboardGesture:S.terminalKeyboardGesture})})]},"pane-side"),nn=l.jsx("div",{className:"nc-dual-handle","data-testid":"dual-handle",role:"separator","aria-orientation":de?"vertical":"horizontal",onPointerDown:Kn},"dual-handle");return l.jsxs("div",{className:"nc-app",children:[l.jsxs("header",{className:"nc-bar nc-bar-single",children:[l.jsxs("button",{onClick:u,title:p("sessions"),children:[l.jsx(Dt,{name:"chevronLeft",size:18}),l.jsx("span",{className:"nc-bar-label",children:p("sessions")})]}),l.jsxs("span",{className:"nc-bar-center",children:[l.jsx("b",{title:e?`${P} · ${e}`:P,children:P}),v&&v.cell&&v.cell===s?l.jsx("span",{className:`nc-live-host-dot ${gg(v)} nc-live-host-dot-header`,"data-testid":"live-host-header-dot",title:p("live-host-indicator").replace("{cell}",v.cell).replace("{mode}",p(v.mode?`live-host-mode-${v.mode}`:"live-host-mode-unknown")).replace("{state}",p(`live-host-state-${v.state}`))}):null,j&&l.jsx("small",{className:"nc-bar-sub",children:j})]}),l.jsxs("span",{className:"nc-bar-right",children:[l.jsx("button",{onClick:()=>ie(-1),title:p("zoom-out"),children:l.jsx(Dt,{name:"zoomOut",size:18})}),l.jsx("button",{onClick:()=>ie(1),title:p("zoom-in"),children:l.jsx(Dt,{name:"zoomIn",size:18})}),!E&&Xt&&l.jsx("button",{type:"button",onClick:Jt,title:p("bar-menu-files"),"aria-label":p("bar-menu-files"),"aria-pressed":(at==null?void 0:at.source)===Vt?"true":"false",children:l.jsx(Dt,{name:"folder",size:18})}),l.jsx("button",{type:"button",className:`nc-bar-menu${C?" on":""}`,title:p("bar-menu-open"),"aria-label":p("bar-menu-open"),"aria-haspopup":"menu","aria-expanded":C?"true":"false",onClick:Ke=>{C||I(Ke.currentTarget.getBoundingClientRect()),N(Ze=>!Ze)},children:"⋯"})]})]}),l.jsxs("div",{className:"nc-termwrap",children:[g?l.jsx("div",{className:`nc-dual${de?" row":""}`,ref:dt,children:tt?Le?[en,$n]:[$n,en]:Le?[en,nn,$n]:[$n,nn,en]}):l.jsx(dc,{session:t,node:e,token:i,readonly:a,takeSize:!0,sendRef:Pe,composerRef:ut,actionRef:yt,ctrlRef:St,setCtrlArmed:pt,altRef:mt,setAltArmed:Kt,keyboardRef:Bt,onFiles:st,fontSize:z,selectionMode:ln,onSelectionModeChange:an,keyboardGesture:S.terminalKeyboardGesture,onRendererChange:q}),$&&A&&R&&l.jsx(rg,{cellId:R,panelUrl:A,route:e?e.split("/"):[],panelPort:c,token:i,title:P})]}),l.jsx(LP,{onKeyboard:()=>H(Ke=>!Ke),onCellSwitcher:h,cellSwitcherOpen:f,send:Ke=>(ne?J:Pe).current(Ke),action:Ke=>(ne?De:yt).current(Ke),ctrlArmed:Pt,onCtrl:tn,altArmed:qt,onAlt:hn,onAltConsume:()=>{const Ke=ne?Ve:mt;Ke.current=!1,Kt(!1)},onKeyboardKeep:()=>{var Ke,Ze;return(Ze=(Ke=ne?Qe:Bt).current)==null?void 0:Ze.call(Ke)},selectionMode:ln,onSelectionMode:an,keepKeyboardClosed:S.keybarKeepsKeyboardClosed,showEnter:S.showKeybarEnter,keybarLayout:S.keybarLayout}),L&&l.jsx(XC,{submitText:Ke=>(ne?Se:ut).current(Ke),token:i,session:ne?g.session:t,node:ne?g.node:e,ownerId:ne?g.ownerId:n,readonly:a,keepKeyboardClosedOnVoice:S.voiceKeepsKeyboardClosed}),at&&(ot?l.jsx(gv,{session:g.session,node:g.node,token:i,filesEvent:at.ev,onClose:()=>bt(null)}):at.source==="main"?l.jsx(gv,{session:t,node:e,token:i,filesEvent:at.ev,onClose:()=>bt(null)}):null),C&&(E?l.jsx(SC,{anchorRect:k,items:Qt,onClose:()=>N(!1)}):l.jsx(vg,{cellName:P,items:Qt,onClose:()=>N(!1)}))]})}function v4(){qn();const[t]=w.useState(d4),[e,n]=w.useState(t.token),[s,i]=w.useState(!1);QD(s?"":e);const a=w.useRef(t.token);a.current=e,w.useEffect(()=>{const he=Ce=>{Ce&&Ce.detail&&Ce.detail.token===a.current&&i(!0)};return window.addEventListener(tm,he),()=>window.removeEventListener(tm,he)},[]);const c=w.useCallback((he,Ce)=>{const Ue=c1(he,{remember:Ce});if(!Ue.ok||Ce&&Ue.where!=="local")try{window.dispatchEvent(new CustomEvent(nm))}catch{}i(!1),n(he)},[]),[u,h]=w.useState(t.pair||""),f=w.useCallback(()=>{h("");try{sessionStorage.removeItem("nc_pair")}catch{}},[]),v=tC(),[g]=w.useState(()=>hI(typeof location<"u"?location.pathname:"/")),[_,b]=w.useState(g.id),S=_===qo(null,ei),[E,C]=w.useState(null),N=he=>{const Ce=kr(he);C(Ce?{...Ce,...typeof(he==null?void 0:he.cellName)=="string"&&he.cellName?{cellName:he.cellName}:{}}:null)},[k,I]=w.useState(null);w.useEffect(()=>{const he=O6();I(he&&E&&Pv(he.main,E)?he.side:null)},[E]);const L=he=>{const Ce=E?{session:E.session,node:E.node}:null,Ue=D6(Ce,k,he);I(Ue),Ue?B6(Ce,Ue):KS()},H=()=>{I(null),KS()},[z,V]=w.useState([]),[Y,G]=w.useState(!0),[Z,q]=w.useState(null),[T,P]=w.useState([]),[D,j]=w.useState([]),[O,A]=w.useState(!1),[M,R]=w.useState(null),[F,$]=w.useState(()=>g.ownerId?uo():ZS(g.name)),[K,oe]=w.useState(null),[ce,ne]=w.useState(null),Le=he=>ne(kr(he)),[Ee,pe]=w.useState(null),Re=dg(e,v),de=w.useMemo(()=>(Re||[]).filter(he=>he.instanceId).map(he=>({instanceId:he.instanceId,route:he.route,label:he.label,status:he.status,stale:he.stale===!0})),[Re]),fe=V6(e,_,F,$,de),{notice:ke,showActionNotice:we}=zC(),ge=fe.decks;w.useEffect(()=>{const he=new Map;for(const Ce of Re||[]){const Ue=(Ce.route||[Ce.name]).join("/"),wt=new Set((Ce.sessions||[]).map(Lt=>Lt.name));for(const Lt of Ce.cells||[])!Lt.cell||!Lt.tmuxSession||Lt.cell===Lt.tmuxSession||wt.has(Lt.cell)||he.set(`${Ue}:${Lt.cell}`,`${Ue}:${Lt.tmuxSession}`)}$(Ce=>YT(Ce,he))},[Re]),w.useEffect(()=>{fe.localNodeId&&g.ownerId&&g.ownerId===fe.localNodeId&&$(he=>he.columns.some(Ce=>Ce.tiles.length)?he:ZS(g.name))},[fe.localNodeId]),w.useEffect(()=>{fe.localNodeId&&(aI(de),fe.viewUpdate(he=>{const Ce=za(he,fe.localNodeId,de);return JSON.stringify(Ce)===JSON.stringify(he)?he:Ce}))},[de,fe.localNodeId,fe.viewUpdate]);const[Ie,Ae]=w.useState(null),[Te,J]=w.useState(null),Se=w.useRef(0),[De,Me]=w.useState(!1),[Ve,Qe]=w.useState(u4),[dt,at]=w.useState(!S),[bt,st]=w.useState(()=>S?localStorage.getItem(JS)==="1":!0),[ft,ot]=w.useState(!1),[Rt,U]=w.useState("nodes"),[Q,X]=w.useState(!1),[_e,me]=w.useState(""),[tt,ie]=w.useState(!1),Pe=(he="nodes",Ce=!1,Ue="")=>{U(he),X(Ce),me(Ue),ot(!0)},[ut,yt]=w.useState(!1),[St,Pt]=w.useState(null),[pt,mt]=w.useState({deviceDefault:"",localNodeId:"",localNameDefault:"",deviceNameNeeded:!1,deviceNameSuggestion:""}),[qt,Kt]=w.useState(""),[Bt,ln]=w.useState(!1),[an,tn]=w.useState(0),[hn,fn]=w.useState({});w.useEffect(()=>{try{localStorage.setItem(c2,String(Ve))}catch{}},[Ve]),w.useEffect(()=>{try{localStorage.setItem(JS,bt?"1":"")}catch{}},[bt]),w.useEffect(()=>{if(!e)return;let he=!1;return Promise.all([g1(e),bn("/api/config",e).then(Ce=>Ce.json())]).then(([Ce,Ue])=>{if(!he){if(mt({deviceDefault:Ce.deviceName||"",localNodeId:Ce.nodeId||"",localNameDefault:Ce.localName||"",deviceNameNeeded:Ce.deviceNameNeeded===!0,deviceNameSuggestion:Ce.deviceNameSuggestion||""}),Kt(Ce.deviceName||""),ln(!!Ue.readonlyDefault),hM(Ue.terminal),tn(Number.isInteger(Ue.panelPort)?Ue.panelPort:0),fn(Ue.nodePanelPorts&&typeof Ue.nodePanelPorts=="object"&&!Array.isArray(Ue.nodePanelPorts)?Ue.nodePanelPorts:{}),Ce.firstRun===!0&&!Ue.readonlyDefault)yt(!0);else if(u)yt(!0);else if(Ce.deviceNameNeeded===!0&&!Ue.readonlyDefault){let wt=!1;try{wt=sessionStorage.getItem("nc_device_ask_later")==="1"}catch{}wt||Pt({suggestion:Ce.deviceNameSuggestion||""})}}}).catch(()=>{}),()=>{he=!0}},[e,u]);const[Vt,Xt]=w.useState({}),pn=w.useCallback(({route:he,hostCell:Ce,revision:Ue})=>{const wt=ks(he);Xt(Lt=>({...Lt,[wt]:{hostCell:Ce||null,hostLease:null,hostRevision:Number.isInteger(Ue)?Ue:(Lt[wt]||{}).hostRevision||0,threadStatus:"absent"}}))},[]),Jt=he=>{const Ce=ks(he),Ue=he.length?((Re||[]).find(wt=>ks(Array.isArray(wt.route)?wt.route:[])===Ce)||{}).cells||[]:T;return Ka({liveHost:Vt[Ce]||null,cells:Ue,localNodeId:fe.localNodeId,ownerId:he.length?Ce:fe.localNodeId})},Qt=w.useRef(Re);w.useEffect(()=>{Qt.current=Re},[Re]);const Kn=w.useRef(null);Kn.current||(Kn.current=WS());const $n=w.useRef(null);$n.current||($n.current=WS());const en=3500,nn=w.useCallback(async()=>{const he=$n.current,Ce=he.begin();if(Ce!==null)try{try{const zn=await(await bn("/api/sessions",e,{timeoutMs:en})).json();if(!he.isCurrent(Ce))return;zn.error?G(!1):(V(zn.sessions||[]),G(!0),q(Date.now()))}catch{he.isCurrent(Ce)&&G(!1)}let Ue=null,wt=null;try{Ue=await Cr(e,void 0,{timeoutMs:en})}catch(An){wt=An}if(!he.isCurrent(Ce))return;const Lt=ug({fs:Ue,error:wt});Lt.kind==="data"?(qa("local",Lt.cells),P(Lt.cells),j(Lt.capabilities),A(!1),R(null)):Lt.kind==="stale"?(P(An=>An.length?An:cg("local")),A(!0),R(null)):(P([]),qa("local",[]),j([]),A(!1),R(Lt.reason||""))}finally{he.end(Ce)}},[e]);w.useEffect(()=>{let he=!1;const Ce=async()=>{const wt=Kn.current,Lt=wt.begin();if(Lt!==null)try{const An=[[],...(Qt.current||[]).filter(Ht=>Ht.kind!=="vl"&&Ht.status==="up").map(Ht=>Array.isArray(Ht.route)&&Ht.route.length?Ht.route:[Ht.name])],zn=await Promise.all(An.map(async Ht=>{const Ls=ks(Ht);try{const cn=await Ud(e,Ht,{timeoutMs:en});return[Ls,{hostCell:cn&&typeof cn.hostCell=="string"?cn.hostCell:null,hostLease:cn&&cn.host&&typeof cn.host.lease=="string"?cn.host.lease:null,hostRevision:Number.isInteger(cn&&cn.revision)?cn.revision:0,threadStatus:cn&&QS.has(cn.threadStatus)?cn.threadStatus:"unknown"}]}catch{return[Ls,{error:!0}]}}));if(he||!wt.isCurrent(Lt))return;Xt(Ht=>{let Ls=!1;const cn={...Ht};for(const fo of zn){if(!fo)continue;const[rr,Wt]=fo;cn[rr]=Wt.error?{...Ht[rr]||{},threadStatus:"unknown"}:Wt,Ls=!0}return Ls?cn:Ht})}finally{wt.end(Lt)}};Ce();const Ue=setInterval(Ce,4e3);return()=>{he=!0,clearInterval(Ue),Kn.current.reset()}},[e]),w.useEffect(()=>{if(!v)return;nn();const he=setInterval(nn,4e3);return()=>{clearInterval(he),$n.current.reset()}},[v,nn]);const Ns=w.useCallback(async(he,Ce=[])=>{const Ue=ks(Ce),wt=Vt[Ue]&&Vt[Ue].hostRevision||0;try{const Lt=await Wd(e,he,wt,Ce);return Xt(An=>({...An,[Ue]:{hostCell:Lt.hostCell||null,hostLease:Lt.host&&typeof Lt.host.lease=="string"?Lt.host.lease:null,hostRevision:Number.isInteger(Lt.revision)?Lt.revision:wt,threadStatus:QS.has(Lt.threadStatus)?Lt.threadStatus:"unknown"}})),{ok:!0}}catch(Lt){return{ok:!1,error:Lt}}},[e,Vt]),Ke=w.useCallback(async(he,Ce=[])=>{const Ue=await Ns(he,Ce);return Ue.ok||window.alert(p(rm(Ue.error))),Ue.ok},[Ns]),Ze=w.useCallback(async(he=[])=>{const Ce=ks(he),Ue=Vt[Ce]&&Vt[Ce].hostRevision||0;try{const wt=await qd(e,Ue,he);return Xt(Lt=>({...Lt,[Ce]:{hostCell:wt.hostCell||null,hostLease:null,hostRevision:Number.isInteger(wt.revision)?wt.revision:Ue,threadStatus:"unknown"}})),{ok:!0}}catch(wt){return{ok:!1,error:wt}}},[e,Vt]),sn=w.useCallback(async(he=[])=>{const Ce=await Ze(he);return Ce.ok||window.alert(p(rm(Ce.error))),Ce.ok},[Ze]);w.useEffect(()=>{let he=!1;const Ce=()=>{bn("/api/config",e).then(wt=>wt.json()).then(wt=>{he||s4(wt.version,wt.uiVersion,"0.9.53")}).catch(()=>{})};Ce();const Ue=setInterval(Ce,6e4);return()=>{he=!0,clearInterval(Ue)}},[e]);const te=new Set([...z.map(he=>he.name),...Re.flatMap(he=>he.sessions.map(Ce=>Ce.key))]),xe=w.useMemo(()=>{const he=new Map;for(const Ce of z)Ce&&typeof Ce.name=="string"&&Number.isFinite(Ce.created)&&he.set(Ce.name,Ce.created);return he},[z]),ze=_s(F),qe=he=>$(Ce=>{const Ue=sk(he,fe.localNodeId,de)||he,wt=jC(Ce,Ue);return wt===Ce&&_s(Ce).length>=9&&fe.setError(p("grid-full")),wt}),xt=async(he,Ce=[])=>{try{await $v(e,he,Ce)}catch{return}const Ue=Ce.length?`${Ce.join("/")}:${he}`:he;$(wt=>xc(wt,Ue)),nn()},W=async(he,Ce,Ue=[])=>{try{await v1(e,he,Ce,Ue)}catch{return}nn()},se=async(he,Ce,Ue=[])=>{await f1(e,{cell:he,enabled:!!Ce},Ue),nn()},be=async he=>{if(!Ie)return;const{cell:Ce}=Ie,Ue=Array.isArray(Ie.route)?Ie.route:[];if(!await wg({token:e,powerCell:Ie,payload:he,onNotice:we})){const Lt=he.action==="up"?!!he.boot:he.boot?!1:!!Ie.boot;J({id:++Se.current,cell:Ce,route:Ue,enabled:Lt})}nn()},He=w.useCallback(he=>{J(Ce=>(Ce==null?void 0:Ce.id)===he?null:Ce)},[]),Ne=async he=>{if(!(!(he!=null&&he.direct)||De)){Me(!0);try{await Uv(e,he.name,he.tunnelStatus==="up"?"down":"up")}finally{Me(!1)}}},Nt=async(he,Ce)=>{const Ue=String(Ce||"").trim();return!(he!=null&&he.direct)||!Ya(Ue)?!1:(await b1(e,he.name,Ue),!0)},_t=he=>{const Ce=ge.find(Ue=>Ue.id===he);if(!Ce)return!1;try{const Ue=window.open(bp(Ce,e),"_blank");return Ue&&(Ue.opener=null),!!Ue}catch{return!1}},Ge=async he=>{if(!he||he===_)return;const Ce=await fe.select(he),Ue=fe.records.find(wt=>wt.id===he);b(he),$(Ce),oe(null),ne(null);try{history.replaceState(null,"",bp(Ue||he,null))}catch{}},Tt=async(he,Ce)=>{const Ue=await fe.add(he,Ce);await Ge(Ue.id)},nt=async(he,Ce)=>{const Ue=await fe.rename(he,Ce);if(he===_){b(Ue.id),$(fe.vistaMaterializzata(Ue)),oe(null),ne(null);try{history.replaceState(null,"",bp(Ue,null))}catch{}}},Be=async he=>{await fe.remove(he),he===_&&await Ge(fe.localMainId)},Zt=async(he,Ce)=>{!Ce||Ce===_||(await fe.addTileTo(Ce,he),$(Ue=>xc(Ue,he)))};if(!e||s)return l.jsx(F6,{onSubmit:c,reason:s?"invalid":""});const Rn=l.jsxs(l.Fragment,{children:[ft&&l.jsx(u6,{token:e,initialTab:Rt,initialLocation:_e,startNewCell:Q,onClose:()=>{ot(!1),X(!1),me("")}}),ut&&l.jsx(d6,{token:e,initialPair:u,...pt,onPairDone:f,onDone:()=>yt(!1)}),St&&l.jsx(h6,{token:e,suggestion:St.suggestion,onSaved:he=>{Kt(he),mt(Ce=>({...Ce,deviceDefault:he,deviceNameNeeded:!1})),Pt(null)},onLater:()=>{try{sessionStorage.setItem("nc_device_ask_later","1")}catch{}Pt(null)}}),l.jsx(E6,{token:e})]});if(!v)return Ee?l.jsxs(l.Fragment,{children:[l.jsx("div",{className:"nc-single-overlay",children:l.jsx(qS,{peer:Ee,token:e,onBack:()=>pe(null)})}),Rn]}):E?l.jsxs(l.Fragment,{children:[l.jsx(t1,{session:E.session,node:E.node,ownerId:E.ownerId,cellName:E.cellName,token:e,readonly:Bt,liveHost:Jt(E.node?E.node.split("/"):[]),panelPort:wc(E.node?E.node.split("/"):[],hn,an),side:k,onSideClose:H,onSideGone:H,onBack:()=>C(null),onCellSwitcher:()=>ie(!0),cellSwitcherOpen:tt}),tt&&l.jsx(M6,{token:e,current:E,localNodeLabel:qt,panelPort:an,nodePanelPorts:hn,hostByRoute:Vt,onDesignateCell:Ns,onClearHostCell:Ze,onLiveHostApplied:pn,sideKey:k?Wa(k.node?k.node.split("/"):[],k.session):null,onToggleSide:L,onPick:he=>{N(he),ie(!1)},onClose:()=>ie(!1)}),Rn]}):l.jsxs(l.Fragment,{children:[l.jsx(SP,{onPick:N,token:e,onSettings:Pe,onOpenVlSession:pe,panelPort:an,nodePanelPorts:hn,hostByRoute:Vt,onDesignateCell:Ke,onClearHostCell:sn}),Rn]});const wi=S||!dt;return l.jsxs("div",{className:"nc-workspace",children:[wi&&l.jsx(VP,{sessions:z,cells:T,localVerified:Y,activeSessions:ze,nodeGroups:Re,token:e,onPeekOpen:()=>ie(!1),overlayOpen:tt,fleetCapabilities:D,fleetStale:O,fleetOff:M,bootSettlement:Te,onBootSettlementApplied:He,localNodeId:fe.localNodeId,hostByRoute:Vt,onDesignateCell:Ke,onClearHostCell:sn,onPick:Le,onAddTile:qe,onPower:Ae,onBoot:se,onBootError:he=>fe.setError(String((he==null?void 0:he.message)||he)),onNodePower:Ne,onNodeRename:Nt,onKill:xt,onVisibility:W,onNew:()=>Pe("fleet",!0),onSettings:Pe,onOpenVlSession:pe,width:Ve,collapsed:bt,onResize:Qe,onToggleCollapse:()=>st(he=>!he)}),l.jsxs("div",{className:"nc-workspace-main",children:[l.jsx(II,{decks:ge,currentDeck:_,onCreate:Tt,onRename:nt,onDelete:Be,onReorder:fe.reorder,onOpenWindow:_t,onNavigate:Ge,saveState:fe.saveState,error:fe.error,conflict:fe.conflict,onReloadDeck:fe.reloadCurrent,sidebarVisible:wi,onToggleSidebar:S?null:()=>at(he=>!he)}),ke&&l.jsx("div",{className:"nc-notice nc-deck-notice",role:"status",title:ke,children:ke}),l.jsx(oI,{layout:F,onLayoutChange:$,onResizeEnd:()=>{fe.saveNow()},token:e,readonly:Bt,sessionsAlive:te,localVerified:Y,localIdentities:xe,localVerifiedAt:Z,focusSession:K,onFocus:oe,onOpenSingle:Le,decks:ge,currentDeck:_,onSendToDeck:Zt,cells:T,nodeGroups:Re,panelPort:an,nodePanelPorts:hn})]}),Ee&&l.jsx("div",{className:"nc-single-overlay",children:l.jsx(qS,{peer:Ee,token:e,onBack:()=>pe(null)})}),ce&&l.jsx("div",{className:"nc-single-overlay",children:l.jsx(t1,{session:ce.session,node:ce.node,ownerId:ce.ownerId,cellName:Cc({session:ce.session,node:ce.node,ownerId:ce.ownerId,cells:T,nodeGroups:Re}),token:e,readonly:Bt,liveHost:Jt(ce.node?ce.node.split("/"):[]),panelPort:wc(ce.node?ce.node.split("/"):[],hn,an),onBack:()=>ne(null)})}),Ie&&l.jsx(Nd,{cell:Ie,token:e,route:Array.isArray(Ie.route)?Ie.route:[],onConfirm:be,onClose:()=>Ae(null)}),Rn]})}function g4(t){return t.kind==="install"?p("update-installed-restart").replace("{v}",t.version):t.kind==="stale"?p("update-stale").replace("{ui}",t.version).replace("{browser}",t.browserVersion):p("update-available").replace("{v}",t.version).replace(" "," ").trim()}function _4(){qn();const t=w.useSyncExternalStore(G6,GS,GS);return t.needed?l.jsxs("div",{className:"nc-update",role:"status","aria-live":"polite",children:[l.jsx("span",{className:"nc-update-msg",children:g4(t)}),t.kind==="stale"&&l.jsx("button",{className:"nc-update-btn",onClick:l2,children:p("reload-no-cache")}),t.kind==="reload"&&l.jsx("button",{className:"nc-update-btn",onClick:a4,children:p("reload")}),l.jsx("button",{className:"nc-update-close",onClick:n4,"aria-label":p("update-dismiss"),title:p("update-dismiss"),children:"×"})]}):null}function y4(){qn();const[t,e]=w.useState(!1);return w.useEffect(()=>{const n=()=>e(!0);return window.addEventListener(nm,n),()=>window.removeEventListener(nm,n)},[]),t?l.jsxs("div",{className:"nc-update",role:"status","aria-live":"polite",children:[l.jsx("span",{className:"nc-update-msg",children:p("auth-not-remembered")}),l.jsx("button",{className:"nc-update-close",onClick:()=>e(!1),"aria-label":p("update-dismiss"),title:p("update-dismiss"),children:"×"})]}):null}o4();DD();VE.createRoot(document.getElementById("root")).render(l.jsxs(zE.StrictMode,{children:[l.jsx(v4,{}),l.jsx(_4,{}),l.jsx(y4,{})]}));
169
+ `],{type:"application/json"}),O=URL.createObjectURL(j),A=document.createElement("a");A.href=O,A.download="nexuscrew-diagnostics.json",A.click(),URL.revokeObjectURL(O)}catch{_(p("diagnostics-export-failed"))}};return l.jsxs("div",{className:"nc-set-tab nc-diagnostics",children:[l.jsxs("label",{className:"nc-field",children:[p("diagnostics-target"),l.jsx("select",{value:c.key,onChange:j=>a(j.target.value),children:s.map(j=>l.jsxs("option",{value:j.key,children:[j.label,j.status!=="up"?` · ${j.status}`:""]},j.key))})]}),l.jsxs("div",{className:"nc-set-form nc-diag-controls",children:[l.jsx("div",{className:"nc-sheet-label",children:p("diagnostics-verbose")}),l.jsxs("div",{className:"nc-set-row",children:[l.jsx("select",{"aria-label":p("diagnostics-duration"),value:N,onChange:j=>k(Number(j.target.value)),disabled:n,children:[300,900,1800,3600].map(j=>l.jsxs("option",{value:j,children:[j/60," min"]},j))}),l.jsx("button",{type:"button",className:"nc-btn primary",disabled:n||(u==null?void 0:u.verbose)===!0,onClick:()=>T(()=>Cw(t,!0,N,c.route)),children:p("enable")}),l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:n||(u==null?void 0:u.verbose)!==!0,onClick:()=>T(()=>Cw(t,!1,N,c.route)),children:p("stop")})]}),l.jsx("small",{className:"nc-set-hint",children:u!=null&&u.verbose?p("diagnostics-expires").replace("{time}",new Date(u.expiresAt).toLocaleTimeString()):p("diagnostics-off")})]}),l.jsxs("div",{className:"nc-diag-filters",children:[l.jsxs("select",{"aria-label":p("diagnostics-level"),value:I,onChange:j=>L(j.target.value),children:[l.jsx("option",{value:"all",children:p("diagnostics-all-levels")}),["debug","info","warn","error"].map(j=>l.jsx("option",{value:j,children:j},j))]}),l.jsx("input",{"aria-label":p("diagnostics-component"),placeholder:p("diagnostics-component"),value:H,onChange:j=>z(j.target.value)})]}),l.jsxs("div",{className:"nc-set-row",children:[l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox",checked:b,onChange:j=>S(j.target.checked)})," ",p("diagnostics-pause")]}),l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox",checked:E,onChange:j=>C(j.target.checked)})," ",p("diagnostics-autoscroll")]})]}),l.jsx("pre",{ref:Y,className:"nc-diag-log","aria-label":p("diagnostics-log"),children:q||p("diagnostics-empty")}),l.jsxs("div",{className:"nc-set-row",children:[l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:P,children:p("copy")}),l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:D,children:p("diagnostics-export")}),l.jsx("button",{type:"button",className:"nc-btn danger",disabled:n,onClick:()=>{window.confirm(p("diagnostics-clear-confirm"))&&T(async()=>{const j=await D5(t,c.route);return V.current=0,v([]),j})},children:p("diagnostics-clear")})]}),g&&l.jsx("div",{className:"nc-err",children:g})]})}function c6({token:t,settings:e,readonly:n,refresh:s,roster:i,section:a,setSection:c}){const[u,h]=w.useState(null),[f,v]=w.useState(null),[g,_]=w.useState(!1),[b,S]=w.useState(!1),[E,C]=w.useState(null),[N,k]=w.useState(!0),[I,L]=w.useState(!1),[H,z]=w.useState(null);w.useEffect(()=>{C(e&&e.update||null),k(!e||e.autoUpdate!==!1),L(!!(e&&e.alternateScreen))},[e]);const V=async()=>{h(null),v(null),S(!0);try{const A=await v5(t);v(A.note||"ok"),_(!1)}catch(A){h(String(A.message||A))}S(!1)},Y=async()=>{h(null),v(null),S(!0);try{const A=await j5(t);v(`${A.note||"ok"}${A.target?` (${A.target})`:""}`)}catch(A){h(String(A.message||A))}S(!1)},G=async A=>{h(null),v(null),S(!0);try{await gd(t,{autoUpdate:A}),k(A),s&&await s()}catch(M){h(String(M.message||M))}S(!1)},Z=async A=>{h(null),v(null),S(!0);try{await gd(t,{alternateScreen:A}),L(A),s&&await s()}catch(M){h(String(M.message||M))}S(!1)},q=w.useCallback(async()=>{if(t)try{z(await m5(t))}catch{z(null)}},[t]);w.useEffect(()=>{q()},[q]);const T=async A=>{h(null),v(null),S(!0);try{if(!A&&H&&H.running&&!window.confirm(p("ai-desktop-confirm-stop"))){S(!1);return}const M=await w1(t,A);M&&M.ok===!1&&h(M.error||"comando fallito"),await q(),s&&await s()}catch(M){h(String(M.message||M))}S(!1)},P=async()=>{h(null),v(null),S(!0);try{C(await M5(t))}catch(A){h(String(A.message||A))}S(!1)},D=async()=>{h(null),v(null),S(!0);try{const A=await T5(t);C(A),v(p("npm-update-restarting"))}catch(A){h(String(A.message||A))}S(!1)},j=()=>{window.confirm(p("composer-clear-confirm"))&&(h(null),$P()?(window.dispatchEvent(new Event(_v)),v(p("composer-clear-done"))):h(p("composer-clear-failed")))},O=e&&e.service;return l.jsxs("div",{className:"nc-set-tab",children:[l.jsx("div",{className:"nc-system-tabs",role:"tablist","aria-label":p("tab-system"),children:["general","diagnostics"].map(A=>l.jsx("button",{type:"button",role:"tab","aria-selected":a===A,className:`nc-set-tabbtn${a===A?" on":""}`,onClick:()=>c(A),children:p(`system-${A}`)},A))}),a==="general"&&l.jsxs(l.Fragment,{children:[l.jsxs("section",{className:"nc-system-group",children:[l.jsx("h3",{children:p("system-this-node")}),e&&l.jsxs("div",{className:"nc-set-info",children:["v",e.version," · ",e.platform," · :",e.port,l.jsx("br",{}),O&&O.installed?p("service-installed"):p("service-missing"),O&&O.installed?` · ${O.active?p("service-active"):p("service-inactive")}`:"",O?` · boot ${O.boot?"on":"off"}`:""]}),l.jsx("div",{className:"nc-set-row",children:l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:n||b,title:n?p("settings-readonly"):"",onClick:Y,children:p("service-regenerate")})}),l.jsx(i6,{token:t,readonly:n}),l.jsx(r6,{})]}),l.jsxs("section",{className:"nc-system-group",children:[l.jsx("h3",{children:p("system-updates")}),l.jsxs("div",{className:"nc-set-form nc-update-settings",children:[l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox",checked:N,disabled:n||b||E&&!E.supported,onChange:A=>G(A.target.checked)}),l.jsxs("span",{children:[l.jsx("b",{children:p("npm-auto-update")}),l.jsx("small",{children:p("npm-auto-update-help")})]})]}),E&&l.jsxs("div",{className:"nc-set-info",children:[p("npm-update-current")," v",E.current,E.latest?` · ${p("npm-update-latest")} v${E.latest}`:""," · ",p(E.supported?E.phase==="idle"&&E.checked!==!0?"npm-update-never":`npm-update-${E.phase}`:"unsupported")]}),l.jsxs("div",{className:"nc-set-row",children:[l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:n||b||!E||!E.supported,onClick:P,children:p("npm-update-check")}),E&&E.available&&l.jsx("button",{type:"button",className:"nc-btn primary",disabled:n||b||E.phase==="installing",onClick:D,children:p("npm-update-install")})]}),E&&E.lastError&&l.jsx("div",{className:"nc-err",children:E.lastError})]})]}),l.jsxs("section",{className:"nc-system-group",children:[l.jsx("h3",{children:p("ai-desktop-title")}),l.jsxs("div",{className:"nc-set-form",children:[l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox","aria-label":p("ai-desktop"),disabled:n||b,checked:!!(H&&H.desired),onChange:A=>T(A.target.checked)}),l.jsxs("span",{children:[l.jsx("b",{children:p("ai-desktop")}),l.jsx("small",{children:p("ai-desktop-help")})]})]}),H&&!H.desired&&H.running&&l.jsx("div",{className:"nc-set-info",children:p("ai-desktop-stop-pending")})]})]}),l.jsxs("section",{className:"nc-system-group",children:[l.jsx("h3",{children:p("system-security")}),l.jsx("div",{className:"nc-set-row",children:l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:n||b,title:n?p("settings-readonly"):"",onClick:()=>{h(null),v(null),_(!0)},children:p("token-rotate")})})]}),l.jsxs("section",{className:"nc-system-group",children:[l.jsx("h3",{children:p("system-local-data")}),l.jsxs("div",{className:"nc-set-form",children:[l.jsx("div",{className:"nc-sheet-label",children:p("composer-clear-data")}),l.jsx("small",{className:"nc-set-hint",children:p("composer-clear-data-help")}),l.jsx("div",{className:"nc-set-row",children:l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:j,children:p("composer-clear-data")})})]})]})]}),a==="diagnostics"&&l.jsxs("section",{className:"nc-system-group nc-system-diagnostics",children:[l.jsx("h3",{children:p("system-diagnostics")}),l.jsxs("div",{className:"nc-set-form nc-alternate-screen-settings",children:[l.jsx("div",{className:"nc-sheet-label",children:p("system-terminal")}),l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox","aria-label":p("alternate-screen"),checked:I,disabled:n||b,onChange:A=>Z(A.target.checked)}),l.jsxs("span",{children:[l.jsx("b",{children:p("alternate-screen")}),l.jsx("small",{children:p("alternate-screen-help")})]})]})]}),l.jsx(e6,{token:t}),l.jsx(BD,{}),l.jsx(l6,{token:t,roster:i,readonly:n})]}),g&&l.jsxs("div",{className:"nc-set-confirm",children:[l.jsx("div",{children:p("token-rotate-explain")}),l.jsxs("div",{className:"nc-sheet-actions",children:[l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:b,onClick:()=>_(!1),children:p("cancel")}),l.jsx("button",{type:"button",className:"nc-btn primary",disabled:b,onClick:V,children:p("confirm")})]})]}),f&&l.jsx("div",{className:"nc-set-note",children:f}),u&&l.jsx("div",{className:"nc-err",children:u})]})}function u6({token:t,onClose:e,initialTab:n="nodes",initialLocation:s="",startNewCell:i=!1}){qn();const a=n==="diagnostics"?"diagnostics":"general",[c,u]=w.useState(n==="diagnostics"?"system":n),h=w.useRef(null),f=w.useRef(null),[v,g]=w.useState({start:!1,end:!1}),[_,b]=w.useState(a),[S,E]=w.useState(null),[C,N]=w.useState([]),[k,I]=w.useState(null),[L,H]=w.useState([]),[z,V]=w.useState(!1),[Y,G]=w.useState(null),[Z,q]=w.useState(0),T=dg(t,!0,Z),P=w.useCallback(()=>{const j=h.current;if(!j)return;const O=j.scrollWidth>j.clientWidth+1,A={start:O&&j.scrollLeft>1,end:O&&j.scrollLeft+j.clientWidth<j.scrollWidth-1};g(M=>M.start===A.start&&M.end===A.end?M:A)},[]);w.useEffect(()=>{const j=h.current;if(!j)return;const O=typeof ResizeObserver=="function"?new ResizeObserver(P):null;return O==null||O.observe(j),window.addEventListener("resize",P),P(),()=>{O==null||O.disconnect(),window.removeEventListener("resize",P)}},[P]),w.useEffect(()=>{var O,A;(A=(O=f.current)==null?void 0:O.scrollIntoView)==null||A.call(O,{behavior:"smooth",block:"nearest",inline:"nearest"});const j=window.requestAnimationFrame?window.requestAnimationFrame(P):setTimeout(P,0);return()=>{window.cancelAnimationFrame?window.cancelAnimationFrame(j):clearTimeout(j)}},[c,P]);const D=w.useCallback(async()=>{var j;try{const O=await g1(t);E(O),G(null)}catch(O){G(String(O.message||O))}try{const O=await f5(t),A=O.peers||[];I(Number.isInteger(O.accessRevision)?O.accessRevision:null);let M=[],R=[];try{const[F,$]=await Promise.all([bn("/api/config",t).then(ne=>ne.json()).catch(()=>null),y1(t).catch(()=>null)]),K=F&&typeof F.instanceId=="string"?F.instanceId:"",oe=[{instanceId:K||null,route:[],label:null},...uC($,K)],ce=await Promise.all(oe.map(async ne=>{try{return{ok:!0,peers:((await _1(t,ne.route)).nodes||[]).map(pe=>cC(pe,ne)).filter(Boolean)}}catch(Le){return{ok:!1,owner:ne,error:Le}}}));for(const ne of ce){if(ne.ok){M.push(...ne.peers);continue}ne.owner.route.length!==0&&R.push({instanceId:ne.owner.instanceId,label:ne.owner.label,route:ne.owner.route,failure:/timeout/i.test(String(((j=ne.error)==null?void 0:j.message)||ne.error))?"timeout":"unreachable"})}}catch{}H(R),N([...A,...M])}catch(O){G(String(O.message||O))}},[t]);return w.useEffect(()=>{D();const j=setInterval(D,5e3);return()=>clearInterval(j)},[D]),w.useEffect(()=>{let j=!1;return bn("/api/config",t).then(O=>O.json()).then(O=>{j||V(!!O.readonlyDefault)}).catch(()=>{}),()=>{j=!0}},[t]),l.jsx("div",{className:"nc-set-overlay",onClick:e,children:l.jsxs("div",{className:"nc-set-panel",onClick:j=>j.stopPropagation(),children:[l.jsxs("div",{className:"nc-set-head",children:[l.jsx(Dt,{name:"gear",size:18}),l.jsx("b",{children:p("settings")}),l.jsx("button",{type:"button",className:"nc-set-close",onClick:e,title:p("close"),children:l.jsx(Dt,{name:"x",size:18})})]}),z&&l.jsx("div",{className:"nc-set-readonly",children:p("settings-readonly")}),Y&&l.jsx("div",{className:"nc-err",children:Y}),l.jsx("div",{className:`nc-set-tabs-wrap${v.start?" has-start-overflow":""}${v.end?" has-end-overflow":""}`,children:l.jsx("div",{className:"nc-set-tabs",ref:h,onScroll:P,children:["nodes","fleet","audio","input","system"].map(j=>l.jsx("button",{ref:c===j?f:null,type:"button",className:`nc-set-tabbtn${c===j?" on":""}`,onClick:()=>u(j),children:p(`tab-${j}`)},j))})}),l.jsxs("div",{className:"nc-set-body",children:[c==="nodes"&&l.jsx(s6,{token:t,nodes:C,roster:T,settings:S,readonly:z,vlUnavailable:L,accessRevision:k,refresh:D,refreshAliases:()=>q(j=>j+1)}),c==="fleet"&&l.jsx(_D,{token:t,readonly:z,startNewCell:i,initialLocation:s,targets:T.map(j=>({route:j.route,label:j.label||j.name,status:j.status}))}),c==="audio"&&l.jsx(o6,{token:t,readonly:z,nodes:C,settings:S}),c==="input"&&l.jsx(a6,{}),c==="system"&&l.jsx(c6,{token:t,settings:S,readonly:z,refresh:D,roster:T,section:_,setSection:b})]})]})})}function d6({token:t,initialPair:e,deviceDefault:n="",localNodeId:s="",localNameDefault:i="",deviceNameNeeded:a=!1,deviceNameSuggestion:c="",onPairDone:u,onDone:h}){qn();const[f,v]=w.useState(e?"pair":"welcome"),[g,_]=w.useState(!1),[b,S]=w.useState(null),[E,C]=w.useState(c||""),[N,k]=w.useState(null),I=async()=>{_(!0),S(null);try{const L={wizardDone:!0};a&&E.trim()&&(L.deviceName=E.trim()),await gd(t,L),u&&u(),h()}catch(L){S(String(L.message||L)),_(!1)}};return l.jsx("div",{className:"nc-wiz-overlay",children:l.jsxs("div",{className:"nc-wiz",children:[l.jsxs("div",{className:"nc-wiz-head",children:[l.jsx("b",{children:p("wizard-title")}),l.jsx("small",{children:p("hydra-simple")})]}),f==="welcome"&&l.jsxs("div",{className:"nc-wiz-body",children:[l.jsx("div",{className:"nc-wiz-done",children:p("local-ready")}),a&&l.jsx("div",{className:"nc-wiz-done",children:p("wizard-device-name")}),a&&l.jsxs("label",{className:"nc-field",children:[l.jsx("span",{children:p("device-name-label")}),l.jsx("input",{value:E,onChange:L=>C(L.target.value),maxLength:64,"data-testid":"wizard-device-name-input"})]}),l.jsxs("div",{className:"nc-sheet-actions",children:[l.jsx("button",{className:"nc-btn ghost",disabled:g,onClick:I,children:p("local-only")}),l.jsx("button",{className:"nc-btn primary",disabled:g,onClick:()=>v("pair"),children:p("add-node")})]})]}),f==="pair"&&l.jsxs("div",{className:"nc-wiz-body",children:[l.jsx(bk,{token:t,initial:e||"",autoStart:!!e,deviceDefault:a&&E.trim()?E.trim():n,localNodeId:s,localNameDefault:i,onBusyChange:_,onSuccess:async L=>{k(L&&L.authorizedKeys?{line:L.authorizedKeys,note:L.authorizedKeysNote||""}:null),u&&u(),v("done")}}),l.jsx("div",{className:"nc-sheet-actions",children:l.jsx("button",{className:"nc-btn ghost",disabled:g,onClick:()=>{u&&u(),v("welcome")},children:p("back")})})]}),f==="done"&&l.jsxs("div",{className:"nc-wiz-body",children:[l.jsx("div",{className:"nc-wiz-done",children:p("node-connected")}),N&&l.jsx(Tg,{line:N.line,note:N.note}),l.jsx("div",{className:"nc-sheet-actions",children:l.jsx("button",{className:"nc-btn primary",disabled:g,onClick:I,children:p("finish")})})]}),b&&l.jsx("div",{className:"nc-err",children:b})]})})}function h6({token:t,suggestion:e="",onSaved:n,onLater:s}){qn();const[i,a]=w.useState(e||""),[c,u]=w.useState(!1),[h,f]=w.useState(null),v=async()=>{const g=i.trim();if(g){u(!0),f(null);try{await gd(t,{deviceName:g}),n&&n(g)}catch(_){f(String(_.message||_)),u(!1)}}};return l.jsx("div",{className:"nc-wiz-overlay",role:"dialog","aria-label":p("device-name-ask-title"),"data-testid":"device-name-ask",children:l.jsxs("div",{className:"nc-wiz",children:[l.jsx("div",{className:"nc-wiz-head",children:l.jsx("b",{children:p("device-name-ask-title")})}),l.jsxs("div",{className:"nc-wiz-body",children:[l.jsx("p",{className:"nc-wiz-done",children:p("device-name-ask-text")}),l.jsxs("label",{className:"nc-field",children:[l.jsx("span",{children:p("device-name-label")}),l.jsx("input",{value:i,onChange:g=>a(g.target.value),maxLength:64,"data-testid":"device-name-input"})]}),l.jsxs("div",{className:"nc-sheet-actions",children:[l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:c,onClick:s,children:p("device-name-later")}),l.jsx("button",{type:"button",className:"nc-btn primary",disabled:c||!i.trim(),onClick:v,children:p("device-name-save")})]})]}),h&&l.jsx("div",{className:"nc-err",children:h})]})})}const f6=50;function p6(t){if(Number.isFinite(t))return t;const e=typeof t=="string"?Date.parse(t):NaN;return Number.isFinite(e)?e:0}function m6(t,e){return`${String(t)}|${String(e)}`}function HS(t,e){if(!t||typeof t!="object"||t.type!=="notify"||!t.eventId)return null;const n=typeof t.title=="string"?t.title:"",s=typeof t.body=="string"?t.body:"";return!n&&!s?null:{key:m6(e,t.eventId),ownerId:String(e),eventId:String(t.eventId),title:n,body:s,urgency:t.urgency==="high"?"high":"normal",ts:p6(t.ts)}}function US(t){return[...t].sort((e,n)=>n.ts-e.ts).slice(0,f6)}function v6(t,e,n){const s=new Map;for(const i of t||[])s.set(i.key,i);for(const i of e||[])i&&s.set(i.key,i);return[...s.values()]}function g6(t,e){if(typeof EventSource>"u"||!t)return()=>{};const n=new EventSource(`/api/events?token=${encodeURIComponent(t)}`);return n.onmessage=s=>{try{const i=JSON.parse(s.data);i&&typeof i=="object"&&typeof i.type=="string"&&e(i)}catch{}},()=>{try{n.close()}catch{}}}const _6=6e3,y6=12e3,Pi=(t,e,n)=>`${e||""}:${n||t}`,w6=(t,e)=>{const n=t&&t[e];return n?n.stale===!0||n.error===!0?"degraded":"live":"missing"},b6=600*1e3,Mv=new Map;function S6(t){Mv.set(t,Date.now())}function Gk(t){const e=Pi(t.id,t.ownerId,t.ownerAskId),n=Mv.get(e);return n===void 0?!1:Date.now()-n>b6?(Mv.delete(e),!1):!0}function Xk(t,e){const n=new Set(t.map(i=>Pi(i.id,i.ownerId,i.ownerAskId))),s=(e||[]).filter(i=>i&&i.id&&!n.has(Pi(i.id,i.ownerId,i.ownerAskId))&&!Gk(i));return s.length?[...t,...s]:t}function x6(t,e){const n=Xk([],t.filter(a=>a.imported)),s=new Set(n.map(a=>Pi(a.id,a.ownerId,a.ownerAskId)));return[...(e||[]).filter(a=>a&&a.id&&!s.has(Pi(a.id,a.ownerId,a.ownerAskId))&&!Gk(a)),...n]}function C6({n:t,onClose:e}){return l.jsxs("div",{className:`nc-ntf-toast${t.urgency==="high"?" high":""}`,role:"status","aria-live":"polite",children:[l.jsxs("div",{className:"nc-ntf-toast-txt",children:[l.jsx("b",{children:t.title}),t.body&&l.jsx("small",{children:t.body}),t.session&&l.jsx("span",{className:"nc-ntf-from",children:t.session}),t.ownerId&&l.jsx("span",{className:"nc-ntf-from",children:p("feed-owner")})]}),l.jsx("button",{type:"button",className:"nc-ntf-x",onClick:e,title:p("close"),children:l.jsx(Dt,{name:"x",size:14})})]})}function k6({ask:t,token:e,onAnswered:n,onDismiss:s,askReplyAccess:i=!1,feedViewState:a="live",initialUncertainRid:c=null}){const[u,h]=w.useState(""),[f,v]=w.useState(!1),[g,_]=w.useState(null),[b,S]=w.useState(!1),[E,C]=w.useState(c),[N,k]=w.useState(!1),[I,L]=w.useState(!1),H=async Y=>{const G=String(Y||"").trim();if(!(!G||f)){_(null),v(!0);try{if(t.ownerId){const Z=t.ownerAskId||t.id,q=await z5(e,{ownerId:t.ownerId,askId:Z,text:G});if(q&&q.uncertain){C(q.originalRequestId||null),L(!q.originalRequestId);return}n(t.id,t.ownerId)}else await B5(e,t.id,G),n(t.id)}catch(Z){_(String(Z.message||Z))}v(!1)}},z=async()=>{if(!b&&!E){_(null),S(!0);try{t.ownerId?await U5(e,{ownerId:t.ownerId,askId:t.ownerAskId||t.id}):await $5(e,t.id),S6(Pi(t.id,t.ownerId,t.ownerAskId)),s(t.id,t.ownerId)}catch(Y){_(String(Y&&Y.message||Y))}S(!1)}},V=p(E?"ask-uncertain":a==="degraded"?"ask-dismiss-stale":"ask-dismiss");return l.jsxs("div",{className:"nc-ask-card",children:[l.jsxs("div",{className:"nc-ask-head",children:[l.jsx("span",{className:"nc-ntf-from",children:t.session}),t.ownerId&&l.jsx("span",{className:"nc-ntf-from",children:p("feed-owner")}),l.jsxs("code",{className:"nc-ask-id",children:["#",t.id]}),l.jsx("button",{type:"button",className:"nc-ask-dismiss",title:V,"aria-label":V,disabled:b||!!E||!!t.ownerId&&i===!1,onClick:z,children:l.jsx(Dt,{name:"x",size:14})})]}),l.jsx("div",{className:"nc-ask-q",children:t.question}),t.ownerId&&i===!1&&l.jsx("small",{className:"nc-set-hint",children:p(a==="live"?"ask-remote-readonly":"ask-remote-no-feed")}),t.ownerId&&i!==!1&&a==="degraded"&&l.jsx("small",{className:"nc-set-hint",children:p("ask-feed-stale")}),(E||I)&&l.jsxs(l.Fragment,{children:[l.jsx("div",{className:"nc-err",children:p("ask-uncertain")}),I&&!E&&l.jsx("div",{className:"nc-err",children:p("ask-reconcile")}),l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:N,onClick:async()=>{k(!0);try{const Y=await F5(e,{ownerId:t.ownerId,askId:t.ownerAskId||t.id,requestId:E});Y&&(Y.state==="committed"||Y.state==="failed")&&s(t.id,t.ownerId)}finally{k(!1)}},children:p("ask-verify")})]}),(!t.ownerId||i===!0)&&!E&&!I&&l.jsxs(l.Fragment,{children:[Array.isArray(t.options)&&t.options.length>0&&l.jsx("div",{className:"nc-ask-opts",children:t.options.map(Y=>l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:f,onClick:()=>H(Y),children:Y},Y))}),l.jsxs("div",{className:"nc-ask-reply",children:[l.jsx("textarea",{rows:2,placeholder:p("ask-reply-ph"),value:u,disabled:f,onChange:Y=>h(Y.target.value)}),l.jsx("button",{type:"button",className:"nc-btn primary",disabled:f||!u.trim(),onClick:()=>H(u),children:p("send")})]})]}),g&&l.jsx("div",{className:"nc-err",children:g})]})}function E6({token:t}){const[e]=qn(),[n]=Fk(),[s,i]=w.useState([]),[a,c]=w.useState([]),[u,h]=w.useState([]),[f,v]=w.useState(()=>{try{return/(?:^|[#&])ask=/.test(location.hash)}catch{return!1}}),g=w.useRef(0),_=w.useRef(null);_.current||(_.current=PD());const b=w.useRef({enabled:n,lang:e});b.current={enabled:n,lang:e};const S=w.useCallback(V=>{i(Y=>Y.filter(G=>G.key!==V))},[]),E=w.useCallback(V=>{const Y=`t${g.current+=1}`;i(Z=>[...Z.slice(-3),{...V,key:Y}]),setTimeout(()=>S(Y),V.urgency==="high"?y6:_6);const G=b.current;if(G.enabled)try{_.current.enqueue(V,RD(V,G.lang))}catch{}},[S]);w.useEffect(()=>{n||_.current.stop()},[n]),w.useEffect(()=>{const V=()=>{(document.visibilityState!=="visible"||!document.hasFocus())&&_.current.stop()},Y=()=>_.current.stop();return document.addEventListener("visibilitychange",V),window.addEventListener("blur",V),window.addEventListener(Cv,Y),()=>{document.removeEventListener("visibilitychange",V),window.removeEventListener("blur",V),window.removeEventListener(Cv,Y),typeof _.current.dispose=="function"?_.current.dispose():_.current.stop()}},[]);const C=(V,Y)=>c(G=>G.filter(Z=>Pi(Z.id,Z.ownerId)!==Pi(V,Y)));w.useEffect(()=>{if(!t)return;let V=!1;O5(t).then(G=>{V||c(Z=>x6(Z,G.asks))}).catch(()=>{});const Y=g6(t,G=>{if(G.type==="notify"&&G.ownerId&&G.eventId){const Z=HS(G,G.ownerId);if(!Z)return;h(q=>US(v6(q,[Z],null)))}if(G.type==="notify")E(G);else if(G.type==="ask"&&G.ask&&G.ask.id){const Z=Pi(G.ask.id,G.ask.ownerId);c(q=>q.some(T=>Pi(T.id,T.ownerId)===Z)?q:[...q,G.ask])}else(G.type==="ask-answered"&&G.id||G.type==="ask-dismissed"&&G.id)&&C(G.id,G.ownerId)});return()=>{V=!0,Y()}},[t,E]);const[N,k]=w.useState({});w.useEffect(()=>{if(!t)return;let V=!0;return H5(t).then(Y=>{if(!V)return;const G={};for(const Z of Y&&Y.attempts||[])Z&&Z.state==="uncertain"&&Z.ownerId&&Z.askId&&Z.requestId&&(G[Z.ownerId+"|"+Z.askId]=Z.requestId);k(G)}).catch(()=>{}),()=>{V=!1}},[t]);const[I,L]=w.useState({}),[H,z]=w.useState({});return w.useEffect(()=>{let V=!0;return W5(t).then(Y=>{if(!V)return;const G={},Z={},q=[],T=new Map,P=new Set;for(const D of Y&&Y.views||[]){G[D.ownerId]=D.askReplyAccess===!0,Z[D.ownerId]={stale:D.stale===!0,error:!!D.lastError},P.add(D.ownerId);for(const j of D.asks||[])j&&j.id&&q.push({...j,ownerId:D.ownerId,imported:!0});for(const j of D.notifications||[]){const O=HS(j,D.ownerId);O&&T.set(O.key,O)}}L(G),z(Z),q.length&&c(D=>Xk(D,q)),h(D=>{const j=[];for(const O of D)P.has(O.ownerId)&&j.push(O);for(const O of T.values())j.push({...O,key:O.key});return US(j)})}).catch(()=>{}),()=>{V=!1}},[t]),l.jsxs(l.Fragment,{children:[s.length>0&&l.jsx("div",{className:"nc-ntf-toasts",children:s.map(V=>l.jsx(C6,{n:V,onClose:()=>S(V.key)},V.key))}),(a.length>0||u.length>0)&&!f&&l.jsxs("button",{type:"button",className:"nc-ask-badge",onClick:()=>v(!0),title:p("asks-title"),children:["? ",l.jsx("span",{className:"nc-ask-count",children:a.length+u.length})]}),(a.length>0||u.length>0)&&f&&l.jsxs("div",{className:"nc-ask-panel",children:[l.jsxs("div",{className:"nc-ask-panel-head",children:[l.jsx("b",{children:p("asks-title")}),l.jsx("span",{className:"nc-ask-count",children:a.length}),l.jsx("button",{type:"button",className:"nc-ntf-x",onClick:()=>v(!1),title:p("close"),children:l.jsx(Dt,{name:"x",size:16})})]}),l.jsxs("div",{className:"nc-ask-panel-body",children:[a.map(V=>l.jsx(k6,{ask:V,token:t,askReplyAccess:!V.ownerId||I[V.ownerId]===!0,feedViewState:V.ownerId?w6(H,V.ownerId):"live",initialUncertainRid:V.ownerId&&N[V.ownerId+"|"+(V.ownerAskId||V.id)]||null,onAnswered:C,onDismiss:C},Pi(V.id,V.ownerId))),u.length>0&&l.jsxs("div",{className:"nc-remote-notices",children:[l.jsx("div",{className:"nc-remote-notices-head",children:l.jsx("b",{children:p("remote-notices-title")})}),u.map(V=>l.jsxs("div",{className:"nc-remote-notice"+(V.urgency==="high"?" nc-remote-notice-high":""),children:[V.title?l.jsx("b",{children:V.title}):null,V.body?l.jsx("div",{children:V.body}):null,l.jsxs("div",{className:"nc-remote-notice-meta",children:[V.ownerId.slice(0,8)," · ",new Date(V.ts||Date.now()).toLocaleString()]})]},V.key))]})]})]})]})}const Jk="nc_fontsize",Qk=9,Zk=24;function Tv(t=globalThis.localStorage){const e=Number(t.getItem(Jk));return e>=Qk&&e<=Zk?e:13}function e2(t,e=globalThis.localStorage){const n=Math.max(Qk,Math.min(Zk,t));return e.setItem(Jk,String(n)),n}const N6=4e3;async function L6(t){const e=await bn("/api/sessions",t);if((e==null?void 0:e.ok)===!1)throw new Error(`HTTP ${e.status}`);const n=await e.json();if(!Array.isArray(n==null?void 0:n.sessions))throw new Error("invalid sessions payload");return n.sessions}async function Jp(t,e=[]){var u;const[n,s]=await Promise.allSettled([e.length?Fv(t,e):L6(t),Cr(t,e)]),i=n.status==="fulfilled"&&Array.isArray((u=n.value)==null?void 0:u.sessions)?n.value.sessions:Array.isArray(n.value)?n.value:null,a=s.status==="fulfilled"?s.value:null,c=(a==null?void 0:a.available)===!0&&Array.isArray(a.cells)?a.cells:null;return{sessions:i,cells:c,fresh:Array.isArray(i)&&Array.isArray(c)}}function t2(t,e,n){return n===!0&&(t==null?void 0:t.degraded)!==!0&&(t==null?void 0:t.active)===!0&&t.tmux!==!1&&!!t.tmuxSession&&(e||[]).some(s=>(s==null?void 0:s.name)===t.tmuxSession)}function R6(t){const e=new Map((t.sessions||[]).map(i=>[i.name,i])),n=[],s=(i,a,c,u=[],h="")=>{const f=new Map((a||[]).map(v=>[v.name,v]));for(const v of i||[]){const g=f.get(v.tmuxSession)||{},_=th(v,g),b=t2(v,a,c);n.push({key:Wa(u,v.tmuxSession||v.cell),session:v.tmuxSession,route:u,cellName:v.cell,label:v.cell,node:u.length?u.join("/"):"",nodeLabel:h,live:b,selectable:b,verified:c===!0,working:_.working,degraded:!!v.degraded,active:v.active===!0,activity:g.activity||v.activity||0,subtitle:_.subtitle,preview:g.preview||v.preview||"",telemetry:g.telemetry||null,panelUrl:v.panelUrl||""})}};s(t.cells,[...e.values()],t.localFresh===!0);for(const i of t.nodeGroups||[]){const a=Array.isArray(i.route)?i.route:[];i.kind==="vl"||!a.length||s(i.cells,i.sessions,i.switcherFresh===!0,a,i.label||i.name||"")}return n}function A6(t){const e=new Map,n=Array.isArray(t.sessions)?t.sessions:[],s=Array.isArray(t.cells)?t.cells:[],i=new Map(n.map(c=>[c.name,c])),a=new Set(s.map(c=>c.tmuxSession).filter(Boolean));e.set("local",_g(s,n.filter(c=>!a.has(c.name)),i));for(const c of t.nodeGroups||[]){const u=Array.isArray(c.route)?c.route:[];if(c.kind==="vl"||!u.length)continue;const h=Array.isArray(c.cells)?c.cells:[],f=Array.isArray(c.sessions)?c.sessions:[],v=new Set(h.map(g=>g.tmuxSession).filter(Boolean));e.set(u.join("/"),hc({...c,route:u,cells:h,sessions:f,unmanaged:f.filter(g=>!v.has(g.name))}).rawItems)}return e}function j6(t,e,n,s){return[...new Set(t.map(a=>a.node||"local"))].flatMap(a=>{const c=t.filter(v=>(v.node||"local")===a),u=new Map((e.get(a)||[]).map(v=>[v.key,v])),h=new Map(c.map(v=>[v.key,v])),f=c.map(v=>{const g=u.get(v.key);return{...v,label:(g==null?void 0:g.label)||v.label,live:(g==null?void 0:g.live)??v.live,fresh:(g==null?void 0:g.fresh)===!0,activity:(g==null?void 0:g.activity)??v.activity}});return co(f,n,"all",Ii(s,a)).map(v=>h.get(v.key))})}function M6({token:t,current:e,onPick:n,onClose:s,panelPort:i=0,nodePanelPorts:a={},localNodeLabel:c="",hostByRoute:u={},onDesignateCell:h,onClearHostCell:f,onLiveHostApplied:v,sideKey:g=null,onToggleSide:_,pollMs:b=N6}){const[S,E]=w.useState(E0),[C,N]=w.useState(!1),[k,I]=w.useState(!1),[L,H]=w.useState(""),[z,V]=w.useState(null),Y="stream",[G,Z]=w.useState(Tv),q=U=>Z(Q=>e2(Q+U)),[T,P]=w.useState(null),[D,j]=w.useState(!1),[O,A]=w.useState(""),M=w.useRef(null),R=w.useRef(null),F=w.useMemo(()=>R6(S),[S]),$=w.useMemo(()=>A6(S),[S]),{pins:K,orders:oe,togglePin:ce,removePin:ne,pinError:Le,canMoveRoster:Ee,moveRoster:pe,stepRoster:Re}=fg(),de=w.useMemo(()=>j6(F,$,K,oe),[F,$,K,oe]),fe=w.useMemo(()=>C?de:de.filter(U=>U.selectable||U.degraded&&U.active),[de,C]),ke=w.useMemo(()=>z?fe.find(U=>U.key===z&&U.selectable):null,[fe,z]);w.useEffect(()=>{z&&!fe.some(U=>U.key===z&&U.selectable)&&V(null)},[fe,z]);const we=w.useMemo(()=>T?F.find(U=>U.key===T.key):null,[F,T]),ge=!!(T&&we);w.useEffect(()=>{Le&&Le.message&&H(Le.message)},[Le]),w.useEffect(()=>{var X;const U=document.activeElement;(X=R.current)==null||X.focus();const Q=_e=>{_e.key==="Escape"&&!ge&&s()};return document.addEventListener("keydown",Q),()=>{var _e;document.removeEventListener("keydown",Q),(_e=U==null?void 0:U.focus)==null||_e.call(U)}},[s,ge]),w.useEffect(()=>{let U=!0,Q=!1;const X=async()=>{if(Q)return;Q=!0;const me=E0(),tt=Array.isArray(me.nodeGroups)?me.nodeGroups:[],ie=Jp(t),Pe=mt=>mt.kind!=="vl"&&Array.isArray(mt.route)&&mt.route.length>0,ut=await Promise.all(tt.filter(Pe).map(async mt=>({group:mt,result:await Jp(t,mt.route)}))),yt=await ie;if(!U)return;const St=new Map(ut.map(({group:mt,result:qt})=>[JSON.stringify(mt.route||[]),qt])),Pt=tt.map(mt=>{if(!Pe(mt))return{...mt,switcherFresh:!1};const qt=St.get(JSON.stringify(mt.route||[]));return qt?{...mt,sessions:qt.sessions||mt.sessions||[],cells:qt.cells||mt.cells||[],switcherFresh:qt.fresh}:{...mt,switcherFresh:!1}}),pt=FC({...me,sessions:yt.sessions||me.sessions||[],cells:yt.cells||me.cells||[],localFresh:yt.fresh,nodeGroups:Pt,refreshedAt:Date.now()});E(pt),I(!0),Q=!1};X();const _e=setInterval(X,b);return()=>{U=!1,clearInterval(_e)}},[t,b]);const[Ie,Ae]=w.useState(""),Te={getLiveHost:U=>Ud(t,U),designateHostCell:(U,Q,X)=>Wd(t,U,Q,X),clearHostCell:(U,Q)=>qd(t,U,Q)},J=U=>(u[ks(U)]||{}).hostCell||null,Se=async(U,Q)=>{Ae(U.key);const X=await Kd({action:Q?"remove":"use",cellId:U.cellName,route:U.route||[],api:Te});Ae(""),H(p(X.messageKey).replace("{cell}",X.hostCell||U.cellName)),X.ok&&v&&v({route:U.route||[],hostCell:X.hostCell,revision:X.revision})},De=U=>U.degraded?p("cell-degraded"):U.verified?U.selectable?U.working?p("cell-working"):p("cell-idle"):p("cell-off"):p("cell-switcher-not-confirmed"),Me=async U=>{if(H(""),!U.selectable){H(U.verified?p("cell-switcher-not-active"):p("cell-switcher-not-confirmed"));return}A(U.key);try{const Q=await Jp(t,U.route),X=(Q.cells||[]).find(_e=>(_e==null?void 0:_e.cell)===U.cellName&&(_e==null?void 0:_e.tmuxSession)===U.session);if(Q.fresh!==!0){H(p("cell-switcher-verify-failed"));return}if(!t2(X,Q.sessions,Q.fresh)){H(p("cell-switcher-not-active"));return}n({session:U.session,...U.node?{node:U.node}:{},cellName:U.cellName}),s()}catch{H(p("cell-switcher-verify-failed"))}finally{A("")}},Ve=U=>{if(!U.selectable){Me(U);return}if(z===U.key){Me(U);return}V(U.key)},Qe=w.useRef(null),dt=8,at=U=>{const Q=Qe.current;if(U.isPrimary===!1){Q&&Q.state==="open"&&(Q.state="invalid");return}if(Q&&Q.state==="open"&&(Q.id!==U.pointerId||Q.row!==U.currentTarget)){Q.state="invalid";return}Qe.current={id:U.pointerId,row:U.currentTarget,x:U.clientX,y:U.clientY,maxDelta:0,state:"open"}},bt=U=>{const Q=Qe.current;!Q||Q.state!=="open"||Q.id!==U.pointerId||(Q.maxDelta=Math.max(Q.maxDelta,Math.hypot(U.clientX-Q.x,U.clientY-Q.y)),Q.maxDelta>dt&&(Q.state="invalid"))},st=U=>{const Q=Qe.current;!Q||Q.id!==U.pointerId||Q.state!=="open"||(Q.state=Q.maxDelta<=dt?"tap":"invalid")},ft=U=>{const Q=Qe.current;Q&&Q.id===U.pointerId&&(Q.state="invalid")},ot=U=>{const Q=Qe.current;return Qe.current=null,U.detail===0?!0:!Q||Q.state==="invalid"||Q.row!==U.currentTarget?!1:Math.hypot(U.clientX-Q.x,U.clientY-Q.y)<=dt},Rt=U=>({onToggleLive:()=>Se(U,J(U.route||[])===U.cellName),onTogglePin:()=>pg({view:eh({item:{key:U.key,value:{cell:U.cellName}},pins:K,hostByRoute:u,route:U.route||[]}),itemKey:U.key,togglePin:ce,removePin:ne})});return l.jsxs("div",{className:"nc-cell-switcher-backdrop",onClick:s,children:[ke&&l.jsxs("div",{className:"nc-cell-switcher-anteprima","data-testid":"cell-switcher-anteprima",onClick:U=>U.stopPropagation(),children:[l.jsxs("div",{className:"nc-cell-switcher-anteprima-testa",children:[l.jsxs("b",{children:[p("cell-switcher-preview-word")," ",ke.cellName]}),l.jsx("small",{children:p("cell-switcher-preview-readonly")}),l.jsxs("span",{className:"nc-cell-switcher-anteprima-zoom",children:[l.jsx("button",{type:"button",onClick:()=>q(-1),title:p("zoom-out"),"aria-label":p("zoom-out"),children:"−"}),l.jsxs("span",{"data-testid":"cell-switcher-fontsize",children:[G," px"]}),l.jsx("button",{type:"button",onClick:()=>q(1),title:p("zoom-in"),"aria-label":p("zoom-in"),children:"+"})]})]}),l.jsx(og,{row:ke,token:t,source:Y,chrome:!1,panelPort:wc(ke.route||[],a,i),liveHost:Ka({liveHost:u[ks(ke.route||[])],cells:S.cells||[]}),onLiveHostApplied:v,fontSize:G,readOnly:!0})]}),l.jsxs("aside",{ref:M,className:`nc-cell-switcher${ke?" with-anteprima":""}`,role:"dialog","aria-label":p("fleet-cells"),tabIndex:-1,onClick:U=>U.stopPropagation(),children:[l.jsxs("div",{className:"nc-cell-switcher-controls",children:[l.jsx("b",{children:p("cell-switcher-title")}),c&&l.jsx("small",{className:"nc-cell-switcher-node",children:c}),l.jsxs("div",{className:"nc-cell-switcher-filter",role:"group","aria-label":p("cell-switcher-filter"),children:[l.jsx("button",{type:"button",className:C?"":"on","aria-pressed":!C,onClick:()=>{H(""),N(!1)},children:p("cell-switcher-show-active")}),l.jsx("button",{type:"button",className:C?"on":"","aria-pressed":C,onClick:()=>{H(""),N(!0)},children:p("cell-switcher-show-all")})]}),l.jsx("button",{type:"button",className:`nc-cell-switcher-reorder${D?" on":""}`,"aria-pressed":D,title:p("reorder-help"),"aria-label":p("reorder"),onClick:()=>{H(""),j(U=>!U)},children:"↕"}),l.jsx("button",{ref:R,type:"button",className:"nc-cell-switcher-close","aria-label":p("cell-switcher-close"),title:p("cell-switcher-close"),onClick:s,children:"×"})]}),!ke&&l.jsx("div",{className:"nc-cell-switcher-hint",children:p("cell-switcher-tap-hint")}),l.jsxs("div",{className:"nc-cell-switcher-list",children:[(()=>{const U=Ka({liveHost:u[ks([])],cells:S.cells||[]});if(!U||!U.cell)return null;const{modeKey:Q}=HT(U);return l.jsx("div",{className:"nc-cell-switcher-live-strip","data-testid":"cell-switcher-live-strip",children:p("cell-switcher-live-strip").replace("{cell}",U.cell).replace("{mode}",p(Q||"live-host-mode-unknown"))})})(),!k&&l.jsx("div",{className:"nc-empty",role:"status",children:p("cell-switcher-refreshing")}),k&&fe.length===0&&l.jsx("div",{className:"nc-empty",role:"status",children:p("cell-switcher-empty-active")}),fe.map((U,Q)=>{const X=(e==null?void 0:e.session)===U.session&&((e==null?void 0:e.node)||"")===U.node,_e=!!T&&T.key===U.key,me=g!=null&&g===U.key,tt=De(U),ie=ev(p,U.activity),Pe=tv(p,U.telemetry),ut=[ie,Pe].filter(Boolean).join(" · "),yt=U.node||"local",St=Q>0?fe[Q-1].node||"local":null,Pt=yt!==St,pt=$.get(yt)||F.filter(mt=>(mt.node||"local")===yt);return l.jsxs(w.Fragment,{children:[Pt&&l.jsx("div",{className:"nc-cell-switcher-position",children:p("cell-switcher-group").replace("{node}",U.nodeLabel||c||p("cell-switcher-group-local"))}),l.jsxs("div",{className:`nc-cell-switcher-row${X?" current":""}${z===U.key?" selected":""}${me?" side":""}${U.selectable?"":" off"}`,"data-roster-key":U.key,"data-position":yt,children:[D&&l.jsx(Gi,{position:yt,itemKey:U.key,label:U.cellName,canMove:Ee,onMove:(mt,qt)=>pe(yt,mt,qt,pt),onStep:mt=>Re(yt,U.key,mt,pt)}),l.jsx("span",{className:"nc-cell-switcher-peek",children:l.jsx("span",{className:`nc-cell-switcher-dot${U.degraded?" warn":U.live?` on${U.working?" working":""}`:""}`})}),l.jsx("button",{type:"button",className:"nc-cell-switcher-row-select","aria-current":X?"true":void 0,"aria-disabled":!U.selectable,"data-selected":z===U.key?"true":void 0,disabled:O===U.key,onPointerDown:at,onPointerMove:bt,onPointerUp:st,onPointerCancel:ft,onClick:mt=>{ot(mt)&&Ve(U)},children:l.jsxs("span",{className:"nc-cell-switcher-copy",children:[l.jsxs("span",{className:"nc-cell-switcher-nameline",children:[l.jsx("b",{children:U.cellName}),X&&l.jsx("span",{className:"nc-cell-switcher-here",children:p("cell-switcher-here")}),z===U.key&&l.jsx("span",{className:"nc-cell-switcher-taptwo",children:p("cell-switcher-two-taps")})]}),l.jsxs("span",{className:"nc-cell-switcher-stateline",children:[l.jsx("small",{className:"nc-cell-switcher-state",children:tt}),ut&&l.jsx("small",{className:"nc-cell-switcher-telemetry",children:ut})]})]})}),_&&l.jsx("button",{type:"button",className:`nc-cell-switcher-side${me?" on":""}`,title:p(me?"cell-switcher-side-remove":"cell-switcher-side-add"),"aria-label":p(me?"cell-switcher-side-remove":"cell-switcher-side-add"),"aria-pressed":me?"true":"false",disabled:X||!U.selectable,onClick:mt=>{mt.stopPropagation(),!X&&U.selectable&&_(U)},children:l.jsxs("svg",{viewBox:"0 0 24 24",width:"20",height:"20","aria-hidden":"true",focusable:"false",children:[l.jsx("rect",{x:"3.5",y:"5.5",width:"17",height:"13",rx:"1.5"}),l.jsx("line",{x1:"3.5",y1:"12",x2:"20.5",y2:"12"})]})}),l.jsx("button",{type:"button",className:`nc-cell-switcher-menu${_e?" on":""}`,title:`${p("cell-actions-open")}: ${U.cellName}`,"aria-label":`${p("cell-actions-open")}: ${U.cellName}`,"aria-haspopup":"menu","aria-expanded":_e?"true":"false",onClick:mt=>{mt.stopPropagation(),P({key:U.key})},children:"⋯"})]})]},U.key)})]}),L&&l.jsx("div",{className:"nc-cell-switcher-notice",role:"status",children:L}),ge&&(()=>{const U=we,Q=mg({...oo({item:{key:U.key,value:{cell:U.cellName}},cellName:U.cellName,route:U.route||[],pins:K,hostByRoute:u}),canBoot:!1,alive:U.selectable,handlers:Rt(U)});return l.jsx(vg,{cellName:U.cellName,items:Q,busy:Ie===U.key,onClose:()=>P(null)})})()]})]})}function WS(){let t=0,e=!1;return{begin(){return e?null:(e=!0,t+=1,t)},end(n){n===t&&(e=!1)},reset(){t+=1,e=!1},isCurrent(n){return n!==null&&n===t}}}const T6=2e3;function P6(t){if(t.kind==="gap")return`${p("vl-events-gap")} ${t.count||"?"}`;if(t.kind==="truncate")return p("vl-events-truncated");if(t.kind==="turn_end")return p("vl-events-turn-end");if(t.kind==="done")return p("vl-events-done");if(t.kind==="writer_epoch")return p("vl-events-writer-epoch");if(t.kind==="tool_start")return`${p("vl-events-tool")} ${t.name||""}`.trim();if(t.kind==="tool_end"){const e=t.isError?p("vl-events-tool-failed"):p("vl-events-tool-ok");return`${p("vl-events-tool")} ${t.name||""} — ${e}`.trim()}return t.kind==="usage"?t.text||p("vl-events-usage"):t.text||""}function I6({token:t,nodeId:e,route:n=[]}){const[s,i]=w.useState([]),[a,c]=w.useState(!1),u=w.useRef(0),h=w.useRef(!1);return w.useEffect(()=>{let f=!0;u.current=0,h.current=!1,i([]);const v=async()=>{if(!h.current){h.current=!0;try{const b=await p5(t,e,u.current,n);if(!f)return;c(!1);const E=(Array.isArray(b==null?void 0:b.events)?b.events:[]).filter(C=>Number.isSafeInteger(C==null?void 0:C.seq)&&C.seq>u.current);E.length&&(i(C=>C.concat(E).slice(-500)),u.current=E[E.length-1].seq),Number.isSafeInteger(b==null?void 0:b.cursor)&&b.cursor>u.current&&(u.current=b.cursor)}catch{f&&c(!0)}finally{h.current=!1}}},g=()=>{v().catch(()=>{})};g();const _=setInterval(g,T6);return()=>{f=!1,clearInterval(_)}},[t,e,JSON.stringify(n)]),l.jsxs("div",{className:"nc-vl-events",children:[a&&l.jsx("div",{className:"nc-set-hint nc-vl-events-stale",children:p("vl-events-stale")}),s.length===0&&!a&&l.jsx("small",{className:"nc-set-hint","data-testid":"vl-events-empty",children:p("vl-events-empty")}),s.length>0&&l.jsx("ol",{className:"nc-vl-events-list",children:s.map(f=>l.jsx("li",{"data-testid":`vl-ev-${f.seq}`,className:`nc-vl-ev nc-vl-ev-${f.kind}${f.isError?" error":""}${f.kind==="gap"?" gap":""}`,children:P6(f)},`${f.seq}-${f.kind}`))})]})}function qS({peer:t,token:e,onBack:n}){var s;return qn(),t?l.jsxs("section",{className:"nc-vl-session-view",children:[l.jsxs("header",{className:"nc-bar nc-bar-single",children:[l.jsxs("button",{onClick:n,title:p("back"),children:[l.jsx(Dt,{name:"chevronLeft",size:18}),l.jsx("span",{className:"nc-bar-label",children:p("back")})]}),l.jsxs("span",{className:"nc-bar-center",children:[l.jsx("b",{title:t.label,children:t.label}),((s=t.session)==null?void 0:s.profile)&&l.jsxs("small",{className:"nc-bar-sub",children:[t.session.profile," · ",p("vl-events-title")]})]}),l.jsx("span",{className:"nc-bar-right"})]}),l.jsx("div",{className:"nc-vl-session-body",children:l.jsx(I6,{token:e,nodeId:t.nodeId,route:t.route||[]})})]}):null}const Od="nc_dual_side";function Pv(t,e){return!t||!e?!1:t.session===e.session&&(t.node||"")===(e.node||"")}function D6(t,e,n){return!n||!n.session||t&&Pv(t,n)?e:e&&Pv(e,n)?null:{session:n.session,...n.node?{node:n.node}:{},...n.ownerId?{ownerId:n.ownerId}:{}}}function O6(){try{const t=JSON.parse(localStorage.getItem(Od)||"null");return!t||!t.main||!t.side||!t.main.session||!t.side.session?null:t}catch{return null}}function B6(t,e){try{if(!t||!e||!t.session||!e.session){localStorage.removeItem(Od);return}const n=s=>({session:s.session,...s.node?{node:s.node}:{}});localStorage.setItem(Od,JSON.stringify({main:n(t),side:n(e)}))}catch{}}function KS(){try{localStorage.removeItem(Od)}catch{}}const $6=.2;function td(t){return Math.max($6,t)}function z6(){try{if(typeof matchMedia=="function"&&matchMedia("(pointer: coarse)").matches)return!0}catch{}try{return Number(globalThis.navigator&&globalThis.navigator.maxTouchPoints)>0}catch{return!1}}function F6({onSubmit:t,reason:e=""}){qn();const[n,s]=w.useState(""),[i,a]=w.useState(z6),c=n.trim(),u=h=>{h&&h.preventDefault&&h.preventDefault(),c&&t(c,i)};return l.jsxs("form",{className:"nc-auth",onSubmit:u,children:[l.jsx("p",{children:p("auth-prompt")}),e==="invalid"&&l.jsx("p",{className:"nc-auth-error",role:"alert",children:p("auth-invalid")}),l.jsx("input",{type:"text",value:n,placeholder:"token","aria-label":"token",autoComplete:"off",autoCapitalize:"off",autoCorrect:"off",spellCheck:!1,onChange:h=>s(h.target.value)}),l.jsxs("label",{children:[l.jsx("input",{type:"checkbox",checked:i,onChange:h=>a(h.target.checked)})," ",p("remember-device")]}),l.jsx("button",{type:"submit",disabled:!c,children:"ok"})]})}const Qp=t=>_s(Ti(t)).length===0;function Ba(t,e){return Array.isArray(t)?t.flatMap(n=>{var c;const s={session:n.session,height:1,fontSize:n.fontSize};n.node&&(s.node=n.node),n.ownerId&&(s.ownerId=n.ownerId);const i=(c=e({columns:[{width:1,tiles:[s]}]}).columns[0])==null?void 0:c.tiles[0];if(!i)return[];const a={session:i.session,x:n.x,y:n.y,w:n.w,h:n.h,fontSize:n.fontSize};return i.node&&(a.node=i.node),i.ownerId&&(a.ownerId=i.ownerId),[a]}):[]}function VS(t,e){return t.length?t:Array.isArray(e.floating)&&e.floating.length?[]:void 0}function H6(t,e,n,s,i){const a=c=>Ba(c&&c.floating,u=>za(u,s,i));return eP(a(t),a(e),n)}function YS(t,e,n,s,i,a){const c=g=>za(g,i,a),u=g=>Ba(g&&g.floating,c),{grid:h,floating:f}=Ad(n),v=tP(s(h),H6(t,e,f,i,a),{grid:t?c(t.layout):uo(),floating:u(t)},{grid:c(e.layout),floating:u(e)},{grid:h,floating:f});return fv(v.grid,v.floating)}const Zp=t=>Array.isArray(t)?t.join("/"):"",U6="nc-decks-cache-v1",n2=t=>`${U6}:${t}`;function W6(t){if(!t)return[];try{const e=localStorage.getItem(n2(t));if(!e)return[];const n=JSON.parse(e);return Array.isArray(n)&&n.every(s=>s&&typeof s.id=="string"&&typeof s.name=="string")?n:[]}catch{return[]}}function q6(t,e){if(t)try{localStorage.setItem(n2(t),JSON.stringify(e))}catch{}}function K6(t){const e=new Set,n=[];for(const s of Array.isArray(t)?t:[])!s||!Ks.test(String(s.instanceId||""))||!Array.isArray(s.route)||!s.route.length||e.has(s.instanceId)||(e.add(s.instanceId),n.push({instanceId:s.instanceId,route:[...s.route],label:String(s.label||s.name||s.route.join(" › ")),status:s.status||"offline",stale:s.stale===!0}));return n.sort((s,i)=>s.label.localeCompare(i.label))}function Jl(t){return{instanceId:t.ownerId,route:t.ownerRoute||[],label:t.ownerLabel,status:t.available===!1?"offline":"up"}}function Po(t,e,n,s=!1,i=!0){const a=e.instanceId;return{...t,id:qo(s?null:a,t.name),ownerId:a,ownerRoute:s?[]:[...e.route],ownerLabel:s?"Local":e.label,local:s,available:i,ownerTopology:Array.isArray(n)?n:[],layout:bv(t.layout,a,n)}}function V6(t,e,n,s,i=[]){const[a,c]=w.useState([]),[u,h]=w.useState(!1),[f,v]=w.useState("idle"),[g,_]=w.useState(""),[b,S]=w.useState(!1),[E,C]=w.useState(""),N=w.useRef([]),k=w.useRef([]),I=w.useRef(new Map),L=w.useRef(""),H=w.useRef(e),z=w.useRef(n),V=w.useRef(!1),Y=w.useRef(!0),G=w.useRef(""),Z=w.useMemo(()=>K6(i),[i]),q=Z.map(de=>`${de.instanceId}:${Zp(de.route)}`).join("|");k.current=Z,z.current=n,H.current=e,N.current=a;const T=w.useCallback(de=>za(de.layout,L.current,k.current),[]),P=w.useCallback(()=>Yl(H.current,L.current),[]),D=w.useCallback(de=>(Array.isArray(de)?de:[]).find(fe=>fe.id===P()),[P]),j=w.useCallback((de,fe=!0,ke)=>{const we=ke===void 0?P():Yl(ke,L.current),ge=H0(de,Gu()),Ie=N.current.some(Te=>Te.id===we);N.current=ge,c(ge),q6(L.current,ge.map(Te=>{if(!Te.refreshFailedAt)return Te;const J={...Te};return delete J.refreshFailedAt,J}));const Ae=ge.find(Te=>Te.id===we);if(fe&&Ae){Y.current=!0;const Te=fv(T(Ae),Ba(Ae.floating,J=>za(J,L.current,k.current)));s(Te),Ae.local&&_I(Ae.name,Ti(Te))}else Ie&&!Ae&&(Y.current=!0,s(uo()),_("deck non più condiviso dal nodo owner"));pI(ge.filter(Te=>Te.local).map(Te=>Te.name))},[s,T]),O=w.useCallback(async de=>{let fe=await Iu(t);const ke=fe.decks.find(we=>we.name==="main");if(fe.decks.length===1&&ke&&ke.revision===0&&Qp(ke.layout)){const we=fI(),ge=Ti(Sv("main")||uo());if(!Qp(ge)){const Ie=bv(ge,de,[]);fe.decks[0]=await Du(t,"main",Ie,0,[])}for(const Ie of we.filter(Ae=>Ae!=="main"))try{let Ae=await kw(t,Ie,[]);const Te=Ti(Sv(Ie)||uo());Qp(Te)||(Ae=await Du(t,Ie,bv(Te,de,[]),Ae.revision,[]))}catch{}fe=await Iu(t)}return fe},[t]),A=w.useCallback((de,fe)=>{const ke=new Map(fe.map(Ie=>[Ie.id,Ie])),we=new Set,ge=[];for(const Ie of N.current){if(Ie.local||Ie.ownerId!==de.instanceId){ge.push(Ie);continue}const Ae=ke.get(Ie.id);Ae&&(ge.push(Ae),we.add(Ie.id))}for(const Ie of fe)we.has(Ie.id)||ge.push(Ie);j(ge,!1)},[j]),M=w.useCallback(async de=>{try{const[fe,ke]=await Promise.all([Iu(t,de.route),Sw(t,de.route).catch(()=>({nodes:[]}))]);A(de,fe.decks.map(we=>Po(we,de,ke.nodes,!1,!0)))}catch(fe){if(fe&&(fe.status===403||fe.status===404)){A(de,[]);return}const ke=N.current.filter(we=>!we.local&&we.ownerId===de.instanceId).map(we=>({...we,available:!1,stale:!0,refreshFailedAt:Date.now(),ownerRoute:[...de.route],ownerLabel:de.label}));A(de,ke)}},[t,A]),R=w.useCallback(async({migrate:de=!1}={})=>{const fe=await Hv(t,[]),ke=Ks.test(String(fe.instanceId||""))?fe.instanceId:"";if(!ke)throw new Error("instanceId locale non disponibile");L.current=ke,C(ke);const[we,ge]=await Promise.all([de?O(ke):Iu(t),Sw(t,[]).catch(()=>({nodes:[]}))]),Ie={instanceId:ke,route:[],label:"Local"},Ae=we.decks.map(Ve=>Po(Ve,Ie,ge.nodes,!0,!0)),Te=new Map(k.current.map(Ve=>[Ve.instanceId,Ve])),J=N.current.length?N.current:W6(ke),Se=I.current,De=Date.now(),Me=J.filter(Ve=>!Ve.local).flatMap(Ve=>{const Qe=Te.get(Ve.ownerId);if(!Qe){const at=Se.get(Ve.ownerId);return at===void 0?(Se.set(Ve.ownerId,De),[{...Ve,available:!1,stale:!0}]):De-at>mC?[]:[{...Ve,available:!1,stale:!0}]}Se.delete(Ve.ownerId);const dt=Qe.status==="up";return[{...Ve,available:dt?Ve.available!==!1:!1,stale:Qe.stale===!0,ownerRoute:[...Qe.route],ownerLabel:Qe.label}]});return setTimeout(()=>{for(const Ve of Te.values())Ve.status==="up"&&M(Ve)},0),[...Ae,...Me]},[t,O,M,q]);w.useEffect(()=>{if(!t)return;let de=!1;const fe=G.current!==t;return G.current=t,R({migrate:fe}).then(ke=>{if(de)return;const we=D(N.current),ge=D(ke),Ie=ge&&(!we||ge.revision>we.revision||we.available!==ge.available||Zp(we.ownerRoute)!==Zp(ge.ownerRoute));j(ke,fe||!!Ie&&!V.current),h(!0),ge&&_("")}).catch(ke=>{de||(h(!0),_(String(ke.message||ke)))}),()=>{de=!0}},[j,R,q,t,D]);const F=w.useCallback(async(de,fe=!0)=>{if(!u||!V.current)return!0;const ke=de===void 0?P():Yl(de,L.current),we=N.current.find(ge=>ge.id===ke);if(!we)return _(`deck inesistente: ${ke}`),!1;if(we.available===!1)return _(`nodo owner offline: ${we.ownerLabel}`),!1;v("saving");try{const{grid:ge,floating:Ie}=Ad(z.current),Ae=Gl(Ti(ge),we.ownerId,we.ownerTopology),Te=Ba(Ie,De=>Gl(De,we.ownerId,we.ownerTopology)),J=await Du(t,we.name,Ae,we.revision,we.ownerRoute,VS(Te,we)),Se=Po(J,Jl(we),we.ownerTopology,we.local,!0);return j(N.current.map(De=>De.id===ke?Se:De),!1),V.current=!1,v("saved"),_(""),S(!1),setTimeout(()=>v("idle"),1500),!0}catch(ge){if(fe&&ge.status===409&&ge.data&&ge.data.current){const Ie=N.current.find(Ae=>Ae.id===ke);if(Ie){const Ae=Po(ge.data.current,Jl(Ie),Ie.ownerTopology,Ie.local,!0),Te=YS(Ie,Ae,z.current,J=>J,L.current,k.current);return nP(Te,z.current)||(z.current=Te,Y.current=!0,s(Te)),j(N.current.map(J=>J.id===ke?Ae:J),!1),V.current=!0,F(ke,!1)}}return v("error"),_(String(ge.message||ge)),ge.status===409&&S(!0),!1}},[u,t,j,s]),$=w.useCallback(async()=>{try{const de=await R();V.current=!1,S(!1),j(de,!0),_("")}catch(de){_(String(de.message||de))}},[R,j]);w.useEffect(()=>{if(!u)return;const de=Y.current&&!V.current;if(Y.current=!1,de)return;V.current=!0,v("saving");const fe=setTimeout(F,650);return()=>clearTimeout(fe)},[n,u,F]),w.useEffect(()=>{if(!u)return;const de=()=>{if(!V.current)return;const fe=N.current.find(Ae=>Ae.id===P());if(!fe||fe.available===!1)return;const{grid:ke,floating:we}=Ad(z.current),ge=Gl(Ti(ke),fe.ownerId,fe.ownerTopology),Ie=Ba(we,Ae=>Gl(Ae,fe.ownerId,fe.ownerTopology));q5(t,fe.name,ge,fe.revision,fe.ownerRoute,VS(Ie,fe))};return window.addEventListener("pagehide",de),window.addEventListener("beforeunload",de),()=>{window.removeEventListener("pagehide",de),window.removeEventListener("beforeunload",de)}},[u,t,P]),w.useEffect(()=>{if(!u)return;const de=setInterval(async()=>{try{const fe=await R(),ke=D(N.current),we=D(fe),ge=!!(we&&ke&&we.revision>ke.revision),Ie=!!(we&&(!ke||ge||ke.available!==we.available));if(ge&&V.current&&we){const Ae=YS(ke,we,z.current,Te=>rP(T(we),Te),L.current,k.current);j(fe,!1),s(Ae);return}j(fe,Ie&&!V.current)}catch{}},5e3);return()=>clearInterval(de)},[u,R,j,T,s]);const K=w.useCallback(de=>{s(fe=>{const ke=de(fe);return ke!==fe&&(Y.current=!0),ke})},[]),oe=async(de,fe=null)=>{const ke=fe===Xi?N.current.find(Ie=>Ie.local):fe?N.current.find(Ie=>Ie.ownerId===fe):null;if(!ke||ke.available===!1)throw new Error("nodo owner non disponibile");const we=await kw(t,de,ke.ownerRoute),ge=Po(we,Jl(ke),ke.ownerTopology,ke.local,!0);return j([...N.current,ge],!1),ge},ce=async(de,fe)=>{const ke=N.current.find(Te=>Te.id===de);if(!ke)throw new Error("deck inesistente");if(Yl(de,L.current)===P()&&V.current&&!await F(de))throw new Error(`salvataggio di "${ke.name}" fallito: rinomina annullata`);const we=N.current.find(Te=>Te.id===de);if(!we)throw new Error("deck inesistente");const ge=await K5(t,we.name,fe,we.revision,we.ownerRoute),Ie=Po(ge,Jl(we),we.ownerTopology,we.local,!0),Ae=we.local?Xi:we.ownerId;return Sp(vI(Gu(),Ae,de,Ie.id)),j(N.current.map(Te=>Te.id===de?Ie:Te),!1),Ie},ne=async de=>{const fe=N.current.find(we=>we.id===de);if(!fe)throw new Error("deck inesistente");Yl(de,L.current)===P()&&(V.current=!1),await V5(t,fe.name,fe.revision,fe.ownerRoute);const ke=fe.local?Xi:fe.ownerId;Sp(gI(Gu(),ke,de)),j(N.current.filter(we=>we.id!==de),!1)},Le=(de,fe)=>{const ke=N.current.find(J=>J.id===de),we=N.current.find(J=>J.id===fe);if(!ke||!we)return!1;const ge=ke.local?Xi:ke.ownerId,Ie=we.local?Xi:we.ownerId;if(ge!==Ie)return!1;const Ae=N.current.filter(J=>(J.local?Xi:J.ownerId)===ge).map(J=>J.id),Te=Sp(mI(Gu(),ge,de,fe,Ae));return j(H0(N.current,Te),!1),!0},Ee=async(de,fe)=>{const ke=N.current.find(J=>J.id===de);if(!ke)throw new Error("deck inesistente");if(ke.available===!1)throw new Error(`nodo owner offline: ${ke.ownerLabel}`);const we=sk(fe,L.current,k.current);if(!we)throw new Error("riferimento sessione non valido");const ge=T(ke),Ie=Gl(jC(ge,we),ke.ownerId,ke.ownerTopology),Ae=await Du(t,ke.name,Ie,ke.revision,ke.ownerRoute),Te=Po(Ae,Jl(ke),ke.ownerTopology,ke.local,!0);return j(N.current.map(J=>J.id===de?Te:J),!1),Te},pe=w.useCallback(de=>fv(T(de),Ba(de.floating,fe=>za(fe,L.current,k.current))),[T]);return{decks:a,records:a,localNodeId:E,ready:u,saveState:f,error:g,setError:_,conflict:b,reloadCurrent:$,saveNow:F,select:async de=>{if(V.current&&!await F(P()))throw new Error("salvataggio del deck corrente fallito: cambio annullato");const fe=N.current.find(ke=>ke.id===de);if(!fe)throw new Error(`deck inesistente: ${de}`);return V.current=!1,Y.current=!0,pe(fe)},add:oe,rename:ce,remove:ne,reorder:Le,addTileTo:Ee,viewUpdate:K,vistaMaterializzata:pe,localMainId:qo(null,"main"),parseDeckId:Oc}}const Y6="/sw.js",Iv="nc-sw-update";let Rc=null,Bd=!1,$d=null,s2=Object.freeze({needed:!1,kind:null,version:"",browserVersion:""}),i2=!1;function Yg(){typeof window<"u"&&window.dispatchEvent(new Event(Iv))}function Gg(){const t=$d||(Bd?{kind:"reload",version:"",browserVersion:""}:null);s2=Object.freeze({needed:!!t,kind:(t==null?void 0:t.kind)||null,version:(t==null?void 0:t.version)||"",browserVersion:(t==null?void 0:t.browserVersion)||""})}function GS(){return s2}function G6(t){return typeof window>"u"?()=>{}:(window.addEventListener(Iv,t),()=>window.removeEventListener(Iv,t))}function Xg(t){Bd!==t&&(Bd=t,Gg(),Yg())}const nd="nc-auto-reload",zd="nc-reload";function Jg(){try{return typeof location<"u"?location:null}catch{return null}}function r2(){try{return typeof history<"u"?history:null}catch{return null}}function X6(t){const e=t===void 0?Jg():t;if(!e||typeof e.search!="string")return null;try{return new URLSearchParams(e.search).get(zd)}catch{return null}}function J6(t,{location:e,history:n}={}){const s=e===void 0?Jg():e,i=n===void 0?r2():n;if(!s||!i||typeof i.replaceState!="function")return!1;try{const a=new URLSearchParams(s.search||"");return a.set(zd,t),i.replaceState(i.state??null,"",`${s.pathname||"/"}?${a.toString()}${s.hash||""}`),!0}catch{return!1}}function Q6({location:t,history:e}={}){const n=t===void 0?Jg():t,s=e===void 0?r2():e;if(!n||!s||typeof s.replaceState!="function")return!1;try{const i=new URLSearchParams(n.search||"");if(!i.has(zd))return!1;i.delete(zd);const a=i.toString();return s.replaceState(s.state??null,"",`${n.pathname||"/"}${a?`?${a}`:""}${n.hash||""}`),!0}catch{return!1}}const o2="nc-update-dismissed";function a2(){try{return typeof sessionStorage<"u"?sessionStorage:null}catch{return null}}function Z6(t,e,n){return[t,e,n].map(s=>s||"").join("|")}let Dv=null;function e4(t,e,n){const s=n;return t&&e&&t!==e&&t!==s?{kind:"install",version:t,browserVersion:s}:e&&s&&e!==s?{kind:"stale",version:e,browserVersion:s}:null}function t4(t,e){if(!t)return!1;try{return t.getItem(o2)===e}catch{return!1}}function n4(t={}){const e=t.storage===void 0?a2():t.storage;if(Dv&&e)try{e.setItem(o2,Dv)}catch{}Bd=!1,$d=null,Gg(),Yg()}function s4(t,e,n,s={}){const i=s.storage===void 0?a2():s.storage,a=n,c=Z6(t,e,a);Dv=c;const u=e4(t,e,a);let h=t4(i,c)?null:u;if(h&&h.kind==="stale"){const v=`${e}|${a}`,g=X6(s.location)===v;let _=!1;if(!g&&i&&i.getItem(nd)!==v){try{i.setItem(nd,v)}catch{}_=i.getItem(nd)===v}_&&(J6(v,{location:s.location,history:s.history}),(s.applyImpl||l2)(),h=null)}const f=JSON.stringify(h)===JSON.stringify($d);if($d=h,Gg(),f||Yg(),!u){try{i&&i.removeItem(nd)}catch{}Q6({location:s.location,history:s.history})}}const i4=1200;async function XS(t){if(typeof fetch=="function")try{await Promise.race([fetch(t,{cache:"reload"}),new Promise(e=>setTimeout(e,i4))])}catch{}}async function l2(){try{Rc&&await Rc.update()}catch{}typeof location<"u"&&(await XS(location.pathname),await XS("/version.json"),location.reload())}function r4(t){t.addEventListener("statechange",()=>{t.state==="installed"&&navigator.serviceWorker.controller&&Xg(!0)})}function o4(){typeof navigator>"u"||!("serviceWorker"in navigator)||(navigator.serviceWorker.addEventListener("controllerchange",()=>{i2&&location.reload()}),navigator.serviceWorker.register(Y6).then(t=>{Rc=t,t.waiting&&Xg(!0),t.addEventListener("updatefound",()=>{const e=t.installing;e&&r4(e)}),setInterval(()=>{t.update().catch(()=>{})},3600*1e3)}).catch(()=>{}))}function a4(){i2=!0,Xg(!1);const t=Rc&&Rc.waiting;t?(t.postMessage({type:"SKIP_WAITING"}),setTimeout(()=>location.reload(),4e3)):location.reload()}function l4({hash:t="",origin:e="",pathname:n="",search:s=""}={}){const i=String(t||"").replace(/^#/,""),a=`${n||""}${s||""}`;if(!i)return{token:"",pair:"",device:"",nextUrl:a};const c=new URLSearchParams(i),u=c.get("token")||"",h=c.get("device")||"",f=/^[a-f0-9]{32}$/.test(h)?h:"",v=c.get("pair")||"",g=v?`${e||""}${n||""}#pair=${v}`:"";return{token:u,pair:g,device:f,nextUrl:a}}const c2="nc_side_w",JS="nc_side_min",c4=240,QS=new Set(["absent","present","active","unknown"]);function u4(){const t=Number(localStorage.getItem(c2));return t>=180&&t<=480?t:c4}function d4(){const t={token:"",pair:""};try{const{token:e,pair:n,device:s,nextUrl:i}=l4({hash:location.hash,origin:location.origin,pathname:location.pathname,search:location.search});if(e&&(t.token=e,c1(e,{remember:!0})),s&&HD(s),n){t.pair=n;try{sessionStorage.setItem("nc_pair",n)}catch{}}if(location.hash)try{history.replaceState(null,"",i)}catch{}}catch{}if(t.token||(t.token=GE()),!t.pair){const e=sessionStorage.getItem("nc_pair");e&&(t.pair=e)}return t}function ZS(t){try{return Ti(Sv(t))}catch{return uo()}}function e1(t){if(!t)return"";const e=Math.floor(Date.now()/1e3)-t;return e<0||e<60?"ora":e<3600?`${Math.floor(e/60)}m`:e<86400?`${Math.floor(e/3600)}h`:`${Math.floor(e/86400)}g`}const u2="nc_bar_files_button";function h4(){try{return localStorage.getItem(u2)==="on"}catch{return!1}}function f4(t){try{localStorage.setItem(u2,t?"on":"off")}catch{}}function p4({showComposer:t,showFiles:e,showPanel:n,hasPanel:s,rendererKind:i,filesSetting:a=null,handlers:c={}}={}){const u=[];return typeof c.onToggleComposer=="function"&&u.push({id:"keyboard",kind:"switch",on:!!t,labelKey:"bar-menu-keyboard",descKey:"bar-menu-keyboard-desc",run:c.onToggleComposer}),typeof c.onToggleFiles=="function"&&u.push(a===null?{id:"files",kind:"switch",on:!!e,labelKey:"bar-menu-files",descKey:"bar-menu-files-desc",run:c.onToggleFiles}:{id:"files",kind:"switch",on:!!a,labelKey:"bar-menu-files",descKey:"bar-menu-files-setting-desc",run:c.onToggleFiles}),s&&typeof c.onTogglePanel=="function"&&u.push({id:"panel",kind:"switch",on:!!n,labelKey:"bar-menu-panel",descKey:"bar-menu-panel-desc",run:c.onTogglePanel}),typeof c.onSwitchRenderer=="function"&&u.push({id:"renderer",kind:"switch",on:i==="webgl",labelKey:"bar-menu-renderer",descKey:"bar-menu-renderer-desc",run:c.onSwitchRenderer}),u}function m4(t,e){if(!t||!t.tmux)return"";const n=th(t,e||{});return n.stato==="lavora"?p("cell-working"):n.stato==="attesa"?p("cell-permission"):n.stato==="ferma"?p("cell-idle"):""}function t1({session:t,node:e,ownerId:n,cellName:s,token:i,readonly:a=!1,panelPort:c=0,onBack:u,onCellSwitcher:h,cellSwitcherOpen:f=!1,liveHost:v=null,side:g=null,onSideClose:_=null,onSideGone:b=null}){var Ns;qn();const[S]=Cg(),E=tC(),[C,N]=w.useState(!1),[k,I]=w.useState(null),[L,H]=w.useState(()=>window.matchMedia("(pointer: coarse)").matches),[z,V]=w.useState(Tv),[Y,G]=w.useState(uc),[Z,q]=w.useState(()=>uc()),T=()=>{const Ke=aM(lM(uc()));G(Ke),typeof window<"u"&&window.location.reload()},[P,D]=w.useState(s||t),[j,O]=w.useState(""),[A,M]=w.useState(""),[R,F]=w.useState(""),[$,K]=w.useState(!1),[oe,ce]=w.useState(!1),ne=!!g&&oe,[Le,Ee]=w.useState(!1),[pe,Re]=w.useState({v:{main:1,side:1},h:{main:1,side:1}}),[de,fe]=w.useState(()=>window.matchMedia("(orientation: landscape)").matches);w.useEffect(()=>{const Ke=window.matchMedia("(orientation: landscape)"),Ze=sn=>fe(sn.matches);return Ke.addEventListener("change",Ze),()=>Ke.removeEventListener("change",Ze)},[]);const ke=de?pe.h:pe.v,we=w.useRef(ke);we.current=ke;const[ge,Ie]=w.useState(null),[Ae,Te]=w.useState(!0),J=w.useRef(()=>{}),Se=w.useRef(()=>!1),De=w.useRef(()=>{}),Me=w.useRef(!1),Ve=w.useRef(!1),Qe=w.useRef(null),dt=w.useRef(null),[at,bt]=w.useState(null),st=w.useCallback(Ke=>bt({source:"main",ev:Ke}),[]),ft=w.useCallback(Ke=>bt({source:"side",ev:Ke}),[]),ot=!!g&&(at==null?void 0:at.source)==="side",Rt=Ke=>{ce(Ke),pt((Ke?Me:St).current),Kt((Ke?Ve:mt).current)},U=g?`${g.node||""}:${g.session}`:"";w.useEffect(()=>{ce(!1),Ee(!1),Re({v:{main:1,side:1},h:{main:1,side:1}}),Ie(null),bt(Ke=>Ke&&Ke.source==="side"?null:Ke)},[U]);const Q=w.useMemo(()=>{const Ke=new Map;return Ze=>{if(Ke.has(Ze))return Ke.get(Ze);let sn=Ze*.6;try{const te=document.createElement("span");te.style.cssText="position:absolute;visibility:hidden;white-space:pre;font-family:courier-new,courier,monospace;",te.style.fontSize=`${Ze}px`,te.textContent="0".repeat(20),document.body.appendChild(te);const xe=te.getBoundingClientRect().width;document.body.removeChild(te),Number.isFinite(xe)&&xe>0&&(sn=xe/20)}catch{}return Ke.set(Ze,sn),sn}},[]),X=Math.max(.01,ke.main+ke.side),_e=((Ns=dt.current)==null?void 0:Ns.clientWidth)||window.innerWidth,me=Math.max(0,_e-12)*(Math.min(ke.main,ke.side)/X)-26,tt=!!g&&de&&me/Q(Math.max(1,z))<40,ie=Ke=>V(Ze=>e2(Ze+Ke));w.useEffect(()=>{f||V(Tv())},[f]);const Pe=w.useRef(()=>{}),ut=w.useRef(()=>!1),yt=w.useRef(()=>{}),St=w.useRef(!1),[Pt,pt]=w.useState(!1),mt=w.useRef(!1),[qt,Kt]=w.useState(!1),Bt=w.useRef(null),[ln,an]=w.useState(!1),tn=()=>{const Ke=ne?Me:St;Ke.current=!Ke.current,pt(Ke.current)},hn=()=>{const Ke=ne?Ve:mt;Ke.current=!Ke.current,Kt(Ke.current)};w.useEffect(()=>{D(s||t),K(!1)},[s,t]),w.useEffect(()=>{let Ke=!0;const Ze=e?e.split("/"):[],sn=e?`/api/route/${e.split("/").map(encodeURIComponent).join("/")}/_`:"/api";async function te(){let ze=null,qe=null;try{const se=await(await bn(`${sn}/sessions`,i)).json();Array.isArray(se.sessions)&&(ze=se.sessions.find(be=>be.name===t))}catch{}try{const W=await Cr(i,Ze);W.available&&Array.isArray(W.cells)&&(qe=W.cells.find(se=>se.tmuxSession===t))}catch{}if(!Ke)return;D(Cc({session:t,cell:qe||(s?{cell:s}:null)})),M(typeof(qe==null?void 0:qe.panelUrl)=="string"?qe.panelUrl.trim():""),F(typeof(qe==null?void 0:qe.cell)=="string"?qe.cell:"");let xt="";qe?xt=[`${qe.engine}${qe.key?`·${qe.key}`:""}`,m4(qe,ze)].filter(Boolean).join(" · "):ze&&(xt=ze.attached?`attached · ${e1(ze.activity)}`:ze.activity?e1(ze.activity):""),O(xt),Te(!!(ze||qe))}te();const xe=setInterval(te,4e3);return()=>{Ke=!1,clearInterval(xe)}},[t,e,i]);const fn=w.useRef(b);fn.current=b,w.useEffect(()=>{if(!g){Ie(null);return}let Ke=!0;const Ze=g.node?g.node.split("/"):[],sn=g.node?`/api/route/${g.node.split("/").map(encodeURIComponent).join("/")}/_`:"/api";async function te(){var se;let ze=null,qe=null,xt=!1,W=!1;try{const He=await(await bn(`${sn}/sessions`,i)).json();Array.isArray(He.sessions)&&(xt=!0,ze=He.sessions.find(Ne=>Ne.name===g.session))}catch{}try{const be=await Cr(i,Ze);be.available&&Array.isArray(be.cells)&&(W=!0,qe=be.cells.find(He=>He.tmuxSession===g.session))}catch{}Ke&&(Ie({title:Cc({session:g.session,cell:qe}),present:!!(ze||qe)}),(xt||W)&&!ze&&!qe&&((se=fn.current)==null||se.call(fn)))}te();const xe=setInterval(te,4e3);return()=>{Ke=!1,clearInterval(xe)}},[g==null?void 0:g.session,g==null?void 0:g.node,i]);const Vt=ne?"side":"main",[Xt,pn]=w.useState(h4),Jt=()=>bt(Ke=>Ke&&Ke.source===Vt?null:{source:Vt,ev:null}),Qt=p4({showComposer:L,showFiles:(at==null?void 0:at.source)===Vt,showPanel:$,hasPanel:!!A,rendererKind:Z,filesSetting:E?null:Xt,handlers:{onToggleComposer:()=>H(Ke=>!Ke),onToggleFiles:E?Jt:()=>pn(Ke=>(f4(!Ke),!Ke)),onTogglePanel:()=>K(Ke=>!Ke),onSwitchRenderer:T}}),Kn=Ke=>{Ke.preventDefault();const Ze=dt.current;if(!Ze)return;const sn=(se,be)=>Re(He=>({...He,[de?"h":"v"]:{main:se,side:be}}));if(de){const se=Ke.clientX,be=we.current,He=Ze.clientWidth||1,Ne=Le?-1:1,Nt=Ge=>{const Tt=be.main+be.side,nt=(Ge.clientX-se)/He*Tt*Ne,Be=td(be.main+nt);sn(Be,td(Tt-Be))},_t=()=>{window.removeEventListener("pointermove",Nt),window.removeEventListener("pointerup",_t),window.removeEventListener("pointercancel",_t),window.removeEventListener("blur",_t)};window.addEventListener("pointermove",Nt),window.addEventListener("pointerup",_t),window.addEventListener("pointercancel",_t),window.addEventListener("blur",_t);return}const te=Ke.clientY,xe=we.current,ze=Ze.clientHeight||1,qe=Le?-1:1,xt=se=>{const be=xe.main+xe.side,He=(se.clientY-te)/ze*be*qe,Ne=td(xe.main+He);sn(Ne,td(be-Ne))},W=()=>{window.removeEventListener("pointermove",xt),window.removeEventListener("pointerup",W),window.removeEventListener("pointercancel",W),window.removeEventListener("blur",W)};window.addEventListener("pointermove",xt),window.addEventListener("pointerup",W),window.addEventListener("pointercancel",W),window.addEventListener("blur",W)},$n=g&&l.jsxs("div",{className:`nc-dual-pane${ne?"":" foco"}${tt&&ne?" nascosto":""}`,"data-testid":"pane-main",style:{flexGrow:ke.main,flexBasis:de?0:void 0},onPointerDown:()=>Rt(!1),children:[l.jsxs("div",{className:"nc-dual-strip",children:[l.jsx("span",{className:`nc-dual-dot${Ae?" on":""}`,"aria-hidden":"true"}),l.jsx("b",{children:P}),!ne&&l.jsx("span",{className:"nc-dual-matita","aria-hidden":"true",title:p("dual-focus"),children:"✎"}),tt&&l.jsxs("button",{type:"button",className:"nc-dual-alt",title:p("dual-go-to").replace("{cell}",(ge==null?void 0:ge.title)||g.session),"aria-label":p("dual-go-to").replace("{cell}",(ge==null?void 0:ge.title)||g.session),onPointerDown:Ke=>Ke.stopPropagation(),onClick:Ke=>{Ke.stopPropagation(),Rt(!ne)},children:[l.jsxs("svg",{viewBox:"0 0 24 24",width:"14",height:"14","aria-hidden":"true",focusable:"false",children:[l.jsx("rect",{x:"3.5",y:"6",width:"17",height:"12",rx:"1.5",fill:"none",stroke:"currentColor",strokeWidth:"1.5"}),l.jsx("rect",{x:"3.5",y:"6",width:"8.5",height:"12",fill:"currentColor"})]}),l.jsx("span",{className:`nc-dual-dot${ge!=null&&ge.present?" on":""}`,"aria-hidden":"true"})]})]}),l.jsx("div",{className:"nc-dual-body",children:l.jsx(dc,{session:t,node:e,token:i,readonly:a,takeSize:!0,focused:!ne,sendRef:Pe,composerRef:ut,actionRef:yt,ctrlRef:St,setCtrlArmed:pt,altRef:mt,setAltArmed:Kt,keyboardRef:Bt,onFiles:st,fontSize:z,selectionMode:ln,onSelectionModeChange:an,keyboardGesture:S.terminalKeyboardGesture,onRendererChange:q})})]},"pane-main"),en=g&&l.jsxs("div",{className:`nc-dual-pane${ne?" foco":""}${tt&&!ne?" nascosto":""}`,"data-testid":"pane-side",style:{flexGrow:ke.side,flexBasis:de?0:void 0},onPointerDown:()=>Rt(!0),children:[l.jsxs("div",{className:"nc-dual-strip",children:[l.jsx("span",{className:`nc-dual-dot${ge!=null&&ge.present?" on":""}`,"aria-hidden":"true"}),l.jsx("b",{children:ge?ge.title:g.session}),ne&&l.jsx("span",{className:"nc-dual-matita","aria-hidden":"true",title:p("dual-focus"),children:"✎"}),l.jsxs("span",{className:"nc-dual-tasti",children:[l.jsx("button",{type:"button",title:p("dual-swap"),"aria-label":p("dual-swap"),onPointerDown:Ke=>Ke.stopPropagation(),onClick:Ke=>{Ke.stopPropagation(),Ee(Ze=>!Ze)},children:de?"⇆":"⇅"}),l.jsx("button",{type:"button",title:p("dual-close"),"aria-label":p("dual-close"),onPointerDown:Ke=>Ke.stopPropagation(),onClick:Ke=>{Ke.stopPropagation(),_==null||_()},children:"✕"})]}),tt&&l.jsxs("button",{type:"button",className:"nc-dual-alt",title:p("dual-go-to").replace("{cell}",P),"aria-label":p("dual-go-to").replace("{cell}",P),onPointerDown:Ke=>Ke.stopPropagation(),onClick:Ke=>{Ke.stopPropagation(),Rt(!ne)},children:[l.jsxs("svg",{viewBox:"0 0 24 24",width:"14",height:"14","aria-hidden":"true",focusable:"false",children:[l.jsx("rect",{x:"3.5",y:"6",width:"17",height:"12",rx:"1.5",fill:"none",stroke:"currentColor",strokeWidth:"1.5"}),l.jsx("rect",{x:"12",y:"6",width:"8.5",height:"12",fill:"currentColor"})]}),l.jsx("span",{className:`nc-dual-dot${Ae?" on":""}`,"aria-hidden":"true"})]})]}),l.jsx("div",{className:"nc-dual-body",children:l.jsx(dc,{session:g.session,node:g.node,token:i,readonly:a,takeSize:!1,focused:ne,sendRef:J,composerRef:Se,actionRef:De,ctrlRef:Me,setCtrlArmed:pt,altRef:Ve,setAltArmed:Kt,keyboardRef:Qe,onFiles:ft,fontSize:z,selectionMode:ln,onSelectionModeChange:an,keyboardGesture:S.terminalKeyboardGesture})})]},"pane-side"),nn=l.jsx("div",{className:"nc-dual-handle","data-testid":"dual-handle",role:"separator","aria-orientation":de?"vertical":"horizontal",onPointerDown:Kn},"dual-handle");return l.jsxs("div",{className:"nc-app",children:[l.jsxs("header",{className:"nc-bar nc-bar-single",children:[l.jsxs("button",{onClick:u,title:p("sessions"),children:[l.jsx(Dt,{name:"chevronLeft",size:18}),l.jsx("span",{className:"nc-bar-label",children:p("sessions")})]}),l.jsxs("span",{className:"nc-bar-center",children:[l.jsx("b",{title:e?`${P} · ${e}`:P,children:P}),v&&v.cell&&v.cell===s?l.jsx("span",{className:`nc-live-host-dot ${gg(v)} nc-live-host-dot-header`,"data-testid":"live-host-header-dot",title:p("live-host-indicator").replace("{cell}",v.cell).replace("{mode}",p(v.mode?`live-host-mode-${v.mode}`:"live-host-mode-unknown")).replace("{state}",p(`live-host-state-${v.state}`))}):null,j&&l.jsx("small",{className:"nc-bar-sub",children:j})]}),l.jsxs("span",{className:"nc-bar-right",children:[l.jsx("button",{onClick:()=>ie(-1),title:p("zoom-out"),children:l.jsx(Dt,{name:"zoomOut",size:18})}),l.jsx("button",{onClick:()=>ie(1),title:p("zoom-in"),children:l.jsx(Dt,{name:"zoomIn",size:18})}),!E&&Xt&&l.jsx("button",{type:"button",onClick:Jt,title:p("bar-menu-files"),"aria-label":p("bar-menu-files"),"aria-pressed":(at==null?void 0:at.source)===Vt?"true":"false",children:l.jsx(Dt,{name:"folder",size:18})}),l.jsx("button",{type:"button",className:`nc-bar-menu${C?" on":""}`,title:p("bar-menu-open"),"aria-label":p("bar-menu-open"),"aria-haspopup":"menu","aria-expanded":C?"true":"false",onClick:Ke=>{C||I(Ke.currentTarget.getBoundingClientRect()),N(Ze=>!Ze)},children:"⋯"})]})]}),l.jsxs("div",{className:"nc-termwrap",children:[g?l.jsx("div",{className:`nc-dual${de?" row":""}`,ref:dt,children:tt?Le?[en,$n]:[$n,en]:Le?[en,nn,$n]:[$n,nn,en]}):l.jsx(dc,{session:t,node:e,token:i,readonly:a,takeSize:!0,sendRef:Pe,composerRef:ut,actionRef:yt,ctrlRef:St,setCtrlArmed:pt,altRef:mt,setAltArmed:Kt,keyboardRef:Bt,onFiles:st,fontSize:z,selectionMode:ln,onSelectionModeChange:an,keyboardGesture:S.terminalKeyboardGesture,onRendererChange:q}),$&&A&&R&&l.jsx(rg,{cellId:R,panelUrl:A,route:e?e.split("/"):[],panelPort:c,token:i,title:P})]}),l.jsx(LP,{onKeyboard:()=>H(Ke=>!Ke),onCellSwitcher:h,cellSwitcherOpen:f,send:Ke=>(ne?J:Pe).current(Ke),action:Ke=>(ne?De:yt).current(Ke),ctrlArmed:Pt,onCtrl:tn,altArmed:qt,onAlt:hn,onAltConsume:()=>{const Ke=ne?Ve:mt;Ke.current=!1,Kt(!1)},onKeyboardKeep:()=>{var Ke,Ze;return(Ze=(Ke=ne?Qe:Bt).current)==null?void 0:Ze.call(Ke)},selectionMode:ln,onSelectionMode:an,keepKeyboardClosed:S.keybarKeepsKeyboardClosed,showEnter:S.showKeybarEnter,keybarLayout:S.keybarLayout}),L&&l.jsx(XC,{submitText:Ke=>(ne?Se:ut).current(Ke),token:i,session:ne?g.session:t,node:ne?g.node:e,ownerId:ne?g.ownerId:n,readonly:a,keepKeyboardClosedOnVoice:S.voiceKeepsKeyboardClosed}),at&&(ot?l.jsx(gv,{session:g.session,node:g.node,token:i,filesEvent:at.ev,onClose:()=>bt(null)}):at.source==="main"?l.jsx(gv,{session:t,node:e,token:i,filesEvent:at.ev,onClose:()=>bt(null)}):null),C&&(E?l.jsx(SC,{anchorRect:k,items:Qt,onClose:()=>N(!1)}):l.jsx(vg,{cellName:P,items:Qt,onClose:()=>N(!1)}))]})}function v4(){qn();const[t]=w.useState(d4),[e,n]=w.useState(t.token),[s,i]=w.useState(!1);QD(s?"":e);const a=w.useRef(t.token);a.current=e,w.useEffect(()=>{const he=Ce=>{Ce&&Ce.detail&&Ce.detail.token===a.current&&i(!0)};return window.addEventListener(tm,he),()=>window.removeEventListener(tm,he)},[]);const c=w.useCallback((he,Ce)=>{const Ue=c1(he,{remember:Ce});if(!Ue.ok||Ce&&Ue.where!=="local")try{window.dispatchEvent(new CustomEvent(nm))}catch{}i(!1),n(he)},[]),[u,h]=w.useState(t.pair||""),f=w.useCallback(()=>{h("");try{sessionStorage.removeItem("nc_pair")}catch{}},[]),v=tC(),[g]=w.useState(()=>hI(typeof location<"u"?location.pathname:"/")),[_,b]=w.useState(g.id),S=_===qo(null,ei),[E,C]=w.useState(null),N=he=>{const Ce=kr(he);C(Ce?{...Ce,...typeof(he==null?void 0:he.cellName)=="string"&&he.cellName?{cellName:he.cellName}:{}}:null)},[k,I]=w.useState(null);w.useEffect(()=>{const he=O6();I(he&&E&&Pv(he.main,E)?he.side:null)},[E]);const L=he=>{const Ce=E?{session:E.session,node:E.node}:null,Ue=D6(Ce,k,he);I(Ue),Ue?B6(Ce,Ue):KS()},H=()=>{I(null),KS()},[z,V]=w.useState([]),[Y,G]=w.useState(!0),[Z,q]=w.useState(null),[T,P]=w.useState([]),[D,j]=w.useState([]),[O,A]=w.useState(!1),[M,R]=w.useState(null),[F,$]=w.useState(()=>g.ownerId?uo():ZS(g.name)),[K,oe]=w.useState(null),[ce,ne]=w.useState(null),Le=he=>ne(kr(he)),[Ee,pe]=w.useState(null),Re=dg(e,v),de=w.useMemo(()=>(Re||[]).filter(he=>he.instanceId).map(he=>({instanceId:he.instanceId,route:he.route,label:he.label,status:he.status,stale:he.stale===!0})),[Re]),fe=V6(e,_,F,$,de),{notice:ke,showActionNotice:we}=zC(),ge=fe.decks;w.useEffect(()=>{const he=new Map;for(const Ce of Re||[]){const Ue=(Ce.route||[Ce.name]).join("/"),wt=new Set((Ce.sessions||[]).map(Lt=>Lt.name));for(const Lt of Ce.cells||[])!Lt.cell||!Lt.tmuxSession||Lt.cell===Lt.tmuxSession||wt.has(Lt.cell)||he.set(`${Ue}:${Lt.cell}`,`${Ue}:${Lt.tmuxSession}`)}$(Ce=>YT(Ce,he))},[Re]),w.useEffect(()=>{fe.localNodeId&&g.ownerId&&g.ownerId===fe.localNodeId&&$(he=>he.columns.some(Ce=>Ce.tiles.length)?he:ZS(g.name))},[fe.localNodeId]),w.useEffect(()=>{fe.localNodeId&&(aI(de),fe.viewUpdate(he=>{const Ce=za(he,fe.localNodeId,de);return JSON.stringify(Ce)===JSON.stringify(he)?he:Ce}))},[de,fe.localNodeId,fe.viewUpdate]);const[Ie,Ae]=w.useState(null),[Te,J]=w.useState(null),Se=w.useRef(0),[De,Me]=w.useState(!1),[Ve,Qe]=w.useState(u4),[dt,at]=w.useState(!S),[bt,st]=w.useState(()=>S?localStorage.getItem(JS)==="1":!0),[ft,ot]=w.useState(!1),[Rt,U]=w.useState("nodes"),[Q,X]=w.useState(!1),[_e,me]=w.useState(""),[tt,ie]=w.useState(!1),Pe=(he="nodes",Ce=!1,Ue="")=>{U(he),X(Ce),me(Ue),ot(!0)},[ut,yt]=w.useState(!1),[St,Pt]=w.useState(null),[pt,mt]=w.useState({deviceDefault:"",localNodeId:"",localNameDefault:"",deviceNameNeeded:!1,deviceNameSuggestion:""}),[qt,Kt]=w.useState(""),[Bt,ln]=w.useState(!1),[an,tn]=w.useState(0),[hn,fn]=w.useState({});w.useEffect(()=>{try{localStorage.setItem(c2,String(Ve))}catch{}},[Ve]),w.useEffect(()=>{try{localStorage.setItem(JS,bt?"1":"")}catch{}},[bt]),w.useEffect(()=>{if(!e)return;let he=!1;return Promise.all([g1(e),bn("/api/config",e).then(Ce=>Ce.json())]).then(([Ce,Ue])=>{if(!he){if(mt({deviceDefault:Ce.deviceName||"",localNodeId:Ce.nodeId||"",localNameDefault:Ce.localName||"",deviceNameNeeded:Ce.deviceNameNeeded===!0,deviceNameSuggestion:Ce.deviceNameSuggestion||""}),Kt(Ce.deviceName||""),ln(!!Ue.readonlyDefault),hM(Ue.terminal),tn(Number.isInteger(Ue.panelPort)?Ue.panelPort:0),fn(Ue.nodePanelPorts&&typeof Ue.nodePanelPorts=="object"&&!Array.isArray(Ue.nodePanelPorts)?Ue.nodePanelPorts:{}),Ce.firstRun===!0&&!Ue.readonlyDefault)yt(!0);else if(u)yt(!0);else if(Ce.deviceNameNeeded===!0&&!Ue.readonlyDefault){let wt=!1;try{wt=sessionStorage.getItem("nc_device_ask_later")==="1"}catch{}wt||Pt({suggestion:Ce.deviceNameSuggestion||""})}}}).catch(()=>{}),()=>{he=!0}},[e,u]);const[Vt,Xt]=w.useState({}),pn=w.useCallback(({route:he,hostCell:Ce,revision:Ue})=>{const wt=ks(he);Xt(Lt=>({...Lt,[wt]:{hostCell:Ce||null,hostLease:null,hostRevision:Number.isInteger(Ue)?Ue:(Lt[wt]||{}).hostRevision||0,threadStatus:"absent"}}))},[]),Jt=he=>{const Ce=ks(he),Ue=he.length?((Re||[]).find(wt=>ks(Array.isArray(wt.route)?wt.route:[])===Ce)||{}).cells||[]:T;return Ka({liveHost:Vt[Ce]||null,cells:Ue,localNodeId:fe.localNodeId,ownerId:he.length?Ce:fe.localNodeId})},Qt=w.useRef(Re);w.useEffect(()=>{Qt.current=Re},[Re]);const Kn=w.useRef(null);Kn.current||(Kn.current=WS());const $n=w.useRef(null);$n.current||($n.current=WS());const en=3500,nn=w.useCallback(async()=>{const he=$n.current,Ce=he.begin();if(Ce!==null)try{try{const zn=await(await bn("/api/sessions",e,{timeoutMs:en})).json();if(!he.isCurrent(Ce))return;zn.error?G(!1):(V(zn.sessions||[]),G(!0),q(Date.now()))}catch{he.isCurrent(Ce)&&G(!1)}let Ue=null,wt=null;try{Ue=await Cr(e,void 0,{timeoutMs:en})}catch(An){wt=An}if(!he.isCurrent(Ce))return;const Lt=ug({fs:Ue,error:wt});Lt.kind==="data"?(qa("local",Lt.cells),P(Lt.cells),j(Lt.capabilities),A(!1),R(null)):Lt.kind==="stale"?(P(An=>An.length?An:cg("local")),A(!0),R(null)):(P([]),qa("local",[]),j([]),A(!1),R(Lt.reason||""))}finally{he.end(Ce)}},[e]);w.useEffect(()=>{let he=!1;const Ce=async()=>{const wt=Kn.current,Lt=wt.begin();if(Lt!==null)try{const An=[[],...(Qt.current||[]).filter(Ht=>Ht.kind!=="vl"&&Ht.status==="up").map(Ht=>Array.isArray(Ht.route)&&Ht.route.length?Ht.route:[Ht.name])],zn=await Promise.all(An.map(async Ht=>{const Ls=ks(Ht);try{const cn=await Ud(e,Ht,{timeoutMs:en});return[Ls,{hostCell:cn&&typeof cn.hostCell=="string"?cn.hostCell:null,hostLease:cn&&cn.host&&typeof cn.host.lease=="string"?cn.host.lease:null,hostRevision:Number.isInteger(cn&&cn.revision)?cn.revision:0,threadStatus:cn&&QS.has(cn.threadStatus)?cn.threadStatus:"unknown"}]}catch{return[Ls,{error:!0}]}}));if(he||!wt.isCurrent(Lt))return;Xt(Ht=>{let Ls=!1;const cn={...Ht};for(const fo of zn){if(!fo)continue;const[rr,Wt]=fo;cn[rr]=Wt.error?{...Ht[rr]||{},threadStatus:"unknown"}:Wt,Ls=!0}return Ls?cn:Ht})}finally{wt.end(Lt)}};Ce();const Ue=setInterval(Ce,4e3);return()=>{he=!0,clearInterval(Ue),Kn.current.reset()}},[e]),w.useEffect(()=>{if(!v)return;nn();const he=setInterval(nn,4e3);return()=>{clearInterval(he),$n.current.reset()}},[v,nn]);const Ns=w.useCallback(async(he,Ce=[])=>{const Ue=ks(Ce),wt=Vt[Ue]&&Vt[Ue].hostRevision||0;try{const Lt=await Wd(e,he,wt,Ce);return Xt(An=>({...An,[Ue]:{hostCell:Lt.hostCell||null,hostLease:Lt.host&&typeof Lt.host.lease=="string"?Lt.host.lease:null,hostRevision:Number.isInteger(Lt.revision)?Lt.revision:wt,threadStatus:QS.has(Lt.threadStatus)?Lt.threadStatus:"unknown"}})),{ok:!0}}catch(Lt){return{ok:!1,error:Lt}}},[e,Vt]),Ke=w.useCallback(async(he,Ce=[])=>{const Ue=await Ns(he,Ce);return Ue.ok||window.alert(p(rm(Ue.error))),Ue.ok},[Ns]),Ze=w.useCallback(async(he=[])=>{const Ce=ks(he),Ue=Vt[Ce]&&Vt[Ce].hostRevision||0;try{const wt=await qd(e,Ue,he);return Xt(Lt=>({...Lt,[Ce]:{hostCell:wt.hostCell||null,hostLease:null,hostRevision:Number.isInteger(wt.revision)?wt.revision:Ue,threadStatus:"unknown"}})),{ok:!0}}catch(wt){return{ok:!1,error:wt}}},[e,Vt]),sn=w.useCallback(async(he=[])=>{const Ce=await Ze(he);return Ce.ok||window.alert(p(rm(Ce.error))),Ce.ok},[Ze]);w.useEffect(()=>{let he=!1;const Ce=()=>{bn("/api/config",e).then(wt=>wt.json()).then(wt=>{he||s4(wt.version,wt.uiVersion,"0.9.54")}).catch(()=>{})};Ce();const Ue=setInterval(Ce,6e4);return()=>{he=!0,clearInterval(Ue)}},[e]);const te=new Set([...z.map(he=>he.name),...Re.flatMap(he=>he.sessions.map(Ce=>Ce.key))]),xe=w.useMemo(()=>{const he=new Map;for(const Ce of z)Ce&&typeof Ce.name=="string"&&Number.isFinite(Ce.created)&&he.set(Ce.name,Ce.created);return he},[z]),ze=_s(F),qe=he=>$(Ce=>{const Ue=sk(he,fe.localNodeId,de)||he,wt=jC(Ce,Ue);return wt===Ce&&_s(Ce).length>=9&&fe.setError(p("grid-full")),wt}),xt=async(he,Ce=[])=>{try{await $v(e,he,Ce)}catch{return}const Ue=Ce.length?`${Ce.join("/")}:${he}`:he;$(wt=>xc(wt,Ue)),nn()},W=async(he,Ce,Ue=[])=>{try{await v1(e,he,Ce,Ue)}catch{return}nn()},se=async(he,Ce,Ue=[])=>{await f1(e,{cell:he,enabled:!!Ce},Ue),nn()},be=async he=>{if(!Ie)return;const{cell:Ce}=Ie,Ue=Array.isArray(Ie.route)?Ie.route:[];if(!await wg({token:e,powerCell:Ie,payload:he,onNotice:we})){const Lt=he.action==="up"?!!he.boot:he.boot?!1:!!Ie.boot;J({id:++Se.current,cell:Ce,route:Ue,enabled:Lt})}nn()},He=w.useCallback(he=>{J(Ce=>(Ce==null?void 0:Ce.id)===he?null:Ce)},[]),Ne=async he=>{if(!(!(he!=null&&he.direct)||De)){Me(!0);try{await Uv(e,he.name,he.tunnelStatus==="up"?"down":"up")}finally{Me(!1)}}},Nt=async(he,Ce)=>{const Ue=String(Ce||"").trim();return!(he!=null&&he.direct)||!Ya(Ue)?!1:(await b1(e,he.name,Ue),!0)},_t=he=>{const Ce=ge.find(Ue=>Ue.id===he);if(!Ce)return!1;try{const Ue=window.open(bp(Ce,e),"_blank");return Ue&&(Ue.opener=null),!!Ue}catch{return!1}},Ge=async he=>{if(!he||he===_)return;const Ce=await fe.select(he),Ue=fe.records.find(wt=>wt.id===he);b(he),$(Ce),oe(null),ne(null);try{history.replaceState(null,"",bp(Ue||he,null))}catch{}},Tt=async(he,Ce)=>{const Ue=await fe.add(he,Ce);await Ge(Ue.id)},nt=async(he,Ce)=>{const Ue=await fe.rename(he,Ce);if(he===_){b(Ue.id),$(fe.vistaMaterializzata(Ue)),oe(null),ne(null);try{history.replaceState(null,"",bp(Ue,null))}catch{}}},Be=async he=>{await fe.remove(he),he===_&&await Ge(fe.localMainId)},Zt=async(he,Ce)=>{!Ce||Ce===_||(await fe.addTileTo(Ce,he),$(Ue=>xc(Ue,he)))};if(!e||s)return l.jsx(F6,{onSubmit:c,reason:s?"invalid":""});const Rn=l.jsxs(l.Fragment,{children:[ft&&l.jsx(u6,{token:e,initialTab:Rt,initialLocation:_e,startNewCell:Q,onClose:()=>{ot(!1),X(!1),me("")}}),ut&&l.jsx(d6,{token:e,initialPair:u,...pt,onPairDone:f,onDone:()=>yt(!1)}),St&&l.jsx(h6,{token:e,suggestion:St.suggestion,onSaved:he=>{Kt(he),mt(Ce=>({...Ce,deviceDefault:he,deviceNameNeeded:!1})),Pt(null)},onLater:()=>{try{sessionStorage.setItem("nc_device_ask_later","1")}catch{}Pt(null)}}),l.jsx(E6,{token:e})]});if(!v)return Ee?l.jsxs(l.Fragment,{children:[l.jsx("div",{className:"nc-single-overlay",children:l.jsx(qS,{peer:Ee,token:e,onBack:()=>pe(null)})}),Rn]}):E?l.jsxs(l.Fragment,{children:[l.jsx(t1,{session:E.session,node:E.node,ownerId:E.ownerId,cellName:E.cellName,token:e,readonly:Bt,liveHost:Jt(E.node?E.node.split("/"):[]),panelPort:wc(E.node?E.node.split("/"):[],hn,an),side:k,onSideClose:H,onSideGone:H,onBack:()=>C(null),onCellSwitcher:()=>ie(!0),cellSwitcherOpen:tt}),tt&&l.jsx(M6,{token:e,current:E,localNodeLabel:qt,panelPort:an,nodePanelPorts:hn,hostByRoute:Vt,onDesignateCell:Ns,onClearHostCell:Ze,onLiveHostApplied:pn,sideKey:k?Wa(k.node?k.node.split("/"):[],k.session):null,onToggleSide:L,onPick:he=>{N(he),ie(!1)},onClose:()=>ie(!1)}),Rn]}):l.jsxs(l.Fragment,{children:[l.jsx(SP,{onPick:N,token:e,onSettings:Pe,onOpenVlSession:pe,panelPort:an,nodePanelPorts:hn,hostByRoute:Vt,onDesignateCell:Ke,onClearHostCell:sn}),Rn]});const wi=S||!dt;return l.jsxs("div",{className:"nc-workspace",children:[wi&&l.jsx(VP,{sessions:z,cells:T,localVerified:Y,activeSessions:ze,nodeGroups:Re,token:e,onPeekOpen:()=>ie(!1),overlayOpen:tt,fleetCapabilities:D,fleetStale:O,fleetOff:M,bootSettlement:Te,onBootSettlementApplied:He,localNodeId:fe.localNodeId,hostByRoute:Vt,onDesignateCell:Ke,onClearHostCell:sn,onPick:Le,onAddTile:qe,onPower:Ae,onBoot:se,onBootError:he=>fe.setError(String((he==null?void 0:he.message)||he)),onNodePower:Ne,onNodeRename:Nt,onKill:xt,onVisibility:W,onNew:()=>Pe("fleet",!0),onSettings:Pe,onOpenVlSession:pe,width:Ve,collapsed:bt,onResize:Qe,onToggleCollapse:()=>st(he=>!he)}),l.jsxs("div",{className:"nc-workspace-main",children:[l.jsx(II,{decks:ge,currentDeck:_,onCreate:Tt,onRename:nt,onDelete:Be,onReorder:fe.reorder,onOpenWindow:_t,onNavigate:Ge,saveState:fe.saveState,error:fe.error,conflict:fe.conflict,onReloadDeck:fe.reloadCurrent,sidebarVisible:wi,onToggleSidebar:S?null:()=>at(he=>!he)}),ke&&l.jsx("div",{className:"nc-notice nc-deck-notice",role:"status",title:ke,children:ke}),l.jsx(oI,{layout:F,onLayoutChange:$,onResizeEnd:()=>{fe.saveNow()},token:e,readonly:Bt,sessionsAlive:te,localVerified:Y,localIdentities:xe,localVerifiedAt:Z,focusSession:K,onFocus:oe,onOpenSingle:Le,decks:ge,currentDeck:_,onSendToDeck:Zt,cells:T,nodeGroups:Re,panelPort:an,nodePanelPorts:hn})]}),Ee&&l.jsx("div",{className:"nc-single-overlay",children:l.jsx(qS,{peer:Ee,token:e,onBack:()=>pe(null)})}),ce&&l.jsx("div",{className:"nc-single-overlay",children:l.jsx(t1,{session:ce.session,node:ce.node,ownerId:ce.ownerId,cellName:Cc({session:ce.session,node:ce.node,ownerId:ce.ownerId,cells:T,nodeGroups:Re}),token:e,readonly:Bt,liveHost:Jt(ce.node?ce.node.split("/"):[]),panelPort:wc(ce.node?ce.node.split("/"):[],hn,an),onBack:()=>ne(null)})}),Ie&&l.jsx(Nd,{cell:Ie,token:e,route:Array.isArray(Ie.route)?Ie.route:[],onConfirm:be,onClose:()=>Ae(null)}),Rn]})}function g4(t){return t.kind==="install"?p("update-installed-restart").replace("{v}",t.version):t.kind==="stale"?p("update-stale").replace("{ui}",t.version).replace("{browser}",t.browserVersion):p("update-available").replace("{v}",t.version).replace(" "," ").trim()}function _4(){qn();const t=w.useSyncExternalStore(G6,GS,GS);return t.needed?l.jsxs("div",{className:"nc-update",role:"status","aria-live":"polite",children:[l.jsx("span",{className:"nc-update-msg",children:g4(t)}),t.kind==="stale"&&l.jsx("button",{className:"nc-update-btn",onClick:l2,children:p("reload-no-cache")}),t.kind==="reload"&&l.jsx("button",{className:"nc-update-btn",onClick:a4,children:p("reload")}),l.jsx("button",{className:"nc-update-close",onClick:n4,"aria-label":p("update-dismiss"),title:p("update-dismiss"),children:"×"})]}):null}function y4(){qn();const[t,e]=w.useState(!1);return w.useEffect(()=>{const n=()=>e(!0);return window.addEventListener(nm,n),()=>window.removeEventListener(nm,n)},[]),t?l.jsxs("div",{className:"nc-update",role:"status","aria-live":"polite",children:[l.jsx("span",{className:"nc-update-msg",children:p("auth-not-remembered")}),l.jsx("button",{className:"nc-update-close",onClick:()=>e(!1),"aria-label":p("update-dismiss"),title:p("update-dismiss"),children:"×"})]}):null}o4();DD();VE.createRoot(document.getElementById("root")).render(l.jsxs(zE.StrictMode,{children:[l.jsx(v4,{}),l.jsx(_4,{}),l.jsx(y4,{})]}));
@@ -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-DBlFdkZn.js"></script>
14
+ <script type="module" crossorigin src="/assets/index-DdTN41V3.js"></script>
15
15
  <link rel="stylesheet" crossorigin href="/assets/index-Da4oBb4f.css">
16
16
  </head>
17
17
  <body>
@@ -1 +1 @@
1
- {"version":"0.9.53"}
1
+ {"version":"0.9.54"}
@@ -988,8 +988,16 @@ function autoUpdateCommand(args, opts = {}) {
988
988
  if (!attivo) {
989
989
  // Servizio spento: si scrive il file, e si DICE che vale al prossimo avvio.
990
990
  // Tacerlo lascerebbe credere che abbia gia' effetto.
991
- let cfg = {};
992
- try { cfg = JSON.parse(fs.readFileSync(configPath, 'utf8')); } catch (_) { /* file nuovo */ }
991
+ // Se la config esiste ma non si legge, NON si riscrive: partire da un
992
+ // oggetto vuoto cancellerebbe le chiavi dell'operatore (wizardDone e le
993
+ // altre) per salvarne una sola. Motivo categorico, mai il messaggio del
994
+ // parser (contiene un estratto del file).
995
+ const letta = require('../config.js').readConfigForWrite(configPath);
996
+ if (!letta.ok) {
997
+ log(`autoupdate: config illeggibile ${letta.path} (${letta.motivo}) — non la riscrivo; ripara o rimuovi il file`);
998
+ return { code: 1 };
999
+ }
1000
+ const cfg = letta.cfg;
993
1001
  // Scrittura atomica e rifiuto dei symlink, come fa la route che scrive lo
994
1002
  // stesso file: tmp nella stessa directory, 0600, rename. Un `writeFileSync`
995
1003
  // diretto puo' lasciare un config.json troncato se il processo muore a
package/lib/cli/init.js CHANGED
@@ -18,6 +18,7 @@ const {
18
18
  selectProviderModeSync, fleetFileMode,
19
19
  } = require('./fleet-service.js');
20
20
  const { resolveBootPaths } = require('./stable-alias.js');
21
+ const { readConfigForWrite } = require('../config.js');
21
22
  const { aggiornaDefinizioni } = require('../fleet/definitions.js');
22
23
  const { defaultDefinitions } = require('../fleet/managed.js');
23
24
  const { commandExists, resolveCommand } = require('./path.js');
@@ -169,17 +170,26 @@ function runInit(opts = {}) {
169
170
  writeConfigAtomic(configPath, { port });
170
171
  actions.push(`created config ${configPath} (port ${port})`);
171
172
  } else {
172
- let current;
173
- try {
174
- current = JSON.parse(fs.readFileSync(configPath, 'utf8'));
175
- } catch (_) { current = {}; }
176
- if (opts.port) {
173
+ // Fail-closed come per fleet.json (vedi ensureFleetDefaults): un file
174
+ // PRESENTE ma illeggibile NON si riscrive. Riscriverlo con la sola porta
175
+ // cancellerebbe le chiavi dell'operatore (autoUpdate, wizardDone) e
176
+ // riporterebbe i default: e' il guasto osservato sulle macchine, dove
177
+ // l'opzione autoUpdate tornava a true da sola dopo essere stata spenta.
178
+ // La lettura e' la stessa usata dagli altri scrittori di config
179
+ // (readConfigForWrite): una sola regola, un solo motivo categorico.
180
+ const letta = readConfigForWrite(configPath);
181
+ const current = letta.ok ? letta.cfg : null;
182
+ const illeggibile = letta.ok ? null : letta.motivo;
183
+ if (!current) {
184
+ actions.push(`WARN: config illeggibile ${configPath} (${illeggibile}): non la riscrivo, il file resta com'e' (fail-closed)`);
185
+ if (opts.port) actions.push(`WARN: porta ${opts.port} non applicata alla config illeggibile`);
186
+ } else if (opts.port) {
177
187
  current.port = opts.port;
178
188
  port = opts.port;
179
189
  writeConfigAtomic(configPath, current);
180
190
  actions.push(`updated config ${configPath} (port ${port})`);
181
- } else if (current && current.port) port = current.port;
182
- actions.push(`preserved config ${configPath} (port ${port})`);
191
+ } else if (current.port) port = current.port;
192
+ if (current) actions.push(`preserved config ${configPath} (port ${port})`);
183
193
  }
184
194
  }
185
195
 
package/lib/config.js CHANGED
@@ -147,6 +147,37 @@ function readConfigJson() {
147
147
  } catch (_) { return {}; }
148
148
  }
149
149
 
150
+ // Lettura della config per una SCRITTURA (merge). Distingue tre casi, e i tre
151
+ // non collassano in uno: chi scrive deve poter dire «assente» (legittimo: si
152
+ // parte da zero) da «presente ma illeggibile» (mai partire da zero: si
153
+ // perderebbero le chiavi dell'operatore, e i default tornerebbero — e' il
154
+ // guasto per cui autoUpdate si riaccendeva da solo).
155
+ // Il motivo e' una CATEGORIA fissa — 'parse-error', 'not-object',
156
+ // 'read-error:<codice errno>' — MAI il messaggio del parser: su Node recenti
157
+ // JSON.parse include un estratto dell'input, cioe' contenuto della config, e
158
+ // questi messaggi finiscono in risposte HTTP e log.
159
+ // -> { ok: true, cfg } | { ok: false, motivo, path }
160
+ function readConfigForWrite(filePath, { fsImpl = fs } = {}) {
161
+ const target = filePath || configJsonPath();
162
+ let testo;
163
+ try {
164
+ testo = fsImpl.readFileSync(target, 'utf8');
165
+ } catch (e) {
166
+ if (e && e.code === 'ENOENT') return { ok: true, cfg: {} }; // assente: si parte da zero
167
+ return { ok: false, motivo: `read-error${e && e.code ? `:${e.code}` : ''}`, path: target };
168
+ }
169
+ let parsed;
170
+ try {
171
+ parsed = JSON.parse(testo);
172
+ } catch (_) {
173
+ return { ok: false, motivo: 'parse-error', path: target };
174
+ }
175
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
176
+ return { ok: false, motivo: 'not-object', path: target };
177
+ }
178
+ return { ok: true, cfg: parsed };
179
+ }
180
+
150
181
  // Override da env (precedence più alta di config.json).
151
182
  function envOverrides() {
152
183
  const e = {};
@@ -259,4 +290,4 @@ function defaults() {
259
290
  return { ...base, ...env, terminal: resolveTerminal(base, env) };
260
291
  }
261
292
 
262
- module.exports = { assertLoopback, baseDefaults, readConfigJson, loadConfig, defaults, LOOPBACK, configJsonPath, eventsEnabledFlag, readFederationEventsEnabled, TERMINAL_DEFAULTS, resolveTerminal };
293
+ module.exports = { assertLoopback, baseDefaults, readConfigJson, readConfigForWrite, loadConfig, defaults, LOOPBACK, configJsonPath, eventsEnabledFlag, readFederationEventsEnabled, TERMINAL_DEFAULTS, resolveTerminal };
@@ -10,6 +10,7 @@
10
10
  const fs = require('node:fs');
11
11
  const path = require('node:path');
12
12
  const crypto = require('node:crypto');
13
+ const { readConfigForWrite } = require('../config.js');
13
14
 
14
15
  const CREDENTIAL_FILES = Object.freeze({
15
16
  identityDaemonCredential: 'daemon.credential',
@@ -61,6 +62,23 @@ function provisionIdentityAuthority({
61
62
  fsImpl = fs,
62
63
  now = new Date,
63
64
  } = {}) {
65
+ // PRIMA di qualunque scrittura (cartella compresa): se la config esiste ma
66
+ // non si legge, si rifiuta senza aver toccato NULLA. Motivo categorico, mai
67
+ // il messaggio del parser: contiene un estratto del file e finirebbe nel
68
+ // referto del comando.
69
+ const resolvedConfigPath = configPath
70
+ || (process.env.NEXUSCREW_CONFIG_FILE
71
+ || path.join(home || require('node:os').homedir(), '.nexuscrew', 'config.json'));
72
+ const lettaConfig = writeConfig
73
+ ? readConfigForWrite(resolvedConfigPath, { fsImpl })
74
+ : { ok: true, cfg: {} };
75
+ if (!lettaConfig.ok) {
76
+ return {
77
+ ok: false, code: 'CONFIG_UNREADABLE', dir: dir || defaultAuthorityDir(home),
78
+ message: `config illeggibile ${lettaConfig.path} (${lettaConfig.motivo}): non la riscrivo, niente e' stato scritto`,
79
+ };
80
+ }
81
+
64
82
  const targetDir = dir || defaultAuthorityDir(home);
65
83
  fsImpl.mkdirSync(targetDir, { recursive: true, mode: 0o700 });
66
84
 
@@ -104,18 +122,10 @@ function provisionIdentityAuthority({
104
122
  for (const filePath of written) fsImpl.chmodSync(filePath, 0o600);
105
123
  for (const filePath of written) assertSafeMode(filePath, 0o600);
106
124
 
107
- const resolvedConfigPath = configPath
108
- || (process.env.NEXUSCREW_CONFIG_FILE
109
- || path.join(home || require('node:os').homedir(), '.nexuscrew', 'config.json'));
110
-
111
125
  let configUpdated = false;
112
126
  let configInstructions = null;
113
127
  if (writeConfig) {
114
- let config = {};
115
- try {
116
- config = JSON.parse(fsImpl.readFileSync(resolvedConfigPath, 'utf8'));
117
- if (!config || typeof config !== 'object' || Array.isArray(config)) config = {};
118
- } catch (_) { config = {}; }
128
+ const config = lettaConfig.cfg;
119
129
  config.fleet = { ...(config.fleet || {}), identity: { ...(config.fleet?.identity || {}), mode: 'authority' } };
120
130
  fsImpl.mkdirSync(path.dirname(resolvedConfigPath), { recursive: true });
121
131
  fsImpl.writeFileSync(resolvedConfigPath, `${JSON.stringify(config, null, 2)}\n`, { mode: 0o600 });
@@ -1620,6 +1620,22 @@ function forwardUpgrade({ req, socket, head, nodesPath, localPort, localCredenti
1620
1620
  }
1621
1621
  }
1622
1622
  const up = net.connect({ host: '127.0.0.1', port });
1623
+ // ECONNREFUSED sull'hop locale (tunnel che si riavvia) arriva PRIMA del
1624
+ // 'connect': nel ramo hubMode il listener 'error' era registrato solo dentro
1625
+ // up.once('connect', …) e l'evento restava senza gestore → Unhandled 'error'
1626
+ // event → crash del processo (caduto 5 volte su un nodo Termux). Lo
1627
+ // registriamo QUI, sincrono, prima che qualunque I/O possa fallire, valido
1628
+ // per entrambi i rami. Idempotente con i listener registrati dopo il connect:
1629
+ // destroy() e upstreamGone() sono gia' protetti da flag.
1630
+ let heldRecord = null;
1631
+ up.on('error', () => {
1632
+ if (hubMode) {
1633
+ if (heldRecord) hubAttaches.destroy(heldRecord);
1634
+ else acceptWsThenClose(socket, req, 4402, 'upstream gone');
1635
+ } else {
1636
+ upstreamGone();
1637
+ }
1638
+ });
1623
1639
  // Osservatore NON consumante della testa di risposta dell'upstream: serve
1624
1640
  // solo a sapere se il 101 e' transitato (client in stato WebSocket) o se
1625
1641
  // l'hop e' morto prima. La pipe resta l'unico trasporto dei byte: il
@@ -1679,6 +1695,7 @@ function forwardUpgrade({ req, socket, head, nodesPath, localPort, localCredenti
1679
1695
  const record = hubAttaches.hold({
1680
1696
  attachId, tokenHash: tokenFingerprint(attachToken), route: attachRoute, session: attachSession, up,
1681
1697
  });
1698
+ heldRecord = record;
1682
1699
  up.on('data', (chunk) => hubAttaches.feed(record, chunk));
1683
1700
  up.on('close', () => hubAttaches.destroy(record));
1684
1701
  up.on('error', () => hubAttaches.destroy(record));
@@ -44,6 +44,7 @@ const crypto = require('node:crypto');
44
44
  const express = require('express');
45
45
 
46
46
  const nodesStore = require('../nodes/store.js');
47
+ const { readConfigForWrite } = require('../config.js');
47
48
  const nodeAliases = require('../nodes/aliases.js');
48
49
  const { setConsent: setAudioConsent, isConsent: isAudioConsent } = require('../audio/consent.js');
49
50
  const { describeCapability } = require('../audio/capability.js');
@@ -360,8 +361,14 @@ function settingsRoutes(deps = {}) {
360
361
  return send(res, 400, { error: 'aiDesktop deve essere boolean' });
361
362
  }
362
363
 
363
- // merge sul config esistente (preserva le chiavi non gestite qui)
364
- const { cfg: current } = readConfigFile(configPath);
364
+ // merge sul config esistente (preserva le chiavi non gestite qui).
365
+ // Se il file ESISTE ma non si legge, NON si parte da un oggetto vuoto: si
366
+ // risponderebbe 200 avendo appena cancellato le chiavi dell'operatore.
367
+ const letta = readConfigForWrite(configPath);
368
+ if (!letta.ok) {
369
+ return send(res, 409, { error: 'config-unreadable', reason: letta.motivo, path: letta.path });
370
+ }
371
+ const current = letta.cfg;
365
372
  const next = { ...current };
366
373
  if (b.roles !== undefined) {
367
374
  const prev = (current.roles && typeof current.roles === 'object') ? current.roles : {};
@@ -425,9 +432,12 @@ function settingsRoutes(deps = {}) {
425
432
  if (!b || typeof b !== 'object' || Array.isArray(b) || typeof b.enabled !== 'boolean') {
426
433
  return send(res, 400, { error: 'body deve essere {enabled: boolean}' });
427
434
  }
428
- const { cfg: cfgNow } = readConfigFile(configPath);
435
+ const letta = readConfigForWrite(configPath);
436
+ if (!letta.ok) {
437
+ return send(res, 409, { error: 'config-unreadable', reason: letta.motivo, path: letta.path });
438
+ }
429
439
  try {
430
- atomicWriteConfig(configPath, { ...cfgNow, aiDesktop: b.enabled });
440
+ atomicWriteConfig(configPath, { ...letta.cfg, aiDesktop: b.enabled });
431
441
  } catch (e) {
432
442
  return send(res, 500, { error: `config non salvata: ${e.message}` });
433
443
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mmmbuto/nexuscrew",
3
- "version": "0.9.53",
3
+ "version": "0.9.54",
4
4
  "description": "Faithful browser tmux client — attach to live sessions over a real PTY, localhost-only, mobile-easy",
5
5
  "main": "lib/server.js",
6
6
  "bin": {