@xenon-device-management/xenon 1.7.0 → 1.7.1

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.
Files changed (69) hide show
  1. package/lib/package.json +1 -1
  2. package/lib/public/assets/{ApiKeyGate-BSN8crwz.js → ApiKeyGate-DBl_AZ8N.js} +1 -1
  3. package/lib/public/assets/{BugReportButton-DNja1wQ1.js → BugReportButton-Cz4aeGCX.js} +1 -1
  4. package/lib/public/assets/{DeviceMosaicView-DVk1IpIR.js → DeviceMosaicView-DP4AanNV.js} +1 -1
  5. package/lib/public/assets/{EmptyState-CqQ21n-H.js → EmptyState-BwaAbjZt.js} +1 -1
  6. package/lib/public/assets/{FieldGroup-DE3u01Nu.js → FieldGroup-CGdoHDQ3.js} +1 -1
  7. package/lib/public/assets/{Modal-BJcFdiBP.js → Modal-OY-an2g6.js} +1 -1
  8. package/lib/public/assets/{SegmentedControl-CSHjmrvy.js → SegmentedControl-C_gsCi2P.js} +1 -1
  9. package/lib/public/assets/{SettingCard-M-lFn_Wm.js → SettingCard-CRlStb6_.js} +1 -1
  10. package/lib/public/assets/{Table-B3EUgBi6.js → Table-CbmGiPJe.js} +1 -1
  11. package/lib/public/assets/{activity-DK3R5GAb.js → activity-BhRPBZ3G.js} +1 -1
  12. package/lib/public/assets/{ai-settings-AKMDh8pd.js → ai-settings-DteGlf4r.js} +1 -1
  13. package/lib/public/assets/{api-keys-B5Q1EkGN.js → api-keys-BmikiaSF.js} +1 -1
  14. package/lib/public/assets/{apps-CWWrkTZW.js → apps-BfEC5qsb.js} +1 -1
  15. package/lib/public/assets/apps-DS59NYjg.css +1 -0
  16. package/lib/public/assets/{arrow-left-9933DNlF.js → arrow-left-y_SSjJz-.js} +1 -1
  17. package/lib/public/assets/{arrow-up-right-B7q_1mXs.js → arrow-up-right-NQ8ZGfd3.js} +1 -1
  18. package/lib/public/assets/{builds-page-DgWXOgh5.js → builds-page-DkLt4J8-.js} +2 -2
  19. package/lib/public/assets/{button-lkxVyarW.js → button-wz7ra9cW.js} +1 -1
  20. package/lib/public/assets/{check-BkT38An9.js → check-CV94AcJF.js} +1 -1
  21. package/lib/public/assets/{chevron-right-WELZ1Z8v.js → chevron-right-_iIkyWqd.js} +1 -1
  22. package/lib/public/assets/{circle-check--2DSsfaI.js → circle-check-0COJnxUq.js} +1 -1
  23. package/lib/public/assets/{circle-x-x7R8vTBo.js → circle-x-DGNoObyH.js} +1 -1
  24. package/lib/public/assets/{clock-DIpGd4Pn.js → clock-DwtXByAH.js} +1 -1
  25. package/lib/public/assets/{copy-CEcFYYHm.js → copy-DL_iD5Dh.js} +1 -1
  26. package/lib/public/assets/device-explorer-CKcXaWmZ.css +1 -0
  27. package/lib/public/assets/device-explorer-CpC-MZNT.js +210 -0
  28. package/lib/public/assets/{download-CaKkGvKw.js → download-aeG6Qqs8.js} +1 -1
  29. package/lib/public/assets/{forgot-password-CsAF11d2.js → forgot-password-Cu05XOKH.js} +1 -1
  30. package/lib/public/assets/{funnel-D2rLIKlM.js → funnel-ChogDM6h.js} +1 -1
  31. package/lib/public/assets/{index-BrVV0Kla.js → index-CkwQBzCl.js} +2 -2
  32. package/lib/public/assets/index-gXUPv-oo.css +1 -0
  33. package/lib/public/assets/{layers-DZwF8z_0.js → layers-a5nj78PI.js} +1 -1
  34. package/lib/public/assets/{lock-CVUUnm1V.js → lock-CqQvL12G.js} +1 -1
  35. package/lib/public/assets/{login-BavGkTli.js → login-DoaCgEPu.js} +1 -1
  36. package/lib/public/assets/{maintenance-settings-Vr_u8hoR.js → maintenance-settings-CBnV_5Rl.js} +1 -1
  37. package/lib/public/assets/{mouse-pointer-2-n4xUMxHJ.js → mouse-pointer-2-De_oynWc.js} +1 -1
  38. package/lib/public/assets/{overview-DVgoOoYF.js → overview-DvyGTzku.js} +1 -1
  39. package/lib/public/assets/{page-header-C0pnt4xz.js → page-header-BeUDGs-O.js} +1 -1
  40. package/lib/public/assets/{plus-BObE-_z6.js → plus-BM5UAzcK.js} +1 -1
  41. package/lib/public/assets/{profile-page-DNKD4MS2.js → profile-page-Cner_Muq.js} +1 -1
  42. package/lib/public/assets/{reset-password-C2gSMy8a.js → reset-password-BKWBemnU.js} +1 -1
  43. package/lib/public/assets/{runbook-page-BRxjWJVQ.js → runbook-page-CXZdhAjc.js} +1 -1
  44. package/lib/public/assets/{selector-detail-page-DcV8jQuX.js → selector-detail-page-C6yA7Lwl.js} +1 -1
  45. package/lib/public/assets/{selector-health-DraY2a4b.js → selector-health-BWOVdnlp.js} +1 -1
  46. package/lib/public/assets/{selector-health-page-tb5e3CXy.js → selector-health-page-CrR7bh4f.js} +2 -2
  47. package/lib/public/assets/{session-detail-page-CEtQr37W.js → session-detail-page-DzW5PcxL.js} +1 -1
  48. package/lib/public/assets/{settings-Cr-YjLbX.js → settings-COrR3YcC.js} +1 -1
  49. package/lib/public/assets/{shield-BBc4qisQ.js → shield-CAA9vrIs.js} +1 -1
  50. package/lib/public/assets/{shield-alert-BfoPJ8q_.js → shield-alert-Dm3Oz4Kc.js} +1 -1
  51. package/lib/public/assets/{status-pill-outline-Cc4PF7Mg.js → status-pill-outline-3FA5raqd.js} +1 -1
  52. package/lib/public/assets/{tablet-CaOqzQv_.js → tablet-CWU6hxZF.js} +1 -1
  53. package/lib/public/assets/{teams-B3Tt_9i2.js → teams-xa_B0pyz.js} +1 -1
  54. package/lib/public/assets/{trash-2-CE5TRHb2.js → trash-2-DUWA0N9n.js} +1 -1
  55. package/lib/public/assets/{useSocket-Bkt5i-U6.js → useSocket-lsg6f_Dn.js} +1 -1
  56. package/lib/public/assets/{users-BIvjvjM6.js → users-DJDpKaGy.js} +1 -1
  57. package/lib/public/assets/{webhook-settings-dAp8wwEB.js → webhook-settings-BPf_iC_h.js} +1 -1
  58. package/lib/public/assets/{zap-BzdRuL9F.js → zap-D8JQHaNH.js} +1 -1
  59. package/lib/public/index.html +2 -2
  60. package/lib/src/app/routers/auth.js +19 -2
  61. package/lib/src/scripts/run-migrations.js +14 -3
  62. package/lib/test/unit/auth-me-auth-disabled.test.js +77 -0
  63. package/lib/test/unit/run-migrations-fail-fast.test.js +87 -0
  64. package/lib/tsconfig.tsbuildinfo +1 -1
  65. package/package.json +1 -1
  66. package/lib/public/assets/apps-Dt5dUIag.css +0 -1
  67. package/lib/public/assets/device-explorer-3H1hf8ld.css +0 -1
  68. package/lib/public/assets/device-explorer-nV6L3w7x.js +0 -210
  69. package/lib/public/assets/index-Dz1K6OJU.css +0 -1
