@mmmbuto/nexuscrew 0.9.13 → 0.9.14
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.
|
@@ -90,4 +90,4 @@ Minimum version required to store current data is: `+H+`.
|
|
|
90
90
|
`).filter(o=>o!==""),promptMode:e.promptMode};return e.modelFlag&&(s.model={flag:e.modelFlag,value:e.modelValue||""}),e.promptMode==="flag"&&(s.promptFlag=e.promptFlag),t&&(s.env=Object.fromEntries(e.envRows.filter(o=>!o.remove&&o.key).map(o=>[o.key,o.value]))),Ny(s,e,t)}function Hs({children:e,onClose:t,label:n,error:s=""}){const o=k.useRef(null),a=k.useRef(null),u=k.useRef(t);return u.current=t,k.useEffect(()=>{const d=document.activeElement,p=o.current,m=()=>Array.from((p==null?void 0:p.querySelectorAll('button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [href], [tabindex]:not([tabindex="-1"])'))||[]).filter(b=>b.offsetParent!==null),v=requestAnimationFrame(()=>{var b;return(b=m()[0]||p)==null?void 0:b.focus({preventScroll:!0})}),y=b=>{var w;if(b.key==="Escape"){b.preventDefault(),(w=u.current)==null||w.call(u);return}if(b.key!=="Tab")return;const S=m();if(!S.length){b.preventDefault(),p==null||p.focus();return}const x=S[0],E=S[S.length-1];b.shiftKey&&document.activeElement===x?(b.preventDefault(),E.focus()):!b.shiftKey&&document.activeElement===E&&(b.preventDefault(),x.focus())};return document.addEventListener("keydown",y),()=>{cancelAnimationFrame(v),document.removeEventListener("keydown",y),d&&d.isConnected&&typeof d.focus=="function"&&d.focus({preventScroll:!0})}},[]),k.useEffect(()=>{s&&requestAnimationFrame(()=>{var d;return(d=a.current)==null?void 0:d.scrollIntoView({block:"nearest"})})},[s]),l.jsx("div",{className:"nc-fleet-modal",role:"presentation",onMouseDown:d=>{d.target===d.currentTarget&&t()},children:l.jsxs("div",{ref:o,className:"nc-fleet-modal-dialog",role:"dialog","aria-modal":"true","aria-label":n||f("settings"),tabIndex:-1,children:[e,s&&l.jsx("div",{ref:a,className:"nc-err nc-fleet-modal-error",role:"alert","aria-live":"assertive",children:s})]})})}function dh({token:e,targets:t=[],readonly:n=!1,onPower:s,onImport:o}){const[a,u]=k.useState([]),[d,p]=k.useState(0);k.useEffect(()=>{let w=!0;async function N(){const L=[{route:[],label:f("local")}].concat((t||[]).map(G=>({route:Array.isArray(G.route)?G.route:[],label:G.label||(G.route||[]).join(" › ")}))),I=await Promise.all(L.map(async G=>{const K={...G,available:!1,readonly:!1,capabilities:[],provider:null,cells:[],unmanaged:[],err:""};try{const Y=await Xs(e,G.route);K.available=!!Y.available,K.capabilities=Y.capabilities||[],K.provider=Y.provider||null,K.cells=(Y.cells||[]).map(Q=>({...Q,route:G.route}));try{K.readonly=!!(await Df(e,G.route)).readonlyDefault}catch{}try{const Q=await Tf(e,G.route),W=new Set(K.cells.map(X=>X.tmuxSession).filter(Boolean));K.unmanaged=(Q.sessions||[]).filter(X=>X&&!W.has(X.name))}catch{}}catch(Y){K.err=String(Y&&Y.message||Y)}return K}));w&&u(I)}N();const C=setInterval(N,6e3);return()=>{w=!1,clearInterval(C)}},[e,t,d]);const m=(w,N)=>Array.isArray(w.capabilities)&&w.capabilities.includes(N)&&!n&&!w.readonly,v=()=>p(w=>w+1),y=(w,N)=>{s&&s({...w,route:N})},b=(w,N)=>{s&&s({...w,route:N})},S=async(w,N)=>{try{await fa(e,w.cell,N)}catch{}v()},x=async(w,N)=>{if(window.confirm(f("fleet-remove-cell").replace("{id}",w.cell))){try{await Uy(e,w.cell,!0,N)}catch{}v()}},E=async(w,N)=>{if(window.confirm(f("terminate-confirm").replace("{name}",w.name))){try{await Af(e,w.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:f("fleet-inventory")}),l.jsx("small",{children:f("fleet-inventory-help")})]}),a.map(w=>{const N=w.route.length?w.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 ${w.available?"on":"warn"}`}),l.jsx("b",{children:w.label}),l.jsx("small",{children:w.available?`${w.cells.length} ${f("fleet-cells")} · ${w.unmanaged.length} ${f("fleet-tmux")}`:w.err||f("fleet-not-available")})]}),w.cells.map(C=>l.jsxs("div",{className:"nc-fleet-item nc-fleet-cell",children:[l.jsxs("span",{children:[l.jsx("b",{children:C.cell}),l.jsx("small",{children:`${C.engine||""}${C.key?`·${C.key}`:""}${C.active?"":` · ${f("cell-off")}`}`})]}),l.jsxs("span",{className:"nc-fleet-cell-actions",children:[C.active&&m(w,"down")&&l.jsx("button",{className:"nc-btn ghost",title:f("power-off"),onClick:()=>b(C,w.route),children:f("stop")}),!C.active&&m(w,"up")&&l.jsx("button",{className:"nc-btn ghost",title:f("power-on"),onClick:()=>y(C,w.route),children:f("start")}),m(w,"restart")&&C.active&&l.jsx("button",{className:"nc-btn ghost",title:f("restart"),onClick:()=>S(C,w.route),children:f("restart")}),m(w,"remove")&&l.jsx("button",{className:"nc-btn danger",title:f("delete"),onClick:()=>x(C,w.route),children:"×"})]})]},`${N}:${C.cell}`)),w.unmanaged.map(C=>l.jsxs("div",{className:"nc-fleet-item nc-fleet-unmanaged",children:[l.jsxs("span",{children:[l.jsx("b",{children:C.name}),l.jsx("small",{children:f("fleet-tmux")})]}),l.jsxs("span",{className:"nc-fleet-cell-actions",children:[m(w,"import")&&o&&l.jsx("button",{className:"nc-btn ghost",title:f("import-as-cell"),onClick:()=>o(C,w.route),children:f("import-as-cell")}),l.jsx("button",{className:"nc-btn danger",title:f("terminate"),onClick:()=>E(C,w.route),children:"×"})]})]},`${N}:u:${C.name}`)),w.available&&w.cells.length===0&&w.unmanaged.length===0&&l.jsx("div",{className:"nc-empty",children:f("fleet-inventory-empty")})]},N)})]})}function ER({cells:e=[],engines:t=[],models:n=[],busy:s,canRestore:o=!1,onRestore:a,onClose:u}){const[d,p]=k.useState("export"),[m,v]=k.useState([]),[y,b]=k.useState(()=>new Set(e.map(A=>A.id))),[S,x]=k.useState(()=>new Set(t.map(A=>A.id))),[E,w]=k.useState([]),[N,C]=k.useState([]),[L,I]=k.useState(""),G=new Set(t.map(A=>A.id)),K=new Set(e.map(A=>A.id)),Y=(A,T)=>A(j=>{const z=new Set(j);return z.has(T)?z.delete(T):z.add(T),z}),Q=()=>{const A=yR(e,y,t,S,new Date,n);if(A.ok===!1){I(f(`fleet-backup-${A.error}`));return}const T=e.filter(B=>y.has(B.id)).length,j=t.filter(B=>S.has(B.id)).length;if(A.cells.length!==T){I(f("fleet-backup-invalid-cell"));return}if(A.engines.length!==j){I(f("fleet-backup-invalid-engine"));return}if(!A.cells.length&&!A.engines.length){I(f("fleet-backup-select-one"));return}const z=new Blob([`${JSON.stringify(A,null,2)}
|
|
91
91
|
`],{type:"application/json"}),M=URL.createObjectURL(z),D=document.createElement("a");D.href=M,D.download=`nexuscrew-fleet-${new Date().toISOString().slice(0,10)}.json`,document.body.appendChild(D),D.click(),D.remove(),setTimeout(()=>URL.revokeObjectURL(M),0),I("")},W=async A=>{if(I(""),w([]),C([]),!!A){if(A.size>1024*1024){I(f("fleet-backup-too-large"));return}try{const T=bR(await A.text());if(!T.ok){I(f(`fleet-backup-${T.error}`));return}v(Array.isArray(T.models)?T.models:[]);const j=new Set(T.engines.map(z=>z.id));C(T.engines.map(z=>({engine:z,exists:G.has(z.id),selected:!G.has(z.id)}))),w(T.cells.map(z=>{const M=G.has(z.engine)||j.has(z.engine),D=K.has(z.id);return{cell:z,engine:M?z.engine:"",selected:M&&!D,exists:D}}))}catch(T){I(String(T.message||T))}}},X=(A,T)=>w(j=>j.map((z,M)=>M===A?{...z,...T}:z)),H=(A,T)=>C(j=>j.map((z,M)=>M===A?{...z,...T}:z)),$=new Set([...G,...N.filter(A=>A.selected).map(A=>A.engine.id)]),R=E.filter(A=>A.selected&&A.engine&&$.has(A.engine)),O=N.filter(A=>A.selected),F=[...new Map([...t.map(A=>[A.id,A.label||A.id]),...N.filter(A=>A.selected).map(A=>[A.engine.id,A.engine.label||A.engine.id])]).entries()];return l.jsxs("div",{className:"nc-set-form nc-fleet-form nc-backup-dialog",children:[l.jsx("b",{children:f("fleet-backup")}),l.jsx("small",{children:f("fleet-backup-help")}),l.jsxs("div",{className:"nc-set-tabs nc-backup-tabs",children:[l.jsx("button",{type:"button",className:`nc-set-tabbtn${d==="export"?" on":""}`,onClick:()=>{p("export"),I("")},children:f("fleet-backup-export")}),l.jsx("button",{type:"button",className:`nc-set-tabbtn${d==="import"?" on":""}`,disabled:!o,title:o?"":f("fleet-backup-restore-unavailable"),onClick:()=>{p("import"),I("")},children:f("fleet-backup-import")})]}),d==="export"?l.jsxs(l.Fragment,{children:[l.jsxs("div",{className:"nc-set-row",children:[l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:()=>{b(new Set(e.map(A=>A.id))),x(new Set(t.map(A=>A.id)))},children:f("select-all")}),l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:()=>{b(new Set),x(new Set)},children:f("select-none")})]}),l.jsxs("div",{className:"nc-backup-list",children:[l.jsx("b",{children:f("fleet-engines")}),t.map(A=>{var T;return l.jsxs("label",{className:"nc-check nc-backup-row",children:[l.jsx("input",{type:"checkbox",checked:S.has(A.id),onChange:()=>Y(x,A.id)}),l.jsxs("span",{children:[l.jsx("b",{children:A.label||A.id}),l.jsxs("small",{children:[A.id,(T=A.envKeys)!=null&&T.length?` · ${A.envKeys.length} ${f("fleet-backup-env-names")}`:""]})]})]},A.id)}),l.jsx("b",{children:f("fleet-cells")}),e.map(A=>l.jsxs("label",{className:"nc-check nc-backup-row",children:[l.jsx("input",{type:"checkbox",checked:y.has(A.id),onChange:()=>Y(b,A.id)}),l.jsxs("span",{children:[l.jsx("b",{children:A.id}),l.jsxs("small",{children:[A.engine," · ",f("fleet-system-prompt")," ",(A.prompt||"").length," ",f("characters")]})]})]},A.id)),!e.length&&!t.length&&l.jsx("div",{className:"nc-empty",children:f("fleet-backup-empty")})]}),l.jsxs("div",{className:"nc-sheet-actions",children:[l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:u,children:f("cancel")}),l.jsx("button",{type:"button",className:"nc-btn primary",disabled:!y.size&&!S.size,onClick:Q,children:f("fleet-backup-download")})]})]}):l.jsxs(l.Fragment,{children:[l.jsx("input",{type:"file",accept:"application/json,.json",disabled:s,onChange:A=>W(A.target.files&&A.target.files[0])}),l.jsx("small",{children:f("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:()=>{C(A=>A.map(T=>({...T,selected:!0}))),w(A=>A.map(T=>({...T,selected:!!T.engine})))},children:f("select-all")}),l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:()=>{C(A=>A.map(T=>({...T,selected:!1}))),w(A=>A.map(T=>({...T,selected:!1})))},children:f("select-none")})]}),l.jsxs("div",{className:"nc-backup-list",children:[!!N.length&&l.jsx("b",{children:f("fleet-engines")}),N.map((A,T)=>{var j;return l.jsx("div",{className:"nc-backup-import-row",children:l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox",checked:A.selected,onChange:z=>H(T,{selected:z.target.checked})}),l.jsxs("span",{children:[l.jsx("b",{children:A.engine.label||A.engine.id}),l.jsxs("small",{children:[A.engine.id," · ",A.exists?f("fleet-backup-overwrite"):f("fleet-backup-new"),(j=A.engine.envKeys)!=null&&j.length?` · ${f("fleet-backup-env-values-required")}`:""]})]})]})},A.engine.id)}),!!E.length&&l.jsx("b",{children:f("fleet-cells")}),E.map((A,T)=>l.jsxs("div",{className:"nc-backup-import-row",children:[l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox",checked:A.selected,disabled:!A.engine||!$.has(A.engine),onChange:j=>X(T,{selected:j.target.checked})}),l.jsxs("span",{children:[l.jsx("b",{children:A.cell.id}),l.jsxs("small",{children:[A.exists?f("fleet-backup-overwrite"):f("fleet-backup-new")," · ",f("fleet-system-prompt")," ",A.cell.systemPrompt.length," ",f("characters")]})]})]}),l.jsxs("select",{value:A.engine,onChange:j=>X(T,{engine:j.target.value,selected:!!j.target.value}),children:[l.jsx("option",{value:"",children:f("fleet-backup-engine-missing")}),F.map(([j,z])=>l.jsx("option",{value:j,children:z},j))]})]},A.cell.id))]}),l.jsxs("div",{className:"nc-sheet-actions",children:[l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:u,children:f("cancel")}),l.jsx("button",{type:"button",className:"nc-btn primary",disabled:s||!R.length&&!O.length,onClick:()=>a({engineRows:N,cellRows:E,models:m}),children:f("fleet-backup-restore")})]})]}),L&&l.jsx("div",{className:"nc-err",children:L})]})}function NR({state:e,setState:t,busy:n,onSave:s,catalog:o}){var N;const a=e.form,u=C=>t({...e,form:{...a,...C}}),d=a.envRows||[],p=[...new Map(o.map(C=>[C.client,C.clientLabel||C.client])).entries()],m=o.filter(C=>C.client===a.client),v=ja(o,a),y=typeof(v==null?void 0:v.credentialEnv)=="string"?v.credentialEnv:"",b=Array.isArray(v==null?void 0:v.credentialUsedBy)?v.credentialUsedBy:[],S=(v==null?void 0:v.credentialSource)||"missing",x=!!(v!=null&&v.credentialEnv)||a.credentialProfile==="a"||a.credentialProfile==="p",E=!!y&&e.mode==="new"&&(v==null?void 0:v.authConfigured)!==!0&&!a.credentialValue&&!a.allowMissingCredential,w=C=>{C&&u({client:C.client,provider:C.provider,credentialProfile:C.credentialProfile||"",managedModel:C.model||"",protocol:C.protocol||"",permissionPolicy:C.permissionPolicyDefault||"standard",credentialSourcePolicy:"auto",rc:!!C.rc,displayName:C.custom?f("fleet-custom-provider-default"):"",baseUrl:C.custom?"":C.endpoint||"",envKey:C.defaultEnvKey||"",providerId:"nexuscrew-custom",credentialValue:"",credentialReveal:!1,allowMissingCredential:!1,...e.mode==="new"?{id:C.id,label:""}:{}})};return l.jsxs("div",{className:"nc-set-form nc-fleet-form",children:[l.jsx("b",{children:e.mode==="new"?f("fleet-new-engine"):`${f("edit")} ${a.id}`}),l.jsx("input",{value:a.id,disabled:e.mode!=="new",placeholder:"id",onChange:C=>u({id:C.target.value})}),l.jsx("input",{value:a.label,placeholder:f("label"),onChange:C=>u({label:C.target.value})}),l.jsxs("select",{value:a.kind,disabled:e.mode!=="new",onChange:C=>u({kind:C.target.value}),children:[l.jsx("option",{value:"managed",children:f("fleet-managed")}),l.jsx("option",{value:"custom",children:f("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:e.mode!=="new",onChange:C=>w(o.find(L=>L.client===C.target.value&&L.default)||o.find(L=>L.client===C.target.value)),children:p.map(([C,L])=>l.jsx("option",{value:C,children:L},C))}),l.jsx("select",{value:((N=ja(o,a))==null?void 0:N.id)||"",disabled:e.mode!=="new",onChange:C=>w(o.find(L=>L.id===C.target.value)),children:m.map(C=>l.jsx("option",{value:C.id,children:C.label},C.id))})]}),a.client!=="shell"&&l.jsxs(l.Fragment,{children:[l.jsx("input",{value:a.managedModel,list:"nc-managed-models",placeholder:f(v!=null&&v.requiresModel?"fleet-model-required":"fleet-model-default"),onChange:C=>u({managedModel:C.target.value})}),l.jsx("datalist",{id:"nc-managed-models",children:[...(v==null?void 0:v.models)||[],...a.modelOptions||[]].filter((C,L,I)=>C&&I.indexOf(C)===L).map(C=>l.jsx("option",{value:C},C))})]}),v!=null&&v.supportsUnsafe?l.jsxs("select",{value:a.permissionPolicy,onChange:C=>u({permissionPolicy:C.target.value}),children:[l.jsx("option",{value:"standard",children:f("fleet-standard-permissions")}),l.jsx("option",{value:"unsafe",children:f("fleet-unsafe-permissions")})]}):l.jsx("small",{children:f("fleet-standard-permissions")}),(v==null?void 0:v.supportsUnsafe)&&a.permissionPolicy==="unsafe"&&l.jsx("small",{className:"nc-err",children:f("fleet-unsafe-warning")}),x&&l.jsxs("select",{"aria-label":f("fleet-credential-source-policy"),value:a.credentialSourcePolicy||"auto",onChange:C=>u({credentialSourcePolicy:C.target.value}),children:[l.jsx("option",{value:"auto",children:f("fleet-credential-source-policy-auto")}),l.jsx("option",{value:"nexuscrew-store",children:f("fleet-credential-source-policy-nexuscrew-store")}),l.jsx("option",{value:"environment",children:f("fleet-credential-source-policy-environment")})]}),(v==null?void 0:v.credentialEnv)===!0&&l.jsxs(l.Fragment,{children:[l.jsx("input",{value:a.envKey,placeholder:f("fleet-api-key-env"),onChange:C=>u({envKey:C.target.value})}),l.jsx("small",{children:f("fleet-custom-secret-help")})]}),y&&l.jsxs("section",{className:"nc-fleet-key","aria-label":f("fleet-key-section"),children:[l.jsxs("div",{className:"nc-fleet-key-head",children:[l.jsx("b",{children:f("fleet-key-section")}),l.jsx("span",{children:f(`fleet-credential-source-${S}`)})]}),l.jsxs("label",{className:"nc-field",children:[f("fleet-key-variable"),l.jsx("input",{value:y,readOnly:!0,"aria-label":f("fleet-key-variable")})]}),l.jsx("small",{children:b.length?f("fleet-key-used-by").replace("{engines}",b.join(", ")):f("fleet-key-used-by-none")}),b.length>0&&l.jsx("small",{children:f("fleet-key-shared-impact").replace("{key}",y).replace("{engines}",b.join(", "))}),l.jsxs("div",{className:"nc-fleet-key-input",children:[l.jsx("input",{type:a.credentialReveal?"text":"password",value:a.credentialValue||"","aria-label":f("fleet-key-value").replace("{key}",y),autoComplete:"new-password",spellCheck:!1,autoCapitalize:"none",autoCorrect:"off",placeholder:v!=null&&v.authConfigured||e.mode==="edit"?f("fleet-key-blank-keeps"):f("fleet-key-enter"),onChange:C=>u({credentialValue:C.target.value,allowMissingCredential:C.target.value?!1:a.allowMissingCredential})}),l.jsx("button",{type:"button",className:"nc-btn ghost","aria-label":f(a.credentialReveal?"fleet-key-hide":"fleet-key-reveal"),onClick:()=>u({credentialReveal:!a.credentialReveal}),children:f(a.credentialReveal?"fleet-key-hide":"fleet-key-reveal")})]}),l.jsx("small",{children:f("fleet-key-local-help")}),e.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:C=>u({allowMissingCredential:C.target.checked})}),f("fleet-key-create-missing")]}),(v==null?void 0:v.notice)&&l.jsx("small",{className:"nc-fleet-provider-notice",children:f(`fleet-provider-notice-${v.notice}`)})]}),(v==null?void 0:v.notice)&&!y&&l.jsx("small",{className:"nc-fleet-provider-notice",children:f(`fleet-provider-notice-${v.notice}`)}),a.provider==="custom"&&l.jsxs(l.Fragment,{children:[l.jsx("input",{value:a.displayName,placeholder:f("fleet-provider-display"),onChange:C=>u({displayName:C.target.value})}),l.jsx("input",{value:a.baseUrl,placeholder:"https://api.example.com/v1",onChange:C=>u({baseUrl:C.target.value})}),((v==null?void 0:v.protocols)||[]).length>1&&l.jsx("select",{value:a.protocol,onChange:C=>u({protocol:C.target.value}),children:v.protocols.map(C=>l.jsx("option",{value:C,children:C},C))}),l.jsxs("div",{className:"nc-fleet-pair",children:[l.jsx("input",{value:a.envKey,placeholder:f("fleet-api-key-env"),onChange:C=>u({envKey:C.target.value})}),l.jsx("input",{value:a.providerId,placeholder:f("fleet-provider-id"),onChange:C=>u({providerId:C.target.value})})]}),l.jsxs("small",{children:[a.protocol," · ",f("fleet-custom-secret-help")]})]}),l.jsx("small",{children:f(a.client==="shell"?"fleet-shell-engine-help":"fleet-managed-help")})]}):l.jsxs(l.Fragment,{children:[l.jsx("input",{value:a.command,placeholder:f("command-path"),onChange:C=>u({command:C.target.value})}),l.jsx("textarea",{value:a.argsText,placeholder:f("args-lines"),onChange:C=>u({argsText:C.target.value})}),l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox",checked:a.rc,onChange:C=>u({rc:C.target.checked})})," ",f("fleet-remote-control")]}),l.jsxs("select",{value:a.promptMode,onChange:C=>u({promptMode:C.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:C=>u({promptFlag:C.target.value})}),l.jsxs("div",{className:"nc-fleet-pair",children:[l.jsx("input",{value:a.modelFlag,placeholder:"model flag",onChange:C=>u({modelFlag:C.target.value})}),l.jsx("input",{value:a.modelValue,placeholder:"model default",onChange:C=>u({modelValue:C.target.value})})]}),l.jsx("small",{children:f("env-write-only")}),d.map((C,L)=>l.jsxs("div",{className:"nc-fleet-env",children:[l.jsx("input",{value:C.key,disabled:C.configured,placeholder:"ENV_KEY",onChange:I=>{const G=d.slice();G[L]={...C,key:I.target.value},u({envRows:G})}}),l.jsx("input",{type:"password",value:C.value,placeholder:C.configured?"•••••• (unchanged)":"value",onChange:I=>{const G=d.slice();G[L]={...C,value:I.target.value},u({envRows:G})}}),l.jsx("button",{className:"nc-btn danger",onClick:()=>u({envRows:d.filter((I,G)=>G!==L)}),children:"×"})]},`${C.key}-${L}`)),l.jsx("button",{className:"nc-btn ghost",onClick:()=>u({envRows:[...d,{key:"",value:"",configured:!1}]}),children:"+ env"})]}),l.jsx("input",{value:a.panelUrl||"",maxLength:512,placeholder:f("fleet-panel-url"),onChange:C=>u({panelUrl:C.target.value})}),l.jsx("small",{children:f("fleet-panel-url-help")}),a.panelUrl&&!xp(a.panelUrl)&&l.jsx("small",{className:"nc-err",children:f("fleet-panel-url-invalid")}),l.jsxs("div",{className:"nc-sheet-actions",children:[l.jsx("button",{className:"nc-btn ghost",onClick:()=>t(null),children:f("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:f("save")})]})]})}function jR({state:e,setState:t,busy:n,onSave:s,onTest:o,profiles:a=[],canTest:u=!0}){const[d,p]=k.useState(null),[m,v]=k.useState(!1),y=e.form,b=w=>t({...e,form:{...y,...w}}),S=/^[^\x00-\x1f\x7f]{1,128}$/.test(y.id||""),x=!!(y.id||"").trim()&&!!(y.engine||"").trim()&&S,E=async()=>{p(null),v(!0);try{p(await o(y.engine,y.id))}catch(w){p({outcome:"unverified",detail:String(w&&w.message||w)})}v(!1)};return l.jsxs("div",{className:"nc-fleet-form",children:[l.jsxs("label",{className:"nc-field",children:[f("model-editor-engine"),l.jsxs("select",{value:y.engine||"",disabled:n||e.mode==="edit",onChange:w=>{p(null),b({engine:w.target.value})},children:[l.jsx("option",{value:"",children:"—"}),a.map(w=>l.jsx("option",{value:w.id,children:w.label?`${w.id} · ${w.label}`:w.id},w.id))]})]}),l.jsxs("label",{className:"nc-field",children:[f("model-editor-id"),l.jsx("input",{value:y.id||"",disabled:n||e.mode==="edit",placeholder:"qwen3.9-max",onChange:w=>{p(null),b({id:w.target.value})}})]}),l.jsx("small",{className:"nc-set-hint",children:f("model-editor-id-help")}),l.jsxs("label",{className:"nc-field",children:[f("model-editor-context"),l.jsx("input",{inputMode:"numeric",value:y.contextWindow||"",disabled:n,onChange:w=>b({contextWindow:w.target.value.replace(/[^0-9]/g,"").slice(0,9)})})]}),l.jsxs("label",{className:"nc-field",children:[f("model-editor-max-tokens"),l.jsx("input",{inputMode:"numeric",value:y.maxTokens||"",disabled:n,onChange:w=>b({maxTokens:w.target.value.replace(/[^0-9]/g,"").slice(0,9)})})]}),l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox",checked:y.reasoning===!0,disabled:n,onChange:w=>b({reasoning:w.target.checked})})," ",f("model-editor-reasoning")]}),l.jsxs("div",{className:"nc-set-row",children:[u&&l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:n||m||!x,onClick:E,children:f(m?"model-test-running":"model-test")}),d&&l.jsxs("span",{className:`nc-model-test ${d.outcome}`,children:[f(`model-test-${d.outcome}`),d.outcome==="ok"&&Number.isInteger(d.latencyMs)?` · ${d.latencyMs}ms`:""]})]}),d&&d.detail&&l.jsx("small",{className:"nc-set-hint",children:d.detail}),d&&d.outcome==="unverified"&&l.jsx("small",{className:"nc-set-hint",children:f("model-test-unverified-help")}),l.jsxs("div",{className:"nc-sheet-actions",children:[l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:()=>t(null),children:f("cancel")}),l.jsx("button",{type:"button",className:"nc-btn primary",disabled:n||!x,onClick:()=>s(y),children:f("save")})]})]})}function RR({token:e,route:t,targets:n=[],location:s,setLocation:o,state:a,setState:u,engines:d,mcpServers:p=[],managedCatalog:m=[],busy:v,onSave:y}){var O,F,A;const[b,S]=k.useState(null),[x,E]=k.useState(""),w=a.form,N=T=>u({...a,form:{...w,...T}}),C=d.find(T=>T.id===w.engine),L=((O=C==null?void 0:C.managed)==null?void 0:O.client)==="shell",I=((F=C==null?void 0:C.managed)==null?void 0:F.client)||"",G=((A=m.find(T=>T.client===I))==null?void 0:A.mcpManaged)!==!1,K=T=>{var M,D,B,U;const j=d.find(se=>se.id===T),z={...w.commands||{}};((M=C==null?void 0:C.managed)==null?void 0:M.client)==="shell"&&(w.command?z[w.engine]=w.command:delete z[w.engine]),N({engine:T,model:((D=w.models)==null?void 0:D[T])||((B=j==null?void 0:j.managed)==null?void 0:B.model)||((U=j==null?void 0:j.model)==null?void 0:U.value)||"",commands:z,command:z[T]||""})},Y=T=>{const j={...w.commands||{}};T?j[w.engine]=T:delete j[w.engine],N({command:T,commands:j})},Q=L&&/[|&;<>()`$*?{}\[\]~]/.test(w.command||""),W=[...new Set([...p||[],...Array.isArray(w.mcp)?w.mcp:[]])].sort(),X=Array.isArray(w.mcp)?w.mcp.length?"some":"none":"all",H=T=>{var j;return N({mcp:T==="all"?void 0:T==="none"?[]:(j=w.mcp)!=null&&j.length?w.mcp:[...W]})},$=T=>{const j=Array.isArray(w.mcp)?w.mcp:[];N({mcp:j.includes(T)?j.filter(z=>z!==T):[...j,T].sort()})},R=async T=>{try{const j=await Mf(e,T,t);S(j),N({cwd:j.path}),E("")}catch(j){E(String(j.message||j))}};return l.jsxs("div",{className:"nc-set-form nc-fleet-form",children:[l.jsx("b",{children:a.mode==="new"?f("fleet-new-cell"):`${f("edit")} ${w.id}`}),a.mode==="new"&&l.jsxs("label",{className:"nc-field",children:[f("location"),l.jsx("span",{className:"nc-req",children:" *"}),l.jsxs("select",{value:s,onChange:T=>{o(T.target.value),N({engine:""})},children:[l.jsx("option",{value:"",children:f("local")}),n.map(T=>l.jsxs("option",{value:T.route.join("/"),disabled:T.status&&T.status!=="up",children:[T.label,T.status&&T.status!=="up"?` · ${f("node-offline")}`:""]},T.route.join("/")))]})]}),l.jsx("input",{value:w.id,disabled:a.mode!=="new",placeholder:"id",onChange:T=>N({id:T.target.value})}),l.jsx("input",{value:w.label||"",maxLength:64,placeholder:f("fleet-cell-label"),onChange:T=>N({label:T.target.value})}),l.jsxs("div",{className:"nc-fleet-pair",children:[l.jsx("input",{value:w.cwd,placeholder:f("cwd"),onChange:T=>N({cwd:T.target.value})}),l.jsx("button",{className:"nc-btn ghost",onClick:()=>b?S(null):R(w.cwd),children:f("browse")})]}),b&&l.jsxs("div",{className:"nc-fs",children:[l.jsx("div",{className:"nc-fs-path",children:b.path}),l.jsxs("div",{className:"nc-fs-list",children:[b.parent&&l.jsxs("button",{className:"nc-fs-item nc-fs-nav",onClick:()=>R(b.parent),children:["↑ ",f("fs-parent")]}),(b.dirs||[]).map(T=>l.jsxs("button",{className:"nc-fs-item",onClick:()=>R(`${b.path.replace(/\/$/,"")}/${T}`),children:["📁 ",T]},T))]})]}),x&&l.jsx("div",{className:"nc-err",children:x}),l.jsx("select",{value:w.engine,onChange:T=>K(T.target.value),children:d.map(T=>l.jsx("option",{value:T.id,children:T.label},T.id))}),l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox",checked:!!w.boot,onChange:T=>N({boot:T.target.checked})})," ",f("fleet-boot")]}),l.jsx("input",{value:w.panelUrl||"",maxLength:512,placeholder:f("fleet-panel-url"),onChange:T=>N({panelUrl:T.target.value})}),l.jsx("small",{children:f("fleet-panel-url-help")}),w.panelUrl&&!xp(w.panelUrl)&&l.jsx("small",{className:"nc-err",children:f("fleet-panel-url-invalid")}),L?l.jsxs(l.Fragment,{children:[l.jsx("input",{value:w.command||"",maxLength:4096,placeholder:f("fleet-shell-command-placeholder"),onChange:T=>Y(T.target.value)}),l.jsx("small",{children:w.command?f("fleet-shell-command-help"):f("fleet-shell-interactive")}),Q&&l.jsx("small",{className:"nc-note",children:f("fleet-shell-command-metachar")})]}):l.jsxs(l.Fragment,{children:[l.jsx("input",{value:w.model||"",list:"nc-cell-models",placeholder:f("fleet-model-override"),onChange:T=>N({model:T.target.value})}),l.jsx("datalist",{id:"nc-cell-models",children:((C==null?void 0:C.availableModels)||[]).map(T=>l.jsx("option",{value:T},T))}),l.jsx("textarea",{value:w.prompt||"",placeholder:f("cell-prompt"),onChange:T=>N({prompt:T.target.value})}),l.jsx("small",{children:f("cell-prompt-help")}),l.jsxs("label",{className:"nc-field",children:[f("cell-mcp"),l.jsxs("select",{value:X,onChange:T=>H(T.target.value),children:[l.jsx("option",{value:"all",children:f("cell-mcp-all")}),l.jsx("option",{value:"none",children:f("cell-mcp-none")}),l.jsx("option",{value:"some",children:f("cell-mcp-some")})]})]}),!G&&l.jsx("small",{className:"nc-note",children:f("cell-mcp-inert")}),X==="some"&&l.jsx("div",{className:"nc-fleet-mcp-list",children:W.map(T=>l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox",checked:(w.mcp||[]).includes(T),onChange:()=>$(T)})," ",T]},T))}),l.jsx("small",{children:f("cell-mcp-help")})]}),l.jsxs("div",{className:"nc-sheet-actions",children:[l.jsx("button",{className:"nc-btn ghost",onClick:()=>u(null),children:f("cancel")}),l.jsx("button",{className:"nc-btn primary",disabled:v||!w.id||!w.cwd||!w.engine,onClick:y,children:f("save")})]})]})}function jy({token:e,route:t=[],state:n,setState:s,busy:o,onSave:a}){const[u,d]=k.useState(null),[p,m]=k.useState([]),[v,y]=k.useState(""),b=Array.isArray(t)?t.join("/"):"";k.useEffect(()=>{let N=!0;return Ec(e,b?b.split("/"):[]).then(C=>{N&&(m(C.engines||[]),y(""))}).catch(C=>{N&&(m([]),y(String(C.message||C)))}),()=>{N=!1}},[e,b]);const S=n.form,x=N=>s({...n,form:{...S,...N}}),E=async N=>{try{const C=await Mf(e,N,t);d(C),x({cwd:C.path})}catch{}},w=!S.id&&S.tmuxSession?S.tmuxSession.replace(/[^A-Za-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"").slice(0,32):S.id;return l.jsxs("div",{className:"nc-set-form nc-fleet-form",children:[l.jsxs("b",{children:[f("import-as-cell")," · ",S.tmuxSession]}),l.jsx("small",{children:f("import-help")}),l.jsx("input",{value:S.tmuxSession,disabled:!0,placeholder:"tmux session",readOnly:!0}),l.jsx("input",{value:S.id,placeholder:f("name"),onChange:N=>x({id:N.target.value})}),l.jsxs("div",{className:"nc-fleet-pair",children:[l.jsx("input",{value:S.cwd,placeholder:f("cwd"),onChange:N=>x({cwd:N.target.value})}),l.jsx("button",{className:"nc-btn ghost",type:"button",onClick:()=>u?d(null):E(S.cwd),children:f("browse")})]}),u&&l.jsxs("div",{className:"nc-fs",children:[l.jsx("div",{className:"nc-fs-path",children:u.path}),l.jsxs("div",{className:"nc-fs-list",children:[u.parent&&l.jsxs("button",{className:"nc-fs-item nc-fs-nav",onClick:()=>E(u.parent),children:["↑ ",f("fs-parent")]}),(u.dirs||[]).map(N=>l.jsxs("button",{className:"nc-fs-item",onClick:()=>E(`${u.path.replace(/\/$/,"")}/${N}`),children:["📁 ",N]},N))]})]}),l.jsxs("select",{value:S.engine,onChange:N=>x({engine:N.target.value}),children:[l.jsx("option",{value:"",children:f("import-engine-required")}),p.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:!!S.boot,onChange:N=>x({boot:N.target.checked})})," ",f("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:f("cancel")}),l.jsx("button",{className:"nc-btn primary",disabled:o||!S.tmuxSession||!S.engine||!p.length,onClick:a,children:f(w?"import-as-cell":"save")})]})]})}function Jl(e){const t=br(e);return t===null?`~/${e}`:t?`~/${t}`:"~"}function PR(e){if(!e||typeof e.path!="string"||typeof e.home!="string")return"";const{path:t,home:n}=e;return!n||t===n||!t.startsWith(n+"/")?"":t.slice(n.length+1).replace(/\/+$/,"")}function LR({token:e,route:t,cell:n,busy:s=!1,onSaved:o,onClose:a}){const[u,d]=k.useState(""),[p,m]=k.useState(null),[v,y]=k.useState(!1),[b,S]=k.useState(""),x=typeof(n==null?void 0:n.cwdSuggestion)=="string"&&br(n.cwdSuggestion)!==null?br(n.cwdSuggestion):null,[E,w]=k.useState(x),N=n==null?void 0:n.id,C=s||v,L=async W=>{const X=br(W);if(X===null){m({rel:"",dirs:[],loading:!1,err:f("fleet-cwd-repair-invalid")});return}m({rel:X,dirs:[],loading:!0,err:""});try{const H=await Mf(e,X,t),$=PR(H);m({rel:$,dirs:Array.isArray(H.dirs)?H.dirs:[],loading:!1,err:""})}catch(H){m({rel:X,dirs:[],loading:!1,err:String(H&&H.message||H)})}},I=W=>{if(!p)return;const X=p.rel?`${p.rel}/${W}`:W;L(X)},G=()=>{p!=null&&p.rel&&L(p.rel.split("/").slice(0,-1).join("/"))},K=()=>{p&&(d(p.rel||""),m(null),S(""),w(null))},Y=()=>{E!==null&&(d(E),w(null),S(""))},Q=async()=>{if(C)return;const W=br(u);if(W===null){S(f("fleet-cwd-repair-invalid"));return}const X=Jl(W);let H=!0;try{H=window.confirm(f("fleet-cwd-repair-confirm").replace("{id}",String(N||"")).replace("{path}",X))}catch{H=!1}if(H){y(!0),S(""),w(null);try{const $=await Hy(e,N,{cwdRel:W},t);o==null||o($)}catch($){const R=$&&$.data||{};if(R.code==="unportable-cwd"){S(f("fleet-cwd-repair-unportable"));const O=Array.isArray(R.cells)?R.cells.find(A=>A&&A.id===N):null,F=O&&typeof O.suggestion=="string"?O.suggestion:null;F!==null&&br(F)!==null&&w(F)}else S(String($&&$.message||$))}finally{y(!1)}}};return l.jsxs("div",{className:"nc-set-form nc-fleet-form nc-cwd-repair",children:[l.jsx("b",{children:f("fleet-cwd-repair-title").replace("{id}",String(N||""))}),l.jsx("small",{className:"nc-set-info",children:f("fleet-cwd-repair-help")}),l.jsx("small",{className:"nc-cwd-no-source",children:f("fleet-cwd-repair-no-source-path")}),l.jsxs("label",{className:"nc-field",children:[f("cwd"),l.jsxs("div",{className:"nc-cwd-rel-row",children:[l.jsx("span",{className:"nc-cwd-rel-prefix",children:"~/"}),l.jsx("input",{value:u,placeholder:f("fleet-cwd-repair-placeholder"),autoComplete:"off",spellCheck:"false",autoCapitalize:"none",onChange:W=>d(W.target.value)}),l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:C,onClick:()=>p?m(null):L(""),children:f(p?"close":"fleet-cwd-repair-browse")})]})]}),l.jsx("div",{className:"nc-cwd-preview",children:f("fleet-cwd-repair-preview").replace("{path}",Jl(u))}),p&&l.jsxs("div",{className:"nc-fs",children:[l.jsx("div",{className:"nc-fs-path",children:Jl(p.rel)}),l.jsxs("div",{className:"nc-fs-list",children:[p.rel&&l.jsxs("button",{type:"button",className:"nc-fs-item nc-fs-nav",onClick:G,children:["↑ ",f("fs-parent")]}),p.loading&&l.jsx("div",{className:"nc-fs-empty",children:"…"}),!p.loading&&p.dirs.length===0&&l.jsx("div",{className:"nc-fs-empty",children:f("fleet-cwd-repair-fs-empty")}),!p.loading&&p.dirs.map(W=>l.jsxs("button",{type:"button",className:"nc-fs-item",onClick:()=>I(W),children:["📁 ",W]},W))]}),p.err&&l.jsx("div",{className:"nc-err",children:p.err}),l.jsx("div",{className:"nc-sheet-actions",children:l.jsx("button",{type:"button",className:"nc-btn primary",disabled:C||p.loading||!!p.err,onClick:K,children:f("fleet-cwd-repair-use-current")})})]}),b&&l.jsx("div",{className:"nc-err",role:"alert",children:b}),E!==null&&l.jsxs("div",{className:"nc-cwd-suggestion",role:"status",children:[l.jsx("span",{children:f("fleet-cwd-repair-suggestion")}),l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:Y,children:f("fleet-cwd-repair-use-suggestion").replace("{path}",Jl(E))})]}),l.jsxs("div",{className:"nc-sheet-actions",children:[l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:v,onClick:a,children:f("cancel")}),l.jsx("button",{type:"button",className:"nc-btn primary",disabled:C,onClick:Q,children:v?"…":f("save")})]})]})}function AR({token:e,readonly:t,targets:n=[],startNewCell:s=!1,initialLocation:o=""}){const[a,u]=k.useState({engines:[],cells:[],managedCatalog:[]}),[d,p]=k.useState({available:!1,capabilities:[]}),[m,v]=k.useState(!1),[y,b]=k.useState(null),[S,x]=k.useState(null),[E,w]=k.useState({}),[N,C]=k.useState(null),[L,I]=k.useState(!1),[G,K]=k.useState(""),[Y,Q]=k.useState(""),[W,X]=k.useState(o),[H,$]=k.useState(!1),[R,O]=k.useState(null),[F,A]=k.useState(null),[T,j]=k.useState(null),[z,M]=k.useState(!1),[D,B]=k.useState([]),[U,se]=k.useState(null),[ee,de]=k.useState("manage"),ve=k.useRef(!1),fe=W?W.split("/"):[],pe=k.useCallback(async()=>{try{const oe=await Xs(e,fe);p(oe);try{const ie=await Df(e,fe);$(!!ie.readonlyDefault)}catch{$(!1)}if(oe.provider==="builtin"&&(oe.capabilities||[]).includes("definitions")){const ie=await Ec(e,fe),_e=new Map((oe.engines||[]).map(be=>[be.id,be]));if(ie.engines=(ie.engines||[]).map(be=>{var ke;return{...be,availableModels:((ke=_e.get(be.id))==null?void 0:ke.models)||[]}}),u(ie),(oe.capabilities||[]).includes("credentials"))try{B((await lx(e,fe)).credentials||[])}catch{B([])}else B([])}K("")}catch(oe){K(String(oe.message||oe))}finally{v(!0)}},[e,W]);k.useEffect(()=>{pe();const oe=setInterval(pe,5e3);return()=>clearInterval(oe)},[pe]);const Ve=new Set((d.cells||[]).filter(oe=>oe.active).map(oe=>oe.cell)),ut=d.provider==="builtin"&&(d.capabilities||[]).includes("edit"),vt=(d.capabilities||[]).includes("restore");k.useEffect(()=>{!s||ve.current||!ut||!a.engines.length||(ve.current=!0,C({mode:"new",form:Ey(a.engines[0].id)}))},[s,ut,a.engines]);const je=async oe=>{I(!0),K(""),Q("");try{await oe(),await pe()}catch(ie){K(String(ie.message||ie))}I(!1)},Ct=async(oe,ie)=>{const _e=await mx(e,oe,ie,fe);return w(be=>({...be,[`${oe}::${ie}`]:_e})),_e},dn=oe=>je(async()=>{const ie={id:String(oe.id||"").trim(),engine:String(oe.engine||"").trim()};for(const _e of["contextWindow","maxTokens"]){const be=String(oe[_e]||"").trim();be&&(ie[_e]=Number(be))}oe.reasoning===!0&&(ie.reasoning=!0),await fx(e,ie,fe),x(null),await pe()}),gn=()=>je(async()=>{var zt;const oe=y.mode==="new",ie=y.form,_e=a.managedCatalog||[],be=ie.kind==="managed"?ja(_e,ie):null,ke=typeof(be==null?void 0:be.credentialEnv)=="string"?be.credentialEnv:"",it=ke&&ie.credentialValue||"",ht=CR(ie,oe,_e);!oe&&y.form.kind==="custom"&&!y.form.modelFlag&&(ht.model=null),!oe&&y.form.kind==="custom"&&y.form.promptMode!=="flag"&&(ht.promptFlag=null);let dt;if(oe)dt=await ux(e,ht,fe);else{const Je=y.original,J=new Set(y.form.envRows.filter(Oe=>!Oe.remove).map(Oe=>Oe.key)),Ne=(Je.envKeys||[]).filter(Oe=>!J.has(Oe)),Ue=Object.fromEntries(y.form.envRows.filter(Oe=>!Oe.remove&&Oe.key&&(!Oe.configured||Oe.value!=="")).map(Oe=>[Oe.key,Oe.value]));dt=await dx(e,Je.id,ht,y.form.kind==="custom"?{set:Ue,remove:Ne}:void 0,fe)}let Rt=null;if(ke&&it)try{Rt=await Zg(e,ke,it,fe),B(Rt.credentials||[])}catch{throw await pe(),oe&&b({mode:"edit",original:{...ht,id:ie.id},form:{...ie,credentialReveal:!1}}),new Error(f(oe?"fleet-key-partial-create":"fleet-key-partial-edit"))}await pe(),b(null),Q(f("fleet-saved"));const wt=((zt=((Rt==null?void 0:Rt.credentials)||[]).find(Je=>Je.envKey===ke))==null?void 0:zt.activeCells)||[],_t=[...new Set([...(dt==null?void 0:dt.activeCells)||[],...wt])];if(_t.length&&window.confirm(f("fleet-restart-confirm").replace("{cells}",_t.join(", "))))for(const Je of _t)await fa(e,Je,fe)}),Yt=()=>je(async()=>{var wt,_t,zt,Je,J,Ne;const oe=N.mode==="new",ie=N.form,_e={...oe?{id:ie.id}:{},cwd:ie.cwd,engine:ie.engine,boot:!!ie.boot},be={...ie.commands||{}},ke=a.engines.find(Ue=>Ue.id===ie.engine);((wt=ke==null?void 0:ke.managed)==null?void 0:wt.client)==="shell"&&typeof ie.command=="string"&&ie.command.length?be[ie.engine]=ie.command:((_t=ke==null?void 0:ke.managed)==null?void 0:_t.client)==="shell"&&delete be[ie.engine],(Object.keys(be).length||!oe)&&(_e.commands=be);const it=(ie.label||"").trim();oe?it&&(_e.label=it):_e.label=it||null;const ht=(ie.panelUrl||"").trim();oe?ht&&(_e.panelUrl=ht):_e.panelUrl=ht||null,oe?Array.isArray(ie.mcp)&&(_e.mcp=ie.mcp):_e.mcp=Array.isArray(ie.mcp)?ie.mcp:null,oe?(((zt=ke==null?void 0:ke.managed)==null?void 0:zt.client)!=="shell"&&ie.model&&(_e.model=ie.model),((Je=ke==null?void 0:ke.managed)==null?void 0:Je.client)!=="shell"&&ie.prompt&&(_e.prompt=ie.prompt)):(_e.model=((J=ke==null?void 0:ke.managed)==null?void 0:J.client)==="shell"?null:ie.model||null,((Ne=ke==null?void 0:ke.managed)==null?void 0:Ne.client)!=="shell"&&(_e.prompt=ie.prompt||null));const dt=oe?await gx(e,_e,fe):await Hy(e,N.original.id,_e,fe),Rt=oe?ie.id:N.original.id;C(null),Q(f("fleet-saved")),!oe&&(dt!=null&&dt.active)&&window.confirm(f("fleet-restart-confirm").replace("{cells}",Rt))&&await fa(e,Rt,fe)}),xt=t||H,Ot=d.capabilities||[],Ut=fe.length>0&&xt,Nt=oe=>D.find(ie=>{var _e;return(_e=ie.engines)==null?void 0:_e.includes(oe.id)})||null,Dt=()=>je(async()=>{var _e;const oe=await Zg(e,U.envKey,U.value,fe);B(oe.credentials||[]),se(null),Q(f("fleet-credential-saved"));const ie=((_e=(oe.credentials||[]).find(be=>be.envKey===U.envKey))==null?void 0:_e.activeCells)||[];if(ie.length&&window.confirm(f("fleet-restart-confirm").replace("{cells}",ie.join(", "))))for(const be of ie)await fa(e,be,fe)}),At=oe=>je(async()=>{if(!window.confirm(f("fleet-credential-remove-confirm").replace("{key}",oe.envKey)))return;const ie=await cx(e,oe.envKey,fe);B(ie.credentials||[]),Q(f("fleet-credential-removed"))}),jt=oe=>O({...oe,route:Array.isArray(oe==null?void 0:oe.route)?oe.route:fe}),hn=async oe=>{if(!R)return;const ie=R.cell||R.id,_e=Array.isArray(R.route)?R.route:fe;if(oe.action==="up"){const be=await Lf(e,{cell:ie,boot:!!oe.boot,...oe.engine?{engine:oe.engine}:{},...oe.model!==void 0?{model:oe.model}:{},...oe.permissionPolicy?{permissionPolicy:oe.permissionPolicy}:{}},_e),ke=Vf(be);ke&&Q(ke.text)}else await lc(e,{cell:ie,boot:!!oe.boot},_e)},re=(oe,ie)=>{K(""),A({mode:"new",route:Array.isArray(ie)?ie:fe,form:{tmuxSession:oe.name,id:"",engine:"",cwd:"",boot:!1},err:""})},Qe=()=>je(async()=>{const oe=F.form;if(!oe.engine){A({...F,err:f("import-engine-required")});return}await vx(e,{tmuxSession:oe.tmuxSession,id:oe.id||void 0,engine:oe.engine,cwd:oe.cwd||void 0,boot:!!oe.boot},oe.route||fe),A(null),Q(f("fleet-saved"))}),me=({engineRows:oe=[],cellRows:ie=[],models:_e=[]})=>je(async()=>{const be=oe.filter(Je=>Je.selected),ke=be.map(Je=>rS(Je.engine));if(ke.some(Je=>!Je))throw new Error(f("fleet-backup-invalid-engine"));const it=be.filter(Je=>Je.exists).map(Je=>Je.engine.id);if(it.length&&!window.confirm(f("fleet-backup-confirm-engine-overwrite").replace("{engines}",it.join(", "))))return;const ht=[...new Set([...a.engines.map(Je=>Je.id),...ke.map(Je=>Je.id)])],dt=[];for(const Je of ie.filter(J=>J.selected)){const J=wR(Je.cell,Je.engine,ht);if(!J)throw new Error(`${Je.cell.id}: ${f("fleet-backup-engine-missing")}`);dt.push(J)}const Rt=ie.filter(Je=>Je.selected&&Je.exists).map(Je=>Je.cell.id);if(Rt.length&&!window.confirm(f("fleet-backup-confirm-overwrite").replace("{cells}",Rt.join(", "))))return;const wt=ke.length?await yx(e,ke,it.length>0,fe,_e):{needsRestart:[]},_t=dt.length?await _x(e,dt,fe):{needsRestart:[]},zt=[...new Set([...wt.needsRestart||[],..._t.needsRestart||[]])];M(!1),Q(`${f("fleet-backup-restored").replace("{n}",String(dt.length))}${ke.length?` · ${ke.length} ${f("fleet-engines").toLowerCase()}`:""}${zt.length?` · ${f("fleet-backup-needs-restart").replace("{cells}",zt.join(", "))}`:""}`)}),Ge=l.jsxs("label",{className:"nc-field",children:[f("location"),l.jsxs("select",{value:W,onChange:oe=>{X(oe.target.value),b(null),C(null),K(""),Q(""),$(!1),v(!1),p({available:!1,capabilities:[]}),u({engines:[],cells:[],managedCatalog:[]}),B([]),se(null)},children:[l.jsx("option",{value:"",children:f("local")}),n.map(oe=>l.jsxs("option",{value:oe.route.join("/"),disabled:oe.status&&oe.status!=="up",children:[oe.label,oe.status&&oe.status!=="up"?` · ${f("node-offline")}`:""]},oe.route.join("/")))]})]}),ct=l.jsxs("div",{className:"nc-fleet-view-tabs",role:"tablist","aria-label":f("tab-fleet"),children:[l.jsx("button",{type:"button",role:"tab","aria-selected":ee==="manage",className:`nc-set-tabbtn${ee==="manage"?" on":""}`,onClick:()=>de("manage"),children:f("fleet-manage-location")}),l.jsx("button",{type:"button",role:"tab","aria-selected":ee==="overview",className:`nc-set-tabbtn${ee==="overview"?" on":""}`,onClick:()=>de("overview"),children:f("fleet-network-overview")})]});return m?ut?l.jsxs("div",{className:"nc-set-tab nc-fleet-editor",children:[ct,ee==="overview"?l.jsxs(l.Fragment,{children:[l.jsx("div",{className:"nc-set-info",children:f("fleet-overview-help")}),l.jsx(dh,{token:e,targets:n,readonly:t,onPower:jt,onImport:re})]}):l.jsxs(l.Fragment,{children:[l.jsx("div",{className:"nc-set-info",children:f("fleet-manage-help")}),Ge,l.jsxs("div",{className:"nc-set-row nc-fleet-backup-actions",children:[l.jsx("button",{className:"nc-btn ghost",disabled:xt||L,onClick:()=>{K(""),M(!0)},children:f("fleet-backup")}),l.jsx("small",{children:f("fleet-backup-help")})]}),l.jsxs("div",{className:"nc-fleet-section-head",children:[l.jsx("b",{children:f("fleet-cells")}),l.jsx("span",{className:"nc-fleet-head-actions",children:l.jsxs("button",{className:"nc-btn primary",disabled:xt||L||!a.engines.length,onClick:()=>{var oe;K(""),C({mode:"new",form:Ey((oe=a.engines[0])==null?void 0:oe.id)})},children:["+ ",f("add")]})})]}),a.cells.map(oe=>{const ie=Ve.has(oe.id),_e=oe.needsRepair===!0;return l.jsxs("div",{className:"nc-fleet-item",children:[l.jsxs("span",{children:[l.jsx("b",{children:oe.id}),oe.label?l.jsxs("small",{className:"nc-fleet-label",children:[" ",oe.label]}):null,l.jsxs("small",{children:[oe.engine," · ",_e?l.jsx("span",{className:"nc-fleet-tag nc-fleet-tag-warn",children:f("fleet-cwd-needs-repair")}):oe.cwd,ie?` · ${f("service-active")}`:` · ${f("cell-off")}`]})]}),l.jsxs("span",{children:[ie&&Ot.includes("down")&&l.jsx("button",{className:"nc-btn ghost",disabled:xt||L,onClick:()=>je(()=>lc(e,{cell:oe.id},fe)),children:f("stop")}),!ie&&Ot.includes("up")&&l.jsx("button",{className:"nc-btn primary",disabled:xt||L,onClick:()=>jt({cell:oe.id,id:oe.id,engine:oe.engine,model:oe.model,models:oe.models,permissionPolicies:oe.permissionPolicies,active:!1,boot:oe.boot}),children:f("start")}),ie&&Ot.includes("restart")&&l.jsx("button",{className:"nc-btn ghost",disabled:xt||L,onClick:()=>je(()=>fa(e,oe.id,fe)),children:f("restart")}),_e?l.jsx("button",{className:"nc-btn ghost",disabled:xt||L,onClick:()=>{K(""),j(oe)},children:f("fleet-cwd-repair")}):l.jsx("button",{className:"nc-btn ghost",disabled:xt||L,onClick:()=>{var be;K(""),C({mode:"edit",original:oe,form:{...oe,commands:{...oe.commands||{}},command:((be=oe.commands)==null?void 0:be[oe.engine])||""}})},children:f("edit")}),l.jsx("button",{className:"nc-btn danger",disabled:xt||L,onClick:()=>je(async()=>{window.confirm(f("fleet-remove-cell").replace("{id}",oe.id))&&await Uy(e,oe.id,!0,fe)}),children:"×"})]})]},oe.id)}),l.jsxs("div",{className:"nc-fleet-section-head",children:[l.jsx("b",{children:f("fleet-engines")}),l.jsxs("button",{className:"nc-btn primary",disabled:xt||L,onClick:()=>{K(""),b({mode:"new",form:SR()})},children:["+ ",f("add")]})]}),a.engines.map(oe=>{var _e,be;const ie=Nt(oe);return l.jsxs("div",{className:"nc-fleet-item",children:[l.jsxs("span",{children:[l.jsx("b",{children:oe.label}),l.jsx("small",{children:oe.managed?`${oe.id} · ${oe.managed.client} / ${oe.managed.provider} · ${(_e=oe.managedInfo)!=null&&_e.configured?f("fleet-ready"):((be=oe.managedInfo)==null?void 0:be.reason)||f("fleet-not-ready")}`:`${oe.id} · ${oe.command}`}),ie&&l.jsxs("small",{children:[ie.envKey," · ",f(`fleet-credential-source-${ie.source||"missing"}`)]})]}),l.jsxs("span",{children:[ie&&l.jsx("button",{className:"nc-btn ghost",disabled:xt||L,onClick:()=>{K(""),se({envKey:ie.envKey,value:""})},children:ie.configured?f("fleet-credential-change"):f("fleet-credential-set")}),(ie==null?void 0:ie.source)==="local"&&l.jsx("button",{className:"nc-btn danger",disabled:xt||L,onClick:()=>At(ie),children:f("fleet-credential-forget")}),l.jsx("button",{className:"nc-btn ghost",disabled:xt||L,onClick:()=>{K(""),b({mode:"edit",original:oe,form:kR(oe)})},children:f("edit")}),l.jsx("button",{className:"nc-btn danger",disabled:xt||L,onClick:()=>je(async()=>{window.confirm(f("fleet-remove-engine").replace("{id}",oe.id))&&await hx(e,oe.id,fe)}),children:"×"})]})]},oe.id)}),l.jsxs("div",{className:"nc-fleet-section-head",children:[l.jsx("b",{children:f("fleet-models")}),l.jsxs("button",{className:"nc-btn primary",disabled:xt||L,onClick:()=>{K(""),x({mode:"new",form:{id:"",engine:""}})},children:["+ ",f("add")]})]}),!(a.models||[]).length&&l.jsx("small",{className:"nc-set-hint",children:f("fleet-no-models")}),(a.models||[]).map(oe=>{const ie=`${oe.engine}::${oe.id}`,_e=E[ie],be=(a.engines||[]).some(ke=>ke.managed&&ke.managed.model===oe.id);return l.jsxs("div",{className:"nc-fleet-item",children:[l.jsxs("span",{children:[l.jsx("b",{children:oe.id}),l.jsxs("small",{children:[oe.engine,oe.contextWindow?` · ${oe.contextWindow}`:"",be?` · ${f("model-in-use")}`:""]}),_e&&l.jsxs("small",{className:`nc-model-test ${_e.outcome}`,children:[f(`model-test-${_e.outcome}`),_e.outcome==="ok"&&Number.isInteger(_e.latencyMs)?` · ${_e.latencyMs}ms`:""]})]}),l.jsxs("span",{children:[Ot.includes("model-test")&&l.jsx("button",{className:"nc-btn ghost",disabled:L||Ut,onClick:()=>je(()=>Ct(oe.engine,oe.id)),children:f("model-test")}),l.jsx("button",{className:"nc-btn danger",disabled:xt||L,onClick:()=>je(()=>px(e,oe.id,oe.engine,fe)),children:"×"})]})]},ie)})]}),S&&l.jsx(Hs,{onClose:()=>x(null),label:f("fleet-models"),error:G,children:l.jsx(jR,{state:S,setState:x,busy:L,onSave:dn,onTest:Ct,profiles:a.managedCatalog||[],canTest:Ot.includes("model-test")&&!Ut})}),y&&l.jsx(Hs,{onClose:()=>b(null),label:f("fleet-new-engine"),error:G,children:l.jsx(NR,{state:y,setState:b,busy:L,onSave:gn,catalog:a.managedCatalog||[]})}),N&&l.jsx(Hs,{onClose:()=>C(null),label:f("fleet-new-cell"),error:G,children:l.jsx(RR,{token:e,route:fe,targets:n,location:W,setLocation:X,state:N,setState:C,engines:a.engines,mcpServers:a.mcpServers||[],managedCatalog:a.managedCatalog||[],busy:L,onSave:Yt})}),T&&l.jsx(Hs,{onClose:()=>j(null),label:f("fleet-cwd-repair-title").replace("{id}",T.id),error:"",children:l.jsx(LR,{token:e,route:fe,cell:T,busy:L,onSaved:async()=>{j(null),Q(f("fleet-cwd-repaired")),await pe()},onClose:()=>j(null)})}),Y&&l.jsx("div",{className:"nc-set-note",children:Y}),G&&l.jsx("div",{className:"nc-err",children:G}),z&&l.jsx(Hs,{onClose:()=>M(!1),label:f("fleet-backup"),error:G,children:l.jsx(ER,{cells:a.cells,engines:a.engines,models:a.models||[],busy:L,canRestore:vt,onRestore:me,onClose:()=>M(!1)})}),U&&l.jsx(Hs,{onClose:()=>se(null),label:f("fleet-credential-title"),error:G,children:l.jsxs("div",{className:"nc-fleet-form nc-credential-form",children:[l.jsx("b",{children:f("fleet-credential-title")}),l.jsx("small",{children:f("fleet-credential-help")}),l.jsxs("label",{className:"nc-field",children:[U.envKey,l.jsx("input",{type:"password",autoComplete:"off",spellCheck:"false",autoCapitalize:"none",value:U.value,onChange:oe=>se({...U,value:oe.target.value})})]}),l.jsxs("div",{className:"nc-sheet-actions",children:[l.jsx("button",{className:"nc-btn ghost",onClick:()=>se(null),children:f("cancel")}),l.jsx("button",{className:"nc-btn primary",disabled:L||!U.value,onClick:Dt,children:f("save")})]})]})}),F&&l.jsx(Hs,{onClose:()=>A(null),label:f("import-as-cell"),error:G,children:l.jsx(jy,{token:e,route:F.route||fe,state:F,setState:A,busy:L,onSave:Qe})}),R&&l.jsx(uc,{cell:R,token:e,route:Array.isArray(R.route)?R.route:fe,onConfirm:async oe=>{try{await hn(oe)}finally{await pe()}},onClose:()=>O(null)})]}):l.jsxs("div",{className:"nc-set-tab",children:[ct,ee==="overview"?l.jsxs(l.Fragment,{children:[l.jsx("div",{className:"nc-set-info",children:f("fleet-overview-help")}),l.jsx(dh,{token:e,targets:n,readonly:t,onPower:jt,onImport:re})]}):l.jsxs(l.Fragment,{children:[Ge,l.jsxs("div",{className:"nc-set-info",children:[f(G?"fleet-editor-load-error":"fleet-editor-unavailable"),!G&&d.reason?` ${d.reason}`:""]})]}),G&&l.jsx("div",{className:"nc-err",children:G}),F&&l.jsx(Hs,{onClose:()=>A(null),label:f("import-as-cell"),error:G,children:l.jsx(jy,{token:e,route:F.route||fe,state:F,setState:A,busy:L,onSave:Qe})}),R&&l.jsx(uc,{cell:R,token:e,route:Array.isArray(R.route)?R.route:fe,onConfirm:async oe=>{try{await hn(oe)}finally{await pe()}},onClose:()=>O(null)})]}):l.jsxs("div",{className:"nc-set-tab",children:[ct,ee==="overview"?l.jsxs(l.Fragment,{children:[l.jsx("div",{className:"nc-set-info",children:f("fleet-overview-help")}),l.jsx(dh,{token:e,targets:n,readonly:t,onPower:jt,onImport:re})]}):l.jsxs(l.Fragment,{children:[Ge,l.jsx("div",{className:"nc-set-info",children:f("fleet-editor-loading")})]})]})}const Cp="nc_notification_speech_v1",Zl="nc-notification-speech",xf="nc-notification-speech-preview",MR=320,TR=2,DR=3e4,IR=1e4,OR=6e4,BR=64,Ry=Object.freeze({enabled:!1}),zR=Object.freeze({it:"it-IT",en:"en-US",es:"es-ES"}),$R=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"])}),Ep=new WeakSet;function Np(e){return{enabled:(e&&typeof e=="object"&&!Array.isArray(e)?e:{}).enabled===!0}}function aS(){try{return typeof localStorage<"u"?localStorage:null}catch{return null}}function Py(e=aS()){if(!e)return{...Ry};try{return Np(JSON.parse(e.getItem(Cp)||"null"))}catch{return{...Ry}}}function FR(e,t=aS()){const n=Np(e);if(t)try{t.setItem(Cp,JSON.stringify(n))}catch{}return n}function Eo(){try{return typeof window<"u"?window:null}catch{return null}}function Ra(e=Eo()){try{return!!(e&&e.speechSynthesis&&typeof e.speechSynthesis.speak=="function"&&typeof e.SpeechSynthesisUtterance=="function")}catch{return!1}}function lS(e=Eo()){return!!(e&&(typeof e=="object"||typeof e=="function")&&Ep.has(e))}function kf(e=Eo()){e&&(typeof e=="object"||typeof e=="function")&&Ep.delete(e)}function mo(e){const t=String(e||"").trim().toLowerCase().split("-")[0];return zR[t]||""}function Bc(e){return String(e||"").normalize("NFC").replace(/[\p{Cc}\p{Cf}]+/gu," ").replace(/\s+/g," ").trim()}function HR(e){const t=Bc(e).normalize("NFD").replace(new RegExp("\\p{M}+","gu"),"").toLowerCase(),n=new Set(t.match(new RegExp("\\p{L}+","gu"))||[]);if(n.size<4)return"";const s=Object.entries($R).map(([o,a])=>({lang:o,score:[...n].reduce((u,d)=>u+(a.has(d)?1:0),0)})).sort((o,a)=>a.score-o.score);return s[0].score>=3&&s[0].score-s[1].score>=2?s[0].lang:""}function UR(e,t){const n=mo(e&&e.lang);return n||mo(HR(e&&e.body))||mo(t)}function cS(e){try{const t=e&&e.speechSynthesis&&e.speechSynthesis.getVoices;return typeof t=="function"?Array.from(t.call(e.speechSynthesis)||[]).filter(Boolean):[]}catch{return[]}}function uS(e,t){const n=mo(t);if(!n)return null;const s=Array.from(e||[]).filter(d=>d&&typeof d.lang=="string"&&d.lang.trim()),o=s.filter(d=>d.lang.trim().toLowerCase()===n.toLowerCase()),a=n.slice(0,2).toLowerCase(),u=s.filter(d=>d.lang.trim().toLowerCase().split("-")[0]===a);return o.find(d=>d.default===!0)||o[0]||u.find(d=>d.default===!0)||u[0]||null}function Ly(e){return Bc(e).replace(/\bBearer\s+\S+/gi,"Bearer [redacted]").replace(/\b(?:sk|hf|zai|xox[baprs]|gh[pousr]|npm)[_-][A-Za-z0-9._-]{8,}\b/gi,"[redacted]").replace(/\b(?:token|password|secret|credential|api[_-]?key)\s*[=:]\s*(?:"[^"]*"|'[^']*'|\S+)/gi,"[redacted]").replace(/\b[A-Z][A-Z0-9_]{2,}\s*=\s*(?:"[^"]*"|'[^']*'|\S+)/g,"[redacted]").replace(/(?:\/home\/[^/\s]+|\/Users\/[^/\s]+|\/data\/(?:data|user\/\d+)\/[^/\s]+)(?:\/[^\s]*)?/g,"[private path]").replace(/\b[A-Za-z]:\\Users\\[^\\\s]+(?:\\[^\s]*)?/g,"[private path]")}function WR(e,t=MR){const n=Ly(e&&e.title),s=Ly(e&&e.body),o=[n,s&&s!==n?s:""].filter(Boolean).join(". "),a=Array.from(o);return a.length<=t?o:`${a.slice(0,Math.max(0,t-1)).join("").trimEnd()}…`}function KR(e){try{return!!(e&&e.visibilityState==="visible"&&typeof e.hasFocus=="function"&&e.hasFocus())}catch{return!1}}function dS(e=Eo()){if(!Ra(e))return!1;try{return e.speechSynthesis.cancel(),!0}catch{return!1}}function qR(e){try{e&&typeof e.dispatchEvent=="function"&&typeof e.Event=="function"&&e.dispatchEvent(new e.Event(xf))}catch{}}function VR(e,t,n=Eo(),s={}){var m;if(kf(n),!Ra(n))return Promise.resolve(!1);const o=Bc(e);if(!o||(m=s.signal)!=null&&m.aborted)return Promise.resolve(!1);const a=Number.isFinite(s.timeoutMs)&&s.timeoutMs>0?s.timeoutMs:IR,u=s.setTimer||((v,y)=>setTimeout(v,y)),d=s.clearTimer||(v=>clearTimeout(v)),p=s.signal;return qR(n),new Promise(v=>{let y=!1,b=!1,S=null,x=null;const E=w=>{if(!y){if(y=!0,p&&x&&p.removeEventListener("abort",x),S!==null&&d(S),w!==!0)try{n.speechSynthesis.cancel()}catch{}else Ep.add(n);v(w)}};x=()=>E("no-activation"),p&&p.addEventListener("abort",x,{once:!0});try{n.speechSynthesis.cancel();const w=new n.SpeechSynthesisUtterance(o);w.lang=mo(t);const N=uS(cS(n),w.lang);N&&(w.voice=N),w.onstart=()=>{b=!0},w.onend=()=>E(b?!0:"no-activation"),w.onerror=()=>E("voice-error"),S=u(()=>E("timeout"),a),n.speechSynthesis.speak(w)}catch{E("no-activation")}})}function YR(e={}){const t=e.scope||Eo(),n=e.document||t&&t.document,s=Number.isInteger(e.maxPending)&&e.maxPending>=0?e.maxPending:TR,o=Number.isFinite(e.watchdogMs)&&e.watchdogMs>0?e.watchdogMs:DR,a=Number.isFinite(e.dedupWindowMs)&&e.dedupWindowMs>0?e.dedupWindowMs:OR,u=Number.isInteger(e.maxDedup)&&e.maxDedup>0?e.maxDedup:BR,d=e.now||Date.now,p=e.setTimer||((H,$)=>setTimeout(H,$)),m=e.clearTimer||(H=>clearTimeout(H)),v=e.isPrimed||(()=>lS(t)),y=t&&t.speechSynthesis;let b=null,S=null,x=[],E=[],w=()=>{};const N=new Map,C=()=>{E=cS(t)};if(C(),y&&typeof y.addEventListener=="function")y.addEventListener("voiceschanged",C),w=()=>y.removeEventListener("voiceschanged",C);else if(y&&"onvoiceschanged"in y){const H=y.onvoiceschanged,$=(...R)=>{C(),typeof H=="function"&&H.apply(y,R)};y.onvoiceschanged=$,w=()=>{y.onvoiceschanged===$&&(y.onvoiceschanged=H)}}const L=H=>{if(H&&typeof H.id=="string"&&H.id)return`id:${H.id}`;const $=Number(H&&H.ts),R=Bc(H&&H.title);return Number.isFinite($)&&R?`frame:${$}:${R}`:""},I=H=>{if(!H)return!0;const $=d();for(const[R,O]of N)$-O>=a&&N.delete(R);if(N.has(H))return!1;for(N.set(H,$);N.size>u;)N.delete(N.keys().next().value);return!0},G=()=>{S!==null&&m(S),S=null},K=()=>{G(),b&&(b.onend=null,b.onerror=null,b=null),dS(t)},Y=H=>{if(!Ra(t))return x=[],"unsupported";let $;try{$=new t.SpeechSynthesisUtterance(H.text),$.lang=mo(H.lang);const O=uS(E,$.lang);O&&($.voice=O)}catch{return x=[],"error"}b=$;const R=()=>{if(b!==$)return;G(),b=null,$.onend=null,$.onerror=null;const O=x.shift();O&&Y(O)};$.onend=R,$.onerror=R;try{return S=p(()=>{if(b!==$)return;b=null,$.onend=null,$.onerror=null;try{t.speechSynthesis.cancel()}catch{}G();const O=x.shift();O&&Y(O)},o),t.speechSynthesis.speak($),"speaking"}catch{return R(),"error"}},Q=(H,$)=>{if(!Ra(t))return"unsupported";const R=WR(H);if(!R)return"empty";if(!I(L(H)))return"duplicate";if(!KR(n))return"inactive";if(!v())return"unprimed";const O={text:R,lang:$};return H&&H.urgency==="high"?(x=[],K(),Y(O)):b?s===0?"dropped":(x.length>=s&&x.shift(),x.push(O),"queued"):Y(O)},W=()=>{x=[],K()};return{enqueue:Q,stop:W,dispose:()=>{W(),w(),w=()=>{}}}}function hS(){const[e,t]=k.useState(Py);k.useEffect(()=>{const s=o=>{if((o==null?void 0:o.type)==="storage"&&o.key!==Cp&&o.key!==null)return;const a=(o==null?void 0:o.type)===Zl?Np(o.detail):Py();t(a)};return window.addEventListener(Zl,s),window.addEventListener("storage",s),()=>{window.removeEventListener(Zl,s),window.removeEventListener("storage",s)}},[]);const n=k.useCallback(s=>{const o=FR({enabled:s===!0});return t(o),window.dispatchEvent(new CustomEvent(Zl,{detail:o})),o.enabled},[]);return[e.enabled,n]}function GR({text:e}){const[t,n]=k.useState(!1),s=async()=>{try{await navigator.clipboard.writeText(e),n(!0),setTimeout(()=>n(!1),1500)}catch{}};return l.jsxs("div",{className:"nc-set-copyline",children:[l.jsx("code",{children:e}),l.jsxs("button",{type:"button",className:"nc-btn ghost",onClick:s,children:[l.jsx(lt,{name:"copy",size:14})," ",f(t?"copied":"copy")]})]})}function XR({value:e}){const[t,n]=k.useState("");return k.useEffect(()=>{let s=!0;return Cj.toDataURL(e,{margin:1,width:220}).then(o=>{s&&n(o)}).catch(()=>{}),()=>{s=!1}},[e]),t?l.jsx("img",{src:t,width:"220",height:"220",alt:"NexusCrew pairing QR"}):null}function QR({token:e,nodes:t,roster:n,settings:s,readonly:o,refresh:a,refreshAliases:u,vlUnavailable:d=[]}){const[p,m]=k.useState(null),[v,y]=k.useState(null),[b,S]=k.useState(null),[x,E]=k.useState({ssh:"",sshPort:"",name:""}),[w,N]=k.useState(""),[C,L]=k.useState(""),[I,G]=k.useState(!1),[K,Y]=k.useState(null),Q=Date.now(),W=s&&s.deviceName||"",X=(t||[]).filter(j=>j&&j.direction==="outbound"&&j.name&&j.ssh),H=X.find(j=>j.name===w)||X[0]||null,$=H?Ch(H.tunnel,Q):null,R=H!=null&&H.shared?$!=null&&$.up?"share-local-active":"share-local-pending":$!=null&&$.up?"share-local-private":"share-local-private-down",O=[{key:"peer-group-hubs",rows:(t||[]).filter(j=>j.kind!=="transitive"&&j.kind!=="vl"&&j.relation!=="client")},{key:"peer-group-clients",rows:(t||[]).filter(j=>j.kind!=="transitive"&&j.kind!=="vl"&&j.relation==="client")},{key:"peer-group-routed",rows:(t||[]).filter(j=>j.kind==="transitive")},{key:"peer-group-vl",rows:(t||[]).filter(j=>j.kind==="vl")}],F=K&&(t||[]).find(j=>`${j.kind||"direct"}:${j.nodeId||j.name}`===K)||null,A=async j=>{if(H){m(null),y(`${H.name}:share`);try{const z=await Rx(e,H.name,j);await a(),z&&z.reversePoolPending===!0&&m(`${H.name}: ${f("share-reverse-pool-pending")}`)}catch(z){const M=z!=null&&z.data&&z.data.shared===!1?z.data:null;if(M)try{await a()}catch{}const D=z!=null&&z.data&&typeof z.data.hint=="string"?z.data.hint:"",B=(M==null?void 0:M.revoked)===!0&&(M==null?void 0:M.localReconcilePending)===!0?f("share-off-local-reconcile-pending"):(M==null?void 0:M.revoked)===!1&&(M==null?void 0:M.reconcilePending)===!0?f("share-off-hub-reconcile-pending"):"",U=z!=null&&z.data&&z.data.reversePoolPending===!0?f("share-reverse-pool-pending"):"",se=z!=null&&z.data&&typeof z.data.code=="string"?z.data.code:"",ee=z!=null&&z.data&&typeof z.data.detail=="string"?z.data.detail.trim():"",de=ee&&ee!==String(z.message||"")?ee:"";m(`${H.name}: ${String(z.message||z)}${se?` [${se}]`:""}${de?` — ${de}`:""}${D?` — ${D}`:""}${B?` — ${B}`:""}${U?` — ${U}`:""}`)}y(null)}},T=async()=>{m(null);const j=Vs(x.name||C||W||"NexusCrew"),z=Fk({name:j,ssh:x.ssh,sshPort:x.sshPort});if(!z.ok){m(f(z.error));return}y("invite");try{S(await Cx(e,{...C||W?{label:C||W}:{},name:j,ssh:z.value.ssh,...z.value.sshPort?{sshPort:z.value.sshPort}:{}}))}catch(M){m(String(M.message||M))}y(null)};return l.jsxs("div",{className:"nc-set-tab",children:[l.jsx("div",{className:"nc-sheet-label",children:f("peer-inventory-title")}),(t||[]).length===0&&l.jsx("div",{className:"nc-empty",children:f("no-nodes")}),O.map(j=>j.rows.length>0&&l.jsxs("div",{className:"nc-peer-group",children:[l.jsxs("div",{className:"nc-peer-group-title",children:[f(j.key)," ",l.jsx("span",{children:j.rows.length})]}),j.rows.map(z=>{const M=Oj(z);if(!M)return null;const D=`${z.kind||"direct"}:${z.nodeId||z.name}`,B=M.routed?{up:M.reach.up,since:null}:Ch(z.tunnel,Q);return l.jsxs("button",{type:"button",className:`nc-set-node nc-node-row${M.routed?" routed":""}`,"aria-label":`${M.title} — ${f("node-detail-open")}`,onClick:()=>Y(D),children:[l.jsx("span",{className:`nc-dot ${M.reach.up?"on":""}`}),l.jsxs("span",{className:"nc-node-row-text",children:[l.jsx("b",{children:M.title}),l.jsxs("small",{children:[M.routed?M.routeLabel:`${M.subtitle} · ${f(M.exposure.shortKey)}`,!M.routed&&M.exposure.shortKey==="visibility-selected"?` (${M.exposure.count})`:""]})]}),l.jsxs("span",{className:`nc-set-tunnel${M.reach.up?" up":""}`,children:[f(M.reach.key),B.since?` · ${B.since}`:""]}),l.jsx("span",{className:"nc-node-row-more",children:l.jsx(lt,{name:"chevronDown",size:14})})]},D)})]},j.key)),d.length>0&&l.jsxs("div",{className:"nc-err",children:[f("vl-owners-unavailable"),": ",d.map(j=>j.label||j.route.join("/")).join(", ")]}),F&&l.jsx(Jj,{node:F,nodes:t||[],token:e,readonly:o,refresh:a,onClose:()=>Y(null)}),(n||[]).some(j=>!j.direct&&j.instanceId)&&l.jsxs("div",{className:"nc-set-form",children:[l.jsx("div",{className:"nc-sheet-label",children:f("routed-node-aliases")}),l.jsx("small",{className:"nc-set-hint",children:f("routed-node-aliases-help")}),(n||[]).filter(j=>!j.direct&&j.instanceId).map(j=>l.jsxs("div",{className:"nc-set-node",children:[l.jsxs("div",{className:"nc-set-node-head",children:[l.jsx("span",{className:`nc-dot ${j.status==="up"?"on":""}`}),l.jsx("b",{children:j.label||j.name}),l.jsx("small",{children:(j.route||[]).join(" › ")})]}),l.jsxs("div",{className:"nc-set-node-actions",children:[l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:o||!!v,onClick:async()=>{const z=window.prompt(f("node-local-alias"),j.alias||"");if(z!=null){if(z.trim()&&!_o(z.normalize("NFC"))){m(f("err-label"));return}y(`${j.instanceId}:alias`),m(null);try{z.trim()?await Nx(e,j.instanceId,z):await nv(e,j.instanceId),u()}catch(M){m(String(M.message||M))}y(null)}},children:f("alias-on-device")}),j.alias&&l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:o||!!v,onClick:async()=>{y(`${j.instanceId}:alias-reset`),m(null);try{await nv(e,j.instanceId),u()}catch(z){m(String(z.message||z))}y(null)},children:f("reset-alias")})]})]},j.instanceId))]}),H&&l.jsxs("div",{className:"nc-set-form nc-local-share",children:[l.jsx("div",{className:"nc-sheet-label",children:f("share-local-heading")}),X.length>1&&l.jsxs("label",{className:"nc-field",children:[f("share-local-hub"),l.jsx("select",{value:H.name,disabled:o||!!v,onChange:j=>N(j.target.value),children:X.map(j=>l.jsx("option",{value:j.name,children:j.label||j.name},j.name))})]}),l.jsxs("label",{className:"nc-check nc-node-share",children:[l.jsx("input",{type:"checkbox",checked:H.shared===!0,disabled:o||!!v,onChange:j=>A(j.target.checked)}),l.jsxs("span",{children:[l.jsx("b",{children:f("share-local-through").replace("{device}",W||f("local")).replace("{hub}",H.label||H.name)}),l.jsx("small",{children:f(H.shared?"share-node-on-desc":"share-node-off-desc")})]})]}),l.jsx("div",{className:`nc-set-test${H.shared&&($!=null&&$.up)?" ok":$!=null&&$.up?"":" ko"}`,children:f(R)}),!($!=null&&$.up)&&l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:o||!!v,onClick:()=>A(H.shared===!0),children:f("share-local-reconnect")})]}),l.jsx(Gw,{token:e,deviceDefault:W,localNodeId:s&&s.nodeId||"",localNameDefault:s&&s.localName||"",readonly:o,onSuccess:a}),l.jsxs("div",{className:"nc-set-form",children:[l.jsx("div",{className:"nc-sheet-label",children:f("invite-node")}),l.jsx("small",{className:"nc-set-hint",children:f("invite-v2-hint")}),l.jsxs("div",{className:"nc-set-info nc-invite-endpoint",children:[f("invite-target-local"),": ",l.jsx("b",{children:W||f("invite-target-this")})]}),l.jsxs("label",{className:"nc-field",children:[f("invite-endpoint-label"),l.jsx("input",{placeholder:"user@host",value:x.ssh,disabled:o,onChange:j=>E({...x,ssh:j.target.value})}),l.jsx("small",{className:"nc-set-hint",children:f("invite-endpoint-needed")})]}),X.length>0&&l.jsx("small",{className:"nc-set-hint nc-invite-hub-hint",children:f("invite-hub-only")}),I&&l.jsxs("div",{className:"nc-invite-advanced",children:[l.jsxs("label",{className:"nc-field",children:[f("node-ssh-port-label"),l.jsx("input",{inputMode:"numeric",placeholder:"22",value:x.sshPort,disabled:o,onChange:j=>E({...x,sshPort:j.target.value.replace(/[^0-9]/g,"").slice(0,5)})})]}),l.jsxs("label",{className:"nc-field",children:[f("device-name-label"),l.jsx("input",{placeholder:W||"NexusCrew",value:C,disabled:o,onChange:j=>L(j.target.value)}),l.jsx("small",{className:"nc-set-hint",children:f("device-name-hint")})]}),l.jsxs("label",{className:"nc-field",children:[f("node-name-label"),l.jsx("input",{placeholder:Vs(C||W||f("node-name-ph")),value:x.name,disabled:o,onChange:j=>E({...x,name:j.target.value?Vs(j.target.value):""})})]})]}),l.jsxs("div",{className:"nc-set-row nc-invite-actions",children:[l.jsx("button",{type:"button",className:"nc-btn primary",disabled:o||!!v||!x.ssh.trim(),onClick:T,children:f("create-pairing-link")}),l.jsxs("button",{type:"button",className:"nc-btn ghost",disabled:!!v,onClick:()=>G(j=>!j),children:[I?"▾":"▸"," ",f("pair-advanced")]})]}),b&&l.jsxs(l.Fragment,{children:[l.jsx(XR,{value:b.pairingUrl}),l.jsx(GR,{text:b.pairingUrl}),l.jsx("div",{className:"nc-set-info",children:f("invite-next-steps")})]})]}),p&&l.jsx("div",{className:"nc-err",children:p})]})}function JR({token:e,readonly:t}){const[n,s]=k.useState("idle"),[o,a]=k.useState(!1),[u,d]=k.useState(null);k.useEffect(()=>{let m=!1;return eR().then(v=>{m||s(v)}),()=>{m=!0}},[]);const p=async()=>{d(null),a(!0);try{n==="subscribed"?(await nR(e),s("idle")):(await tR(e),s("subscribed"))}catch(m){const v=String(m.message||m);v==="push-denied"?(s("denied"),d(f("push-denied"))):v==="push-unsupported"?(s("unsupported"),d(f("push-unsupported"))):d(v)}a(!1)};return n==="unsupported"?l.jsx("div",{className:"nc-set-info",children:f("push-unsupported")}):l.jsxs(l.Fragment,{children:[l.jsxs("div",{className:"nc-set-row",children:[l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:t||o||n==="denied",title:t?f("settings-readonly"):"",onClick:p,children:f(n==="subscribed"?"push-disable":"push-enable")}),l.jsx("span",{className:"nc-set-info",children:f(n==="subscribed"?"push-on":n==="denied"?"push-denied":"push-off")})]}),u&&l.jsx("div",{className:"nc-err",children:u})]})}function ZR(){const[e,t]=hS(),[n,s]=k.useState(""),[o,a]=k.useState(""),[u,d]=k.useState(!1),[p,m]=k.useState(lS),v=k.useRef(0),y=k.useRef(!1),b=k.useRef(null),S=Ra();k.useEffect(()=>()=>{var w;v.current+=1,y.current&&((w=b.current)==null||w.abort(),b.current=null,y.current=!1,kf())},[]);const x=async()=>{const w=v.current+=1,N=typeof AbortController=="function"?new AbortController:null;s(""),a(""),d(!0),m(!1),y.current=!0,b.current=N;const C=await VR(f("notification-speech-preview"),cc(),void 0,N?{signal:N.signal}:{});return w!==v.current||(b.current=null,y.current=!1,d(!1),m(C===!0),C===!0?a(f("notification-speech-preview-ok")):s(f(C==="voice-error"?"notification-speech-preview-voice-error":C==="timeout"?"notification-speech-preview-timeout":"notification-speech-preview-failed"))),C},E=w=>{var N;if(t(w),s(""),a(""),w)x();else{v.current+=1;const C=y.current;(N=b.current)==null||N.abort(),b.current=null,y.current=!1,d(!1),m(!1),kf(),C||dS()}};return l.jsxs("div",{className:"nc-set-form",children:[l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox","aria-label":f("notification-speech-enable"),checked:e,disabled:!S,onChange:w=>E(w.target.checked)}),l.jsxs("span",{children:[l.jsx("b",{children:f("notification-speech-enable")}),l.jsx("small",{children:f("notification-speech-help")})]})]}),S?l.jsx("div",{className:"nc-set-row",children:l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:!e||u,onClick:()=>{x()},children:f(u?"notification-speech-testing":"notification-speech-test")})}):l.jsx("div",{className:"nc-set-info",children:f("notification-speech-unsupported")}),e&&!p&&!u&&!n&&l.jsx("div",{className:"nc-set-info",children:f("notification-speech-needs-test")}),o&&l.jsx("div",{className:"nc-set-info",role:"status",children:o}),n&&l.jsx("div",{className:"nc-err",children:n})]})}function eP({token:e,readonly:t,nodes:n=[],settings:s=null}){const[o,a]=k.useState(null),[u,d]=k.useState([]),[p,m]=k.useState({name:"",mode:"primary-failover",targets:[]}),[v,y]=k.useState(null),[b,S]=k.useState(!1),[x,E]=k.useState(null),[w,N]=k.useState(""),C=k.useCallback(async()=>{try{const[T,j]=await Promise.all([Lx(e),Dx(e)]);a(T),d(Array.isArray(j==null?void 0:j.groups)?j.groups:[]),N("")}catch(T){N(String(T.message||T))}},[e]);k.useEffect(()=>{C()},[C]);const L=async T=>{S(!0),E(null),N("");try{a(await Ax(e,T))}catch(j){N(String(j.message||j))}S(!1)},I=async()=>{S(!0),E(null),N("");try{E({kind:"test",...await Mx(e)})}catch(T){N(String(T.message||T))}S(!1)},G=async()=>{S(!0),E(null),N("");try{E({kind:"stop",...await Tx(e)})}catch(T){N(String(T.message||T))}S(!1)},K=[],Y=new Set,Q=(T,j)=>{const z=typeof T=="string"?T.toLowerCase():"";!/^[a-f0-9]{32}$/.test(z)||Y.has(z)||(Y.add(z),K.push({id:z,label:j||z}))};Q(s==null?void 0:s.nodeId,f("audio-group-local"));for(const T of n||[])Q((T==null?void 0:T.nodeId)||(T==null?void 0:T.instanceId),(T==null?void 0:T.label)||(T==null?void 0:T.name)||(T==null?void 0:T.nodeId));for(const T of p.targets)Q(T,`${T} (${f("audio-group-unavailable-target")})`);const W=(T=null)=>{N(""),T?(y(T.name),m({name:T.name,mode:T.mode,targets:[...T.targets||[]]})):(y(null),m({name:"",mode:"primary-failover",targets:[]}))},X=(T,j)=>m(z=>({...z,targets:j?[...new Set([...z.targets,T])]:z.targets.filter(M=>M!==T)})),H=async()=>{const T=p.name.trim().toLowerCase();if(!/^[a-z0-9][a-z0-9-]{0,31}$/.test(T)||p.targets.length<1){N(f("audio-group-invalid"));return}S(!0),N("");try{const j=await Ix(e,T,{targets:p.targets,mode:p.mode}),z=j==null?void 0:j.group;if(!z||!z.name)throw new Error(f("audio-group-save-failed"));d(M=>[...M.filter(D=>D.name!==z.name),z].sort((D,B)=>D.name.localeCompare(B.name))),W(null)}catch(j){N(String(j.message||j))}S(!1)},$=async T=>{S(!0),N("");try{await Ox(e,T),d(j=>j.filter(z=>z.name!==T)),v===T&&W(null)}catch(j){N(String(j.message||j))}S(!1)},R=(o==null?void 0:o.installed)===!0,O=(o==null?void 0:o.liveness)==="ready",F=(o==null?void 0:o.consent)===!0&&R&&O,A=x?x.kind==="stop"?f(x.stopped?"audio-stop-stopped":"audio-stop-idle"):x.status==="accepted"||x.status==="spoken"?f("audio-test-accepted"):x.status==="unknown"?f("audio-test-unknown"):`${f("audio-test-refused")}${x.reason?` (${x.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:f("audio-title")}),l.jsx("br",{}),f("audio-help")]}),o?l.jsxs(l.Fragment,{children:[l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox","aria-label":f("audio-consent"),checked:o.consent===!0,disabled:t||b,onChange:T=>{L(T.target.checked)}}),l.jsxs("span",{children:[l.jsx("b",{children:f("audio-consent")}),l.jsx("small",{children:f("audio-consent-help")})]})]}),l.jsxs("div",{className:"nc-set-form",children:[l.jsx("div",{className:"nc-sheet-label",children:f("audio-capability")}),l.jsxs("div",{className:"nc-set-info",children:[f("audio-adapter"),": ",o.adapter||f("audio-adapter-none"),l.jsx("br",{}),f("audio-installed"),": ",f(R?"audio-installed-yes":"audio-installed-no"),l.jsx("br",{}),f("audio-liveness"),": ",f(O?"audio-liveness-ready":"audio-liveness-unavailable"),Array.isArray(o.languages)&&o.languages.length>0&&l.jsxs(l.Fragment,{children:[l.jsx("br",{}),f("audio-languages"),": ",o.languages.join(", ")]})]}),o.limits&&l.jsxs("small",{className:"nc-set-hint",children:[f("audio-limits"),": ",o.limits]})]}),!o.consent&&l.jsx("div",{className:"nc-set-info",children:f("audio-test-needs-consent")}),!R&&l.jsx("div",{className:"nc-set-info",children:f("audio-unavailable")}),l.jsxs("div",{className:"nc-set-row",children:[l.jsx("button",{type:"button",className:"nc-btn primary",disabled:t||b||!F,title:t?f("settings-readonly"):"",onClick:()=>{I()},children:f(b?"audio-testing":"audio-test")}),l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:b,onClick:()=>{G()},children:f(b?"audio-stopping":"audio-stop")}),l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:b,onClick:()=>{C()},children:f("refresh")})]}),l.jsxs("div",{className:"nc-set-form",children:[l.jsx("div",{className:"nc-sheet-label",children:f("audio-groups-title")}),l.jsx("small",{className:"nc-set-hint",children:f("audio-groups-help")}),u.length===0&&l.jsx("div",{className:"nc-set-info",children:f("audio-groups-empty")}),u.map(T=>{var j;return l.jsxs("div",{className:"nc-set-row",children:[l.jsxs("span",{children:[l.jsx("b",{children:T.name})," ",l.jsxs("small",{children:["· ",T.mode==="fanout"?f("audio-group-fanout"):f("audio-group-primary")," · ",((j=T.targets)==null?void 0:j.length)||0]})]}),l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:t||b,onClick:()=>W(T),children:f("audio-group-edit")}),l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:t||b,onClick:()=>{$(T.name)},children:f("audio-group-delete")})]},T.name)}),l.jsx("div",{className:"nc-set-row",children:l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:t||b,onClick:()=>W(null),children:f("audio-group-new")})}),l.jsxs("label",{className:"nc-field",children:[f("audio-group-name"),l.jsx("input",{"aria-label":f("audio-group-name"),value:p.name,maxLength:"32",disabled:t||b,onChange:T=>m(j=>({...j,name:T.target.value}))})]}),l.jsxs("label",{className:"nc-field",children:[f("audio-group-mode"),l.jsxs("select",{"aria-label":f("audio-group-mode"),value:p.mode,disabled:t||b,onChange:T=>m(j=>({...j,mode:T.target.value})),children:[l.jsx("option",{value:"primary-failover",children:f("audio-group-primary")}),l.jsx("option",{value:"fanout",children:f("audio-group-fanout")})]})]}),l.jsx("div",{className:"nc-set-info",children:f("audio-group-targets")}),K.length===0?l.jsx("small",{className:"nc-set-hint",children:f("audio-group-no-targets")}):K.map(T=>l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox",checked:p.targets.includes(T.id),disabled:t||b,onChange:j=>X(T.id,j.target.checked)}),l.jsxs("span",{children:[T.label,l.jsx("small",{children:T.id})]})]},T.id)),l.jsxs("div",{className:"nc-set-row",children:[l.jsx("button",{type:"button",className:"nc-btn primary",disabled:t||b,onClick:()=>{H()},children:f("audio-group-save")}),v&&l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:b,onClick:()=>W(null),children:f("audio-group-cancel")})]})]})]}):l.jsx("div",{className:"nc-set-info",children:f("audio-loading")}),A&&l.jsx("div",{className:"nc-set-note",role:"status",children:A}),w&&l.jsx("div",{className:"nc-err",children:w})]})}function tP(){const[e,t]=up();return l.jsxs("div",{className:"nc-set-tab nc-input-settings",children:[l.jsx("div",{className:"nc-set-info",children:f("input-settings-local")}),l.jsxs("div",{className:"nc-set-form",children:[l.jsxs("label",{className:"nc-field",children:[f("terminal-keyboard-gesture"),l.jsx("select",{"aria-label":f("terminal-keyboard-gesture"),value:e.terminalKeyboardGesture,onChange:n=>t({terminalKeyboardGesture:n.target.value}),children:Ew.map(n=>l.jsx("option",{value:n,children:f(`terminal-keyboard-${n}`)},n))}),l.jsx("small",{children:f("terminal-keyboard-gesture-help")})]}),l.jsxs("label",{className:"nc-field",children:[f("keybar-layout"),l.jsx("select",{"aria-label":f("keybar-layout"),value:e.keybarLayout,onChange:n=>t({keybarLayout:n.target.value}),children:Nw.map(n=>l.jsx("option",{value:n,children:f(`keybar-layout-${n}`)},n))}),l.jsx("small",{children:f("keybar-layout-help")})]})]}),l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox",checked:e.keybarKeepsKeyboardClosed,onChange:n=>t({keybarKeepsKeyboardClosed:n.target.checked})}),l.jsxs("span",{children:[l.jsx("b",{children:f("keybar-ime-lock")}),l.jsx("small",{children:f("keybar-ime-lock-help")})]})]}),l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox",checked:e.voiceKeepsKeyboardClosed,onChange:n=>t({voiceKeepsKeyboardClosed:n.target.checked})}),l.jsxs("span",{children:[l.jsx("b",{children:f("voice-ime-lock")}),l.jsx("small",{children:f("voice-ime-lock-help")})]})]}),l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox",checked:e.showKeybarEnter,onChange:n=>t({showKeybarEnter:n.target.checked})}),l.jsxs("span",{children:[l.jsx("b",{children:f("keybar-enter-show")}),l.jsx("small",{children:f("keybar-enter-show-help")})]})]}),l.jsx("div",{className:"nc-set-row",children:l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:()=>t(Ws),children:f("input-settings-reset")})})]})}function nP({token:e,roster:t=[],readonly:n}){const s=[{key:"local",route:[],label:f("diagnostics-local"),status:"up"},...t.filter(F=>Array.isArray(F.route)&&F.route.length).map(F=>({key:F.route.join("/"),route:F.route,label:F.label||F.name,status:F.status}))],[o,a]=k.useState("local"),u=s.find(F=>F.key===o)||s[0],[d,p]=k.useState(null),[m,v]=k.useState([]),[y,b]=k.useState(""),[S,x]=k.useState(!1),[E,w]=k.useState(!0),[N,C]=k.useState(900),[L,I]=k.useState("all"),[G,K]=k.useState(""),Y=k.useRef(0),Q=k.useRef(null),W=k.useCallback(async()=>{try{const F=await Fx(e,u.route);if(p(F),b(""),!S){const A=await Hx(e,{after:Y.current,limit:200},u.route);Array.isArray(A.records)&&A.records.length&&(Y.current=A.cursor,v(T=>[...T,...A.records].slice(-500)))}}catch(F){b(F&&F.status===404?f("diagnostics-unsupported"):String(F.message||F))}},[e,u.key,S]);k.useEffect(()=>{Y.current=0,v([]),p(null),b("")},[u.key]),k.useEffect(()=>{let F=null,A=!0;const T=()=>{!A||document.visibilityState==="hidden"||W()},j=()=>{F&&clearInterval(F),F=document.visibilityState==="hidden"?null:setInterval(T,2e3),document.visibilityState!=="hidden"&&T()};return document.addEventListener("visibilitychange",j),j(),()=>{A=!1,F&&clearInterval(F),document.removeEventListener("visibilitychange",j)}},[W]),k.useEffect(()=>{E&&Q.current&&(Q.current.scrollTop=Q.current.scrollHeight)},[m,E]);const X=m.filter(F=>(L==="all"||F.level===L)&&(!G||String(F.component||"").toLowerCase().includes(G.toLowerCase()))),H=X.map(F=>`${F.ts} ${F.level.toUpperCase()} ${F.component} ${F.code} ${F.message}${Object.keys(F.meta||{}).length?` ${JSON.stringify(F.meta)}`:""}`).join(`
|
|
92
92
|
`),$=async F=>{b("");try{const A=await F();p(A),await W()}catch(A){b(String(A.message||A))}},R=async()=>{try{await navigator.clipboard.writeText(H)}catch{b(f("copy-manual"))}},O=()=>{try{const F=new Blob([`${JSON.stringify(X,null,2)}
|
|
93
|
-
`],{type:"application/json"}),A=URL.createObjectURL(F),T=document.createElement("a");T.href=A,T.download="nexuscrew-diagnostics.json",T.click(),URL.revokeObjectURL(A)}catch{b(f("diagnostics-export-failed"))}};return l.jsxs("div",{className:"nc-set-tab nc-diagnostics",children:[l.jsxs("label",{className:"nc-field",children:[f("diagnostics-target"),l.jsx("select",{value:u.key,onChange:F=>a(F.target.value),children:s.map(F=>l.jsxs("option",{value:F.key,children:[F.label,F.status!=="up"?` · ${F.status}`:""]},F.key))})]}),l.jsxs("div",{className:"nc-set-form nc-diag-controls",children:[l.jsx("div",{className:"nc-sheet-label",children:f("diagnostics-verbose")}),l.jsxs("div",{className:"nc-set-row",children:[l.jsx("select",{"aria-label":f("diagnostics-duration"),value:N,onChange:F=>C(Number(F.target.value)),disabled:n,children:[300,900,1800,3600].map(F=>l.jsxs("option",{value:F,children:[F/60," min"]},F))}),l.jsx("button",{type:"button",className:"nc-btn primary",disabled:n||(d==null?void 0:d.verbose)===!0,onClick:()=>$(()=>sv(e,!0,N,u.route)),children:f("enable")}),l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:n||(d==null?void 0:d.verbose)!==!0,onClick:()=>$(()=>sv(e,!1,N,u.route)),children:f("stop")})]}),l.jsx("small",{className:"nc-set-hint",children:d!=null&&d.verbose?f("diagnostics-expires").replace("{time}",new Date(d.expiresAt).toLocaleTimeString()):f("diagnostics-off")})]}),l.jsxs("div",{className:"nc-diag-filters",children:[l.jsxs("select",{"aria-label":f("diagnostics-level"),value:L,onChange:F=>I(F.target.value),children:[l.jsx("option",{value:"all",children:f("diagnostics-all-levels")}),["debug","info","warn","error"].map(F=>l.jsx("option",{value:F,children:F},F))]}),l.jsx("input",{"aria-label":f("diagnostics-component"),placeholder:f("diagnostics-component"),value:G,onChange:F=>K(F.target.value)})]}),l.jsxs("div",{className:"nc-set-row",children:[l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox",checked:S,onChange:F=>x(F.target.checked)})," ",f("diagnostics-pause")]}),l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox",checked:E,onChange:F=>w(F.target.checked)})," ",f("diagnostics-autoscroll")]})]}),l.jsx("pre",{ref:Q,className:"nc-diag-log","aria-label":f("diagnostics-log"),children:H||f("diagnostics-empty")}),l.jsxs("div",{className:"nc-set-row",children:[l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:R,children:f("copy")}),l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:O,children:f("diagnostics-export")}),l.jsx("button",{type:"button",className:"nc-btn danger",disabled:n,onClick:()=>{window.confirm(f("diagnostics-clear-confirm"))&&$(async()=>{const F=await Ux(e,u.route);return Y.current=0,v([]),F})},children:f("diagnostics-clear")})]}),y&&l.jsx("div",{className:"nc-err",children:y})]})}function iP({token:e,settings:t,readonly:n,refresh:s,roster:o,section:a,setSection:u}){const[d,p]=k.useState(null),[m,v]=k.useState(null),[y,b]=k.useState(!1),[S,x]=k.useState(!1),[E,w]=k.useState(null),[N,C]=k.useState(!0),[L,I]=k.useState(!1);k.useEffect(()=>{w(t&&t.update||null),C(!t||t.autoUpdate!==!1),I(!!(t&&t.alternateScreen))},[t]);const G=async()=>{p(null),v(null),x(!0);try{const R=await xx(e);v(R.note||"ok"),b(!1)}catch(R){p(String(R.message||R))}x(!1)},K=async()=>{p(null),v(null),x(!0);try{const R=await Bx(e);v(`${R.note||"ok"}${R.target?` (${R.target})`:""}`)}catch(R){p(String(R.message||R))}x(!1)},Y=async R=>{p(null),v(null),x(!0);try{await gh(e,{autoUpdate:R}),C(R),s&&await s()}catch(O){p(String(O.message||O))}x(!1)},Q=async R=>{p(null),v(null),x(!0);try{await gh(e,{alternateScreen:R}),I(R),s&&await s()}catch(O){p(String(O.message||O))}x(!1)},W=async()=>{p(null),v(null),x(!0);try{w(await zx(e))}catch(R){p(String(R.message||R))}x(!1)},X=async()=>{p(null),v(null),x(!0);try{const R=await $x(e);w(R),v(f("npm-update-restarting"))}catch(R){p(String(R.message||R))}x(!1)},H=()=>{window.confirm(f("composer-clear-confirm"))&&(p(null),a2()?(window.dispatchEvent(new Event(mf)),v(f("composer-clear-done"))):p(f("composer-clear-failed")))},$=t&&t.service;return l.jsxs("div",{className:"nc-set-tab",children:[l.jsx("div",{className:"nc-system-tabs",role:"tablist","aria-label":f("tab-system"),children:["general","diagnostics"].map(R=>l.jsx("button",{type:"button",role:"tab","aria-selected":a===R,className:`nc-set-tabbtn${a===R?" on":""}`,onClick:()=>u(R),children:f(`system-${R}`)},R))}),a==="general"&&l.jsxs(l.Fragment,{children:[l.jsxs("section",{className:"nc-system-group",children:[l.jsx("h3",{children:f("system-this-node")}),t&&l.jsxs("div",{className:"nc-set-info",children:["v",t.version," · ",t.platform," · :",t.port,l.jsx("br",{}),$&&$.installed?f("service-installed"):f("service-missing"),$&&$.installed?` · ${$.active?f("service-active"):f("service-inactive")}`:"",$?` · boot ${$.boot?"on":"off"}`:""]}),l.jsx("div",{className:"nc-set-row",children:l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:n||S,title:n?f("settings-readonly"):"",onClick:K,children:f("service-regenerate")})}),l.jsx(JR,{token:e,readonly:n}),l.jsx(ZR,{})]}),l.jsxs("section",{className:"nc-system-group",children:[l.jsx("h3",{children:f("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||S||E&&!E.supported,onChange:R=>Y(R.target.checked)}),l.jsxs("span",{children:[l.jsx("b",{children:f("npm-auto-update")}),l.jsx("small",{children:f("npm-auto-update-help")})]})]}),E&&l.jsxs("div",{className:"nc-set-info",children:[f("npm-update-current")," v",E.current,E.latest?` · ${f("npm-update-latest")} v${E.latest}`:""," · ",f(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||S||!E||!E.supported,onClick:W,children:f("npm-update-check")}),E&&E.available&&l.jsx("button",{type:"button",className:"nc-btn primary",disabled:n||S||E.phase==="installing",onClick:X,children:f("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:f("system-security")}),l.jsx("div",{className:"nc-set-row",children:l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:n||S,title:n?f("settings-readonly"):"",onClick:()=>{p(null),v(null),b(!0)},children:f("token-rotate")})})]}),l.jsxs("section",{className:"nc-system-group",children:[l.jsx("h3",{children:f("system-local-data")}),l.jsxs("div",{className:"nc-set-form",children:[l.jsx("div",{className:"nc-sheet-label",children:f("composer-clear-data")}),l.jsx("small",{className:"nc-set-hint",children:f("composer-clear-data-help")}),l.jsx("div",{className:"nc-set-row",children:l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:H,children:f("composer-clear-data")})})]})]})]}),a==="diagnostics"&&l.jsxs("section",{className:"nc-system-group nc-system-diagnostics",children:[l.jsx("h3",{children:f("system-diagnostics")}),l.jsxs("div",{className:"nc-set-form nc-alternate-screen-settings",children:[l.jsx("div",{className:"nc-sheet-label",children:f("system-terminal")}),l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox","aria-label":f("alternate-screen"),checked:L,disabled:n||S,onChange:R=>Q(R.target.checked)}),l.jsxs("span",{children:[l.jsx("b",{children:f("alternate-screen")}),l.jsx("small",{children:f("alternate-screen-help")})]})]})]}),l.jsx(nP,{token:e,roster:o,readonly:n})]}),y&&l.jsxs("div",{className:"nc-set-confirm",children:[l.jsx("div",{children:f("token-rotate-explain")}),l.jsxs("div",{className:"nc-sheet-actions",children:[l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:S,onClick:()=>b(!1),children:f("cancel")}),l.jsx("button",{type:"button",className:"nc-btn primary",disabled:S,onClick:G,children:f("confirm")})]})]}),m&&l.jsx("div",{className:"nc-set-note",children:m}),d&&l.jsx("div",{className:"nc-err",children:d})]})}function sP({token:e,onClose:t,initialTab:n="nodes",initialLocation:s="",startNewCell:o=!1}){Yn();const a=n==="diagnostics"?"diagnostics":"general",[u,d]=k.useState(n==="diagnostics"?"system":n),p=k.useRef(null),m=k.useRef(null),[v,y]=k.useState({start:!1,end:!1}),[b,S]=k.useState(a),[x,E]=k.useState(null),[w,N]=k.useState([]),[C,L]=k.useState([]),[I,G]=k.useState(!1),[K,Y]=k.useState(null),[Q,W]=k.useState(0),X=zf(e,!0,Q),H=k.useCallback(()=>{const R=p.current;if(!R)return;const O=R.scrollWidth>R.clientWidth+1,F={start:O&&R.scrollLeft>1,end:O&&R.scrollLeft+R.clientWidth<R.scrollWidth-1};y(A=>A.start===F.start&&A.end===F.end?A:F)},[]);k.useEffect(()=>{const R=p.current;if(!R)return;const O=typeof ResizeObserver=="function"?new ResizeObserver(H):null;return O==null||O.observe(R),window.addEventListener("resize",H),H(),()=>{O==null||O.disconnect(),window.removeEventListener("resize",H)}},[H]),k.useEffect(()=>{var O,F;(F=(O=m.current)==null?void 0:O.scrollIntoView)==null||F.call(O,{behavior:"smooth",block:"nearest",inline:"nearest"});const R=window.requestAnimationFrame?window.requestAnimationFrame(H):setTimeout(H,0);return()=>{window.cancelAnimationFrame?window.cancelAnimationFrame(R):clearTimeout(R)}},[u,H]);const $=k.useCallback(async()=>{var R;try{const O=await Ky(e);E(O),Y(null)}catch(O){Y(String(O.message||O))}try{const F=(await wx(e)).peers||[];let A=[],T=[];try{const[j,z]=await Promise.all([on("/api/config",e).then(U=>U.json()).catch(()=>null),Vy(e).catch(()=>null)]),M=j&&typeof j.instanceId=="string"?j.instanceId:"",D=[{instanceId:M||null,route:[],label:null},...nb(z,M)],B=await Promise.all(D.map(async U=>{try{return{ok:!0,peers:((await qy(e,U.route)).nodes||[]).map(de=>tb(de,U)).filter(Boolean)}}catch(se){return{ok:!1,owner:U,error:se}}}));for(const U of B){if(U.ok){A.push(...U.peers);continue}U.owner.route.length!==0&&T.push({instanceId:U.owner.instanceId,label:U.owner.label,route:U.owner.route,failure:/timeout/i.test(String(((R=U.error)==null?void 0:R.message)||U.error))?"timeout":"unreachable"})}}catch{}L(T),N([...F,...A])}catch(O){Y(String(O.message||O))}},[e]);return k.useEffect(()=>{$();const R=setInterval($,5e3);return()=>clearInterval(R)},[$]),k.useEffect(()=>{let R=!1;return on("/api/config",e).then(O=>O.json()).then(O=>{R||G(!!O.readonlyDefault)}).catch(()=>{}),()=>{R=!0}},[e]),l.jsx("div",{className:"nc-set-overlay",onClick:t,children:l.jsxs("div",{className:"nc-set-panel",onClick:R=>R.stopPropagation(),children:[l.jsxs("div",{className:"nc-set-head",children:[l.jsx(lt,{name:"gear",size:18}),l.jsx("b",{children:f("settings")}),l.jsx("button",{type:"button",className:"nc-set-close",onClick:t,title:f("close"),children:l.jsx(lt,{name:"x",size:18})})]}),I&&l.jsx("div",{className:"nc-set-readonly",children:f("settings-readonly")}),K&&l.jsx("div",{className:"nc-err",children:K}),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:p,onScroll:H,children:["nodes","fleet","audio","input","system"].map(R=>l.jsx("button",{ref:u===R?m:null,type:"button",className:`nc-set-tabbtn${u===R?" on":""}`,onClick:()=>d(R),children:f(`tab-${R}`)},R))})}),l.jsxs("div",{className:"nc-set-body",children:[u==="nodes"&&l.jsx(QR,{token:e,nodes:w,roster:X,settings:x,readonly:I,vlUnavailable:C,refresh:$,refreshAliases:()=>W(R=>R+1)}),u==="fleet"&&l.jsx(AR,{token:e,readonly:I,startNewCell:o,initialLocation:s,targets:X.map(R=>({route:R.route,label:R.label||R.name,status:R.status}))}),u==="audio"&&l.jsx(eP,{token:e,readonly:I,nodes:w,settings:x}),u==="input"&&l.jsx(tP,{}),u==="system"&&l.jsx(iP,{token:e,settings:x,readonly:I,refresh:$,roster:X,section:b,setSection:S})]})]})})}function rP({token:e,initialPair:t,deviceDefault:n="",localNodeId:s="",localNameDefault:o="",onPairDone:a,onDone:u}){Yn();const[d,p]=k.useState(t?"pair":"welcome"),[m,v]=k.useState(!1),[y,b]=k.useState(null),[S,x]=k.useState(null),E=async()=>{v(!0),b(null);try{await gh(e,{wizardDone:!0}),a&&a(),u()}catch(w){b(String(w.message||w)),v(!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:f("wizard-title")}),l.jsx("small",{children:f("hydra-simple")})]}),d==="welcome"&&l.jsxs("div",{className:"nc-wiz-body",children:[l.jsx("div",{className:"nc-wiz-done",children:f("local-ready")}),l.jsxs("div",{className:"nc-sheet-actions",children:[l.jsx("button",{className:"nc-btn ghost",disabled:m,onClick:E,children:f("local-only")}),l.jsx("button",{className:"nc-btn primary",disabled:m,onClick:()=>p("pair"),children:f("add-node")})]})]}),d==="pair"&&l.jsxs("div",{className:"nc-wiz-body",children:[l.jsx(Gw,{token:e,initial:t||"",autoStart:!!t,deviceDefault:n,localNodeId:s,localNameDefault:o,onBusyChange:v,onSuccess:async w=>{x(w&&w.authorizedKeys?{line:w.authorizedKeys,note:w.authorizedKeysNote||""}:null),a&&a(),p("done")}}),l.jsx("div",{className:"nc-sheet-actions",children:l.jsx("button",{className:"nc-btn ghost",disabled:m,onClick:()=>{a&&a(),p("welcome")},children:f("back")})})]}),d==="done"&&l.jsxs("div",{className:"nc-wiz-body",children:[l.jsx("div",{className:"nc-wiz-done",children:f("node-connected")}),S&&l.jsx(bp,{line:S.line,note:S.note}),l.jsx("div",{className:"nc-sheet-actions",children:l.jsx("button",{className:"nc-btn primary",disabled:m,onClick:E,children:f("finish")})})]}),y&&l.jsx("div",{className:"nc-err",children:y})]})})}function oP(e,t){if(typeof EventSource>"u"||!e)return()=>{};const n=new EventSource(`/api/events?token=${encodeURIComponent(e)}`);return n.onmessage=s=>{try{const o=JSON.parse(s.data);o&&typeof o=="object"&&typeof o.type=="string"&&t(o)}catch{}},()=>{try{n.close()}catch{}}}const aP=6e3,lP=12e3;function cP({n:e,onClose:t}){return l.jsxs("div",{className:`nc-ntf-toast${e.urgency==="high"?" high":""}`,role:"status","aria-live":"polite",children:[l.jsxs("div",{className:"nc-ntf-toast-txt",children:[l.jsx("b",{children:e.title}),e.body&&l.jsx("small",{children:e.body}),e.session&&l.jsx("span",{className:"nc-ntf-from",children:e.session})]}),l.jsx("button",{type:"button",className:"nc-ntf-x",onClick:t,title:f("close"),children:l.jsx(lt,{name:"x",size:14})})]})}function uP({ask:e,token:t,onAnswered:n,onDismiss:s}){const[o,a]=k.useState(""),[u,d]=k.useState(!1),[p,m]=k.useState(null),[v,y]=k.useState(!1),b=async x=>{const E=String(x||"").trim();if(!(!E||u)){m(null),d(!0);try{await Kx(t,e.id,E),n(e.id)}catch(w){m(String(w.message||w))}d(!1)}},S=async()=>{if(!v){y(!0);try{await qx(t,e.id),s(e.id)}catch{y(!1)}}};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:e.session}),l.jsxs("code",{className:"nc-ask-id",children:["#",e.id]}),l.jsx("button",{type:"button",className:"nc-ask-dismiss",title:f("ask-dismiss"),"aria-label":f("ask-dismiss"),disabled:v,onClick:S,children:l.jsx(lt,{name:"x",size:14})})]}),l.jsx("div",{className:"nc-ask-q",children:e.question}),Array.isArray(e.options)&&e.options.length>0&&l.jsx("div",{className:"nc-ask-opts",children:e.options.map(x=>l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:u,onClick:()=>b(x),children:x},x))}),l.jsxs("div",{className:"nc-ask-reply",children:[l.jsx("textarea",{rows:2,placeholder:f("ask-reply-ph"),value:o,disabled:u,onChange:x=>a(x.target.value)}),l.jsx("button",{type:"button",className:"nc-btn primary",disabled:u||!o.trim(),onClick:()=>b(o),children:f("send")})]}),p&&l.jsx("div",{className:"nc-err",children:p})]})}function dP({token:e}){const[t]=Yn(),[n]=hS(),[s,o]=k.useState([]),[a,u]=k.useState([]),[d,p]=k.useState(()=>{try{return/(?:^|[#&])ask=/.test(location.hash)}catch{return!1}}),m=k.useRef(0),v=k.useRef(null);v.current||(v.current=YR());const y=k.useRef({enabled:n,lang:t});y.current={enabled:n,lang:t};const b=k.useCallback(w=>{o(N=>N.filter(C=>C.key!==w))},[]),S=k.useCallback(w=>{const N=`t${m.current+=1}`;o(L=>[...L.slice(-3),{...w,key:N}]),setTimeout(()=>b(N),w.urgency==="high"?lP:aP);const C=y.current;if(C.enabled)try{v.current.enqueue(w,UR(w,C.lang))}catch{}},[b]);k.useEffect(()=>{n||v.current.stop()},[n]),k.useEffect(()=>{const w=()=>{(document.visibilityState!=="visible"||!document.hasFocus())&&v.current.stop()},N=()=>v.current.stop();return document.addEventListener("visibilitychange",w),window.addEventListener("blur",w),window.addEventListener(xf,N),()=>{document.removeEventListener("visibilitychange",w),window.removeEventListener("blur",w),window.removeEventListener(xf,N),typeof v.current.dispose=="function"?v.current.dispose():v.current.stop()}},[]),k.useEffect(()=>{if(!e)return;let w=!1;Wx(e).then(C=>{w||u(C.asks||[])}).catch(()=>{});const N=oP(e,C=>{C.type==="notify"?S(C):C.type==="ask"&&C.ask&&C.ask.id?u(L=>L.some(I=>I.id===C.ask.id)?L:[...L,C.ask]):C.type==="ask-answered"&&C.id?u(L=>L.filter(I=>I.id!==C.id)):C.type==="ask-dismissed"&&C.id&&u(L=>L.filter(I=>I.id!==C.id))});return()=>{w=!0,N()}},[e,S]);const x=w=>u(N=>N.filter(C=>C.id!==w)),E=w=>u(N=>N.filter(C=>C.id!==w));return l.jsxs(l.Fragment,{children:[s.length>0&&l.jsx("div",{className:"nc-ntf-toasts",children:s.map(w=>l.jsx(cP,{n:w,onClose:()=>b(w.key)},w.key))}),a.length>0&&!d&&l.jsxs("button",{type:"button",className:"nc-ask-badge",onClick:()=>p(!0),title:f("asks-title"),children:["? ",l.jsx("span",{className:"nc-ask-count",children:a.length})]}),a.length>0&&d&&l.jsxs("div",{className:"nc-ask-panel",children:[l.jsxs("div",{className:"nc-ask-panel-head",children:[l.jsx("b",{children:f("asks-title")}),l.jsx("span",{className:"nc-ask-count",children:a.length}),l.jsx("button",{type:"button",className:"nc-ntf-x",onClick:()=>p(!1),title:f("close"),children:l.jsx(lt,{name:"x",size:16})})]}),l.jsx("div",{className:"nc-ask-panel-body",children:a.map(w=>l.jsx(uP,{ask:w,token:e,onAnswered:x,onDismiss:E},w.id))})]})]})}const hP=4e3;async function fP(e){const t=await on("/api/sessions",e);if((t==null?void 0:t.ok)===!1)throw new Error(`HTTP ${t.status}`);const n=await t.json();if(!Array.isArray(n==null?void 0:n.sessions))throw new Error("invalid sessions payload");return n.sessions}async function hh(e,t=[]){var d;const[n,s]=await Promise.allSettled([t.length?Tf(e,t):fP(e),Xs(e,t)]),o=n.status==="fulfilled"&&Array.isArray((d=n.value)==null?void 0:d.sessions)?n.value.sessions:Array.isArray(n.value)?n.value:null,a=s.status==="fulfilled"?s.value:null,u=(a==null?void 0:a.available)===!0&&Array.isArray(a.cells)?a.cells:null;return{sessions:o,cells:u,fresh:Array.isArray(o)&&Array.isArray(u)}}function fS(e,t,n){return n===!0&&(e==null?void 0:e.degraded)!==!0&&(e==null?void 0:e.active)===!0&&e.tmux!==!1&&!!e.tmuxSession&&(t||[]).some(s=>(s==null?void 0:s.name)===e.tmuxSession)}function pP(e){const t=new Map((e.sessions||[]).map(o=>[o.name,o])),n=[],s=(o,a,u,d=[],p="")=>{const m=new Map((a||[]).map(v=>[v.name,v]));for(const v of o||[]){const y=m.get(v.tmuxSession)||{},b=Uf(v,y),S=fS(v,a,u);n.push({key:ka(d,v.tmuxSession||v.cell),session:v.tmuxSession,route:d,cellName:v.cell,label:v.cell,node:d.length?d.join("/"):"",nodeLabel:p,live:S,selectable:S,verified:u===!0,working:b.working,degraded:!!v.degraded,active:v.active===!0,activity:y.activity||v.activity||0,subtitle:b.subtitle,preview:y.preview||v.preview||"",telemetry:y.telemetry||null,panelUrl:v.panelUrl||""})}};s(e.cells,[...t.values()],e.localFresh===!0);for(const o of e.nodeGroups||[]){const a=Array.isArray(o.route)?o.route:[];o.kind==="vl"||!a.length||s(o.cells,o.sessions,o.switcherFresh===!0,a,o.label||o.name||"")}return n}function mP(e){const t=new Map,n=Array.isArray(e.sessions)?e.sessions:[],s=Array.isArray(e.cells)?e.cells:[],o=new Map(n.map(u=>[u.name,u])),a=new Set(s.map(u=>u.tmuxSession).filter(Boolean));t.set("local",Wf(s,n.filter(u=>!a.has(u.name)),o));for(const u of e.nodeGroups||[]){const d=Array.isArray(u.route)?u.route:[];if(u.kind==="vl"||!d.length)continue;const p=Array.isArray(u.cells)?u.cells:[],m=Array.isArray(u.sessions)?u.sessions:[],v=new Set(p.map(y=>y.tmuxSession).filter(Boolean));t.set(d.join("/"),fc({...u,route:d,cells:p,sessions:m,unmanaged:m.filter(y=>!v.has(y.name))}).rawItems)}return t}function gP(e,t,n,s){return[...new Set(e.map(a=>a.node||"local"))].flatMap(a=>{const u=e.filter(v=>(v.node||"local")===a),d=new Map((t.get(a)||[]).map(v=>[v.key,v])),p=new Map(u.map(v=>[v.key,v])),m=u.map(v=>{const y=d.get(v.key);return{...v,label:(y==null?void 0:y.label)||v.label,live:(y==null?void 0:y.live)??v.live,fresh:(y==null?void 0:y.fresh)===!0,activity:(y==null?void 0:y.activity)??v.activity}});return qs(m,n,"all",ms(s,a)).map(v=>p.get(v.key))})}function vP({token:e,current:t,onPick:n,onClose:s,panelPort:o=0,nodePanelPorts:a={}}){const[u,d]=k.useState(wv),[p,m]=k.useState(!1),[v,y]=k.useState(!1),[b,S]=k.useState(""),[x,E]=k.useState(null),[w,N]=k.useState(""),[C,L]=k.useState(""),I=k.useRef(null),G=k.useRef(null),K=k.useMemo(()=>pP(u),[u]),Y=k.useMemo(()=>mP(u),[u]),{pins:Q,orders:W,canMoveRoster:X,moveRoster:H,stepRoster:$}=Ff(),R=k.useMemo(()=>gP(K,Y,Q,W),[K,Y,Q,W]),O=k.useMemo(()=>p?R:R.filter(M=>M.selectable||M.degraded&&M.active),[R,p]),F=k.useMemo(()=>K.find(M=>M.key===w&&M.selectable),[K,w]),A=k.useMemo(()=>x?K.find(M=>M.key===x.key):null,[K,x]);k.useEffect(()=>{var B;const M=document.activeElement;(B=G.current)==null||B.focus();const D=U=>{U.key==="Escape"&&s()};return document.addEventListener("keydown",D),()=>{var U;document.removeEventListener("keydown",D),(U=M==null?void 0:M.focus)==null||U.call(M)}},[s]),k.useEffect(()=>{let M=!0,D=!1;const B=async()=>{if(D)return;D=!0;const se=wv(),ee=Array.isArray(se.nodeGroups)?se.nodeGroups:[],de=hh(e),ve=je=>je.kind!=="vl"&&Array.isArray(je.route)&&je.route.length>0,fe=await Promise.all(ee.filter(ve).map(async je=>({group:je,result:await hh(e,je.route)}))),pe=await de;if(!M)return;const Ve=new Map(fe.map(({group:je,result:Ct})=>[JSON.stringify(je.route||[]),Ct])),ut=ee.map(je=>{if(!ve(je))return{...je,switcherFresh:!1};const Ct=Ve.get(JSON.stringify(je.route||[]));return Ct?{...je,sessions:Ct.sessions||je.sessions||[],cells:Ct.cells||je.cells||[],switcherFresh:Ct.fresh}:{...je,switcherFresh:!1}}),vt=bb({...se,sessions:pe.sessions||se.sessions||[],cells:pe.cells||se.cells||[],localFresh:pe.fresh,nodeGroups:ut,refreshedAt:Date.now()});d(vt),y(!0),D=!1};B();const U=setInterval(B,hP);return()=>{M=!1,clearInterval(U)}},[e]);const T=M=>M.degraded?f("cell-degraded"):M.verified?M.selectable?M.working?f("cell-working"):f("cell-idle"):f("cell-off"):f("cell-switcher-not-confirmed"),j=M=>{if(S(""),!M.selectable){S(M.verified?f("cell-switcher-not-active"):f("cell-switcher-not-confirmed"));return}N(M.key)},z=async()=>{const M=F;if(!M){S(f("cell-switcher-select"));return}S(""),L(M.key);try{const D=await hh(e,M.route),B=(D.cells||[]).find(U=>(U==null?void 0:U.cell)===M.cellName&&(U==null?void 0:U.tmuxSession)===M.session);if(D.fresh!==!0){S(f("cell-switcher-verify-failed"));return}if(!fS(B,D.sessions,D.fresh)){S(f("cell-switcher-not-active"));return}n({session:M.session,...M.node?{node:M.node}:{},cellName:M.cellName}),s()}catch{S(f("cell-switcher-verify-failed"))}finally{L("")}};return l.jsx("div",{className:"nc-cell-switcher-backdrop",onClick:s,children:l.jsxs("aside",{ref:I,className:"nc-cell-switcher",role:"dialog","aria-label":f("fleet-cells"),tabIndex:-1,onClick:M=>M.stopPropagation(),children:[l.jsxs("div",{className:"nc-cell-switcher-list",children:[!v&&l.jsx("div",{className:"nc-empty",role:"status",children:f("cell-switcher-refreshing")}),v&&O.length===0&&l.jsx("div",{className:"nc-empty",role:"status",children:f("cell-switcher-empty-active")}),O.map(M=>{const D=(t==null?void 0:t.session)===M.session&&((t==null?void 0:t.node)||"")===M.node,B=w===M.key,U=T(M),se=vf(f,M.activity),ee=_f(f,M.telemetry),de=[se,ee].filter(Boolean).join(" · "),ve=M.node||"local",fe=Y.get(ve)||K.filter(pe=>(pe.node||"local")===ve);return l.jsxs("div",{className:`nc-cell-switcher-row${D?" current":""}${B?" selected":""}${M.selectable?"":" off"}`,"data-roster-key":M.key,"data-position":ve,children:[l.jsx(Yi,{position:ve,itemKey:M.key,label:M.cellName,canMove:X,onMove:(pe,Ve)=>H(ve,pe,Ve,fe),onStep:pe=>$(ve,M.key,pe,fe)}),l.jsx("button",{type:"button",className:"nc-cell-switcher-peek",title:f("cell-peek"),"aria-label":`${f("cell-peek")}: ${M.cellName}`,onClick:pe=>{pe.stopPropagation(),E({key:M.key,source:"preview"})},children:l.jsx("span",{className:`nc-cell-switcher-dot${M.degraded?" warn":M.live?` on${M.working?" working":""}`:""}`})}),l.jsxs("span",{className:"nc-cell-switcher-acts",children:[l.jsx("button",{type:"button",className:"nc-cell-switcher-act",title:f("cell-peek-stream"),"aria-label":`${f("cell-peek-stream")}: ${M.cellName}`,onClick:pe=>{pe.stopPropagation(),E({key:M.key,source:"stream"})},children:"▶"}),M.panelUrl&&l.jsx("button",{type:"button",className:"nc-cell-switcher-act",title:f("cell-peek-panel"),"aria-label":`${f("cell-peek-panel")}: ${M.cellName}`,onClick:pe=>{pe.stopPropagation(),E({key:M.key,source:"panel"})},children:"▣"})]}),l.jsx("button",{type:"button",className:"nc-cell-switcher-row-select","aria-current":D?"true":void 0,"aria-pressed":B,"aria-disabled":!M.selectable,disabled:C===M.key,onClick:()=>j(M),children:l.jsxs("span",{className:"nc-cell-switcher-copy",children:[l.jsx("b",{children:M.cellName}),l.jsx("small",{className:"nc-cell-switcher-state",children:U}),l.jsx("small",{children:[M.nodeLabel,M.subtitle].filter(Boolean).join(" · ")}),de&&l.jsx("small",{className:"nc-cell-switcher-telemetry",children:de})]})})]},M.key)})]}),b&&l.jsx("div",{className:"nc-cell-switcher-notice",role:"status",children:b}),x&&A&&l.jsx(Cw,{row:A,token:e,initialSource:x.source,panelPort:kc(A.route||[],a,o),onClose:()=>E(null)}),l.jsx("div",{className:"nc-cell-switcher-actions",children:l.jsx("button",{type:"button",className:"nc-cell-switcher-open",disabled:!F||!!C,onClick:z,children:F?`${f("cell-switcher-open")}: ${F.cellName}`:f("cell-switcher-select")})}),l.jsxs("div",{className:"nc-cell-switcher-controls",children:[l.jsx("b",{children:f("fleet-cells")}),l.jsx("button",{type:"button",className:"nc-cell-switcher-filter","aria-pressed":p,onClick:()=>{S(""),m(M=>!M)},children:f(p?"cell-switcher-show-active":"cell-switcher-show-all")}),l.jsx("button",{ref:G,type:"button",className:"nc-cell-switcher-close","aria-label":f("cell-switcher-close"),title:f("cell-switcher-close"),onClick:s,children:"×"})]})]})})}const _P=2e3;function yP(e){if(e.kind==="gap")return`${f("vl-events-gap")} ${e.count||"?"}`;if(e.kind==="truncate")return f("vl-events-truncated");if(e.kind==="turn_end")return f("vl-events-turn-end");if(e.kind==="done")return f("vl-events-done");if(e.kind==="writer_epoch")return f("vl-events-writer-epoch");if(e.kind==="tool_start")return`${f("vl-events-tool")} ${e.name||""}`.trim();if(e.kind==="tool_end"){const t=e.isError?f("vl-events-tool-failed"):f("vl-events-tool-ok");return`${f("vl-events-tool")} ${e.name||""} — ${t}`.trim()}return e.kind==="usage"?e.text||f("vl-events-usage"):e.text||""}function bP({token:e,nodeId:t,route:n=[]}){const[s,o]=k.useState([]),[a,u]=k.useState(!1),d=k.useRef(0),p=k.useRef(!1);return k.useEffect(()=>{let m=!0;d.current=0,p.current=!1,o([]);const v=async()=>{if(!p.current){p.current=!0;try{const S=await Sx(e,t,d.current,n);if(!m)return;u(!1);const E=(Array.isArray(S==null?void 0:S.events)?S.events:[]).filter(w=>Number.isSafeInteger(w==null?void 0:w.seq)&&w.seq>d.current);E.length&&(o(w=>w.concat(E).slice(-500)),d.current=E[E.length-1].seq),Number.isSafeInteger(S==null?void 0:S.cursor)&&S.cursor>d.current&&(d.current=S.cursor)}catch{m&&u(!0)}finally{p.current=!1}}},y=()=>{v().catch(()=>{})};y();const b=setInterval(y,_P);return()=>{m=!1,clearInterval(b)}},[e,t,JSON.stringify(n)]),l.jsxs("div",{className:"nc-vl-events",children:[a&&l.jsx("div",{className:"nc-set-hint nc-vl-events-stale",children:f("vl-events-stale")}),s.length===0&&!a&&l.jsx("small",{className:"nc-set-hint","data-testid":"vl-events-empty",children:f("vl-events-empty")}),s.length>0&&l.jsx("ol",{className:"nc-vl-events-list",children:s.map(m=>l.jsx("li",{"data-testid":`vl-ev-${m.seq}`,className:`nc-vl-ev nc-vl-ev-${m.kind}${m.isError?" error":""}${m.kind==="gap"?" gap":""}`,children:yP(m)},`${m.seq}-${m.kind}`))})]})}function Ay({peer:e,token:t,onBack:n}){var s;return Yn(),e?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:f("back"),children:[l.jsx(lt,{name:"chevronLeft",size:18}),l.jsx("span",{className:"nc-bar-label",children:f("back")})]}),l.jsxs("span",{className:"nc-bar-center",children:[l.jsx("b",{title:e.label,children:e.label}),((s=e.session)==null?void 0:s.profile)&&l.jsxs("small",{className:"nc-bar-sub",children:[e.session.profile," · ",f("vl-events-title")]})]}),l.jsx("span",{className:"nc-bar-right"})]}),l.jsx("div",{className:"nc-vl-session-body",children:l.jsx(bP,{token:t,nodeId:e.nodeId,route:e.route||[]})})]}):null}const fh=e=>Qi(xr(e)).length===0,ph=e=>Array.isArray(e)?e.join("/"):"";function wP(e){const t=new Set,n=[];for(const s of Array.isArray(e)?e:[])!s||!gi.test(String(s.instanceId||""))||!Array.isArray(s.route)||!s.route.length||t.has(s.instanceId)||(t.add(s.instanceId),n.push({instanceId:s.instanceId,route:[...s.route],label:String(s.label||s.name||s.route.join(" › ")),status:s.status||"offline"}));return n.sort((s,o)=>s.label.localeCompare(o.label))}function ha(e){return{instanceId:e.ownerId,route:e.ownerRoute||[],label:e.ownerLabel,status:e.available===!1?"offline":"up"}}function vr(e,t,n,s=!1,o=!0){const a=t.instanceId;return{...e,id:po(s?null:a,e.name),ownerId:a,ownerRoute:s?[]:[...t.route],ownerLabel:s?"Local":t.label,local:s,available:o,ownerTopology:Array.isArray(n)?n:[],layout:yf(e.layout,a,n)}}function SP(e,t,n,s,o=[]){const[a,u]=k.useState([]),[d,p]=k.useState(!1),[m,v]=k.useState("idle"),[y,b]=k.useState(""),[S,x]=k.useState(""),E=k.useRef([]),w=k.useRef([]),N=k.useRef(""),C=k.useRef(t),L=k.useRef(n),I=k.useRef(!1),G=k.useRef(!0),K=k.useRef(""),Y=k.useMemo(()=>wP(o),[o]),Q=Y.map(M=>`${M.instanceId}:${ph(M.route)}:${M.status}:${M.label}`).join("|");w.current=Y,L.current=n,C.current=t,E.current=a;const W=k.useCallback(M=>bf(M.layout,N.current,w.current),[]),X=k.useCallback((M,D=!0,B=C.current)=>{const U=O_(M,Gl()),se=E.current.some(de=>de.id===B);E.current=U,u(U);const ee=U.find(de=>de.id===B);if(D&&ee){G.current=!0;const de=W(ee);s(de),ee.local&&B2(ee.name,de)}else se&&!ee&&(G.current=!0,s(fo()),b("deck non più condiviso dal nodo owner"));T2(U.filter(de=>de.local).map(de=>de.name))},[s,W]),H=k.useCallback(async M=>{let D=await $l(e);const B=D.decks.find(U=>U.name==="main");if(D.decks.length===1&&B&&B.revision===0&&fh(B.layout)){const U=M2(),se=xr(wf("main")||fo());if(!fh(se)){const ee=yf(se,M,[]);D.decks[0]=await Fl(e,"main",ee,0,[])}for(const ee of U.filter(de=>de!=="main"))try{let de=await rv(e,ee,[]);const ve=xr(wf(ee)||fo());fh(ve)||(de=await Fl(e,ee,yf(ve,M,[]),de.revision,[]))}catch{}D=await $l(e)}return D},[e]),$=k.useCallback(async({migrate:M=!1}={})=>{const D=await Df(e,[]),B=gi.test(String(D.instanceId||""))?D.instanceId:"";if(!B)throw new Error("instanceId locale non disponibile");N.current=B,x(B);const[U,se]=await Promise.all([M?H(B):$l(e),tv(e,[]).catch(()=>({nodes:[]}))]),ee={instanceId:B,route:[],label:"Local"},de=U.decks.map(fe=>vr(fe,ee,se.nodes,!0,!0)),ve=E.current;return await Promise.all(w.current.map(async fe=>{if(fe.status!=="up"){de.push(...ve.filter(pe=>!pe.local&&pe.ownerId===fe.instanceId).map(pe=>({...pe,ownerRoute:[...fe.route],ownerLabel:fe.label,available:!1})));return}try{const[pe,Ve]=await Promise.all([$l(e,fe.route),tv(e,fe.route).catch(()=>({nodes:[]}))]);de.push(...pe.decks.map(ut=>vr(ut,fe,Ve.nodes,!1,!0)))}catch{de.push(...ve.filter(Ve=>!Ve.local&&Ve.ownerId===fe.instanceId).map(Ve=>({...Ve,ownerRoute:[...fe.route],ownerLabel:fe.label,available:!1})))}})),de.sort((fe,pe)=>fe.local===pe.local?fe.ownerLabel.localeCompare(pe.ownerLabel)||(fe.name==="main"?-1:pe.name==="main"?1:fe.name.localeCompare(pe.name)):fe.local?-1:1),de},[e,H,Q]);k.useEffect(()=>{if(!e)return;let M=!1;const D=K.current!==e;return K.current=e,$({migrate:D}).then(B=>{if(M)return;const U=E.current.find(de=>de.id===C.current),se=B.find(de=>de.id===C.current),ee=se&&(!U||se.revision>U.revision||U.available!==se.available||ph(U.ownerRoute)!==ph(se.ownerRoute));X(B,D||!!ee&&!I.current),p(!0),se&&b("")}).catch(B=>{M||(p(!0),b(String(B.message||B)))}),()=>{M=!0}},[X,$,Q,e]);const R=k.useCallback(async(M=C.current)=>{if(!d||!I.current)return!0;const D=E.current.find(B=>B.id===M);if(!D)return b(`deck inesistente: ${M}`),!1;if(D.available===!1)return b(`nodo owner offline: ${D.ownerLabel}`),!1;v("saving");try{const B=D_(xr(L.current),D.ownerId,D.ownerTopology),U=await Fl(e,D.name,B,D.revision,D.ownerRoute),se=vr(U,ha(D),D.ownerTopology,D.local,!0);return X(E.current.map(ee=>ee.id===M?se:ee),!1),I.current=!1,v("saved"),b(""),setTimeout(()=>v("idle"),1500),!0}catch(B){if(v("error"),b(String(B.message||B)),B.status===409&&B.data&&B.data.current){const U=E.current.find(ee=>ee.id===M),se=vr(B.data.current,ha(U),U.ownerTopology,U.local,!0);X(E.current.map(ee=>ee.id===M?se:ee),!1)}return!1}},[d,e,X]);return k.useEffect(()=>{if(!d)return;if(G.current){G.current=!1;return}I.current=!0,v("saving");const M=setTimeout(R,650);return()=>clearTimeout(M)},[n,d,R]),k.useEffect(()=>{if(!d)return;const M=setInterval(async()=>{try{const D=await $(),B=E.current.find(ee=>ee.id===C.current),U=D.find(ee=>ee.id===C.current),se=U&&(!B||U.revision>B.revision||B.available!==U.available);X(D,se&&!I.current)}catch{}},5e3);return()=>clearInterval(M)},[d,$,X]),{decks:a,records:a,localNodeId:S,ready:d,saveState:m,error:y,setError:b,saveNow:R,select:async M=>{if(I.current&&!await R(C.current))throw new Error("salvataggio del deck corrente fallito: cambio annullato");const D=E.current.find(B=>B.id===M);if(!D)throw new Error(`deck inesistente: ${M}`);return I.current=!1,G.current=!0,W(D)},add:async(M,D=null)=>{const B=D===Gi?E.current.find(ee=>ee.local):D?E.current.find(ee=>ee.ownerId===D):null;if(!B||B.available===!1)throw new Error("nodo owner non disponibile");const U=await rv(e,M,B.ownerRoute),se=vr(U,ha(B),B.ownerTopology,B.local,!0);return X([...E.current,se],!1),se},rename:async(M,D)=>{const B=E.current.find(ve=>ve.id===M);if(!B)throw new Error("deck inesistente");if(M===C.current&&I.current&&!await R(M))throw new Error(`salvataggio di "${B.name}" fallito: rinomina annullata`);const U=E.current.find(ve=>ve.id===M);if(!U)throw new Error("deck inesistente");const se=await Vx(e,U.name,D,U.revision,U.ownerRoute),ee=vr(se,ha(U),U.ownerTopology,U.local,!0),de=U.local?Gi:U.ownerId;return $d(I2(Gl(),de,M,ee.id)),X(E.current.map(ve=>ve.id===M?ee:ve),!1),ee},remove:async M=>{const D=E.current.find(U=>U.id===M);if(!D)throw new Error("deck inesistente");M===C.current&&(I.current=!1),await Yx(e,D.name,D.revision,D.ownerRoute);const B=D.local?Gi:D.ownerId;$d(O2(Gl(),B,M)),X(E.current.filter(U=>U.id!==M),!1)},reorder:(M,D)=>{const B=E.current.find(fe=>fe.id===M),U=E.current.find(fe=>fe.id===D);if(!B||!U)return!1;const se=B.local?Gi:B.ownerId,ee=U.local?Gi:U.ownerId;if(se!==ee)return!1;const de=E.current.filter(fe=>(fe.local?Gi:fe.ownerId)===se).map(fe=>fe.id),ve=$d(D2(Gl(),se,M,D,de));return X(O_(E.current,ve),!1),!0},addTileTo:async(M,D)=>{const B=E.current.find(fe=>fe.id===M);if(!B)throw new Error("deck inesistente");if(B.available===!1)throw new Error(`nodo owner offline: ${B.ownerLabel}`);const U=Lw(D,N.current,w.current);if(!U)throw new Error("riferimento sessione non valido");const se=W(B),ee=D_(vb(se,U),B.ownerId,B.ownerTopology),de=await Fl(e,B.name,ee,B.revision,B.ownerRoute),ve=vr(de,ha(B),B.ownerTopology,B.local,!0);return X(E.current.map(fe=>fe.id===M?ve:fe),!1),ve},localMainId:po(null,"main"),parseDeckId:Mc}}const xP="/sw.js",Cf="nc-sw-update";let Ef=null,Nf=!1,jf=null,pS=Object.freeze({needed:!1,kind:null,version:""}),mS=!1;function gS(){typeof window<"u"&&window.dispatchEvent(new Event(Cf))}function vS(){const e=jf||(Nf?{kind:"reload",version:""}:null);pS=Object.freeze({needed:!!e,kind:(e==null?void 0:e.kind)||null,version:(e==null?void 0:e.version)||""})}function My(){return pS}function kP(e){return typeof window>"u"?()=>{}:(window.addEventListener(Cf,e),()=>window.removeEventListener(Cf,e))}function jp(e){Nf!==e&&(Nf=e,vS(),gS())}const mh="nc-auto-reload";function CP(){try{return typeof sessionStorage<"u"?sessionStorage:null}catch{return null}}function EP(e,t,n,s={}){let o=null;e&&t&&e!==t?o={kind:"install",version:e}:t&&n&&t!==n&&(o={kind:"reload",version:t});const a=JSON.stringify(o)===JSON.stringify(jf);jf=o,vS(),a||gS();const u=s.storage===void 0?CP():s.storage;if(!o){try{u&&u.removeItem(mh)}catch{}return}if(o.kind!=="reload"||!u)return;const d=`${t}|${n}`;try{if(u.getItem(mh)===d)return;u.setItem(mh,d)}catch{return}(s.applyImpl||_S)()}function NP(e){e.addEventListener("statechange",()=>{e.state==="installed"&&navigator.serviceWorker.controller&&jp(!0)})}function jP(){typeof navigator>"u"||!("serviceWorker"in navigator)||(navigator.serviceWorker.addEventListener("controllerchange",()=>{mS&&location.reload()}),navigator.serviceWorker.register(xP).then(e=>{Ef=e,e.waiting&&jp(!0),e.addEventListener("updatefound",()=>{const t=e.installing;t&&NP(t)}),setInterval(()=>{e.update().catch(()=>{})},3600*1e3)}).catch(()=>{}))}function _S(){mS=!0,jp(!1);const e=Ef&&Ef.waiting;e?(e.postMessage({type:"SKIP_WAITING"}),setTimeout(()=>location.reload(),4e3)):location.reload()}function RP({hash:e="",origin:t="",pathname:n="",search:s=""}={}){const o=String(e||"").replace(/^#/,""),a=`${n||""}${s||""}`;if(!o)return{token:"",pair:"",nextUrl:a};const u=new URLSearchParams(o),d=u.get("token")||"",p=u.get("pair")||"",m=p?`${t||""}${n||""}#pair=${p}`:"";return{token:d,pair:m,nextUrl:a}}const yS=9,bS=24,wS="nc_side_w",Ty="nc_side_min",PP=240;function LP(){const e=Number(localStorage.getItem(wS));return e>=180&&e<=480?e:PP}function AP(){const e=Number(localStorage.getItem("nc_fontsize"));return e>=yS&&e<=bS?e:13}function MP(){const e={token:"",pair:""};try{const{token:t,pair:n,nextUrl:s}=RP({hash:location.hash,origin:location.origin,pathname:location.pathname,search:location.search});if(t){e.token=t;try{localStorage.setItem("nc_token",t)}catch{}}if(n){e.pair=n;try{sessionStorage.setItem("nc_pair",n)}catch{}}if(location.hash)try{history.replaceState(null,"",s)}catch{}}catch{}if(e.token||(e.token=sessionStorage.getItem("nc_token")||localStorage.getItem("nc_token")||""),!e.pair){const t=sessionStorage.getItem("nc_pair");t&&(e.pair=t)}return e}function TP(e){try{return xr(wf(e))}catch{return fo()}}function Dy(e){if(!e)return"";const t=Math.floor(Date.now()/1e3)-e;return t<0||t<60?"ora":t<3600?`${Math.floor(t/60)}m`:t<86400?`${Math.floor(t/3600)}h`:`${Math.floor(t/86400)}g`}function Iy({session:e,node:t,ownerId:n,cellName:s,token:o,readonly:a=!1,panelPort:u=0,onBack:d,onCellSwitcher:p,cellSwitcherOpen:m=!1}){Yn();const[v]=up(),[y,b]=k.useState(!1),[S,x]=k.useState(()=>window.matchMedia("(pointer: coarse)").matches),[E,w]=k.useState(null),[N,C]=k.useState(AP),[L,I]=k.useState(s||e),[G,K]=k.useState(""),[Y,Q]=k.useState(""),[W,X]=k.useState(""),[H,$]=k.useState(!1),R=U=>C(se=>{const ee=Math.max(yS,Math.min(bS,se+U));return localStorage.setItem("nc_fontsize",String(ee)),ee}),O=k.useRef(()=>{}),F=k.useRef(()=>!1),A=k.useRef(()=>{}),T=k.useRef(!1),[j,z]=k.useState(!1),[M,D]=k.useState(!1),B=()=>{T.current=!T.current,z(T.current)};return k.useEffect(()=>{I(s||e),$(!1)},[s,e]),k.useEffect(()=>{let U=!0;const se=t?t.split("/"):[],ee=t?`/api/route/${t.split("/").map(encodeURIComponent).join("/")}/_`:"/api";async function de(){let fe=null,pe=null;try{const vt=await(await on(`${ee}/sessions`,o)).json();Array.isArray(vt.sessions)&&(fe=vt.sessions.find(je=>je.name===e))}catch{}try{const ut=await Xs(o,se);ut.available&&Array.isArray(ut.cells)&&(pe=ut.cells.find(vt=>vt.tmuxSession===e))}catch{}if(!U)return;I(dp({session:e,cell:pe||(s?{cell:s}:null)})),Q(typeof(pe==null?void 0:pe.panelUrl)=="string"?pe.panelUrl.trim():""),X(typeof(pe==null?void 0:pe.cell)=="string"?pe.cell:"");let Ve="";pe?Ve=`${pe.engine}${pe.key?`·${pe.key}`:""}`:fe&&(Ve=fe.attached?`attached · ${Dy(fe.activity)}`:fe.activity?Dy(fe.activity):""),K(Ve)}de();const ve=setInterval(de,4e3);return()=>{U=!1,clearInterval(ve)}},[e,t,o]),l.jsxs("div",{className:"nc-app",children:[l.jsxs("header",{className:"nc-bar nc-bar-single",children:[l.jsxs("button",{onClick:d,title:f("sessions"),children:[l.jsx(lt,{name:"chevronLeft",size:18}),l.jsx("span",{className:"nc-bar-label",children:f("sessions")})]}),l.jsxs("span",{className:"nc-bar-center",children:[l.jsx("b",{title:t?`${L} · ${t}`:L,children:L}),G&&l.jsx("small",{className:"nc-bar-sub",children:G})]}),l.jsxs("span",{className:"nc-bar-right",children:[l.jsx("button",{onClick:()=>R(-1),title:f("zoom-out"),children:l.jsx(lt,{name:"zoomOut",size:18})}),l.jsx("button",{onClick:()=>R(1),title:f("zoom-in"),children:l.jsx(lt,{name:"zoomIn",size:18})}),l.jsx("button",{onClick:()=>x(U=>!U),title:f("composer"),children:l.jsx(lt,{name:"keyboard",size:20})}),l.jsx("button",{onClick:()=>b(U=>!U),title:f("files"),children:l.jsx(lt,{name:"folder",size:20})}),Y&&l.jsx("button",{onClick:()=>$(U=>!U),title:f("panel"),"aria-pressed":H,children:l.jsx(lt,{name:"monitor",size:20})})]})]}),l.jsxs("div",{className:"nc-termwrap",children:[l.jsx(sp,{session:e,node:t,token:o,readonly:a,takeSize:!0,sendRef:O,composerRef:F,actionRef:A,ctrlRef:T,setCtrlArmed:z,onFiles:w,fontSize:N,selectionMode:M,onSelectionModeChange:D,keyboardGesture:v.terminalKeyboardGesture}),H&&Y&&W&&l.jsx(ap,{cellId:W,panelUrl:Y,route:t?t.split("/"):[],panelPort:u,token:o,title:L})]}),l.jsx(XN,{onKeyboard:()=>x(U=>!U),onCellSwitcher:p,cellSwitcherOpen:m,send:U=>O.current(U),action:U=>A.current(U),ctrlArmed:j,onCtrl:B,selectionMode:M,onSelectionMode:D,keepKeyboardClosed:v.keybarKeepsKeyboardClosed,showEnter:v.showKeybarEnter,keybarLayout:v.keybarLayout}),S&&l.jsx(Sw,{submitText:U=>F.current(U),token:o,session:e,node:t,ownerId:n,readonly:a,keepKeyboardClosedOnVoice:v.voiceKeepsKeyboardClosed}),y&&l.jsx(fw,{session:e,node:t,token:o,filesEvent:E,onClose:()=>b(!1)})]})}function DP(){Yn();const[e]=k.useState(MP),[t,n]=k.useState(e.token),[s,o]=k.useState(e.pair||""),a=k.useCallback(()=>{o("");try{sessionStorage.removeItem("nc_pair")}catch{}},[]),[u,d]=k.useState(!1),p=jN(),[m]=k.useState(()=>A2(typeof location<"u"?location.pathname:"/")),[v,y]=k.useState(m.id),b=v===po(null,vi),[S,x]=k.useState(null),E=te=>{const Se=Gs(te);x(Se?{...Se,...typeof(te==null?void 0:te.cellName)=="string"&&te.cellName?{cellName:te.cellName}:{}}:null)},[w,N]=k.useState([]),[C,L]=k.useState([]),[I,G]=k.useState([]),[K,Y]=k.useState(!1),[Q,W]=k.useState(null),[X,H]=k.useState(()=>m.ownerId?fo():TP(m.name)),[$,R]=k.useState(null),[O,F]=k.useState(null),A=te=>F(Gs(te)),[T,j]=k.useState(null),z=zf(t,p),M=k.useMemo(()=>(z||[]).filter(te=>te.instanceId).map(te=>({instanceId:te.instanceId,route:te.route,label:te.label,status:te.status})),[z]),D=SP(t,v,X,H,M),B=D.decks;k.useEffect(()=>{const te=new Map;for(const Se of z||[]){const Te=(Se.route||[Se.name]).join("/"),tt=new Set((Se.sessions||[]).map(nt=>nt.name));for(const nt of Se.cells||[])!nt.cell||!nt.tmuxSession||nt.cell===nt.tmuxSession||tt.has(nt.cell)||te.set(`${Te}:${nt.cell}`,`${Te}:${nt.tmuxSession}`)}H(Se=>Ak(Se,te))},[z]),k.useEffect(()=>{D.localNodeId&&H(te=>{const Se=bf(te,D.localNodeId,M);return JSON.stringify(Se)===JSON.stringify(te)?te:Se})},[M,D.localNodeId]);const[U,se]=k.useState(null),[ee,de]=k.useState(null),ve=k.useRef(0),[fe,pe]=k.useState(!1),[Ve,ut]=k.useState(LP),[vt,je]=k.useState(!b),[Ct,dn]=k.useState(()=>b?localStorage.getItem(Ty)==="1":!0),[gn,Yt]=k.useState(!1),[xt,Ot]=k.useState("nodes"),[Ut,Nt]=k.useState(!1),[Dt,At]=k.useState(""),[jt,hn]=k.useState(!1),re=(te="nodes",Se=!1,Te="")=>{Ot(te),Nt(Se),At(Te),Yt(!0)},[Qe,me]=k.useState(!1),[Ge,ct]=k.useState({deviceDefault:"",localNodeId:"",localNameDefault:""}),[oe,ie]=k.useState(!1),[_e,be]=k.useState(0),[ke,it]=k.useState({});k.useEffect(()=>{try{localStorage.setItem(wS,String(Ve))}catch{}},[Ve]),k.useEffect(()=>{try{localStorage.setItem(Ty,Ct?"1":"")}catch{}},[Ct]),k.useEffect(()=>{if(!t)return;let te=!1;return Promise.all([Ky(t),on("/api/config",t).then(Se=>Se.json())]).then(([Se,Te])=>{te||(ct({deviceDefault:Se.deviceName||"",localNodeId:Se.nodeId||"",localNameDefault:Se.localName||""}),ie(!!Te.readonlyDefault),be(Number.isInteger(Te.panelPort)?Te.panelPort:0),it(Te.nodePanelPorts&&typeof Te.nodePanelPorts=="object"&&!Array.isArray(Te.nodePanelPorts)?Te.nodePanelPorts:{}),(Se.firstRun===!0&&!Te.readonlyDefault||s)&&me(!0))}).catch(()=>{}),()=>{te=!0}},[t,s]);const[ht,dt]=k.useState({}),Rt=k.useRef(z);k.useEffect(()=>{Rt.current=z},[z]);const wt=k.useCallback(async()=>{try{const nt=await(await on("/api/sessions",t)).json();nt.error||N(nt.sessions||[])}catch{}let te=null,Se=null;try{te=await Xs(t)}catch(tt){Se=tt}const Te=Bf({fs:te,error:Se});Te.kind==="data"?(L(Te.cells),G(Te.capabilities),Y(!1),W(null)):Te.kind==="stale"?(Y(!0),W(null)):(L([]),G([]),Y(!1),W(Te.reason||""))},[t]);k.useEffect(()=>{let te=!1;const Se=async()=>{const tt=[[],...(Rt.current||[]).filter(St=>St.kind!=="vl"&&St.status==="up").map(St=>Array.isArray(St.route)&&St.route.length?St.route:[St.name])],nt=await Promise.all(tt.map(async St=>{try{const It=await Gx(t,St);return[wa(St),{hostCell:It&&typeof It.hostCell=="string"?It.hostCell:null,hostLease:It&&It.host&&typeof It.host.lease=="string"?It.host.lease:null,hostRevision:Number.isInteger(It&&It.revision)?It.revision:0}]}catch{return null}}));te||dt(St=>{let It=!1;const Sn={...St};for(const ri of nt)ri&&(Sn[ri[0]]=ri[1],It=!0);return It?Sn:St})};Se();const Te=setInterval(Se,4e3);return()=>{te=!0,clearInterval(Te)}},[t]),k.useEffect(()=>{if(!p)return;wt();const te=setInterval(wt,4e3);return()=>clearInterval(te)},[p,wt]);const _t=k.useCallback(async(te,Se=[])=>{const Te=wa(Se),tt=ht[Te]&&ht[Te].hostRevision||0;try{const nt=await Xx(t,te,tt,Se);dt(St=>({...St,[Te]:{hostCell:nt.hostCell||null,hostLease:nt.host&&typeof nt.host.lease=="string"?nt.host.lease:null,hostRevision:Number.isInteger(nt.revision)?nt.revision:tt}}))}catch(nt){window.alert(f(_v(nt)))}},[t,ht]),zt=k.useCallback(async(te=[])=>{const Se=wa(te),Te=ht[Se]&&ht[Se].hostRevision||0;try{const tt=await Qx(t,Te,te);return dt(nt=>({...nt,[Se]:{hostCell:tt.hostCell||null,hostLease:null,hostRevision:Number.isInteger(tt.revision)?tt.revision:Te}})),!0}catch(tt){return window.alert(f(_v(tt))),!1}},[t,ht]);k.useEffect(()=>{let te=!1;const Se=()=>{on("/api/config",t).then(tt=>tt.json()).then(tt=>{te||EP(tt.version,tt.uiVersion,"0.9.12")}).catch(()=>{})};Se();const Te=setInterval(Se,6e4);return()=>{te=!0,clearInterval(Te)}},[t]);const Je=new Set([...w.map(te=>te.name),...z.flatMap(te=>te.sessions.map(Se=>Se.key))]),J=Qi(X),Ne=te=>H(Se=>{const Te=Lw(te,D.localNodeId,M)||te,tt=vb(Se,Te);return tt===Se&&Qi(Se).length>=9&&D.setError(f("grid-full")),tt}),Ue=async(te,Se=[])=>{try{await Af(t,te,Se)}catch{return}const Te=Se.length?`${Se.join("/")}:${te}`:te;H(tt=>mc(tt,Te)),wt()},Oe=async(te,Se,Te=[])=>{try{await Wy(t,te,Se,Te)}catch{return}wt()},Le=async(te,Se,Te=[])=>{await Fy(t,{cell:te,enabled:!!Se},Te),wt()},Et=async te=>{if(!U)return;const{cell:Se}=U,Te=Array.isArray(U.route)?U.route:[];if(te.action==="up"){const nt=await Lf(t,{cell:Se,boot:!!te.boot,...te.engine?{engine:te.engine}:{},...te.model!==void 0?{model:te.model}:{},...te.permissionPolicy?{permissionPolicy:te.permissionPolicy}:{}},Te),St=Vf(nt);St&&D.setError(St.text)}else await lc(t,{cell:Se,boot:!!te.boot},Te);const tt=te.action==="up"?!!te.boot:te.boot?!1:!!U.boot;de({id:++ve.current,cell:Se,route:Te,enabled:tt}),wt()},kt=k.useCallback(te=>{de(Se=>(Se==null?void 0:Se.id)===te?null:Se)},[]),V=async te=>{if(!(!(te!=null&&te.direct)||fe)){pe(!0);try{await If(t,te.name,te.tunnelStatus==="up"?"down":"up")}finally{pe(!1)}}},ae=async(te,Se)=>{const Te=String(Se||"").trim();return!(te!=null&&te.direct)||!_o(Te)?!1:(await Yy(t,te.name,Te),!0)},ye=te=>{const Se=B.find(Te=>Te.id===te);if(!Se)return!1;try{const Te=window.open(zd(Se,t),"_blank");return Te&&(Te.opener=null),!!Te}catch{return!1}},Me=async te=>{if(!te||te===v)return;const Se=await D.select(te),Te=D.records.find(tt=>tt.id===te);y(te),H(Se),R(null),F(null);try{history.replaceState(null,"",zd(Te||te,null))}catch{}},De=async(te,Se)=>{const Te=await D.add(te,Se);await Me(Te.id)},Ee=async(te,Se)=>{const Te=await D.rename(te,Se);if(te===v){y(Te.id),H(bf(Te.layout,D.localNodeId,M)),R(null),F(null);try{history.replaceState(null,"",zd(Te,null))}catch{}}},Xe=async te=>{await D.remove(te),te===v&&await Me(D.localMainId)},yt=async(te,Se)=>{!Se||Se===v||(await D.addTileTo(Se,te),H(Te=>mc(Te,te)))};if(!t)return l.jsxs("div",{className:"nc-auth",children:[l.jsx("p",{children:f("auth-prompt")}),l.jsx("input",{onChange:te=>n(te.target.value.trim()),placeholder:"token"}),l.jsxs("label",{children:[l.jsx("input",{type:"checkbox",checked:u,onChange:te=>d(te.target.checked)})," ",f("remember-device")]}),l.jsx("button",{onClick:()=>{(u?localStorage:sessionStorage).setItem("nc_token",t)},children:"ok"})]});const $t=l.jsxs(l.Fragment,{children:[gn&&l.jsx(sP,{token:t,initialTab:xt,initialLocation:Dt,startNewCell:Ut,onClose:()=>{Yt(!1),Nt(!1),At("")}}),Qe&&l.jsx(rP,{token:t,initialPair:s,...Ge,onPairDone:a,onDone:()=>me(!1)}),l.jsx(dP,{token:t})]});if(!p)return T?l.jsxs(l.Fragment,{children:[l.jsx("div",{className:"nc-single-overlay",children:l.jsx(Ay,{peer:T,token:t,onBack:()=>j(null)})}),$t]}):S?l.jsxs(l.Fragment,{children:[l.jsx(Iy,{session:S.session,node:S.node,ownerId:S.ownerId,cellName:S.cellName,token:t,readonly:oe,panelPort:kc(S.node?S.node.split("/"):[],ke,_e),onBack:()=>x(null),onCellSwitcher:()=>hn(!0),cellSwitcherOpen:jt}),jt&&l.jsx(vP,{token:t,current:S,panelPort:_e,nodePanelPorts:ke,onPick:te=>{E(te),hn(!1)},onClose:()=>hn(!1)}),$t]}):l.jsxs(l.Fragment,{children:[l.jsx(Xk,{onPick:E,token:t,onSettings:re,onOpenVlSession:j,hostByRoute:ht,onDesignateCell:_t,onClearHostCell:zt}),$t]});const Be=b||!vt;return l.jsxs("div",{className:"nc-workspace",children:[Be&&l.jsx(w2,{sessions:w,cells:C,activeSessions:J,nodeGroups:z,token:t,onPeekOpen:()=>hn(!1),overlayOpen:jt,fleetCapabilities:I,fleetStale:K,fleetOff:Q,bootSettlement:ee,onBootSettlementApplied:kt,localNodeId:D.localNodeId,hostByRoute:ht,onDesignateCell:_t,onClearHostCell:zt,onPick:A,onAddTile:Ne,onPower:se,onBoot:Le,onBootError:te=>D.setError(String((te==null?void 0:te.message)||te)),onNodePower:V,onNodeRename:ae,onKill:Ue,onVisibility:Oe,onNew:()=>re("fleet",!0),onSettings:re,onOpenVlSession:j,width:Ve,collapsed:Ct,onResize:ut,onToggleCollapse:()=>dn(te=>!te)}),l.jsxs("div",{className:"nc-workspace-main",children:[l.jsx(tj,{decks:B,currentDeck:v,onCreate:De,onRename:Ee,onDelete:Xe,onReorder:D.reorder,onOpenWindow:ye,onNavigate:Me,saveState:D.saveState,error:D.error,sidebarVisible:Be,onToggleSidebar:b?null:()=>je(te=>!te)}),l.jsx(N2,{layout:X,onLayoutChange:H,token:t,readonly:oe,sessionsAlive:Je,focusSession:$,onFocus:R,onOpenSingle:A,decks:B,currentDeck:v,onSendToDeck:yt,cells:C,nodeGroups:z,panelPort:_e,nodePanelPorts:ke})]}),T&&l.jsx("div",{className:"nc-single-overlay",children:l.jsx(Ay,{peer:T,token:t,onBack:()=>j(null)})}),O&&l.jsx("div",{className:"nc-single-overlay",children:l.jsx(Iy,{session:O.session,node:O.node,ownerId:O.ownerId,cellName:dp({session:O.session,node:O.node,ownerId:O.ownerId,cells:C,nodeGroups:z}),token:t,readonly:oe,panelPort:kc(O.node?O.node.split("/"):[],ke,_e),onBack:()=>F(null)})}),U&&l.jsx(uc,{cell:U,token:t,route:Array.isArray(U.route)?U.route:[],onConfirm:Et,onClose:()=>se(null)}),$t]})}function IP(){Yn();const e=k.useSyncExternalStore(kP,My,My);if(!e.needed)return null;const t=e.kind==="install"?f("install-version-mismatch").replace("{v}",e.version):f("update-available").replace("{v}",e.version).replace(" "," ").trim();return l.jsxs("div",{className:"nc-update",role:"status","aria-live":"polite",children:[l.jsx("span",{className:"nc-update-msg",children:t}),e.kind==="reload"&&l.jsx("button",{className:"nc-update-btn",onClick:_S,children:f("reload")})]})}jP();ox.createRoot(document.getElementById("root")).render(l.jsxs(Z0.StrictMode,{children:[l.jsx(DP,{}),l.jsx(IP,{})]}));
|
|
93
|
+
`],{type:"application/json"}),A=URL.createObjectURL(F),T=document.createElement("a");T.href=A,T.download="nexuscrew-diagnostics.json",T.click(),URL.revokeObjectURL(A)}catch{b(f("diagnostics-export-failed"))}};return l.jsxs("div",{className:"nc-set-tab nc-diagnostics",children:[l.jsxs("label",{className:"nc-field",children:[f("diagnostics-target"),l.jsx("select",{value:u.key,onChange:F=>a(F.target.value),children:s.map(F=>l.jsxs("option",{value:F.key,children:[F.label,F.status!=="up"?` · ${F.status}`:""]},F.key))})]}),l.jsxs("div",{className:"nc-set-form nc-diag-controls",children:[l.jsx("div",{className:"nc-sheet-label",children:f("diagnostics-verbose")}),l.jsxs("div",{className:"nc-set-row",children:[l.jsx("select",{"aria-label":f("diagnostics-duration"),value:N,onChange:F=>C(Number(F.target.value)),disabled:n,children:[300,900,1800,3600].map(F=>l.jsxs("option",{value:F,children:[F/60," min"]},F))}),l.jsx("button",{type:"button",className:"nc-btn primary",disabled:n||(d==null?void 0:d.verbose)===!0,onClick:()=>$(()=>sv(e,!0,N,u.route)),children:f("enable")}),l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:n||(d==null?void 0:d.verbose)!==!0,onClick:()=>$(()=>sv(e,!1,N,u.route)),children:f("stop")})]}),l.jsx("small",{className:"nc-set-hint",children:d!=null&&d.verbose?f("diagnostics-expires").replace("{time}",new Date(d.expiresAt).toLocaleTimeString()):f("diagnostics-off")})]}),l.jsxs("div",{className:"nc-diag-filters",children:[l.jsxs("select",{"aria-label":f("diagnostics-level"),value:L,onChange:F=>I(F.target.value),children:[l.jsx("option",{value:"all",children:f("diagnostics-all-levels")}),["debug","info","warn","error"].map(F=>l.jsx("option",{value:F,children:F},F))]}),l.jsx("input",{"aria-label":f("diagnostics-component"),placeholder:f("diagnostics-component"),value:G,onChange:F=>K(F.target.value)})]}),l.jsxs("div",{className:"nc-set-row",children:[l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox",checked:S,onChange:F=>x(F.target.checked)})," ",f("diagnostics-pause")]}),l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox",checked:E,onChange:F=>w(F.target.checked)})," ",f("diagnostics-autoscroll")]})]}),l.jsx("pre",{ref:Q,className:"nc-diag-log","aria-label":f("diagnostics-log"),children:H||f("diagnostics-empty")}),l.jsxs("div",{className:"nc-set-row",children:[l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:R,children:f("copy")}),l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:O,children:f("diagnostics-export")}),l.jsx("button",{type:"button",className:"nc-btn danger",disabled:n,onClick:()=>{window.confirm(f("diagnostics-clear-confirm"))&&$(async()=>{const F=await Ux(e,u.route);return Y.current=0,v([]),F})},children:f("diagnostics-clear")})]}),y&&l.jsx("div",{className:"nc-err",children:y})]})}function iP({token:e,settings:t,readonly:n,refresh:s,roster:o,section:a,setSection:u}){const[d,p]=k.useState(null),[m,v]=k.useState(null),[y,b]=k.useState(!1),[S,x]=k.useState(!1),[E,w]=k.useState(null),[N,C]=k.useState(!0),[L,I]=k.useState(!1);k.useEffect(()=>{w(t&&t.update||null),C(!t||t.autoUpdate!==!1),I(!!(t&&t.alternateScreen))},[t]);const G=async()=>{p(null),v(null),x(!0);try{const R=await xx(e);v(R.note||"ok"),b(!1)}catch(R){p(String(R.message||R))}x(!1)},K=async()=>{p(null),v(null),x(!0);try{const R=await Bx(e);v(`${R.note||"ok"}${R.target?` (${R.target})`:""}`)}catch(R){p(String(R.message||R))}x(!1)},Y=async R=>{p(null),v(null),x(!0);try{await gh(e,{autoUpdate:R}),C(R),s&&await s()}catch(O){p(String(O.message||O))}x(!1)},Q=async R=>{p(null),v(null),x(!0);try{await gh(e,{alternateScreen:R}),I(R),s&&await s()}catch(O){p(String(O.message||O))}x(!1)},W=async()=>{p(null),v(null),x(!0);try{w(await zx(e))}catch(R){p(String(R.message||R))}x(!1)},X=async()=>{p(null),v(null),x(!0);try{const R=await $x(e);w(R),v(f("npm-update-restarting"))}catch(R){p(String(R.message||R))}x(!1)},H=()=>{window.confirm(f("composer-clear-confirm"))&&(p(null),a2()?(window.dispatchEvent(new Event(mf)),v(f("composer-clear-done"))):p(f("composer-clear-failed")))},$=t&&t.service;return l.jsxs("div",{className:"nc-set-tab",children:[l.jsx("div",{className:"nc-system-tabs",role:"tablist","aria-label":f("tab-system"),children:["general","diagnostics"].map(R=>l.jsx("button",{type:"button",role:"tab","aria-selected":a===R,className:`nc-set-tabbtn${a===R?" on":""}`,onClick:()=>u(R),children:f(`system-${R}`)},R))}),a==="general"&&l.jsxs(l.Fragment,{children:[l.jsxs("section",{className:"nc-system-group",children:[l.jsx("h3",{children:f("system-this-node")}),t&&l.jsxs("div",{className:"nc-set-info",children:["v",t.version," · ",t.platform," · :",t.port,l.jsx("br",{}),$&&$.installed?f("service-installed"):f("service-missing"),$&&$.installed?` · ${$.active?f("service-active"):f("service-inactive")}`:"",$?` · boot ${$.boot?"on":"off"}`:""]}),l.jsx("div",{className:"nc-set-row",children:l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:n||S,title:n?f("settings-readonly"):"",onClick:K,children:f("service-regenerate")})}),l.jsx(JR,{token:e,readonly:n}),l.jsx(ZR,{})]}),l.jsxs("section",{className:"nc-system-group",children:[l.jsx("h3",{children:f("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||S||E&&!E.supported,onChange:R=>Y(R.target.checked)}),l.jsxs("span",{children:[l.jsx("b",{children:f("npm-auto-update")}),l.jsx("small",{children:f("npm-auto-update-help")})]})]}),E&&l.jsxs("div",{className:"nc-set-info",children:[f("npm-update-current")," v",E.current,E.latest?` · ${f("npm-update-latest")} v${E.latest}`:""," · ",f(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||S||!E||!E.supported,onClick:W,children:f("npm-update-check")}),E&&E.available&&l.jsx("button",{type:"button",className:"nc-btn primary",disabled:n||S||E.phase==="installing",onClick:X,children:f("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:f("system-security")}),l.jsx("div",{className:"nc-set-row",children:l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:n||S,title:n?f("settings-readonly"):"",onClick:()=>{p(null),v(null),b(!0)},children:f("token-rotate")})})]}),l.jsxs("section",{className:"nc-system-group",children:[l.jsx("h3",{children:f("system-local-data")}),l.jsxs("div",{className:"nc-set-form",children:[l.jsx("div",{className:"nc-sheet-label",children:f("composer-clear-data")}),l.jsx("small",{className:"nc-set-hint",children:f("composer-clear-data-help")}),l.jsx("div",{className:"nc-set-row",children:l.jsx("button",{type:"button",className:"nc-btn ghost",onClick:H,children:f("composer-clear-data")})})]})]})]}),a==="diagnostics"&&l.jsxs("section",{className:"nc-system-group nc-system-diagnostics",children:[l.jsx("h3",{children:f("system-diagnostics")}),l.jsxs("div",{className:"nc-set-form nc-alternate-screen-settings",children:[l.jsx("div",{className:"nc-sheet-label",children:f("system-terminal")}),l.jsxs("label",{className:"nc-check",children:[l.jsx("input",{type:"checkbox","aria-label":f("alternate-screen"),checked:L,disabled:n||S,onChange:R=>Q(R.target.checked)}),l.jsxs("span",{children:[l.jsx("b",{children:f("alternate-screen")}),l.jsx("small",{children:f("alternate-screen-help")})]})]})]}),l.jsx(nP,{token:e,roster:o,readonly:n})]}),y&&l.jsxs("div",{className:"nc-set-confirm",children:[l.jsx("div",{children:f("token-rotate-explain")}),l.jsxs("div",{className:"nc-sheet-actions",children:[l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:S,onClick:()=>b(!1),children:f("cancel")}),l.jsx("button",{type:"button",className:"nc-btn primary",disabled:S,onClick:G,children:f("confirm")})]})]}),m&&l.jsx("div",{className:"nc-set-note",children:m}),d&&l.jsx("div",{className:"nc-err",children:d})]})}function sP({token:e,onClose:t,initialTab:n="nodes",initialLocation:s="",startNewCell:o=!1}){Yn();const a=n==="diagnostics"?"diagnostics":"general",[u,d]=k.useState(n==="diagnostics"?"system":n),p=k.useRef(null),m=k.useRef(null),[v,y]=k.useState({start:!1,end:!1}),[b,S]=k.useState(a),[x,E]=k.useState(null),[w,N]=k.useState([]),[C,L]=k.useState([]),[I,G]=k.useState(!1),[K,Y]=k.useState(null),[Q,W]=k.useState(0),X=zf(e,!0,Q),H=k.useCallback(()=>{const R=p.current;if(!R)return;const O=R.scrollWidth>R.clientWidth+1,F={start:O&&R.scrollLeft>1,end:O&&R.scrollLeft+R.clientWidth<R.scrollWidth-1};y(A=>A.start===F.start&&A.end===F.end?A:F)},[]);k.useEffect(()=>{const R=p.current;if(!R)return;const O=typeof ResizeObserver=="function"?new ResizeObserver(H):null;return O==null||O.observe(R),window.addEventListener("resize",H),H(),()=>{O==null||O.disconnect(),window.removeEventListener("resize",H)}},[H]),k.useEffect(()=>{var O,F;(F=(O=m.current)==null?void 0:O.scrollIntoView)==null||F.call(O,{behavior:"smooth",block:"nearest",inline:"nearest"});const R=window.requestAnimationFrame?window.requestAnimationFrame(H):setTimeout(H,0);return()=>{window.cancelAnimationFrame?window.cancelAnimationFrame(R):clearTimeout(R)}},[u,H]);const $=k.useCallback(async()=>{var R;try{const O=await Ky(e);E(O),Y(null)}catch(O){Y(String(O.message||O))}try{const F=(await wx(e)).peers||[];let A=[],T=[];try{const[j,z]=await Promise.all([on("/api/config",e).then(U=>U.json()).catch(()=>null),Vy(e).catch(()=>null)]),M=j&&typeof j.instanceId=="string"?j.instanceId:"",D=[{instanceId:M||null,route:[],label:null},...nb(z,M)],B=await Promise.all(D.map(async U=>{try{return{ok:!0,peers:((await qy(e,U.route)).nodes||[]).map(de=>tb(de,U)).filter(Boolean)}}catch(se){return{ok:!1,owner:U,error:se}}}));for(const U of B){if(U.ok){A.push(...U.peers);continue}U.owner.route.length!==0&&T.push({instanceId:U.owner.instanceId,label:U.owner.label,route:U.owner.route,failure:/timeout/i.test(String(((R=U.error)==null?void 0:R.message)||U.error))?"timeout":"unreachable"})}}catch{}L(T),N([...F,...A])}catch(O){Y(String(O.message||O))}},[e]);return k.useEffect(()=>{$();const R=setInterval($,5e3);return()=>clearInterval(R)},[$]),k.useEffect(()=>{let R=!1;return on("/api/config",e).then(O=>O.json()).then(O=>{R||G(!!O.readonlyDefault)}).catch(()=>{}),()=>{R=!0}},[e]),l.jsx("div",{className:"nc-set-overlay",onClick:t,children:l.jsxs("div",{className:"nc-set-panel",onClick:R=>R.stopPropagation(),children:[l.jsxs("div",{className:"nc-set-head",children:[l.jsx(lt,{name:"gear",size:18}),l.jsx("b",{children:f("settings")}),l.jsx("button",{type:"button",className:"nc-set-close",onClick:t,title:f("close"),children:l.jsx(lt,{name:"x",size:18})})]}),I&&l.jsx("div",{className:"nc-set-readonly",children:f("settings-readonly")}),K&&l.jsx("div",{className:"nc-err",children:K}),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:p,onScroll:H,children:["nodes","fleet","audio","input","system"].map(R=>l.jsx("button",{ref:u===R?m:null,type:"button",className:`nc-set-tabbtn${u===R?" on":""}`,onClick:()=>d(R),children:f(`tab-${R}`)},R))})}),l.jsxs("div",{className:"nc-set-body",children:[u==="nodes"&&l.jsx(QR,{token:e,nodes:w,roster:X,settings:x,readonly:I,vlUnavailable:C,refresh:$,refreshAliases:()=>W(R=>R+1)}),u==="fleet"&&l.jsx(AR,{token:e,readonly:I,startNewCell:o,initialLocation:s,targets:X.map(R=>({route:R.route,label:R.label||R.name,status:R.status}))}),u==="audio"&&l.jsx(eP,{token:e,readonly:I,nodes:w,settings:x}),u==="input"&&l.jsx(tP,{}),u==="system"&&l.jsx(iP,{token:e,settings:x,readonly:I,refresh:$,roster:X,section:b,setSection:S})]})]})})}function rP({token:e,initialPair:t,deviceDefault:n="",localNodeId:s="",localNameDefault:o="",onPairDone:a,onDone:u}){Yn();const[d,p]=k.useState(t?"pair":"welcome"),[m,v]=k.useState(!1),[y,b]=k.useState(null),[S,x]=k.useState(null),E=async()=>{v(!0),b(null);try{await gh(e,{wizardDone:!0}),a&&a(),u()}catch(w){b(String(w.message||w)),v(!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:f("wizard-title")}),l.jsx("small",{children:f("hydra-simple")})]}),d==="welcome"&&l.jsxs("div",{className:"nc-wiz-body",children:[l.jsx("div",{className:"nc-wiz-done",children:f("local-ready")}),l.jsxs("div",{className:"nc-sheet-actions",children:[l.jsx("button",{className:"nc-btn ghost",disabled:m,onClick:E,children:f("local-only")}),l.jsx("button",{className:"nc-btn primary",disabled:m,onClick:()=>p("pair"),children:f("add-node")})]})]}),d==="pair"&&l.jsxs("div",{className:"nc-wiz-body",children:[l.jsx(Gw,{token:e,initial:t||"",autoStart:!!t,deviceDefault:n,localNodeId:s,localNameDefault:o,onBusyChange:v,onSuccess:async w=>{x(w&&w.authorizedKeys?{line:w.authorizedKeys,note:w.authorizedKeysNote||""}:null),a&&a(),p("done")}}),l.jsx("div",{className:"nc-sheet-actions",children:l.jsx("button",{className:"nc-btn ghost",disabled:m,onClick:()=>{a&&a(),p("welcome")},children:f("back")})})]}),d==="done"&&l.jsxs("div",{className:"nc-wiz-body",children:[l.jsx("div",{className:"nc-wiz-done",children:f("node-connected")}),S&&l.jsx(bp,{line:S.line,note:S.note}),l.jsx("div",{className:"nc-sheet-actions",children:l.jsx("button",{className:"nc-btn primary",disabled:m,onClick:E,children:f("finish")})})]}),y&&l.jsx("div",{className:"nc-err",children:y})]})})}function oP(e,t){if(typeof EventSource>"u"||!e)return()=>{};const n=new EventSource(`/api/events?token=${encodeURIComponent(e)}`);return n.onmessage=s=>{try{const o=JSON.parse(s.data);o&&typeof o=="object"&&typeof o.type=="string"&&t(o)}catch{}},()=>{try{n.close()}catch{}}}const aP=6e3,lP=12e3;function cP({n:e,onClose:t}){return l.jsxs("div",{className:`nc-ntf-toast${e.urgency==="high"?" high":""}`,role:"status","aria-live":"polite",children:[l.jsxs("div",{className:"nc-ntf-toast-txt",children:[l.jsx("b",{children:e.title}),e.body&&l.jsx("small",{children:e.body}),e.session&&l.jsx("span",{className:"nc-ntf-from",children:e.session})]}),l.jsx("button",{type:"button",className:"nc-ntf-x",onClick:t,title:f("close"),children:l.jsx(lt,{name:"x",size:14})})]})}function uP({ask:e,token:t,onAnswered:n,onDismiss:s}){const[o,a]=k.useState(""),[u,d]=k.useState(!1),[p,m]=k.useState(null),[v,y]=k.useState(!1),b=async x=>{const E=String(x||"").trim();if(!(!E||u)){m(null),d(!0);try{await Kx(t,e.id,E),n(e.id)}catch(w){m(String(w.message||w))}d(!1)}},S=async()=>{if(!v){y(!0);try{await qx(t,e.id),s(e.id)}catch{y(!1)}}};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:e.session}),l.jsxs("code",{className:"nc-ask-id",children:["#",e.id]}),l.jsx("button",{type:"button",className:"nc-ask-dismiss",title:f("ask-dismiss"),"aria-label":f("ask-dismiss"),disabled:v,onClick:S,children:l.jsx(lt,{name:"x",size:14})})]}),l.jsx("div",{className:"nc-ask-q",children:e.question}),Array.isArray(e.options)&&e.options.length>0&&l.jsx("div",{className:"nc-ask-opts",children:e.options.map(x=>l.jsx("button",{type:"button",className:"nc-btn ghost",disabled:u,onClick:()=>b(x),children:x},x))}),l.jsxs("div",{className:"nc-ask-reply",children:[l.jsx("textarea",{rows:2,placeholder:f("ask-reply-ph"),value:o,disabled:u,onChange:x=>a(x.target.value)}),l.jsx("button",{type:"button",className:"nc-btn primary",disabled:u||!o.trim(),onClick:()=>b(o),children:f("send")})]}),p&&l.jsx("div",{className:"nc-err",children:p})]})}function dP({token:e}){const[t]=Yn(),[n]=hS(),[s,o]=k.useState([]),[a,u]=k.useState([]),[d,p]=k.useState(()=>{try{return/(?:^|[#&])ask=/.test(location.hash)}catch{return!1}}),m=k.useRef(0),v=k.useRef(null);v.current||(v.current=YR());const y=k.useRef({enabled:n,lang:t});y.current={enabled:n,lang:t};const b=k.useCallback(w=>{o(N=>N.filter(C=>C.key!==w))},[]),S=k.useCallback(w=>{const N=`t${m.current+=1}`;o(L=>[...L.slice(-3),{...w,key:N}]),setTimeout(()=>b(N),w.urgency==="high"?lP:aP);const C=y.current;if(C.enabled)try{v.current.enqueue(w,UR(w,C.lang))}catch{}},[b]);k.useEffect(()=>{n||v.current.stop()},[n]),k.useEffect(()=>{const w=()=>{(document.visibilityState!=="visible"||!document.hasFocus())&&v.current.stop()},N=()=>v.current.stop();return document.addEventListener("visibilitychange",w),window.addEventListener("blur",w),window.addEventListener(xf,N),()=>{document.removeEventListener("visibilitychange",w),window.removeEventListener("blur",w),window.removeEventListener(xf,N),typeof v.current.dispose=="function"?v.current.dispose():v.current.stop()}},[]),k.useEffect(()=>{if(!e)return;let w=!1;Wx(e).then(C=>{w||u(C.asks||[])}).catch(()=>{});const N=oP(e,C=>{C.type==="notify"?S(C):C.type==="ask"&&C.ask&&C.ask.id?u(L=>L.some(I=>I.id===C.ask.id)?L:[...L,C.ask]):C.type==="ask-answered"&&C.id?u(L=>L.filter(I=>I.id!==C.id)):C.type==="ask-dismissed"&&C.id&&u(L=>L.filter(I=>I.id!==C.id))});return()=>{w=!0,N()}},[e,S]);const x=w=>u(N=>N.filter(C=>C.id!==w)),E=w=>u(N=>N.filter(C=>C.id!==w));return l.jsxs(l.Fragment,{children:[s.length>0&&l.jsx("div",{className:"nc-ntf-toasts",children:s.map(w=>l.jsx(cP,{n:w,onClose:()=>b(w.key)},w.key))}),a.length>0&&!d&&l.jsxs("button",{type:"button",className:"nc-ask-badge",onClick:()=>p(!0),title:f("asks-title"),children:["? ",l.jsx("span",{className:"nc-ask-count",children:a.length})]}),a.length>0&&d&&l.jsxs("div",{className:"nc-ask-panel",children:[l.jsxs("div",{className:"nc-ask-panel-head",children:[l.jsx("b",{children:f("asks-title")}),l.jsx("span",{className:"nc-ask-count",children:a.length}),l.jsx("button",{type:"button",className:"nc-ntf-x",onClick:()=>p(!1),title:f("close"),children:l.jsx(lt,{name:"x",size:16})})]}),l.jsx("div",{className:"nc-ask-panel-body",children:a.map(w=>l.jsx(uP,{ask:w,token:e,onAnswered:x,onDismiss:E},w.id))})]})]})}const hP=4e3;async function fP(e){const t=await on("/api/sessions",e);if((t==null?void 0:t.ok)===!1)throw new Error(`HTTP ${t.status}`);const n=await t.json();if(!Array.isArray(n==null?void 0:n.sessions))throw new Error("invalid sessions payload");return n.sessions}async function hh(e,t=[]){var d;const[n,s]=await Promise.allSettled([t.length?Tf(e,t):fP(e),Xs(e,t)]),o=n.status==="fulfilled"&&Array.isArray((d=n.value)==null?void 0:d.sessions)?n.value.sessions:Array.isArray(n.value)?n.value:null,a=s.status==="fulfilled"?s.value:null,u=(a==null?void 0:a.available)===!0&&Array.isArray(a.cells)?a.cells:null;return{sessions:o,cells:u,fresh:Array.isArray(o)&&Array.isArray(u)}}function fS(e,t,n){return n===!0&&(e==null?void 0:e.degraded)!==!0&&(e==null?void 0:e.active)===!0&&e.tmux!==!1&&!!e.tmuxSession&&(t||[]).some(s=>(s==null?void 0:s.name)===e.tmuxSession)}function pP(e){const t=new Map((e.sessions||[]).map(o=>[o.name,o])),n=[],s=(o,a,u,d=[],p="")=>{const m=new Map((a||[]).map(v=>[v.name,v]));for(const v of o||[]){const y=m.get(v.tmuxSession)||{},b=Uf(v,y),S=fS(v,a,u);n.push({key:ka(d,v.tmuxSession||v.cell),session:v.tmuxSession,route:d,cellName:v.cell,label:v.cell,node:d.length?d.join("/"):"",nodeLabel:p,live:S,selectable:S,verified:u===!0,working:b.working,degraded:!!v.degraded,active:v.active===!0,activity:y.activity||v.activity||0,subtitle:b.subtitle,preview:y.preview||v.preview||"",telemetry:y.telemetry||null,panelUrl:v.panelUrl||""})}};s(e.cells,[...t.values()],e.localFresh===!0);for(const o of e.nodeGroups||[]){const a=Array.isArray(o.route)?o.route:[];o.kind==="vl"||!a.length||s(o.cells,o.sessions,o.switcherFresh===!0,a,o.label||o.name||"")}return n}function mP(e){const t=new Map,n=Array.isArray(e.sessions)?e.sessions:[],s=Array.isArray(e.cells)?e.cells:[],o=new Map(n.map(u=>[u.name,u])),a=new Set(s.map(u=>u.tmuxSession).filter(Boolean));t.set("local",Wf(s,n.filter(u=>!a.has(u.name)),o));for(const u of e.nodeGroups||[]){const d=Array.isArray(u.route)?u.route:[];if(u.kind==="vl"||!d.length)continue;const p=Array.isArray(u.cells)?u.cells:[],m=Array.isArray(u.sessions)?u.sessions:[],v=new Set(p.map(y=>y.tmuxSession).filter(Boolean));t.set(d.join("/"),fc({...u,route:d,cells:p,sessions:m,unmanaged:m.filter(y=>!v.has(y.name))}).rawItems)}return t}function gP(e,t,n,s){return[...new Set(e.map(a=>a.node||"local"))].flatMap(a=>{const u=e.filter(v=>(v.node||"local")===a),d=new Map((t.get(a)||[]).map(v=>[v.key,v])),p=new Map(u.map(v=>[v.key,v])),m=u.map(v=>{const y=d.get(v.key);return{...v,label:(y==null?void 0:y.label)||v.label,live:(y==null?void 0:y.live)??v.live,fresh:(y==null?void 0:y.fresh)===!0,activity:(y==null?void 0:y.activity)??v.activity}});return qs(m,n,"all",ms(s,a)).map(v=>p.get(v.key))})}function vP({token:e,current:t,onPick:n,onClose:s,panelPort:o=0,nodePanelPorts:a={}}){const[u,d]=k.useState(wv),[p,m]=k.useState(!1),[v,y]=k.useState(!1),[b,S]=k.useState(""),[x,E]=k.useState(null),[w,N]=k.useState(""),[C,L]=k.useState(""),I=k.useRef(null),G=k.useRef(null),K=k.useMemo(()=>pP(u),[u]),Y=k.useMemo(()=>mP(u),[u]),{pins:Q,orders:W,canMoveRoster:X,moveRoster:H,stepRoster:$}=Ff(),R=k.useMemo(()=>gP(K,Y,Q,W),[K,Y,Q,W]),O=k.useMemo(()=>p?R:R.filter(M=>M.selectable||M.degraded&&M.active),[R,p]),F=k.useMemo(()=>K.find(M=>M.key===w&&M.selectable),[K,w]),A=k.useMemo(()=>x?K.find(M=>M.key===x.key):null,[K,x]);k.useEffect(()=>{var B;const M=document.activeElement;(B=G.current)==null||B.focus();const D=U=>{U.key==="Escape"&&s()};return document.addEventListener("keydown",D),()=>{var U;document.removeEventListener("keydown",D),(U=M==null?void 0:M.focus)==null||U.call(M)}},[s]),k.useEffect(()=>{let M=!0,D=!1;const B=async()=>{if(D)return;D=!0;const se=wv(),ee=Array.isArray(se.nodeGroups)?se.nodeGroups:[],de=hh(e),ve=je=>je.kind!=="vl"&&Array.isArray(je.route)&&je.route.length>0,fe=await Promise.all(ee.filter(ve).map(async je=>({group:je,result:await hh(e,je.route)}))),pe=await de;if(!M)return;const Ve=new Map(fe.map(({group:je,result:Ct})=>[JSON.stringify(je.route||[]),Ct])),ut=ee.map(je=>{if(!ve(je))return{...je,switcherFresh:!1};const Ct=Ve.get(JSON.stringify(je.route||[]));return Ct?{...je,sessions:Ct.sessions||je.sessions||[],cells:Ct.cells||je.cells||[],switcherFresh:Ct.fresh}:{...je,switcherFresh:!1}}),vt=bb({...se,sessions:pe.sessions||se.sessions||[],cells:pe.cells||se.cells||[],localFresh:pe.fresh,nodeGroups:ut,refreshedAt:Date.now()});d(vt),y(!0),D=!1};B();const U=setInterval(B,hP);return()=>{M=!1,clearInterval(U)}},[e]);const T=M=>M.degraded?f("cell-degraded"):M.verified?M.selectable?M.working?f("cell-working"):f("cell-idle"):f("cell-off"):f("cell-switcher-not-confirmed"),j=M=>{if(S(""),!M.selectable){S(M.verified?f("cell-switcher-not-active"):f("cell-switcher-not-confirmed"));return}N(M.key)},z=async()=>{const M=F;if(!M){S(f("cell-switcher-select"));return}S(""),L(M.key);try{const D=await hh(e,M.route),B=(D.cells||[]).find(U=>(U==null?void 0:U.cell)===M.cellName&&(U==null?void 0:U.tmuxSession)===M.session);if(D.fresh!==!0){S(f("cell-switcher-verify-failed"));return}if(!fS(B,D.sessions,D.fresh)){S(f("cell-switcher-not-active"));return}n({session:M.session,...M.node?{node:M.node}:{},cellName:M.cellName}),s()}catch{S(f("cell-switcher-verify-failed"))}finally{L("")}};return l.jsx("div",{className:"nc-cell-switcher-backdrop",onClick:s,children:l.jsxs("aside",{ref:I,className:"nc-cell-switcher",role:"dialog","aria-label":f("fleet-cells"),tabIndex:-1,onClick:M=>M.stopPropagation(),children:[l.jsxs("div",{className:"nc-cell-switcher-list",children:[!v&&l.jsx("div",{className:"nc-empty",role:"status",children:f("cell-switcher-refreshing")}),v&&O.length===0&&l.jsx("div",{className:"nc-empty",role:"status",children:f("cell-switcher-empty-active")}),O.map(M=>{const D=(t==null?void 0:t.session)===M.session&&((t==null?void 0:t.node)||"")===M.node,B=w===M.key,U=T(M),se=vf(f,M.activity),ee=_f(f,M.telemetry),de=[se,ee].filter(Boolean).join(" · "),ve=M.node||"local",fe=Y.get(ve)||K.filter(pe=>(pe.node||"local")===ve);return l.jsxs("div",{className:`nc-cell-switcher-row${D?" current":""}${B?" selected":""}${M.selectable?"":" off"}`,"data-roster-key":M.key,"data-position":ve,children:[l.jsx(Yi,{position:ve,itemKey:M.key,label:M.cellName,canMove:X,onMove:(pe,Ve)=>H(ve,pe,Ve,fe),onStep:pe=>$(ve,M.key,pe,fe)}),l.jsx("button",{type:"button",className:"nc-cell-switcher-peek",title:f("cell-peek"),"aria-label":`${f("cell-peek")}: ${M.cellName}`,onClick:pe=>{pe.stopPropagation(),E({key:M.key,source:"preview"})},children:l.jsx("span",{className:`nc-cell-switcher-dot${M.degraded?" warn":M.live?` on${M.working?" working":""}`:""}`})}),l.jsxs("span",{className:"nc-cell-switcher-acts",children:[l.jsx("button",{type:"button",className:"nc-cell-switcher-act",title:f("cell-peek-stream"),"aria-label":`${f("cell-peek-stream")}: ${M.cellName}`,onClick:pe=>{pe.stopPropagation(),E({key:M.key,source:"stream"})},children:"▶"}),M.panelUrl&&l.jsx("button",{type:"button",className:"nc-cell-switcher-act",title:f("cell-peek-panel"),"aria-label":`${f("cell-peek-panel")}: ${M.cellName}`,onClick:pe=>{pe.stopPropagation(),E({key:M.key,source:"panel"})},children:"▣"})]}),l.jsx("button",{type:"button",className:"nc-cell-switcher-row-select","aria-current":D?"true":void 0,"aria-pressed":B,"aria-disabled":!M.selectable,disabled:C===M.key,onClick:()=>j(M),children:l.jsxs("span",{className:"nc-cell-switcher-copy",children:[l.jsx("b",{children:M.cellName}),l.jsx("small",{className:"nc-cell-switcher-state",children:U}),l.jsx("small",{children:[M.nodeLabel,M.subtitle].filter(Boolean).join(" · ")}),de&&l.jsx("small",{className:"nc-cell-switcher-telemetry",children:de})]})})]},M.key)})]}),b&&l.jsx("div",{className:"nc-cell-switcher-notice",role:"status",children:b}),x&&A&&l.jsx(Cw,{row:A,token:e,initialSource:x.source,panelPort:kc(A.route||[],a,o),onClose:()=>E(null)}),l.jsx("div",{className:"nc-cell-switcher-actions",children:l.jsx("button",{type:"button",className:"nc-cell-switcher-open",disabled:!F||!!C,onClick:z,children:F?`${f("cell-switcher-open")}: ${F.cellName}`:f("cell-switcher-select")})}),l.jsxs("div",{className:"nc-cell-switcher-controls",children:[l.jsx("b",{children:f("fleet-cells")}),l.jsx("button",{type:"button",className:"nc-cell-switcher-filter","aria-pressed":p,onClick:()=>{S(""),m(M=>!M)},children:f(p?"cell-switcher-show-active":"cell-switcher-show-all")}),l.jsx("button",{ref:G,type:"button",className:"nc-cell-switcher-close","aria-label":f("cell-switcher-close"),title:f("cell-switcher-close"),onClick:s,children:"×"})]})]})})}const _P=2e3;function yP(e){if(e.kind==="gap")return`${f("vl-events-gap")} ${e.count||"?"}`;if(e.kind==="truncate")return f("vl-events-truncated");if(e.kind==="turn_end")return f("vl-events-turn-end");if(e.kind==="done")return f("vl-events-done");if(e.kind==="writer_epoch")return f("vl-events-writer-epoch");if(e.kind==="tool_start")return`${f("vl-events-tool")} ${e.name||""}`.trim();if(e.kind==="tool_end"){const t=e.isError?f("vl-events-tool-failed"):f("vl-events-tool-ok");return`${f("vl-events-tool")} ${e.name||""} — ${t}`.trim()}return e.kind==="usage"?e.text||f("vl-events-usage"):e.text||""}function bP({token:e,nodeId:t,route:n=[]}){const[s,o]=k.useState([]),[a,u]=k.useState(!1),d=k.useRef(0),p=k.useRef(!1);return k.useEffect(()=>{let m=!0;d.current=0,p.current=!1,o([]);const v=async()=>{if(!p.current){p.current=!0;try{const S=await Sx(e,t,d.current,n);if(!m)return;u(!1);const E=(Array.isArray(S==null?void 0:S.events)?S.events:[]).filter(w=>Number.isSafeInteger(w==null?void 0:w.seq)&&w.seq>d.current);E.length&&(o(w=>w.concat(E).slice(-500)),d.current=E[E.length-1].seq),Number.isSafeInteger(S==null?void 0:S.cursor)&&S.cursor>d.current&&(d.current=S.cursor)}catch{m&&u(!0)}finally{p.current=!1}}},y=()=>{v().catch(()=>{})};y();const b=setInterval(y,_P);return()=>{m=!1,clearInterval(b)}},[e,t,JSON.stringify(n)]),l.jsxs("div",{className:"nc-vl-events",children:[a&&l.jsx("div",{className:"nc-set-hint nc-vl-events-stale",children:f("vl-events-stale")}),s.length===0&&!a&&l.jsx("small",{className:"nc-set-hint","data-testid":"vl-events-empty",children:f("vl-events-empty")}),s.length>0&&l.jsx("ol",{className:"nc-vl-events-list",children:s.map(m=>l.jsx("li",{"data-testid":`vl-ev-${m.seq}`,className:`nc-vl-ev nc-vl-ev-${m.kind}${m.isError?" error":""}${m.kind==="gap"?" gap":""}`,children:yP(m)},`${m.seq}-${m.kind}`))})]})}function Ay({peer:e,token:t,onBack:n}){var s;return Yn(),e?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:f("back"),children:[l.jsx(lt,{name:"chevronLeft",size:18}),l.jsx("span",{className:"nc-bar-label",children:f("back")})]}),l.jsxs("span",{className:"nc-bar-center",children:[l.jsx("b",{title:e.label,children:e.label}),((s=e.session)==null?void 0:s.profile)&&l.jsxs("small",{className:"nc-bar-sub",children:[e.session.profile," · ",f("vl-events-title")]})]}),l.jsx("span",{className:"nc-bar-right"})]}),l.jsx("div",{className:"nc-vl-session-body",children:l.jsx(bP,{token:t,nodeId:e.nodeId,route:e.route||[]})})]}):null}const fh=e=>Qi(xr(e)).length===0,ph=e=>Array.isArray(e)?e.join("/"):"";function wP(e){const t=new Set,n=[];for(const s of Array.isArray(e)?e:[])!s||!gi.test(String(s.instanceId||""))||!Array.isArray(s.route)||!s.route.length||t.has(s.instanceId)||(t.add(s.instanceId),n.push({instanceId:s.instanceId,route:[...s.route],label:String(s.label||s.name||s.route.join(" › ")),status:s.status||"offline"}));return n.sort((s,o)=>s.label.localeCompare(o.label))}function ha(e){return{instanceId:e.ownerId,route:e.ownerRoute||[],label:e.ownerLabel,status:e.available===!1?"offline":"up"}}function vr(e,t,n,s=!1,o=!0){const a=t.instanceId;return{...e,id:po(s?null:a,e.name),ownerId:a,ownerRoute:s?[]:[...t.route],ownerLabel:s?"Local":t.label,local:s,available:o,ownerTopology:Array.isArray(n)?n:[],layout:yf(e.layout,a,n)}}function SP(e,t,n,s,o=[]){const[a,u]=k.useState([]),[d,p]=k.useState(!1),[m,v]=k.useState("idle"),[y,b]=k.useState(""),[S,x]=k.useState(""),E=k.useRef([]),w=k.useRef([]),N=k.useRef(""),C=k.useRef(t),L=k.useRef(n),I=k.useRef(!1),G=k.useRef(!0),K=k.useRef(""),Y=k.useMemo(()=>wP(o),[o]),Q=Y.map(M=>`${M.instanceId}:${ph(M.route)}:${M.status}:${M.label}`).join("|");w.current=Y,L.current=n,C.current=t,E.current=a;const W=k.useCallback(M=>bf(M.layout,N.current,w.current),[]),X=k.useCallback((M,D=!0,B=C.current)=>{const U=O_(M,Gl()),se=E.current.some(de=>de.id===B);E.current=U,u(U);const ee=U.find(de=>de.id===B);if(D&&ee){G.current=!0;const de=W(ee);s(de),ee.local&&B2(ee.name,de)}else se&&!ee&&(G.current=!0,s(fo()),b("deck non più condiviso dal nodo owner"));T2(U.filter(de=>de.local).map(de=>de.name))},[s,W]),H=k.useCallback(async M=>{let D=await $l(e);const B=D.decks.find(U=>U.name==="main");if(D.decks.length===1&&B&&B.revision===0&&fh(B.layout)){const U=M2(),se=xr(wf("main")||fo());if(!fh(se)){const ee=yf(se,M,[]);D.decks[0]=await Fl(e,"main",ee,0,[])}for(const ee of U.filter(de=>de!=="main"))try{let de=await rv(e,ee,[]);const ve=xr(wf(ee)||fo());fh(ve)||(de=await Fl(e,ee,yf(ve,M,[]),de.revision,[]))}catch{}D=await $l(e)}return D},[e]),$=k.useCallback(async({migrate:M=!1}={})=>{const D=await Df(e,[]),B=gi.test(String(D.instanceId||""))?D.instanceId:"";if(!B)throw new Error("instanceId locale non disponibile");N.current=B,x(B);const[U,se]=await Promise.all([M?H(B):$l(e),tv(e,[]).catch(()=>({nodes:[]}))]),ee={instanceId:B,route:[],label:"Local"},de=U.decks.map(fe=>vr(fe,ee,se.nodes,!0,!0)),ve=E.current;return await Promise.all(w.current.map(async fe=>{if(fe.status!=="up"){de.push(...ve.filter(pe=>!pe.local&&pe.ownerId===fe.instanceId).map(pe=>({...pe,ownerRoute:[...fe.route],ownerLabel:fe.label,available:!1})));return}try{const[pe,Ve]=await Promise.all([$l(e,fe.route),tv(e,fe.route).catch(()=>({nodes:[]}))]);de.push(...pe.decks.map(ut=>vr(ut,fe,Ve.nodes,!1,!0)))}catch{de.push(...ve.filter(Ve=>!Ve.local&&Ve.ownerId===fe.instanceId).map(Ve=>({...Ve,ownerRoute:[...fe.route],ownerLabel:fe.label,available:!1})))}})),de.sort((fe,pe)=>fe.local===pe.local?fe.ownerLabel.localeCompare(pe.ownerLabel)||(fe.name==="main"?-1:pe.name==="main"?1:fe.name.localeCompare(pe.name)):fe.local?-1:1),de},[e,H,Q]);k.useEffect(()=>{if(!e)return;let M=!1;const D=K.current!==e;return K.current=e,$({migrate:D}).then(B=>{if(M)return;const U=E.current.find(de=>de.id===C.current),se=B.find(de=>de.id===C.current),ee=se&&(!U||se.revision>U.revision||U.available!==se.available||ph(U.ownerRoute)!==ph(se.ownerRoute));X(B,D||!!ee&&!I.current),p(!0),se&&b("")}).catch(B=>{M||(p(!0),b(String(B.message||B)))}),()=>{M=!0}},[X,$,Q,e]);const R=k.useCallback(async(M=C.current)=>{if(!d||!I.current)return!0;const D=E.current.find(B=>B.id===M);if(!D)return b(`deck inesistente: ${M}`),!1;if(D.available===!1)return b(`nodo owner offline: ${D.ownerLabel}`),!1;v("saving");try{const B=D_(xr(L.current),D.ownerId,D.ownerTopology),U=await Fl(e,D.name,B,D.revision,D.ownerRoute),se=vr(U,ha(D),D.ownerTopology,D.local,!0);return X(E.current.map(ee=>ee.id===M?se:ee),!1),I.current=!1,v("saved"),b(""),setTimeout(()=>v("idle"),1500),!0}catch(B){if(v("error"),b(String(B.message||B)),B.status===409&&B.data&&B.data.current){const U=E.current.find(ee=>ee.id===M),se=vr(B.data.current,ha(U),U.ownerTopology,U.local,!0);X(E.current.map(ee=>ee.id===M?se:ee),!1)}return!1}},[d,e,X]);return k.useEffect(()=>{if(!d)return;if(G.current){G.current=!1;return}I.current=!0,v("saving");const M=setTimeout(R,650);return()=>clearTimeout(M)},[n,d,R]),k.useEffect(()=>{if(!d)return;const M=setInterval(async()=>{try{const D=await $(),B=E.current.find(ee=>ee.id===C.current),U=D.find(ee=>ee.id===C.current),se=U&&(!B||U.revision>B.revision||B.available!==U.available);X(D,se&&!I.current)}catch{}},5e3);return()=>clearInterval(M)},[d,$,X]),{decks:a,records:a,localNodeId:S,ready:d,saveState:m,error:y,setError:b,saveNow:R,select:async M=>{if(I.current&&!await R(C.current))throw new Error("salvataggio del deck corrente fallito: cambio annullato");const D=E.current.find(B=>B.id===M);if(!D)throw new Error(`deck inesistente: ${M}`);return I.current=!1,G.current=!0,W(D)},add:async(M,D=null)=>{const B=D===Gi?E.current.find(ee=>ee.local):D?E.current.find(ee=>ee.ownerId===D):null;if(!B||B.available===!1)throw new Error("nodo owner non disponibile");const U=await rv(e,M,B.ownerRoute),se=vr(U,ha(B),B.ownerTopology,B.local,!0);return X([...E.current,se],!1),se},rename:async(M,D)=>{const B=E.current.find(ve=>ve.id===M);if(!B)throw new Error("deck inesistente");if(M===C.current&&I.current&&!await R(M))throw new Error(`salvataggio di "${B.name}" fallito: rinomina annullata`);const U=E.current.find(ve=>ve.id===M);if(!U)throw new Error("deck inesistente");const se=await Vx(e,U.name,D,U.revision,U.ownerRoute),ee=vr(se,ha(U),U.ownerTopology,U.local,!0),de=U.local?Gi:U.ownerId;return $d(I2(Gl(),de,M,ee.id)),X(E.current.map(ve=>ve.id===M?ee:ve),!1),ee},remove:async M=>{const D=E.current.find(U=>U.id===M);if(!D)throw new Error("deck inesistente");M===C.current&&(I.current=!1),await Yx(e,D.name,D.revision,D.ownerRoute);const B=D.local?Gi:D.ownerId;$d(O2(Gl(),B,M)),X(E.current.filter(U=>U.id!==M),!1)},reorder:(M,D)=>{const B=E.current.find(fe=>fe.id===M),U=E.current.find(fe=>fe.id===D);if(!B||!U)return!1;const se=B.local?Gi:B.ownerId,ee=U.local?Gi:U.ownerId;if(se!==ee)return!1;const de=E.current.filter(fe=>(fe.local?Gi:fe.ownerId)===se).map(fe=>fe.id),ve=$d(D2(Gl(),se,M,D,de));return X(O_(E.current,ve),!1),!0},addTileTo:async(M,D)=>{const B=E.current.find(fe=>fe.id===M);if(!B)throw new Error("deck inesistente");if(B.available===!1)throw new Error(`nodo owner offline: ${B.ownerLabel}`);const U=Lw(D,N.current,w.current);if(!U)throw new Error("riferimento sessione non valido");const se=W(B),ee=D_(vb(se,U),B.ownerId,B.ownerTopology),de=await Fl(e,B.name,ee,B.revision,B.ownerRoute),ve=vr(de,ha(B),B.ownerTopology,B.local,!0);return X(E.current.map(fe=>fe.id===M?ve:fe),!1),ve},localMainId:po(null,"main"),parseDeckId:Mc}}const xP="/sw.js",Cf="nc-sw-update";let Ef=null,Nf=!1,jf=null,pS=Object.freeze({needed:!1,kind:null,version:""}),mS=!1;function gS(){typeof window<"u"&&window.dispatchEvent(new Event(Cf))}function vS(){const e=jf||(Nf?{kind:"reload",version:""}:null);pS=Object.freeze({needed:!!e,kind:(e==null?void 0:e.kind)||null,version:(e==null?void 0:e.version)||""})}function My(){return pS}function kP(e){return typeof window>"u"?()=>{}:(window.addEventListener(Cf,e),()=>window.removeEventListener(Cf,e))}function jp(e){Nf!==e&&(Nf=e,vS(),gS())}const mh="nc-auto-reload";function CP(){try{return typeof sessionStorage<"u"?sessionStorage:null}catch{return null}}function EP(e,t,n,s={}){let o=null;e&&t&&e!==t?o={kind:"install",version:e}:t&&n&&t!==n&&(o={kind:"reload",version:t});const a=JSON.stringify(o)===JSON.stringify(jf);jf=o,vS(),a||gS();const u=s.storage===void 0?CP():s.storage;if(!o){try{u&&u.removeItem(mh)}catch{}return}if(o.kind!=="reload"||!u)return;const d=`${t}|${n}`;try{if(u.getItem(mh)===d)return;u.setItem(mh,d)}catch{return}(s.applyImpl||_S)()}function NP(e){e.addEventListener("statechange",()=>{e.state==="installed"&&navigator.serviceWorker.controller&&jp(!0)})}function jP(){typeof navigator>"u"||!("serviceWorker"in navigator)||(navigator.serviceWorker.addEventListener("controllerchange",()=>{mS&&location.reload()}),navigator.serviceWorker.register(xP).then(e=>{Ef=e,e.waiting&&jp(!0),e.addEventListener("updatefound",()=>{const t=e.installing;t&&NP(t)}),setInterval(()=>{e.update().catch(()=>{})},3600*1e3)}).catch(()=>{}))}function _S(){mS=!0,jp(!1);const e=Ef&&Ef.waiting;e?(e.postMessage({type:"SKIP_WAITING"}),setTimeout(()=>location.reload(),4e3)):location.reload()}function RP({hash:e="",origin:t="",pathname:n="",search:s=""}={}){const o=String(e||"").replace(/^#/,""),a=`${n||""}${s||""}`;if(!o)return{token:"",pair:"",nextUrl:a};const u=new URLSearchParams(o),d=u.get("token")||"",p=u.get("pair")||"",m=p?`${t||""}${n||""}#pair=${p}`:"";return{token:d,pair:m,nextUrl:a}}const yS=9,bS=24,wS="nc_side_w",Ty="nc_side_min",PP=240;function LP(){const e=Number(localStorage.getItem(wS));return e>=180&&e<=480?e:PP}function AP(){const e=Number(localStorage.getItem("nc_fontsize"));return e>=yS&&e<=bS?e:13}function MP(){const e={token:"",pair:""};try{const{token:t,pair:n,nextUrl:s}=RP({hash:location.hash,origin:location.origin,pathname:location.pathname,search:location.search});if(t){e.token=t;try{localStorage.setItem("nc_token",t)}catch{}}if(n){e.pair=n;try{sessionStorage.setItem("nc_pair",n)}catch{}}if(location.hash)try{history.replaceState(null,"",s)}catch{}}catch{}if(e.token||(e.token=sessionStorage.getItem("nc_token")||localStorage.getItem("nc_token")||""),!e.pair){const t=sessionStorage.getItem("nc_pair");t&&(e.pair=t)}return e}function TP(e){try{return xr(wf(e))}catch{return fo()}}function Dy(e){if(!e)return"";const t=Math.floor(Date.now()/1e3)-e;return t<0||t<60?"ora":t<3600?`${Math.floor(t/60)}m`:t<86400?`${Math.floor(t/3600)}h`:`${Math.floor(t/86400)}g`}function Iy({session:e,node:t,ownerId:n,cellName:s,token:o,readonly:a=!1,panelPort:u=0,onBack:d,onCellSwitcher:p,cellSwitcherOpen:m=!1}){Yn();const[v]=up(),[y,b]=k.useState(!1),[S,x]=k.useState(()=>window.matchMedia("(pointer: coarse)").matches),[E,w]=k.useState(null),[N,C]=k.useState(AP),[L,I]=k.useState(s||e),[G,K]=k.useState(""),[Y,Q]=k.useState(""),[W,X]=k.useState(""),[H,$]=k.useState(!1),R=U=>C(se=>{const ee=Math.max(yS,Math.min(bS,se+U));return localStorage.setItem("nc_fontsize",String(ee)),ee}),O=k.useRef(()=>{}),F=k.useRef(()=>!1),A=k.useRef(()=>{}),T=k.useRef(!1),[j,z]=k.useState(!1),[M,D]=k.useState(!1),B=()=>{T.current=!T.current,z(T.current)};return k.useEffect(()=>{I(s||e),$(!1)},[s,e]),k.useEffect(()=>{let U=!0;const se=t?t.split("/"):[],ee=t?`/api/route/${t.split("/").map(encodeURIComponent).join("/")}/_`:"/api";async function de(){let fe=null,pe=null;try{const vt=await(await on(`${ee}/sessions`,o)).json();Array.isArray(vt.sessions)&&(fe=vt.sessions.find(je=>je.name===e))}catch{}try{const ut=await Xs(o,se);ut.available&&Array.isArray(ut.cells)&&(pe=ut.cells.find(vt=>vt.tmuxSession===e))}catch{}if(!U)return;I(dp({session:e,cell:pe||(s?{cell:s}:null)})),Q(typeof(pe==null?void 0:pe.panelUrl)=="string"?pe.panelUrl.trim():""),X(typeof(pe==null?void 0:pe.cell)=="string"?pe.cell:"");let Ve="";pe?Ve=`${pe.engine}${pe.key?`·${pe.key}`:""}`:fe&&(Ve=fe.attached?`attached · ${Dy(fe.activity)}`:fe.activity?Dy(fe.activity):""),K(Ve)}de();const ve=setInterval(de,4e3);return()=>{U=!1,clearInterval(ve)}},[e,t,o]),l.jsxs("div",{className:"nc-app",children:[l.jsxs("header",{className:"nc-bar nc-bar-single",children:[l.jsxs("button",{onClick:d,title:f("sessions"),children:[l.jsx(lt,{name:"chevronLeft",size:18}),l.jsx("span",{className:"nc-bar-label",children:f("sessions")})]}),l.jsxs("span",{className:"nc-bar-center",children:[l.jsx("b",{title:t?`${L} · ${t}`:L,children:L}),G&&l.jsx("small",{className:"nc-bar-sub",children:G})]}),l.jsxs("span",{className:"nc-bar-right",children:[l.jsx("button",{onClick:()=>R(-1),title:f("zoom-out"),children:l.jsx(lt,{name:"zoomOut",size:18})}),l.jsx("button",{onClick:()=>R(1),title:f("zoom-in"),children:l.jsx(lt,{name:"zoomIn",size:18})}),l.jsx("button",{onClick:()=>x(U=>!U),title:f("composer"),children:l.jsx(lt,{name:"keyboard",size:20})}),l.jsx("button",{onClick:()=>b(U=>!U),title:f("files"),children:l.jsx(lt,{name:"folder",size:20})}),Y&&l.jsx("button",{onClick:()=>$(U=>!U),title:f("panel"),"aria-pressed":H,children:l.jsx(lt,{name:"monitor",size:20})})]})]}),l.jsxs("div",{className:"nc-termwrap",children:[l.jsx(sp,{session:e,node:t,token:o,readonly:a,takeSize:!0,sendRef:O,composerRef:F,actionRef:A,ctrlRef:T,setCtrlArmed:z,onFiles:w,fontSize:N,selectionMode:M,onSelectionModeChange:D,keyboardGesture:v.terminalKeyboardGesture}),H&&Y&&W&&l.jsx(ap,{cellId:W,panelUrl:Y,route:t?t.split("/"):[],panelPort:u,token:o,title:L})]}),l.jsx(XN,{onKeyboard:()=>x(U=>!U),onCellSwitcher:p,cellSwitcherOpen:m,send:U=>O.current(U),action:U=>A.current(U),ctrlArmed:j,onCtrl:B,selectionMode:M,onSelectionMode:D,keepKeyboardClosed:v.keybarKeepsKeyboardClosed,showEnter:v.showKeybarEnter,keybarLayout:v.keybarLayout}),S&&l.jsx(Sw,{submitText:U=>F.current(U),token:o,session:e,node:t,ownerId:n,readonly:a,keepKeyboardClosedOnVoice:v.voiceKeepsKeyboardClosed}),y&&l.jsx(fw,{session:e,node:t,token:o,filesEvent:E,onClose:()=>b(!1)})]})}function DP(){Yn();const[e]=k.useState(MP),[t,n]=k.useState(e.token),[s,o]=k.useState(e.pair||""),a=k.useCallback(()=>{o("");try{sessionStorage.removeItem("nc_pair")}catch{}},[]),[u,d]=k.useState(!1),p=jN(),[m]=k.useState(()=>A2(typeof location<"u"?location.pathname:"/")),[v,y]=k.useState(m.id),b=v===po(null,vi),[S,x]=k.useState(null),E=te=>{const Se=Gs(te);x(Se?{...Se,...typeof(te==null?void 0:te.cellName)=="string"&&te.cellName?{cellName:te.cellName}:{}}:null)},[w,N]=k.useState([]),[C,L]=k.useState([]),[I,G]=k.useState([]),[K,Y]=k.useState(!1),[Q,W]=k.useState(null),[X,H]=k.useState(()=>m.ownerId?fo():TP(m.name)),[$,R]=k.useState(null),[O,F]=k.useState(null),A=te=>F(Gs(te)),[T,j]=k.useState(null),z=zf(t,p),M=k.useMemo(()=>(z||[]).filter(te=>te.instanceId).map(te=>({instanceId:te.instanceId,route:te.route,label:te.label,status:te.status})),[z]),D=SP(t,v,X,H,M),B=D.decks;k.useEffect(()=>{const te=new Map;for(const Se of z||[]){const Te=(Se.route||[Se.name]).join("/"),tt=new Set((Se.sessions||[]).map(nt=>nt.name));for(const nt of Se.cells||[])!nt.cell||!nt.tmuxSession||nt.cell===nt.tmuxSession||tt.has(nt.cell)||te.set(`${Te}:${nt.cell}`,`${Te}:${nt.tmuxSession}`)}H(Se=>Ak(Se,te))},[z]),k.useEffect(()=>{D.localNodeId&&H(te=>{const Se=bf(te,D.localNodeId,M);return JSON.stringify(Se)===JSON.stringify(te)?te:Se})},[M,D.localNodeId]);const[U,se]=k.useState(null),[ee,de]=k.useState(null),ve=k.useRef(0),[fe,pe]=k.useState(!1),[Ve,ut]=k.useState(LP),[vt,je]=k.useState(!b),[Ct,dn]=k.useState(()=>b?localStorage.getItem(Ty)==="1":!0),[gn,Yt]=k.useState(!1),[xt,Ot]=k.useState("nodes"),[Ut,Nt]=k.useState(!1),[Dt,At]=k.useState(""),[jt,hn]=k.useState(!1),re=(te="nodes",Se=!1,Te="")=>{Ot(te),Nt(Se),At(Te),Yt(!0)},[Qe,me]=k.useState(!1),[Ge,ct]=k.useState({deviceDefault:"",localNodeId:"",localNameDefault:""}),[oe,ie]=k.useState(!1),[_e,be]=k.useState(0),[ke,it]=k.useState({});k.useEffect(()=>{try{localStorage.setItem(wS,String(Ve))}catch{}},[Ve]),k.useEffect(()=>{try{localStorage.setItem(Ty,Ct?"1":"")}catch{}},[Ct]),k.useEffect(()=>{if(!t)return;let te=!1;return Promise.all([Ky(t),on("/api/config",t).then(Se=>Se.json())]).then(([Se,Te])=>{te||(ct({deviceDefault:Se.deviceName||"",localNodeId:Se.nodeId||"",localNameDefault:Se.localName||""}),ie(!!Te.readonlyDefault),be(Number.isInteger(Te.panelPort)?Te.panelPort:0),it(Te.nodePanelPorts&&typeof Te.nodePanelPorts=="object"&&!Array.isArray(Te.nodePanelPorts)?Te.nodePanelPorts:{}),(Se.firstRun===!0&&!Te.readonlyDefault||s)&&me(!0))}).catch(()=>{}),()=>{te=!0}},[t,s]);const[ht,dt]=k.useState({}),Rt=k.useRef(z);k.useEffect(()=>{Rt.current=z},[z]);const wt=k.useCallback(async()=>{try{const nt=await(await on("/api/sessions",t)).json();nt.error||N(nt.sessions||[])}catch{}let te=null,Se=null;try{te=await Xs(t)}catch(tt){Se=tt}const Te=Bf({fs:te,error:Se});Te.kind==="data"?(L(Te.cells),G(Te.capabilities),Y(!1),W(null)):Te.kind==="stale"?(Y(!0),W(null)):(L([]),G([]),Y(!1),W(Te.reason||""))},[t]);k.useEffect(()=>{let te=!1;const Se=async()=>{const tt=[[],...(Rt.current||[]).filter(St=>St.kind!=="vl"&&St.status==="up").map(St=>Array.isArray(St.route)&&St.route.length?St.route:[St.name])],nt=await Promise.all(tt.map(async St=>{try{const It=await Gx(t,St);return[wa(St),{hostCell:It&&typeof It.hostCell=="string"?It.hostCell:null,hostLease:It&&It.host&&typeof It.host.lease=="string"?It.host.lease:null,hostRevision:Number.isInteger(It&&It.revision)?It.revision:0}]}catch{return null}}));te||dt(St=>{let It=!1;const Sn={...St};for(const ri of nt)ri&&(Sn[ri[0]]=ri[1],It=!0);return It?Sn:St})};Se();const Te=setInterval(Se,4e3);return()=>{te=!0,clearInterval(Te)}},[t]),k.useEffect(()=>{if(!p)return;wt();const te=setInterval(wt,4e3);return()=>clearInterval(te)},[p,wt]);const _t=k.useCallback(async(te,Se=[])=>{const Te=wa(Se),tt=ht[Te]&&ht[Te].hostRevision||0;try{const nt=await Xx(t,te,tt,Se);dt(St=>({...St,[Te]:{hostCell:nt.hostCell||null,hostLease:nt.host&&typeof nt.host.lease=="string"?nt.host.lease:null,hostRevision:Number.isInteger(nt.revision)?nt.revision:tt}}))}catch(nt){window.alert(f(_v(nt)))}},[t,ht]),zt=k.useCallback(async(te=[])=>{const Se=wa(te),Te=ht[Se]&&ht[Se].hostRevision||0;try{const tt=await Qx(t,Te,te);return dt(nt=>({...nt,[Se]:{hostCell:tt.hostCell||null,hostLease:null,hostRevision:Number.isInteger(tt.revision)?tt.revision:Te}})),!0}catch(tt){return window.alert(f(_v(tt))),!1}},[t,ht]);k.useEffect(()=>{let te=!1;const Se=()=>{on("/api/config",t).then(tt=>tt.json()).then(tt=>{te||EP(tt.version,tt.uiVersion,"0.9.14")}).catch(()=>{})};Se();const Te=setInterval(Se,6e4);return()=>{te=!0,clearInterval(Te)}},[t]);const Je=new Set([...w.map(te=>te.name),...z.flatMap(te=>te.sessions.map(Se=>Se.key))]),J=Qi(X),Ne=te=>H(Se=>{const Te=Lw(te,D.localNodeId,M)||te,tt=vb(Se,Te);return tt===Se&&Qi(Se).length>=9&&D.setError(f("grid-full")),tt}),Ue=async(te,Se=[])=>{try{await Af(t,te,Se)}catch{return}const Te=Se.length?`${Se.join("/")}:${te}`:te;H(tt=>mc(tt,Te)),wt()},Oe=async(te,Se,Te=[])=>{try{await Wy(t,te,Se,Te)}catch{return}wt()},Le=async(te,Se,Te=[])=>{await Fy(t,{cell:te,enabled:!!Se},Te),wt()},Et=async te=>{if(!U)return;const{cell:Se}=U,Te=Array.isArray(U.route)?U.route:[];if(te.action==="up"){const nt=await Lf(t,{cell:Se,boot:!!te.boot,...te.engine?{engine:te.engine}:{},...te.model!==void 0?{model:te.model}:{},...te.permissionPolicy?{permissionPolicy:te.permissionPolicy}:{}},Te),St=Vf(nt);St&&D.setError(St.text)}else await lc(t,{cell:Se,boot:!!te.boot},Te);const tt=te.action==="up"?!!te.boot:te.boot?!1:!!U.boot;de({id:++ve.current,cell:Se,route:Te,enabled:tt}),wt()},kt=k.useCallback(te=>{de(Se=>(Se==null?void 0:Se.id)===te?null:Se)},[]),V=async te=>{if(!(!(te!=null&&te.direct)||fe)){pe(!0);try{await If(t,te.name,te.tunnelStatus==="up"?"down":"up")}finally{pe(!1)}}},ae=async(te,Se)=>{const Te=String(Se||"").trim();return!(te!=null&&te.direct)||!_o(Te)?!1:(await Yy(t,te.name,Te),!0)},ye=te=>{const Se=B.find(Te=>Te.id===te);if(!Se)return!1;try{const Te=window.open(zd(Se,t),"_blank");return Te&&(Te.opener=null),!!Te}catch{return!1}},Me=async te=>{if(!te||te===v)return;const Se=await D.select(te),Te=D.records.find(tt=>tt.id===te);y(te),H(Se),R(null),F(null);try{history.replaceState(null,"",zd(Te||te,null))}catch{}},De=async(te,Se)=>{const Te=await D.add(te,Se);await Me(Te.id)},Ee=async(te,Se)=>{const Te=await D.rename(te,Se);if(te===v){y(Te.id),H(bf(Te.layout,D.localNodeId,M)),R(null),F(null);try{history.replaceState(null,"",zd(Te,null))}catch{}}},Xe=async te=>{await D.remove(te),te===v&&await Me(D.localMainId)},yt=async(te,Se)=>{!Se||Se===v||(await D.addTileTo(Se,te),H(Te=>mc(Te,te)))};if(!t)return l.jsxs("div",{className:"nc-auth",children:[l.jsx("p",{children:f("auth-prompt")}),l.jsx("input",{onChange:te=>n(te.target.value.trim()),placeholder:"token"}),l.jsxs("label",{children:[l.jsx("input",{type:"checkbox",checked:u,onChange:te=>d(te.target.checked)})," ",f("remember-device")]}),l.jsx("button",{onClick:()=>{(u?localStorage:sessionStorage).setItem("nc_token",t)},children:"ok"})]});const $t=l.jsxs(l.Fragment,{children:[gn&&l.jsx(sP,{token:t,initialTab:xt,initialLocation:Dt,startNewCell:Ut,onClose:()=>{Yt(!1),Nt(!1),At("")}}),Qe&&l.jsx(rP,{token:t,initialPair:s,...Ge,onPairDone:a,onDone:()=>me(!1)}),l.jsx(dP,{token:t})]});if(!p)return T?l.jsxs(l.Fragment,{children:[l.jsx("div",{className:"nc-single-overlay",children:l.jsx(Ay,{peer:T,token:t,onBack:()=>j(null)})}),$t]}):S?l.jsxs(l.Fragment,{children:[l.jsx(Iy,{session:S.session,node:S.node,ownerId:S.ownerId,cellName:S.cellName,token:t,readonly:oe,panelPort:kc(S.node?S.node.split("/"):[],ke,_e),onBack:()=>x(null),onCellSwitcher:()=>hn(!0),cellSwitcherOpen:jt}),jt&&l.jsx(vP,{token:t,current:S,panelPort:_e,nodePanelPorts:ke,onPick:te=>{E(te),hn(!1)},onClose:()=>hn(!1)}),$t]}):l.jsxs(l.Fragment,{children:[l.jsx(Xk,{onPick:E,token:t,onSettings:re,onOpenVlSession:j,hostByRoute:ht,onDesignateCell:_t,onClearHostCell:zt}),$t]});const Be=b||!vt;return l.jsxs("div",{className:"nc-workspace",children:[Be&&l.jsx(w2,{sessions:w,cells:C,activeSessions:J,nodeGroups:z,token:t,onPeekOpen:()=>hn(!1),overlayOpen:jt,fleetCapabilities:I,fleetStale:K,fleetOff:Q,bootSettlement:ee,onBootSettlementApplied:kt,localNodeId:D.localNodeId,hostByRoute:ht,onDesignateCell:_t,onClearHostCell:zt,onPick:A,onAddTile:Ne,onPower:se,onBoot:Le,onBootError:te=>D.setError(String((te==null?void 0:te.message)||te)),onNodePower:V,onNodeRename:ae,onKill:Ue,onVisibility:Oe,onNew:()=>re("fleet",!0),onSettings:re,onOpenVlSession:j,width:Ve,collapsed:Ct,onResize:ut,onToggleCollapse:()=>dn(te=>!te)}),l.jsxs("div",{className:"nc-workspace-main",children:[l.jsx(tj,{decks:B,currentDeck:v,onCreate:De,onRename:Ee,onDelete:Xe,onReorder:D.reorder,onOpenWindow:ye,onNavigate:Me,saveState:D.saveState,error:D.error,sidebarVisible:Be,onToggleSidebar:b?null:()=>je(te=>!te)}),l.jsx(N2,{layout:X,onLayoutChange:H,token:t,readonly:oe,sessionsAlive:Je,focusSession:$,onFocus:R,onOpenSingle:A,decks:B,currentDeck:v,onSendToDeck:yt,cells:C,nodeGroups:z,panelPort:_e,nodePanelPorts:ke})]}),T&&l.jsx("div",{className:"nc-single-overlay",children:l.jsx(Ay,{peer:T,token:t,onBack:()=>j(null)})}),O&&l.jsx("div",{className:"nc-single-overlay",children:l.jsx(Iy,{session:O.session,node:O.node,ownerId:O.ownerId,cellName:dp({session:O.session,node:O.node,ownerId:O.ownerId,cells:C,nodeGroups:z}),token:t,readonly:oe,panelPort:kc(O.node?O.node.split("/"):[],ke,_e),onBack:()=>F(null)})}),U&&l.jsx(uc,{cell:U,token:t,route:Array.isArray(U.route)?U.route:[],onConfirm:Et,onClose:()=>se(null)}),$t]})}function IP(){Yn();const e=k.useSyncExternalStore(kP,My,My);if(!e.needed)return null;const t=e.kind==="install"?f("install-version-mismatch").replace("{v}",e.version):f("update-available").replace("{v}",e.version).replace(" "," ").trim();return l.jsxs("div",{className:"nc-update",role:"status","aria-live":"polite",children:[l.jsx("span",{className:"nc-update-msg",children:t}),e.kind==="reload"&&l.jsx("button",{className:"nc-update-btn",onClick:_S,children:f("reload")})]})}jP();ox.createRoot(document.getElementById("root")).render(l.jsxs(Z0.StrictMode,{children:[l.jsx(DP,{}),l.jsx(IP,{})]}));
|
package/frontend/dist/index.html
CHANGED
|
@@ -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-
|
|
14
|
+
<script type="module" crossorigin src="/assets/index-9jCxHZwQ.js"></script>
|
|
15
15
|
<link rel="stylesheet" crossorigin href="/assets/index-keXh4CAm.css">
|
|
16
16
|
</head>
|
|
17
17
|
<body>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"0.9.
|
|
1
|
+
{"version":"0.9.14"}
|