@@ -1,4 +1,4 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/overview-DVgoOoYF.js","assets/useSocket-Bkt5i-U6.js","assets/funnel-D2rLIKlM.js","assets/tablet-CaOqzQv_.js","assets/activity-DK3R5GAb.js","assets/plus-BObE-_z6.js","assets/device-explorer-nV6L3w7x.js","assets/page-header-C0pnt4xz.js","assets/button-lkxVyarW.js","assets/button-DtC0WGPu.css","assets/BugReportButton-DNja1wQ1.js","assets/BugReportButton-DeF8gwF1.css","assets/Modal-BJcFdiBP.js","assets/Modal-qvYudaqQ.css","assets/FieldGroup-DE3u01Nu.js","assets/FieldGroup-trY-2qmW.css","assets/clock-DIpGd4Pn.js","assets/copy-CEcFYYHm.js","assets/mouse-pointer-2-n4xUMxHJ.js","assets/layers-DZwF8z_0.js","assets/check-BkT38An9.js","assets/zap-BzdRuL9F.js","assets/chevron-right-WELZ1Z8v.js","assets/shield-alert-BfoPJ8q_.js","assets/keycodes-bIEJfQzr.js","assets/lock-CVUUnm1V.js","assets/trash-2-CE5TRHb2.js","assets/download-CaKkGvKw.js","assets/SegmentedControl-CSHjmrvy.js","assets/SegmentedControl-M7StbYAD.css","assets/device-explorer-3H1hf8ld.css","assets/builds-page-DgWXOgh5.js","assets/status-pill-outline-Cc4PF7Mg.js","assets/circle-x-x7R8vTBo.js","assets/circle-check--2DSsfaI.js","assets/session-detail-page-CEtQr37W.js","assets/arrow-left-9933DNlF.js","assets/arrow-up-right-B7q_1mXs.js","assets/EmptyState-CqQ21n-H.js","assets/EmptyState-BSDHFxd1.css","assets/Table-B3EUgBi6.js","assets/Table-BIjXN_-_.css","assets/session-detail-page-BikvFUAQ.css","assets/runbook-page-BRxjWJVQ.js","assets/runbook-page-BcfSJRZ-.css","assets/apps-CWWrkTZW.js","assets/apps-Dt5dUIag.css","assets/webhook-settings-dAp8wwEB.js","assets/webhook-settings-DEZQtSgr.css","assets/settings-CpRbubta.css","assets/settings-Cr-YjLbX.js","assets/SettingCard-M-lFn_Wm.js","assets/SettingCard-C7wPlNh9.css","assets/shield-BBc4qisQ.js","assets/ai-settings-AKMDh8pd.js","assets/maintenance-settings-Vr_u8hoR.js","assets/api-keys-B5Q1EkGN.js","assets/teams-B3Tt_9i2.js","assets/users-cwrwUhwo.js","assets/selector-health-page-tb5e3CXy.js","assets/selector-health-DraY2a4b.js","assets/selector-health-BwHGcem9.css","assets/selector-detail-page-DcV8jQuX.js","assets/DeviceMosaicView-DVk1IpIR.js","assets/profile-page-DNKD4MS2.js","assets/users-BIvjvjM6.js"])))=>i.map(i=>d[i]);
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/overview-DvyGTzku.js","assets/useSocket-lsg6f_Dn.js","assets/funnel-ChogDM6h.js","assets/tablet-CWU6hxZF.js","assets/activity-BhRPBZ3G.js","assets/plus-BM5UAzcK.js","assets/device-explorer-CpC-MZNT.js","assets/page-header-BeUDGs-O.js","assets/button-wz7ra9cW.js","assets/button-DtC0WGPu.css","assets/BugReportButton-Cz4aeGCX.js","assets/BugReportButton-DeF8gwF1.css","assets/Modal-OY-an2g6.js","assets/Modal-qvYudaqQ.css","assets/FieldGroup-CGdoHDQ3.js","assets/FieldGroup-trY-2qmW.css","assets/clock-DwtXByAH.js","assets/copy-DL_iD5Dh.js","assets/mouse-pointer-2-De_oynWc.js","assets/layers-a5nj78PI.js","assets/check-CV94AcJF.js","assets/zap-D8JQHaNH.js","assets/chevron-right-_iIkyWqd.js","assets/shield-alert-Dm3Oz4Kc.js","assets/keycodes-bIEJfQzr.js","assets/lock-CqQvL12G.js","assets/trash-2-DUWA0N9n.js","assets/download-aeG6Qqs8.js","assets/SegmentedControl-C_gsCi2P.js","assets/SegmentedControl-M7StbYAD.css","assets/device-explorer-CKcXaWmZ.css","assets/builds-page-DkLt4J8-.js","assets/status-pill-outline-3FA5raqd.js","assets/circle-x-DGNoObyH.js","assets/circle-check-0COJnxUq.js","assets/session-detail-page-DzW5PcxL.js","assets/arrow-left-y_SSjJz-.js","assets/arrow-up-right-NQ8ZGfd3.js","assets/EmptyState-BwaAbjZt.js","assets/EmptyState-BSDHFxd1.css","assets/Table-CbmGiPJe.js","assets/Table-BIjXN_-_.css","assets/session-detail-page-BikvFUAQ.css","assets/runbook-page-CXZdhAjc.js","assets/runbook-page-BcfSJRZ-.css","assets/apps-BfEC5qsb.js","assets/apps-DS59NYjg.css","assets/webhook-settings-BPf_iC_h.js","assets/webhook-settings-DEZQtSgr.css","assets/settings-CpRbubta.css","assets/settings-COrR3YcC.js","assets/SettingCard-CRlStb6_.js","assets/SettingCard-C7wPlNh9.css","assets/shield-CAA9vrIs.js","assets/ai-settings-DteGlf4r.js","assets/maintenance-settings-CBnV_5Rl.js","assets/api-keys-BmikiaSF.js","assets/teams-xa_B0pyz.js","assets/users-cwrwUhwo.js","assets/selector-health-page-CrR7bh4f.js","assets/selector-health-BWOVdnlp.js","assets/selector-health-BwHGcem9.css","assets/selector-detail-page-C6yA7Lwl.js","assets/DeviceMosaicView-DP4AanNV.js","assets/profile-page-Cner_Muq.js","assets/users-DJDpKaGy.js"])))=>i.map(i=>d[i]);
2
2
  function $c(e,t){for(var n=0;n<t.length;n++){const r=t[n];if(typeof r!="string"&&!Array.isArray(r)){for(const l in r)if(l!=="default"&&!(l in e)){const o=Object.getOwnPropertyDescriptor(r,l);o&&Object.defineProperty(e,l,o.get?o:{enumerable:!0,get:()=>r[l]})}}}return Object.freeze(Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}))}(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const l of document.querySelectorAll('link[rel="modulepreload"]'))r(l);new MutationObserver(l=>{for(const o of l)if(o.type==="childList")for(const i of o.addedNodes)i.tagName==="LINK"&&i.rel==="modulepreload"&&r(i)}).observe(document,{childList:!0,subtree:!0});function n(l){const o={};return l.integrity&&(o.integrity=l.integrity),l.referrerPolicy&&(o.referrerPolicy=l.referrerPolicy),l.crossOrigin==="use-credentials"?o.credentials="include":l.crossOrigin==="anonymous"?o.credentials="omit":o.credentials="same-origin",o}function r(l){if(l.ep)return;l.ep=!0;const o=n(l);fetch(l.href,o)}})();function _a(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var Ca={exports:{}},tr={};/*
3
3
  object-assign
4
4
  (c) Sindre Sorhus
@@ -206,4 +206,4 @@ Add a <Suspense fallback=...> component higher in the tree to provide a loading
206
206
  *
207
207
  * This source code is licensed under the ISC license.
208
208
  * See the LICENSE file in the root directory of this source tree.
209
- */const Qh=[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]],Kh=B("x",Qh),Pt="/xenon/api/auth";async function Fm(e,t){const n=await fetch(`${Pt}/login`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({email:e,password:t})});if(!n.ok){const r=await n.json().catch(()=>({}));throw new Error(r.error||`Login failed (${n.status})`)}}async function Xh(){await fetch(`${Pt}/logout`,{method:"POST",credentials:"include"})}async function Yh(){const e=await fetch(`${Pt}/me`,{credentials:"include"});if(e.status===401)return null;if(!e.ok)throw new Error(`Failed to fetch /me (${e.status})`);return e.json()}async function Bm(e,t){const n=await fetch(`${Pt}/change-password`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({oldPassword:e,newPassword:t})});if(!n.ok){const r=await n.json().catch(()=>({}));throw new Error(r.error||`Change password failed (${n.status})`)}}async function Vm(e){const t=await fetch(`${Pt}/forgot-password`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({email:e})});if(!t.ok&&t.status!==204)throw t.status===429?new Error("Too many attempts — try again later."):new Error(`Request failed (${t.status})`)}async function Wm(e){return(await fetch(`${Pt}/reset-password/check/${encodeURIComponent(e)}`)).ok}async function Hm(e,t){const n=await fetch(`${Pt}/reset-password`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({token:e,newPassword:t})});if(!n.ok&&n.status!==204){const r=await n.json().catch(()=>({}));throw new Error(r.error||`Reset failed (${n.status})`)}}const Ic=y.createContext(null);function Jh({children:e}){const[t,n]=y.useState(!0),[r,l]=y.useState(null);async function o(){try{l(await Yh())}finally{n(!1)}}async function i(){await Xh(),l(null),window.location.href="/xenon/login"}return y.useEffect(()=>{o()},[]),p.jsx(Ic.Provider,{value:{loading:t,me:r,refresh:o,signOut:i},children:e})}function Bi(){const e=y.useContext(Ic);if(!e)throw new Error("useAuth must be used inside AuthProvider");return e}function Zh(){const[e,t]=y.useState(0),[n]=y.useState(()=>Date.now());y.useEffect(()=>{const a=setInterval(()=>t(u=>u+1),5e3);return()=>clearInterval(a)},[]);const r=Math.floor((Date.now()-n)/1e3)+e*0,l=Math.floor(r/60),o=Math.floor(l/60),i=r<10?"Updated just now":r<60?`Updated ${r}s ago`:l<60?`Updated ${l}m ago`:`Updated ${o}h ago`,s=l>=10?"stale":l>=2?"aging":"fresh";return{label:i,staleness:s}}const bh=()=>{const e=sn(),{me:t,signOut:n}=Bi(),{label:r,staleness:l}=Zh(),[o,i]=y.useState(!1),s=y.useRef(null),a=((t==null?void 0:t.name)??"A").split(" ").map(g=>g[0]).slice(0,2).join("").toUpperCase(),u=(t==null?void 0:t.role)==="SUPER_ADMIN"?"Super Admin":(t==null?void 0:t.role)==="ADMIN"?"Admin":"Member";y.useEffect(()=>{const g=h=>{s.current&&!s.current.contains(h.target)&&i(!1)};return document.addEventListener("mousedown",g),()=>document.removeEventListener("mousedown",g)},[]);const v=()=>window.dispatchEvent(new CustomEvent("xenon.open-command-palette"));return p.jsx("header",{className:"fixed top-0 left-14 right-0 z-20 h-14 border-b border-[var(--border)] bg-[var(--bg)]/80 backdrop-blur-md",children:p.jsxs("div",{className:"flex items-center h-full px-4 gap-4",children:[p.jsx("button",{type:"button",onClick:()=>e("/overview"),className:"flex items-center gap-3 min-w-0 cursor-pointer","aria-label":"Xenon home",children:p.jsx("div",{className:"flex items-center gap-2",children:p.jsx("img",{src:"/xenon/logo.svg",alt:"Xenon Logo",className:"h-8 w-auto object-contain"})})}),p.jsx("div",{className:"flex-1 max-w-xl mx-auto",children:p.jsxs("button",{type:"button",onClick:v,className:"relative w-full h-9 flex items-center text-left","aria-label":"Open command palette",children:[p.jsx("div",{className:"w-full h-9 pl-9 pr-14 rounded-md bg-[var(--surface)] border border-[var(--border)] text-sm text-[var(--text-dim)] hover:border-[var(--border-strong)] hover:text-[var(--text)] transition-colors flex items-center",children:"Search devices, sessions, settings…"}),p.jsx(Lc,{className:"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-[var(--text-dim)]"}),p.jsx("kbd",{className:"absolute right-3 top-1/2 -translate-y-1/2 font-mono text-[10px] text-[var(--text-dim)] border border-[var(--border)] rounded px-1.5 py-0.5",children:"⌘K"})]})}),p.jsxs("div",{className:"flex items-center gap-3",children:[p.jsx("span",{className:`hidden md:inline text-xs font-mono transition-colors ${l==="stale"?"text-[var(--red)]":l==="aging"?"text-[var(--amber)]":"text-[var(--text-dim)]"}`,title:l==="stale"?"Data is stale — reconnection may be needed.":l==="aging"?"Data hasn’t updated in a while.":"Live data.",children:r}),p.jsxs("div",{className:"flex items-center gap-1.5 px-2.5 py-1 rounded-full bg-[var(--green)]/10 border border-[var(--green)]/20",children:[p.jsx("span",{className:"h-1.5 w-1.5 rounded-full bg-[var(--green)] pulse-dot"}),p.jsx("span",{className:"text-[11px] font-medium text-[var(--green)]",children:"Online"})]}),p.jsxs("div",{className:"relative",ref:s,children:[p.jsxs("button",{type:"button",className:"flex items-center gap-2 h-9 pl-1.5 pr-2.5 rounded-md border border-[var(--border)] hover:border-[var(--border-strong)] hover:bg-[var(--surface)] transition-colors",onClick:()=>i(g=>!g),"aria-haspopup":"true","aria-expanded":o,children:[p.jsx("span",{className:"h-6 w-6 rounded-full bg-[var(--green)]/15 text-[var(--green)] text-[11px] font-semibold flex items-center justify-center",children:a}),p.jsxs("span",{className:"flex flex-col items-start leading-tight",children:[p.jsx("span",{className:"text-xs text-[var(--text)]",children:(t==null?void 0:t.name)??"Account"}),p.jsx("span",{className:"text-[10px] text-[var(--text-dim)]",children:u})]}),p.jsx(ph,{className:"h-3.5 w-3.5 text-[var(--text-dim)]"})]}),o&&p.jsxs("div",{className:"absolute top-full right-0 mt-2 w-64 rounded-md border border-[var(--border)] bg-[var(--surface)] shadow-lg overflow-hidden",children:[p.jsxs("div",{className:"px-3 py-2",children:[p.jsx("div",{className:"text-[10px] uppercase tracking-wider text-[var(--text-dim)] mb-1",children:"Workspace"}),p.jsxs("div",{className:"flex items-center justify-between text-xs text-[var(--text)]",children:[p.jsx("span",{className:"text-[var(--text-muted)]",children:"Registry"}),p.jsx("span",{children:"Default"})]}),p.jsxs("div",{className:"flex items-center justify-between text-xs text-[var(--text)] mt-1",children:[p.jsx("span",{className:"text-[var(--text-muted)]",children:"Node"}),p.jsx("span",{children:"Root · Primary"})]})]}),p.jsx("div",{className:"h-px bg-[var(--border)]"}),p.jsxs("div",{className:"px-3 py-2",children:[p.jsx("div",{className:"text-[10px] uppercase tracking-wider text-[var(--text-dim)] mb-1",children:"System"}),p.jsxs("div",{className:"flex items-center justify-between text-xs text-[var(--text)]",children:[p.jsxs("span",{className:"flex items-center gap-1.5",children:[p.jsx("span",{className:"h-1.5 w-1.5 rounded-full bg-[var(--green)]"}),"Stable"]}),p.jsxs("span",{className:"font-mono text-[var(--text-muted)]",children:["v","0.3.0"]})]})]}),p.jsx("div",{className:"h-px bg-[var(--border)]"}),p.jsxs("button",{type:"button",onClick:()=>{i(!1),e("/profile")},className:"w-full flex items-center gap-2 px-3 py-2 text-xs text-[var(--text)] hover:bg-[var(--bg)] text-left",children:[p.jsx(qh,{className:"h-3.5 w-3.5 text-[var(--text-dim)]"}),"Profile"]}),p.jsxs("button",{type:"button",onClick:()=>{i(!1),n()},className:"w-full flex items-center gap-2 px-3 py-2 text-xs text-[var(--red)] hover:bg-[var(--bg)] text-left",children:[p.jsx(Nh,{className:"h-3.5 w-3.5"}),"Logout"]})]})]})]})]})})};class em extends y.Component{constructor(){super(...arguments),this.state={hasError:!1},this.handleReset=()=>{this.setState({hasError:!1}),window.location.reload()}}static getDerivedStateFromError(t){return{hasError:!0,error:t}}componentDidCatch(t,n){console.error("Uncaught error:",t,n)}render(){return this.state.hasError?this.props.fallback||p.jsxs("div",{className:"error-boundary-container",style:{padding:"4rem 2rem",textAlign:"center",display:"flex",flexDirection:"column",alignItems:"center",gap:"1.5rem",color:"var(--text)",background:"var(--bg-main)",minHeight:"100vh"},children:[p.jsx("div",{style:{color:"var(--accent-red)",filter:"drop-shadow(0 0 10px rgba(239, 68, 68, 0.3))"},children:p.jsx(Bh,{size:64})}),p.jsx("h2",{style:{fontSize:"2rem",fontWeight:700,margin:0},children:"Component Exception Detected"}),p.jsx("p",{style:{color:"var(--text-muted)",maxWidth:"500px",lineHeight:1.6},children:"An unexpected error occurred while rendering this section. Xenon's isolation engine has contained the fault to prevent a total system crash."}),this.state.error&&p.jsx("pre",{style:{background:"rgba(0,0,0,0.3)",padding:"1rem",borderRadius:"8px",fontSize:"0.8rem",color:"var(--accent-red)",maxWidth:"80%",overflowX:"auto"},children:this.state.error.message}),p.jsxs("button",{onClick:this.handleReset,style:{background:"var(--green)",color:"var(--secondary)",border:"none",padding:"0.75rem 2rem",borderRadius:"8px",fontWeight:700,cursor:"pointer",display:"flex",alignItems:"center",gap:"0.5rem",transition:"all 0.2s"},onMouseOver:t=>t.currentTarget.style.transform="translateY(-2px)",onMouseOut:t=>t.currentTarget.style.transform="translateY(0)",children:[p.jsx(Oc,{size:18}),"Reload Application"]})]}):this.props.children}}const tm=y.lazy(()=>Q(()=>import("./overview-DVgoOoYF.js"),__vite__mapDeps([0,1,2,3,4,5]))),ga=y.lazy(()=>Q(()=>import("./device-explorer-nV6L3w7x.js"),__vite__mapDeps([6,7,8,9,10,11,12,13,14,15,16,5,17,18,19,20,21,22,23,24,25,26,27,28,29,1,30]))),wa=y.lazy(()=>Q(()=>import("./builds-page-DgWXOgh5.js"),__vite__mapDeps([31,32,1,4,33,34,16,27,22,3]))),nm=y.lazy(()=>Q(()=>import("./session-detail-page-CEtQr37W.js"),__vite__mapDeps([35,32,1,10,11,36,22,17,37,38,39,40,41,12,13,27,42]))),rm=y.lazy(()=>Q(()=>import("./runbook-page-BRxjWJVQ.js"),__vite__mapDeps([43,36,44]))),lm=y.lazy(()=>Q(()=>import("./apps-CWWrkTZW.js"),__vite__mapDeps([45,8,9,7,20,17,21,27,26,46]))),om=y.lazy(()=>Q(()=>import("./webhook-settings-dAp8wwEB.js"),__vite__mapDeps([47,14,15,7,26,5,33,34,21,4,48,49])).then(e=>({default:e.WebhookSettings}))),im=y.lazy(()=>Q(()=>import("./settings-Cr-YjLbX.js"),__vite__mapDeps([50,51,52,7,1,53,34,16,18,20,4,37,49])).then(e=>({default:e.Settings}))),sm=y.lazy(()=>Q(()=>import("./ai-settings-AKMDh8pd.js"),__vite__mapDeps([54,51,52,7,25,34,4,49])).then(e=>({default:e.AISettings}))),am=y.lazy(()=>Q(()=>import("./maintenance-settings-Vr_u8hoR.js"),__vite__mapDeps([55,51,52,7,53,26,20,49])).then(e=>({default:e.MaintenanceSettings}))),um=y.lazy(()=>Q(()=>import("./api-keys-B5Q1EkGN.js"),__vite__mapDeps([56,40,41,14,15,7,12,13,23,5,26,20,17,49])).then(e=>({default:e.ApiKeys}))),cm=y.lazy(()=>Q(()=>import("./teams-B3Tt_9i2.js"),__vite__mapDeps([57,40,41,14,15,7,12,13,58,23,5,36,26,49])).then(e=>({default:e.Teams}))),fm=y.lazy(()=>Q(()=>import("./selector-health-page-tb5e3CXy.js"),__vite__mapDeps([59,21,60,61,34,12,13,20,17,1,38,39,7,28,29,2,22,37]))),dm=y.lazy(()=>Q(()=>import("./selector-detail-page-DcV8jQuX.js"),__vite__mapDeps([62,7,60,61,19,34,21,20,17]))),pm=y.lazy(()=>Q(()=>import("./DeviceMosaicView-DVk1IpIR.js"),__vite__mapDeps([63,24]))),hm=y.lazy(()=>Q(()=>import("./profile-page-DNKD4MS2.js"),__vite__mapDeps([64,17,26]))),mm=y.lazy(()=>Q(()=>import("./users-BIvjvjM6.js"),__vite__mapDeps([65,58,5,26]))),vm=()=>p.jsxs("div",{className:"flex items-center justify-center gap-2 h-full text-xs text-[var(--text-dim)]",children:[p.jsx(Oc,{className:"animate-spin",size:14}),p.jsx("span",{children:"Hydrating view…"})]}),ym=()=>p.jsx(em,{children:p.jsx(y.Suspense,{fallback:p.jsx(vm,{}),children:p.jsxs(Nc,{children:[p.jsx($,{path:"/",element:p.jsx(nl,{to:"/overview",replace:!0})}),p.jsx($,{path:"/overview",element:p.jsx(tm,{})}),p.jsx($,{path:"/devices",element:p.jsx(ga,{})}),p.jsx($,{path:"/devices/:udid/control/:tab?",element:p.jsx(ga,{})}),p.jsx($,{path:"/apps",element:p.jsx(lm,{})}),p.jsx($,{path:"/builds",element:p.jsx(wa,{})}),p.jsx($,{path:"/builds/:buildId",element:p.jsx(wa,{})}),p.jsx($,{path:"/builds/:buildId/sessions/:sessionId",element:p.jsx(nm,{})}),p.jsx($,{path:"/notifications",element:p.jsx(om,{})}),p.jsx($,{path:"/settings",element:p.jsx(im,{})}),p.jsx($,{path:"/ai-settings",element:p.jsx(sm,{})}),p.jsx($,{path:"/maintenance",element:p.jsx(am,{})}),p.jsx($,{path:"/api-keys",element:p.jsx(um,{})}),p.jsx($,{path:"/teams",element:p.jsx(cm,{})}),p.jsx($,{path:"/users",element:p.jsx(mm,{})}),p.jsx($,{path:"/selector-health",element:p.jsx(fm,{})}),p.jsx($,{path:"/selector-health/detail",element:p.jsx(dm,{})}),p.jsx($,{path:"/devices/live",element:p.jsx(pm,{})}),p.jsx($,{path:"/runbooks/:category",element:p.jsx(rm,{})}),p.jsx($,{path:"/profile",element:p.jsx(hm,{})}),p.jsx($,{path:"*",element:p.jsx(nl,{to:"/overview",replace:!0})})]})})});let Uo=null;function xa(e){Uo=e}class gm{makeGETRequest(t){return fetch(this.formatUrl(t)).then(this.jsonResult)}makePOSTRequest(t,n,r,l={}){return fetch(this.formatUrl(t),{method:"POST",body:JSON.stringify(r||{}),headers:{"Content-Type":"application/json"},...l}).then(this.jsonResult)}makeDELETERequest(t){return fetch(this.formatUrl(t),{method:"DELETE"}).then(this.jsonResult)}formatUrl(t){return`/xenon/api${t}`}async jsonResult(t){if(t.status===403){const n=await t.clone().json().catch(()=>({})),r=n&&(n.error||n.message)||"You do not have permission for this action.";Uo&&Uo(r,"error")}return t.json()}}const j=new gm,Mc=y.createContext(void 0),qm=()=>{const e=y.useContext(Mc);if(!e)throw new Error("useToast must be used within a ToastProvider");return e},wm=({children:e})=>{const[t,n]=y.useState([]),r=y.useCallback(o=>{n(i=>i.filter(s=>s.id!==o))},[]),l=y.useCallback((o,i="info",s=4e3)=>{const a=Math.random().toString(36).substring(2,9);return n(u=>[...u,{id:a,message:o,type:i,duration:s}]),i!=="loading"&&s>0&&setTimeout(()=>{r(a)},s),a},[r]);return y.useEffect(()=>(xa((o,i="info")=>l(o,i)),()=>xa(null)),[l]),p.jsxs(Mc.Provider,{value:{toast:l,removeToast:r},children:[e,p.jsx("div",{className:"toast-container","aria-live":"polite","aria-atomic":"true",role:"status",children:t.map(o=>p.jsxs("div",{className:`toast-item toast-${o.type} animate-slide-in`,children:[p.jsxs("div",{className:"toast-icon",children:[o.type==="success"&&p.jsx(yh,{size:18}),o.type==="error"&&p.jsx(mh,{size:18}),o.type==="info"&&p.jsx(kh,{size:18}),o.type==="loading"&&p.jsx(jh,{size:18,className:"animate-spin"})]}),p.jsx("div",{className:"toast-message",children:o.message}),p.jsx("button",{className:"toast-close",onClick:()=>r(o.id),"aria-label":`Close ${o.type} notification`,children:p.jsx(Kh,{size:14})})]},o.id))})]})},xm=[{id:"overview",label:"Overview",icon:Ch,path:"/overview"},{id:"devices",label:"Devices",icon:Uh,path:"/devices"},{id:"live-devices",label:"Live Devices",icon:Wh,path:"/devices/live"},{id:"apps",label:"Apps",icon:oh,path:"/apps"},{id:"sessions",label:"Sessions",icon:Oh,path:"/builds"},{id:"selector-health",label:"Selector Health",icon:wh,path:"/selector-health"},{id:"notifications",label:"Notifications",icon:sh,path:"/notifications"},{id:"settings",label:"Settings",icon:Dh,path:"/settings",minRole:"ADMIN"},{id:"ai",label:"AI",icon:fh,path:"/ai-settings",minRole:"ADMIN"},{id:"maintenance",label:"Maintenance",icon:zh,path:"/maintenance",minRole:"ADMIN"},{id:"teams",label:"Teams",icon:ya,path:"/teams",minRole:"ADMIN"},{id:"users",label:"Users",icon:ya,path:"/users",minRole:"ADMIN"},{id:"apikeys",label:"API Keys",icon:Sh,path:"/api-keys",minRole:"ADMIN"}],ka={SUPER_ADMIN:3,ADMIN:2,MEMBER:1};function km(e,t){return t?(e?ka[e]??0:0)>=ka[t]:!0}const Em=()=>{const e=sn(),t=at(),{me:n}=Bi(),r=xm.filter(s=>km(n==null?void 0:n.role,s.minRole)),l=t.pathname.replace(/\/$/,"")||"/",o=r.filter(s=>l===s.path||l.startsWith(s.path+"/")).sort((s,a)=>a.path.length-s.path.length)[0],i=s=>(o==null?void 0:o.path)===s;return p.jsxs("aside",{className:"fixed inset-y-0 left-0 z-30 w-14 border-r border-[var(--border)] bg-[var(--surface)] flex flex-col items-center py-3",children:[p.jsx("nav",{className:"flex-1 flex flex-col gap-1 w-full items-center",children:r.map(s=>{const a=s.icon,u=i(s.path);return p.jsxs("button",{type:"button",onClick:()=>e(s.path),className:`group relative w-full flex justify-center py-2.5 mx-1 rounded-md transition-colors ${u?"bg-[var(--surface-2)]":"hover:bg-[var(--surface-2)]/60"}`,"aria-label":s.label,"aria-current":u?"page":void 0,children:[p.jsx("span",{className:`absolute left-0 top-1 bottom-1 w-[3px] rounded-r transition-all ${u?"bg-[var(--green)]":"bg-transparent"}`}),p.jsx(a,{className:`h-[18px] w-[18px] transition-colors ${u?"text-[var(--green)]":"text-[var(--text-dim)] group-hover:text-[var(--text)]"}`,strokeWidth:u?2.25:2}),p.jsx("span",{className:"pointer-events-none absolute left-full ml-2 top-1/2 -translate-y-1/2 whitespace-nowrap rounded-md bg-[var(--surface-2)] border border-[var(--border-strong)] px-2 py-1 text-xs text-[var(--text)] opacity-0 group-hover:opacity-100 transition-opacity z-50 shadow-lg",children:s.label})]},s.id)})}),p.jsxs("button",{type:"button",className:"group relative w-full flex justify-center py-2.5 mt-2","aria-label":"API Docs",onClick:()=>window.open(window.location.origin+"/xenon/api-docs","_blank"),children:[p.jsx(uh,{className:"h-[18px] w-[18px] text-[var(--text-dim)] group-hover:text-[var(--text)] transition-colors"}),p.jsx("span",{className:"pointer-events-none absolute left-full ml-2 top-1/2 -translate-y-1/2 whitespace-nowrap rounded-md bg-[var(--surface-2)] border border-[var(--border-strong)] px-2 py-1 text-xs text-[var(--text)] opacity-0 group-hover:opacity-100 transition-opacity z-50 shadow-lg",children:"API Docs"})]})]})};class Ql{static getDevices(){return j.makeGETRequest(`/device?t=${Date.now()}`)}static getPendingSessionsCount(){return j.makeGETRequest("/queue/length")}static getPendingSessions(){return j.makeGETRequest("/queue")}static getQueueSummary(){return j.makeGETRequest("/queue/summary")}static getQueueStatus(t){return j.makeGETRequest(`/queue/status/${t}`)}static getBuilds(){return j.makeGETRequest("/build")}static getSessions(t={}){let r=`/session?t=${Date.now()}`;return t.buildId&&(r+=`&buildId=${encodeURIComponent(t.buildId)}`),t.query&&(r+=`&query=${encodeURIComponent(t.query)}`),t.status&&(r+=`&status=${encodeURIComponent(t.status)}`),t.platform&&(r+=`&platform=${encodeURIComponent(t.platform)}`),j.makeGETRequest(r)}static getSession(t){return j.makeGETRequest(`/session/${t}`)}static getSessionLogs(t){return j.makeGETRequest(`/session/${t}/session_log`)}static getDeviceLogs(t){return j.makeGETRequest(`/session/${t}/logs/device`)}static getDebugLogs(t){return j.makeGETRequest(`/session/${t}/logs/debug`)}static getProfilingData(t){return j.makeGETRequest(`/session/${t}/profiling`)}static omniScan(t){return j.makeGETRequest(`/session/${t}/xenon/omni-scan`)}static omniScanControl(t){return j.makeGETRequest(`/control/${t}/omni-scan`)}static testAiLocator(t,n,r){return j.makePOSTRequest(`/session/${t}/xenon/test-locator`,{},{strategy:n,selector:r})}static testAiLocatorControl(t,n,r){return j.makePOSTRequest(`/control/${t}/test-locator`,{},{strategy:n,selector:r})}static blockDevice(t,n){return j.makePOSTRequest("/block",{},{udid:t,host:n})}static unblockDevice(t,n){return j.makePOSTRequest("/unblock",{},{udid:t,host:n})}static updateDeviceTags(t,n,r){return j.makePOSTRequest("/device/tags",{},{udid:t,host:n,tags:r})}static async listTeams(){const t=await fetch("/xenon/api/teams",{credentials:"include"});if(!t.ok)throw new Error(`listTeams failed (${t.status})`);return(await t.json()).map(r=>({id:r.id,name:r.name}))}static async setDeviceTeam(t,n){const r=await fetch(`/xenon/api/grid/device/${encodeURIComponent(t)}/team`,{method:"PUT",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({teamId:n})});if(!r.ok&&r.status!==204){const l=await r.json().catch(()=>({}));throw new Error(l.error||`setDeviceTeam failed (${r.status})`)}}static getSessionLiveVideoUrl(t){return j.formatUrl(`/session/${t}/live_video`)}static getReservations(){return j.makeGETRequest("/reservation")}static reserveDevice(t,n,r,l,o){return j.makePOSTRequest("/reservation",{},{udid:t,host:n,reservedBy:r,duration:l,reason:o})}static releaseReservation(t,n){return j.makeDELETERequest(`/reservation/${t}/${encodeURIComponent(n)}`)}static extendReservation(t,n,r){return j.makePOSTRequest(`/reservation/${t}/${encodeURIComponent(n)}/extend`,{},{duration:r})}static getAssetUrl(t){return t?`/xenon/assets/${t.replace(/^\//,"")}`:""}static tap(t,n,r){return j.makePOSTRequest(`/control/${t}/tap`,{},{x:n,y:r})}static swipe(t,n,r,l,o){return j.makePOSTRequest(`/control/${t}/swipe`,{},{x:n,y:r,endX:l,endY:o})}static typeText(t,n){return j.makePOSTRequest(`/control/${t}/text`,{},{text:n})}static pressKey(t,n){return j.makePOSTRequest(`/control/${t}/keyevent`,{},{keyCode:n})}static getClipboard(t){return j.makeGETRequest(`/control/${t}/clipboard`)}static setClipboard(t,n){return j.makePOSTRequest(`/control/${t}/clipboard`,{},{content:n})}static getScreenshot(t){return j.makeGETRequest(`/control/${t}/screenshot`)}static touchAndHold(t,n,r,l){return j.makePOSTRequest(`/control/${t}/touchAndHold`,{},{x:n,y:r,duration:l})}static lock(t){return j.makePOSTRequest(`/control/${t}/lock`,{},{})}static unlock(t){return j.makePOSTRequest(`/control/${t}/unlock`,{},{})}static installApp(t,n){return j.makePOSTRequest(`/control/${t}/install`,{},{appPath:n})}static startStream(t){return j.makePOSTRequest(`/control/${t}/stream/start`,{},{})}static stopStream(t){return j.makePOSTRequest(`/control/${t}/stream/stop`,{},{},{keepalive:!0})}static uninstallApp(t,n){return j.makePOSTRequest(`/control/${t}/uninstall`,{},{bundleId:n})}static uploadAndInstallApp(t,n){const r=new FormData;return r.append("app",n),fetch(`/xenon/api/control/${t}/upload-install`,{method:"POST",body:r}).then(l=>l.json())}static listApps(t){return j.makeGETRequest(`/control/${t}/apps`)}static getLogs(t){return j.makeGETRequest(`/control/${t}/logs`)}static getApps(){return j.makeGETRequest("/apps")}static uploadApp(t){const n=new FormData;return n.append("app",t),fetch("/xenon/api/apps/upload",{method:"POST",body:n}).then(r=>r.json())}static deleteApp(t){return j.makeDELETERequest(`/apps/${t}`)}static installRepositoryApp(t,n){return j.makePOSTRequest(`/control/${t}/install-repository-app`,{},{appId:n})}static executeShell(t,n){return j.makePOSTRequest(`/control/${t}/shell`,{},{command:n})}static getInspectorSnapshot(t){return j.makeGETRequest(`/control/${t}/inspector/snapshot`)}static getWebhookConfigs(){return j.makeGETRequest("/webhook")}static addWebhookConfig(t,n,r,l){return j.makePOSTRequest("/webhook",{},{url:t,events:n,type:r,payloadTemplate:l})}static deleteWebhookConfig(t){return j.makeDELETERequest(`/webhook/${t}`)}static testWebhook(t,n){return j.makePOSTRequest("/webhook/test",{},{url:t,type:n})}static getGlobalConfig(){return j.makeGETRequest("/config")}static updateGlobalConfig(t){return j.makePOSTRequest("/config",{},t)}static testAIConfig(t){return j.makePOSTRequest("/config/test-ai",{},t)}static resetMetrics(){return j.makePOSTRequest("/config/reset-metrics",{},{})}static getRecentHealingEvents(t=50){return j.makeGETRequest(`/healing/events?limit=${t}&t=${Date.now()}`)}static getHealingSummary(t=30){return j.makeGETRequest(`/healing/summary?windowDays=${t}&t=${Date.now()}`)}static getHealingHotspots(t={}){const{windowDays:n=30,limit:r=20,tier:l,platform:o,status:i="active"}=t;let s=`/healing/hotspots?windowDays=${n}&limit=${r}&status=${i}&t=${Date.now()}`;return l&&(s+=`&tier=${encodeURIComponent(l)}`),o&&(s+=`&platform=${encodeURIComponent(o)}`),j.makeGETRequest(s)}static getMutedSelectors(t={}){const{limit:n=50,offset:r=0}=t;return j.makeGETRequest(`/healing/state/muted?limit=${n}&offset=${r}&t=${Date.now()}`)}static getSelectorState(t,n){return j.makeGETRequest(`/healing/state/${encodeURIComponent(t)}/${encodeURIComponent(n)}?t=${Date.now()}`)}static async postSelectorStateAction(t){const n=await fetch("/xenon/api/healing/selector/state",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)});if(!n.ok){const r=await n.json().catch(()=>({})),l=new Error(r.error??`Selector state action failed (${n.status})`);throw l.status=n.status,l.currentStatus=r.currentStatus??null,l}return n.json()}static getHealingSelectorDetail(t,n=30){return j.makeGETRequest(`/healing/selector?value=${encodeURIComponent(t)}&windowDays=${n}&t=${Date.now()}`)}static sendHealingDigest(t={}){return j.makePOSTRequest("/healing/digest/send",{},t)}static async exportBuild(t,n,r){const l=await fetch(`/xenon/api/build/${encodeURIComponent(t)}/export`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({format:n,...r?{sessionIds:r}:{}})});if(!l.ok){const u=await l.text().catch(()=>l.statusText);throw new Error(`Export failed (${l.status}): ${u||l.statusText}`)}const o=l.headers.get("Content-Disposition")||"",i=/filename="?([^";]+)"?/.exec(o),s=i?i[1]:`build-${t}-sessions.${n}`;return{blob:await l.blob(),filename:s}}}function Sm(e){if(!(e instanceof HTMLElement))return!1;if(e.isContentEditable)return!0;const t=e.tagName;return t==="INPUT"||t==="TEXTAREA"||t==="SELECT"}function _m(){const[e,t]=y.useState(!1);return y.useEffect(()=>{const n=l=>{(l.metaKey||l.ctrlKey)&&l.key.toLowerCase()==="k"&&!Sm(l.target)&&(l.preventDefault(),t(o=>!o)),l.key==="Escape"&&t(!1)},r=()=>t(!0);return window.addEventListener("keydown",n),window.addEventListener("xenon.open-command-palette",r),()=>{window.removeEventListener("keydown",n),window.removeEventListener("xenon.open-command-palette",r)}},[]),{open:e,setOpen:t}}function Ea(e,t){if(!e)return 0;const n=e.toLowerCase(),r=t.toLowerCase();if(r===n)return 1e4;if(r.startsWith(n))return 5e3-(r.length-n.length);let l=0,o=0,i=0;for(let s=0;s<n.length;s++){const a=n[s],u=r.indexOf(a,l);if(u===-1)return 0;u===l?(i+=1,o+=20+i*5):(i=0,o+=10-Math.min(u-l,10)),l=u+1}return Math.max(o,1)}const Sa=[{id:"nav:overview",kind:"nav",label:"Overview",path:"/overview"},{id:"nav:devices",kind:"nav",label:"Devices",path:"/devices"},{id:"nav:builds",kind:"nav",label:"Sessions",path:"/builds"},{id:"nav:apps",kind:"nav",label:"Apps",path:"/apps"},{id:"nav:notifications",kind:"nav",label:"Notifications",path:"/notifications"},{id:"nav:settings",kind:"nav",label:"Settings",path:"/settings"},{id:"nav:ai-settings",kind:"nav",label:"AI Engine",path:"/ai-settings"},{id:"nav:maintenance",kind:"nav",label:"Maintenance",path:"/maintenance"},{id:"nav:teams",kind:"nav",label:"Teams",path:"/teams"},{id:"nav:api-keys",kind:"nav",label:"API Keys",path:"/api-keys"}];class Cm{constructor(){this.devices=[],this.sessions=[],this.teams=[],this.keys=[],this.apps=[]}setDevices(t){this.devices=t.map(n=>({id:`device:${n.udid}`,kind:"device",label:n.name||n.udid,sub:n.udid,path:`/devices/${n.udid}/control`}))}setSessions(t){this.sessions=t.map(n=>({id:`session:${n.id}`,kind:"session",label:n.name||n.id,sub:n.id,path:`/builds?session=${encodeURIComponent(n.id)}`}))}setTeams(t){this.teams=t.map(n=>({id:`team:${n.id}`,kind:"team",label:n.name||n.id,sub:n.id,path:`/teams?team=${encodeURIComponent(n.id)}`}))}setKeys(t){this.keys=t.map(n=>({id:`key:${n.id}`,kind:"key",label:n.name||n.id,sub:n.id,path:`/api-keys?key=${encodeURIComponent(n.id)}`}))}setApps(t){this.apps=t.map(n=>({id:`app:${n.id}`,kind:"app",label:n.name||n.id,sub:n.id,path:`/apps?app=${encodeURIComponent(n.id)}`}))}search(t,n=8){return t.trim()?[...Sa,...this.devices,...this.sessions,...this.teams,...this.keys,...this.apps].map(l=>{const o=Ea(t,l.label),i=l.sub?Ea(t,l.sub):0;return{it:l,score:Math.max(o,i)}}).filter(l=>l.score>0).sort((l,o)=>o.score-l.score).slice(0,n).map(l=>l.it):Sa.slice(0,n)}}const Pm={nav:"Navigation",device:"Devices",session:"Sessions",team:"Teams",key:"API Keys",app:"Apps"},jm=["nav","device","session","team","key","app"],Rm=()=>{const{open:e,setOpen:t}=_m(),[n,r]=y.useState(""),[l,o]=y.useState(0),i=sn(),s=y.useRef(new Cm),a=y.useRef(null);y.useEffect(()=>{if(!e)return;Promise.all([Ql.getDevices().catch(()=>[]),Ql.getSessions().catch(()=>[]),Ql.getApps().catch(()=>[])]).then(([x,c,f])=>{Array.isArray(x)&&s.current.setDevices(x),Array.isArray(c)&&s.current.setSessions(c),Array.isArray(f)&&s.current.setApps(f)});const k=setTimeout(()=>{var x;return(x=a.current)==null?void 0:x.focus()},0);return()=>clearTimeout(k)},[e]),y.useEffect(()=>{e||(r(""),o(0))},[e]);const u=y.useMemo(()=>s.current.search(n,8),[n,e]),v=y.useMemo(()=>{const k=new Map;return u.forEach(x=>{const c=k.get(x.kind)||[];c.push(x),k.set(x.kind,c)}),k},[u]),g=y.useCallback(k=>{i(k.path),t(!1)},[i,t]),h=k=>{k.key==="ArrowDown"?(k.preventDefault(),o(x=>Math.min(x+1,Math.max(u.length-1,0)))):k.key==="ArrowUp"?(k.preventDefault(),o(x=>Math.max(x-1,0))):k.key==="Enter"&&(k.preventDefault(),u[l]&&g(u[l]))};if(!e)return null;let S=-1;return p.jsx("div",{className:"cp-overlay",onClick:()=>t(!1),children:p.jsxs("div",{className:"cp",role:"dialog","aria-modal":!0,"aria-label":"Command palette",onClick:k=>k.stopPropagation(),children:[p.jsxs("div",{className:"cp-input-row",children:[p.jsx(Lc,{size:14}),p.jsx("input",{ref:a,className:"cp-input",placeholder:"Search devices, sessions, settings…",value:n,onChange:k=>{r(k.target.value),o(0)},onKeyDown:h}),p.jsx("span",{className:"cp-esc",children:"ESC"})]}),p.jsxs("div",{className:"cp-results",children:[u.length===0&&p.jsx("div",{className:"cp-empty",children:"No results."}),jm.filter(k=>v.has(k)).map(k=>p.jsxs("div",{className:"cp-group",children:[p.jsx("div",{className:"cp-group-head",children:Pm[k]}),v.get(k).map(x=>{S+=1;const c=S===l;return p.jsxs("button",{type:"button",className:`cp-item${c?" cp-item-active":""}`,onMouseEnter:()=>{o(S)},onClick:()=>g(x),children:[p.jsx("span",{className:"cp-item-label",children:x.label}),x.sub&&p.jsx("span",{className:"cp-item-sub",children:x.sub})]},x.id)})]},k))]})]})})};function Nm({children:e}){const{loading:t,me:n}=Bi(),r=at();if(t)return p.jsx("div",{style:{padding:40,textAlign:"center",color:"var(--text-dim)"},children:"Loading…"});if(!n){const l=encodeURIComponent(r.pathname+r.search);return p.jsx(nl,{to:`/login?next=${l}`,replace:!0})}return p.jsx(p.Fragment,{children:e})}const Tm=y.lazy(()=>Q(()=>import("./login-BavGkTli.js"),[])),Om=y.lazy(()=>Q(()=>import("./forgot-password-CsAF11d2.js"),[])),Lm=y.lazy(()=>Q(()=>import("./reset-password-C2gSMy8a.js"),[])),Im=y.lazy(()=>Q(()=>import("./ApiKeyGate-BSN8crwz.js"),[]).then(e=>({default:e.ApiKeyGate})));function Mm(){return p.jsx(wm,{children:p.jsxs("div",{className:"min-h-screen w-full bg-[var(--bg)] text-[var(--text)]",children:[p.jsx(Em,{}),p.jsx(bh,{}),p.jsx("main",{className:"pl-14 pt-14 h-screen overflow-y-auto",children:p.jsx(ym,{})}),p.jsx(Rm,{})]})})}function Dm(){return p.jsx(Xp,{basename:"/xenon",children:p.jsx(Jh,{children:p.jsx(y.Suspense,{fallback:p.jsx("div",{style:{padding:40},children:"Loading…"}),children:p.jsxs(Nc,{children:[p.jsx($,{path:"/login",element:p.jsx(Tm,{})}),p.jsx($,{path:"/forgot-password",element:p.jsx(Om,{})}),p.jsx($,{path:"/reset-password/:token",element:p.jsx(Lm,{})}),p.jsx($,{path:"/api-key-gate",element:p.jsx(Im,{children:p.jsx(nl,{to:"/overview",replace:!0})})}),p.jsx($,{path:"*",element:p.jsx(Nm,{children:p.jsx(Mm,{})})})]})})})})}wc.render(p.jsx(y.StrictMode,{children:p.jsx(Dm,{})}),document.getElementById("root"));export{Um as A,uh as B,mh as C,Bm as D,wh as H,kh as I,Sh as K,Am as L,Qc as R,Uh as S,Wh as T,qh as U,Ql as X,at as a,Bi as b,zm as c,Wm as d,Hm as e,Vm as f,B as g,wc as h,$m as i,p as j,Gc as k,Fm as l,qm as m,Kh as n,Lc as o,Bh as p,ph as q,y as r,zh as s,jh as t,sn as u,Oc as v,_a as w,sh as x,fh as y,ya as z};
209
+ */const Qh=[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]],Kh=B("x",Qh),Pt="/xenon/api/auth";async function Fm(e,t){const n=await fetch(`${Pt}/login`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({email:e,password:t})});if(!n.ok){const r=await n.json().catch(()=>({}));throw new Error(r.error||`Login failed (${n.status})`)}}async function Xh(){await fetch(`${Pt}/logout`,{method:"POST",credentials:"include"})}async function Yh(){const e=await fetch(`${Pt}/me`,{credentials:"include"});if(e.status===401)return null;if(!e.ok)throw new Error(`Failed to fetch /me (${e.status})`);return e.json()}async function Bm(e,t){const n=await fetch(`${Pt}/change-password`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({oldPassword:e,newPassword:t})});if(!n.ok){const r=await n.json().catch(()=>({}));throw new Error(r.error||`Change password failed (${n.status})`)}}async function Vm(e){const t=await fetch(`${Pt}/forgot-password`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({email:e})});if(!t.ok&&t.status!==204)throw t.status===429?new Error("Too many attempts — try again later."):new Error(`Request failed (${t.status})`)}async function Wm(e){return(await fetch(`${Pt}/reset-password/check/${encodeURIComponent(e)}`)).ok}async function Hm(e,t){const n=await fetch(`${Pt}/reset-password`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({token:e,newPassword:t})});if(!n.ok&&n.status!==204){const r=await n.json().catch(()=>({}));throw new Error(r.error||`Reset failed (${n.status})`)}}const Ic=y.createContext(null);function Jh({children:e}){const[t,n]=y.useState(!0),[r,l]=y.useState(null);async function o(){try{l(await Yh())}finally{n(!1)}}async function i(){await Xh(),l(null),window.location.href="/xenon/login"}return y.useEffect(()=>{o()},[]),p.jsx(Ic.Provider,{value:{loading:t,me:r,refresh:o,signOut:i},children:e})}function Bi(){const e=y.useContext(Ic);if(!e)throw new Error("useAuth must be used inside AuthProvider");return e}function Zh(){const[e,t]=y.useState(0),[n]=y.useState(()=>Date.now());y.useEffect(()=>{const a=setInterval(()=>t(u=>u+1),5e3);return()=>clearInterval(a)},[]);const r=Math.floor((Date.now()-n)/1e3)+e*0,l=Math.floor(r/60),o=Math.floor(l/60),i=r<10?"Updated just now":r<60?`Updated ${r}s ago`:l<60?`Updated ${l}m ago`:`Updated ${o}h ago`,s=l>=10?"stale":l>=2?"aging":"fresh";return{label:i,staleness:s}}const bh=()=>{const e=sn(),{me:t,signOut:n}=Bi(),{label:r,staleness:l}=Zh(),[o,i]=y.useState(!1),s=y.useRef(null),a=((t==null?void 0:t.name)??"A").split(" ").map(g=>g[0]).slice(0,2).join("").toUpperCase(),u=(t==null?void 0:t.role)==="SUPER_ADMIN"?"Super Admin":(t==null?void 0:t.role)==="ADMIN"?"Admin":"Member";y.useEffect(()=>{const g=h=>{s.current&&!s.current.contains(h.target)&&i(!1)};return document.addEventListener("mousedown",g),()=>document.removeEventListener("mousedown",g)},[]);const v=()=>window.dispatchEvent(new CustomEvent("xenon.open-command-palette"));return p.jsx("header",{className:"fixed top-0 left-14 right-0 z-20 h-14 border-b border-[var(--border)] bg-[var(--bg)]/80 backdrop-blur-md",children:p.jsxs("div",{className:"flex items-center h-full px-4 gap-4",children:[p.jsx("button",{type:"button",onClick:()=>e("/overview"),className:"flex items-center gap-3 min-w-0 cursor-pointer","aria-label":"Xenon home",children:p.jsx("div",{className:"flex items-center gap-2",children:p.jsx("img",{src:"/xenon/logo.svg",alt:"Xenon Logo",className:"h-8 w-auto object-contain"})})}),p.jsx("div",{className:"flex-1 max-w-xl mx-auto",children:p.jsxs("button",{type:"button",onClick:v,className:"relative w-full h-9 flex items-center text-left","aria-label":"Open command palette",children:[p.jsx("div",{className:"w-full h-9 pl-9 pr-14 rounded-md bg-[var(--surface)] border border-[var(--border)] text-sm text-[var(--text-dim)] hover:border-[var(--border-strong)] hover:text-[var(--text)] transition-colors flex items-center",children:"Search devices, sessions, settings…"}),p.jsx(Lc,{className:"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-[var(--text-dim)]"}),p.jsx("kbd",{className:"absolute right-3 top-1/2 -translate-y-1/2 font-mono text-[10px] text-[var(--text-dim)] border border-[var(--border)] rounded px-1.5 py-0.5",children:"⌘K"})]})}),p.jsxs("div",{className:"flex items-center gap-3",children:[p.jsx("span",{className:`hidden md:inline text-xs font-mono transition-colors ${l==="stale"?"text-[var(--red)]":l==="aging"?"text-[var(--amber)]":"text-[var(--text-dim)]"}`,title:l==="stale"?"Data is stale — reconnection may be needed.":l==="aging"?"Data hasn’t updated in a while.":"Live data.",children:r}),p.jsxs("div",{className:"flex items-center gap-1.5 px-2.5 py-1 rounded-full bg-[var(--green)]/10 border border-[var(--green)]/20",children:[p.jsx("span",{className:"h-1.5 w-1.5 rounded-full bg-[var(--green)] pulse-dot"}),p.jsx("span",{className:"text-[11px] font-medium text-[var(--green)]",children:"Online"})]}),p.jsxs("div",{className:"relative",ref:s,children:[p.jsxs("button",{type:"button",className:"flex items-center gap-2 h-9 pl-1.5 pr-2.5 rounded-md border border-[var(--border)] hover:border-[var(--border-strong)] hover:bg-[var(--surface)] transition-colors",onClick:()=>i(g=>!g),"aria-haspopup":"true","aria-expanded":o,children:[p.jsx("span",{className:"h-6 w-6 rounded-full bg-[var(--green)]/15 text-[var(--green)] text-[11px] font-semibold flex items-center justify-center",children:a}),p.jsxs("span",{className:"flex flex-col items-start leading-tight",children:[p.jsx("span",{className:"text-xs text-[var(--text)]",children:(t==null?void 0:t.name)??"Account"}),p.jsx("span",{className:"text-[10px] text-[var(--text-dim)]",children:u})]}),p.jsx(ph,{className:"h-3.5 w-3.5 text-[var(--text-dim)]"})]}),o&&p.jsxs("div",{className:"absolute top-full right-0 mt-2 w-64 rounded-md border border-[var(--border)] bg-[var(--surface)] shadow-lg overflow-hidden",children:[p.jsxs("div",{className:"px-3 py-2",children:[p.jsx("div",{className:"text-[10px] uppercase tracking-wider text-[var(--text-dim)] mb-1",children:"Workspace"}),p.jsxs("div",{className:"flex items-center justify-between text-xs text-[var(--text)]",children:[p.jsx("span",{className:"text-[var(--text-muted)]",children:"Registry"}),p.jsx("span",{children:"Default"})]}),p.jsxs("div",{className:"flex items-center justify-between text-xs text-[var(--text)] mt-1",children:[p.jsx("span",{className:"text-[var(--text-muted)]",children:"Node"}),p.jsx("span",{children:"Root · Primary"})]})]}),p.jsx("div",{className:"h-px bg-[var(--border)]"}),p.jsxs("div",{className:"px-3 py-2",children:[p.jsx("div",{className:"text-[10px] uppercase tracking-wider text-[var(--text-dim)] mb-1",children:"System"}),p.jsxs("div",{className:"flex items-center justify-between text-xs text-[var(--text)]",children:[p.jsxs("span",{className:"flex items-center gap-1.5",children:[p.jsx("span",{className:"h-1.5 w-1.5 rounded-full bg-[var(--green)]"}),"Stable"]}),p.jsxs("span",{className:"font-mono text-[var(--text-muted)]",children:["v","0.3.0"]})]})]}),p.jsx("div",{className:"h-px bg-[var(--border)]"}),p.jsxs("button",{type:"button",onClick:()=>{i(!1),e("/profile")},className:"w-full flex items-center gap-2 px-3 py-2 text-xs text-[var(--text)] hover:bg-[var(--bg)] text-left",children:[p.jsx(qh,{className:"h-3.5 w-3.5 text-[var(--text-dim)]"}),"Profile"]}),p.jsxs("button",{type:"button",onClick:()=>{i(!1),n()},className:"w-full flex items-center gap-2 px-3 py-2 text-xs text-[var(--red)] hover:bg-[var(--bg)] text-left",children:[p.jsx(Nh,{className:"h-3.5 w-3.5"}),"Logout"]})]})]})]})]})})};class em extends y.Component{constructor(){super(...arguments),this.state={hasError:!1},this.handleReset=()=>{this.setState({hasError:!1}),window.location.reload()}}static getDerivedStateFromError(t){return{hasError:!0,error:t}}componentDidCatch(t,n){console.error("Uncaught error:",t,n)}render(){return this.state.hasError?this.props.fallback||p.jsxs("div",{className:"error-boundary-container",style:{padding:"4rem 2rem",textAlign:"center",display:"flex",flexDirection:"column",alignItems:"center",gap:"1.5rem",color:"var(--text)",background:"var(--bg-main)",minHeight:"100vh"},children:[p.jsx("div",{style:{color:"var(--accent-red)",filter:"drop-shadow(0 0 10px rgba(239, 68, 68, 0.3))"},children:p.jsx(Bh,{size:64})}),p.jsx("h2",{style:{fontSize:"2rem",fontWeight:700,margin:0},children:"Component Exception Detected"}),p.jsx("p",{style:{color:"var(--text-muted)",maxWidth:"500px",lineHeight:1.6},children:"An unexpected error occurred while rendering this section. Xenon's isolation engine has contained the fault to prevent a total system crash."}),this.state.error&&p.jsx("pre",{style:{background:"rgba(0,0,0,0.3)",padding:"1rem",borderRadius:"8px",fontSize:"0.8rem",color:"var(--accent-red)",maxWidth:"80%",overflowX:"auto"},children:this.state.error.message}),p.jsxs("button",{onClick:this.handleReset,style:{background:"var(--green)",color:"var(--secondary)",border:"none",padding:"0.75rem 2rem",borderRadius:"8px",fontWeight:700,cursor:"pointer",display:"flex",alignItems:"center",gap:"0.5rem",transition:"all 0.2s"},onMouseOver:t=>t.currentTarget.style.transform="translateY(-2px)",onMouseOut:t=>t.currentTarget.style.transform="translateY(0)",children:[p.jsx(Oc,{size:18}),"Reload Application"]})]}):this.props.children}}const tm=y.lazy(()=>Q(()=>import("./overview-DvyGTzku.js"),__vite__mapDeps([0,1,2,3,4,5]))),ga=y.lazy(()=>Q(()=>import("./device-explorer-CpC-MZNT.js"),__vite__mapDeps([6,7,8,9,10,11,12,13,14,15,16,5,17,18,19,20,21,22,23,24,25,26,27,28,29,1,30]))),wa=y.lazy(()=>Q(()=>import("./builds-page-DkLt4J8-.js"),__vite__mapDeps([31,32,1,4,33,34,16,27,22,3]))),nm=y.lazy(()=>Q(()=>import("./session-detail-page-DzW5PcxL.js"),__vite__mapDeps([35,32,1,10,11,36,22,17,37,38,39,40,41,12,13,27,42]))),rm=y.lazy(()=>Q(()=>import("./runbook-page-CXZdhAjc.js"),__vite__mapDeps([43,36,44]))),lm=y.lazy(()=>Q(()=>import("./apps-BfEC5qsb.js"),__vite__mapDeps([45,8,9,7,20,17,21,27,26,46]))),om=y.lazy(()=>Q(()=>import("./webhook-settings-BPf_iC_h.js"),__vite__mapDeps([47,14,15,7,26,5,33,34,21,4,48,49])).then(e=>({default:e.WebhookSettings}))),im=y.lazy(()=>Q(()=>import("./settings-COrR3YcC.js"),__vite__mapDeps([50,51,52,7,1,53,34,16,18,20,4,37,49])).then(e=>({default:e.Settings}))),sm=y.lazy(()=>Q(()=>import("./ai-settings-DteGlf4r.js"),__vite__mapDeps([54,51,52,7,25,34,4,49])).then(e=>({default:e.AISettings}))),am=y.lazy(()=>Q(()=>import("./maintenance-settings-CBnV_5Rl.js"),__vite__mapDeps([55,51,52,7,53,26,20,49])).then(e=>({default:e.MaintenanceSettings}))),um=y.lazy(()=>Q(()=>import("./api-keys-BmikiaSF.js"),__vite__mapDeps([56,40,41,14,15,7,12,13,23,5,26,20,17,49])).then(e=>({default:e.ApiKeys}))),cm=y.lazy(()=>Q(()=>import("./teams-xa_B0pyz.js"),__vite__mapDeps([57,40,41,14,15,7,12,13,58,23,5,36,26,49])).then(e=>({default:e.Teams}))),fm=y.lazy(()=>Q(()=>import("./selector-health-page-CrR7bh4f.js"),__vite__mapDeps([59,21,60,61,34,12,13,20,17,1,38,39,7,28,29,2,22,37]))),dm=y.lazy(()=>Q(()=>import("./selector-detail-page-C6yA7Lwl.js"),__vite__mapDeps([62,7,60,61,19,34,21,20,17]))),pm=y.lazy(()=>Q(()=>import("./DeviceMosaicView-DP4AanNV.js"),__vite__mapDeps([63,24]))),hm=y.lazy(()=>Q(()=>import("./profile-page-Cner_Muq.js"),__vite__mapDeps([64,17,26]))),mm=y.lazy(()=>Q(()=>import("./users-DJDpKaGy.js"),__vite__mapDeps([65,58,5,26]))),vm=()=>p.jsxs("div",{className:"flex items-center justify-center gap-2 h-full text-xs text-[var(--text-dim)]",children:[p.jsx(Oc,{className:"animate-spin",size:14}),p.jsx("span",{children:"Hydrating view…"})]}),ym=()=>p.jsx(em,{children:p.jsx(y.Suspense,{fallback:p.jsx(vm,{}),children:p.jsxs(Nc,{children:[p.jsx($,{path:"/",element:p.jsx(nl,{to:"/overview",replace:!0})}),p.jsx($,{path:"/overview",element:p.jsx(tm,{})}),p.jsx($,{path:"/devices",element:p.jsx(ga,{})}),p.jsx($,{path:"/devices/:udid/control/:tab?",element:p.jsx(ga,{})}),p.jsx($,{path:"/apps",element:p.jsx(lm,{})}),p.jsx($,{path:"/builds",element:p.jsx(wa,{})}),p.jsx($,{path:"/builds/:buildId",element:p.jsx(wa,{})}),p.jsx($,{path:"/builds/:buildId/sessions/:sessionId",element:p.jsx(nm,{})}),p.jsx($,{path:"/notifications",element:p.jsx(om,{})}),p.jsx($,{path:"/settings",element:p.jsx(im,{})}),p.jsx($,{path:"/ai-settings",element:p.jsx(sm,{})}),p.jsx($,{path:"/maintenance",element:p.jsx(am,{})}),p.jsx($,{path:"/api-keys",element:p.jsx(um,{})}),p.jsx($,{path:"/teams",element:p.jsx(cm,{})}),p.jsx($,{path:"/users",element:p.jsx(mm,{})}),p.jsx($,{path:"/selector-health",element:p.jsx(fm,{})}),p.jsx($,{path:"/selector-health/detail",element:p.jsx(dm,{})}),p.jsx($,{path:"/devices/live",element:p.jsx(pm,{})}),p.jsx($,{path:"/runbooks/:category",element:p.jsx(rm,{})}),p.jsx($,{path:"/profile",element:p.jsx(hm,{})}),p.jsx($,{path:"*",element:p.jsx(nl,{to:"/overview",replace:!0})})]})})});let Uo=null;function xa(e){Uo=e}class gm{makeGETRequest(t){return fetch(this.formatUrl(t)).then(this.jsonResult)}makePOSTRequest(t,n,r,l={}){return fetch(this.formatUrl(t),{method:"POST",body:JSON.stringify(r||{}),headers:{"Content-Type":"application/json"},...l}).then(this.jsonResult)}makeDELETERequest(t){return fetch(this.formatUrl(t),{method:"DELETE"}).then(this.jsonResult)}formatUrl(t){return`/xenon/api${t}`}async jsonResult(t){if(t.status===403){const n=await t.clone().json().catch(()=>({})),r=n&&(n.error||n.message)||"You do not have permission for this action.";Uo&&Uo(r,"error")}return t.json()}}const j=new gm,Mc=y.createContext(void 0),qm=()=>{const e=y.useContext(Mc);if(!e)throw new Error("useToast must be used within a ToastProvider");return e},wm=({children:e})=>{const[t,n]=y.useState([]),r=y.useCallback(o=>{n(i=>i.filter(s=>s.id!==o))},[]),l=y.useCallback((o,i="info",s=4e3)=>{const a=Math.random().toString(36).substring(2,9);return n(u=>[...u,{id:a,message:o,type:i,duration:s}]),i!=="loading"&&s>0&&setTimeout(()=>{r(a)},s),a},[r]);return y.useEffect(()=>(xa((o,i="info")=>l(o,i)),()=>xa(null)),[l]),p.jsxs(Mc.Provider,{value:{toast:l,removeToast:r},children:[e,p.jsx("div",{className:"toast-container","aria-live":"polite","aria-atomic":"true",role:"status",children:t.map(o=>p.jsxs("div",{className:`toast-item toast-${o.type} animate-slide-in`,children:[p.jsxs("div",{className:"toast-icon",children:[o.type==="success"&&p.jsx(yh,{size:18}),o.type==="error"&&p.jsx(mh,{size:18}),o.type==="info"&&p.jsx(kh,{size:18}),o.type==="loading"&&p.jsx(jh,{size:18,className:"animate-spin"})]}),p.jsx("div",{className:"toast-message",children:o.message}),p.jsx("button",{className:"toast-close",onClick:()=>r(o.id),"aria-label":`Close ${o.type} notification`,children:p.jsx(Kh,{size:14})})]},o.id))})]})},xm=[{id:"overview",label:"Overview",icon:Ch,path:"/overview"},{id:"devices",label:"Devices",icon:Uh,path:"/devices"},{id:"live-devices",label:"Live Devices",icon:Wh,path:"/devices/live"},{id:"apps",label:"Apps",icon:oh,path:"/apps"},{id:"sessions",label:"Sessions",icon:Oh,path:"/builds"},{id:"selector-health",label:"Selector Health",icon:wh,path:"/selector-health"},{id:"notifications",label:"Notifications",icon:sh,path:"/notifications"},{id:"settings",label:"Settings",icon:Dh,path:"/settings",minRole:"ADMIN"},{id:"ai",label:"AI",icon:fh,path:"/ai-settings",minRole:"ADMIN"},{id:"maintenance",label:"Maintenance",icon:zh,path:"/maintenance",minRole:"ADMIN"},{id:"teams",label:"Teams",icon:ya,path:"/teams",minRole:"ADMIN"},{id:"users",label:"Users",icon:ya,path:"/users",minRole:"ADMIN"},{id:"apikeys",label:"API Keys",icon:Sh,path:"/api-keys",minRole:"ADMIN"}],ka={SUPER_ADMIN:3,ADMIN:2,MEMBER:1};function km(e,t){return t?(e?ka[e]??0:0)>=ka[t]:!0}const Em=()=>{const e=sn(),t=at(),{me:n}=Bi(),r=xm.filter(s=>km(n==null?void 0:n.role,s.minRole)),l=t.pathname.replace(/\/$/,"")||"/",o=r.filter(s=>l===s.path||l.startsWith(s.path+"/")).sort((s,a)=>a.path.length-s.path.length)[0],i=s=>(o==null?void 0:o.path)===s;return p.jsxs("aside",{className:"fixed inset-y-0 left-0 z-30 w-14 border-r border-[var(--border)] bg-[var(--surface)] flex flex-col items-center py-3",children:[p.jsx("nav",{className:"flex-1 flex flex-col gap-1 w-full items-center",children:r.map(s=>{const a=s.icon,u=i(s.path);return p.jsxs("button",{type:"button",onClick:()=>e(s.path),className:`group relative w-full flex justify-center py-2.5 mx-1 rounded-md transition-colors ${u?"bg-[var(--surface-2)]":"hover:bg-[var(--surface-2)]/60"}`,"aria-label":s.label,"aria-current":u?"page":void 0,children:[p.jsx("span",{className:`absolute left-0 top-1 bottom-1 w-[3px] rounded-r transition-all ${u?"bg-[var(--green)]":"bg-transparent"}`}),p.jsx(a,{className:`h-[18px] w-[18px] transition-colors ${u?"text-[var(--green)]":"text-[var(--text-dim)] group-hover:text-[var(--text)]"}`,strokeWidth:u?2.25:2}),p.jsx("span",{className:"pointer-events-none absolute left-full ml-2 top-1/2 -translate-y-1/2 whitespace-nowrap rounded-md bg-[var(--surface-2)] border border-[var(--border-strong)] px-2 py-1 text-xs text-[var(--text)] opacity-0 group-hover:opacity-100 transition-opacity z-50 shadow-lg",children:s.label})]},s.id)})}),p.jsxs("button",{type:"button",className:"group relative w-full flex justify-center py-2.5 mt-2","aria-label":"API Docs",onClick:()=>window.open(window.location.origin+"/xenon/api-docs","_blank"),children:[p.jsx(uh,{className:"h-[18px] w-[18px] text-[var(--text-dim)] group-hover:text-[var(--text)] transition-colors"}),p.jsx("span",{className:"pointer-events-none absolute left-full ml-2 top-1/2 -translate-y-1/2 whitespace-nowrap rounded-md bg-[var(--surface-2)] border border-[var(--border-strong)] px-2 py-1 text-xs text-[var(--text)] opacity-0 group-hover:opacity-100 transition-opacity z-50 shadow-lg",children:"API Docs"})]})]})};class Ql{static getDevices(){return j.makeGETRequest(`/device?t=${Date.now()}`)}static getPendingSessionsCount(){return j.makeGETRequest("/queue/length")}static getPendingSessions(){return j.makeGETRequest("/queue")}static getQueueSummary(){return j.makeGETRequest("/queue/summary")}static getQueueStatus(t){return j.makeGETRequest(`/queue/status/${t}`)}static getBuilds(){return j.makeGETRequest("/build")}static getSessions(t={}){let r=`/session?t=${Date.now()}`;return t.buildId&&(r+=`&buildId=${encodeURIComponent(t.buildId)}`),t.query&&(r+=`&query=${encodeURIComponent(t.query)}`),t.status&&(r+=`&status=${encodeURIComponent(t.status)}`),t.platform&&(r+=`&platform=${encodeURIComponent(t.platform)}`),j.makeGETRequest(r)}static getSession(t){return j.makeGETRequest(`/session/${t}`)}static getSessionLogs(t){return j.makeGETRequest(`/session/${t}/session_log`)}static getDeviceLogs(t){return j.makeGETRequest(`/session/${t}/logs/device`)}static getDebugLogs(t){return j.makeGETRequest(`/session/${t}/logs/debug`)}static getProfilingData(t){return j.makeGETRequest(`/session/${t}/profiling`)}static omniScan(t){return j.makeGETRequest(`/session/${t}/xenon/omni-scan`)}static omniScanControl(t){return j.makeGETRequest(`/control/${t}/omni-scan`)}static testAiLocator(t,n,r){return j.makePOSTRequest(`/session/${t}/xenon/test-locator`,{},{strategy:n,selector:r})}static testAiLocatorControl(t,n,r){return j.makePOSTRequest(`/control/${t}/test-locator`,{},{strategy:n,selector:r})}static blockDevice(t,n){return j.makePOSTRequest("/block",{},{udid:t,host:n})}static unblockDevice(t,n){return j.makePOSTRequest("/unblock",{},{udid:t,host:n})}static updateDeviceTags(t,n,r){return j.makePOSTRequest("/device/tags",{},{udid:t,host:n,tags:r})}static async listTeams(){const t=await fetch("/xenon/api/teams",{credentials:"include"});if(!t.ok)throw new Error(`listTeams failed (${t.status})`);return(await t.json()).map(r=>({id:r.id,name:r.name}))}static async setDeviceTeam(t,n){const r=await fetch(`/xenon/api/grid/device/${encodeURIComponent(t)}/team`,{method:"PUT",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({teamId:n})});if(!r.ok&&r.status!==204){const l=await r.json().catch(()=>({}));throw new Error(l.error||`setDeviceTeam failed (${r.status})`)}}static getSessionLiveVideoUrl(t){return j.formatUrl(`/session/${t}/live_video`)}static getReservations(){return j.makeGETRequest("/reservation")}static reserveDevice(t,n,r,l,o){return j.makePOSTRequest("/reservation",{},{udid:t,host:n,reservedBy:r,duration:l,reason:o})}static releaseReservation(t,n){return j.makeDELETERequest(`/reservation/${t}/${encodeURIComponent(n)}`)}static extendReservation(t,n,r){return j.makePOSTRequest(`/reservation/${t}/${encodeURIComponent(n)}/extend`,{},{duration:r})}static getAssetUrl(t){return t?`/xenon/assets/${t.replace(/^\//,"")}`:""}static tap(t,n,r){return j.makePOSTRequest(`/control/${t}/tap`,{},{x:n,y:r})}static swipe(t,n,r,l,o){return j.makePOSTRequest(`/control/${t}/swipe`,{},{x:n,y:r,endX:l,endY:o})}static typeText(t,n){return j.makePOSTRequest(`/control/${t}/text`,{},{text:n})}static pressKey(t,n){return j.makePOSTRequest(`/control/${t}/keyevent`,{},{keyCode:n})}static getClipboard(t){return j.makeGETRequest(`/control/${t}/clipboard`)}static setClipboard(t,n){return j.makePOSTRequest(`/control/${t}/clipboard`,{},{content:n})}static getScreenshot(t){return j.makeGETRequest(`/control/${t}/screenshot`)}static touchAndHold(t,n,r,l){return j.makePOSTRequest(`/control/${t}/touchAndHold`,{},{x:n,y:r,duration:l})}static lock(t){return j.makePOSTRequest(`/control/${t}/lock`,{},{})}static unlock(t){return j.makePOSTRequest(`/control/${t}/unlock`,{},{})}static installApp(t,n){return j.makePOSTRequest(`/control/${t}/install`,{},{appPath:n})}static startStream(t){return j.makePOSTRequest(`/control/${t}/stream/start`,{},{})}static stopStream(t){return j.makePOSTRequest(`/control/${t}/stream/stop`,{},{},{keepalive:!0})}static uninstallApp(t,n){return j.makePOSTRequest(`/control/${t}/uninstall`,{},{bundleId:n})}static uploadAndInstallApp(t,n){const r=new FormData;return r.append("app",n),fetch(`/xenon/api/control/${t}/upload-install`,{method:"POST",body:r}).then(l=>l.json())}static listApps(t){return j.makeGETRequest(`/control/${t}/apps`)}static getLogs(t){return j.makeGETRequest(`/control/${t}/logs`)}static getApps(){return j.makeGETRequest("/apps")}static uploadApp(t){const n=new FormData;return n.append("app",t),fetch("/xenon/api/apps/upload",{method:"POST",body:n}).then(r=>r.json())}static deleteApp(t){return j.makeDELETERequest(`/apps/${t}`)}static installRepositoryApp(t,n){return j.makePOSTRequest(`/control/${t}/install-repository-app`,{},{appId:n})}static executeShell(t,n){return j.makePOSTRequest(`/control/${t}/shell`,{},{command:n})}static getInspectorSnapshot(t){return j.makeGETRequest(`/control/${t}/inspector/snapshot`)}static getWebhookConfigs(){return j.makeGETRequest("/webhook")}static addWebhookConfig(t,n,r,l){return j.makePOSTRequest("/webhook",{},{url:t,events:n,type:r,payloadTemplate:l})}static deleteWebhookConfig(t){return j.makeDELETERequest(`/webhook/${t}`)}static testWebhook(t,n){return j.makePOSTRequest("/webhook/test",{},{url:t,type:n})}static getGlobalConfig(){return j.makeGETRequest("/config")}static updateGlobalConfig(t){return j.makePOSTRequest("/config",{},t)}static testAIConfig(t){return j.makePOSTRequest("/config/test-ai",{},t)}static resetMetrics(){return j.makePOSTRequest("/config/reset-metrics",{},{})}static getRecentHealingEvents(t=50){return j.makeGETRequest(`/healing/events?limit=${t}&t=${Date.now()}`)}static getHealingSummary(t=30){return j.makeGETRequest(`/healing/summary?windowDays=${t}&t=${Date.now()}`)}static getHealingHotspots(t={}){const{windowDays:n=30,limit:r=20,tier:l,platform:o,status:i="active"}=t;let s=`/healing/hotspots?windowDays=${n}&limit=${r}&status=${i}&t=${Date.now()}`;return l&&(s+=`&tier=${encodeURIComponent(l)}`),o&&(s+=`&platform=${encodeURIComponent(o)}`),j.makeGETRequest(s)}static getMutedSelectors(t={}){const{limit:n=50,offset:r=0}=t;return j.makeGETRequest(`/healing/state/muted?limit=${n}&offset=${r}&t=${Date.now()}`)}static getSelectorState(t,n){return j.makeGETRequest(`/healing/state/${encodeURIComponent(t)}/${encodeURIComponent(n)}?t=${Date.now()}`)}static async postSelectorStateAction(t){const n=await fetch("/xenon/api/healing/selector/state",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)});if(!n.ok){const r=await n.json().catch(()=>({})),l=new Error(r.error??`Selector state action failed (${n.status})`);throw l.status=n.status,l.currentStatus=r.currentStatus??null,l}return n.json()}static getHealingSelectorDetail(t,n=30){return j.makeGETRequest(`/healing/selector?value=${encodeURIComponent(t)}&windowDays=${n}&t=${Date.now()}`)}static sendHealingDigest(t={}){return j.makePOSTRequest("/healing/digest/send",{},t)}static async exportBuild(t,n,r){const l=await fetch(`/xenon/api/build/${encodeURIComponent(t)}/export`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({format:n,...r?{sessionIds:r}:{}})});if(!l.ok){const u=await l.text().catch(()=>l.statusText);throw new Error(`Export failed (${l.status}): ${u||l.statusText}`)}const o=l.headers.get("Content-Disposition")||"",i=/filename="?([^";]+)"?/.exec(o),s=i?i[1]:`build-${t}-sessions.${n}`;return{blob:await l.blob(),filename:s}}}function Sm(e){if(!(e instanceof HTMLElement))return!1;if(e.isContentEditable)return!0;const t=e.tagName;return t==="INPUT"||t==="TEXTAREA"||t==="SELECT"}function _m(){const[e,t]=y.useState(!1);return y.useEffect(()=>{const n=l=>{(l.metaKey||l.ctrlKey)&&l.key.toLowerCase()==="k"&&!Sm(l.target)&&(l.preventDefault(),t(o=>!o)),l.key==="Escape"&&t(!1)},r=()=>t(!0);return window.addEventListener("keydown",n),window.addEventListener("xenon.open-command-palette",r),()=>{window.removeEventListener("keydown",n),window.removeEventListener("xenon.open-command-palette",r)}},[]),{open:e,setOpen:t}}function Ea(e,t){if(!e)return 0;const n=e.toLowerCase(),r=t.toLowerCase();if(r===n)return 1e4;if(r.startsWith(n))return 5e3-(r.length-n.length);let l=0,o=0,i=0;for(let s=0;s<n.length;s++){const a=n[s],u=r.indexOf(a,l);if(u===-1)return 0;u===l?(i+=1,o+=20+i*5):(i=0,o+=10-Math.min(u-l,10)),l=u+1}return Math.max(o,1)}const Sa=[{id:"nav:overview",kind:"nav",label:"Overview",path:"/overview"},{id:"nav:devices",kind:"nav",label:"Devices",path:"/devices"},{id:"nav:builds",kind:"nav",label:"Sessions",path:"/builds"},{id:"nav:apps",kind:"nav",label:"Apps",path:"/apps"},{id:"nav:notifications",kind:"nav",label:"Notifications",path:"/notifications"},{id:"nav:settings",kind:"nav",label:"Settings",path:"/settings"},{id:"nav:ai-settings",kind:"nav",label:"AI Engine",path:"/ai-settings"},{id:"nav:maintenance",kind:"nav",label:"Maintenance",path:"/maintenance"},{id:"nav:teams",kind:"nav",label:"Teams",path:"/teams"},{id:"nav:api-keys",kind:"nav",label:"API Keys",path:"/api-keys"}];class Cm{constructor(){this.devices=[],this.sessions=[],this.teams=[],this.keys=[],this.apps=[]}setDevices(t){this.devices=t.map(n=>({id:`device:${n.udid}`,kind:"device",label:n.name||n.udid,sub:n.udid,path:`/devices/${n.udid}/control`}))}setSessions(t){this.sessions=t.map(n=>({id:`session:${n.id}`,kind:"session",label:n.name||n.id,sub:n.id,path:`/builds?session=${encodeURIComponent(n.id)}`}))}setTeams(t){this.teams=t.map(n=>({id:`team:${n.id}`,kind:"team",label:n.name||n.id,sub:n.id,path:`/teams?team=${encodeURIComponent(n.id)}`}))}setKeys(t){this.keys=t.map(n=>({id:`key:${n.id}`,kind:"key",label:n.name||n.id,sub:n.id,path:`/api-keys?key=${encodeURIComponent(n.id)}`}))}setApps(t){this.apps=t.map(n=>({id:`app:${n.id}`,kind:"app",label:n.name||n.id,sub:n.id,path:`/apps?app=${encodeURIComponent(n.id)}`}))}search(t,n=8){return t.trim()?[...Sa,...this.devices,...this.sessions,...this.teams,...this.keys,...this.apps].map(l=>{const o=Ea(t,l.label),i=l.sub?Ea(t,l.sub):0;return{it:l,score:Math.max(o,i)}}).filter(l=>l.score>0).sort((l,o)=>o.score-l.score).slice(0,n).map(l=>l.it):Sa.slice(0,n)}}const Pm={nav:"Navigation",device:"Devices",session:"Sessions",team:"Teams",key:"API Keys",app:"Apps"},jm=["nav","device","session","team","key","app"],Rm=()=>{const{open:e,setOpen:t}=_m(),[n,r]=y.useState(""),[l,o]=y.useState(0),i=sn(),s=y.useRef(new Cm),a=y.useRef(null);y.useEffect(()=>{if(!e)return;Promise.all([Ql.getDevices().catch(()=>[]),Ql.getSessions().catch(()=>[]),Ql.getApps().catch(()=>[])]).then(([x,c,f])=>{Array.isArray(x)&&s.current.setDevices(x),Array.isArray(c)&&s.current.setSessions(c),Array.isArray(f)&&s.current.setApps(f)});const k=setTimeout(()=>{var x;return(x=a.current)==null?void 0:x.focus()},0);return()=>clearTimeout(k)},[e]),y.useEffect(()=>{e||(r(""),o(0))},[e]);const u=y.useMemo(()=>s.current.search(n,8),[n,e]),v=y.useMemo(()=>{const k=new Map;return u.forEach(x=>{const c=k.get(x.kind)||[];c.push(x),k.set(x.kind,c)}),k},[u]),g=y.useCallback(k=>{i(k.path),t(!1)},[i,t]),h=k=>{k.key==="ArrowDown"?(k.preventDefault(),o(x=>Math.min(x+1,Math.max(u.length-1,0)))):k.key==="ArrowUp"?(k.preventDefault(),o(x=>Math.max(x-1,0))):k.key==="Enter"&&(k.preventDefault(),u[l]&&g(u[l]))};if(!e)return null;let S=-1;return p.jsx("div",{className:"cp-overlay",onClick:()=>t(!1),children:p.jsxs("div",{className:"cp",role:"dialog","aria-modal":!0,"aria-label":"Command palette",onClick:k=>k.stopPropagation(),children:[p.jsxs("div",{className:"cp-input-row",children:[p.jsx(Lc,{size:14}),p.jsx("input",{ref:a,className:"cp-input",placeholder:"Search devices, sessions, settings…",value:n,onChange:k=>{r(k.target.value),o(0)},onKeyDown:h}),p.jsx("span",{className:"cp-esc",children:"ESC"})]}),p.jsxs("div",{className:"cp-results",children:[u.length===0&&p.jsx("div",{className:"cp-empty",children:"No results."}),jm.filter(k=>v.has(k)).map(k=>p.jsxs("div",{className:"cp-group",children:[p.jsx("div",{className:"cp-group-head",children:Pm[k]}),v.get(k).map(x=>{S+=1;const c=S===l;return p.jsxs("button",{type:"button",className:`cp-item${c?" cp-item-active":""}`,onMouseEnter:()=>{o(S)},onClick:()=>g(x),children:[p.jsx("span",{className:"cp-item-label",children:x.label}),x.sub&&p.jsx("span",{className:"cp-item-sub",children:x.sub})]},x.id)})]},k))]})]})})};function Nm({children:e}){const{loading:t,me:n}=Bi(),r=at();if(t)return p.jsx("div",{style:{padding:40,textAlign:"center",color:"var(--text-dim)"},children:"Loading…"});if(!n){const l=encodeURIComponent(r.pathname+r.search);return p.jsx(nl,{to:`/login?next=${l}`,replace:!0})}return p.jsx(p.Fragment,{children:e})}const Tm=y.lazy(()=>Q(()=>import("./login-DoaCgEPu.js"),[])),Om=y.lazy(()=>Q(()=>import("./forgot-password-Cu05XOKH.js"),[])),Lm=y.lazy(()=>Q(()=>import("./reset-password-BKWBemnU.js"),[])),Im=y.lazy(()=>Q(()=>import("./ApiKeyGate-DBl_AZ8N.js"),[]).then(e=>({default:e.ApiKeyGate})));function Mm(){return p.jsx(wm,{children:p.jsxs("div",{className:"min-h-screen w-full bg-[var(--bg)] text-[var(--text)]",children:[p.jsx(Em,{}),p.jsx(bh,{}),p.jsx("main",{className:"pl-14 pt-14 h-screen overflow-y-auto",children:p.jsx(ym,{})}),p.jsx(Rm,{})]})})}function Dm(){return p.jsx(Xp,{basename:"/xenon",children:p.jsx(Jh,{children:p.jsx(y.Suspense,{fallback:p.jsx("div",{style:{padding:40},children:"Loading…"}),children:p.jsxs(Nc,{children:[p.jsx($,{path:"/login",element:p.jsx(Tm,{})}),p.jsx($,{path:"/forgot-password",element:p.jsx(Om,{})}),p.jsx($,{path:"/reset-password/:token",element:p.jsx(Lm,{})}),p.jsx($,{path:"/api-key-gate",element:p.jsx(Im,{children:p.jsx(nl,{to:"/overview",replace:!0})})}),p.jsx($,{path:"*",element:p.jsx(Nm,{children:p.jsx(Mm,{})})})]})})})})}wc.render(p.jsx(y.StrictMode,{children:p.jsx(Dm,{})}),document.getElementById("root"));export{Um as A,uh as B,mh as C,Bm as D,wh as H,kh as I,Sh as K,Am as L,Qc as R,Uh as S,Wh as T,qh as U,Ql as X,at as a,Bi as b,zm as c,Wm as d,Hm as e,Vm as f,B as g,wc as h,$m as i,p as j,Gc as k,Fm as l,qm as m,Kh as n,Lc as o,Bh as p,ph as q,y as r,zh as s,jh as t,sn as u,Oc as v,_a as w,sh as x,fh as y,ya as z};
@@ -0,0 +1 @@
1
+ @import"https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap";:root{--bg: #0a0d0c;--surface: #111514;--surface-2: #161b1a;--border: #1f2624;--border-strong: #2a3331;--text: #e6ebe9;--text-muted: #8a938f;--text-dim: #5b6460;--green: #22c55e;--green-dim: #16a34a;--amber: #f59e0b;--red: #ef4444;--blue: #3b82f6;--accent-subtle: rgba(34, 197, 94, .1);--accent-border: rgba(34, 197, 94, .3);--status-ready-fg: var(--green);--status-busy-fg: var(--amber);--status-reserved-fg: var(--blue);--status-error-fg: var(--red);--status-offline-fg: var(--text-muted);--status-ready-bg: rgba(34, 197, 94, .1);--status-busy-bg: rgba(245, 158, 11, .1);--status-reserved-bg: rgba(59, 130, 246, .1);--status-error-bg: rgba(239, 68, 68, .1);--status-offline-bg: rgba(138, 147, 143, .08);--status-ready-border: rgba(34, 197, 94, .3);--status-busy-border: rgba(245, 158, 11, .3);--status-reserved-border: rgba(59, 130, 246, .3);--status-error-border: rgba(239, 68, 68, .3);--status-offline-border: rgba(138, 147, 143, .25);--space-1: 4px;--space-2: 8px;--space-3: 12px;--space-4: 16px;--space-5: 20px;--space-6: 24px;--space-8: 32px;--space-12: 48px;--radius-sm: 4px;--radius-md: 6px;--radius-lg: 8px;--shadow-sm: 0 1px 2px rgba(0, 0, 0, .25);--shadow-md: 0 4px 12px rgba(0, 0, 0, .35);--shadow-lg: 0 12px 32px rgba(0, 0, 0, .45);--motion-fast: .15s cubic-bezier(.2, 0, 0, 1);--motion-slow: .25s cubic-bezier(.2, 0, 0, 1)}.scanline,.header-container:after{display:none!important}.animate-pulse-success,.animate-pulse-running{animation:none!important}.text-glow{text-shadow:none!important}@media (prefers-reduced-motion: reduce){*{transition:none!important;animation:none!important}}*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;font-family:Inter,system-ui,-apple-system,sans-serif;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:JetBrains Mono,ui-monospace,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.container{width:100%}@media (min-width: 640px){.container{max-width:640px}}@media (min-width: 768px){.container{max-width:768px}}@media (min-width: 1024px){.container{max-width:1024px}}@media (min-width: 1280px){.container{max-width:1280px}}@media (min-width: 1536px){.container{max-width:1536px}}.pointer-events-none{pointer-events:none}.visible{visibility:visible}.collapse{visibility:collapse}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{top:0;right:0;bottom:0;left:0}.inset-y-0{top:0;bottom:0}.-top-12{top:-3rem}.bottom-0{bottom:0}.bottom-1{bottom:.25rem}.bottom-2{bottom:.5rem}.bottom-4{bottom:1rem}.left-0{left:0}.left-1\/2{left:50%}.left-14{left:3.5rem}.left-2{left:.5rem}.left-2\.5{left:.625rem}.left-3{left:.75rem}.left-full{left:100%}.right-0{right:0}.right-2{right:.5rem}.right-3{right:.75rem}.right-4{right:1rem}.top-0{top:0}.top-1{top:.25rem}.top-1\/2{top:50%}.top-2{top:.5rem}.top-3{top:.75rem}.top-full{top:100%}.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:30}.z-40{z-index:40}.z-50{z-index:50}.mx-1{margin-left:.25rem;margin-right:.25rem}.mx-auto{margin-left:auto;margin-right:auto}.my-auto{margin-top:auto;margin-bottom:auto}.mb-1{margin-bottom:.25rem}.mb-1\.5{margin-bottom:.375rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-6{margin-bottom:1.5rem}.mb-8{margin-bottom:2rem}.ml-1{margin-left:.25rem}.ml-2{margin-left:.5rem}.ml-auto{margin-left:auto}.mr-1{margin-right:.25rem}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-1\.5{margin-top:.375rem}.mt-12{margin-top:3rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-5{margin-top:1.25rem}.mt-6{margin-top:1.5rem}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.hidden{display:none}.aspect-video{aspect-ratio:16 / 9}.h-1\.5{height:.375rem}.h-10{height:2.5rem}.h-12{height:3rem}.h-14{height:3.5rem}.h-2{height:.5rem}.h-3{height:.75rem}.h-3\.5{height:.875rem}.h-32{height:8rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-7{height:1.75rem}.h-8{height:2rem}.h-9{height:2.25rem}.h-\[18px\]{height:18px}.h-\[2px\]{height:2px}.h-full{height:100%}.h-px{height:1px}.h-screen{height:100vh}.max-h-64{max-height:16rem}.max-h-96{max-height:24rem}.max-h-full{max-height:100%}.min-h-0{min-height:0px}.min-h-\[120px\]{min-height:120px}.min-h-\[280px\]{min-height:280px}.min-h-screen{min-height:100vh}.w-1\.5{width:.375rem}.w-10{width:2.5rem}.w-12{width:3rem}.w-14{width:3.5rem}.w-2{width:.5rem}.w-20{width:5rem}.w-24{width:6rem}.w-3{width:.75rem}.w-3\.5{width:.875rem}.w-32{width:8rem}.w-4{width:1rem}.w-40{width:10rem}.w-5{width:1.25rem}.w-56{width:14rem}.w-6{width:1.5rem}.w-64{width:16rem}.w-7{width:1.75rem}.w-8{width:2rem}.w-9{width:2.25rem}.w-\[104px\]{width:104px}.w-\[108px\]{width:108px}.w-\[160px\]{width:160px}.w-\[18px\]{width:18px}.w-\[280px\]{width:280px}.w-\[2px\]{width:2px}.w-\[32px\]{width:32px}.w-\[36px\]{width:36px}.w-\[3px\]{width:3px}.w-\[64px\]{width:64px}.w-\[92px\]{width:92px}.w-auto{width:auto}.w-fit{width:fit-content}.w-full{width:100%}.w-px{width:1px}.min-w-0{min-width:0px}.min-w-\[18px\]{min-width:18px}.max-w-3xl{max-width:48rem}.max-w-5xl{max-width:64rem}.max-w-7xl{max-width:80rem}.max-w-\[160px\]{max-width:160px}.max-w-\[180px\]{max-width:180px}.max-w-\[240px\]{max-width:240px}.max-w-\[420px\]{max-width:420px}.max-w-\[45\%\]{max-width:45%}.max-w-full{max-width:100%}.max-w-md{max-width:28rem}.max-w-sm{max-width:24rem}.max-w-xl{max-width:36rem}.max-w-xs{max-width:20rem}.flex-1{flex:1 1 0%}.shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.table-fixed{table-layout:fixed}.-translate-x-1\/2{--tw-translate-x: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-y-1\/2{--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-rotate-90{--tw-rotate: -90deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.rotate-0{--tw-rotate: 0deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.rotate-90{--tw-rotate: 90deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes ping{75%,to{transform:scale(2);opacity:0}}.animate-ping{animation:ping 1s cubic-bezier(0,0,.2,1) infinite}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.touch-none{touch-action:none}.select-none{-webkit-user-select:none;user-select:none}.resize{resize:both}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-\[260px_1fr\]{grid-template-columns:260px 1fr}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.items-baseline{align-items:baseline}.items-stretch{align-items:stretch}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-0\.5{gap:.125rem}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-6{gap:1.5rem}.space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(.5rem * var(--tw-space-x-reverse));margin-left:calc(.5rem * calc(1 - var(--tw-space-x-reverse)))}.space-y-0\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.125rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.125rem * var(--tw-space-y-reverse))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-1\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.375rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.375rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse))}.divide-\[var\(--border\)\]>:not([hidden])~:not([hidden]){border-color:var(--border)}.self-center{align-self:center}.self-stretch{align-self:stretch}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-nowrap{white-space:nowrap}.whitespace-pre{white-space:pre}.whitespace-pre-wrap{white-space:pre-wrap}.break-all{word-break:break-all}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-sm{border-radius:.125rem}.rounded-r{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.rounded-t{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.border{border-width:1px}.border-2{border-width:2px}.border-4{border-width:4px}.border-b{border-bottom-width:1px}.border-b-2{border-bottom-width:2px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-dashed{border-style:dashed}.border-\[var\(--border\)\]{border-color:var(--border)}.border-\[var\(--border-strong\)\]{border-color:var(--border-strong)}.border-\[var\(--green\)\]{border-color:var(--green)}.border-\[var\(--red\,\#dc2626\)\]{border-color:var(--red,#dc2626)}.border-emerald-300\/80{border-color:#6ee7b7cc}.border-emerald-500\/40{border-color:#10b98166}.border-emerald-500\/60{border-color:#10b98199}.border-neutral-800{--tw-border-opacity: 1;border-color:rgb(38 38 38 / var(--tw-border-opacity, 1))}.border-red-500\/40{border-color:#ef444466}.border-transparent{border-color:transparent}.border-white\/10{border-color:#ffffff1a}.border-t-red-500{--tw-border-opacity: 1;border-top-color:rgb(239 68 68 / var(--tw-border-opacity, 1))}.bg-\[\#000\]{--tw-bg-opacity: 1;background-color:rgb(0 0 0 / var(--tw-bg-opacity, 1))}.bg-\[var\(--accent\,\#3b82f6\)\]{background-color:var(--accent,#3b82f6)}.bg-\[var\(--amber\)\]{background-color:var(--amber)}.bg-\[var\(--bg\)\]{background-color:var(--bg)}.bg-\[var\(--blue\)\]{background-color:var(--blue)}.bg-\[var\(--border\)\]{background-color:var(--border)}.bg-\[var\(--border-strong\)\]{background-color:var(--border-strong)}.bg-\[var\(--green\)\]{background-color:var(--green)}.bg-\[var\(--green-dim\)\]{background-color:var(--green-dim)}.bg-\[var\(--red\)\]{background-color:var(--red)}.bg-\[var\(--red-soft\,rgba\(220\,38\,38\,0\.08\)\)\]{background-color:var(--red-soft,rgba(220,38,38,.08))}.bg-\[var\(--surface\)\]{background-color:var(--surface)}.bg-\[var\(--surface-1\,rgba\(255\,255\,255\,0\.02\)\)\]{background-color:var(--surface-1,rgba(255,255,255,.02))}.bg-\[var\(--surface-2\)\]{background-color:var(--surface-2)}.bg-\[var\(--surface-2\,\#2a2a2a\)\]{background-color:var(--surface-2,#2a2a2a)}.bg-\[var\(--surface-2\,rgba\(255\,255\,255\,0\.06\)\)\]{background-color:var(--surface-2,rgba(255,255,255,.06))}.bg-\[var\(--surface-2\,var\(--surface\)\)\]{background-color:var(--surface-2,var(--surface))}.bg-\[var\(--text-dim\)\]{background-color:var(--text-dim)}.bg-black{--tw-bg-opacity: 1;background-color:rgb(0 0 0 / var(--tw-bg-opacity, 1))}.bg-black\/40{background-color:#0006}.bg-black\/50{background-color:#00000080}.bg-black\/60{background-color:#0009}.bg-black\/80{background-color:#000c}.bg-emerald-400{--tw-bg-opacity: 1;background-color:rgb(52 211 153 / var(--tw-bg-opacity, 1))}.bg-emerald-500{--tw-bg-opacity: 1;background-color:rgb(16 185 129 / var(--tw-bg-opacity, 1))}.bg-emerald-500\/15{background-color:#10b98126}.bg-emerald-500\/5{background-color:#10b9810d}.bg-neutral-900{--tw-bg-opacity: 1;background-color:rgb(23 23 23 / var(--tw-bg-opacity, 1))}.bg-red-500\/10{background-color:#ef44441a}.bg-red-600{--tw-bg-opacity: 1;background-color:rgb(220 38 38 / var(--tw-bg-opacity, 1))}.bg-transparent{background-color:transparent}.bg-white\/5{background-color:#ffffff0d}.bg-yellow-500{--tw-bg-opacity: 1;background-color:rgb(234 179 8 / var(--tw-bg-opacity, 1))}.bg-gradient-to-br{background-image:linear-gradient(to bottom right,var(--tw-gradient-stops))}.from-\[\#0a0e1a\]{--tw-gradient-from: #0a0e1a var(--tw-gradient-from-position);--tw-gradient-to: rgb(10 14 26 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.via-\[\#131a2e\]{--tw-gradient-to: rgb(19 26 46 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), #131a2e var(--tw-gradient-via-position), var(--tw-gradient-to)}.to-\[\#1a2548\]{--tw-gradient-to: #1a2548 var(--tw-gradient-to-position)}.object-contain{object-fit:contain}.p-0\.5{padding:.125rem}.p-1{padding:.25rem}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-6{padding:1.5rem}.px-1{padding-left:.25rem;padding-right:.25rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-12{padding-left:3rem;padding-right:3rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-3\.5{padding-left:.875rem;padding-right:.875rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-8{padding-left:2rem;padding-right:2rem}.py-0{padding-top:0;padding-bottom:0}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-10{padding-top:2.5rem;padding-bottom:2.5rem}.py-12{padding-top:3rem;padding-bottom:3rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pb-2{padding-bottom:.5rem}.pb-3{padding-bottom:.75rem}.pb-4{padding-bottom:1rem}.pb-8{padding-bottom:2rem}.pl-1\.5{padding-left:.375rem}.pl-14{padding-left:3.5rem}.pl-7{padding-left:1.75rem}.pl-8{padding-left:2rem}.pl-9{padding-left:2.25rem}.pr-14{padding-right:3.5rem}.pr-2{padding-right:.5rem}.pr-2\.5{padding-right:.625rem}.pt-14{padding-top:3.5rem}.pt-3{padding-top:.75rem}.pt-6{padding-top:1.5rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.align-top{vertical-align:top}.font-mono{font-family:JetBrains Mono,ui-monospace,monospace}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-5xl{font-size:3rem;line-height:1}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[13px\]{font-size:13px}.text-\[9px\]{font-size:9px}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-black{font-weight:900}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.italic{font-style:italic}.tabular-nums{--tw-numeric-spacing: tabular-nums;font-variant-numeric:var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)}.leading-10{line-height:2.5rem}.leading-none{line-height:1}.leading-relaxed{line-height:1.625}.leading-tight{line-height:1.25}.tracking-tight{letter-spacing:-.025em}.tracking-wide{letter-spacing:.025em}.tracking-wider{letter-spacing:.05em}.tracking-widest{letter-spacing:.1em}.text-\[var\(--amber\)\]{color:var(--amber)}.text-\[var\(--blue\)\]{color:var(--blue)}.text-\[var\(--green\)\]{color:var(--green)}.text-\[var\(--red\)\]{color:var(--red)}.text-\[var\(--red\,\#dc2626\)\]{color:var(--red,#dc2626)}.text-\[var\(--text\)\]{color:var(--text)}.text-\[var\(--text-dim\)\]{color:var(--text-dim)}.text-\[var\(--text-muted\)\]{color:var(--text-muted)}.text-black{--tw-text-opacity: 1;color:rgb(0 0 0 / var(--tw-text-opacity, 1))}.text-emerald-300{--tw-text-opacity: 1;color:rgb(110 231 183 / var(--tw-text-opacity, 1))}.text-emerald-400{--tw-text-opacity: 1;color:rgb(52 211 153 / var(--tw-text-opacity, 1))}.text-neutral-200{--tw-text-opacity: 1;color:rgb(229 229 229 / var(--tw-text-opacity, 1))}.text-neutral-400{--tw-text-opacity: 1;color:rgb(163 163 163 / var(--tw-text-opacity, 1))}.text-neutral-500{--tw-text-opacity: 1;color:rgb(115 115 115 / var(--tw-text-opacity, 1))}.text-red-100{--tw-text-opacity: 1;color:rgb(254 226 226 / var(--tw-text-opacity, 1))}.text-red-500{--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.text-white\/60{color:#fff9}.underline{text-decoration-line:underline}.opacity-0{opacity:0}.opacity-20{opacity:.2}.opacity-40{opacity:.4}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.opacity-75{opacity:.75}.opacity-80{opacity:.8}.shadow-\[0_0_20px_rgba\(220\,38\,38\,0\.3\)\]{--tw-shadow: 0 0 20px rgba(220,38,38,.3);--tw-shadow-colored: 0 0 20px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-\[0_0_4px_rgba\(52\,211\,153\,0\.7\)\]{--tw-shadow: 0 0 4px rgba(52,211,153,.7);--tw-shadow-colored: 0 0 4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-xl{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.outline-none{outline:2px solid transparent;outline-offset:2px}.outline{outline-style:solid}.ring{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-2{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-inset{--tw-ring-inset: inset}.ring-emerald-400\/60{--tw-ring-color: rgb(52 211 153 / .6)}.blur{--tw-blur: blur(8px);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.drop-shadow{--tw-drop-shadow: drop-shadow(0 1px 2px rgb(0 0 0 / .1)) drop-shadow(0 1px 1px rgb(0 0 0 / .06));filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-blur-md{--tw-backdrop-blur: blur(12px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-150{transition-duration:.15s}.ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}*{box-sizing:border-box}html,body,#root{height:100%;margin:0;padding:0;background:var(--bg);color:var(--text);font-family:Inter,system-ui,-apple-system,sans-serif;font-feature-settings:"cv11","ss01";-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;line-height:1.5}body{overflow:hidden}h1,h2,h3,h4,h5,h6,.brand-font{font-family:Inter,sans-serif;font-weight:700;letter-spacing:-.02em;color:var(--text)}.font-mono,code,.code-font{font-family:JetBrains Mono,ui-monospace,Menlo,Monaco,Consolas,monospace}code,.code-font{font-size:.9em;background:var(--surface-2);padding:2px 6px;border-radius:var(--radius-sm);color:var(--green)}button{font-family:inherit;cursor:pointer;transition:background var(--motion-fast),border-color var(--motion-fast),color var(--motion-fast)}a{color:var(--blue);text-decoration:none;transition:color var(--motion-fast)}a:hover{color:#79b8ff}::-webkit-scrollbar{width:10px;height:10px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:var(--border);border-radius:var(--radius-md)}::-webkit-scrollbar-thumb:hover{background:var(--border-strong)}input[type=checkbox]{-moz-appearance:none;appearance:none;-webkit-appearance:none;width:16px;height:16px;background:var(--bg);border:1px solid var(--border-strong);border-radius:var(--radius-sm);cursor:pointer;position:relative;transition:background var(--motion-fast),border-color var(--motion-fast);display:inline-flex;align-items:center;justify-content:center}input[type=checkbox]:hover{border-color:var(--green)}input[type=checkbox]:checked{background:var(--green);border-color:var(--green)}input[type=checkbox]:checked:after{content:"✓";color:var(--bg);font-size:11px;font-weight:700}input[type=checkbox]:focus{outline:none;box-shadow:0 0 0 2px #22c55e40}.bg-grid{background-image:linear-gradient(to right,rgba(255,255,255,.02) 1px,transparent 1px),linear-gradient(to bottom,rgba(255,255,255,.02) 1px,transparent 1px);background-size:32px 32px}@keyframes pulse-dot{0%,to{opacity:1;transform:scale(1)}50%{opacity:.5;transform:scale(.85)}}.pulse-dot{animation:pulse-dot 2s ease-in-out infinite}.fade-in{animation:fadeIn .2s ease-out forwards}@keyframes fadeIn{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}.placeholder\:text-\[var\(--text-dim\)\]::placeholder{color:var(--text-dim)}.last\:border-b-0:last-child{border-bottom-width:0px}.last\:border-r-0:last-child{border-right-width:0px}.hover\:border-\[var\(--border\)\]:hover{border-color:var(--border)}.hover\:border-\[var\(--border-strong\)\]:hover{border-color:var(--border-strong)}.hover\:bg-\[var\(--bg\)\]:hover{background-color:var(--bg)}.hover\:bg-\[var\(--green-dim\)\]:hover{background-color:var(--green-dim)}.hover\:bg-\[var\(--surface\)\]:hover{background-color:var(--surface)}.hover\:bg-\[var\(--surface-2\)\]:hover{background-color:var(--surface-2)}.hover\:bg-\[var\(--surface-2\,\#1a1a1a\)\]:hover{background-color:var(--surface-2,#1a1a1a)}.hover\:bg-\[var\(--surface-2\,rgba\(255\,255\,255\,0\.04\)\)\]:hover{background-color:var(--surface-2,rgba(255,255,255,.04))}.hover\:bg-\[var\(--surface-raised\)\]:hover{background-color:var(--surface-raised)}.hover\:bg-emerald-500\/10:hover{background-color:#10b9811a}.hover\:bg-red-500:hover{--tw-bg-opacity: 1;background-color:rgb(239 68 68 / var(--tw-bg-opacity, 1))}.hover\:bg-red-600\/70:hover{background-color:#dc2626b3}.hover\:bg-white\/15:hover{background-color:#ffffff26}.hover\:text-\[var\(--green\)\]:hover{color:var(--green)}.hover\:text-\[var\(--text\)\]:hover{color:var(--text)}.hover\:text-white:hover{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-100:hover{opacity:1}.hover\:opacity-80:hover{opacity:.8}.focus\:border-\[var\(--accent\,\#3b82f6\)\]:focus{border-color:var(--accent,#3b82f6)}.focus\:border-\[var\(--border-strong\)\]:focus{border-color:var(--border-strong)}.focus\:border-\[var\(--green\)\]:focus{border-color:var(--green)}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.active\:scale-95:active{--tw-scale-x: .95;--tw-scale-y: .95;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-30:disabled{opacity:.3}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-50:disabled{opacity:.5}.group:hover .group-hover\:bg-\[var\(--green\)\]{background-color:var(--green)}.group:hover .group-hover\:text-\[var\(--text\)\]{color:var(--text)}.group:hover .group-hover\:opacity-100{opacity:1}@media (min-width: 640px){.sm\:inline-block{display:inline-block}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:flex-row{flex-direction:row}}@media (min-width: 768px){.md\:block{display:block}.md\:inline{display:inline}.md\:flex{display:flex}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:divide-x>:not([hidden])~:not([hidden]){--tw-divide-x-reverse: 0;border-right-width:calc(1px * var(--tw-divide-x-reverse));border-left-width:calc(1px * calc(1 - var(--tw-divide-x-reverse)))}.md\:divide-y-0>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(0px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(0px * var(--tw-divide-y-reverse))}.md\:px-12{padding-left:3rem;padding-right:3rem}}@media (min-width: 1024px){.lg\:col-span-2{grid-column:span 2 / span 2}.lg\:block{display:block}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lg\:grid-cols-\[1fr_340px\]{grid-template-columns:1fr 340px}}.surface-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-lg)}.toast-container{position:fixed;bottom:32px;right:32px;display:flex;flex-direction:column;gap:16px;z-index:10000;pointer-events:none}.toast-item{pointer-events:auto;min-width:320px;max-width:480px;padding:16px 20px;border-radius:6px;display:flex;align-items:center;gap:16px;background:var(--surface);-webkit-backdrop-filter:blur(16px);backdrop-filter:blur(16px);border:1px solid var(--border);box-shadow:0 20px 40px #0006;color:var(--text);font-size:13px;font-weight:600;font-family:JetBrains Mono,monospace;transition:all .3s cubic-bezier(.16,1,.3,1);position:relative;overflow:hidden}.toast-item:after{content:"";position:absolute;top:0;left:0;width:100%;height:2px;background:currentColor;opacity:.3}.toast-message{flex:1;text-transform:uppercase;letter-spacing:.02em}.toast-icon{display:flex;align-items:center;justify-content:center;flex-shrink:0}.toast-close{background:transparent;border:none;color:var(--text-dim);cursor:pointer;padding:4px;border-radius:6px;display:flex;align-items:center;justify-content:center;transition:all .2s}.toast-close:hover{background:#ffffff0d;color:var(--text)}.toast-success{border-color:#00ff884d;color:var(--green)}.toast-success .toast-icon{color:var(--green)}.toast-error{border-color:#ff4d4d4d;color:#ff4d4d}.toast-error .toast-icon{color:#ff4d4d}.toast-info{border-color:#00bfff4d;color:#00bfff}.toast-info .toast-icon{color:#00bfff}.toast-loading{border-color:var(--text-muted);color:var(--text-dim)}.toast-loading .toast-icon{color:var(--text-dim)}@keyframes slide-in{0%{transform:translate(100%) scale(.95);opacity:0}to{transform:translate(0) scale(1);opacity:1}}.animate-slide-in{animation:slide-in .4s cubic-bezier(.16,1,.3,1) forwards}.cp-overlay{position:fixed;top:0;right:0;bottom:0;left:0;background:#0009;z-index:9000;display:flex;justify-content:center;align-items:flex-start;padding-top:12vh;font-family:Inter,sans-serif}.cp{width:560px;max-width:90vw;background:var(--surface);border:1px solid var(--border-strong);border-radius:var(--radius-lg);box-shadow:var(--shadow-lg);overflow:hidden;display:flex;flex-direction:column}.cp-input-row{display:flex;align-items:center;gap:10px;padding:12px 14px;border-bottom:1px solid var(--border);color:var(--text-muted)}.cp-input{flex:1;background:transparent;border:none;outline:none;color:var(--text);font-family:Inter,sans-serif;font-size:14px}.cp-input::placeholder{color:var(--text-dim)}.cp-esc{font-family:JetBrains Mono,monospace;font-size:10px;color:var(--text-muted);background:var(--surface-2);border:1px solid var(--border);padding:2px 6px;border-radius:var(--radius-sm)}.cp-results{max-height:56vh;overflow-y:auto;padding:8px}.cp-empty{padding:20px;text-align:center;color:var(--text-muted);font-size:12px}.cp-group{padding:4px 0}.cp-group-head{font-family:JetBrains Mono,monospace;font-size:9px;letter-spacing:.12em;color:var(--text-dim);padding:6px 8px;text-transform:uppercase}.cp-item{display:flex;width:100%;align-items:center;gap:10px;padding:8px 10px;border-radius:var(--radius-sm);background:transparent;border:none;cursor:pointer;text-align:left;font-family:Inter,sans-serif}.cp-item-active,.cp-item:hover{background:var(--surface-2)}.cp-item-label{color:var(--text);font-size:13px;font-weight:500}.cp-item-sub{margin-left:auto;color:var(--text-dim);font-family:JetBrains Mono,monospace;font-size:10px}
@@ -1,4 +1,4 @@
1
- import{g as a}from"./index-BrVV0Kla.js";/**
1
+ import{g as a}from"./index-CkwQBzCl.js";/**
2
2
  * @license lucide-react v0.555.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{g as e}from"./index-BrVV0Kla.js";/**
1
+ import{g as e}from"./index-CkwQBzCl.js";/**
2
2
  * @license lucide-react v0.555.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1 +1 @@
1
- import{u as p,a as h,b as f,r as a,j as e,L as j,l as w}from"./index-BrVV0Kla.js";function S(){const d=p(),c=h(),{refresh:m}=f(),x=new URLSearchParams(c.search).get("next")||"/overview",[s,u]=a.useState(""),[r,b]=a.useState(""),[i,n]=a.useState(!1),[l,o]=a.useState(null);async function g(t){t.preventDefault(),n(!0),o(null);try{await w(s,r),await m(),d(x,{replace:!0})}catch(v){o(v.message||"Login failed")}finally{n(!1)}}return e.jsxs("div",{className:"min-h-screen w-full grid grid-cols-1 md:grid-cols-2 bg-[var(--bg)] text-[var(--text)]",children:[e.jsxs("aside",{className:"relative hidden md:flex flex-col justify-center px-12 overflow-hidden bg-gradient-to-br from-[#0a0e1a] via-[#131a2e] to-[#1a2548]",children:[e.jsx("div",{className:"absolute inset-0 pointer-events-none",style:{background:"radial-gradient(circle at 80% 20%, rgba(99,102,241,0.18), transparent 60%)"}}),e.jsxs("div",{className:"relative",children:[e.jsx("div",{className:"text-3xl font-semibold tracking-tight mb-2",children:"Xenon"}),e.jsx("p",{className:"text-sm text-[var(--text-dim)] max-w-sm leading-relaxed mb-8",children:"Enterprise-grade Appium device lab orchestration with AI self-healing, live device streaming, and proof-pack recording."}),e.jsx("div",{className:"flex flex-wrap gap-2 max-w-sm",children:["Hub-Node","5-tier Healing","Live MJPEG","Mosaic Recording"].map(t=>e.jsx("span",{className:"text-[11px] px-2.5 py-1 rounded-full bg-white/5 border border-white/10 text-[var(--text-muted)]",children:t},t))})]})]}),e.jsx("main",{className:"flex items-center justify-center px-6 md:px-12",children:e.jsxs("form",{onSubmit:g,className:"w-full max-w-sm",children:[e.jsx("h1",{className:"text-2xl font-semibold mb-1",children:"Welcome back!"}),e.jsx("p",{className:"text-sm text-[var(--text-dim)] mb-6",children:"Sign in to your account"}),e.jsx("label",{className:"block text-xs text-[var(--text-dim)] mb-1",children:"Email"}),e.jsx("input",{type:"email",value:s,onChange:t=>u(t.target.value),autoFocus:!0,required:!0,className:"w-full mb-4 h-10 px-3 rounded-md bg-[var(--surface)] border border-[var(--border)] text-sm focus:border-[var(--green)] outline-none"}),e.jsx("label",{className:"block text-xs text-[var(--text-dim)] mb-1",children:"Password"}),e.jsx("input",{type:"password",value:r,onChange:t=>b(t.target.value),required:!0,className:"w-full mb-2 h-10 px-3 rounded-md bg-[var(--surface)] border border-[var(--border)] text-sm focus:border-[var(--green)] outline-none"}),e.jsx("div",{className:"text-right mb-4",children:e.jsx(j,{to:"/forgot-password",className:"text-[11px] text-[var(--text-dim)] hover:text-[var(--text)]",children:"Forgot password?"})}),l&&e.jsx("div",{className:"mt-3 text-xs text-[var(--red)]",children:l}),e.jsx("button",{type:"submit",disabled:i,className:"mt-5 w-full h-10 rounded-md bg-[var(--green)] text-black font-medium text-sm disabled:opacity-50",children:i?"Signing in…":"Sign in"})]})})]})}export{S as default};
1
+ import{u as p,a as h,b as f,r as a,j as e,L as j,l as w}from"./index-CkwQBzCl.js";function S(){const d=p(),c=h(),{refresh:m}=f(),x=new URLSearchParams(c.search).get("next")||"/overview",[s,u]=a.useState(""),[r,b]=a.useState(""),[i,n]=a.useState(!1),[l,o]=a.useState(null);async function g(t){t.preventDefault(),n(!0),o(null);try{await w(s,r),await m(),d(x,{replace:!0})}catch(v){o(v.message||"Login failed")}finally{n(!1)}}return e.jsxs("div",{className:"min-h-screen w-full grid grid-cols-1 md:grid-cols-2 bg-[var(--bg)] text-[var(--text)]",children:[e.jsxs("aside",{className:"relative hidden md:flex flex-col justify-center px-12 overflow-hidden bg-gradient-to-br from-[#0a0e1a] via-[#131a2e] to-[#1a2548]",children:[e.jsx("div",{className:"absolute inset-0 pointer-events-none",style:{background:"radial-gradient(circle at 80% 20%, rgba(99,102,241,0.18), transparent 60%)"}}),e.jsxs("div",{className:"relative",children:[e.jsx("div",{className:"text-3xl font-semibold tracking-tight mb-2",children:"Xenon"}),e.jsx("p",{className:"text-sm text-[var(--text-dim)] max-w-sm leading-relaxed mb-8",children:"Enterprise-grade Appium device lab orchestration with AI self-healing, live device streaming, and proof-pack recording."}),e.jsx("div",{className:"flex flex-wrap gap-2 max-w-sm",children:["Hub-Node","5-tier Healing","Live MJPEG","Mosaic Recording"].map(t=>e.jsx("span",{className:"text-[11px] px-2.5 py-1 rounded-full bg-white/5 border border-white/10 text-[var(--text-muted)]",children:t},t))})]})]}),e.jsx("main",{className:"flex items-center justify-center px-6 md:px-12",children:e.jsxs("form",{onSubmit:g,className:"w-full max-w-sm",children:[e.jsx("h1",{className:"text-2xl font-semibold mb-1",children:"Welcome back!"}),e.jsx("p",{className:"text-sm text-[var(--text-dim)] mb-6",children:"Sign in to your account"}),e.jsx("label",{className:"block text-xs text-[var(--text-dim)] mb-1",children:"Email"}),e.jsx("input",{type:"email",value:s,onChange:t=>u(t.target.value),autoFocus:!0,required:!0,className:"w-full mb-4 h-10 px-3 rounded-md bg-[var(--surface)] border border-[var(--border)] text-sm focus:border-[var(--green)] outline-none"}),e.jsx("label",{className:"block text-xs text-[var(--text-dim)] mb-1",children:"Password"}),e.jsx("input",{type:"password",value:r,onChange:t=>b(t.target.value),required:!0,className:"w-full mb-2 h-10 px-3 rounded-md bg-[var(--surface)] border border-[var(--border)] text-sm focus:border-[var(--green)] outline-none"}),e.jsx("div",{className:"text-right mb-4",children:e.jsx(j,{to:"/forgot-password",className:"text-[11px] text-[var(--text-dim)] hover:text-[var(--text)]",children:"Forgot password?"})}),l&&e.jsx("div",{className:"mt-3 text-xs text-[var(--red)]",children:l}),e.jsx("button",{type:"submit",disabled:i,className:"mt-5 w-full h-10 rounded-md bg-[var(--green)] text-black font-medium text-sm disabled:opacity-50",children:i?"Signing in…":"Sign in"})]})})]})}export{S as default};
@@ -1,4 +1,4 @@
1
- import{g as S,m as N,r as d,X as C,j as e,v as D,s as M,I as A}from"./index-BrVV0Kla.js";/* empty css */import{S as o,A as B}from"./SettingCard-M-lFn_Wm.js";import{P as w}from"./page-header-C0pnt4xz.js";import{S as k,C as z}from"./shield-BBc4qisQ.js";import{T as E}from"./trash-2-CE5TRHb2.js";import{C as L}from"./check-BkT38An9.js";/**
1
+ import{g as S,m as N,r as d,X as C,j as e,v as D,s as M,I as A}from"./index-CkwQBzCl.js";/* empty css */import{S as o,A as B}from"./SettingCard-CRlStb6_.js";import{P as w}from"./page-header-BeUDGs-O.js";import{S as k,C as z}from"./shield-CAA9vrIs.js";import{T as E}from"./trash-2-DUWA0N9n.js";import{C as L}from"./check-CV94AcJF.js";/**
2
2
  * @license lucide-react v0.555.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{g as e}from"./index-BrVV0Kla.js";/**
1
+ import{g as e}from"./index-CkwQBzCl.js";/**
2
2
  * @license lucide-react v0.555.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{g as B,r as g,X as y,j as e,u as U,T as X,S as Y}from"./index-BrVV0Kla.js";import{u as z}from"./useSocket-Bkt5i-U6.js";import{F as V}from"./funnel-D2rLIKlM.js";import{T as W,M as K}from"./tablet-CaOqzQv_.js";import{A as Q}from"./activity-DK3R5GAb.js";import{P as G}from"./plus-BObE-_z6.js";/**
1
+ import{g as B,r as g,X as y,j as e,u as U,T as X,S as Y}from"./index-CkwQBzCl.js";import{u as z}from"./useSocket-lsg6f_Dn.js";import{F as V}from"./funnel-ChogDM6h.js";import{T as W,M as K}from"./tablet-CWU6hxZF.js";import{A as Q}from"./activity-BhRPBZ3G.js";import{P as G}from"./plus-BM5UAzcK.js";/**
2
2
  * @license lucide-react v0.555.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1 +1 @@
1
- import{j as e}from"./index-BrVV0Kla.js";const m=({icon:s,eyebrow:t,title:x,subtitle:a,action:r})=>e.jsx("header",{className:"px-6 pt-6 pb-4 border-b border-[var(--border)]",children:e.jsxs("div",{className:"flex items-start justify-between gap-4",children:[e.jsxs("div",{className:"min-w-0",children:[t&&e.jsx("div",{className:"text-[10px] font-mono font-semibold uppercase tracking-widest text-[var(--text-dim)] mb-1.5",children:t}),e.jsxs("h1",{className:"flex items-center gap-2 text-xl font-semibold tracking-tight text-[var(--text)]",children:[s&&e.jsx(s,{className:"h-5 w-5 text-[var(--green)] shrink-0"}),e.jsx("span",{className:"truncate",children:x})]}),a&&e.jsx("p",{className:"mt-1.5 text-sm text-[var(--text-muted)] max-w-3xl",children:a})]}),r&&e.jsx("div",{className:"flex items-center gap-2 shrink-0",children:r})]})});export{m as P};
1
+ import{j as e}from"./index-CkwQBzCl.js";const m=({icon:s,eyebrow:t,title:x,subtitle:a,action:r})=>e.jsx("header",{className:"px-6 pt-6 pb-4 border-b border-[var(--border)]",children:e.jsxs("div",{className:"flex items-start justify-between gap-4",children:[e.jsxs("div",{className:"min-w-0",children:[t&&e.jsx("div",{className:"text-[10px] font-mono font-semibold uppercase tracking-widest text-[var(--text-dim)] mb-1.5",children:t}),e.jsxs("h1",{className:"flex items-center gap-2 text-xl font-semibold tracking-tight text-[var(--text)]",children:[s&&e.jsx(s,{className:"h-5 w-5 text-[var(--green)] shrink-0"}),e.jsx("span",{className:"truncate",children:x})]}),a&&e.jsx("p",{className:"mt-1.5 text-sm text-[var(--text-muted)] max-w-3xl",children:a})]}),r&&e.jsx("div",{className:"flex items-center gap-2 shrink-0",children:r})]})});export{m as P};
@@ -1,4 +1,4 @@
1
- import{g as e}from"./index-BrVV0Kla.js";/**
1
+ import{g as e}from"./index-CkwQBzCl.js";/**
2
2
  * @license lucide-react v0.555.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1 +1 @@
1
- import{b as j,r as o,j as e,D as g,v as k}from"./index-BrVV0Kla.js";import{C as N}from"./copy-CEcFYYHm.js";import{T as S}from"./trash-2-CE5TRHb2.js";function T(){const{me:t}=j(),[r,n]=o.useState(""),[d,i]=o.useState(""),[b,h]=o.useState(""),[x,c]=o.useState(!1),[m,u]=o.useState(null);async function l(a){if(a.preventDefault(),u(null),d!==b){u({kind:"err",text:"Passwords do not match."});return}c(!0);try{await g(r,d),u({kind:"ok",text:"Password updated. Other sessions for your account were signed out."}),n(""),i(""),h("")}catch(s){u({kind:"err",text:s.message})}finally{c(!1)}}return e.jsxs("div",{className:"max-w-md",children:[(t==null?void 0:t.role)==="MEMBER"&&(t.teams.length>0?e.jsxs("div",{className:"mb-6",children:[e.jsx("div",{className:"text-xs text-[var(--text-dim)] uppercase tracking-wide mb-2",children:"Your Teams"}),e.jsx("div",{className:"flex flex-wrap gap-2",children:t.teams.map(a=>e.jsx("span",{className:"inline-block px-2 py-1 rounded bg-[var(--surface)] border border-[var(--border)] text-xs",children:a.name},a.id))})]}):e.jsx("div",{className:"mb-6 text-xs text-[var(--text-dim)]",children:"You're not on any team — ask an admin to add you so you can see team-scoped devices."})),e.jsxs("form",{onSubmit:l,children:[e.jsx("h2",{className:"text-xl font-semibold mb-4",children:"Update Password"}),["oldPassword","newPassword","confirm"].map(a=>e.jsxs("div",{className:"mb-3",children:[e.jsx("label",{className:"block text-xs text-[var(--text-dim)] mb-1",children:a==="oldPassword"?"Current password":a==="newPassword"?"New password":"Confirm new password"}),e.jsx("input",{type:"password",value:a==="oldPassword"?r:a==="newPassword"?d:b,onChange:s=>{a==="oldPassword"?n(s.target.value):a==="newPassword"?i(s.target.value):h(s.target.value)},className:"w-full h-10 px-3 rounded-md bg-[var(--surface)] border border-[var(--border)] text-sm"})]},a)),m&&e.jsx("div",{className:`text-xs mb-3 ${m.kind==="ok"?"text-[var(--green)]":"text-[var(--red)]"}`,children:m.text}),e.jsx("button",{type:"submit",disabled:x||d.length<8,className:"h-10 px-4 rounded-md bg-[var(--green)] text-black font-medium text-sm disabled:opacity-50",children:x?"Updating…":"Update Password"})]})]})}const f="/xenon/api/profile";async function P(){const t=await fetch(`${f}/tokens`,{credentials:"include"});if(!t.ok)throw new Error(`listTokens failed (${t.status})`);return t.json()}async function A(t,r,n){const d=await fetch(`${f}/tokens`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:t,scopes:r,expiresAt:n??void 0})});if(!d.ok){const i=await d.json().catch(()=>({}));throw new Error(i.error||`createToken failed (${d.status})`)}return d.json()}async function C(t){const r=await fetch(`${f}/tokens/${t}`,{method:"DELETE",credentials:"include"});if(!r.ok&&r.status!==204)throw new Error(`deleteToken failed (${r.status})`)}async function E(){const t=await fetch(`${f}/access-key`,{credentials:"include"});if(!t.ok)throw new Error(`getAccessKey failed (${t.status})`);return(await t.json()).accessKey}async function D(){const t=await fetch(`${f}/access-key/rotate`,{method:"POST",credentials:"include"});if(!t.ok)throw new Error(`rotateAccessKey failed (${t.status})`);return(await t.json()).accessKey}const v={"7d":"7 days","30d":"30 days","90d":"90 days","1y":"1 year",never:"No expiry"},$={"7d":7,"30d":30,"90d":90,"1y":365};function w(t){if(t==="never")return null;const r=$[t]*24*60*60*1e3;return new Date(Date.now()+r).toISOString()}function L({onClose:t,onCreated:r}){const[n,d]=o.useState(""),[i,b]=o.useState("30d"),[h,x]=o.useState(!1),[c,m]=o.useState(null);async function u(l){l.preventDefault(),x(!0),m(null);try{const a=w(i),s=await A(n,void 0,a);r({name:n,token:s.token,expiresAt:s.expiresAt})}catch(a){m(a.message)}finally{x(!1)}}return e.jsx("div",{className:"fixed inset-0 z-30 bg-black/50 flex items-center justify-center",role:"dialog","aria-modal":"true",children:e.jsxs("form",{onSubmit:u,className:"bg-[var(--bg)] border border-[var(--border)] rounded-lg w-full max-w-md p-6",children:[e.jsx("h3",{className:"text-lg font-semibold mb-4",children:"Generate Identity Token"}),e.jsx("label",{className:"block text-xs text-[var(--text-dim)] mb-1",children:"Description"}),e.jsx("input",{autoFocus:!0,value:n,onChange:l=>d(l.target.value),placeholder:"e.g. mac, CI, etc.",required:!0,className:"w-full mb-4 h-10 px-3 rounded-md bg-[var(--surface)] border border-[var(--border)] text-sm"}),e.jsx("label",{className:"block text-xs text-[var(--text-dim)] mb-1",children:"Expires after"}),e.jsx("select",{value:i,onChange:l=>b(l.target.value),className:"w-full mb-1 h-10 px-3 rounded-md bg-[var(--surface)] border border-[var(--border)] text-sm",children:Object.keys(v).map(l=>e.jsx("option",{value:l,children:v[l]},l))}),e.jsx("p",{className:"text-[11px] text-[var(--text-dim)] mb-4",children:i==="never"?"Token never expires. Rotate manually when needed.":`Token will stop working on ${new Date(w(i)).toLocaleDateString()}.`}),c&&e.jsx("div",{className:"text-xs text-[var(--red)] mb-2",children:c}),e.jsxs("div",{className:"flex justify-end gap-2",children:[e.jsx("button",{type:"button",onClick:t,className:"h-9 px-3 rounded-md border border-[var(--border)] text-sm",children:"Cancel"}),e.jsx("button",{type:"submit",disabled:h||!n,className:"h-9 px-4 rounded-md bg-[var(--green)] text-black text-sm font-medium disabled:opacity-50",children:h?"Creating…":"Create"})]})]})})}function K(){const[t,r]=o.useState(""),[n,d]=o.useState([]),[i,b]=o.useState(!0),[h,x]=o.useState(!1),[c,m]=o.useState(null);async function u(){b(!0);const[s,p]=await Promise.all([E(),P()]);r(s),d(p),b(!1)}o.useEffect(()=>{u()},[]);async function l(){confirm("Rotate access key? Existing tokens stay valid but the old accessKey will stop working immediately.")&&r(await D())}async function a(s){confirm("Delete this token? It will stop working immediately.")&&(await C(s),d(p=>p.filter(y=>y.id!==s)))}return e.jsxs("div",{className:"max-w-3xl",children:[e.jsxs("div",{className:"flex items-center gap-3 mb-6",children:[e.jsx("span",{className:"text-xs text-[var(--text-dim)]",children:"Access Key"}),e.jsx("code",{className:"px-2 py-1 rounded bg-[var(--surface)] border border-[var(--border)] text-xs",children:t||"…"}),e.jsx("button",{onClick:()=>navigator.clipboard.writeText(t),"aria-label":"Copy access key",className:"text-[var(--text-dim)] hover:text-[var(--text)]",children:e.jsx(N,{size:14})}),e.jsx("button",{onClick:l,"aria-label":"Rotate access key",className:"text-[var(--text-dim)] hover:text-[var(--text)]",children:e.jsx(k,{size:14})}),e.jsx("span",{className:"text-[10px] text-[var(--text-dim)] ml-2",children:"Public — paired with a token below"})]}),e.jsxs("div",{className:"flex items-center justify-between mb-3",children:[e.jsx("h2",{className:"text-base font-semibold",children:"Identity Tokens"}),e.jsx("button",{onClick:()=>x(!0),className:"h-9 px-4 rounded-md bg-[var(--green)] text-black font-medium text-sm",children:"Generate New Token"})]}),i?e.jsx("div",{className:"text-sm text-[var(--text-dim)]",children:"Loading…"}):n.length===0?e.jsx("div",{className:"text-sm text-[var(--text-dim)] py-6 text-center border border-dashed border-[var(--border)] rounded-md",children:"No tokens yet — generate one to use programmatically."}):e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{className:"text-[11px] text-[var(--text-dim)] uppercase tracking-wide",children:e.jsxs("tr",{children:[e.jsx("th",{className:"text-left py-2",children:"Name"}),e.jsx("th",{className:"text-left py-2",children:"Issued"}),e.jsx("th",{className:"text-left py-2",children:"Last Used"}),e.jsx("th",{className:"text-left py-2",children:"Expires"}),e.jsx("th",{className:"w-px"})]})}),e.jsx("tbody",{children:n.map(s=>{const p=s.expiresAt?new Date(s.expiresAt).getTime()<=Date.now():!1;return e.jsxs("tr",{className:"border-t border-[var(--border)]",children:[e.jsx("td",{className:"py-2",children:s.name}),e.jsx("td",{className:"py-2 text-[var(--text-muted)]",children:new Date(s.createdAt).toLocaleString()}),e.jsx("td",{className:"py-2 text-[var(--text-muted)]",children:s.lastUsedAt?new Date(s.lastUsedAt).toLocaleString():"—"}),e.jsx("td",{className:`py-2 ${p?"text-[var(--red)]":"text-[var(--text-muted)]"}`,children:s.expiresAt?`${new Date(s.expiresAt).toLocaleDateString()}${p?" (expired)":""}`:"Never"}),e.jsx("td",{className:"py-2 text-right",children:e.jsx("button",{onClick:()=>a(s.id),"aria-label":"Delete token",className:"text-[var(--red)] hover:opacity-80",children:e.jsx(S,{size:14})})})]},s.id)})})]}),h&&e.jsx(L,{onClose:()=>x(!1),onCreated:s=>{x(!1),m(s),u()}}),c&&e.jsx("div",{className:"fixed inset-0 z-30 bg-black/50 flex items-center justify-center",role:"dialog",children:e.jsxs("div",{className:"bg-[var(--bg)] border border-[var(--border)] rounded-lg w-full max-w-md p-6",children:[e.jsx("h3",{className:"text-base font-semibold mb-2",children:"Token created"}),e.jsx("p",{className:"text-xs text-[var(--text-dim)] mb-3",children:"Copy this now — it will not be shown again."}),e.jsx("code",{className:"block break-all px-3 py-2 rounded bg-[var(--surface)] border border-[var(--border)] text-xs mb-3",children:c.token}),e.jsx("p",{className:"text-[11px] text-[var(--text-dim)] mb-4",children:c.expiresAt?`Expires ${new Date(c.expiresAt).toLocaleDateString()}`:"No expiry — rotate manually."}),e.jsx("div",{className:"flex justify-end",children:e.jsx("button",{onClick:()=>m(null),className:"h-9 px-4 rounded-md bg-[var(--green)] text-black text-sm font-medium",children:"Done"})})]})})]})}function M(){const[t,r]=o.useState("password");return e.jsxs("div",{className:"flex",children:[e.jsxs("nav",{className:"w-56 shrink-0 border-r border-[var(--border)] py-6 px-3",children:[e.jsx("div",{className:"text-sm font-semibold mb-4 px-2",children:"Profile Settings"}),[{id:"password",label:"Password & Authentication"},{id:"tokens",label:"API Tokens"}].map(n=>e.jsx("button",{onClick:()=>r(n.id),className:`block w-full text-left px-3 py-2 text-sm rounded-md mb-1 ${t===n.id?"bg-[var(--green)]/10 text-[var(--green)]":"text-[var(--text)] hover:bg-[var(--surface)]"}`,children:n.label},n.id))]}),e.jsx("section",{className:"flex-1 px-8 py-6",children:t==="password"?e.jsx(T,{}):e.jsx(K,{})})]})}export{M as default};
1
+ import{b as j,r as o,j as e,D as g,v as k}from"./index-CkwQBzCl.js";import{C as N}from"./copy-DL_iD5Dh.js";import{T as S}from"./trash-2-DUWA0N9n.js";function T(){const{me:t}=j(),[r,n]=o.useState(""),[d,i]=o.useState(""),[b,h]=o.useState(""),[x,c]=o.useState(!1),[m,u]=o.useState(null);async function l(a){if(a.preventDefault(),u(null),d!==b){u({kind:"err",text:"Passwords do not match."});return}c(!0);try{await g(r,d),u({kind:"ok",text:"Password updated. Other sessions for your account were signed out."}),n(""),i(""),h("")}catch(s){u({kind:"err",text:s.message})}finally{c(!1)}}return e.jsxs("div",{className:"max-w-md",children:[(t==null?void 0:t.role)==="MEMBER"&&(t.teams.length>0?e.jsxs("div",{className:"mb-6",children:[e.jsx("div",{className:"text-xs text-[var(--text-dim)] uppercase tracking-wide mb-2",children:"Your Teams"}),e.jsx("div",{className:"flex flex-wrap gap-2",children:t.teams.map(a=>e.jsx("span",{className:"inline-block px-2 py-1 rounded bg-[var(--surface)] border border-[var(--border)] text-xs",children:a.name},a.id))})]}):e.jsx("div",{className:"mb-6 text-xs text-[var(--text-dim)]",children:"You're not on any team — ask an admin to add you so you can see team-scoped devices."})),e.jsxs("form",{onSubmit:l,children:[e.jsx("h2",{className:"text-xl font-semibold mb-4",children:"Update Password"}),["oldPassword","newPassword","confirm"].map(a=>e.jsxs("div",{className:"mb-3",children:[e.jsx("label",{className:"block text-xs text-[var(--text-dim)] mb-1",children:a==="oldPassword"?"Current password":a==="newPassword"?"New password":"Confirm new password"}),e.jsx("input",{type:"password",value:a==="oldPassword"?r:a==="newPassword"?d:b,onChange:s=>{a==="oldPassword"?n(s.target.value):a==="newPassword"?i(s.target.value):h(s.target.value)},className:"w-full h-10 px-3 rounded-md bg-[var(--surface)] border border-[var(--border)] text-sm"})]},a)),m&&e.jsx("div",{className:`text-xs mb-3 ${m.kind==="ok"?"text-[var(--green)]":"text-[var(--red)]"}`,children:m.text}),e.jsx("button",{type:"submit",disabled:x||d.length<8,className:"h-10 px-4 rounded-md bg-[var(--green)] text-black font-medium text-sm disabled:opacity-50",children:x?"Updating…":"Update Password"})]})]})}const f="/xenon/api/profile";async function P(){const t=await fetch(`${f}/tokens`,{credentials:"include"});if(!t.ok)throw new Error(`listTokens failed (${t.status})`);return t.json()}async function A(t,r,n){const d=await fetch(`${f}/tokens`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:t,scopes:r,expiresAt:n??void 0})});if(!d.ok){const i=await d.json().catch(()=>({}));throw new Error(i.error||`createToken failed (${d.status})`)}return d.json()}async function C(t){const r=await fetch(`${f}/tokens/${t}`,{method:"DELETE",credentials:"include"});if(!r.ok&&r.status!==204)throw new Error(`deleteToken failed (${r.status})`)}async function E(){const t=await fetch(`${f}/access-key`,{credentials:"include"});if(!t.ok)throw new Error(`getAccessKey failed (${t.status})`);return(await t.json()).accessKey}async function D(){const t=await fetch(`${f}/access-key/rotate`,{method:"POST",credentials:"include"});if(!t.ok)throw new Error(`rotateAccessKey failed (${t.status})`);return(await t.json()).accessKey}const v={"7d":"7 days","30d":"30 days","90d":"90 days","1y":"1 year",never:"No expiry"},$={"7d":7,"30d":30,"90d":90,"1y":365};function w(t){if(t==="never")return null;const r=$[t]*24*60*60*1e3;return new Date(Date.now()+r).toISOString()}function L({onClose:t,onCreated:r}){const[n,d]=o.useState(""),[i,b]=o.useState("30d"),[h,x]=o.useState(!1),[c,m]=o.useState(null);async function u(l){l.preventDefault(),x(!0),m(null);try{const a=w(i),s=await A(n,void 0,a);r({name:n,token:s.token,expiresAt:s.expiresAt})}catch(a){m(a.message)}finally{x(!1)}}return e.jsx("div",{className:"fixed inset-0 z-30 bg-black/50 flex items-center justify-center",role:"dialog","aria-modal":"true",children:e.jsxs("form",{onSubmit:u,className:"bg-[var(--bg)] border border-[var(--border)] rounded-lg w-full max-w-md p-6",children:[e.jsx("h3",{className:"text-lg font-semibold mb-4",children:"Generate Identity Token"}),e.jsx("label",{className:"block text-xs text-[var(--text-dim)] mb-1",children:"Description"}),e.jsx("input",{autoFocus:!0,value:n,onChange:l=>d(l.target.value),placeholder:"e.g. mac, CI, etc.",required:!0,className:"w-full mb-4 h-10 px-3 rounded-md bg-[var(--surface)] border border-[var(--border)] text-sm"}),e.jsx("label",{className:"block text-xs text-[var(--text-dim)] mb-1",children:"Expires after"}),e.jsx("select",{value:i,onChange:l=>b(l.target.value),className:"w-full mb-1 h-10 px-3 rounded-md bg-[var(--surface)] border border-[var(--border)] text-sm",children:Object.keys(v).map(l=>e.jsx("option",{value:l,children:v[l]},l))}),e.jsx("p",{className:"text-[11px] text-[var(--text-dim)] mb-4",children:i==="never"?"Token never expires. Rotate manually when needed.":`Token will stop working on ${new Date(w(i)).toLocaleDateString()}.`}),c&&e.jsx("div",{className:"text-xs text-[var(--red)] mb-2",children:c}),e.jsxs("div",{className:"flex justify-end gap-2",children:[e.jsx("button",{type:"button",onClick:t,className:"h-9 px-3 rounded-md border border-[var(--border)] text-sm",children:"Cancel"}),e.jsx("button",{type:"submit",disabled:h||!n,className:"h-9 px-4 rounded-md bg-[var(--green)] text-black text-sm font-medium disabled:opacity-50",children:h?"Creating…":"Create"})]})]})})}function K(){const[t,r]=o.useState(""),[n,d]=o.useState([]),[i,b]=o.useState(!0),[h,x]=o.useState(!1),[c,m]=o.useState(null);async function u(){b(!0);const[s,p]=await Promise.all([E(),P()]);r(s),d(p),b(!1)}o.useEffect(()=>{u()},[]);async function l(){confirm("Rotate access key? Existing tokens stay valid but the old accessKey will stop working immediately.")&&r(await D())}async function a(s){confirm("Delete this token? It will stop working immediately.")&&(await C(s),d(p=>p.filter(y=>y.id!==s)))}return e.jsxs("div",{className:"max-w-3xl",children:[e.jsxs("div",{className:"flex items-center gap-3 mb-6",children:[e.jsx("span",{className:"text-xs text-[var(--text-dim)]",children:"Access Key"}),e.jsx("code",{className:"px-2 py-1 rounded bg-[var(--surface)] border border-[var(--border)] text-xs",children:t||"…"}),e.jsx("button",{onClick:()=>navigator.clipboard.writeText(t),"aria-label":"Copy access key",className:"text-[var(--text-dim)] hover:text-[var(--text)]",children:e.jsx(N,{size:14})}),e.jsx("button",{onClick:l,"aria-label":"Rotate access key",className:"text-[var(--text-dim)] hover:text-[var(--text)]",children:e.jsx(k,{size:14})}),e.jsx("span",{className:"text-[10px] text-[var(--text-dim)] ml-2",children:"Public — paired with a token below"})]}),e.jsxs("div",{className:"flex items-center justify-between mb-3",children:[e.jsx("h2",{className:"text-base font-semibold",children:"Identity Tokens"}),e.jsx("button",{onClick:()=>x(!0),className:"h-9 px-4 rounded-md bg-[var(--green)] text-black font-medium text-sm",children:"Generate New Token"})]}),i?e.jsx("div",{className:"text-sm text-[var(--text-dim)]",children:"Loading…"}):n.length===0?e.jsx("div",{className:"text-sm text-[var(--text-dim)] py-6 text-center border border-dashed border-[var(--border)] rounded-md",children:"No tokens yet — generate one to use programmatically."}):e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{className:"text-[11px] text-[var(--text-dim)] uppercase tracking-wide",children:e.jsxs("tr",{children:[e.jsx("th",{className:"text-left py-2",children:"Name"}),e.jsx("th",{className:"text-left py-2",children:"Issued"}),e.jsx("th",{className:"text-left py-2",children:"Last Used"}),e.jsx("th",{className:"text-left py-2",children:"Expires"}),e.jsx("th",{className:"w-px"})]})}),e.jsx("tbody",{children:n.map(s=>{const p=s.expiresAt?new Date(s.expiresAt).getTime()<=Date.now():!1;return e.jsxs("tr",{className:"border-t border-[var(--border)]",children:[e.jsx("td",{className:"py-2",children:s.name}),e.jsx("td",{className:"py-2 text-[var(--text-muted)]",children:new Date(s.createdAt).toLocaleString()}),e.jsx("td",{className:"py-2 text-[var(--text-muted)]",children:s.lastUsedAt?new Date(s.lastUsedAt).toLocaleString():"—"}),e.jsx("td",{className:`py-2 ${p?"text-[var(--red)]":"text-[var(--text-muted)]"}`,children:s.expiresAt?`${new Date(s.expiresAt).toLocaleDateString()}${p?" (expired)":""}`:"Never"}),e.jsx("td",{className:"py-2 text-right",children:e.jsx("button",{onClick:()=>a(s.id),"aria-label":"Delete token",className:"text-[var(--red)] hover:opacity-80",children:e.jsx(S,{size:14})})})]},s.id)})})]}),h&&e.jsx(L,{onClose:()=>x(!1),onCreated:s=>{x(!1),m(s),u()}}),c&&e.jsx("div",{className:"fixed inset-0 z-30 bg-black/50 flex items-center justify-center",role:"dialog",children:e.jsxs("div",{className:"bg-[var(--bg)] border border-[var(--border)] rounded-lg w-full max-w-md p-6",children:[e.jsx("h3",{className:"text-base font-semibold mb-2",children:"Token created"}),e.jsx("p",{className:"text-xs text-[var(--text-dim)] mb-3",children:"Copy this now — it will not be shown again."}),e.jsx("code",{className:"block break-all px-3 py-2 rounded bg-[var(--surface)] border border-[var(--border)] text-xs mb-3",children:c.token}),e.jsx("p",{className:"text-[11px] text-[var(--text-dim)] mb-4",children:c.expiresAt?`Expires ${new Date(c.expiresAt).toLocaleDateString()}`:"No expiry — rotate manually."}),e.jsx("div",{className:"flex justify-end",children:e.jsx("button",{onClick:()=>m(null),className:"h-9 px-4 rounded-md bg-[var(--green)] text-black text-sm font-medium",children:"Done"})})]})})]})}function M(){const[t,r]=o.useState("password");return e.jsxs("div",{className:"flex",children:[e.jsxs("nav",{className:"w-56 shrink-0 border-r border-[var(--border)] py-6 px-3",children:[e.jsx("div",{className:"text-sm font-semibold mb-4 px-2",children:"Profile Settings"}),[{id:"password",label:"Password & Authentication"},{id:"tokens",label:"API Tokens"}].map(n=>e.jsx("button",{onClick:()=>r(n.id),className:`block w-full text-left px-3 py-2 text-sm rounded-md mb-1 ${t===n.id?"bg-[var(--green)]/10 text-[var(--green)]":"text-[var(--text)] hover:bg-[var(--surface)]"}`,children:n.label},n.id))]}),e.jsx("section",{className:"flex-1 px-8 py-6",children:t==="password"?e.jsx(T,{}):e.jsx(K,{})})]})}export{M as default};
@@ -1 +1 @@
1
- import{c as b,u as f,r as n,d as v,j as e,L as g,e as p}from"./index-BrVV0Kla.js";function j(){const{token:i}=b(),c=f(),[s,r]=n.useState("checking"),[a,m]=n.useState(""),[l,x]=n.useState(""),[o,d]=n.useState(null);n.useEffect(()=>{if(!i){r("invalid");return}v(i).then(t=>r(t?"ready":"invalid"))},[i]);async function u(t){if(t.preventDefault(),d(null),a!==l){d("Passwords do not match.");return}if(a.length<8){d("Password must be at least 8 characters.");return}r("submitting");try{await p(i,a),r("done"),setTimeout(()=>c("/login",{replace:!0}),1500)}catch(h){d(h.message||"Reset failed"),r("ready")}}return s==="checking"?e.jsx("div",{className:"min-h-screen flex items-center justify-center text-sm text-[var(--text-dim)]",children:"Checking link…"}):s==="invalid"?e.jsx("div",{className:"min-h-screen flex items-center justify-center text-center px-6",children:e.jsxs("div",{children:[e.jsx("h1",{className:"text-xl font-semibold mb-3",children:"This link is invalid or expired"}),e.jsx("p",{className:"text-sm text-[var(--text-dim)] mb-6",children:"Reset links are good for 1 hour and single-use. Request a new one."}),e.jsx(g,{to:"/forgot-password",className:"inline-block h-10 px-4 rounded-md bg-[var(--green)] text-black text-sm font-medium leading-10",children:"Request a new link"})]})}):s==="done"?e.jsx("div",{className:"min-h-screen flex items-center justify-center text-center px-6",children:e.jsxs("div",{children:[e.jsx("h1",{className:"text-xl font-semibold mb-3",children:"Password updated"}),e.jsx("p",{className:"text-sm text-[var(--text-dim)]",children:"Redirecting to sign in…"})]})}):e.jsx("div",{className:"min-h-screen w-full flex items-center justify-center bg-[var(--bg)] text-[var(--text)]",children:e.jsxs("form",{onSubmit:u,className:"w-full max-w-sm px-6",children:[e.jsx("h1",{className:"text-2xl font-semibold mb-1",children:"Reset your password"}),e.jsx("p",{className:"text-sm text-[var(--text-dim)] mb-6",children:"Choose a new password to sign in with."}),e.jsx("label",{className:"block text-xs text-[var(--text-dim)] mb-1",children:"New password"}),e.jsx("input",{type:"password",value:a,onChange:t=>m(t.target.value),autoFocus:!0,required:!0,className:"w-full mb-3 h-10 px-3 rounded-md bg-[var(--surface)] border border-[var(--border)] text-sm focus:border-[var(--green)] outline-none"}),e.jsx("label",{className:"block text-xs text-[var(--text-dim)] mb-1",children:"Confirm new password"}),e.jsx("input",{type:"password",value:l,onChange:t=>x(t.target.value),required:!0,className:"w-full mb-3 h-10 px-3 rounded-md bg-[var(--surface)] border border-[var(--border)] text-sm focus:border-[var(--green)] outline-none"}),o&&e.jsx("div",{className:"text-xs text-[var(--red)] mb-3",children:o}),e.jsx("button",{type:"submit",disabled:s==="submitting"||a.length<8,className:"w-full h-10 rounded-md bg-[var(--green)] text-black font-medium text-sm disabled:opacity-50",children:s==="submitting"?"Updating…":"Update password"})]})})}export{j as default};
1
+ import{c as b,u as f,r as n,d as v,j as e,L as g,e as p}from"./index-CkwQBzCl.js";function j(){const{token:i}=b(),c=f(),[s,r]=n.useState("checking"),[a,m]=n.useState(""),[l,x]=n.useState(""),[o,d]=n.useState(null);n.useEffect(()=>{if(!i){r("invalid");return}v(i).then(t=>r(t?"ready":"invalid"))},[i]);async function u(t){if(t.preventDefault(),d(null),a!==l){d("Passwords do not match.");return}if(a.length<8){d("Password must be at least 8 characters.");return}r("submitting");try{await p(i,a),r("done"),setTimeout(()=>c("/login",{replace:!0}),1500)}catch(h){d(h.message||"Reset failed"),r("ready")}}return s==="checking"?e.jsx("div",{className:"min-h-screen flex items-center justify-center text-sm text-[var(--text-dim)]",children:"Checking link…"}):s==="invalid"?e.jsx("div",{className:"min-h-screen flex items-center justify-center text-center px-6",children:e.jsxs("div",{children:[e.jsx("h1",{className:"text-xl font-semibold mb-3",children:"This link is invalid or expired"}),e.jsx("p",{className:"text-sm text-[var(--text-dim)] mb-6",children:"Reset links are good for 1 hour and single-use. Request a new one."}),e.jsx(g,{to:"/forgot-password",className:"inline-block h-10 px-4 rounded-md bg-[var(--green)] text-black text-sm font-medium leading-10",children:"Request a new link"})]})}):s==="done"?e.jsx("div",{className:"min-h-screen flex items-center justify-center text-center px-6",children:e.jsxs("div",{children:[e.jsx("h1",{className:"text-xl font-semibold mb-3",children:"Password updated"}),e.jsx("p",{className:"text-sm text-[var(--text-dim)]",children:"Redirecting to sign in…"})]})}):e.jsx("div",{className:"min-h-screen w-full flex items-center justify-center bg-[var(--bg)] text-[var(--text)]",children:e.jsxs("form",{onSubmit:u,className:"w-full max-w-sm px-6",children:[e.jsx("h1",{className:"text-2xl font-semibold mb-1",children:"Reset your password"}),e.jsx("p",{className:"text-sm text-[var(--text-dim)] mb-6",children:"Choose a new password to sign in with."}),e.jsx("label",{className:"block text-xs text-[var(--text-dim)] mb-1",children:"New password"}),e.jsx("input",{type:"password",value:a,onChange:t=>m(t.target.value),autoFocus:!0,required:!0,className:"w-full mb-3 h-10 px-3 rounded-md bg-[var(--surface)] border border-[var(--border)] text-sm focus:border-[var(--green)] outline-none"}),e.jsx("label",{className:"block text-xs text-[var(--text-dim)] mb-1",children:"Confirm new password"}),e.jsx("input",{type:"password",value:l,onChange:t=>x(t.target.value),required:!0,className:"w-full mb-3 h-10 px-3 rounded-md bg-[var(--surface)] border border-[var(--border)] text-sm focus:border-[var(--green)] outline-none"}),o&&e.jsx("div",{className:"text-xs text-[var(--red)] mb-3",children:o}),e.jsx("button",{type:"submit",disabled:s==="submitting"||a.length<8,className:"w-full h-10 rounded-md bg-[var(--green)] text-black font-medium text-sm disabled:opacity-50",children:s==="submitting"?"Updating…":"Update password"})]})})}export{j as default};
@@ -1,4 +1,4 @@
1
- import{w as _n,k as In,c as Tr,j as tn,L as Ir,B as Or}from"./index-BrVV0Kla.js";import{A as Lr}from"./arrow-left-9933DNlF.js";const qe=["http","https","mailto","tel"];function vr(n){const e=(n||"").trim(),t=e.charAt(0);if(t==="#"||t==="/")return e;const r=e.indexOf(":");if(r===-1)return e;let i=-1;for(;++i<qe.length;){const l=qe[i];if(r===l.length&&e.slice(0,l.length).toLowerCase()===l)return e}return i=e.indexOf("?"),i!==-1&&r>i||(i=e.indexOf("#"),i!==-1&&r>i)?e:"javascript:void(0)"}/*!
1
+ import{w as _n,k as In,c as Tr,j as tn,L as Ir,B as Or}from"./index-CkwQBzCl.js";import{A as Lr}from"./arrow-left-y_SSjJz-.js";const qe=["http","https","mailto","tel"];function vr(n){const e=(n||"").trim(),t=e.charAt(0);if(t==="#"||t==="/")return e;const r=e.indexOf(":");if(r===-1)return e;let i=-1;for(;++i<qe.length;){const l=qe[i];if(r===l.length&&e.slice(0,l.length).toLowerCase()===l)return e}return i=e.indexOf("?"),i!==-1&&r>i||(i=e.indexOf("#"),i!==-1&&r>i)?e:"javascript:void(0)"}/*!
2
2
  * Determine if an object is a Buffer
3
3
  *
4
4
  * @author Feross Aboukhadijeh <https://feross.org>
@@ -1 +1 @@
1
- import{u as I,m as T,A as D,r,X as v,j as e,H as f,v as C,C as F,p as A}from"./index-BrVV0Kla.js";import{P as k}from"./page-header-C0pnt4xz.js";import{f as L,H as R,V as H,E as P}from"./selector-health-DraY2a4b.js";import{C as S,L as B}from"./layers-DZwF8z_0.js";import{C as E}from"./circle-check--2DSsfaI.js";import{Z as U}from"./zap-BzdRuL9F.js";import{C as O}from"./check-BkT38An9.js";import{C as K}from"./copy-CEcFYYHm.js";function V(d){const h=Date.parse(d);if(!Number.isFinite(h))return"";const x=Math.max(0,Date.now()-h),l=Math.floor(x/1e3);if(l<60)return`${l}s ago`;const i=Math.floor(l/60);if(i<60)return`${i}m ago`;const o=Math.floor(i/60);return o<24?`${o}h ago`:`${Math.floor(o/24)}d ago`}function X(d){return d===0?"$0":d<.01?"<$0.01":`$${d.toFixed(2)}`}const se=()=>{const d=I(),{toast:h}=T(),[x]=D(),l=x.get("value")??"",i=x.get("strategy")??"",o=parseInt(x.get("windowDays")??"30",10)||30,[t,g]=r.useState(null),[a,p]=r.useState(null),[_,y]=r.useState(!1),[M,$]=r.useState(!1),[N,w]=r.useState(null),b=r.useCallback(async()=>{if(l){y(!0);try{const s=await v.getHealingSelectorDetail(l,o);g(s??null)}catch{g(null)}finally{y(!1),$(!0)}}},[l,o]),j=r.useCallback(async()=>{if(!i||!l){p(null);return}try{const s=await v.getSelectorState(i,l);p((s==null?void 0:s.state)??null)}catch{p(null)}},[i,l]);r.useEffect(()=>{b()},[b]),r.useEffect(()=>{j()},[j]);const m=r.useCallback(async s=>{if(!i||!l)return;const n=(()=>{switch(s){case"mark_fixed":return"Mark this selector as fixed? Move to Pending Verification.";case"mute":return"Mute this selector? It will be hidden from Hotspots, the CI gate, and digests.";case"unmute":return"Unmute this selector?";case"cancel_verification":return"Cancel verification? The selector returns to Active and the clean-build counter resets."}})();if(window.confirm(n))try{await v.postSelectorStateAction({original_strategy:i,original_selector:l,action:s}),h("Done.","success"),j()}catch(c){const u=c!=null&&c.currentStatus?` (currently ${c.currentStatus})`:"";h(`${(c==null?void 0:c.message)??"Action failed"}${u}`,"error")}},[i,l,h,j]),z=(s,n)=>{navigator.clipboard.writeText(s).catch(()=>{}),w(n),setTimeout(()=>w(c=>c===n?null:c),1500)};return l?e.jsxs("div",{className:"selector-health-page",children:[e.jsx(k,{icon:f,eyebrow:"Test Quality / Selector",title:e.jsx("span",{className:"sh-detail-title",children:e.jsx("code",{title:l,children:l})}),subtitle:`All heals for this selector over the last ${o} days.`,action:e.jsxs(e.Fragment,{children:[e.jsxs("button",{className:"sh-back-btn",onClick:()=>d("/selector-health"),children:[e.jsx(S,{size:12})," Back"]}),e.jsxs("button",{className:"sh-refresh-btn",onClick:b,disabled:_,title:"Refresh",children:[e.jsx(C,{size:12,className:_?"animate-spin":""}),"Refresh"]})]})}),e.jsxs("div",{className:"sh-content",children:[i&&e.jsxs("div",{className:"sh-detail-strategy-line",title:"Tuple identity for this drill-down",children:[e.jsx("span",{className:"sh-strategy-badge",children:L(i)}),e.jsx("code",{children:l})]}),!i&&e.jsxs("div",{className:"sh-detail-banner",children:["Showing every strategy that ever healed this selector value. To scope to a single tuple, append ",e.jsx("code",{children:"?strategy=<name>"})," ","to the URL or open this row from the Hotspots list."]}),a&&e.jsxs("div",{className:`sh-detail-state sh-detail-state--${a.status}`,children:[e.jsxs("div",{className:"sh-detail-state__head",children:[e.jsxs("span",{className:"sh-detail-state__badge",children:[a.status==="pending"&&e.jsxs(e.Fragment,{children:[e.jsx(R,{size:16,style:{color:"var(--accent, #60a5fa)"}}),e.jsx("span",{children:"Pending verification"})]}),a.status==="resolved"&&e.jsxs(e.Fragment,{children:[e.jsx(E,{size:16,style:{color:"var(--green, #4ade80)"}}),e.jsx("span",{children:"Resolved"})]}),a.status==="muted"&&e.jsxs(e.Fragment,{children:[e.jsx(H,{size:16,style:{color:"var(--text-muted)"}}),e.jsx("span",{children:"Muted"})]}),a.status==="active"&&(a.regression_count>0?e.jsxs(e.Fragment,{children:[e.jsx(F,{size:16,style:{color:"var(--amber, #f59e0b)"}}),e.jsxs("span",{children:["Active — regressed ",a.regression_count,"×"]})]}):e.jsxs(e.Fragment,{children:[e.jsx(U,{size:16}),e.jsx("span",{children:"Active"})]}))]}),e.jsxs("div",{className:"sh-detail-state__actions",children:[a.status==="active"&&e.jsxs(e.Fragment,{children:[e.jsx("button",{type:"button",className:"sh-action-btn sh-action-btn--primary",onClick:()=>m("mark_fixed"),children:"Mark Fixed"}),e.jsx("button",{type:"button",className:"sh-action-btn",onClick:()=>m("mute"),children:"Mute"})]}),a.status==="pending"&&e.jsxs(e.Fragment,{children:[e.jsx("button",{type:"button",className:"sh-action-btn",onClick:()=>m("cancel_verification"),children:"Cancel verification"}),e.jsx("button",{type:"button",className:"sh-action-btn",onClick:()=>m("mute"),children:"Mute"})]}),a.status==="resolved"&&e.jsx("button",{type:"button",className:"sh-action-btn",onClick:()=>m("mute"),children:"Mute"}),a.status==="muted"&&e.jsx("button",{type:"button",className:"sh-action-btn",onClick:()=>m("unmute"),children:"Unmute"})]})]}),e.jsxs("div",{className:"sh-detail-state__meta",children:[a.fixed_at&&e.jsxs("span",{children:["Marked fixed: ",new Date(a.fixed_at).toLocaleString()]}),a.resolved_at&&e.jsxs("span",{children:["Resolved: ",new Date(a.resolved_at).toLocaleString()]}),a.muted_at&&e.jsxs("span",{children:["Muted: ",new Date(a.muted_at).toLocaleString()]}),a.status==="pending"&&e.jsxs("span",{children:["Clean builds: ",a.clean_builds_count,"/3"]}),a.regression_count>0&&e.jsxs("span",{children:["Regressions on record: ",a.regression_count]})]})]}),_&&!M?e.jsxs("div",{className:"sh-empty",children:[e.jsx(C,{size:18,className:"animate-spin"}),e.jsx("span",{children:"Loading detail…"})]}):!t||t.healCount===0?e.jsxs("div",{className:"sh-empty sh-empty--clean",children:[e.jsx(f,{size:28}),e.jsxs("div",{children:[e.jsx("div",{className:"sh-empty__title",children:"No heals recorded"}),e.jsxs("div",{className:"sh-empty__subtitle",children:["This selector has no healing events in the last ",o," days."]})]})]}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"sh-detail-stats",children:[e.jsxs("div",{className:"sh-detail-stat",children:[e.jsx("span",{className:"sh-detail-stat__label",children:"Heals"}),e.jsx("span",{className:"sh-detail-stat__value",children:t.healCount})]}),e.jsxs("div",{className:"sh-detail-stat",children:[e.jsx("span",{className:"sh-detail-stat__label",children:"Sessions"}),e.jsx("span",{className:"sh-detail-stat__value",children:t.sessionCount})]}),e.jsxs("div",{className:"sh-detail-stat",children:[e.jsx("span",{className:"sh-detail-stat__label",children:"Est. cost"}),e.jsx("span",{className:"sh-detail-stat__value",children:X(t.estCostUsd)})]}),e.jsxs("div",{className:"sh-detail-stat",children:[e.jsx("span",{className:"sh-detail-stat__label",children:"Tiers used"}),e.jsx("span",{className:"sh-detail-stat__value",children:Object.keys(t.byTier).length||"—"})]})]}),e.jsxs("div",{className:"sh-detail-grid",children:[e.jsxs("section",{className:"sh-card",children:[e.jsxs("header",{className:"sh-card__head",children:[e.jsx(B,{size:12}),e.jsx("span",{children:"Suggested rewrites"}),e.jsx("span",{className:"sh-card__hint",children:"every alternate the healer landed on, ranked by frequency"})]}),e.jsxs("ul",{className:"sh-alternates",children:[t.alternates.length===0&&e.jsx("li",{className:"sh-alternates__empty",children:"No healed selectors recorded — only the failure was captured."}),t.alternates.map((s,n)=>{const c=Math.round(s.share*100),u=`alt-${n}`;return e.jsxs("li",{className:"sh-alternate",children:[e.jsxs("div",{className:"sh-alternate__top",children:[e.jsxs("span",{className:"sh-alternate__share",children:[c,"%"]}),e.jsx("code",{className:"sh-alternate__value",title:s.healedSelector,children:s.healedSelector}),e.jsx("button",{type:"button",className:`sh-icon-btn ${N===u?"copied":""}`,onClick:()=>z(s.healedSelector,u),"aria-label":"Copy alternate",title:N===u?"Copied":"Copy",children:N===u?e.jsx(O,{size:11}):e.jsx(K,{size:11})})]}),e.jsxs("div",{className:"sh-alternate__meta",children:[e.jsxs("span",{children:[s.count," heal",s.count===1?"":"s"]}),s.averageConfidence!==null&&e.jsxs("span",{children:["· avg ",Math.round(s.averageConfidence*100),"% confidence"]}),s.tiers.length>0&&e.jsxs("span",{children:["· via ",s.tiers.join(", ")]})]})]},s.healedSelector)})]})]}),e.jsxs("section",{className:"sh-card",children:[e.jsxs("header",{className:"sh-card__head",children:[e.jsx(A,{size:12}),e.jsx("span",{children:"Breakdown"})]}),e.jsxs("div",{className:"sh-breakdown",children:[e.jsxs("div",{className:"sh-breakdown__group",children:[e.jsx("div",{className:"sh-breakdown__label",children:"By tier"}),Object.entries(t.byTier).sort((s,n)=>n[1]-s[1]).map(([s,n])=>e.jsxs("div",{className:"sh-breakdown__row",children:[e.jsx("span",{className:"sh-tier-pill",children:s}),e.jsx("span",{className:"sh-breakdown__count",children:n})]},s)),Object.keys(t.byTier).length===0&&e.jsx("div",{className:"sh-breakdown__empty",children:"none recorded"})]}),e.jsxs("div",{className:"sh-breakdown__group",children:[e.jsx("div",{className:"sh-breakdown__label",children:"By platform"}),Object.entries(t.byPlatform).sort((s,n)=>n[1]-s[1]).map(([s,n])=>e.jsxs("div",{className:"sh-breakdown__row",children:[e.jsx("span",{className:"sh-platform-pill",children:s}),e.jsx("span",{className:"sh-breakdown__count",children:n})]},s))]}),e.jsxs("div",{className:"sh-breakdown__group",children:[e.jsx("div",{className:"sh-breakdown__label",children:"By build"}),t.byBuild.slice(0,8).map(s=>e.jsxs("div",{className:"sh-breakdown__row",children:[e.jsx("span",{className:"sh-build-pill",title:s.buildId,children:s.buildId==="unattached"?"unattached":s.buildId.length>12?s.buildId.slice(0,8)+"…":s.buildId}),e.jsx("span",{className:"sh-breakdown__count",children:s.count})]},s.buildId)),t.byBuild.length===0&&e.jsx("div",{className:"sh-breakdown__empty",children:"none recorded"})]})]})]})]}),e.jsxs("section",{className:"sh-card",children:[e.jsxs("header",{className:"sh-card__head",children:[e.jsx("span",{children:"Timeline"}),e.jsxs("span",{className:"sh-card__hint",children:["most recent ",t.timeline.length," of ",t.healCount," heal",t.healCount===1?"":"s"]})]}),e.jsx("div",{className:"sh-timeline",children:t.timeline.map(s=>e.jsxs("div",{className:"sh-timeline__row",children:[e.jsx("span",{className:"sh-timeline__when",children:V(s.createdAt)}),s.tier&&e.jsx("span",{className:"sh-tier-pill",children:s.tier}),e.jsx("span",{className:"sh-timeline__cmd",children:s.commandName??"—"}),e.jsx("span",{className:"sh-timeline__device",children:s.deviceName??s.deviceUdid??"—"}),e.jsx("code",{className:"sh-timeline__healed",title:s.healedSelector??"",children:s.healedSelector??"—"}),s.confidence!==null&&e.jsxs("span",{className:"sh-timeline__conf",children:[Math.round(s.confidence*100),"%"]}),s.buildId&&s.sessionId&&e.jsx("a",{className:"sh-timeline__link",href:`/xenon/builds/${encodeURIComponent(s.buildId)}/sessions/${encodeURIComponent(s.sessionId)}`,title:"Open session detail",children:e.jsx(P,{size:11})})]},s.id))})]})]})]})]}):e.jsxs("div",{className:"selector-health-page",children:[e.jsx(k,{icon:f,eyebrow:"Test Quality",title:"Selector Detail",subtitle:"No selector specified."}),e.jsx("div",{className:"sh-content",children:e.jsxs("button",{className:"sh-back-btn",onClick:()=>d("/selector-health"),children:[e.jsx(S,{size:12})," Back to Selector Health"]})})]})};export{se as default};
1
+ import{u as I,m as T,A as D,r,X as v,j as e,H as f,v as C,C as F,p as A}from"./index-CkwQBzCl.js";import{P as k}from"./page-header-BeUDGs-O.js";import{f as L,H as R,V as H,E as P}from"./selector-health-BWOVdnlp.js";import{C as S,L as B}from"./layers-a5nj78PI.js";import{C as E}from"./circle-check-0COJnxUq.js";import{Z as U}from"./zap-D8JQHaNH.js";import{C as O}from"./check-CV94AcJF.js";import{C as K}from"./copy-DL_iD5Dh.js";function V(d){const h=Date.parse(d);if(!Number.isFinite(h))return"";const x=Math.max(0,Date.now()-h),l=Math.floor(x/1e3);if(l<60)return`${l}s ago`;const i=Math.floor(l/60);if(i<60)return`${i}m ago`;const o=Math.floor(i/60);return o<24?`${o}h ago`:`${Math.floor(o/24)}d ago`}function X(d){return d===0?"$0":d<.01?"<$0.01":`$${d.toFixed(2)}`}const se=()=>{const d=I(),{toast:h}=T(),[x]=D(),l=x.get("value")??"",i=x.get("strategy")??"",o=parseInt(x.get("windowDays")??"30",10)||30,[t,g]=r.useState(null),[a,p]=r.useState(null),[_,y]=r.useState(!1),[M,$]=r.useState(!1),[N,w]=r.useState(null),b=r.useCallback(async()=>{if(l){y(!0);try{const s=await v.getHealingSelectorDetail(l,o);g(s??null)}catch{g(null)}finally{y(!1),$(!0)}}},[l,o]),j=r.useCallback(async()=>{if(!i||!l){p(null);return}try{const s=await v.getSelectorState(i,l);p((s==null?void 0:s.state)??null)}catch{p(null)}},[i,l]);r.useEffect(()=>{b()},[b]),r.useEffect(()=>{j()},[j]);const m=r.useCallback(async s=>{if(!i||!l)return;const n=(()=>{switch(s){case"mark_fixed":return"Mark this selector as fixed? Move to Pending Verification.";case"mute":return"Mute this selector? It will be hidden from Hotspots, the CI gate, and digests.";case"unmute":return"Unmute this selector?";case"cancel_verification":return"Cancel verification? The selector returns to Active and the clean-build counter resets."}})();if(window.confirm(n))try{await v.postSelectorStateAction({original_strategy:i,original_selector:l,action:s}),h("Done.","success"),j()}catch(c){const u=c!=null&&c.currentStatus?` (currently ${c.currentStatus})`:"";h(`${(c==null?void 0:c.message)??"Action failed"}${u}`,"error")}},[i,l,h,j]),z=(s,n)=>{navigator.clipboard.writeText(s).catch(()=>{}),w(n),setTimeout(()=>w(c=>c===n?null:c),1500)};return l?e.jsxs("div",{className:"selector-health-page",children:[e.jsx(k,{icon:f,eyebrow:"Test Quality / Selector",title:e.jsx("span",{className:"sh-detail-title",children:e.jsx("code",{title:l,children:l})}),subtitle:`All heals for this selector over the last ${o} days.`,action:e.jsxs(e.Fragment,{children:[e.jsxs("button",{className:"sh-back-btn",onClick:()=>d("/selector-health"),children:[e.jsx(S,{size:12})," Back"]}),e.jsxs("button",{className:"sh-refresh-btn",onClick:b,disabled:_,title:"Refresh",children:[e.jsx(C,{size:12,className:_?"animate-spin":""}),"Refresh"]})]})}),e.jsxs("div",{className:"sh-content",children:[i&&e.jsxs("div",{className:"sh-detail-strategy-line",title:"Tuple identity for this drill-down",children:[e.jsx("span",{className:"sh-strategy-badge",children:L(i)}),e.jsx("code",{children:l})]}),!i&&e.jsxs("div",{className:"sh-detail-banner",children:["Showing every strategy that ever healed this selector value. To scope to a single tuple, append ",e.jsx("code",{children:"?strategy=<name>"})," ","to the URL or open this row from the Hotspots list."]}),a&&e.jsxs("div",{className:`sh-detail-state sh-detail-state--${a.status}`,children:[e.jsxs("div",{className:"sh-detail-state__head",children:[e.jsxs("span",{className:"sh-detail-state__badge",children:[a.status==="pending"&&e.jsxs(e.Fragment,{children:[e.jsx(R,{size:16,style:{color:"var(--accent, #60a5fa)"}}),e.jsx("span",{children:"Pending verification"})]}),a.status==="resolved"&&e.jsxs(e.Fragment,{children:[e.jsx(E,{size:16,style:{color:"var(--green, #4ade80)"}}),e.jsx("span",{children:"Resolved"})]}),a.status==="muted"&&e.jsxs(e.Fragment,{children:[e.jsx(H,{size:16,style:{color:"var(--text-muted)"}}),e.jsx("span",{children:"Muted"})]}),a.status==="active"&&(a.regression_count>0?e.jsxs(e.Fragment,{children:[e.jsx(F,{size:16,style:{color:"var(--amber, #f59e0b)"}}),e.jsxs("span",{children:["Active — regressed ",a.regression_count,"×"]})]}):e.jsxs(e.Fragment,{children:[e.jsx(U,{size:16}),e.jsx("span",{children:"Active"})]}))]}),e.jsxs("div",{className:"sh-detail-state__actions",children:[a.status==="active"&&e.jsxs(e.Fragment,{children:[e.jsx("button",{type:"button",className:"sh-action-btn sh-action-btn--primary",onClick:()=>m("mark_fixed"),children:"Mark Fixed"}),e.jsx("button",{type:"button",className:"sh-action-btn",onClick:()=>m("mute"),children:"Mute"})]}),a.status==="pending"&&e.jsxs(e.Fragment,{children:[e.jsx("button",{type:"button",className:"sh-action-btn",onClick:()=>m("cancel_verification"),children:"Cancel verification"}),e.jsx("button",{type:"button",className:"sh-action-btn",onClick:()=>m("mute"),children:"Mute"})]}),a.status==="resolved"&&e.jsx("button",{type:"button",className:"sh-action-btn",onClick:()=>m("mute"),children:"Mute"}),a.status==="muted"&&e.jsx("button",{type:"button",className:"sh-action-btn",onClick:()=>m("unmute"),children:"Unmute"})]})]}),e.jsxs("div",{className:"sh-detail-state__meta",children:[a.fixed_at&&e.jsxs("span",{children:["Marked fixed: ",new Date(a.fixed_at).toLocaleString()]}),a.resolved_at&&e.jsxs("span",{children:["Resolved: ",new Date(a.resolved_at).toLocaleString()]}),a.muted_at&&e.jsxs("span",{children:["Muted: ",new Date(a.muted_at).toLocaleString()]}),a.status==="pending"&&e.jsxs("span",{children:["Clean builds: ",a.clean_builds_count,"/3"]}),a.regression_count>0&&e.jsxs("span",{children:["Regressions on record: ",a.regression_count]})]})]}),_&&!M?e.jsxs("div",{className:"sh-empty",children:[e.jsx(C,{size:18,className:"animate-spin"}),e.jsx("span",{children:"Loading detail…"})]}):!t||t.healCount===0?e.jsxs("div",{className:"sh-empty sh-empty--clean",children:[e.jsx(f,{size:28}),e.jsxs("div",{children:[e.jsx("div",{className:"sh-empty__title",children:"No heals recorded"}),e.jsxs("div",{className:"sh-empty__subtitle",children:["This selector has no healing events in the last ",o," days."]})]})]}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"sh-detail-stats",children:[e.jsxs("div",{className:"sh-detail-stat",children:[e.jsx("span",{className:"sh-detail-stat__label",children:"Heals"}),e.jsx("span",{className:"sh-detail-stat__value",children:t.healCount})]}),e.jsxs("div",{className:"sh-detail-stat",children:[e.jsx("span",{className:"sh-detail-stat__label",children:"Sessions"}),e.jsx("span",{className:"sh-detail-stat__value",children:t.sessionCount})]}),e.jsxs("div",{className:"sh-detail-stat",children:[e.jsx("span",{className:"sh-detail-stat__label",children:"Est. cost"}),e.jsx("span",{className:"sh-detail-stat__value",children:X(t.estCostUsd)})]}),e.jsxs("div",{className:"sh-detail-stat",children:[e.jsx("span",{className:"sh-detail-stat__label",children:"Tiers used"}),e.jsx("span",{className:"sh-detail-stat__value",children:Object.keys(t.byTier).length||"—"})]})]}),e.jsxs("div",{className:"sh-detail-grid",children:[e.jsxs("section",{className:"sh-card",children:[e.jsxs("header",{className:"sh-card__head",children:[e.jsx(B,{size:12}),e.jsx("span",{children:"Suggested rewrites"}),e.jsx("span",{className:"sh-card__hint",children:"every alternate the healer landed on, ranked by frequency"})]}),e.jsxs("ul",{className:"sh-alternates",children:[t.alternates.length===0&&e.jsx("li",{className:"sh-alternates__empty",children:"No healed selectors recorded — only the failure was captured."}),t.alternates.map((s,n)=>{const c=Math.round(s.share*100),u=`alt-${n}`;return e.jsxs("li",{className:"sh-alternate",children:[e.jsxs("div",{className:"sh-alternate__top",children:[e.jsxs("span",{className:"sh-alternate__share",children:[c,"%"]}),e.jsx("code",{className:"sh-alternate__value",title:s.healedSelector,children:s.healedSelector}),e.jsx("button",{type:"button",className:`sh-icon-btn ${N===u?"copied":""}`,onClick:()=>z(s.healedSelector,u),"aria-label":"Copy alternate",title:N===u?"Copied":"Copy",children:N===u?e.jsx(O,{size:11}):e.jsx(K,{size:11})})]}),e.jsxs("div",{className:"sh-alternate__meta",children:[e.jsxs("span",{children:[s.count," heal",s.count===1?"":"s"]}),s.averageConfidence!==null&&e.jsxs("span",{children:["· avg ",Math.round(s.averageConfidence*100),"% confidence"]}),s.tiers.length>0&&e.jsxs("span",{children:["· via ",s.tiers.join(", ")]})]})]},s.healedSelector)})]})]}),e.jsxs("section",{className:"sh-card",children:[e.jsxs("header",{className:"sh-card__head",children:[e.jsx(A,{size:12}),e.jsx("span",{children:"Breakdown"})]}),e.jsxs("div",{className:"sh-breakdown",children:[e.jsxs("div",{className:"sh-breakdown__group",children:[e.jsx("div",{className:"sh-breakdown__label",children:"By tier"}),Object.entries(t.byTier).sort((s,n)=>n[1]-s[1]).map(([s,n])=>e.jsxs("div",{className:"sh-breakdown__row",children:[e.jsx("span",{className:"sh-tier-pill",children:s}),e.jsx("span",{className:"sh-breakdown__count",children:n})]},s)),Object.keys(t.byTier).length===0&&e.jsx("div",{className:"sh-breakdown__empty",children:"none recorded"})]}),e.jsxs("div",{className:"sh-breakdown__group",children:[e.jsx("div",{className:"sh-breakdown__label",children:"By platform"}),Object.entries(t.byPlatform).sort((s,n)=>n[1]-s[1]).map(([s,n])=>e.jsxs("div",{className:"sh-breakdown__row",children:[e.jsx("span",{className:"sh-platform-pill",children:s}),e.jsx("span",{className:"sh-breakdown__count",children:n})]},s))]}),e.jsxs("div",{className:"sh-breakdown__group",children:[e.jsx("div",{className:"sh-breakdown__label",children:"By build"}),t.byBuild.slice(0,8).map(s=>e.jsxs("div",{className:"sh-breakdown__row",children:[e.jsx("span",{className:"sh-build-pill",title:s.buildId,children:s.buildId==="unattached"?"unattached":s.buildId.length>12?s.buildId.slice(0,8)+"…":s.buildId}),e.jsx("span",{className:"sh-breakdown__count",children:s.count})]},s.buildId)),t.byBuild.length===0&&e.jsx("div",{className:"sh-breakdown__empty",children:"none recorded"})]})]})]})]}),e.jsxs("section",{className:"sh-card",children:[e.jsxs("header",{className:"sh-card__head",children:[e.jsx("span",{children:"Timeline"}),e.jsxs("span",{className:"sh-card__hint",children:["most recent ",t.timeline.length," of ",t.healCount," heal",t.healCount===1?"":"s"]})]}),e.jsx("div",{className:"sh-timeline",children:t.timeline.map(s=>e.jsxs("div",{className:"sh-timeline__row",children:[e.jsx("span",{className:"sh-timeline__when",children:V(s.createdAt)}),s.tier&&e.jsx("span",{className:"sh-tier-pill",children:s.tier}),e.jsx("span",{className:"sh-timeline__cmd",children:s.commandName??"—"}),e.jsx("span",{className:"sh-timeline__device",children:s.deviceName??s.deviceUdid??"—"}),e.jsx("code",{className:"sh-timeline__healed",title:s.healedSelector??"",children:s.healedSelector??"—"}),s.confidence!==null&&e.jsxs("span",{className:"sh-timeline__conf",children:[Math.round(s.confidence*100),"%"]}),s.buildId&&s.sessionId&&e.jsx("a",{className:"sh-timeline__link",href:`/xenon/builds/${encodeURIComponent(s.buildId)}/sessions/${encodeURIComponent(s.sessionId)}`,title:"Open session detail",children:e.jsx(P,{size:11})})]},s.id))})]})]})]})]}):e.jsxs("div",{className:"selector-health-page",children:[e.jsx(k,{icon:f,eyebrow:"Test Quality",title:"Selector Detail",subtitle:"No selector specified."}),e.jsx("div",{className:"sh-content",children:e.jsxs("button",{className:"sh-back-btn",onClick:()=>d("/selector-health"),children:[e.jsx(S,{size:12})," Back to Selector Health"]})})]})};export{se as default};
@@ -1,4 +1,4 @@
1
- import{g as e}from"./index-BrVV0Kla.js";/**
1
+ import{g as e}from"./index-CkwQBzCl.js";/**
2
2
  * @license lucide-react v0.555.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.