cartethyia 2.5.9 → 2.5.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +7 -42
- package/README.md +11 -10
- package/dist/dashboard/assets/{BannedPage-Brvuj_Eb.js → BannedPage-Cd30Z0b9.js} +1 -1
- package/dist/dashboard/assets/BannedPage-Cd30Z0b9.js.gz +0 -0
- package/dist/dashboard/assets/{CliToolDetailPage-CqfXtI3y.js → CliToolDetailPage-wf5u-ww6.js} +1 -1
- package/dist/dashboard/assets/CliToolDetailPage-wf5u-ww6.js.gz +0 -0
- package/dist/dashboard/assets/{CliToolsPage-GQeS91bg.js → CliToolsPage-DykPvuck.js} +1 -1
- package/dist/dashboard/assets/CliToolsPage-DykPvuck.js.gz +0 -0
- package/dist/dashboard/assets/{CombosPage-BDRsTXBB.js → CombosPage-DwvSD3vs.js} +1 -1
- package/dist/dashboard/assets/CombosPage-DwvSD3vs.js.gz +0 -0
- package/dist/dashboard/assets/{ConsoleLogPage-zP8AFHX0.js → ConsoleLogPage-CIr7KDex.js} +1 -1
- package/dist/dashboard/assets/ConsoleLogPage-CIr7KDex.js.gz +0 -0
- package/dist/dashboard/assets/{CustomizationPage-BmfrNZ14.js → CustomizationPage-82X0DDdH.js} +1 -1
- package/dist/dashboard/assets/CustomizationPage-82X0DDdH.js.gz +0 -0
- package/dist/dashboard/assets/{HealthEventsModal-Dn3M6WZc.js → HealthEventsModal-BYPucTTn.js} +1 -1
- package/dist/dashboard/assets/HealthEventsModal-BYPucTTn.js.gz +0 -0
- package/dist/dashboard/assets/{LoginPage-DoreIgm8.js → LoginPage-CS5mPuVF.js} +1 -1
- package/dist/dashboard/assets/LoginPage-CS5mPuVF.js.gz +0 -0
- package/dist/dashboard/assets/{ModelPicker-C7pDb41R.js → ModelPicker-C0UCUsVJ.js} +1 -1
- package/dist/dashboard/assets/ModelPicker-C0UCUsVJ.js.gz +0 -0
- package/dist/dashboard/assets/{OverviewPage-CvvD1Ugk.js → OverviewPage-Dk_ew3YU.js} +1 -1
- package/dist/dashboard/assets/OverviewPage-Dk_ew3YU.js.gz +0 -0
- package/dist/dashboard/assets/{ProviderDetailPage-Clbn1gsW.js → ProviderDetailPage-CAiRn2Q0.js} +1 -1
- package/dist/dashboard/assets/ProviderDetailPage-CAiRn2Q0.js.gz +0 -0
- package/dist/dashboard/assets/{ProvidersPage-BnoPgA7w.js → ProvidersPage-vdja5ZPK.js} +1 -1
- package/dist/dashboard/assets/ProvidersPage-vdja5ZPK.js.gz +0 -0
- package/dist/dashboard/assets/{ProxyPage-Bq_TGgdb.js → ProxyPage-BB4CNm4-.js} +1 -1
- package/dist/dashboard/assets/ProxyPage-BB4CNm4-.js.gz +0 -0
- package/dist/dashboard/assets/{QuotaPage-D9DHXvom.js → QuotaPage-FEc4iNyq.js} +1 -1
- package/dist/dashboard/assets/QuotaPage-FEc4iNyq.js.gz +0 -0
- package/dist/dashboard/assets/{SettingsPage-7xV8WkWL.js → SettingsPage-Dlfi5L4N.js} +1 -1
- package/dist/dashboard/assets/SettingsPage-Dlfi5L4N.js.gz +0 -0
- package/dist/dashboard/assets/{SetupPage-Day3mCOn.js → SetupPage-FadUOl9S.js} +1 -1
- package/dist/dashboard/assets/SetupPage-FadUOl9S.js.gz +0 -0
- package/dist/dashboard/assets/{SortableList-DQxllnB5.js → SortableList-Cfy6_Khv.js} +1 -1
- package/dist/dashboard/assets/SortableList-Cfy6_Khv.js.gz +0 -0
- package/dist/dashboard/assets/{StudioPage-uMExoWu1.js → StudioPage-CM92fgJf.js} +1 -1
- package/dist/dashboard/assets/{StudioPage-uMExoWu1.js.gz → StudioPage-CM92fgJf.js.gz} +0 -0
- package/dist/dashboard/assets/{UsagePage-DXa1oR-4.js → UsagePage-BT4MyQeT.js} +1 -1
- package/dist/dashboard/assets/UsagePage-BT4MyQeT.js.gz +0 -0
- package/dist/dashboard/assets/{app-BIt446yE.js → app-B7pVRhJ1.js} +1 -1
- package/dist/dashboard/assets/{app-BIt446yE.js.gz → app-B7pVRhJ1.js.gz} +0 -0
- package/dist/dashboard/assets/{badge-CR72dasT.js → badge-Bvyr7D0u.js} +1 -1
- package/dist/dashboard/assets/badge-Bvyr7D0u.js.gz +0 -0
- package/dist/dashboard/assets/{banner-CI9_eSfO.js → banner-DIvKAZih.js} +1 -1
- package/dist/dashboard/assets/banner-DIvKAZih.js.gz +0 -0
- package/dist/dashboard/assets/{card-DS7CQEsO.js → card-D5_gYIS_.js} +1 -1
- package/dist/dashboard/assets/card-D5_gYIS_.js.gz +0 -0
- package/dist/dashboard/assets/{clipboard-button-611pSsaX.js → clipboard-button-B6vDBtbm.js} +1 -1
- package/dist/dashboard/assets/clipboard-button-B6vDBtbm.js.gz +0 -0
- package/dist/dashboard/assets/{dialog-k37exjNt.js → dialog-CpjrgdwJ.js} +1 -1
- package/dist/dashboard/assets/dialog-CpjrgdwJ.js.gz +0 -0
- package/dist/dashboard/assets/{drawer-CX7N8ucR.js → drawer-BWmt3b5y.js} +1 -1
- package/dist/dashboard/assets/drawer-BWmt3b5y.js.gz +0 -0
- package/dist/dashboard/assets/{entry-B9Xvtnfj.js → entry-B-gvimrg.js} +1 -1
- package/dist/dashboard/assets/entry-B-gvimrg.js.gz +0 -0
- package/dist/dashboard/assets/{entry-CTP8AyiS.js → entry-C_oakV3z.js} +1 -1
- package/dist/dashboard/assets/entry-C_oakV3z.js.gz +0 -0
- package/dist/dashboard/assets/{entry-ByMGkR3C.js → entry-Dj0cHfEc.js} +3 -3
- package/dist/dashboard/assets/entry-Dj0cHfEc.js.gz +0 -0
- package/dist/dashboard/assets/{github-badge-sltk1qUi.js → github-badge-RRHHWGxh.js} +1 -1
- package/dist/dashboard/assets/github-badge-RRHHWGxh.js.gz +0 -0
- package/dist/dashboard/assets/{index-z3zDOSMM.js → index-Bhey_rg_.js} +2 -2
- package/dist/dashboard/assets/index-Bhey_rg_.js.gz +0 -0
- package/dist/dashboard/assets/{inline-BhY2sSnO.js → inline-C2_EQ5Uf.js} +1 -1
- package/dist/dashboard/assets/inline-C2_EQ5Uf.js.gz +0 -0
- package/dist/dashboard/assets/{input-V1umFiBk.js → input-BMRlQ450.js} +1 -1
- package/dist/dashboard/assets/input-BMRlQ450.js.gz +0 -0
- package/dist/dashboard/assets/{layout-BBOYycyS.js → layout-XR5xP8ew.js} +1 -1
- package/dist/dashboard/assets/layout-XR5xP8ew.js.gz +0 -0
- package/dist/dashboard/assets/{list-row-1zzZYM0B.js → list-row-Cw07dioc.js} +1 -1
- package/dist/dashboard/assets/list-row-Cw07dioc.js.gz +0 -0
- package/dist/dashboard/assets/{numbers-DkfMR5Qs.js → numbers-DrdA9oSM.js} +1 -1
- package/dist/dashboard/assets/numbers-DrdA9oSM.js.gz +0 -0
- package/dist/dashboard/assets/{select-C6MMiaio.js → select-CxVVB__N.js} +1 -1
- package/dist/dashboard/assets/select-CxVVB__N.js.gz +0 -0
- package/dist/dashboard/assets/{stack-BHTfXdz_.js → stack-uPOwM9Hs.js} +1 -1
- package/dist/dashboard/assets/stack-uPOwM9Hs.js.gz +0 -0
- package/dist/dashboard/assets/{state-mPDRlQkl.js → state-D1Yz79iL.js} +1 -1
- package/dist/dashboard/assets/state-D1Yz79iL.js.gz +0 -0
- package/dist/dashboard/assets/{switch-DOmJxg7H.js → switch-sevsRrRo.js} +1 -1
- package/dist/dashboard/assets/switch-sevsRrRo.js.gz +0 -0
- package/dist/dashboard/index.html +1 -1
- package/dist/dashboard/index.html.gz +0 -0
- package/dist/dashboard/precompressed-assets.json +40 -40
- package/package.json +1 -3
- package/scripts/cli/admin.ts +3 -0
- package/scripts/cli/console-menu.ts +299 -275
- package/scripts/cli/doctor.ts +1 -1
- package/scripts/cli/gateway.ts +1 -2
- package/scripts/{health.ts → cli/health.ts} +4 -4
- package/scripts/cli/main.ts +3 -0
- package/scripts/cli/prompt.ts +137 -107
- package/scripts/cli/start.ts +3 -0
- package/scripts/cli/tray.ts +167 -208
- package/src/config/package-paths.ts +24 -0
- package/src/console/remote-support/service.ts +270 -114
- package/src/console/routing/pools/store.ts +1 -1
- package/src/console/updates/repository-updates.ts +40 -39
- package/src/observability/event-day-index.ts +1 -2
- package/src/protocol/registry.ts +2 -0
- package/src/providers/default-registry.ts +4 -0
- package/src/providers/integrations/buddy/capabilities.ts +4 -0
- package/src/providers/integrations/github/github.ts +3 -1
- package/src/providers/integrations/opencode/provider.ts +2 -0
- package/src/providers/integrations/trae/trae-headers.ts +17 -48
- package/src/providers/integrations/trae/trae.ts +22 -24
- package/src/providers/provider-probe.ts +3 -0
- package/dist/dashboard/assets/BannedPage-Brvuj_Eb.js.gz +0 -0
- package/dist/dashboard/assets/CliToolDetailPage-CqfXtI3y.js.gz +0 -0
- package/dist/dashboard/assets/CliToolsPage-GQeS91bg.js.gz +0 -0
- package/dist/dashboard/assets/CombosPage-BDRsTXBB.js.gz +0 -0
- package/dist/dashboard/assets/ConsoleLogPage-zP8AFHX0.js.gz +0 -0
- package/dist/dashboard/assets/CustomizationPage-BmfrNZ14.js.gz +0 -0
- package/dist/dashboard/assets/HealthEventsModal-Dn3M6WZc.js.gz +0 -0
- package/dist/dashboard/assets/LoginPage-DoreIgm8.js.gz +0 -0
- package/dist/dashboard/assets/ModelPicker-C7pDb41R.js.gz +0 -0
- package/dist/dashboard/assets/OverviewPage-CvvD1Ugk.js.gz +0 -0
- package/dist/dashboard/assets/ProviderDetailPage-Clbn1gsW.js.gz +0 -0
- package/dist/dashboard/assets/ProvidersPage-BnoPgA7w.js.gz +0 -0
- package/dist/dashboard/assets/ProxyPage-Bq_TGgdb.js.gz +0 -0
- package/dist/dashboard/assets/QuotaPage-D9DHXvom.js.gz +0 -0
- package/dist/dashboard/assets/SettingsPage-7xV8WkWL.js.gz +0 -0
- package/dist/dashboard/assets/SetupPage-Day3mCOn.js.gz +0 -0
- package/dist/dashboard/assets/SortableList-DQxllnB5.js.gz +0 -0
- package/dist/dashboard/assets/UsagePage-DXa1oR-4.js.gz +0 -0
- package/dist/dashboard/assets/badge-CR72dasT.js.gz +0 -0
- package/dist/dashboard/assets/banner-CI9_eSfO.js.gz +0 -0
- package/dist/dashboard/assets/card-DS7CQEsO.js.gz +0 -0
- package/dist/dashboard/assets/clipboard-button-611pSsaX.js.gz +0 -0
- package/dist/dashboard/assets/dialog-k37exjNt.js.gz +0 -0
- package/dist/dashboard/assets/drawer-CX7N8ucR.js.gz +0 -0
- package/dist/dashboard/assets/entry-B9Xvtnfj.js.gz +0 -0
- package/dist/dashboard/assets/entry-ByMGkR3C.js.gz +0 -0
- package/dist/dashboard/assets/entry-CTP8AyiS.js.gz +0 -0
- package/dist/dashboard/assets/github-badge-sltk1qUi.js.gz +0 -0
- package/dist/dashboard/assets/index-z3zDOSMM.js.gz +0 -0
- package/dist/dashboard/assets/inline-BhY2sSnO.js.gz +0 -0
- package/dist/dashboard/assets/input-V1umFiBk.js.gz +0 -0
- package/dist/dashboard/assets/layout-BBOYycyS.js.gz +0 -0
- package/dist/dashboard/assets/list-row-1zzZYM0B.js.gz +0 -0
- package/dist/dashboard/assets/numbers-DkfMR5Qs.js.gz +0 -0
- package/dist/dashboard/assets/select-C6MMiaio.js.gz +0 -0
- package/dist/dashboard/assets/stack-BHTfXdz_.js.gz +0 -0
- package/dist/dashboard/assets/state-mPDRlQkl.js.gz +0 -0
- package/dist/dashboard/assets/switch-DOmJxg7H.js.gz +0 -0
- package/scripts/build/aot.ts +0 -143
- package/scripts/build/build.ts +0 -24
- package/scripts/build/compile.ts +0 -88
- package/scripts/build/restart.ts +0 -120
- package/scripts/build/start.ts +0 -25
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{n as e,o as t,r as n,t as r}from"./jsx-runtime-CXUMngI_.js";import{i}from"./terminal-0_IjPWTk.js";import{T as a,c as o,s,t as c,v as l,w as u,x as d}from"./numbers-DkfMR5Qs.js";import{t as f}from"./eye-off-Bk5g2luF.js";import{t as p}from"./eye-C_hawfH4.js";import{t as m}from"./gauge-BbIMy7MB.js";import{n as h,r as g,t as _}from"./state-mPDRlQkl.js";import{t as v}from"./dialog-k37exjNt.js";import{t as y}from"./pencil-768ysRAr.js";import{t as ee}from"./plus-DIdX_g-x.js";import{t as b}from"./power-off-Yjw9GMJh.js";import{t as x}from"./rotate-ccw-CufcqITi.js";import{t as S}from"./shield-check-DVS0Foqh.js";import{t as C}from"./trash-Cppn5c3R.js";import{C as w,T,c as E,v as D,y as O}from"./assert-C9FD_JwJ.js";import{a as k,i as A,l as j,o as M,t as N}from"./query-keys-BFhGpwR1.js";import{t as P}from"./useMutation-Dem0lXQj.js";import{it as te,z as ne}from"./entry-ByMGkR3C.js";import{n as re,r as ie,t as ae}from"./card-DS7CQEsO.js";import{n as oe}from"./download-dRFo5_Wu.js";import{t as F}from"./badge-CR72dasT.js";import{n as I}from"./input-V1umFiBk.js";import{t as se}from"./select-C6MMiaio.js";import{t as L}from"./switch-DOmJxg7H.js";import{t as ce}from"./stack-BHTfXdz_.js";import{n as le}from"./inline-BhY2sSnO.js";import{r as R,t as ue}from"./layout-BBOYycyS.js";import{i as de,n as fe}from"./privacy-mode-GM8bej85.js";import{n as z}from"./live-BivGfuUs.js";var pe=e(`cloud`,[[`path`,{d:`M17.5 19H9a7 7 0 1 1 6.71-9h1.79a4.5 4.5 0 1 1 0 9Z`,key:`p7xjir`}]]),me=e(`power`,[[`path`,{d:`M12 2v10`,key:`mnfbl`}],[`path`,{d:`M18.4 6.6a9 9 0 1 1-12.77.04`,key:`obofu9`}]]),he=1e6,B=1e8,ge=5e6,_e=`sin1`,ve=[{label:`Asia Pacific`,regions:[{id:`sin1`,label:`Singapore`},{id:`hkg1`,label:`Hong Kong`},{id:`icn1`,label:`Seoul`},{id:`hnd1`,label:`Tokyo`},{id:`kix1`,label:`Osaka`},{id:`bom1`,label:`Mumbai`},{id:`syd1`,label:`Sydney`}]},{label:`Europe`,regions:[{id:`fra1`,label:`Frankfurt`},{id:`cdg1`,label:`Paris`},{id:`lhr1`,label:`London`},{id:`arn1`,label:`Stockholm`},{id:`dub1`,label:`Dublin`}]},{label:`North America`,regions:[{id:`iad1`,label:`Washington, D.C.`},{id:`sfo1`,label:`San Francisco`},{id:`pdx1`,label:`Portland`},{id:`cle1`,label:`Cleveland`},{id:`yul1`,label:`Montréal`}]},{label:`Other`,regions:[{id:`gru1`,label:`São Paulo`},{id:`cpt1`,label:`Cape Town`},{id:`dxb1`,label:`Dubai`}]}];function ye(){return w({queryKey:N.network.pools,queryFn:e=>M(`/network/pools`,{signal:D(e)}).then(E),staleTime:A.staleTime,gcTime:A.gcTime})}function be(){let e=T();return P({mutationFn:e=>M(`/network/pools`,{method:`POST`,body:JSON.stringify(e)}),onSuccess:async()=>{await e.invalidateQueries({queryKey:N.network.pools}),s.success(`Proxy pool created`)},onError:e=>{s.error(`Could not create the proxy pool.`,j(e))}})}function xe(){let e=T();return P({mutationFn:e=>M(`/network/pools/relay/deploy`,{method:`POST`,body:JSON.stringify(e)}),onSuccess:async()=>{await e.invalidateQueries({queryKey:N.network.pools})}})}function Se(){return P({mutationFn:e=>M(`/network/pools/test-batch`,{method:`POST`,body:JSON.stringify({targets:e})})})}function Ce(){let e=T();return P({mutationFn:({poolId:e,request:t})=>M(`/network/pools/${encodeURIComponent(e)}`,{method:`PATCH`,body:JSON.stringify(t)}),onSuccess:async()=>{await e.invalidateQueries({queryKey:N.network.pools}),s.success(`Proxy updated`)},onError:e=>{s.error(`Could not update the proxy pool.`,j(e))}})}function we(e){return w({queryKey:[...N.network.pools,e,`health-events`],queryFn:t=>M(`/network/pools/${encodeURIComponent(e??``)}/health-events`,{signal:D(t)}),enabled:!!e,...A,refetchInterval:k.status})}function Te(){let e=T();return P({mutationFn:e=>M(`/network/pools/${encodeURIComponent(e)}/recover`,{method:`POST`,body:`{}`}),onSuccess:async(t,n)=>{await Promise.all([e.invalidateQueries({queryKey:N.network.pools}),e.invalidateQueries({queryKey:[...N.network.pools,n,`health-events`]})]),s.success(`Proxy pool recovered`)},onError:e=>{s.error(`Could not recover the proxy pool.`,j(e))}})}function Ee(){let e=T();return P({mutationFn:e=>M(`/network/pools/${encodeURIComponent(e)}`,{method:`DELETE`}),onSuccess:async()=>{await e.invalidateQueries({queryKey:N.network.pools}),s.success(`Proxy pool deleted`)},onError:e=>{s.error(`Could not delete the proxy pool.`,j(e))}})}function De(){let e=T();return P({mutationFn:({poolId:e,providerId:t})=>M(`/network/pools/${encodeURIComponent(e)}/provider-probe`,{method:`POST`,body:JSON.stringify({providerId:t})}),onSuccess:async()=>{await e.invalidateQueries({queryKey:N.network.pools})}})}function Oe(){return P({mutationFn:({providerId:e,targets:t})=>M(`/network/pools/test-batch/provider`,{method:`POST`,body:JSON.stringify({providerId:e,targets:t})})})}function ke(){let e=T();return P({mutationFn:e=>M(`/network/pools/${encodeURIComponent(e)}/health-check`,{method:`POST`,body:`{}`}),onSuccess:async()=>{await e.invalidateQueries({queryKey:N.network.pools}),s.success(`Health check complete`)},onError:e=>{s.error(`Health check failed.`,j(e))}})}function Ae(){let e=T();return P({mutationFn:({poolId:e,bytes:t})=>M(`/network/pools/${encodeURIComponent(e)}/speed-test`,{method:`POST`,body:JSON.stringify({bytes:t})}),onSuccess:async()=>{await e.invalidateQueries({queryKey:N.network.pools})}})}function je(){let e=T();return P({mutationFn:({poolId:e,providerId:t})=>M(`/network/pools/${encodeURIComponent(e)}/cooldowns/clear`,{method:`POST`,body:JSON.stringify(t?{providerId:t}:{})}),onSuccess:async()=>{await e.invalidateQueries({queryKey:N.network.pools}),s.success(`Provider cooldowns cleared`)},onError:e=>{s.error(`Could not clear provider cooldowns.`,j(e))}})}var V=t(n(),1),H=r(),U={cloudflare:{label:`Cloudflare Workers`,tokenLabel:`Cloudflare API token`,needsAccount:!0,host:`*.workers.dev`,hasRegion:!1},vercel:{label:`Vercel`,tokenLabel:`Vercel API token`,needsAccount:!1,host:`*.vercel.app`,hasRegion:!0},deno:{label:`Deno Deploy`,tokenLabel:`Deno Deploy token`,needsAccount:!1,host:`*.deno.dev`,hasRegion:!1}},Me=ve.flatMap(e=>e.regions.map(t=>({value:t.id,label:`${e.label} — ${t.label}`})));function Ne({onClose:e}){let t=xe(),[n,r]=(0,V.useState)(`cloudflare`),[i,a]=(0,V.useState)(_e),[c,u]=(0,V.useState)(``),[d,f]=(0,V.useState)(``),[p,m]=(0,V.useState)(``),[h,g]=(0,V.useState)(null),_=U[n],y=c.trim().length>0&&(!_.needsAccount||d.trim().length>0);return(0,H.jsx)(v,{open:!0,onClose:e,title:`Deploy Relay`,description:`Run outbound traffic through a hosted relay (Cloudflare, Vercel, Deno).`,size:`md`,children:(0,H.jsxs)(ce,{gap:`12px`,children:[(0,H.jsxs)(`p`,{className:`text-badge text-text-tertiary m-0 flex gap-3`,children:[(0,H.jsx)(te,{size:13,className:`shrink-0 mt-0.5`}),(0,H.jsxs)(`span`,{children:[`Deploys a small relay worker to your own `,_.label,` account and registers its URL (`,(0,H.jsx)(`code`,{children:_.host}),`) as an active HTTP pool. Your API token is used only for the deploy and is never stored.`]})]}),(0,H.jsx)(se,{label:`Relay host`,id:`relay-target`,value:n,onValueChange:e=>r(e),options:O.map(e=>({value:e,label:U[e].label}))}),(0,H.jsx)(I,{label:_.tokenLabel,id:`relay-token`,type:`password`,value:c,placeholder:`Paste a deploy token`,onChange:e=>u(e.target.value)}),_.needsAccount?(0,H.jsx)(I,{label:`Account ID`,id:`relay-account`,value:d,placeholder:`Cloudflare account id`,onChange:e=>f(e.target.value)}):null,(0,H.jsx)(I,{label:`Project name (optional)`,id:`relay-project`,value:p,placeholder:`e.g. cartethyia-relay`,onChange:e=>m(e.target.value)}),_.hasRegion?(0,H.jsx)(se,{label:`Deploy region`,id:`relay-region`,value:i,onValueChange:e=>a(e),options:Me}):null,_.hasRegion?(0,H.jsx)(`p`,{className:`text-badge text-text-tertiary m-0`,children:`Sets the region on the Vercel project, which is what decides the country outbound traffic leaves from. A region sent on the deployment alone is accepted but does not move the Function.`}):null,(0,H.jsxs)(`div`,{className:`flex items-center gap-5`,children:[(0,H.jsx)(o,{variant:`primary`,size:`sm`,onClick:()=>{y&&t.mutate({target:n,token:c.trim(),..._.needsAccount&&d.trim()?{accountId:d.trim()}:{},...p.trim()?{projectName:p.trim()}:{},..._.hasRegion?{region:i}:{}},{onSuccess:e=>{g(e.relayUrl),u(``),s.success(`Relay deployed to ${e.relayUrl} and registered as a pool.`)},onError:e=>s.error(j(e,`Relay deploy failed.`))})},disabled:!y||t.isPending,children:t.isPending?`Deploying…`:`Deploy relay`}),h?(0,H.jsxs)(`span`,{className:`mt-1 text-badge text-text-tertiary`,children:[`Registered pool at `,(0,H.jsx)(`code`,{children:h})]}):null]}),t.isError?(0,H.jsxs)(`p`,{className:`text-badge text-red m-0 flex gap-3`,children:[(0,H.jsx)(l,{size:13,className:`shrink-0 mt-0.5`}),(0,H.jsx)(`span`,{children:j(t.error,`Relay deploy failed.`)})]}):null]})})}function Pe(e,t){if(e!==void 0)return e.endpoint===``||e.endpoint===(t??``)?e.result:void 0}function Fe(e,t,n){switch(t){case`name`:return(e.label||e.endpoint).toLowerCase();case`family`:return e.family===void 0||e.family===null||e.family===``?null:e.family.toLowerCase();case`address`:return e.egressIp??null;case`load`:return n??null}}function Ie(e,t,n,r){let i=n===`asc`?1:-1;return[...e].sort((e,n)=>{let a=Fe(e,t,r(e)),o=Fe(n,t,r(n));return a===null&&o===null?0:a===null?1:o===null?-1:typeof a==`number`&&typeof o==`number`?(a-o)*i:String(a).localeCompare(String(o))*i})}function W(e,t){let n=e.filter(e=>e.status===`active`),r=n.reduce((e,t)=>e+t.maxInflight,0),i=t===void 0?n.reduce((e,t)=>e+(t.inflight??0),0):n.reduce((e,n)=>e+(t.get(n.id)??0),0),a=0,o=0;for(let e of n)(t===void 0?e.inflight??0:t.get(e.id)??0)>=e.maxInflight?o+=1:a+=1;let s=null,c=Date.now(),l=e=>{if(!e)return;let t=Date.parse(e);if(Number.isNaN(t))return;let n=t-c;n<=0||(s===null||n<s)&&(s=n)};for(let t of e){l(t.cooldownUntil);for(let e of t.providerCooldowns??[])l(e.until)}let u=n.filter(e=>e.lastLatencyMs!==void 0&&Number.isFinite(e.lastLatencyMs)),d=u.length===0?null:Math.round(u.reduce((e,t)=>e+(t.lastLatencyMs??0),0)/u.length);return{totalPools:e.length,active:n.length,cooldown:e.filter(e=>e.status===`cooldown`).length,totalMaxConcurrency:r,usedInflight:i,availableCapacity:Math.max(0,r-i),routablePools:a,saturatedPools:o,soonestCooldownMs:s,avgLatencyMs:d,measuredPools:u.length}}var G=[`http`,`https`,`socks5`];function K(e){return/^[a-z][a-z0-9+.-]*:\/\//i.test(e.trim())}function Le(e,t){let n=e.trim();return t===null||K(n)?n:`${t}://${n}`}function q(e){return e.find(e=>e.trim()!==``)}function J(e){let t=e.trim().toLowerCase();return t.startsWith(`https://`)?`https`:t.startsWith(`socks5://`)||t.startsWith(`socks://`)?`socks5`:`http`}var Re=1024**3;function ze(e){let t=e.trim();if(t===``)return null;let n=Number(t);return!Number.isFinite(n)||n<=0?null:Math.max(1,Math.round(n*Re))}function Y(e,t,n){let r=new Map;if(t.trim().toLowerCase()===``||n<=0)return r;let i=Math.floor(e/n),a=e-i*n;for(let e=0;e<n;e+=1){let t=e===n-1?a:0;r.set(e,i+t)}return r}var Be=4,Ve=`cartethyia_proxy_test_payload`,He=`cartethyia_proxy_check_results`,Ue=[{value:`url`,label:`Test URL`},{value:`opencode`,label:`Test OpenCode`}],We=`opencode`,Ge=4,Ke=`Mysterious Proxy`;function X(e){return e.avgLatencyMs===null?`no measurement yet`:`avg across ${e.measuredPools} enabled ${e.measuredPools===1?`pool`:`pools`}`}function qe(e){let t=e.endpoint||``,n=t.includes(`://`)?t:`${e.kind}://${t}`,r={"https:":`443`,"http:":`80`,"socks5:":`1080`,"socks:":`1080`};try{let e=new URL(n),t=e.port||r[e.protocol]||``,i=`${e.hostname}${t?`:${t}`:``}`;return{name:i,endpoint:`${e.protocol}//${i}${e.pathname===`/`?``:e.pathname}${e.search}`}}catch{return{name:e.label||t,endpoint:t}}}function Z(e){return e.label||qe(e).name||e.id}var Q=1024**3;function Je(e){if(e.lastSpeedtestStatus===void 0||e.lastSpeedtestAt===void 0)return;let t=e.lastSpeedtestDurationMs??0,n=e.lastSpeedtestBytes??0,r=t>0?n/(t/1e3):void 0;return{poolId:e.id,status:e.lastSpeedtestStatus,bytes:n,durationMs:t,...r===void 0?{}:{bytesPerSecond:r,megabitsPerSecond:r*8/1e6},...e.lastSpeedtestError?{errorMessage:e.lastSpeedtestError}:{},measuredAt:e.lastSpeedtestAt}}function Ye(e,t){if(!e)return t;if(!t)return e;let n=e.measuredAt?new Date(e.measuredAt).getTime():0;return(t.measuredAt?new Date(t.measuredAt).getTime():0)>=n?t:e}var Xe=[{value:String(he),label:`1 MB`},{value:String(ge),label:`5 MB`},{value:`50000000`,label:`50 MB`},{value:String(B),label:`100 MB`}];function Ze({pool:e,onClose:t,actionsRef:n}){let r=Ce(),i=Oe(),a=ke(),[l,f]=(0,V.useState)(e.label??``),[p,m]=(0,V.useState)(e.family??``),[h,g]=(0,V.useState)(e.endpoint??``),[_,v]=(0,V.useState)(String(e.maxInflight??10)),[y,ee]=(0,V.useState)(String(e.weight??100)),[b,x]=(0,V.useState)(e.quotaBytes?String(Math.round(e.quotaBytes/Q*1e3)/1e3):``),[S,C]=(0,V.useState)(null),[w,T]=(0,V.useState)(!1),E=h.trim()===e.endpoint,D=async()=>{T(!0),C(null);try{if(E){let t=await a.mutateAsync(e.id),n=t.status===`healthy`||t.status===`reachable`;C({ok:n,message:t.status===`healthy`?`Connected in ${t.latencyMs??0}ms`:t.errorMessage??`Connection failed`});return}let t=[{kind:e.kind,endpoint:h.trim(),...e.family===null||e.family===void 0?{}:{family:e.family}}],[n]=await i.mutateAsync({providerId:We,targets:t}),r=n?.result;if(!r){C({ok:!1,message:`Probe returned no result`});return}let o=r.status===`allowed`||r.status===`throttled`;C({ok:o,message:r.reason??(r.status===`allowed`?`Reachable${r.latencyMs===void 0?``:` in ${r.latencyMs}ms`}`:r.status===`throttled`?`Reachable; rate limit spent`:`Probe could not complete`)})}catch(e){C({ok:!1,message:j(e,`Connection failed`)})}finally{T(!1)}},O=ze(b),k=async()=>{await r.mutateAsync({poolId:e.id,request:{...l.trim()===e.label?{}:{label:l.trim()||void 0},...p.trim()===(e.family??``)?{}:{family:p.trim()||null},...h.trim()!==e.endpoint&&h.trim()!==``?{endpoint:h.trim()}:{},...Number(_)===e.maxInflight?{}:{maxInflight:Number(_)},...Number(y)===e.weight?{}:{weight:Number(y)},...O===(e.quotaBytes??null)?{}:{quotaBytes:O}}}),s.success(`Proxy updated`),t()};return(0,V.useEffect)(()=>{n?.((0,H.jsxs)(H.Fragment,{children:[(0,H.jsx)(o,{variant:`secondary`,size:`sm`,onClick:t,children:`Cancel`}),(0,H.jsx)(o,{variant:`primary`,size:`sm`,disabled:r.isPending||!h.trim(),onClick:()=>void k(),children:`Save`})]}))}),(0,H.jsxs)(ce,{gap:`12px`,children:[(0,H.jsx)(`div`,{children:(0,H.jsx)(I,{label:`Name`,value:l,onChange:e=>f(e.target.value)})}),(0,H.jsx)(`div`,{children:(0,H.jsx)(I,{label:`Family`,value:p,placeholder:`e.g. residential-id`,onChange:e=>m(e.target.value)})}),(0,H.jsx)(`div`,{children:(0,H.jsx)(I,{label:`Endpoint`,value:h,onChange:e=>g(e.target.value),className:`font-mono tabular-nums`})}),(0,H.jsxs)(`div`,{className:`grid grid-cols-2 gap-5`,children:[(0,H.jsx)(`div`,{children:(0,H.jsx)(I,{label:`Max concurrent`,type:`number`,min:1,value:_,onChange:e=>v(e.target.value)})}),(0,H.jsx)(`div`,{children:(0,H.jsx)(I,{label:`Weight`,type:`number`,min:1,value:y,onChange:e=>ee(e.target.value)})})]}),(0,H.jsxs)(`div`,{children:[(0,H.jsx)(I,{label:`Bandwidth quota (GB, blank = unmetered)`,type:`number`,min:.001,step:`0.1`,value:b,onChange:e=>x(e.target.value)}),(0,H.jsx)(`div`,{className:`text-micro text-text-tertiary mt-2`,children:O===null?`No quota — the bar shows a running total only.`:`Bar turns orange at 80% and red once ${c(O)} is exceeded.`})]}),S&&(0,H.jsx)(`div`,{className:`rounded-inset px-6 py-4 text-badge font-semibold ${S.ok?`bg-green-soft text-green`:`bg-red-soft text-red`}`,children:S.message}),(0,H.jsx)(`div`,{children:(0,H.jsx)(o,{variant:`secondary`,size:`sm`,disabled:w,icon:w?(0,H.jsx)(d,{size:13,className:`animate-spin`}):(0,H.jsx)(u,{size:13}),onClick:()=>void D(),children:w?`Testing…`:`Test connection`})})]})}function Qe({endpoint:e,chip:t,onChipChange:n}){return(0,H.jsxs)(`div`,{className:`flex flex-wrap items-center gap-3`,role:`group`,"aria-label":`Scheme for the first endpoint`,children:[(0,H.jsx)(`span`,{className:`text-badge text-text-secondary`,children:`Scheme`}),G.map(r=>{let i=t===r;return(0,H.jsxs)(o,{type:`button`,variant:i?`primary`:`secondary`,size:`sm`,disabled:e===void 0,"aria-pressed":i,"data-scheme":r,onClick:()=>n(i?null:r),className:`font-mono`,children:[r,`://`]},r)}),t!==null&&(0,H.jsxs)(`span`,{className:`text-badge text-text-tertiary`,children:[`→ `,Le(e??``,t)]})]})}function $e({onClose:e,actionsRef:t,onProbeResult:n,onHealthResult:r}){let i=be(),a=Se(),c=Oe(),[l,u]=(0,V.useState)(``),[d,f]=(0,V.useState)(``),[p,m]=(0,V.useState)(``),[h,g]=(0,V.useState)(null),[_,v]=(0,V.useState)([]),[y,ee]=(0,V.useState)({}),[b,x]=(0,V.useState)({}),[S,C]=(0,V.useState)(!1),[w,T]=(0,V.useState)(null),E=l.split(`
|
|
1
|
+
import{n as e,o as t,r as n,t as r}from"./jsx-runtime-CXUMngI_.js";import{i}from"./terminal-0_IjPWTk.js";import{T as a,c as o,s,t as c,v as l,w as u,x as d}from"./numbers-DrdA9oSM.js";import{t as f}from"./eye-off-Bk5g2luF.js";import{t as p}from"./eye-C_hawfH4.js";import{t as m}from"./gauge-BbIMy7MB.js";import{n as h,r as g,t as _}from"./state-D1Yz79iL.js";import{t as v}from"./dialog-CpjrgdwJ.js";import{t as y}from"./pencil-768ysRAr.js";import{t as ee}from"./plus-DIdX_g-x.js";import{t as b}from"./power-off-Yjw9GMJh.js";import{t as x}from"./rotate-ccw-CufcqITi.js";import{t as S}from"./shield-check-DVS0Foqh.js";import{t as C}from"./trash-Cppn5c3R.js";import{C as w,T,c as E,v as D,y as O}from"./assert-C9FD_JwJ.js";import{a as k,i as A,l as j,o as M,t as N}from"./query-keys-BFhGpwR1.js";import{t as P}from"./useMutation-Dem0lXQj.js";import{it as te,z as ne}from"./entry-Dj0cHfEc.js";import{n as re,r as ie,t as ae}from"./card-D5_gYIS_.js";import{n as oe}from"./download-dRFo5_Wu.js";import{t as F}from"./badge-Bvyr7D0u.js";import{n as I}from"./input-BMRlQ450.js";import{t as se}from"./select-CxVVB__N.js";import{t as L}from"./switch-sevsRrRo.js";import{t as ce}from"./stack-uPOwM9Hs.js";import{n as le}from"./inline-C2_EQ5Uf.js";import{r as R,t as ue}from"./layout-XR5xP8ew.js";import{i as de,n as fe}from"./privacy-mode-GM8bej85.js";import{n as z}from"./live-BivGfuUs.js";var pe=e(`cloud`,[[`path`,{d:`M17.5 19H9a7 7 0 1 1 6.71-9h1.79a4.5 4.5 0 1 1 0 9Z`,key:`p7xjir`}]]),me=e(`power`,[[`path`,{d:`M12 2v10`,key:`mnfbl`}],[`path`,{d:`M18.4 6.6a9 9 0 1 1-12.77.04`,key:`obofu9`}]]),he=1e6,B=1e8,ge=5e6,_e=`sin1`,ve=[{label:`Asia Pacific`,regions:[{id:`sin1`,label:`Singapore`},{id:`hkg1`,label:`Hong Kong`},{id:`icn1`,label:`Seoul`},{id:`hnd1`,label:`Tokyo`},{id:`kix1`,label:`Osaka`},{id:`bom1`,label:`Mumbai`},{id:`syd1`,label:`Sydney`}]},{label:`Europe`,regions:[{id:`fra1`,label:`Frankfurt`},{id:`cdg1`,label:`Paris`},{id:`lhr1`,label:`London`},{id:`arn1`,label:`Stockholm`},{id:`dub1`,label:`Dublin`}]},{label:`North America`,regions:[{id:`iad1`,label:`Washington, D.C.`},{id:`sfo1`,label:`San Francisco`},{id:`pdx1`,label:`Portland`},{id:`cle1`,label:`Cleveland`},{id:`yul1`,label:`Montréal`}]},{label:`Other`,regions:[{id:`gru1`,label:`São Paulo`},{id:`cpt1`,label:`Cape Town`},{id:`dxb1`,label:`Dubai`}]}];function ye(){return w({queryKey:N.network.pools,queryFn:e=>M(`/network/pools`,{signal:D(e)}).then(E),staleTime:A.staleTime,gcTime:A.gcTime})}function be(){let e=T();return P({mutationFn:e=>M(`/network/pools`,{method:`POST`,body:JSON.stringify(e)}),onSuccess:async()=>{await e.invalidateQueries({queryKey:N.network.pools}),s.success(`Proxy pool created`)},onError:e=>{s.error(`Could not create the proxy pool.`,j(e))}})}function xe(){let e=T();return P({mutationFn:e=>M(`/network/pools/relay/deploy`,{method:`POST`,body:JSON.stringify(e)}),onSuccess:async()=>{await e.invalidateQueries({queryKey:N.network.pools})}})}function Se(){return P({mutationFn:e=>M(`/network/pools/test-batch`,{method:`POST`,body:JSON.stringify({targets:e})})})}function Ce(){let e=T();return P({mutationFn:({poolId:e,request:t})=>M(`/network/pools/${encodeURIComponent(e)}`,{method:`PATCH`,body:JSON.stringify(t)}),onSuccess:async()=>{await e.invalidateQueries({queryKey:N.network.pools}),s.success(`Proxy updated`)},onError:e=>{s.error(`Could not update the proxy pool.`,j(e))}})}function we(e){return w({queryKey:[...N.network.pools,e,`health-events`],queryFn:t=>M(`/network/pools/${encodeURIComponent(e??``)}/health-events`,{signal:D(t)}),enabled:!!e,...A,refetchInterval:k.status})}function Te(){let e=T();return P({mutationFn:e=>M(`/network/pools/${encodeURIComponent(e)}/recover`,{method:`POST`,body:`{}`}),onSuccess:async(t,n)=>{await Promise.all([e.invalidateQueries({queryKey:N.network.pools}),e.invalidateQueries({queryKey:[...N.network.pools,n,`health-events`]})]),s.success(`Proxy pool recovered`)},onError:e=>{s.error(`Could not recover the proxy pool.`,j(e))}})}function Ee(){let e=T();return P({mutationFn:e=>M(`/network/pools/${encodeURIComponent(e)}`,{method:`DELETE`}),onSuccess:async()=>{await e.invalidateQueries({queryKey:N.network.pools}),s.success(`Proxy pool deleted`)},onError:e=>{s.error(`Could not delete the proxy pool.`,j(e))}})}function De(){let e=T();return P({mutationFn:({poolId:e,providerId:t})=>M(`/network/pools/${encodeURIComponent(e)}/provider-probe`,{method:`POST`,body:JSON.stringify({providerId:t})}),onSuccess:async()=>{await e.invalidateQueries({queryKey:N.network.pools})}})}function Oe(){return P({mutationFn:({providerId:e,targets:t})=>M(`/network/pools/test-batch/provider`,{method:`POST`,body:JSON.stringify({providerId:e,targets:t})})})}function ke(){let e=T();return P({mutationFn:e=>M(`/network/pools/${encodeURIComponent(e)}/health-check`,{method:`POST`,body:`{}`}),onSuccess:async()=>{await e.invalidateQueries({queryKey:N.network.pools}),s.success(`Health check complete`)},onError:e=>{s.error(`Health check failed.`,j(e))}})}function Ae(){let e=T();return P({mutationFn:({poolId:e,bytes:t})=>M(`/network/pools/${encodeURIComponent(e)}/speed-test`,{method:`POST`,body:JSON.stringify({bytes:t})}),onSuccess:async()=>{await e.invalidateQueries({queryKey:N.network.pools})}})}function je(){let e=T();return P({mutationFn:({poolId:e,providerId:t})=>M(`/network/pools/${encodeURIComponent(e)}/cooldowns/clear`,{method:`POST`,body:JSON.stringify(t?{providerId:t}:{})}),onSuccess:async()=>{await e.invalidateQueries({queryKey:N.network.pools}),s.success(`Provider cooldowns cleared`)},onError:e=>{s.error(`Could not clear provider cooldowns.`,j(e))}})}var V=t(n(),1),H=r(),U={cloudflare:{label:`Cloudflare Workers`,tokenLabel:`Cloudflare API token`,needsAccount:!0,host:`*.workers.dev`,hasRegion:!1},vercel:{label:`Vercel`,tokenLabel:`Vercel API token`,needsAccount:!1,host:`*.vercel.app`,hasRegion:!0},deno:{label:`Deno Deploy`,tokenLabel:`Deno Deploy token`,needsAccount:!1,host:`*.deno.dev`,hasRegion:!1}},Me=ve.flatMap(e=>e.regions.map(t=>({value:t.id,label:`${e.label} — ${t.label}`})));function Ne({onClose:e}){let t=xe(),[n,r]=(0,V.useState)(`cloudflare`),[i,a]=(0,V.useState)(_e),[c,u]=(0,V.useState)(``),[d,f]=(0,V.useState)(``),[p,m]=(0,V.useState)(``),[h,g]=(0,V.useState)(null),_=U[n],y=c.trim().length>0&&(!_.needsAccount||d.trim().length>0);return(0,H.jsx)(v,{open:!0,onClose:e,title:`Deploy Relay`,description:`Run outbound traffic through a hosted relay (Cloudflare, Vercel, Deno).`,size:`md`,children:(0,H.jsxs)(ce,{gap:`12px`,children:[(0,H.jsxs)(`p`,{className:`text-badge text-text-tertiary m-0 flex gap-3`,children:[(0,H.jsx)(te,{size:13,className:`shrink-0 mt-0.5`}),(0,H.jsxs)(`span`,{children:[`Deploys a small relay worker to your own `,_.label,` account and registers its URL (`,(0,H.jsx)(`code`,{children:_.host}),`) as an active HTTP pool. Your API token is used only for the deploy and is never stored.`]})]}),(0,H.jsx)(se,{label:`Relay host`,id:`relay-target`,value:n,onValueChange:e=>r(e),options:O.map(e=>({value:e,label:U[e].label}))}),(0,H.jsx)(I,{label:_.tokenLabel,id:`relay-token`,type:`password`,value:c,placeholder:`Paste a deploy token`,onChange:e=>u(e.target.value)}),_.needsAccount?(0,H.jsx)(I,{label:`Account ID`,id:`relay-account`,value:d,placeholder:`Cloudflare account id`,onChange:e=>f(e.target.value)}):null,(0,H.jsx)(I,{label:`Project name (optional)`,id:`relay-project`,value:p,placeholder:`e.g. cartethyia-relay`,onChange:e=>m(e.target.value)}),_.hasRegion?(0,H.jsx)(se,{label:`Deploy region`,id:`relay-region`,value:i,onValueChange:e=>a(e),options:Me}):null,_.hasRegion?(0,H.jsx)(`p`,{className:`text-badge text-text-tertiary m-0`,children:`Sets the region on the Vercel project, which is what decides the country outbound traffic leaves from. A region sent on the deployment alone is accepted but does not move the Function.`}):null,(0,H.jsxs)(`div`,{className:`flex items-center gap-5`,children:[(0,H.jsx)(o,{variant:`primary`,size:`sm`,onClick:()=>{y&&t.mutate({target:n,token:c.trim(),..._.needsAccount&&d.trim()?{accountId:d.trim()}:{},...p.trim()?{projectName:p.trim()}:{},..._.hasRegion?{region:i}:{}},{onSuccess:e=>{g(e.relayUrl),u(``),s.success(`Relay deployed to ${e.relayUrl} and registered as a pool.`)},onError:e=>s.error(j(e,`Relay deploy failed.`))})},disabled:!y||t.isPending,children:t.isPending?`Deploying…`:`Deploy relay`}),h?(0,H.jsxs)(`span`,{className:`mt-1 text-badge text-text-tertiary`,children:[`Registered pool at `,(0,H.jsx)(`code`,{children:h})]}):null]}),t.isError?(0,H.jsxs)(`p`,{className:`text-badge text-red m-0 flex gap-3`,children:[(0,H.jsx)(l,{size:13,className:`shrink-0 mt-0.5`}),(0,H.jsx)(`span`,{children:j(t.error,`Relay deploy failed.`)})]}):null]})})}function Pe(e,t){if(e!==void 0)return e.endpoint===``||e.endpoint===(t??``)?e.result:void 0}function Fe(e,t,n){switch(t){case`name`:return(e.label||e.endpoint).toLowerCase();case`family`:return e.family===void 0||e.family===null||e.family===``?null:e.family.toLowerCase();case`address`:return e.egressIp??null;case`load`:return n??null}}function Ie(e,t,n,r){let i=n===`asc`?1:-1;return[...e].sort((e,n)=>{let a=Fe(e,t,r(e)),o=Fe(n,t,r(n));return a===null&&o===null?0:a===null?1:o===null?-1:typeof a==`number`&&typeof o==`number`?(a-o)*i:String(a).localeCompare(String(o))*i})}function W(e,t){let n=e.filter(e=>e.status===`active`),r=n.reduce((e,t)=>e+t.maxInflight,0),i=t===void 0?n.reduce((e,t)=>e+(t.inflight??0),0):n.reduce((e,n)=>e+(t.get(n.id)??0),0),a=0,o=0;for(let e of n)(t===void 0?e.inflight??0:t.get(e.id)??0)>=e.maxInflight?o+=1:a+=1;let s=null,c=Date.now(),l=e=>{if(!e)return;let t=Date.parse(e);if(Number.isNaN(t))return;let n=t-c;n<=0||(s===null||n<s)&&(s=n)};for(let t of e){l(t.cooldownUntil);for(let e of t.providerCooldowns??[])l(e.until)}let u=n.filter(e=>e.lastLatencyMs!==void 0&&Number.isFinite(e.lastLatencyMs)),d=u.length===0?null:Math.round(u.reduce((e,t)=>e+(t.lastLatencyMs??0),0)/u.length);return{totalPools:e.length,active:n.length,cooldown:e.filter(e=>e.status===`cooldown`).length,totalMaxConcurrency:r,usedInflight:i,availableCapacity:Math.max(0,r-i),routablePools:a,saturatedPools:o,soonestCooldownMs:s,avgLatencyMs:d,measuredPools:u.length}}var G=[`http`,`https`,`socks5`];function K(e){return/^[a-z][a-z0-9+.-]*:\/\//i.test(e.trim())}function Le(e,t){let n=e.trim();return t===null||K(n)?n:`${t}://${n}`}function q(e){return e.find(e=>e.trim()!==``)}function J(e){let t=e.trim().toLowerCase();return t.startsWith(`https://`)?`https`:t.startsWith(`socks5://`)||t.startsWith(`socks://`)?`socks5`:`http`}var Re=1024**3;function ze(e){let t=e.trim();if(t===``)return null;let n=Number(t);return!Number.isFinite(n)||n<=0?null:Math.max(1,Math.round(n*Re))}function Y(e,t,n){let r=new Map;if(t.trim().toLowerCase()===``||n<=0)return r;let i=Math.floor(e/n),a=e-i*n;for(let e=0;e<n;e+=1){let t=e===n-1?a:0;r.set(e,i+t)}return r}var Be=4,Ve=`cartethyia_proxy_test_payload`,He=`cartethyia_proxy_check_results`,Ue=[{value:`url`,label:`Test URL`},{value:`opencode`,label:`Test OpenCode`}],We=`opencode`,Ge=4,Ke=`Mysterious Proxy`;function X(e){return e.avgLatencyMs===null?`no measurement yet`:`avg across ${e.measuredPools} enabled ${e.measuredPools===1?`pool`:`pools`}`}function qe(e){let t=e.endpoint||``,n=t.includes(`://`)?t:`${e.kind}://${t}`,r={"https:":`443`,"http:":`80`,"socks5:":`1080`,"socks:":`1080`};try{let e=new URL(n),t=e.port||r[e.protocol]||``,i=`${e.hostname}${t?`:${t}`:``}`;return{name:i,endpoint:`${e.protocol}//${i}${e.pathname===`/`?``:e.pathname}${e.search}`}}catch{return{name:e.label||t,endpoint:t}}}function Z(e){return e.label||qe(e).name||e.id}var Q=1024**3;function Je(e){if(e.lastSpeedtestStatus===void 0||e.lastSpeedtestAt===void 0)return;let t=e.lastSpeedtestDurationMs??0,n=e.lastSpeedtestBytes??0,r=t>0?n/(t/1e3):void 0;return{poolId:e.id,status:e.lastSpeedtestStatus,bytes:n,durationMs:t,...r===void 0?{}:{bytesPerSecond:r,megabitsPerSecond:r*8/1e6},...e.lastSpeedtestError?{errorMessage:e.lastSpeedtestError}:{},measuredAt:e.lastSpeedtestAt}}function Ye(e,t){if(!e)return t;if(!t)return e;let n=e.measuredAt?new Date(e.measuredAt).getTime():0;return(t.measuredAt?new Date(t.measuredAt).getTime():0)>=n?t:e}var Xe=[{value:String(he),label:`1 MB`},{value:String(ge),label:`5 MB`},{value:`50000000`,label:`50 MB`},{value:String(B),label:`100 MB`}];function Ze({pool:e,onClose:t,actionsRef:n}){let r=Ce(),i=Oe(),a=ke(),[l,f]=(0,V.useState)(e.label??``),[p,m]=(0,V.useState)(e.family??``),[h,g]=(0,V.useState)(e.endpoint??``),[_,v]=(0,V.useState)(String(e.maxInflight??10)),[y,ee]=(0,V.useState)(String(e.weight??100)),[b,x]=(0,V.useState)(e.quotaBytes?String(Math.round(e.quotaBytes/Q*1e3)/1e3):``),[S,C]=(0,V.useState)(null),[w,T]=(0,V.useState)(!1),E=h.trim()===e.endpoint,D=async()=>{T(!0),C(null);try{if(E){let t=await a.mutateAsync(e.id),n=t.status===`healthy`||t.status===`reachable`;C({ok:n,message:t.status===`healthy`?`Connected in ${t.latencyMs??0}ms`:t.errorMessage??`Connection failed`});return}let t=[{kind:e.kind,endpoint:h.trim(),...e.family===null||e.family===void 0?{}:{family:e.family}}],[n]=await i.mutateAsync({providerId:We,targets:t}),r=n?.result;if(!r){C({ok:!1,message:`Probe returned no result`});return}let o=r.status===`allowed`||r.status===`throttled`;C({ok:o,message:r.reason??(r.status===`allowed`?`Reachable${r.latencyMs===void 0?``:` in ${r.latencyMs}ms`}`:r.status===`throttled`?`Reachable; rate limit spent`:`Probe could not complete`)})}catch(e){C({ok:!1,message:j(e,`Connection failed`)})}finally{T(!1)}},O=ze(b),k=async()=>{await r.mutateAsync({poolId:e.id,request:{...l.trim()===e.label?{}:{label:l.trim()||void 0},...p.trim()===(e.family??``)?{}:{family:p.trim()||null},...h.trim()!==e.endpoint&&h.trim()!==``?{endpoint:h.trim()}:{},...Number(_)===e.maxInflight?{}:{maxInflight:Number(_)},...Number(y)===e.weight?{}:{weight:Number(y)},...O===(e.quotaBytes??null)?{}:{quotaBytes:O}}}),s.success(`Proxy updated`),t()};return(0,V.useEffect)(()=>{n?.((0,H.jsxs)(H.Fragment,{children:[(0,H.jsx)(o,{variant:`secondary`,size:`sm`,onClick:t,children:`Cancel`}),(0,H.jsx)(o,{variant:`primary`,size:`sm`,disabled:r.isPending||!h.trim(),onClick:()=>void k(),children:`Save`})]}))}),(0,H.jsxs)(ce,{gap:`12px`,children:[(0,H.jsx)(`div`,{children:(0,H.jsx)(I,{label:`Name`,value:l,onChange:e=>f(e.target.value)})}),(0,H.jsx)(`div`,{children:(0,H.jsx)(I,{label:`Family`,value:p,placeholder:`e.g. residential-id`,onChange:e=>m(e.target.value)})}),(0,H.jsx)(`div`,{children:(0,H.jsx)(I,{label:`Endpoint`,value:h,onChange:e=>g(e.target.value),className:`font-mono tabular-nums`})}),(0,H.jsxs)(`div`,{className:`grid grid-cols-2 gap-5`,children:[(0,H.jsx)(`div`,{children:(0,H.jsx)(I,{label:`Max concurrent`,type:`number`,min:1,value:_,onChange:e=>v(e.target.value)})}),(0,H.jsx)(`div`,{children:(0,H.jsx)(I,{label:`Weight`,type:`number`,min:1,value:y,onChange:e=>ee(e.target.value)})})]}),(0,H.jsxs)(`div`,{children:[(0,H.jsx)(I,{label:`Bandwidth quota (GB, blank = unmetered)`,type:`number`,min:.001,step:`0.1`,value:b,onChange:e=>x(e.target.value)}),(0,H.jsx)(`div`,{className:`text-micro text-text-tertiary mt-2`,children:O===null?`No quota — the bar shows a running total only.`:`Bar turns orange at 80% and red once ${c(O)} is exceeded.`})]}),S&&(0,H.jsx)(`div`,{className:`rounded-inset px-6 py-4 text-badge font-semibold ${S.ok?`bg-green-soft text-green`:`bg-red-soft text-red`}`,children:S.message}),(0,H.jsx)(`div`,{children:(0,H.jsx)(o,{variant:`secondary`,size:`sm`,disabled:w,icon:w?(0,H.jsx)(d,{size:13,className:`animate-spin`}):(0,H.jsx)(u,{size:13}),onClick:()=>void D(),children:w?`Testing…`:`Test connection`})})]})}function Qe({endpoint:e,chip:t,onChipChange:n}){return(0,H.jsxs)(`div`,{className:`flex flex-wrap items-center gap-3`,role:`group`,"aria-label":`Scheme for the first endpoint`,children:[(0,H.jsx)(`span`,{className:`text-badge text-text-secondary`,children:`Scheme`}),G.map(r=>{let i=t===r;return(0,H.jsxs)(o,{type:`button`,variant:i?`primary`:`secondary`,size:`sm`,disabled:e===void 0,"aria-pressed":i,"data-scheme":r,onClick:()=>n(i?null:r),className:`font-mono`,children:[r,`://`]},r)}),t!==null&&(0,H.jsxs)(`span`,{className:`text-badge text-text-tertiary`,children:[`→ `,Le(e??``,t)]})]})}function $e({onClose:e,actionsRef:t,onProbeResult:n,onHealthResult:r}){let i=be(),a=Se(),c=Oe(),[l,u]=(0,V.useState)(``),[d,f]=(0,V.useState)(``),[p,m]=(0,V.useState)(``),[h,g]=(0,V.useState)(null),[_,v]=(0,V.useState)([]),[y,ee]=(0,V.useState)({}),[b,x]=(0,V.useState)({}),[S,C]=(0,V.useState)(!1),[w,T]=(0,V.useState)(null),E=l.split(`
|
|
2
2
|
`).map(e=>e.trim()).filter(Boolean),D=q(E),O=(0,V.useMemo)(()=>w===null||D===void 0?E:E.map((e,t)=>e===D&&t===0?Le(e,w):e),[E,w,D]),k=E.length>100,A=ze(p),M=(0,V.useMemo)(()=>O.map(e=>({kind:J(e),endpoint:e})),[O]),N=async()=>{try{let e=await navigator.clipboard.readText();e&&u(t=>t?`${t}\n${e}`:e)}catch{s.error(`Paste failed`,`Clipboard access denied`)}},P=async()=>{if(M.length!==0){v([`Testing ${M.length} proxy target(s)…`]);try{let e=await a.mutateAsync(M),t=e.map(e=>{let t=e.result.status===`healthy`||e.result.status===`reachable`,n=e.result.latencyMs===void 0?``:` · ${e.result.latencyMs}ms`,r=e.result.egressIp?` · ${e.result.egressIp}`:``,i=t?``:` · ${e.result.errorMessage??e.result.status}`;return`${t?`OK `:`FAIL`} ${e.endpoint}${n}${r}${i}`}),n=e.filter(e=>e.result.status===`healthy`||e.result.status===`reachable`).length;x(t=>{let n={...t};for(let t of e)n[t.endpoint]=t.result;return n}),v([`${n}/${e.length} reachable`,...t]),n===e.length?s.success(`All ${e.length} proxies reachable`):s.error(`${e.length-n} of ${e.length} proxies failed`)}catch(e){v([`Test failed: ${j(e,`batch probe failed`)}`]),s.error(`Test failed`,j(e,`batch probe failed`))}}},te=async()=>{if(M.length!==0){v([`Testing ${M.length} proxy target(s) against OpenCode…`]);try{let e=await c.mutateAsync({providerId:We,targets:M}),t=e.map(e=>{let{status:t,latencyMs:n,reason:r}=e.result,i=n===void 0?``:` · ${n}ms`,a=r===void 0?``:` · ${r}`;return`${t===`allowed`?`OK `:t===`blocked`?`BLOCK`:`FAIL`} ${e.endpoint}${i}${a}`});ee(t=>{let n={...t};for(let t of e)n[t.endpoint]=t.result;return n});let n=e.filter(e=>e.result.status===`allowed`).length,r=e.filter(e=>e.result.status===`blocked`).length;v([`${n}/${e.length} allowed · ${r} blocked`,...t]),r===0&&n===e.length?s.success(`OpenCode accepted all ${e.length} proxies`):s.error(`OpenCode: ${n} allowed · ${r} blocked`)}catch(e){v([`Test failed: ${j(e,`provider probe failed`)}`]),s.error(`Test failed`,j(e,`provider probe failed`))}}};return(0,V.useEffect)(()=>{t?.((0,H.jsxs)(H.Fragment,{children:[(0,H.jsx)(o,{variant:`secondary`,type:`button`,onClick:e,children:`Cancel`}),(0,H.jsx)(o,{variant:`primary`,type:`submit`,form:`add-proxy-form`,disabled:S||E.length===0,children:S?`Adding…`:`Add ${E.length} Prox${E.length===1?`y`:`ies`}`})]}))},[t,S,E.length,e]),(0,H.jsxs)(`form`,{id:`add-proxy-form`,onSubmit:async t=>{if(t.preventDefault(),E.length!==0){g(null),C(!0);try{let t=A===null?new Map:Y(A,d,O.length),a=Array(E.length),o=0,c=async()=>{for(;o<E.length;){let e=o++,s=O[e];try{let o=await i.mutateAsync({kind:J(s),endpoint:s,...t.has(e)?{quotaBytes:t.get(e)}:{},...d.trim()===``?{}:{family:d.trim()}}),c=y[s],l=b[s];o?.id&&(l!==void 0&&r?.(o.id,l),c!==void 0&&n?.(o.id,c)),a[e]={ok:!0}}catch(t){a[e]={ok:!1,error:j(t,`Proxy pool creation failed`)}}}};await Promise.all(Array.from({length:Math.min(Be,E.length)},()=>c()));let l=[],f=0;for(let[e,t]of a.entries())t.ok?f++:l.length<3&&l.push(`${E[e].slice(0,48)}…: ${t.error}`);let p=E.length-f,m=a.find(e=>!e.ok)?.error;f>0&&s.success(`Added ${f} proxy pool(s)`,p?`${p} failed: ${m??`see the import details`}`:void 0),p>0&&f===0&&s.error(`Failed to create pool`,m??`See the import details`),p>0&&g(l.join(`
|
|
3
3
|
`)),f>0&&(u(``),e())}finally{C(!1)}}},className:`flex flex-col gap-4`,children:[(0,H.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,H.jsx)(`label`,{htmlFor:`proxy-endpoints`,className:`text-caption font-semibold text-text-primary`,children:`Proxy endpoints`}),(0,H.jsx)(o,{variant:`secondary`,size:`sm`,type:`button`,onClick:N,children:`Paste`})]}),(0,H.jsx)(`textarea`,{id:`proxy-endpoints`,value:l,onChange:e=>u(e.target.value),placeholder:`http://proxy.example:8080
|
|
4
4
|
https://proxy.example:8443
|
|
Binary file
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{n as e,o as t,r as n,t as r}from"./jsx-runtime-CXUMngI_.js";import{i}from"./terminal-0_IjPWTk.js";import{O as a,c as o,s,v as c,x as l}from"./numbers-DkfMR5Qs.js";import{t as u}from"./chevron-right-BXIy5l3h.js";import{t as d}from"./eye-off-Bk5g2luF.js";import{i as f,n as p,r as m,t as h}from"./state-mPDRlQkl.js";import{t as g}from"./dialog-k37exjNt.js";import{t as _}from"./refresh-cw-BqJFk4sU.js";import{t as v}from"./rotate-ccw-CufcqITi.js";import{t as ee}from"./trash-Cppn5c3R.js";import{t as y}from"./zap-C4EeVW4q.js";import{l as b}from"./query-keys-BFhGpwR1.js";import{z as x}from"./entry-ByMGkR3C.js";import{n as S,t as te}from"./card-DS7CQEsO.js";import{t as C}from"./badge-CR72dasT.js";import{t as w}from"./select-C6MMiaio.js";import{t as T}from"./ProviderIcon-CmfzxpVM.js";import{t as ne}from"./switch-DOmJxg7H.js";import{t as E}from"./stack-BHTfXdz_.js";import{n as D}from"./inline-BhY2sSnO.js";import{t as O}from"./layout-BBOYycyS.js";import{a as k,i as A,n as j,o as M,r as N,s as P,t as F}from"./quota-DZGyp0N5.js";import{a as I,c as L,d as R,f as z,i as B,l as V,n as H,o as U,p as W,r as G,s as K,t as q,u as J}from"./HealthEventsModal-Dn3M6WZc.js";var re=e(`calendar-check`,[[`path`,{d:`M8 2v3`,key:`1ioesn`}],[`path`,{d:`M16 2v3`,key:`otl347`}],[`rect`,{x:`3`,y:`3`,width:`18`,height:`18`,rx:`2`,key:`h1oib`}],[`path`,{d:`M3 9h18`,key:`1pudct`}],[`path`,{d:`m9 15 2 2 4-4`,key:`1grp1n`}]]),ie=e(`chevron-left`,[[`path`,{d:`m15 18-6-6 6-6`,key:`1wnfg3`}]]),Y=e(`clock-3`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`path`,{d:`M12 6v6h4`,key:`135r8i`}]]),X=t(n(),1),Z=r();function Q(e){return!!(e.quota?.windows.length&&e.quota.windows.every(e=>e.remainingPercent!==null&&e.remainingPercent<=0))}function $(e){let t=e.quota?.windows.map(e=>e.resetsAt?new Date(e.resetsAt).getTime():1/0)??[];return Math.min(...t,1/0)}function ae({account:e,onClose:t}){let n=B(e.id,!0),r=J(e.id),i=n.data?.credits??[],a=e=>e?new Date(e).toLocaleString():`—`,c=e=>e?new Date(e).toLocaleString():`—`,l=e=>{if(!e)return``;let t=new Date(e).getTime()-Date.now();if(!Number.isFinite(t))return``;if(t<=0)return`expired`;let n=Math.floor(t/864e5);if(n>=1)return`in ${n}d`;let r=Math.floor(t/36e5);return r>=1?`in ${r}h`:`in ${Math.max(1,Math.floor(t/6e4))}m`};return(0,Z.jsx)(g,{open:!0,onClose:t,size:`lg`,title:`Saved Rate-Limit Resets — ${e.name}`,children:(0,Z.jsxs)(`div`,{className:`flex flex-col gap-7`,children:[(0,Z.jsxs)(`div`,{className:`flex items-center justify-between gap-6 rounded-control border border-inner-border bg-surface-2 px-8 py-6`,children:[(0,Z.jsxs)(`div`,{className:`min-w-0`,children:[(0,Z.jsxs)(`div`,{className:`flex items-center gap-4`,children:[(0,Z.jsx)(y,{size:14,className:`text-status-success`}),(0,Z.jsx)(`span`,{className:`text-body font-semibold`,children:`Available resets`})]}),(0,Z.jsx)(`p`,{className:`mt-2 text-text-tertiary text-badge leading-normal`,children:`Each credit lifts a spent rate-limit window before its natural reset.`})]}),(0,Z.jsxs)(C,{tone:n.data&&n.data.availableCount>0?`ok`:`disabled`,dot:!0,children:[n.data?.availableCount??0,` reset`,(n.data?.availableCount??0)===1?``:`s`]})]}),n.isPending?(0,Z.jsx)(m,{compact:!0,label:`Reading saved resets…`}):n.isError?(0,Z.jsx)(p,{compact:!0,message:`Failed to read saved resets`,onRetry:()=>void n.refetch()}):i.length===0?(0,Z.jsx)(h,{compact:!0,title:`No saved resets`,message:`This account has no saved rate-limit reset credits right now.`,icon:(0,Z.jsx)(y,{size:20})}):(0,Z.jsx)(`div`,{className:`max-h-170 overflow-y-auto rounded-control border border-inner-border`,children:(0,Z.jsx)(O,{headers:[`Status`,`Title`,`Granted`,`Expires`,``],children:i.map(e=>{let t=(e.status??`available`)===`available`,n=l(e.expiresAt);return(0,Z.jsxs)(`tr`,{children:[(0,Z.jsx)(`td`,{className:`whitespace-nowrap align-middle`,children:(0,Z.jsx)(C,{tone:t?`ok`:e.status===`expired`?`disabled`:`warn`,children:e.status??`available`})}),(0,Z.jsx)(`td`,{className:`text-caption font-medium whitespace-nowrap align-middle text-text-primary`,children:e.title??`Rate-limit reset`}),(0,Z.jsx)(`td`,{className:`text-badge whitespace-nowrap tabular-nums align-middle text-text-secondary`,children:a(e.grantedAt)}),(0,Z.jsxs)(`td`,{className:`text-badge whitespace-nowrap tabular-nums align-middle text-text-secondary`,children:[c(e.expiresAt),n&&(0,Z.jsxs)(`span`,{className:`ml-3 text-text-tertiary`,children:[`(`,n,`)`]})]}),(0,Z.jsx)(`td`,{className:`whitespace-nowrap text-right align-middle`,children:(0,Z.jsx)(o,{size:`sm`,variant:t?`primary`:`secondary`,disabled:!t||r.isPending,onClick:()=>r.mutate({creditId:e.id},{onSuccess:e=>{e.ok?s.success(e.message??`Rate limit reset applied`):s.error(e.message??`Rate limit reset failed`)},onError:e=>{s.error(b(e,`Unable to redeem rate-limit reset`))}}),children:`Use`})})]},e.id)})})}),(0,Z.jsx)(D,{justify:`flex-end`,gap:`0px`,children:(0,Z.jsx)(o,{variant:`secondary`,size:`sm`,onClick:t,children:`Close`})})]})})}function oe({accounts:e}){let t=(0,X.useMemo)(()=>{let t=new Map;for(let n of e){if(!H(n.provider))continue;let e=t.get(n.provider);e?e.count+=1:t.set(n.provider,{id:n.provider,label:n.providerName||n.provider,count:1})}return[...t.values()]},[e]),[n,r]=(0,X.useState)(``),i=(t.find(e=>e.id===n)??t[0])?.id??``,a=z(i),c=i.length===0||a.isPending||t.length===0;return(0,Z.jsxs)(`div`,{className:`flex min-w-0 flex-wrap items-center gap-2.5`,"aria-label":`Daily growth actions`,children:[(0,Z.jsx)(`div`,{className:`min-w-0 w-67.5`,children:(0,Z.jsx)(w,{"aria-label":`Provider for the daily growth pass`,value:i,onValueChange:r,className:`w-full h-16`,options:t.length>0?t.map(e=>({value:e.id,label:`${e.label} · ${e.count}`})):[{value:``,label:`No buddy providers`}]})}),(0,Z.jsx)(o,{variant:`secondary`,size:`sm`,title:`Send the activity report, then claim the daily check-in, for every account of this provider`,"aria-label":`Run the daily growth pass for this provider`,disabled:c,className:`shrink-0`,icon:a.isPending?(0,Z.jsx)(l,{size:13,className:`animate-spin`}):(0,Z.jsx)(re,{size:13}),onClick:()=>a.mutate(void 0,{onSuccess:e=>{let t=e.data.filter(e=>!e.report.ok).length;t===0?s.success(e.message):s.error(`${e.message} — ${t} report${t===1?``:`s`} failed`)},onError:e=>s.error(b(e,`Unable to run the daily growth pass`))}),children:`Daily growth`})]})}function se({account:e,onToggle:t,onDelete:n,onShowHealth:r,onShowResets:a}){let d=K(e.id),f=R(e.id),p=H(e.provider),m=G(e.provider),h=B(e.id,m),g=e.quota,[_,x]=(0,X.useState)(0),S=g?.windows??[],C=M(S,_),w=C.pageCount;(0,X.useEffect)(()=>{x(e=>Math.min(e,Math.max(0,w-1)))},[w]);let E=d.isPending||f.isPending,D=h.data?.availableCount??0,[O,I]=(0,X.useState)(null),[L,z]=(0,X.useState)(!1),V=e.checkin?.attemptedToday??!1,U=`${O?O.state===`claimed`?`Checked in${O.credit===null?``:` +${O.credit}`}${O.streakDays===null?``:` · ${O.streakDays}d streak`}`:O.state===`already_claimed`?`Check-in attempted · already claimed`:O.state===`not_eligible`?`Check-in attempted · not eligible`:O.state===`event_ended`?`Check-in attempted · event ended`:`Check-in attempted · unavailable`:V?`Check-in attempted today`:`Check-in due`}${L?` · Reported today`:``}`,W=S.reduce((e,t)=>{let n=t.limit;if(typeof n!=`number`||!Number.isFinite(n))return e;let r=typeof t.remaining==`number`&&Number.isFinite(t.remaining)?t.remaining:typeof t.used==`number`&&Number.isFinite(t.used)?n-t.used:typeof t.remainingPercent==`number`&&Number.isFinite(t.remainingPercent)?n*t.remainingPercent/100:null;return r===null?e:e+Math.max(0,r)},0),q=(d.error?b(d.error,`Unable to refresh this account`):null)??g?.refreshError??g?.error??e.health?.sanitizedMessage,J=k(q),Y=J===`Quota tracking is not supported for this provider`?null:J,Q=F(e.credentialHint,e.name),$=e.health?.status??`unknown`;return(0,Z.jsxs)(te,{className:`flex h-full flex-col overflow-hidden`,"aria-busy":E,children:[(0,Z.jsxs)(`div`,{className:`flex flex-wrap items-center gap-5 px-7 py-4`,children:[(0,Z.jsx)(T,{icon:e.providerIcon,name:e.providerName,size:32}),(0,Z.jsxs)(`div`,{className:`flex-[1_1_160px]`,children:[(0,Z.jsxs)(`div`,{className:`flex min-w-0 items-center gap-4`,children:[(0,Z.jsx)(`div`,{className:`truncate text-caption font-bold text-text-primary text-body`,children:e.providerName}),g?.plan&&(0,Z.jsx)(`span`,{className:`shrink-0 rounded-chip bg-accent-soft px-4 py-1 text-micro font-semibold text-accent`,children:g.plan})]}),(0,Z.jsx)(`div`,{className:`truncate text-badge text-text-secondary`,children:Q.primary}),Q.secondary!==null&&(0,Z.jsx)(`div`,{className:`truncate text-micro text-text-tertiary`,children:Q.secondary}),g&&(0,Z.jsx)(`div`,{className:`truncate text-micro text-text-tertiary`,children:j(g.lastSuccessAt??g.fetchedAt)}),m&&(0,Z.jsx)(`div`,{className:`truncate text-micro flex items-center gap-2 text-text-tertiary`,title:`Saved rate-limit reset credits available on this account`,children:h.isPending?`Checking saved resets…`:D>0?(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsx)(y,{size:10,className:`text-status-success shrink-0`,"aria-hidden":`true`}),(0,Z.jsxs)(`span`,{className:`reset-credit-live`,children:[D,` rate-limit reset`,D===1?``:`s`,` available`]})]}):`No rate-limit resets available`}),p&&(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsx)(`div`,{title:`Daily growth state: manual pass result, else the sweep ledger for today`,className:`truncate text-micro text-text-tertiary`,children:f.isPending?`Running growth pass…`:U}),S.some(e=>typeof e.limit==`number`&&Number.isFinite(e.limit))&&(0,Z.jsxs)(`div`,{className:`truncate text-micro text-text-tertiary`,children:[`Total credits: `,W.toLocaleString(void 0,{maximumFractionDigits:2})]})]})]}),(0,Z.jsxs)(`div`,{className:`flex items-center gap-1.75 gap-3 ml-auto`,children:[m&&(0,Z.jsx)(o,{variant:`ghost`,size:`icon`,className:`w-16 h-16 p-0`,title:h.isPending?`Checking saved rate-limit resets…`:D>0?`Saved rate-limit resets (${D} available)`:`Saved rate-limit resets`,"aria-label":`Open saved rate-limit resets for ${e.name}`,disabled:E,onClick:()=>a(e),children:(0,Z.jsx)(y,{size:14})}),p&&(0,Z.jsx)(o,{variant:`ghost`,size:`icon`,className:`w-16 h-16 p-0`,title:`Daily growth pass (check-in + activity report) — ${U}`,"aria-label":`Run daily growth pass for ${e.name}`,disabled:E,onClick:()=>f.mutate(void 0,{onSuccess:e=>{let t=e.checkin.data;t&&I({state:t.state,credit:t.credit,streakDays:t.streakDays}),e.report.ok&&z(!0),e.ok?s.success(e.message):s.error(e.message)},onError:e=>{s.error(b(e,`Unable to run daily growth pass`))}}),children:f.isPending?(0,Z.jsx)(l,{size:14,className:`animate-spin`}):(0,Z.jsx)(re,{size:14})}),(0,Z.jsx)(o,{variant:`ghost`,size:`sm`,title:$===`active`?`Health & Error Log`:`${$} — Inspect account health details`,"aria-label":$===`active`?`Health log for ${e.name}`:`Account is ${$} — inspect health details for ${e.name}`,disabled:E,onClick:()=>r(e),icon:(0,Z.jsx)(i,{size:12})}),(0,Z.jsx)(o,{variant:`ghost`,size:`sm`,title:`Refresh quota`,"aria-label":`Refresh ${e.name} quota`,disabled:E,onClick:()=>d.mutate(),icon:d.isPending?(0,Z.jsx)(l,{size:12,className:`animate-spin`}):(0,Z.jsx)(v,{size:12})}),(0,Z.jsx)(o,{variant:`ghost`,size:`sm`,title:`Delete account`,"aria-label":`Delete ${e.name}`,onClick:()=>n(e),className:`text-red`,icon:(0,Z.jsx)(ee,{size:12})}),(0,Z.jsx)(ne,{checked:e.active,disabled:d.isPending,onChange:n=>t(e,n),label:``,id:`switch-${e.id}`})]})]}),Y&&(0,Z.jsxs)(`div`,{className:`flex items-center justify-center gap-4 border-t border-inner-border px-8 py-5 text-center text-badge text-red`,role:`alert`,children:[(0,Z.jsx)(c,{size:13,className:`shrink-0`}),(0,Z.jsx)(`span`,{children:Y})]}),g?.windows.length?(0,Z.jsxs)(`div`,{className:`quota-window-list flex flex-1 flex-col gap-4 border-t border-inner-border px-7 py-4.5`,children:[(0,Z.jsx)(`div`,{className:`quota-window-section-label text-micro font-bold tracking-label text-text-tertiary`,children:`QUOTA WINDOWS`}),C.items.map((e,t)=>{let n=e.remainingPercent??null,r=typeof e.limit==`number`&&Number.isFinite(e.limit)?e.limit:null,i=typeof e.used==`number`&&Number.isFinite(e.used)?e.used:r!==null&&e.usedPercent!==null&&e.usedPercent!==void 0?r*e.usedPercent/100:null,a=P(n),o=n===null?0:Math.max(0,Math.min(100,n)),s=e=>e.toLocaleString(void 0,{maximumFractionDigits:2}),c=e=>{let t=Math.round(e*10)/10;return t>0&&t<.1?`<0.1`:t.toLocaleString(void 0,{maximumFractionDigits:1})},l=N(e.label);return(0,Z.jsxs)(`div`,{className:`quota-window-row grid grid-cols-quota-window min-w-0 items-center gap-x-6 gap-y-2 max-small:grid-cols-[minmax(0,1fr)_auto] max-small:gap-x-4 max-small:gap-y-2.5`,children:[(0,Z.jsx)(`div`,{className:`quota-window-heading min-w-0 max-small:col-start-1`,children:(0,Z.jsx)(`span`,{className:`text-badge font-semibold text-text-primary`,children:l})}),(0,Z.jsx)(`div`,{className:`quota-bar-track quota-window-bar min-w-0 w-full h-5 rounded-tiny bg-inner-border overflow-hidden max-small:col-span-full max-small:row-start-2`,role:`progressbar`,"aria-label":`${l} remaining quota`,"aria-valuemin":0,"aria-valuemax":100,"aria-valuenow":n===null?void 0:o,"aria-valuetext":n===null?`Quota only`:`${c(n)}% remaining`,children:(0,Z.jsx)(`div`,{className:`quota-bar-fill h-full rounded-tiny transition-[width] duration-(--dur-macro) ease-spring`,style:{width:`${o}%`,background:a.bar}})}),(0,Z.jsx)(`span`,{className:`quota-window-remaining whitespace-nowrap text-badge font-bold tabular-nums max-small:col-start-2 max-small:row-start-1`,style:{color:a.text},children:n===null?`—`:`${c(n)}%`}),(0,Z.jsxs)(`div`,{className:`quota-window-details col-span-full flex min-w-0 items-center justify-end gap-6 text-micro text-text-tertiary max-small:row-start-3 max-small:flex-wrap max-small:justify-between max-small:gap-4`,children:[(0,Z.jsx)(`span`,{className:`quota-window-usage mr-auto tabular-nums max-small:min-w-0`,children:i!==null&&r!==null?`${s(i)} / ${s(r)} Credits`:`Quota only`}),e.resetsAt&&(0,Z.jsx)(`span`,{className:`quota-window-reset whitespace-nowrap tabular-nums text-right max-small:ml-auto`,children:A(e.resetsAt,e.recurring)})]})]},`${e.kind??e.label}:${e.resetsAt??`none`}:${t}`)}),C.pageCount>1&&(0,Z.jsxs)(`nav`,{"aria-label":`Quota windows for ${e.name}`,className:`quota-window-pagination mt-auto flex items-center justify-between gap-4 border-t border-inner-border pt-4 max-small:flex-wrap`,children:[(0,Z.jsxs)(`span`,{"aria-live":`polite`,className:`text-micro text-text-tertiary`,children:[`Showing `,C.startIndex+1,`–`,C.startIndex+C.items.length,` of `,S.length]}),(0,Z.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,Z.jsx)(o,{variant:`ghost`,size:`sm`,"aria-label":`Previous quota windows for ${e.name}`,disabled:C.page===0,icon:(0,Z.jsx)(ie,{size:13}),onClick:()=>x(C.page-1),className:`h-14 px-4 py-0`,children:`Previous`}),(0,Z.jsx)(o,{variant:`ghost`,size:`sm`,"aria-label":`Next quota windows for ${e.name}`,disabled:C.page>=C.pageCount-1,icon:(0,Z.jsx)(u,{size:13}),onClick:()=>x(C.page+1),className:`h-14 px-4 py-0`,children:`Next`})]})]})]}):Y?null:(0,Z.jsx)(`div`,{className:`border-t border-inner-border px-7 py-9 text-center text-badge text-text-tertiary`,children:E||e.pending?`Fetching quota…`:`No quota data`})]})}function ce(){let[e,t]=(0,X.useState)(`all`),[n,r]=(0,X.useState)(`all`),[i,c]=(0,X.useState)(!1),{data:l,isLoading:u,isError:p,error:m,isFetching:g,dataUpdatedAt:v,refetch:ee}=U(),y=(0,X.useMemo)(()=>[...l?.providers??[]].sort((e,t)=>e.name.localeCompare(t.name,void 0,{sensitivity:`base`})),[l?.providers]),b=(0,X.useMemo)(()=>l?.accounts??[],[l?.accounts]),C=l?.refreshing??0,T=L(),ne=W(),D=V(),O=I(),[k,A]=(0,X.useState)(null),[j,M]=(0,X.useState)(null),[N,P]=(0,X.useState)(null),F=(0,X.useMemo)(()=>{let t=b.filter(t=>{if(e!==`all`&&t.provider!==e)return!1;let r=!!t.quota?.windows.length;return n===`untracked`?!r:!(!r||n===`active`&&!t.active||n===`disabled`&&t.active)}),r=(e,t)=>e.providerName.localeCompare(t.providerName,void 0,{sensitivity:`base`})||e.name.localeCompare(t.name,void 0,{sensitivity:`base`});return[...t].sort(i?(e,t)=>$(e)-$(t)||r(e,t):r)},[n,b,i,e]),R=async(e,t)=>{try{await ne.mutateAsync({id:e.id,active:t}),s.success(`${e.name} ${t?`enabled`:`disabled`}`)}catch(e){s.error(e instanceof Error?e.message:`Unable to update account`)}},z=async()=>{let e=b.filter(e=>e.active&&Q(e));await D.mutateAsync({ids:e.map(e=>e.id),active:!1}),s.success(`Disabled ${e.length} empty accounts`)},B=async()=>{let e=b.filter(e=>!e.active&&e.quota?.windows.some(e=>e.remainingPercent!==null&&e.remainingPercent>0));await D.mutateAsync({ids:e.map(e=>e.id),active:!0}),s.success(`Enabled ${e.length} available accounts`)},H=async e=>{await O.mutateAsync(e.id),s.success(`${e.name} deleted`)},G=v>0?new Date(v).toLocaleTimeString([],{hour:`2-digit`,minute:`2-digit`}):`Not updated`,K=b.filter(Q).length;return(0,Z.jsxs)(E,{gap:`16px`,className:`dashboard-page min-h-0 flex-1`,children:[(0,Z.jsx)(te,{children:(0,Z.jsxs)(S,{className:`flex flex-col gap-5`,children:[(0,Z.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-5`,children:[(0,Z.jsxs)(`div`,{className:`flex min-w-0 flex-1 flex-wrap items-center gap-4`,children:[(0,Z.jsx)(w,{"aria-label":`Filter quota by provider`,value:e,onValueChange:t,className:`w-full h-16 max-small:w-80`,options:[{value:`all`,label:`All Providers`},...y.map(e=>({value:e.id,label:e.name}))]}),(0,Z.jsx)(w,{"aria-label":`Filter quota by account`,value:n,onValueChange:r,className:`w-full h-16 max-small:w-67.5`,options:[{value:`all`,label:`With quota`},{value:`active`,label:`Active`},{value:`disabled`,label:`Disabled`},{value:`untracked`,label:`No quota`}]})]}),(0,Z.jsxs)(`div`,{className:`flex flex-wrap items-center gap-4`,children:[(0,Z.jsx)(o,{variant:i?`secondary`:`ghost`,size:`sm`,onClick:()=>c(e=>!e),"aria-pressed":i,icon:(0,Z.jsx)(Y,{size:13}),children:`Expiring first`}),(0,Z.jsx)(o,{variant:`ghost`,size:`sm`,className:`text-red`,disabled:K===0||g,onClick:()=>void z(),icon:(0,Z.jsx)(d,{size:13}),children:`Turn off Empty`}),(0,Z.jsx)(o,{variant:`ghost`,size:`sm`,className:`text-green`,disabled:g,onClick:()=>void B(),icon:(0,Z.jsx)(a,{size:13}),children:`Turn on Available`})]})]}),(0,Z.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-4 border-t border-inner-border pt-5`,children:[(0,Z.jsxs)(`span`,{className:`text-badge text-text-tertiary`,children:[F.length,` shown`,K>0?` · ${K} empty`:``]}),(0,Z.jsxs)(`span`,{className:`flex min-w-0 flex-wrap items-center gap-x-5 gap-y-3 text-badge text-text-tertiary`,children:[C>0?`Refreshing ${C} account${C===1?``:`s`}…`:`Auto-refresh 60s · ${G}`,(0,Z.jsx)(oe,{accounts:b}),(0,Z.jsx)(o,{variant:`secondary`,size:`sm`,title:`Queue quota refresh`,"aria-label":`Queue quota refresh`,disabled:g||T.isPending||b.length===0,icon:(0,Z.jsx)(_,{size:13,className:T.isPending?`animate-spin`:void 0}),onClick:()=>T.mutate(b.map(e=>e.id),{onSuccess:e=>{s.success(e.failed===0?`Refreshed ${e.succeeded} quota${e.succeeded===1?``:`s`}`:`Refreshed ${e.succeeded}, ${e.failed} failed`)},onError:e=>s.error(e instanceof Error?e.message:`Unable to refresh quota`)}),children:`Refresh`})]})]})]})}),(0,Z.jsx)(`div`,{className:`flex min-h-0 flex-1 flex-col gap-6`,children:u?(0,Z.jsx)(f,{className:`min-h-0 flex flex-1 flex-col items-center justify-center`,kind:`loading`,title:`Loading quota data`,description:`Reading provider account limits…`}):p?(0,Z.jsx)(f,{className:`min-h-0 flex flex-1 flex-col items-center justify-center`,kind:`error`,title:`Unable to load quota data`,description:m instanceof Error?m.message:`Check the console session and retry.`,action:(0,Z.jsx)(o,{variant:`secondary`,onClick:()=>void ee(),children:`Retry`})}):F.length===0?(0,Z.jsx)(`div`,{className:`flex-1 flex items-center justify-center p-12 border border-dashed border-transparent rounded-card bg-transparent text-center`,children:(0,Z.jsx)(h,{title:`No account quota data`,message:`Nothing is reporting a quota window yet. Add a provider account and its limits will appear here.`})}):(0,Z.jsx)(`div`,{className:`quota-account-grid scroll-region min-h-0 flex-1 gap-6 [align-content:start]`,children:F.map(e=>(0,Z.jsx)(se,{account:e,onToggle:(e,t)=>void R(e,t),onDelete:e=>A(e),onShowHealth:e=>M(e),onShowResets:e=>P(e)},e.id))})}),j&&(0,Z.jsx)(q,{summary:{providerId:j.provider,accountId:j.id,title:j.name,status:j.health?.status??`unknown`,errorCategory:j.health?.lastErrorCategory??void 0,errorMessage:j.health?.sanitizedMessage??void 0,emptyMessage:`Status transitions, rate limits, quota refreshes, check-ins, and auto-recoveries will appear here.`},onClose:()=>M(null)}),N&&(0,Z.jsx)(ae,{account:N,onClose:()=>P(null)}),(0,Z.jsx)(x,{open:k!==null,onClose:()=>A(null),onConfirm:async()=>{k&&await H(k)},title:`Delete account?`,message:`Delete "${k?.name}"? This cannot be undone.`,confirmLabel:`Delete`,danger:!0})]})}export{ce as default};
|
|
1
|
+
import{n as e,o as t,r as n,t as r}from"./jsx-runtime-CXUMngI_.js";import{i}from"./terminal-0_IjPWTk.js";import{O as a,c as o,s,v as c,x as l}from"./numbers-DrdA9oSM.js";import{t as u}from"./chevron-right-BXIy5l3h.js";import{t as d}from"./eye-off-Bk5g2luF.js";import{i as f,n as p,r as m,t as h}from"./state-D1Yz79iL.js";import{t as g}from"./dialog-CpjrgdwJ.js";import{t as _}from"./refresh-cw-BqJFk4sU.js";import{t as v}from"./rotate-ccw-CufcqITi.js";import{t as ee}from"./trash-Cppn5c3R.js";import{t as y}from"./zap-C4EeVW4q.js";import{l as b}from"./query-keys-BFhGpwR1.js";import{z as x}from"./entry-Dj0cHfEc.js";import{n as S,t as te}from"./card-D5_gYIS_.js";import{t as C}from"./badge-Bvyr7D0u.js";import{t as w}from"./select-CxVVB__N.js";import{t as T}from"./ProviderIcon-CmfzxpVM.js";import{t as ne}from"./switch-sevsRrRo.js";import{t as E}from"./stack-uPOwM9Hs.js";import{n as D}from"./inline-C2_EQ5Uf.js";import{t as O}from"./layout-XR5xP8ew.js";import{a as k,i as A,n as j,o as M,r as N,s as P,t as F}from"./quota-DZGyp0N5.js";import{a as I,c as L,d as R,f as z,i as B,l as V,n as H,o as U,p as W,r as G,s as K,t as q,u as J}from"./HealthEventsModal-BYPucTTn.js";var re=e(`calendar-check`,[[`path`,{d:`M8 2v3`,key:`1ioesn`}],[`path`,{d:`M16 2v3`,key:`otl347`}],[`rect`,{x:`3`,y:`3`,width:`18`,height:`18`,rx:`2`,key:`h1oib`}],[`path`,{d:`M3 9h18`,key:`1pudct`}],[`path`,{d:`m9 15 2 2 4-4`,key:`1grp1n`}]]),ie=e(`chevron-left`,[[`path`,{d:`m15 18-6-6 6-6`,key:`1wnfg3`}]]),Y=e(`clock-3`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`path`,{d:`M12 6v6h4`,key:`135r8i`}]]),X=t(n(),1),Z=r();function Q(e){return!!(e.quota?.windows.length&&e.quota.windows.every(e=>e.remainingPercent!==null&&e.remainingPercent<=0))}function $(e){let t=e.quota?.windows.map(e=>e.resetsAt?new Date(e.resetsAt).getTime():1/0)??[];return Math.min(...t,1/0)}function ae({account:e,onClose:t}){let n=B(e.id,!0),r=J(e.id),i=n.data?.credits??[],a=e=>e?new Date(e).toLocaleString():`—`,c=e=>e?new Date(e).toLocaleString():`—`,l=e=>{if(!e)return``;let t=new Date(e).getTime()-Date.now();if(!Number.isFinite(t))return``;if(t<=0)return`expired`;let n=Math.floor(t/864e5);if(n>=1)return`in ${n}d`;let r=Math.floor(t/36e5);return r>=1?`in ${r}h`:`in ${Math.max(1,Math.floor(t/6e4))}m`};return(0,Z.jsx)(g,{open:!0,onClose:t,size:`lg`,title:`Saved Rate-Limit Resets — ${e.name}`,children:(0,Z.jsxs)(`div`,{className:`flex flex-col gap-7`,children:[(0,Z.jsxs)(`div`,{className:`flex items-center justify-between gap-6 rounded-control border border-inner-border bg-surface-2 px-8 py-6`,children:[(0,Z.jsxs)(`div`,{className:`min-w-0`,children:[(0,Z.jsxs)(`div`,{className:`flex items-center gap-4`,children:[(0,Z.jsx)(y,{size:14,className:`text-status-success`}),(0,Z.jsx)(`span`,{className:`text-body font-semibold`,children:`Available resets`})]}),(0,Z.jsx)(`p`,{className:`mt-2 text-text-tertiary text-badge leading-normal`,children:`Each credit lifts a spent rate-limit window before its natural reset.`})]}),(0,Z.jsxs)(C,{tone:n.data&&n.data.availableCount>0?`ok`:`disabled`,dot:!0,children:[n.data?.availableCount??0,` reset`,(n.data?.availableCount??0)===1?``:`s`]})]}),n.isPending?(0,Z.jsx)(m,{compact:!0,label:`Reading saved resets…`}):n.isError?(0,Z.jsx)(p,{compact:!0,message:`Failed to read saved resets`,onRetry:()=>void n.refetch()}):i.length===0?(0,Z.jsx)(h,{compact:!0,title:`No saved resets`,message:`This account has no saved rate-limit reset credits right now.`,icon:(0,Z.jsx)(y,{size:20})}):(0,Z.jsx)(`div`,{className:`max-h-170 overflow-y-auto rounded-control border border-inner-border`,children:(0,Z.jsx)(O,{headers:[`Status`,`Title`,`Granted`,`Expires`,``],children:i.map(e=>{let t=(e.status??`available`)===`available`,n=l(e.expiresAt);return(0,Z.jsxs)(`tr`,{children:[(0,Z.jsx)(`td`,{className:`whitespace-nowrap align-middle`,children:(0,Z.jsx)(C,{tone:t?`ok`:e.status===`expired`?`disabled`:`warn`,children:e.status??`available`})}),(0,Z.jsx)(`td`,{className:`text-caption font-medium whitespace-nowrap align-middle text-text-primary`,children:e.title??`Rate-limit reset`}),(0,Z.jsx)(`td`,{className:`text-badge whitespace-nowrap tabular-nums align-middle text-text-secondary`,children:a(e.grantedAt)}),(0,Z.jsxs)(`td`,{className:`text-badge whitespace-nowrap tabular-nums align-middle text-text-secondary`,children:[c(e.expiresAt),n&&(0,Z.jsxs)(`span`,{className:`ml-3 text-text-tertiary`,children:[`(`,n,`)`]})]}),(0,Z.jsx)(`td`,{className:`whitespace-nowrap text-right align-middle`,children:(0,Z.jsx)(o,{size:`sm`,variant:t?`primary`:`secondary`,disabled:!t||r.isPending,onClick:()=>r.mutate({creditId:e.id},{onSuccess:e=>{e.ok?s.success(e.message??`Rate limit reset applied`):s.error(e.message??`Rate limit reset failed`)},onError:e=>{s.error(b(e,`Unable to redeem rate-limit reset`))}}),children:`Use`})})]},e.id)})})}),(0,Z.jsx)(D,{justify:`flex-end`,gap:`0px`,children:(0,Z.jsx)(o,{variant:`secondary`,size:`sm`,onClick:t,children:`Close`})})]})})}function oe({accounts:e}){let t=(0,X.useMemo)(()=>{let t=new Map;for(let n of e){if(!H(n.provider))continue;let e=t.get(n.provider);e?e.count+=1:t.set(n.provider,{id:n.provider,label:n.providerName||n.provider,count:1})}return[...t.values()]},[e]),[n,r]=(0,X.useState)(``),i=(t.find(e=>e.id===n)??t[0])?.id??``,a=z(i),c=i.length===0||a.isPending||t.length===0;return(0,Z.jsxs)(`div`,{className:`flex min-w-0 flex-wrap items-center gap-2.5`,"aria-label":`Daily growth actions`,children:[(0,Z.jsx)(`div`,{className:`min-w-0 w-67.5`,children:(0,Z.jsx)(w,{"aria-label":`Provider for the daily growth pass`,value:i,onValueChange:r,className:`w-full h-16`,options:t.length>0?t.map(e=>({value:e.id,label:`${e.label} · ${e.count}`})):[{value:``,label:`No buddy providers`}]})}),(0,Z.jsx)(o,{variant:`secondary`,size:`sm`,title:`Send the activity report, then claim the daily check-in, for every account of this provider`,"aria-label":`Run the daily growth pass for this provider`,disabled:c,className:`shrink-0`,icon:a.isPending?(0,Z.jsx)(l,{size:13,className:`animate-spin`}):(0,Z.jsx)(re,{size:13}),onClick:()=>a.mutate(void 0,{onSuccess:e=>{let t=e.data.filter(e=>!e.report.ok).length;t===0?s.success(e.message):s.error(`${e.message} — ${t} report${t===1?``:`s`} failed`)},onError:e=>s.error(b(e,`Unable to run the daily growth pass`))}),children:`Daily growth`})]})}function se({account:e,onToggle:t,onDelete:n,onShowHealth:r,onShowResets:a}){let d=K(e.id),f=R(e.id),p=H(e.provider),m=G(e.provider),h=B(e.id,m),g=e.quota,[_,x]=(0,X.useState)(0),S=g?.windows??[],C=M(S,_),w=C.pageCount;(0,X.useEffect)(()=>{x(e=>Math.min(e,Math.max(0,w-1)))},[w]);let E=d.isPending||f.isPending,D=h.data?.availableCount??0,[O,I]=(0,X.useState)(null),[L,z]=(0,X.useState)(!1),V=e.checkin?.attemptedToday??!1,U=`${O?O.state===`claimed`?`Checked in${O.credit===null?``:` +${O.credit}`}${O.streakDays===null?``:` · ${O.streakDays}d streak`}`:O.state===`already_claimed`?`Check-in attempted · already claimed`:O.state===`not_eligible`?`Check-in attempted · not eligible`:O.state===`event_ended`?`Check-in attempted · event ended`:`Check-in attempted · unavailable`:V?`Check-in attempted today`:`Check-in due`}${L?` · Reported today`:``}`,W=S.reduce((e,t)=>{let n=t.limit;if(typeof n!=`number`||!Number.isFinite(n))return e;let r=typeof t.remaining==`number`&&Number.isFinite(t.remaining)?t.remaining:typeof t.used==`number`&&Number.isFinite(t.used)?n-t.used:typeof t.remainingPercent==`number`&&Number.isFinite(t.remainingPercent)?n*t.remainingPercent/100:null;return r===null?e:e+Math.max(0,r)},0),q=(d.error?b(d.error,`Unable to refresh this account`):null)??g?.refreshError??g?.error??e.health?.sanitizedMessage,J=k(q),Y=J===`Quota tracking is not supported for this provider`?null:J,Q=F(e.credentialHint,e.name),$=e.health?.status??`unknown`;return(0,Z.jsxs)(te,{className:`flex h-full flex-col overflow-hidden`,"aria-busy":E,children:[(0,Z.jsxs)(`div`,{className:`flex flex-wrap items-center gap-5 px-7 py-4`,children:[(0,Z.jsx)(T,{icon:e.providerIcon,name:e.providerName,size:32}),(0,Z.jsxs)(`div`,{className:`flex-[1_1_160px]`,children:[(0,Z.jsxs)(`div`,{className:`flex min-w-0 items-center gap-4`,children:[(0,Z.jsx)(`div`,{className:`truncate text-caption font-bold text-text-primary text-body`,children:e.providerName}),g?.plan&&(0,Z.jsx)(`span`,{className:`shrink-0 rounded-chip bg-accent-soft px-4 py-1 text-micro font-semibold text-accent`,children:g.plan})]}),(0,Z.jsx)(`div`,{className:`truncate text-badge text-text-secondary`,children:Q.primary}),Q.secondary!==null&&(0,Z.jsx)(`div`,{className:`truncate text-micro text-text-tertiary`,children:Q.secondary}),g&&(0,Z.jsx)(`div`,{className:`truncate text-micro text-text-tertiary`,children:j(g.lastSuccessAt??g.fetchedAt)}),m&&(0,Z.jsx)(`div`,{className:`truncate text-micro flex items-center gap-2 text-text-tertiary`,title:`Saved rate-limit reset credits available on this account`,children:h.isPending?`Checking saved resets…`:D>0?(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsx)(y,{size:10,className:`text-status-success shrink-0`,"aria-hidden":`true`}),(0,Z.jsxs)(`span`,{className:`reset-credit-live`,children:[D,` rate-limit reset`,D===1?``:`s`,` available`]})]}):`No rate-limit resets available`}),p&&(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsx)(`div`,{title:`Daily growth state: manual pass result, else the sweep ledger for today`,className:`truncate text-micro text-text-tertiary`,children:f.isPending?`Running growth pass…`:U}),S.some(e=>typeof e.limit==`number`&&Number.isFinite(e.limit))&&(0,Z.jsxs)(`div`,{className:`truncate text-micro text-text-tertiary`,children:[`Total credits: `,W.toLocaleString(void 0,{maximumFractionDigits:2})]})]})]}),(0,Z.jsxs)(`div`,{className:`flex items-center gap-1.75 gap-3 ml-auto`,children:[m&&(0,Z.jsx)(o,{variant:`ghost`,size:`icon`,className:`w-16 h-16 p-0`,title:h.isPending?`Checking saved rate-limit resets…`:D>0?`Saved rate-limit resets (${D} available)`:`Saved rate-limit resets`,"aria-label":`Open saved rate-limit resets for ${e.name}`,disabled:E,onClick:()=>a(e),children:(0,Z.jsx)(y,{size:14})}),p&&(0,Z.jsx)(o,{variant:`ghost`,size:`icon`,className:`w-16 h-16 p-0`,title:`Daily growth pass (check-in + activity report) — ${U}`,"aria-label":`Run daily growth pass for ${e.name}`,disabled:E,onClick:()=>f.mutate(void 0,{onSuccess:e=>{let t=e.checkin.data;t&&I({state:t.state,credit:t.credit,streakDays:t.streakDays}),e.report.ok&&z(!0),e.ok?s.success(e.message):s.error(e.message)},onError:e=>{s.error(b(e,`Unable to run daily growth pass`))}}),children:f.isPending?(0,Z.jsx)(l,{size:14,className:`animate-spin`}):(0,Z.jsx)(re,{size:14})}),(0,Z.jsx)(o,{variant:`ghost`,size:`sm`,title:$===`active`?`Health & Error Log`:`${$} — Inspect account health details`,"aria-label":$===`active`?`Health log for ${e.name}`:`Account is ${$} — inspect health details for ${e.name}`,disabled:E,onClick:()=>r(e),icon:(0,Z.jsx)(i,{size:12})}),(0,Z.jsx)(o,{variant:`ghost`,size:`sm`,title:`Refresh quota`,"aria-label":`Refresh ${e.name} quota`,disabled:E,onClick:()=>d.mutate(),icon:d.isPending?(0,Z.jsx)(l,{size:12,className:`animate-spin`}):(0,Z.jsx)(v,{size:12})}),(0,Z.jsx)(o,{variant:`ghost`,size:`sm`,title:`Delete account`,"aria-label":`Delete ${e.name}`,onClick:()=>n(e),className:`text-red`,icon:(0,Z.jsx)(ee,{size:12})}),(0,Z.jsx)(ne,{checked:e.active,disabled:d.isPending,onChange:n=>t(e,n),label:``,id:`switch-${e.id}`})]})]}),Y&&(0,Z.jsxs)(`div`,{className:`flex items-center justify-center gap-4 border-t border-inner-border px-8 py-5 text-center text-badge text-red`,role:`alert`,children:[(0,Z.jsx)(c,{size:13,className:`shrink-0`}),(0,Z.jsx)(`span`,{children:Y})]}),g?.windows.length?(0,Z.jsxs)(`div`,{className:`quota-window-list flex flex-1 flex-col gap-4 border-t border-inner-border px-7 py-4.5`,children:[(0,Z.jsx)(`div`,{className:`quota-window-section-label text-micro font-bold tracking-label text-text-tertiary`,children:`QUOTA WINDOWS`}),C.items.map((e,t)=>{let n=e.remainingPercent??null,r=typeof e.limit==`number`&&Number.isFinite(e.limit)?e.limit:null,i=typeof e.used==`number`&&Number.isFinite(e.used)?e.used:r!==null&&e.usedPercent!==null&&e.usedPercent!==void 0?r*e.usedPercent/100:null,a=P(n),o=n===null?0:Math.max(0,Math.min(100,n)),s=e=>e.toLocaleString(void 0,{maximumFractionDigits:2}),c=e=>{let t=Math.round(e*10)/10;return t>0&&t<.1?`<0.1`:t.toLocaleString(void 0,{maximumFractionDigits:1})},l=N(e.label);return(0,Z.jsxs)(`div`,{className:`quota-window-row grid grid-cols-quota-window min-w-0 items-center gap-x-6 gap-y-2 max-small:grid-cols-[minmax(0,1fr)_auto] max-small:gap-x-4 max-small:gap-y-2.5`,children:[(0,Z.jsx)(`div`,{className:`quota-window-heading min-w-0 max-small:col-start-1`,children:(0,Z.jsx)(`span`,{className:`text-badge font-semibold text-text-primary`,children:l})}),(0,Z.jsx)(`div`,{className:`quota-bar-track quota-window-bar min-w-0 w-full h-5 rounded-tiny bg-inner-border overflow-hidden max-small:col-span-full max-small:row-start-2`,role:`progressbar`,"aria-label":`${l} remaining quota`,"aria-valuemin":0,"aria-valuemax":100,"aria-valuenow":n===null?void 0:o,"aria-valuetext":n===null?`Quota only`:`${c(n)}% remaining`,children:(0,Z.jsx)(`div`,{className:`quota-bar-fill h-full rounded-tiny transition-[width] duration-(--dur-macro) ease-spring`,style:{width:`${o}%`,background:a.bar}})}),(0,Z.jsx)(`span`,{className:`quota-window-remaining whitespace-nowrap text-badge font-bold tabular-nums max-small:col-start-2 max-small:row-start-1`,style:{color:a.text},children:n===null?`—`:`${c(n)}%`}),(0,Z.jsxs)(`div`,{className:`quota-window-details col-span-full flex min-w-0 items-center justify-end gap-6 text-micro text-text-tertiary max-small:row-start-3 max-small:flex-wrap max-small:justify-between max-small:gap-4`,children:[(0,Z.jsx)(`span`,{className:`quota-window-usage mr-auto tabular-nums max-small:min-w-0`,children:i!==null&&r!==null?`${s(i)} / ${s(r)} Credits`:`Quota only`}),e.resetsAt&&(0,Z.jsx)(`span`,{className:`quota-window-reset whitespace-nowrap tabular-nums text-right max-small:ml-auto`,children:A(e.resetsAt,e.recurring)})]})]},`${e.kind??e.label}:${e.resetsAt??`none`}:${t}`)}),C.pageCount>1&&(0,Z.jsxs)(`nav`,{"aria-label":`Quota windows for ${e.name}`,className:`quota-window-pagination mt-auto flex items-center justify-between gap-4 border-t border-inner-border pt-4 max-small:flex-wrap`,children:[(0,Z.jsxs)(`span`,{"aria-live":`polite`,className:`text-micro text-text-tertiary`,children:[`Showing `,C.startIndex+1,`–`,C.startIndex+C.items.length,` of `,S.length]}),(0,Z.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,Z.jsx)(o,{variant:`ghost`,size:`sm`,"aria-label":`Previous quota windows for ${e.name}`,disabled:C.page===0,icon:(0,Z.jsx)(ie,{size:13}),onClick:()=>x(C.page-1),className:`h-14 px-4 py-0`,children:`Previous`}),(0,Z.jsx)(o,{variant:`ghost`,size:`sm`,"aria-label":`Next quota windows for ${e.name}`,disabled:C.page>=C.pageCount-1,icon:(0,Z.jsx)(u,{size:13}),onClick:()=>x(C.page+1),className:`h-14 px-4 py-0`,children:`Next`})]})]})]}):Y?null:(0,Z.jsx)(`div`,{className:`border-t border-inner-border px-7 py-9 text-center text-badge text-text-tertiary`,children:E||e.pending?`Fetching quota…`:`No quota data`})]})}function ce(){let[e,t]=(0,X.useState)(`all`),[n,r]=(0,X.useState)(`all`),[i,c]=(0,X.useState)(!1),{data:l,isLoading:u,isError:p,error:m,isFetching:g,dataUpdatedAt:v,refetch:ee}=U(),y=(0,X.useMemo)(()=>[...l?.providers??[]].sort((e,t)=>e.name.localeCompare(t.name,void 0,{sensitivity:`base`})),[l?.providers]),b=(0,X.useMemo)(()=>l?.accounts??[],[l?.accounts]),C=l?.refreshing??0,T=L(),ne=W(),D=V(),O=I(),[k,A]=(0,X.useState)(null),[j,M]=(0,X.useState)(null),[N,P]=(0,X.useState)(null),F=(0,X.useMemo)(()=>{let t=b.filter(t=>{if(e!==`all`&&t.provider!==e)return!1;let r=!!t.quota?.windows.length;return n===`untracked`?!r:!(!r||n===`active`&&!t.active||n===`disabled`&&t.active)}),r=(e,t)=>e.providerName.localeCompare(t.providerName,void 0,{sensitivity:`base`})||e.name.localeCompare(t.name,void 0,{sensitivity:`base`});return[...t].sort(i?(e,t)=>$(e)-$(t)||r(e,t):r)},[n,b,i,e]),R=async(e,t)=>{try{await ne.mutateAsync({id:e.id,active:t}),s.success(`${e.name} ${t?`enabled`:`disabled`}`)}catch(e){s.error(e instanceof Error?e.message:`Unable to update account`)}},z=async()=>{let e=b.filter(e=>e.active&&Q(e));await D.mutateAsync({ids:e.map(e=>e.id),active:!1}),s.success(`Disabled ${e.length} empty accounts`)},B=async()=>{let e=b.filter(e=>!e.active&&e.quota?.windows.some(e=>e.remainingPercent!==null&&e.remainingPercent>0));await D.mutateAsync({ids:e.map(e=>e.id),active:!0}),s.success(`Enabled ${e.length} available accounts`)},H=async e=>{await O.mutateAsync(e.id),s.success(`${e.name} deleted`)},G=v>0?new Date(v).toLocaleTimeString([],{hour:`2-digit`,minute:`2-digit`}):`Not updated`,K=b.filter(Q).length;return(0,Z.jsxs)(E,{gap:`16px`,className:`dashboard-page min-h-0 flex-1`,children:[(0,Z.jsx)(te,{children:(0,Z.jsxs)(S,{className:`flex flex-col gap-5`,children:[(0,Z.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-5`,children:[(0,Z.jsxs)(`div`,{className:`flex min-w-0 flex-1 flex-wrap items-center gap-4`,children:[(0,Z.jsx)(w,{"aria-label":`Filter quota by provider`,value:e,onValueChange:t,className:`w-full h-16 max-small:w-80`,options:[{value:`all`,label:`All Providers`},...y.map(e=>({value:e.id,label:e.name}))]}),(0,Z.jsx)(w,{"aria-label":`Filter quota by account`,value:n,onValueChange:r,className:`w-full h-16 max-small:w-67.5`,options:[{value:`all`,label:`With quota`},{value:`active`,label:`Active`},{value:`disabled`,label:`Disabled`},{value:`untracked`,label:`No quota`}]})]}),(0,Z.jsxs)(`div`,{className:`flex flex-wrap items-center gap-4`,children:[(0,Z.jsx)(o,{variant:i?`secondary`:`ghost`,size:`sm`,onClick:()=>c(e=>!e),"aria-pressed":i,icon:(0,Z.jsx)(Y,{size:13}),children:`Expiring first`}),(0,Z.jsx)(o,{variant:`ghost`,size:`sm`,className:`text-red`,disabled:K===0||g,onClick:()=>void z(),icon:(0,Z.jsx)(d,{size:13}),children:`Turn off Empty`}),(0,Z.jsx)(o,{variant:`ghost`,size:`sm`,className:`text-green`,disabled:g,onClick:()=>void B(),icon:(0,Z.jsx)(a,{size:13}),children:`Turn on Available`})]})]}),(0,Z.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-4 border-t border-inner-border pt-5`,children:[(0,Z.jsxs)(`span`,{className:`text-badge text-text-tertiary`,children:[F.length,` shown`,K>0?` · ${K} empty`:``]}),(0,Z.jsxs)(`span`,{className:`flex min-w-0 flex-wrap items-center gap-x-5 gap-y-3 text-badge text-text-tertiary`,children:[C>0?`Refreshing ${C} account${C===1?``:`s`}…`:`Auto-refresh 60s · ${G}`,(0,Z.jsx)(oe,{accounts:b}),(0,Z.jsx)(o,{variant:`secondary`,size:`sm`,title:`Queue quota refresh`,"aria-label":`Queue quota refresh`,disabled:g||T.isPending||b.length===0,icon:(0,Z.jsx)(_,{size:13,className:T.isPending?`animate-spin`:void 0}),onClick:()=>T.mutate(b.map(e=>e.id),{onSuccess:e=>{s.success(e.failed===0?`Refreshed ${e.succeeded} quota${e.succeeded===1?``:`s`}`:`Refreshed ${e.succeeded}, ${e.failed} failed`)},onError:e=>s.error(e instanceof Error?e.message:`Unable to refresh quota`)}),children:`Refresh`})]})]})]})}),(0,Z.jsx)(`div`,{className:`flex min-h-0 flex-1 flex-col gap-6`,children:u?(0,Z.jsx)(f,{className:`min-h-0 flex flex-1 flex-col items-center justify-center`,kind:`loading`,title:`Loading quota data`,description:`Reading provider account limits…`}):p?(0,Z.jsx)(f,{className:`min-h-0 flex flex-1 flex-col items-center justify-center`,kind:`error`,title:`Unable to load quota data`,description:m instanceof Error?m.message:`Check the console session and retry.`,action:(0,Z.jsx)(o,{variant:`secondary`,onClick:()=>void ee(),children:`Retry`})}):F.length===0?(0,Z.jsx)(`div`,{className:`flex-1 flex items-center justify-center p-12 border border-dashed border-transparent rounded-card bg-transparent text-center`,children:(0,Z.jsx)(h,{title:`No account quota data`,message:`Nothing is reporting a quota window yet. Add a provider account and its limits will appear here.`})}):(0,Z.jsx)(`div`,{className:`quota-account-grid scroll-region min-h-0 flex-1 gap-6 [align-content:start]`,children:F.map(e=>(0,Z.jsx)(se,{account:e,onToggle:(e,t)=>void R(e,t),onDelete:e=>A(e),onShowHealth:e=>M(e),onShowResets:e=>P(e)},e.id))})}),j&&(0,Z.jsx)(q,{summary:{providerId:j.provider,accountId:j.id,title:j.name,status:j.health?.status??`unknown`,errorCategory:j.health?.lastErrorCategory??void 0,errorMessage:j.health?.sanitizedMessage??void 0,emptyMessage:`Status transitions, rate limits, quota refreshes, check-ins, and auto-recoveries will appear here.`},onClose:()=>M(null)}),N&&(0,Z.jsx)(ae,{account:N,onClose:()=>P(null)}),(0,Z.jsx)(x,{open:k!==null,onClose:()=>A(null),onConfirm:async()=>{k&&await H(k)},title:`Delete account?`,message:`Delete "${k?.name}"? This cannot be undone.`,confirmLabel:`Delete`,danger:!0})]})}export{ce as default};
|
|
Binary file
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{n as e,o as t,r as n,t as r}from"./jsx-runtime-CXUMngI_.js";import{i}from"./terminal-0_IjPWTk.js";import{T as a,c as o,i as s,s as c,t as l}from"./numbers-DkfMR5Qs.js";import{t as u}from"./database-Dz9N3zGd.js";import{t as d}from"./eye-C_hawfH4.js";import{n as f,r as p}from"./state-mPDRlQkl.js";import{t as m}from"./dialog-k37exjNt.js";import{n as h,r as g,t as _}from"./settings-DNX9sydi.js";import{t as v}from"./trash-Cppn5c3R.js";import{t as y}from"./zap-C4EeVW4q.js";import{C as b,T as x,v as S}from"./assert-C9FD_JwJ.js";import{a as C,i as w,l as T,o as E,s as D,t as O}from"./query-keys-BFhGpwR1.js";import{t as k}from"./useMutation-Dem0lXQj.js";import{n as A,r as j,t as M}from"./card-DS7CQEsO.js";import{n as ee,t as te}from"./download-dRFo5_Wu.js";import{n as N}from"./input-V1umFiBk.js";import{t as P}from"./select-C6MMiaio.js";import{t as ne}from"./switch-DOmJxg7H.js";import{t as F}from"./stack-BHTfXdz_.js";import{t as I}from"./banner-CI9_eSfO.js";import{t as re}from"./backup-file-gdKIlg8U.js";var L=e(`calendar-days`,[[`path`,{d:`M8 2v3`,key:`1ioesn`}],[`path`,{d:`M16 2v3`,key:`otl347`}],[`rect`,{x:`3`,y:`3`,width:`18`,height:`18`,rx:`2`,key:`h1oib`}],[`path`,{d:`M3 9h18`,key:`1pudct`}],[`path`,{d:`M8 13h.01`,key:`1sbv64`}],[`path`,{d:`M12 13h.01`,key:`y0uutt`}],[`path`,{d:`M16 13h.01`,key:`wip0gl`}],[`path`,{d:`M8 17h.01`,key:`p3bg7i`}],[`path`,{d:`M12 17h.01`,key:`p32p05`}],[`path`,{d:`M16 17h.01`,key:`ql8jdd`}]]),R=e(`file-braces`,[[`path`,{d:`M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z`,key:`1oefj6`}],[`path`,{d:`M14 2v5a1 1 0 0 0 1 1h5`,key:`wfsgrz`}],[`path`,{d:`M10 12a1 1 0 0 0-1 1v1a1 1 0 0 1-1 1 1 1 0 0 1 1 1v1a1 1 0 0 0 1 1`,key:`1oajmo`}],[`path`,{d:`M14 18a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1 1 1 0 0 1-1-1v-1a1 1 0 0 0-1-1`,key:`mpwhp6`}]]),z=e(`file-clock`,[[`path`,{d:`M16 22h2a2 2 0 0 0 2-2V8a2.4 2.4 0 0 0-.706-1.706l-3.588-3.588A2.4 2.4 0 0 0 14 2H6a2 2 0 0 0-2 2v2.85`,key:`ryk6xj`}],[`path`,{d:`M14 2v5a1 1 0 0 0 1 1h5`,key:`wfsgrz`}],[`path`,{d:`M8 14v2.2l1.6 1`,key:`6m4bie`}],[`circle`,{cx:`8`,cy:`16`,r:`6`,key:`10v15b`}]]),B=e(`hard-drive-download`,[[`path`,{d:`M12 2v8`,key:`1q4o3n`}],[`path`,{d:`m16 6-4 4-4-4`,key:`6wukr`}],[`rect`,{width:`20`,height:`8`,x:`2`,y:`14`,rx:`2`,key:`w68u3i`}],[`path`,{d:`M6 18h.01`,key:`uhywen`}],[`path`,{d:`M10 18h.01`,key:`h775k`}]]),V=e(`hard-drive`,[[`path`,{d:`M10 16h.01`,key:`1bzywj`}],[`path`,{d:`M2.212 11.577a2 2 0 0 0-.212.896V18a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-5.527a2 2 0 0 0-.212-.896L18.55 5.11A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z`,key:`18tbho`}],[`path`,{d:`M21.946 12.013H2.054`,key:`zqlbp7`}],[`path`,{d:`M6 16h.01`,key:`1pmjb7`}]]),ie=e(`upload`,[[`path`,{d:`M12 3v12`,key:`1x0j5s`}],[`path`,{d:`m17 8-5-5-5 5`,key:`7q97r8`}],[`path`,{d:`M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4`,key:`ih7n3h`}]]),H=t(n(),1);function ae(){return k({mutationFn:async({password:e,sections:t,compressed:n,onProgress:r})=>{let i=new URLSearchParams({password:e});t!==void 0&&t.length>0&&i.set(`sections`,t),n===!0&&i.set(`compressed`,`1`);let a=`/backup/export?${i.toString()}`;if(n!==!0)return E(a);let o=await E(a),s=atob(o.bytes),c=Uint8Array.from(s,e=>e.charCodeAt(0));return r?.({loaded:c.byteLength,total:c.byteLength}),c}})}function oe(){let e=x();return k({mutationFn:({password:e,scopes:t})=>E(`/backup/delete-all`,{method:`POST`,body:JSON.stringify({password:e,scopes:t})}),onSuccess:async()=>{await e.invalidateQueries()}})}function se(){let e=x();return k({mutationFn:({password:e,backup:t,tables:n,onProgress:r})=>D(`/backup/import`,JSON.stringify({password:e,backup:t,...n===void 0||n.length===0?{}:{tables:[...n]}}),r),onSuccess:async()=>{await e.invalidateQueries()}})}function ce(){return k({mutationFn:({backup:e})=>E(`/backup/inspect`,{method:`POST`,body:JSON.stringify({backup:e})})})}var U=r();function le({title:e,description:t}){return(0,U.jsxs)(`div`,{className:`mb-6 min-w-0`,children:[(0,U.jsx)(`h3`,{className:`text-body-lg font-bold text-text-primary`,children:e}),(0,U.jsx)(`p`,{className:`mt-1 text-caption text-text-secondary`,children:t})]})}function ue({report:e}){let t=Object.entries(e.imported).filter(([,e])=>e>0);return(0,U.jsxs)(F,{gap:`8px`,children:[t.length>0?(0,U.jsxs)(`p`,{className:`text-caption`,children:[`Imported:`,` `,t.map(([e,t])=>`${t} ${e}`).join(`, `)]}):null,e.remapped.length>0?(0,U.jsxs)(`p`,{className:`text-caption text-text-secondary`,children:[`Remapped provider ids: `,e.remapped.join(`, `)]}):null,e.skipped.length>0?(0,U.jsxs)(`div`,{children:[(0,U.jsxs)(`p`,{className:`text-caption text-yellow`,children:[`Skipped (`,e.skipped.length,`) — nothing was guessed:`]}),(0,U.jsx)(`ul`,{className:`text-caption text-text-tertiary mt-2 ml-8`,children:e.skipped.map(e=>(0,U.jsx)(`li`,{children:e},e))})]}):null,e.warnings.length>0?(0,U.jsxs)(`div`,{children:[(0,U.jsx)(`p`,{className:`text-caption text-text-secondary`,children:`Warnings:`}),(0,U.jsx)(`ul`,{className:`text-caption text-text-tertiary mt-2 ml-8`,children:e.warnings.map(e=>(0,U.jsx)(`li`,{children:e},e))})]}):null]})}function de({warnings:e}){return e.length===0?null:(0,U.jsxs)(I,{tone:`warning`,surface:`raised`,live:`status`,children:[(0,U.jsxs)(`strong`,{children:[`Restore completed with `,e.length,` warning`,e.length===1?``:`s`]}),(0,U.jsx)(`ul`,{className:`mt-2 ml-8`,children:e.map((e,t)=>(0,U.jsxs)(`li`,{children:[e.table?`${e.table}${e.column?`.${e.column}`:``}: `:``,e.reason]},`${e.table??`backup`}:${e.column??`general`}:${t}`))})]})}function W(e){return e<1024?`${e} B`:e<1048576?`${(e/1024).toFixed(1)} KB`:`${(e/1048576).toFixed(1)} MB`}function fe(e,t){if(e===null)return t;let n=Math.max((Date.now()-e.startedAt)/1e3,.1),r=W(e.loaded/n);return`${e.total===null?W(e.loaded):`${W(e.loaded)} / ${W(e.total)}`} · ${r}/s`}function G(){let[e,t]=(0,H.useState)(``),[n,r]=(0,H.useState)(null),[i,s]=(0,H.useState)(!0),[l,u]=(0,H.useState)(!1),[d,f]=(0,H.useState)(!0),[p,h]=(0,H.useState)(null),[g,_]=(0,H.useState)(null),[y,b]=(0,H.useState)(null),[x,S]=(0,H.useState)(null),[C,w]=(0,H.useState)(null),[E,D]=(0,H.useState)(null),[O,k]=(0,H.useState)(new Set),[A,j]=(0,H.useState)(null),[M,P]=(0,H.useState)(null),[L,R]=(0,H.useState)(new Set),[z,B]=(0,H.useState)(null),V=(0,H.useRef)(null),W=ae(),G=se(),K=oe(),q=ce(),pe=e=>{k(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})},J=()=>{r(null),t(``)},me=()=>{O.size!==0&&(t(``),r(`delete`))},Y=async()=>{if(e.length===0)return;let t=await K.mutateAsync({password:e,scopes:[...O]});k(new Set),J(),c.success(`Selected configuration deleted.`,Object.entries(t.deleted).map(([e,t])=>`${e}: ${t}`).join(` · `))},he=()=>{let t=[...i?[`config`]:[],...l?[`telemetry`]:[]].join(`,`);if(t.length===0){c.error(`Select at least one backup section.`);return}W.mutate({password:e,sections:t,compressed:d,onProgress:e=>h(t=>({...e,startedAt:t?.startedAt??Date.now()}))},{onSuccess:e=>{let t=new Date().toISOString().slice(0,19).replace(/[:T]/g,`-`);e instanceof Uint8Array?te(`cartethyia_backup_${t}.json.gz`,e,`application/gzip`):ee(`cartethyia_backup_${t}.json`,JSON.stringify(e,null,2),`application/json`),J(),c.success(`Backup downloaded.`)},onError:e=>c.error(T(e,`Backup export failed.`))})},ge=async e=>{_(null),b(null),S(null),w(null),D(null),B(null),P(null),R(new Set),j(e);try{let t=await re(e),n=await q.mutateAsync({backup:t});P(n),R(new Set(n.rows.filter(e=>e.supported).map(e=>e.table)))}catch(e){j(null),c.error(`Could not read that backup`,T(e,`The file is not a readable backup.`))}},_e=e=>{R(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})},X=()=>{P(null),j(null),B(null)},ve=()=>{A!==null&&L.size!==0&&(t(``),S(null),r(`restore`))},ye=async()=>{let t=A;if(t!==null){S(null);try{let n=await re(t),r=await G.mutateAsync({password:e,backup:n,tables:[...L],onProgress:e=>h(t=>({...e,startedAt:t?.startedAt??Date.now()}))});_(r.restored),b(r.warnings),w(r.report??null),D(r.format),J(),j(null),P(null),c.success(r.warnings.length===0?`Restore complete.`:`Restore completed with warnings.`,r.warnings.length===0?null:`${r.warnings.length} item(s) need attention. See the restore report below.`)}catch(e){let t=T(e,`Backup restore failed.`);S(t),c.error(`Backup restore failed`,t)}}},Z=g===null?[]:Object.entries(g);return(0,U.jsxs)(U.Fragment,{children:[(0,U.jsxs)(`div`,{className:`grid grid-cols-2 gap-8 w-full min-w-0 max-medium:grid-cols-1`,children:[(0,U.jsxs)(`section`,{"aria-label":`Backup`,className:`min-w-0`,children:[(0,U.jsx)(le,{title:`Backup`,description:`Download a JSON snapshot, or restore one you already trust.`}),(0,U.jsxs)(F,{gap:`14px`,children:[(0,U.jsxs)(`fieldset`,{className:`grid grid-cols-2 gap-5 min-w-0 border-0 m-0 p-0 max-medium:grid-cols-1`,children:[(0,U.jsx)(`legend`,{className:`mb-4 text-text-secondary text-caption font-semibold`,children:`Include in the download`}),(0,U.jsxs)(`label`,{className:`flex items-start gap-5 min-h-21 px-6 py-5 border border-inner-border rounded-control bg-surface-2 text-text-primary text-caption leading-snug cursor-pointer hover:border-border-strong hover:bg-hover has-checked:border-accent has-checked:bg-accent-soft`,children:[(0,U.jsx)(`input`,{type:`checkbox`,checked:i,onChange:e=>s(e.target.checked)}),(0,U.jsxs)(`span`,{className:`flex flex-col gap-1 min-w-0`,children:[(0,U.jsx)(`strong`,{children:`Account, proxy & settings`}),(0,U.jsx)(`small`,{className:`text-text-tertiary text-badge`,children:`Credentials, API-key hashes, routing, and settings`})]})]}),(0,U.jsxs)(`label`,{className:`flex items-start gap-5 min-h-21 px-6 py-5 border border-inner-border rounded-control bg-surface-2 text-text-primary text-caption leading-snug cursor-pointer hover:border-border-strong hover:bg-hover has-checked:border-accent has-checked:bg-accent-soft`,children:[(0,U.jsx)(`input`,{type:`checkbox`,checked:l,onChange:e=>u(e.target.checked)}),(0,U.jsxs)(`span`,{className:`flex flex-col gap-1 min-w-0`,children:[(0,U.jsx)(`strong`,{children:`Telemetry history`}),(0,U.jsx)(`small`,{className:`text-text-tertiary text-badge`,children:`Status, tokens, cost, latency — never prompt bodies`})]})]})]}),(0,U.jsxs)(`div`,{className:`flex items-center justify-between gap-6 rounded-control border border-inner-border px-6 py-5`,children:[(0,U.jsxs)(`span`,{children:[(0,U.jsx)(`strong`,{className:`block text-body`,children:`Highly Compress Backup`}),(0,U.jsx)(`small`,{className:`text-caption text-text-tertiary`,children:`Makes the download smaller.`})]}),(0,U.jsx)(ne,{checked:d,onChange:f,"aria-label":`Highly Compress Backup`})]}),(0,U.jsx)(`p`,{className:`mt-1 text-caption text-text-tertiary`,children:`The file contains provider credentials. Treat it like the database. Prompt and response bodies, health-event history, and console sessions are left out.`}),(0,U.jsxs)(`div`,{className:`mt-auto flex justify-end gap-4`,children:[(0,U.jsx)(o,{variant:`primary`,size:`sm`,onClick:()=>{t(``),r(`download`)},disabled:!i&&!l,icon:(0,U.jsx)(a,{size:13}),children:`Download backup`}),(0,U.jsx)(o,{variant:`secondary`,size:`sm`,onClick:()=>V.current?.click(),icon:(0,U.jsx)(ie,{size:13}),children:`Restore from file`}),(0,U.jsx)(`input`,{ref:V,type:`file`,accept:`application/json,.json,.gz,application/gzip`,className:`sr-only`,onChange:e=>{let t=e.target.files?.[0];t&&ge(t),e.target.value=``}})]}),E===null?null:(0,U.jsxs)(`p`,{className:`mt-1 text-caption text-text-tertiary`,children:[`Detected format:`,` `,E===`nine_router`?`router export`:`Cartethyia backup`]}),g===null?null:(0,U.jsxs)(I,{tone:`success`,surface:`raised`,live:`status`,children:[(0,U.jsx)(`strong`,{children:`Restore complete`}),Z.length>0?(0,U.jsx)(`ul`,{children:Z.map(([e,t])=>(0,U.jsxs)(`li`,{children:[e,`: `,t]},e))}):(0,U.jsx)(`p`,{children:`No rows were imported.`})]}),y===null?null:(0,U.jsx)(de,{warnings:y}),C===null?null:(0,U.jsx)(ue,{report:C})]})]}),(0,U.jsxs)(`section`,{"aria-label":`Delete data`,className:`settings-danger min-w-0`,children:[(0,U.jsx)(le,{title:`Delete data`,description:`Removes the scopes you check. Console users, sessions, and audit history stay.`}),(0,U.jsxs)(F,{gap:`12px`,children:[(0,U.jsxs)(`fieldset`,{className:`grid grid-cols-1 gap-5 min-w-0 border-0 m-0 p-0`,children:[(0,U.jsx)(`legend`,{className:`mb-4 text-text-secondary text-caption font-semibold`,children:`Delete`}),[[`providers`,`Providers`,`Accounts, credentials, tenant models, routing, and account health`],[`proxies`,`Proxies`,`Network pools, pool settings, and pool health`],[`configuration`,`All configuration`,`Providers, proxies, aliases, combos, API keys, CLI tools, and settings`]].map(([e,t,n])=>(0,U.jsxs)(`label`,{className:`flex items-start gap-5 min-h-21 px-6 py-5 border border-inner-border rounded-control bg-surface-2 text-text-primary text-caption leading-snug cursor-pointer hover:border-border-strong hover:bg-hover has-checked:border-accent has-checked:bg-accent-soft`,children:[(0,U.jsx)(`input`,{type:`checkbox`,checked:O.has(e),onChange:()=>pe(e)}),(0,U.jsxs)(`span`,{className:`flex flex-col gap-1 min-w-0`,children:[(0,U.jsx)(`strong`,{children:t}),(0,U.jsx)(`small`,{className:`text-text-tertiary text-badge`,children:n})]})]},e))]}),(0,U.jsx)(`div`,{className:`mt-auto flex justify-end`,children:(0,U.jsx)(o,{variant:`danger`,size:`sm`,icon:(0,U.jsx)(v,{size:14}),disabled:O.size===0,onClick:me,children:`Delete selected`})})]})]})]}),(0,U.jsx)(m,{open:M!==null,onClose:X,title:`Restore from backup`,description:`Choose which parts of this file to restore, then confirm with your console password.`,size:`md`,footer:(0,U.jsxs)(U.Fragment,{children:[(0,U.jsx)(o,{variant:`secondary`,size:`sm`,onClick:X,children:`Cancel`}),(0,U.jsx)(o,{variant:`primary`,size:`sm`,disabled:L.size===0,onClick:ve,children:`Restore now`})]}),children:(0,U.jsx)(F,{gap:`12px`,children:M===null?null:(0,U.jsxs)(U.Fragment,{children:[(0,U.jsx)(`p`,{className:`text-caption text-text-tertiary`,children:M.format===`nine_router`?`Router export — it is converted at restore time, so every table it produces is restored.`:`${M.total} rows · exported ${M.exportedAt||`unknown date`}`}),M.rows.length>0?(0,U.jsxs)(`fieldset`,{className:`grid grid-cols-1 gap-4 min-w-0 border-0 m-0 p-0`,children:[(0,U.jsx)(`legend`,{className:`mb-3 text-text-secondary text-caption font-semibold`,children:`Restore these tables`}),(0,U.jsxs)(`div`,{className:`flex justify-end gap-4`,children:[(0,U.jsx)(`button`,{type:`button`,className:`text-badge text-accent hover:underline`,onClick:()=>R(new Set(M.rows.filter(e=>e.supported).map(e=>e.table))),children:`Select all`}),(0,U.jsx)(`button`,{type:`button`,className:`text-badge text-text-secondary hover:underline`,onClick:()=>R(new Set),children:`Select none`})]}),M.rows.map(e=>(0,U.jsxs)(`label`,{className:`flex items-start gap-4 px-5 py-4 border border-inner-border rounded-control bg-surface-2 text-caption leading-snug cursor-pointer hover:border-border-strong hover:bg-hover has-checked:border-accent has-checked:bg-accent-soft`,children:[(0,U.jsx)(`input`,{type:`checkbox`,checked:L.has(e.table),disabled:!e.supported,onChange:()=>_e(e.table)}),(0,U.jsxs)(`span`,{className:`flex flex-col gap-1 min-w-0`,children:[(0,U.jsx)(`strong`,{className:`text-text-primary`,children:e.table}),(0,U.jsxs)(`small`,{className:`text-text-tertiary text-badge`,children:[e.count,` rows · `,e.section,e.supported?``:` · not in the current schema, will be skipped`]})]})]},`${e.section}:${e.table}`))]}):null,z===null?null:(0,U.jsx)(`p`,{role:`alert`,className:`text-caption text-red`,children:z})]})})}),(0,U.jsx)(m,{open:n!==null,onClose:J,title:n===`delete`?`Confirm deletion`:n===`restore`?`Restore backup`:`Download backup`,description:`The console password is checked again before this runs.`,size:`sm`,footer:(0,U.jsxs)(U.Fragment,{children:[(0,U.jsx)(o,{variant:`secondary`,size:`sm`,onClick:J,children:`Cancel`}),(0,U.jsx)(o,{variant:n===`delete`?`danger`:`primary`,size:`sm`,loading:W.isPending||G.isPending||K.isPending,disabled:e.length===0||W.isPending||G.isPending||K.isPending,onClick:()=>{h(null),n===`download`?he():n===`restore`?ye():Y()},children:W.isPending?fe(p,`Downloading…`):G.isPending?fe(p,`Uploading…`):K.isPending?`Working…`:n===`delete`?`Delete permanently`:n===`restore`?`Restore`:`Download`})]}),children:(0,U.jsxs)(F,{gap:`10px`,children:[n===`restore`&&x!==null?(0,U.jsx)(`p`,{role:`alert`,className:`text-caption text-red`,children:x}):null,(0,U.jsx)(`p`,{className:`mt-1 text-caption text-text-tertiary`,children:n===`delete`?`This cannot be undone. The password is verified again before anything is removed.`:n===`restore`?`Restore replaces the tenant configuration in this file. Continue only if the file is trusted.`:`The export is plain JSON and contains provider credentials.`}),(0,U.jsx)(N,{label:`Console password`,type:`password`,value:e,onChange:e=>t(e.target.value),autoComplete:`current-password`,"data-autofocus":!0})]})})]})}function K(){return b({queryKey:O.settings.diskUsage,queryFn:e=>E(`/data-management/usage`,{signal:S(e)}),...w,staleTime:C.status})}function q(){let e=x();return k({mutationFn:e=>E(`/data-management/reclaim`,{method:`POST`,body:JSON.stringify({action:e})}),onSuccess:async()=>{await e.invalidateQueries({queryKey:O.settings.diskUsage})}})}function pe(){return k({mutationFn:()=>E(`/data-management/flush`,{method:`POST`})})}function J(){let e=x();return k({mutationFn:()=>E(`/data-management/purge`,{method:`POST`,body:JSON.stringify({target:`health_events`})}),onSuccess:async()=>{await e.invalidateQueries({queryKey:O.settings.diskUsage})}})}function me(){let e=K(),t=q(),n=pe(),r=J(),[a,u]=(0,H.useState)(null),[d,m]=(0,H.useState)(!1);if(e.isPending)return(0,U.jsx)(p,{label:`Measuring disk usage…`});if(e.isError||!e.data)return(0,U.jsx)(f,{message:T(e.error,`Failed to measure disk usage`),onRetry:()=>void e.refetch()});let h=e.data,g=e=>{e!==null&&(u(null),t.mutate(e,{onSuccess:e=>{if(e.deletedFiles===0){c.success(`Nothing to reclaim.`);return}c.success(`Reclaimed ${l(e.reclaimedBytes)} across ${s(e.deletedFiles)} file${e.deletedFiles===1?``:`s`}.`)},onError:e=>c.error(T(e,`Reclaim failed.`))}))},_=h.healthEventCount;return(0,U.jsxs)(F,{gap:`14px`,children:[(0,U.jsxs)(`div`,{className:`flex items-center justify-between gap-4 flex-wrap`,children:[(0,U.jsxs)(`span`,{className:`text-caption text-text-tertiary`,children:[l(h.totalBytes),` on disk across`,` `,s(h.buckets.reduce((e,t)=>e+t.files,0)),` files`]}),(0,U.jsx)(o,{variant:`secondary`,size:`sm`,icon:(0,U.jsx)(V,{size:14}),onClick:()=>void e.refetch(),disabled:e.isFetching,children:e.isFetching?`Measuring…`:`Refresh`})]}),(0,U.jsx)(`div`,{className:`grid grid-cols-3 gap-6 w-full min-w-0 max-medium:grid-cols-1`,children:h.buckets.map(e=>{let n=Y(e);return(0,U.jsx)(ge,{bucket:e,busy:t.isPending,confirming:n!==null&&a===n,onAsk:()=>u(n),onCancel:()=>u(null),onConfirm:()=>g(n)},e.id)})}),(0,U.jsxs)(`div`,{"data-panel":`health_events`,className:`flex items-center justify-between gap-6 rounded-control border border-inner-border px-6 py-5`,children:[(0,U.jsxs)(`span`,{className:`min-w-0 flex items-center gap-4`,children:[(0,U.jsx)(`span`,{className:`grid size-9 shrink-0 place-items-center rounded-control bg-surface-1 text-text-secondary`,children:(0,U.jsx)(i,{size:15,"aria-hidden":`true`})}),(0,U.jsxs)(`span`,{className:`min-w-0`,children:[(0,U.jsx)(`strong`,{className:`block text-body`,children:`Health & Error Log`}),(0,U.jsx)(`small`,{className:`text-caption text-text-tertiary`,children:_===void 0?`Purging is not offered in this deployment's console composition.`:`${s(_)} recorded transition${_===1?``:`s`} across accounts and pools. Purge clears only this audit trail — account statuses and cooldowns stay as they are, and this cannot be undone.`})]})]}),_===void 0?null:d?(0,U.jsxs)(`span`,{className:`shrink-0 flex items-center gap-3`,children:[(0,U.jsx)(o,{variant:`secondary`,size:`sm`,onClick:()=>m(!1),disabled:r.isPending,children:`Cancel`}),(0,U.jsx)(o,{variant:`danger`,size:`sm`,icon:(0,U.jsx)(v,{size:14}),disabled:r.isPending,onClick:()=>r.mutate(void 0,{onSuccess:e=>{m(!1),c.success(e.deleted===0?`Health & error log was already empty.`:`Purged ${s(e.deleted)} health event${e.deleted===1?``:`s`}.`)},onError:e=>c.error(T(e,`Purge failed.`))}),children:`Delete`})]}):(0,U.jsx)(o,{variant:`secondary`,size:`sm`,className:`shrink-0`,icon:(0,U.jsx)(v,{size:14}),disabled:r.isPending||_===0,onClick:()=>m(!0),children:`Purge`})]}),(0,U.jsxs)(`div`,{className:`flex items-center justify-between gap-6 rounded-control border border-inner-border px-6 py-5`,children:[(0,U.jsxs)(`span`,{className:`min-w-0 flex items-center gap-4`,children:[(0,U.jsx)(`span`,{className:`grid size-9 shrink-0 place-items-center rounded-control bg-surface-1 text-text-secondary`,children:(0,U.jsx)(B,{size:15,"aria-hidden":`true`})}),(0,U.jsxs)(`span`,{className:`min-w-0`,children:[(0,U.jsx)(`strong`,{className:`block text-body`,children:`Flush pending writes`}),(0,U.jsx)(`small`,{className:`text-caption text-text-tertiary`,children:`Write queued telemetry, usage, and health events now instead of waiting for the interval. Nothing is deleted.`})]})]}),(0,U.jsx)(o,{variant:`secondary`,size:`sm`,icon:(0,U.jsx)(y,{size:14}),disabled:n.isPending,onClick:()=>n.mutate(void 0,{onSuccess:()=>c.success(`Buffers flushed.`),onError:e=>c.error(T(e,`Flush failed.`))}),children:n.isPending?`Flushing…`:`Flush`})]}),t.isError?(0,U.jsx)(I,{tone:`danger`,surface:`raised`,live:`status`,children:T(t.error,`Reclaim failed.`)}):null]})}function Y(e){return e.id===`payload_frames`?`payload_frames`:e.id===`telemetry_index`?`telemetry_retention`:null}function he(e){return e.id===`payload_frames`?R:e.id===`telemetry_index`?L:z}function ge({bucket:e,busy:t,confirming:n,onAsk:r,onCancel:i,onConfirm:a}){let c=Y(e),u=e.reclaimableBytes??0,d=e.reclaimableFiles??0,f=c!==null&&u===0,p=he(e);return(0,U.jsxs)(`div`,{"data-bucket":e.id,className:`flex flex-col rounded-control border border-inner-border px-6 py-5 min-w-0`,children:[(0,U.jsxs)(`span`,{className:`flex items-start gap-4`,children:[(0,U.jsx)(`span`,{className:`grid size-9 shrink-0 place-items-center rounded-control bg-surface-1 text-text-secondary`,children:(0,U.jsx)(p,{size:15,"aria-hidden":`true`})}),(0,U.jsxs)(`span`,{className:`min-w-0`,children:[(0,U.jsx)(`span`,{className:`block text-caption text-text-tertiary`,children:e.label}),(0,U.jsx)(`span`,{className:`mt-1 block text-lead font-semibold text-text-primary`,children:l(e.bytes)}),(0,U.jsxs)(`span`,{className:`block text-caption text-text-tertiary`,children:[s(e.files),` file`,e.files===1?``:`s`,` · `,e.note]})]})]}),(0,U.jsx)(`div`,{className:`mt-auto pt-5`,children:c===null?(0,U.jsx)(`p`,{className:`text-caption text-text-tertiary`,children:`Kept — no other copy.`}):n?(0,U.jsxs)(`span`,{className:`flex flex-col gap-3`,children:[(0,U.jsxs)(`span`,{className:`text-caption text-text-secondary`,children:[`Delete `,s(d),` file`,d===1?``:`s`,`,`,` `,l(u),`?`]}),(0,U.jsxs)(`span`,{className:`flex items-center gap-3`,children:[(0,U.jsx)(o,{variant:`secondary`,size:`sm`,onClick:i,disabled:t,children:`Cancel`}),(0,U.jsx)(o,{variant:`danger`,size:`sm`,icon:(0,U.jsx)(v,{size:14}),onClick:a,disabled:t,children:`Delete`})]})]}):(0,U.jsxs)(`span`,{className:`flex items-center justify-between gap-3 flex-wrap`,children:[(0,U.jsx)(`span`,{className:`text-caption text-text-tertiary`,children:f?`Clean`:`${l(u)} free`}),(0,U.jsx)(o,{variant:`secondary`,size:`sm`,icon:(0,U.jsx)(v,{size:14}),onClick:r,disabled:t||f,children:`Reclaim`})]})})]})}function _e(){return k({mutationFn:e=>E(`/auth/change-password`,{method:`POST`,body:JSON.stringify(e)})})}var X=[5,15,30,60,120,300,600],ve=[5,15,30,60,180,720,1440],ye=[1,5,10,25,50,100];function Z({name:e}){let t={size:16};return e===`privacy`?(0,U.jsx)(d,{...t}):e===`operations`?(0,U.jsx)(y,{...t}):e===`data`?(0,U.jsx)(u,{...t}):(0,U.jsx)(g,{...t})}function Q(e,t,n){return(t===null||e.includes(t)?[...e]:[...e,t].sort((e,t)=>e-t)).map(e=>({value:String(e),label:n(e)}))}function $({id:e,title:t,description:n,children:r}){return(0,U.jsxs)(M,{id:e,"aria-label":t,className:`min-w-0 scroll-mt-4`,children:[(0,U.jsx)(j,{title:t,subtitle:n,icon:(0,U.jsx)(Z,{name:e})}),(0,U.jsx)(A,{className:`flex flex-col`,children:r})]})}function be(){let e=_(),t=h(),n=e.data;return e.isPending?(0,U.jsx)(p,{label:`Loading privacy settings…`}):e.isError||!n?(0,U.jsx)(f,{message:T(e.error,`Failed to load runtime settings`),onRetry:()=>void e.refetch()}):(0,U.jsxs)(F,{gap:`16px`,children:[(0,U.jsxs)(`div`,{className:`settings-field`,children:[(0,U.jsx)(P,{label:`Telemetry payloads`,id:`privacy-payloads`,value:n.telemetryPayloads,onValueChange:e=>t.mutate({telemetryPayloads:e===`full`||e===`metadata`?e:`none`},{onSuccess:()=>c.success(`Payload capture updated`),onError:e=>c.error(T(e,`Could not update payload capture.`))}),options:[{value:`none`,label:`Off — no payload capture`},{value:`metadata`,label:`Metadata — method and headers only`},{value:`full`,label:`Full — redacted bodies`}]}),(0,U.jsx)(`p`,{className:`mt-3 text-caption text-text-tertiary`,children:`Request metadata is always kept. Bodies stay off until you turn them on, and anything captured is redacted and deleted when its retention below runs out.`})]}),n.telemetryPayloads===`none`?null:(0,U.jsxs)(`div`,{className:`settings-field`,children:[(0,U.jsx)(P,{label:`Keep captured payloads for`,id:`privacy-payload-retention`,value:String(n.telemetryPayloadRetentionMinutes??``),onValueChange:e=>t.mutate({telemetryPayloadRetentionMinutes:e===``?null:Number(e)},{onSuccess:()=>c.success(`Payload retention updated`),onError:e=>c.error(T(e,`Could not update payload retention.`))}),options:[{value:`15`,label:`15 minutes`},{value:`30`,label:`30 minutes`},{value:`60`,label:`1 hour`},{value:`360`,label:`6 hours`},{value:`720`,label:`12 hours`},{value:`1440`,label:`1 day`},{value:`10080`,label:`7 days — maximum`}]}),(n.telemetryPayloadRetentionMinutes??15)>=60?(0,U.jsxs)(I,{tone:`warning`,surface:`raised`,className:`text-text-secondary`,children:[(0,U.jsx)(`strong`,{children:`Keeping payloads this long costs server disk.`}),` `,`Every captured request keeps a gzipped copy of its bodies for the whole window — at 7 days a busy deployment can fill the data directory. Use it to debug, then set it back.`]}):null]}),n.telemetryPayloads===`full`?(0,U.jsxs)(`div`,{className:`settings-field`,children:[(0,U.jsx)(P,{label:`Capture depth`,id:`privacy-payload-depth`,value:n.telemetryPayloadDepth,onValueChange:e=>t.mutate({telemetryPayloadDepth:e===`moderate`||e===`maximum`?e:`minimum`},{onSuccess:()=>c.success(`Capture depth updated`),onError:e=>c.error(T(e,`Could not update capture depth.`))}),options:[{value:`minimum`,label:`Minimum — 1 MiB cap`},{value:`moderate`,label:`Moderate — 8 MiB cap`},{value:`maximum`,label:`Maximum — 16 MiB cap`}]}),n.telemetryPayloadDepth===`minimum`?null:(0,U.jsxs)(I,{tone:`warning`,surface:`raised`,className:`text-text-secondary`,children:[(0,U.jsx)(`strong`,{children:`High CPU and memory while this is on.`}),` Use it to debug, then switch back to Metadata or Minimum.`]})]}):null,(0,U.jsxs)(`div`,{className:`settings-field`,children:[(0,U.jsx)(P,{label:`Client IP display`,id:`privacy-ip`,value:n.privacyMode,onValueChange:e=>t.mutate({privacyMode:e===`full`?`full`:`masked`},{onSuccess:()=>c.success(`IP display updated`),onError:e=>c.error(T(e,`Could not update IP display.`))}),options:[{value:`masked`,label:`Masked — recommended`},{value:`full`,label:`Show full IP`}]}),(0,U.jsx)(`p`,{className:`mt-1 text-caption text-text-tertiary`,children:`Raw addresses stay stored. This only changes how they are shown.`})]})]})}function xe(){let e=_(),t=h(),n=e.data;if(e.isPending)return(0,U.jsx)(p,{label:`Loading operational settings…`});if(e.isError||!n)return(0,U.jsx)(f,{message:T(e.error,`Failed to load runtime settings`),onRetry:()=>void e.refetch()});let r=(e,n)=>{t.mutate(e,{onSuccess:()=>c.success(n),onError:e=>c.error(T(e,`Could not update settings.`))})};return(0,U.jsxs)(F,{gap:`14px`,children:[(0,U.jsxs)(`div`,{className:`flex items-center justify-between gap-6 rounded-control border border-inner-border px-6 py-5`,children:[(0,U.jsxs)(`span`,{className:`min-w-0`,children:[(0,U.jsx)(`strong`,{className:`block text-body`,children:`Force disable cooldown`}),(0,U.jsx)(`small`,{className:`text-caption text-text-tertiary`,children:`Route to accounts that are cooling down, including ones already parked.`})]}),(0,U.jsx)(ne,{checked:n.forceDisableCooldown,onChange:e=>r({forceDisableCooldown:e},e?`Cooldowns will be ignored.`:`Cooldowns are enforced again.`),"aria-label":`Force disable cooldown`})]}),n.forceDisableCooldown?(0,U.jsxs)(I,{tone:`warning`,surface:`raised`,live:`status`,children:[(0,U.jsx)(`strong`,{children:`This may cause admission failure.`}),` A cooled-down account was parked because the upstream refused it, so dialing it anyway reproduces that refusal on every attempt — and if every candidate is cooling, the request fails instead of waiting for a reset. The cooldown is still recorded and still recovered by the sweep, so turning this back off needs no cleanup. Per-model cooldowns are still enforced.`]}):null,(0,U.jsxs)(`div`,{className:`grid grid-cols-3 gap-8 w-full min-w-0 max-medium:grid-cols-1`,children:[(0,U.jsxs)(`div`,{className:`settings-field`,children:[(0,U.jsx)(P,{label:`Upstream timeout`,id:`upstream-timeout`,value:n.upstreamTimeoutSeconds?.toString()??``,placeholder:`Deployment default`,onValueChange:e=>r({upstreamTimeoutSeconds:e===``?null:Number(e)},`Upstream timeout updated.`),options:[...Q(X,n.upstreamTimeoutSeconds,e=>`${e} seconds`),{value:``,label:`Deployment default`}]}),(0,U.jsx)(`p`,{className:`mt-3 text-caption text-text-tertiary`,children:`5–600 seconds. Applied when the request is dispatched, so it can only shorten a deadline that has already started.`})]}),(0,U.jsxs)(`div`,{className:`settings-field`,children:[(0,U.jsx)(P,{label:`Request detail window`,id:`telemetry-window-minutes`,value:n.telemetryWindowMinutes?.toString()??``,placeholder:`Deployment default`,onValueChange:e=>r({telemetryWindowMinutes:e===``?null:Number(e)},`Detail window updated.`),options:[...Q(ve,n.telemetryWindowMinutes,e=>e===60?`1 hour`:e===1440?`1 day`:`${e} minutes`),{value:``,label:`Deployment default`}]}),(0,U.jsx)(`p`,{className:`mt-3 text-caption text-text-tertiary`,children:`1–1440 minutes. Requests are kept in full for this long, then folded into the day's summary: totals keep counting, but the request list and detail drawer no longer show them. Files hold every tenant together, so the largest window across all tenants wins — keeping them longer only costs disk, while folding sooner gives up detail someone expected to keep.`})]}),(0,U.jsxs)(`div`,{className:`settings-field`,children:[(0,U.jsx)(P,{label:`Max attachment size`,id:`image-clamp-max-bytes`,value:n.imageClampMaxBytes===null?``:String(Math.round(n.imageClampMaxBytes/1048576)),placeholder:`Deployment default (10 MB)`,onValueChange:e=>r({imageClampMaxBytes:e===``?null:Number(e)*1024*1024},`Attachment size limit updated.`),options:[...Q(ye,n.imageClampMaxBytes===null?null:Math.round(n.imageClampMaxBytes/1048576),e=>`${e} MB`),{value:``,label:`Deployment default (10 MB)`}]}),(0,U.jsx)(`p`,{className:`mt-3 text-caption text-text-tertiary`,children:`Per image. An oversized attachment is refused before send rather than after the upstream rejects it — a block too large poisons every retry and every replayed turn. Raising this asserts your upstreams accept more; lowering it is the safer direction. Applies to the Messages and Gemini wires.`})]})]})]})}function Se(){let e=_e(),[t,n]=(0,H.useState)(``),[r,i]=(0,H.useState)(``),[a,s]=(0,H.useState)(``),[c,l]=(0,H.useState)(null),[u,d]=(0,H.useState)(!1);return(0,U.jsxs)(F,{gap:`12px`,className:`flex-1`,children:[(0,U.jsx)(N,{id:`current-password`,label:`Current password`,type:`password`,value:t,onChange:e=>n(e.target.value),autoComplete:`current-password`}),(0,U.jsxs)(`div`,{className:`settings-pair settings-pair-tight`,children:[(0,U.jsx)(N,{id:`new-password`,label:`New password`,type:`password`,value:r,onChange:e=>i(e.target.value),autoComplete:`new-password`}),(0,U.jsx)(N,{id:`confirm-password`,label:`Confirm new password`,type:`password`,value:a,onChange:e=>s(e.target.value),autoComplete:`new-password`})]}),c?(0,U.jsx)(`p`,{role:`alert`,className:`settings-feedback`,"data-tone":`err`,children:c}):null,u?(0,U.jsx)(`p`,{role:`status`,className:`settings-feedback`,"data-tone":`ok`,children:`Password updated.`}):null,(0,U.jsx)(`div`,{className:`mt-auto flex justify-end`,children:(0,U.jsx)(o,{variant:`primary`,size:`sm`,onClick:()=>{if(d(!1),r.length<8){l(`New password must be at least 8 characters.`);return}if(r!==a){l(`New password and confirmation do not match.`);return}l(null),e.mutate({currentPassword:t,newPassword:r},{onSuccess:()=>{d(!0),n(``),i(``),s(``)},onError:e=>l(T(e,`Password change failed.`))})},disabled:e.isPending||!t||!r||!a,children:e.isPending?`Updating…`:`Update password`})})]})}function Ce(){return(0,U.jsxs)(M,{children:[(0,U.jsx)(j,{title:`Settings`,subtitle:`Account security, privacy, and tenant data`,icon:(0,U.jsx)(g,{size:16})}),(0,U.jsxs)(A,{className:`flex flex-col gap-12`,children:[(0,U.jsxs)(`div`,{className:`grid grid-cols-2 gap-8 w-full min-w-0 max-medium:grid-cols-1`,children:[(0,U.jsx)($,{id:`security`,title:`Security`,description:`Change the password used to sign in to this console.`,children:(0,U.jsx)(Se,{})}),(0,U.jsx)($,{id:`privacy`,title:`Privacy`,description:`What request telemetry stores, and how client addresses are shown.`,children:(0,U.jsx)(be,{})})]}),(0,U.jsx)($,{id:`operations`,title:`Operations`,description:`Routing, timeouts, and telemetry retention for this tenant.`,children:(0,U.jsx)(xe,{})}),(0,U.jsx)($,{id:`data`,title:`Data`,description:`Export or restore this tenant's configuration and history.`,children:(0,U.jsx)(G,{})}),(0,U.jsx)($,{id:`data-management`,title:`Data Management`,description:`See what the gateway keeps on disk, reclaim space, and flush queued writes.`,children:(0,U.jsx)(me,{})})]})]})}export{Q as boundedOptions,Ce as default};
|
|
1
|
+
import{n as e,o as t,r as n,t as r}from"./jsx-runtime-CXUMngI_.js";import{i}from"./terminal-0_IjPWTk.js";import{T as a,c as o,i as s,s as c,t as l}from"./numbers-DrdA9oSM.js";import{t as u}from"./database-Dz9N3zGd.js";import{t as d}from"./eye-C_hawfH4.js";import{n as f,r as p}from"./state-D1Yz79iL.js";import{t as m}from"./dialog-CpjrgdwJ.js";import{n as h,r as g,t as _}from"./settings-DNX9sydi.js";import{t as v}from"./trash-Cppn5c3R.js";import{t as y}from"./zap-C4EeVW4q.js";import{C as b,T as x,v as S}from"./assert-C9FD_JwJ.js";import{a as C,i as w,l as T,o as E,s as D,t as O}from"./query-keys-BFhGpwR1.js";import{t as k}from"./useMutation-Dem0lXQj.js";import{n as A,r as j,t as M}from"./card-D5_gYIS_.js";import{n as ee,t as te}from"./download-dRFo5_Wu.js";import{n as N}from"./input-BMRlQ450.js";import{t as P}from"./select-CxVVB__N.js";import{t as ne}from"./switch-sevsRrRo.js";import{t as F}from"./stack-uPOwM9Hs.js";import{t as I}from"./banner-DIvKAZih.js";import{t as re}from"./backup-file-gdKIlg8U.js";var L=e(`calendar-days`,[[`path`,{d:`M8 2v3`,key:`1ioesn`}],[`path`,{d:`M16 2v3`,key:`otl347`}],[`rect`,{x:`3`,y:`3`,width:`18`,height:`18`,rx:`2`,key:`h1oib`}],[`path`,{d:`M3 9h18`,key:`1pudct`}],[`path`,{d:`M8 13h.01`,key:`1sbv64`}],[`path`,{d:`M12 13h.01`,key:`y0uutt`}],[`path`,{d:`M16 13h.01`,key:`wip0gl`}],[`path`,{d:`M8 17h.01`,key:`p3bg7i`}],[`path`,{d:`M12 17h.01`,key:`p32p05`}],[`path`,{d:`M16 17h.01`,key:`ql8jdd`}]]),R=e(`file-braces`,[[`path`,{d:`M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z`,key:`1oefj6`}],[`path`,{d:`M14 2v5a1 1 0 0 0 1 1h5`,key:`wfsgrz`}],[`path`,{d:`M10 12a1 1 0 0 0-1 1v1a1 1 0 0 1-1 1 1 1 0 0 1 1 1v1a1 1 0 0 0 1 1`,key:`1oajmo`}],[`path`,{d:`M14 18a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1 1 1 0 0 1-1-1v-1a1 1 0 0 0-1-1`,key:`mpwhp6`}]]),z=e(`file-clock`,[[`path`,{d:`M16 22h2a2 2 0 0 0 2-2V8a2.4 2.4 0 0 0-.706-1.706l-3.588-3.588A2.4 2.4 0 0 0 14 2H6a2 2 0 0 0-2 2v2.85`,key:`ryk6xj`}],[`path`,{d:`M14 2v5a1 1 0 0 0 1 1h5`,key:`wfsgrz`}],[`path`,{d:`M8 14v2.2l1.6 1`,key:`6m4bie`}],[`circle`,{cx:`8`,cy:`16`,r:`6`,key:`10v15b`}]]),B=e(`hard-drive-download`,[[`path`,{d:`M12 2v8`,key:`1q4o3n`}],[`path`,{d:`m16 6-4 4-4-4`,key:`6wukr`}],[`rect`,{width:`20`,height:`8`,x:`2`,y:`14`,rx:`2`,key:`w68u3i`}],[`path`,{d:`M6 18h.01`,key:`uhywen`}],[`path`,{d:`M10 18h.01`,key:`h775k`}]]),V=e(`hard-drive`,[[`path`,{d:`M10 16h.01`,key:`1bzywj`}],[`path`,{d:`M2.212 11.577a2 2 0 0 0-.212.896V18a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-5.527a2 2 0 0 0-.212-.896L18.55 5.11A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z`,key:`18tbho`}],[`path`,{d:`M21.946 12.013H2.054`,key:`zqlbp7`}],[`path`,{d:`M6 16h.01`,key:`1pmjb7`}]]),ie=e(`upload`,[[`path`,{d:`M12 3v12`,key:`1x0j5s`}],[`path`,{d:`m17 8-5-5-5 5`,key:`7q97r8`}],[`path`,{d:`M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4`,key:`ih7n3h`}]]),H=t(n(),1);function ae(){return k({mutationFn:async({password:e,sections:t,compressed:n,onProgress:r})=>{let i=new URLSearchParams({password:e});t!==void 0&&t.length>0&&i.set(`sections`,t),n===!0&&i.set(`compressed`,`1`);let a=`/backup/export?${i.toString()}`;if(n!==!0)return E(a);let o=await E(a),s=atob(o.bytes),c=Uint8Array.from(s,e=>e.charCodeAt(0));return r?.({loaded:c.byteLength,total:c.byteLength}),c}})}function oe(){let e=x();return k({mutationFn:({password:e,scopes:t})=>E(`/backup/delete-all`,{method:`POST`,body:JSON.stringify({password:e,scopes:t})}),onSuccess:async()=>{await e.invalidateQueries()}})}function se(){let e=x();return k({mutationFn:({password:e,backup:t,tables:n,onProgress:r})=>D(`/backup/import`,JSON.stringify({password:e,backup:t,...n===void 0||n.length===0?{}:{tables:[...n]}}),r),onSuccess:async()=>{await e.invalidateQueries()}})}function ce(){return k({mutationFn:({backup:e})=>E(`/backup/inspect`,{method:`POST`,body:JSON.stringify({backup:e})})})}var U=r();function le({title:e,description:t}){return(0,U.jsxs)(`div`,{className:`mb-6 min-w-0`,children:[(0,U.jsx)(`h3`,{className:`text-body-lg font-bold text-text-primary`,children:e}),(0,U.jsx)(`p`,{className:`mt-1 text-caption text-text-secondary`,children:t})]})}function ue({report:e}){let t=Object.entries(e.imported).filter(([,e])=>e>0);return(0,U.jsxs)(F,{gap:`8px`,children:[t.length>0?(0,U.jsxs)(`p`,{className:`text-caption`,children:[`Imported:`,` `,t.map(([e,t])=>`${t} ${e}`).join(`, `)]}):null,e.remapped.length>0?(0,U.jsxs)(`p`,{className:`text-caption text-text-secondary`,children:[`Remapped provider ids: `,e.remapped.join(`, `)]}):null,e.skipped.length>0?(0,U.jsxs)(`div`,{children:[(0,U.jsxs)(`p`,{className:`text-caption text-yellow`,children:[`Skipped (`,e.skipped.length,`) — nothing was guessed:`]}),(0,U.jsx)(`ul`,{className:`text-caption text-text-tertiary mt-2 ml-8`,children:e.skipped.map(e=>(0,U.jsx)(`li`,{children:e},e))})]}):null,e.warnings.length>0?(0,U.jsxs)(`div`,{children:[(0,U.jsx)(`p`,{className:`text-caption text-text-secondary`,children:`Warnings:`}),(0,U.jsx)(`ul`,{className:`text-caption text-text-tertiary mt-2 ml-8`,children:e.warnings.map(e=>(0,U.jsx)(`li`,{children:e},e))})]}):null]})}function de({warnings:e}){return e.length===0?null:(0,U.jsxs)(I,{tone:`warning`,surface:`raised`,live:`status`,children:[(0,U.jsxs)(`strong`,{children:[`Restore completed with `,e.length,` warning`,e.length===1?``:`s`]}),(0,U.jsx)(`ul`,{className:`mt-2 ml-8`,children:e.map((e,t)=>(0,U.jsxs)(`li`,{children:[e.table?`${e.table}${e.column?`.${e.column}`:``}: `:``,e.reason]},`${e.table??`backup`}:${e.column??`general`}:${t}`))})]})}function W(e){return e<1024?`${e} B`:e<1048576?`${(e/1024).toFixed(1)} KB`:`${(e/1048576).toFixed(1)} MB`}function fe(e,t){if(e===null)return t;let n=Math.max((Date.now()-e.startedAt)/1e3,.1),r=W(e.loaded/n);return`${e.total===null?W(e.loaded):`${W(e.loaded)} / ${W(e.total)}`} · ${r}/s`}function G(){let[e,t]=(0,H.useState)(``),[n,r]=(0,H.useState)(null),[i,s]=(0,H.useState)(!0),[l,u]=(0,H.useState)(!1),[d,f]=(0,H.useState)(!0),[p,h]=(0,H.useState)(null),[g,_]=(0,H.useState)(null),[y,b]=(0,H.useState)(null),[x,S]=(0,H.useState)(null),[C,w]=(0,H.useState)(null),[E,D]=(0,H.useState)(null),[O,k]=(0,H.useState)(new Set),[A,j]=(0,H.useState)(null),[M,P]=(0,H.useState)(null),[L,R]=(0,H.useState)(new Set),[z,B]=(0,H.useState)(null),V=(0,H.useRef)(null),W=ae(),G=se(),K=oe(),q=ce(),pe=e=>{k(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})},J=()=>{r(null),t(``)},me=()=>{O.size!==0&&(t(``),r(`delete`))},Y=async()=>{if(e.length===0)return;let t=await K.mutateAsync({password:e,scopes:[...O]});k(new Set),J(),c.success(`Selected configuration deleted.`,Object.entries(t.deleted).map(([e,t])=>`${e}: ${t}`).join(` · `))},he=()=>{let t=[...i?[`config`]:[],...l?[`telemetry`]:[]].join(`,`);if(t.length===0){c.error(`Select at least one backup section.`);return}W.mutate({password:e,sections:t,compressed:d,onProgress:e=>h(t=>({...e,startedAt:t?.startedAt??Date.now()}))},{onSuccess:e=>{let t=new Date().toISOString().slice(0,19).replace(/[:T]/g,`-`);e instanceof Uint8Array?te(`cartethyia_backup_${t}.json.gz`,e,`application/gzip`):ee(`cartethyia_backup_${t}.json`,JSON.stringify(e,null,2),`application/json`),J(),c.success(`Backup downloaded.`)},onError:e=>c.error(T(e,`Backup export failed.`))})},ge=async e=>{_(null),b(null),S(null),w(null),D(null),B(null),P(null),R(new Set),j(e);try{let t=await re(e),n=await q.mutateAsync({backup:t});P(n),R(new Set(n.rows.filter(e=>e.supported).map(e=>e.table)))}catch(e){j(null),c.error(`Could not read that backup`,T(e,`The file is not a readable backup.`))}},_e=e=>{R(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})},X=()=>{P(null),j(null),B(null)},ve=()=>{A!==null&&L.size!==0&&(t(``),S(null),r(`restore`))},ye=async()=>{let t=A;if(t!==null){S(null);try{let n=await re(t),r=await G.mutateAsync({password:e,backup:n,tables:[...L],onProgress:e=>h(t=>({...e,startedAt:t?.startedAt??Date.now()}))});_(r.restored),b(r.warnings),w(r.report??null),D(r.format),J(),j(null),P(null),c.success(r.warnings.length===0?`Restore complete.`:`Restore completed with warnings.`,r.warnings.length===0?null:`${r.warnings.length} item(s) need attention. See the restore report below.`)}catch(e){let t=T(e,`Backup restore failed.`);S(t),c.error(`Backup restore failed`,t)}}},Z=g===null?[]:Object.entries(g);return(0,U.jsxs)(U.Fragment,{children:[(0,U.jsxs)(`div`,{className:`grid grid-cols-2 gap-8 w-full min-w-0 max-medium:grid-cols-1`,children:[(0,U.jsxs)(`section`,{"aria-label":`Backup`,className:`min-w-0`,children:[(0,U.jsx)(le,{title:`Backup`,description:`Download a JSON snapshot, or restore one you already trust.`}),(0,U.jsxs)(F,{gap:`14px`,children:[(0,U.jsxs)(`fieldset`,{className:`grid grid-cols-2 gap-5 min-w-0 border-0 m-0 p-0 max-medium:grid-cols-1`,children:[(0,U.jsx)(`legend`,{className:`mb-4 text-text-secondary text-caption font-semibold`,children:`Include in the download`}),(0,U.jsxs)(`label`,{className:`flex items-start gap-5 min-h-21 px-6 py-5 border border-inner-border rounded-control bg-surface-2 text-text-primary text-caption leading-snug cursor-pointer hover:border-border-strong hover:bg-hover has-checked:border-accent has-checked:bg-accent-soft`,children:[(0,U.jsx)(`input`,{type:`checkbox`,checked:i,onChange:e=>s(e.target.checked)}),(0,U.jsxs)(`span`,{className:`flex flex-col gap-1 min-w-0`,children:[(0,U.jsx)(`strong`,{children:`Account, proxy & settings`}),(0,U.jsx)(`small`,{className:`text-text-tertiary text-badge`,children:`Credentials, API-key hashes, routing, and settings`})]})]}),(0,U.jsxs)(`label`,{className:`flex items-start gap-5 min-h-21 px-6 py-5 border border-inner-border rounded-control bg-surface-2 text-text-primary text-caption leading-snug cursor-pointer hover:border-border-strong hover:bg-hover has-checked:border-accent has-checked:bg-accent-soft`,children:[(0,U.jsx)(`input`,{type:`checkbox`,checked:l,onChange:e=>u(e.target.checked)}),(0,U.jsxs)(`span`,{className:`flex flex-col gap-1 min-w-0`,children:[(0,U.jsx)(`strong`,{children:`Telemetry history`}),(0,U.jsx)(`small`,{className:`text-text-tertiary text-badge`,children:`Status, tokens, cost, latency — never prompt bodies`})]})]})]}),(0,U.jsxs)(`div`,{className:`flex items-center justify-between gap-6 rounded-control border border-inner-border px-6 py-5`,children:[(0,U.jsxs)(`span`,{children:[(0,U.jsx)(`strong`,{className:`block text-body`,children:`Highly Compress Backup`}),(0,U.jsx)(`small`,{className:`text-caption text-text-tertiary`,children:`Makes the download smaller.`})]}),(0,U.jsx)(ne,{checked:d,onChange:f,"aria-label":`Highly Compress Backup`})]}),(0,U.jsx)(`p`,{className:`mt-1 text-caption text-text-tertiary`,children:`The file contains provider credentials. Treat it like the database. Prompt and response bodies, health-event history, and console sessions are left out.`}),(0,U.jsxs)(`div`,{className:`mt-auto flex justify-end gap-4`,children:[(0,U.jsx)(o,{variant:`primary`,size:`sm`,onClick:()=>{t(``),r(`download`)},disabled:!i&&!l,icon:(0,U.jsx)(a,{size:13}),children:`Download backup`}),(0,U.jsx)(o,{variant:`secondary`,size:`sm`,onClick:()=>V.current?.click(),icon:(0,U.jsx)(ie,{size:13}),children:`Restore from file`}),(0,U.jsx)(`input`,{ref:V,type:`file`,accept:`application/json,.json,.gz,application/gzip`,className:`sr-only`,onChange:e=>{let t=e.target.files?.[0];t&&ge(t),e.target.value=``}})]}),E===null?null:(0,U.jsxs)(`p`,{className:`mt-1 text-caption text-text-tertiary`,children:[`Detected format:`,` `,E===`nine_router`?`router export`:`Cartethyia backup`]}),g===null?null:(0,U.jsxs)(I,{tone:`success`,surface:`raised`,live:`status`,children:[(0,U.jsx)(`strong`,{children:`Restore complete`}),Z.length>0?(0,U.jsx)(`ul`,{children:Z.map(([e,t])=>(0,U.jsxs)(`li`,{children:[e,`: `,t]},e))}):(0,U.jsx)(`p`,{children:`No rows were imported.`})]}),y===null?null:(0,U.jsx)(de,{warnings:y}),C===null?null:(0,U.jsx)(ue,{report:C})]})]}),(0,U.jsxs)(`section`,{"aria-label":`Delete data`,className:`settings-danger min-w-0`,children:[(0,U.jsx)(le,{title:`Delete data`,description:`Removes the scopes you check. Console users, sessions, and audit history stay.`}),(0,U.jsxs)(F,{gap:`12px`,children:[(0,U.jsxs)(`fieldset`,{className:`grid grid-cols-1 gap-5 min-w-0 border-0 m-0 p-0`,children:[(0,U.jsx)(`legend`,{className:`mb-4 text-text-secondary text-caption font-semibold`,children:`Delete`}),[[`providers`,`Providers`,`Accounts, credentials, tenant models, routing, and account health`],[`proxies`,`Proxies`,`Network pools, pool settings, and pool health`],[`configuration`,`All configuration`,`Providers, proxies, aliases, combos, API keys, CLI tools, and settings`]].map(([e,t,n])=>(0,U.jsxs)(`label`,{className:`flex items-start gap-5 min-h-21 px-6 py-5 border border-inner-border rounded-control bg-surface-2 text-text-primary text-caption leading-snug cursor-pointer hover:border-border-strong hover:bg-hover has-checked:border-accent has-checked:bg-accent-soft`,children:[(0,U.jsx)(`input`,{type:`checkbox`,checked:O.has(e),onChange:()=>pe(e)}),(0,U.jsxs)(`span`,{className:`flex flex-col gap-1 min-w-0`,children:[(0,U.jsx)(`strong`,{children:t}),(0,U.jsx)(`small`,{className:`text-text-tertiary text-badge`,children:n})]})]},e))]}),(0,U.jsx)(`div`,{className:`mt-auto flex justify-end`,children:(0,U.jsx)(o,{variant:`danger`,size:`sm`,icon:(0,U.jsx)(v,{size:14}),disabled:O.size===0,onClick:me,children:`Delete selected`})})]})]})]}),(0,U.jsx)(m,{open:M!==null,onClose:X,title:`Restore from backup`,description:`Choose which parts of this file to restore, then confirm with your console password.`,size:`md`,footer:(0,U.jsxs)(U.Fragment,{children:[(0,U.jsx)(o,{variant:`secondary`,size:`sm`,onClick:X,children:`Cancel`}),(0,U.jsx)(o,{variant:`primary`,size:`sm`,disabled:L.size===0,onClick:ve,children:`Restore now`})]}),children:(0,U.jsx)(F,{gap:`12px`,children:M===null?null:(0,U.jsxs)(U.Fragment,{children:[(0,U.jsx)(`p`,{className:`text-caption text-text-tertiary`,children:M.format===`nine_router`?`Router export — it is converted at restore time, so every table it produces is restored.`:`${M.total} rows · exported ${M.exportedAt||`unknown date`}`}),M.rows.length>0?(0,U.jsxs)(`fieldset`,{className:`grid grid-cols-1 gap-4 min-w-0 border-0 m-0 p-0`,children:[(0,U.jsx)(`legend`,{className:`mb-3 text-text-secondary text-caption font-semibold`,children:`Restore these tables`}),(0,U.jsxs)(`div`,{className:`flex justify-end gap-4`,children:[(0,U.jsx)(`button`,{type:`button`,className:`text-badge text-accent hover:underline`,onClick:()=>R(new Set(M.rows.filter(e=>e.supported).map(e=>e.table))),children:`Select all`}),(0,U.jsx)(`button`,{type:`button`,className:`text-badge text-text-secondary hover:underline`,onClick:()=>R(new Set),children:`Select none`})]}),M.rows.map(e=>(0,U.jsxs)(`label`,{className:`flex items-start gap-4 px-5 py-4 border border-inner-border rounded-control bg-surface-2 text-caption leading-snug cursor-pointer hover:border-border-strong hover:bg-hover has-checked:border-accent has-checked:bg-accent-soft`,children:[(0,U.jsx)(`input`,{type:`checkbox`,checked:L.has(e.table),disabled:!e.supported,onChange:()=>_e(e.table)}),(0,U.jsxs)(`span`,{className:`flex flex-col gap-1 min-w-0`,children:[(0,U.jsx)(`strong`,{className:`text-text-primary`,children:e.table}),(0,U.jsxs)(`small`,{className:`text-text-tertiary text-badge`,children:[e.count,` rows · `,e.section,e.supported?``:` · not in the current schema, will be skipped`]})]})]},`${e.section}:${e.table}`))]}):null,z===null?null:(0,U.jsx)(`p`,{role:`alert`,className:`text-caption text-red`,children:z})]})})}),(0,U.jsx)(m,{open:n!==null,onClose:J,title:n===`delete`?`Confirm deletion`:n===`restore`?`Restore backup`:`Download backup`,description:`The console password is checked again before this runs.`,size:`sm`,footer:(0,U.jsxs)(U.Fragment,{children:[(0,U.jsx)(o,{variant:`secondary`,size:`sm`,onClick:J,children:`Cancel`}),(0,U.jsx)(o,{variant:n===`delete`?`danger`:`primary`,size:`sm`,loading:W.isPending||G.isPending||K.isPending,disabled:e.length===0||W.isPending||G.isPending||K.isPending,onClick:()=>{h(null),n===`download`?he():n===`restore`?ye():Y()},children:W.isPending?fe(p,`Downloading…`):G.isPending?fe(p,`Uploading…`):K.isPending?`Working…`:n===`delete`?`Delete permanently`:n===`restore`?`Restore`:`Download`})]}),children:(0,U.jsxs)(F,{gap:`10px`,children:[n===`restore`&&x!==null?(0,U.jsx)(`p`,{role:`alert`,className:`text-caption text-red`,children:x}):null,(0,U.jsx)(`p`,{className:`mt-1 text-caption text-text-tertiary`,children:n===`delete`?`This cannot be undone. The password is verified again before anything is removed.`:n===`restore`?`Restore replaces the tenant configuration in this file. Continue only if the file is trusted.`:`The export is plain JSON and contains provider credentials.`}),(0,U.jsx)(N,{label:`Console password`,type:`password`,value:e,onChange:e=>t(e.target.value),autoComplete:`current-password`,"data-autofocus":!0})]})})]})}function K(){return b({queryKey:O.settings.diskUsage,queryFn:e=>E(`/data-management/usage`,{signal:S(e)}),...w,staleTime:C.status})}function q(){let e=x();return k({mutationFn:e=>E(`/data-management/reclaim`,{method:`POST`,body:JSON.stringify({action:e})}),onSuccess:async()=>{await e.invalidateQueries({queryKey:O.settings.diskUsage})}})}function pe(){return k({mutationFn:()=>E(`/data-management/flush`,{method:`POST`})})}function J(){let e=x();return k({mutationFn:()=>E(`/data-management/purge`,{method:`POST`,body:JSON.stringify({target:`health_events`})}),onSuccess:async()=>{await e.invalidateQueries({queryKey:O.settings.diskUsage})}})}function me(){let e=K(),t=q(),n=pe(),r=J(),[a,u]=(0,H.useState)(null),[d,m]=(0,H.useState)(!1);if(e.isPending)return(0,U.jsx)(p,{label:`Measuring disk usage…`});if(e.isError||!e.data)return(0,U.jsx)(f,{message:T(e.error,`Failed to measure disk usage`),onRetry:()=>void e.refetch()});let h=e.data,g=e=>{e!==null&&(u(null),t.mutate(e,{onSuccess:e=>{if(e.deletedFiles===0){c.success(`Nothing to reclaim.`);return}c.success(`Reclaimed ${l(e.reclaimedBytes)} across ${s(e.deletedFiles)} file${e.deletedFiles===1?``:`s`}.`)},onError:e=>c.error(T(e,`Reclaim failed.`))}))},_=h.healthEventCount;return(0,U.jsxs)(F,{gap:`14px`,children:[(0,U.jsxs)(`div`,{className:`flex items-center justify-between gap-4 flex-wrap`,children:[(0,U.jsxs)(`span`,{className:`text-caption text-text-tertiary`,children:[l(h.totalBytes),` on disk across`,` `,s(h.buckets.reduce((e,t)=>e+t.files,0)),` files`]}),(0,U.jsx)(o,{variant:`secondary`,size:`sm`,icon:(0,U.jsx)(V,{size:14}),onClick:()=>void e.refetch(),disabled:e.isFetching,children:e.isFetching?`Measuring…`:`Refresh`})]}),(0,U.jsx)(`div`,{className:`grid grid-cols-3 gap-6 w-full min-w-0 max-medium:grid-cols-1`,children:h.buckets.map(e=>{let n=Y(e);return(0,U.jsx)(ge,{bucket:e,busy:t.isPending,confirming:n!==null&&a===n,onAsk:()=>u(n),onCancel:()=>u(null),onConfirm:()=>g(n)},e.id)})}),(0,U.jsxs)(`div`,{"data-panel":`health_events`,className:`flex items-center justify-between gap-6 rounded-control border border-inner-border px-6 py-5`,children:[(0,U.jsxs)(`span`,{className:`min-w-0 flex items-center gap-4`,children:[(0,U.jsx)(`span`,{className:`grid size-9 shrink-0 place-items-center rounded-control bg-surface-1 text-text-secondary`,children:(0,U.jsx)(i,{size:15,"aria-hidden":`true`})}),(0,U.jsxs)(`span`,{className:`min-w-0`,children:[(0,U.jsx)(`strong`,{className:`block text-body`,children:`Health & Error Log`}),(0,U.jsx)(`small`,{className:`text-caption text-text-tertiary`,children:_===void 0?`Purging is not offered in this deployment's console composition.`:`${s(_)} recorded transition${_===1?``:`s`} across accounts and pools. Purge clears only this audit trail — account statuses and cooldowns stay as they are, and this cannot be undone.`})]})]}),_===void 0?null:d?(0,U.jsxs)(`span`,{className:`shrink-0 flex items-center gap-3`,children:[(0,U.jsx)(o,{variant:`secondary`,size:`sm`,onClick:()=>m(!1),disabled:r.isPending,children:`Cancel`}),(0,U.jsx)(o,{variant:`danger`,size:`sm`,icon:(0,U.jsx)(v,{size:14}),disabled:r.isPending,onClick:()=>r.mutate(void 0,{onSuccess:e=>{m(!1),c.success(e.deleted===0?`Health & error log was already empty.`:`Purged ${s(e.deleted)} health event${e.deleted===1?``:`s`}.`)},onError:e=>c.error(T(e,`Purge failed.`))}),children:`Delete`})]}):(0,U.jsx)(o,{variant:`secondary`,size:`sm`,className:`shrink-0`,icon:(0,U.jsx)(v,{size:14}),disabled:r.isPending||_===0,onClick:()=>m(!0),children:`Purge`})]}),(0,U.jsxs)(`div`,{className:`flex items-center justify-between gap-6 rounded-control border border-inner-border px-6 py-5`,children:[(0,U.jsxs)(`span`,{className:`min-w-0 flex items-center gap-4`,children:[(0,U.jsx)(`span`,{className:`grid size-9 shrink-0 place-items-center rounded-control bg-surface-1 text-text-secondary`,children:(0,U.jsx)(B,{size:15,"aria-hidden":`true`})}),(0,U.jsxs)(`span`,{className:`min-w-0`,children:[(0,U.jsx)(`strong`,{className:`block text-body`,children:`Flush pending writes`}),(0,U.jsx)(`small`,{className:`text-caption text-text-tertiary`,children:`Write queued telemetry, usage, and health events now instead of waiting for the interval. Nothing is deleted.`})]})]}),(0,U.jsx)(o,{variant:`secondary`,size:`sm`,icon:(0,U.jsx)(y,{size:14}),disabled:n.isPending,onClick:()=>n.mutate(void 0,{onSuccess:()=>c.success(`Buffers flushed.`),onError:e=>c.error(T(e,`Flush failed.`))}),children:n.isPending?`Flushing…`:`Flush`})]}),t.isError?(0,U.jsx)(I,{tone:`danger`,surface:`raised`,live:`status`,children:T(t.error,`Reclaim failed.`)}):null]})}function Y(e){return e.id===`payload_frames`?`payload_frames`:e.id===`telemetry_index`?`telemetry_retention`:null}function he(e){return e.id===`payload_frames`?R:e.id===`telemetry_index`?L:z}function ge({bucket:e,busy:t,confirming:n,onAsk:r,onCancel:i,onConfirm:a}){let c=Y(e),u=e.reclaimableBytes??0,d=e.reclaimableFiles??0,f=c!==null&&u===0,p=he(e);return(0,U.jsxs)(`div`,{"data-bucket":e.id,className:`flex flex-col rounded-control border border-inner-border px-6 py-5 min-w-0`,children:[(0,U.jsxs)(`span`,{className:`flex items-start gap-4`,children:[(0,U.jsx)(`span`,{className:`grid size-9 shrink-0 place-items-center rounded-control bg-surface-1 text-text-secondary`,children:(0,U.jsx)(p,{size:15,"aria-hidden":`true`})}),(0,U.jsxs)(`span`,{className:`min-w-0`,children:[(0,U.jsx)(`span`,{className:`block text-caption text-text-tertiary`,children:e.label}),(0,U.jsx)(`span`,{className:`mt-1 block text-lead font-semibold text-text-primary`,children:l(e.bytes)}),(0,U.jsxs)(`span`,{className:`block text-caption text-text-tertiary`,children:[s(e.files),` file`,e.files===1?``:`s`,` · `,e.note]})]})]}),(0,U.jsx)(`div`,{className:`mt-auto pt-5`,children:c===null?(0,U.jsx)(`p`,{className:`text-caption text-text-tertiary`,children:`Kept — no other copy.`}):n?(0,U.jsxs)(`span`,{className:`flex flex-col gap-3`,children:[(0,U.jsxs)(`span`,{className:`text-caption text-text-secondary`,children:[`Delete `,s(d),` file`,d===1?``:`s`,`,`,` `,l(u),`?`]}),(0,U.jsxs)(`span`,{className:`flex items-center gap-3`,children:[(0,U.jsx)(o,{variant:`secondary`,size:`sm`,onClick:i,disabled:t,children:`Cancel`}),(0,U.jsx)(o,{variant:`danger`,size:`sm`,icon:(0,U.jsx)(v,{size:14}),onClick:a,disabled:t,children:`Delete`})]})]}):(0,U.jsxs)(`span`,{className:`flex items-center justify-between gap-3 flex-wrap`,children:[(0,U.jsx)(`span`,{className:`text-caption text-text-tertiary`,children:f?`Clean`:`${l(u)} free`}),(0,U.jsx)(o,{variant:`secondary`,size:`sm`,icon:(0,U.jsx)(v,{size:14}),onClick:r,disabled:t||f,children:`Reclaim`})]})})]})}function _e(){return k({mutationFn:e=>E(`/auth/change-password`,{method:`POST`,body:JSON.stringify(e)})})}var X=[5,15,30,60,120,300,600],ve=[5,15,30,60,180,720,1440],ye=[1,5,10,25,50,100];function Z({name:e}){let t={size:16};return e===`privacy`?(0,U.jsx)(d,{...t}):e===`operations`?(0,U.jsx)(y,{...t}):e===`data`?(0,U.jsx)(u,{...t}):(0,U.jsx)(g,{...t})}function Q(e,t,n){return(t===null||e.includes(t)?[...e]:[...e,t].sort((e,t)=>e-t)).map(e=>({value:String(e),label:n(e)}))}function $({id:e,title:t,description:n,children:r}){return(0,U.jsxs)(M,{id:e,"aria-label":t,className:`min-w-0 scroll-mt-4`,children:[(0,U.jsx)(j,{title:t,subtitle:n,icon:(0,U.jsx)(Z,{name:e})}),(0,U.jsx)(A,{className:`flex flex-col`,children:r})]})}function be(){let e=_(),t=h(),n=e.data;return e.isPending?(0,U.jsx)(p,{label:`Loading privacy settings…`}):e.isError||!n?(0,U.jsx)(f,{message:T(e.error,`Failed to load runtime settings`),onRetry:()=>void e.refetch()}):(0,U.jsxs)(F,{gap:`16px`,children:[(0,U.jsxs)(`div`,{className:`settings-field`,children:[(0,U.jsx)(P,{label:`Telemetry payloads`,id:`privacy-payloads`,value:n.telemetryPayloads,onValueChange:e=>t.mutate({telemetryPayloads:e===`full`||e===`metadata`?e:`none`},{onSuccess:()=>c.success(`Payload capture updated`),onError:e=>c.error(T(e,`Could not update payload capture.`))}),options:[{value:`none`,label:`Off — no payload capture`},{value:`metadata`,label:`Metadata — method and headers only`},{value:`full`,label:`Full — redacted bodies`}]}),(0,U.jsx)(`p`,{className:`mt-3 text-caption text-text-tertiary`,children:`Request metadata is always kept. Bodies stay off until you turn them on, and anything captured is redacted and deleted when its retention below runs out.`})]}),n.telemetryPayloads===`none`?null:(0,U.jsxs)(`div`,{className:`settings-field`,children:[(0,U.jsx)(P,{label:`Keep captured payloads for`,id:`privacy-payload-retention`,value:String(n.telemetryPayloadRetentionMinutes??``),onValueChange:e=>t.mutate({telemetryPayloadRetentionMinutes:e===``?null:Number(e)},{onSuccess:()=>c.success(`Payload retention updated`),onError:e=>c.error(T(e,`Could not update payload retention.`))}),options:[{value:`15`,label:`15 minutes`},{value:`30`,label:`30 minutes`},{value:`60`,label:`1 hour`},{value:`360`,label:`6 hours`},{value:`720`,label:`12 hours`},{value:`1440`,label:`1 day`},{value:`10080`,label:`7 days — maximum`}]}),(n.telemetryPayloadRetentionMinutes??15)>=60?(0,U.jsxs)(I,{tone:`warning`,surface:`raised`,className:`text-text-secondary`,children:[(0,U.jsx)(`strong`,{children:`Keeping payloads this long costs server disk.`}),` `,`Every captured request keeps a gzipped copy of its bodies for the whole window — at 7 days a busy deployment can fill the data directory. Use it to debug, then set it back.`]}):null]}),n.telemetryPayloads===`full`?(0,U.jsxs)(`div`,{className:`settings-field`,children:[(0,U.jsx)(P,{label:`Capture depth`,id:`privacy-payload-depth`,value:n.telemetryPayloadDepth,onValueChange:e=>t.mutate({telemetryPayloadDepth:e===`moderate`||e===`maximum`?e:`minimum`},{onSuccess:()=>c.success(`Capture depth updated`),onError:e=>c.error(T(e,`Could not update capture depth.`))}),options:[{value:`minimum`,label:`Minimum — 1 MiB cap`},{value:`moderate`,label:`Moderate — 8 MiB cap`},{value:`maximum`,label:`Maximum — 16 MiB cap`}]}),n.telemetryPayloadDepth===`minimum`?null:(0,U.jsxs)(I,{tone:`warning`,surface:`raised`,className:`text-text-secondary`,children:[(0,U.jsx)(`strong`,{children:`High CPU and memory while this is on.`}),` Use it to debug, then switch back to Metadata or Minimum.`]})]}):null,(0,U.jsxs)(`div`,{className:`settings-field`,children:[(0,U.jsx)(P,{label:`Client IP display`,id:`privacy-ip`,value:n.privacyMode,onValueChange:e=>t.mutate({privacyMode:e===`full`?`full`:`masked`},{onSuccess:()=>c.success(`IP display updated`),onError:e=>c.error(T(e,`Could not update IP display.`))}),options:[{value:`masked`,label:`Masked — recommended`},{value:`full`,label:`Show full IP`}]}),(0,U.jsx)(`p`,{className:`mt-1 text-caption text-text-tertiary`,children:`Raw addresses stay stored. This only changes how they are shown.`})]})]})}function xe(){let e=_(),t=h(),n=e.data;if(e.isPending)return(0,U.jsx)(p,{label:`Loading operational settings…`});if(e.isError||!n)return(0,U.jsx)(f,{message:T(e.error,`Failed to load runtime settings`),onRetry:()=>void e.refetch()});let r=(e,n)=>{t.mutate(e,{onSuccess:()=>c.success(n),onError:e=>c.error(T(e,`Could not update settings.`))})};return(0,U.jsxs)(F,{gap:`14px`,children:[(0,U.jsxs)(`div`,{className:`flex items-center justify-between gap-6 rounded-control border border-inner-border px-6 py-5`,children:[(0,U.jsxs)(`span`,{className:`min-w-0`,children:[(0,U.jsx)(`strong`,{className:`block text-body`,children:`Force disable cooldown`}),(0,U.jsx)(`small`,{className:`text-caption text-text-tertiary`,children:`Route to accounts that are cooling down, including ones already parked.`})]}),(0,U.jsx)(ne,{checked:n.forceDisableCooldown,onChange:e=>r({forceDisableCooldown:e},e?`Cooldowns will be ignored.`:`Cooldowns are enforced again.`),"aria-label":`Force disable cooldown`})]}),n.forceDisableCooldown?(0,U.jsxs)(I,{tone:`warning`,surface:`raised`,live:`status`,children:[(0,U.jsx)(`strong`,{children:`This may cause admission failure.`}),` A cooled-down account was parked because the upstream refused it, so dialing it anyway reproduces that refusal on every attempt — and if every candidate is cooling, the request fails instead of waiting for a reset. The cooldown is still recorded and still recovered by the sweep, so turning this back off needs no cleanup. Per-model cooldowns are still enforced.`]}):null,(0,U.jsxs)(`div`,{className:`grid grid-cols-3 gap-8 w-full min-w-0 max-medium:grid-cols-1`,children:[(0,U.jsxs)(`div`,{className:`settings-field`,children:[(0,U.jsx)(P,{label:`Upstream timeout`,id:`upstream-timeout`,value:n.upstreamTimeoutSeconds?.toString()??``,placeholder:`Deployment default`,onValueChange:e=>r({upstreamTimeoutSeconds:e===``?null:Number(e)},`Upstream timeout updated.`),options:[...Q(X,n.upstreamTimeoutSeconds,e=>`${e} seconds`),{value:``,label:`Deployment default`}]}),(0,U.jsx)(`p`,{className:`mt-3 text-caption text-text-tertiary`,children:`5–600 seconds. Applied when the request is dispatched, so it can only shorten a deadline that has already started.`})]}),(0,U.jsxs)(`div`,{className:`settings-field`,children:[(0,U.jsx)(P,{label:`Request detail window`,id:`telemetry-window-minutes`,value:n.telemetryWindowMinutes?.toString()??``,placeholder:`Deployment default`,onValueChange:e=>r({telemetryWindowMinutes:e===``?null:Number(e)},`Detail window updated.`),options:[...Q(ve,n.telemetryWindowMinutes,e=>e===60?`1 hour`:e===1440?`1 day`:`${e} minutes`),{value:``,label:`Deployment default`}]}),(0,U.jsx)(`p`,{className:`mt-3 text-caption text-text-tertiary`,children:`1–1440 minutes. Requests are kept in full for this long, then folded into the day's summary: totals keep counting, but the request list and detail drawer no longer show them. Files hold every tenant together, so the largest window across all tenants wins — keeping them longer only costs disk, while folding sooner gives up detail someone expected to keep.`})]}),(0,U.jsxs)(`div`,{className:`settings-field`,children:[(0,U.jsx)(P,{label:`Max attachment size`,id:`image-clamp-max-bytes`,value:n.imageClampMaxBytes===null?``:String(Math.round(n.imageClampMaxBytes/1048576)),placeholder:`Deployment default (10 MB)`,onValueChange:e=>r({imageClampMaxBytes:e===``?null:Number(e)*1024*1024},`Attachment size limit updated.`),options:[...Q(ye,n.imageClampMaxBytes===null?null:Math.round(n.imageClampMaxBytes/1048576),e=>`${e} MB`),{value:``,label:`Deployment default (10 MB)`}]}),(0,U.jsx)(`p`,{className:`mt-3 text-caption text-text-tertiary`,children:`Per image. An oversized attachment is refused before send rather than after the upstream rejects it — a block too large poisons every retry and every replayed turn. Raising this asserts your upstreams accept more; lowering it is the safer direction. Applies to the Messages and Gemini wires.`})]})]})]})}function Se(){let e=_e(),[t,n]=(0,H.useState)(``),[r,i]=(0,H.useState)(``),[a,s]=(0,H.useState)(``),[c,l]=(0,H.useState)(null),[u,d]=(0,H.useState)(!1);return(0,U.jsxs)(F,{gap:`12px`,className:`flex-1`,children:[(0,U.jsx)(N,{id:`current-password`,label:`Current password`,type:`password`,value:t,onChange:e=>n(e.target.value),autoComplete:`current-password`}),(0,U.jsxs)(`div`,{className:`settings-pair settings-pair-tight`,children:[(0,U.jsx)(N,{id:`new-password`,label:`New password`,type:`password`,value:r,onChange:e=>i(e.target.value),autoComplete:`new-password`}),(0,U.jsx)(N,{id:`confirm-password`,label:`Confirm new password`,type:`password`,value:a,onChange:e=>s(e.target.value),autoComplete:`new-password`})]}),c?(0,U.jsx)(`p`,{role:`alert`,className:`settings-feedback`,"data-tone":`err`,children:c}):null,u?(0,U.jsx)(`p`,{role:`status`,className:`settings-feedback`,"data-tone":`ok`,children:`Password updated.`}):null,(0,U.jsx)(`div`,{className:`mt-auto flex justify-end`,children:(0,U.jsx)(o,{variant:`primary`,size:`sm`,onClick:()=>{if(d(!1),r.length<8){l(`New password must be at least 8 characters.`);return}if(r!==a){l(`New password and confirmation do not match.`);return}l(null),e.mutate({currentPassword:t,newPassword:r},{onSuccess:()=>{d(!0),n(``),i(``),s(``)},onError:e=>l(T(e,`Password change failed.`))})},disabled:e.isPending||!t||!r||!a,children:e.isPending?`Updating…`:`Update password`})})]})}function Ce(){return(0,U.jsxs)(M,{children:[(0,U.jsx)(j,{title:`Settings`,subtitle:`Account security, privacy, and tenant data`,icon:(0,U.jsx)(g,{size:16})}),(0,U.jsxs)(A,{className:`flex flex-col gap-12`,children:[(0,U.jsxs)(`div`,{className:`grid grid-cols-2 gap-8 w-full min-w-0 max-medium:grid-cols-1`,children:[(0,U.jsx)($,{id:`security`,title:`Security`,description:`Change the password used to sign in to this console.`,children:(0,U.jsx)(Se,{})}),(0,U.jsx)($,{id:`privacy`,title:`Privacy`,description:`What request telemetry stores, and how client addresses are shown.`,children:(0,U.jsx)(be,{})})]}),(0,U.jsx)($,{id:`operations`,title:`Operations`,description:`Routing, timeouts, and telemetry retention for this tenant.`,children:(0,U.jsx)(xe,{})}),(0,U.jsx)($,{id:`data`,title:`Data`,description:`Export or restore this tenant's configuration and history.`,children:(0,U.jsx)(G,{})}),(0,U.jsx)($,{id:`data-management`,title:`Data Management`,description:`See what the gateway keeps on disk, reclaim space, and flush queued writes.`,children:(0,U.jsx)(me,{})})]})]})}export{Q as boundedOptions,Ce as default};
|
|
Binary file
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{n as e,o as t,r as n,t as r}from"./jsx-runtime-CXUMngI_.js";import{c as i}from"./numbers-
|
|
1
|
+
import{n as e,o as t,r as n,t as r}from"./jsx-runtime-CXUMngI_.js";import{c as i}from"./numbers-DrdA9oSM.js";import{o as a,t as o}from"./query-keys-BFhGpwR1.js";import{$ as s,L as c,Q as l}from"./entry-Dj0cHfEc.js";import{n as u}from"./input-BMRlQ450.js";import{t as d}from"./layout-XR5xP8ew.js";import{t as f}from"./backup-file-gdKIlg8U.js";var p=e(`user-plus`,[[`path`,{d:`M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2`,key:`1yyitq`}],[`circle`,{cx:`9`,cy:`7`,r:`4`,key:`nufk8`}],[`line`,{x1:`19`,x2:`19`,y1:`8`,y2:`14`,key:`1bvyxn`}],[`line`,{x1:`22`,x2:`16`,y1:`11`,y2:`11`,key:`1shjgl`}]]),m=t(n(),1),h=r();function g(){let e=s(),[t,n]=(0,m.useState)(null),[r,d]=(0,m.useState)(`admin`),[g,y]=(0,m.useState)(``),[b,x]=(0,m.useState)(``),[S,C]=(0,m.useState)(``),[w,T]=(0,m.useState)(null),[E,D]=(0,m.useState)(!1),[O,k]=(0,m.useState)(`create`),[A,j]=(0,m.useState)(null),[M,N]=(0,m.useState)(null),P=(0,m.useRef)(null);(0,m.useEffect)(()=>{let t=!0;return a(`/auth/first-boot`).then(r=>{t&&(n(r.requires_setup),r.requires_setup||e(`/login`,{replace:!0}))}).catch(()=>{t&&n(!0)}),()=>{t=!1}},[e]);let F=async n=>{if(n.preventDefault(),t===!1){T(`This console already has an account. Sign in instead.`);return}if(!r.trim()){T(`Administrator username is required.`);return}if(b.length<8){T(`Administrator password must be at least 8 characters.`);return}if(b!==S){T(`Passwords do not match.`);return}D(!0),T(null);try{let t=await a(`/auth/setup`,{method:`POST`,body:JSON.stringify({username:r.trim(),password:b,...g.trim()?{display_name:g.trim()}:{}})});if(t.status!==`success`){T(t.message??`Setup failed. Please try again.`);return}c.removeQueries({queryKey:o.session.current}),e(`/login`,{replace:!0})}catch(e){if(e&&typeof e==`object`&&`message`in e){let t=e.message;if(typeof t==`string`){T(t);return}}T(`An unexpected network error occurred.`)}finally{D(!1)}},I=async t=>{D(!0),T(null);try{if(b.length<8){T(`Administrator password must be at least 8 characters.`);return}if(b!==S){T(`Passwords do not match.`);return}let n=await f(t),i=await a(`/auth/setup/restore`,{method:`POST`,body:JSON.stringify({backup:n,username:r.trim(),password:b,...g.trim()?{display_name:g.trim()}:{}})});if(i.status!==`success`){T(i.message??`Restore failed. Please try again.`);return}c.removeQueries({queryKey:o.session.current}),e(`/login`,{replace:!0})}catch(e){if(e instanceof Error){T(e.message);return}T(`An unexpected network error occurred.`)}finally{D(!1)}},L=e=>{if(j(e),T(null),e===null){N(null);return}f(e).then(async t=>{try{let n=await a(`/auth/setup/inspect`,{method:`POST`,body:JSON.stringify({backup:t})});if(n.status!==`success`){N(null),T(n.message??`Could not read that backup.`);return}N({fileName:e.name,version:n.version??0,exportedAt:n.exportedAt??``,rows:n.rows??[],total:n.total??0,warnings:n.warnings??[]})}catch{N(null)}}).catch(e=>{N(null),T(e instanceof Error?e.message:`That file is not a JSON backup.`)})};return t===!1?(0,h.jsx)(`main`,{className:`auth-viewport`,children:(0,h.jsxs)(`div`,{className:`card-solid auth-window`,children:[(0,h.jsxs)(`div`,{className:`auth-header`,children:[(0,h.jsx)(`div`,{className:`auth-logo`,"aria-hidden":`true`}),(0,h.jsx)(`h1`,{className:`auth-title`,children:`Account Already Registered`}),(0,h.jsx)(`p`,{className:`auth-desc`,children:`This console already has an administrator account, so setup is closed. Sign in with the account that was created.`})]}),(0,h.jsxs)(`div`,{className:`flex flex-col gap-7`,children:[(0,h.jsx)(v,{message:`Setup is already finished. Creating a second administrator is not possible from here.`}),(0,h.jsx)(l,{to:`/login`,className:`no-underline`,children:(0,h.jsx)(i,{variant:`primary`,type:`button`,className:`w-full h-20`,children:`Go to sign in`})})]})]})}):(0,h.jsx)(`main`,{className:`auth-viewport`,children:(0,h.jsxs)(`div`,{className:`card-solid auth-window`,children:[(0,h.jsxs)(`div`,{className:`auth-header`,children:[(0,h.jsx)(`div`,{className:`auth-logo`,"aria-hidden":`true`}),(0,h.jsx)(`h1`,{className:`auth-title`,children:`Cartethyia Console Setup`}),O===`create`?(0,h.jsx)(`p`,{className:`auth-desc`,children:`Configure the administrator account for Cartethyia AI Gateway`}):null]}),(0,h.jsxs)(`div`,{className:`grid grid-cols-2 gap-2 mb-7`,children:[(0,h.jsx)(i,{type:`button`,variant:O===`create`?`primary`:`secondary`,onClick:()=>k(`create`),children:`New account`}),(0,h.jsx)(i,{type:`button`,variant:O===`restore`?`primary`:`secondary`,onClick:()=>k(`restore`),children:`Restore`})]}),O===`restore`?(0,h.jsxs)(`div`,{className:`flex flex-col gap-7`,children:[(0,h.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,h.jsx)(`span`,{className:`text-text-secondary text-caption`,children:`Backup file`}),(0,h.jsxs)(`div`,{className:`flex items-center gap-3 rounded-lg border border-border-subtle px-3 py-2.5`,children:[(0,h.jsx)(i,{type:`button`,variant:`secondary`,size:`sm`,onClick:()=>P.current?.click(),disabled:E||t===null,children:`Choose file…`}),(0,h.jsx)(`span`,{className:`min-w-0 flex-1 truncate text-caption text-text-secondary`,children:A?.name??`No file chosen`})]})]}),(0,h.jsx)(`input`,{ref:P,id:`setup-backup`,type:`file`,accept:`application/json,.json,.gz,application/gzip`,disabled:E,className:`hidden`,onChange:e=>{let t=e.target.files?.[0]??null;L(t),e.target.value=``}}),M?(0,h.jsx)(_,{preview:M}):null,(0,h.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,h.jsx)(`p`,{className:`m-0 text-text-secondary text-caption`,children:`Backups carry settings only — no logins. Create the administrator for this install.`}),(0,h.jsx)(u,{label:`Administrator Username`,id:`restore-username`,value:r,onChange:e=>d(e.target.value),required:!0,autoComplete:`username`}),(0,h.jsx)(u,{label:`Master Password`,hint:`(min. 8 chars)`,id:`restore-password`,type:`password`,required:!0,minLength:8,value:b,onChange:e=>x(e.target.value),autoComplete:`new-password`}),(0,h.jsx)(u,{label:`Confirm Password`,id:`restore-confirm`,type:`password`,required:!0,minLength:8,value:S,onChange:e=>C(e.target.value),autoComplete:`new-password`})]}),w?(0,h.jsx)(v,{message:w}):null,(0,h.jsxs)(`div`,{className:`grid grid-cols-2 gap-2`,children:[(0,h.jsx)(i,{type:`button`,variant:`secondary`,onClick:()=>k(`create`),disabled:E,children:`Cancel`}),(0,h.jsx)(i,{type:`button`,variant:`primary`,disabled:E||t===null||A===null,onClick:()=>{A&&I(A)},children:E?`Restoring…`:`Restore this backup`})]})]}):(0,h.jsxs)(`form`,{onSubmit:F,className:`flex flex-col gap-7`,children:[(0,h.jsx)(u,{label:`Administrator Username`,id:`setup-username`,value:r,onChange:e=>d(e.target.value),required:!0,autoComplete:`username`,placeholder:`e.g. admin, risun`}),(0,h.jsx)(u,{label:`Display Name`,hint:`(optional)`,id:`display-name`,value:g,onChange:e=>y(e.target.value),autoComplete:`name`,placeholder:`e.g. Administrator, risun`}),(0,h.jsx)(u,{label:`Master Password`,hint:`(min. 8 chars)`,id:`setup-password`,type:`password`,required:!0,minLength:8,value:b,onChange:e=>x(e.target.value),autoComplete:`new-password`}),(0,h.jsx)(u,{label:`Confirm Password`,id:`setup-confirm`,type:`password`,required:!0,minLength:8,value:S,onChange:e=>C(e.target.value),autoComplete:`new-password`}),w?(0,h.jsx)(v,{message:w}):null,(0,h.jsx)(i,{variant:`primary`,type:`submit`,disabled:E||t===null,className:`w-full mt-3 h-20`,icon:(0,h.jsx)(p,{size:15}),children:E?`Initializing…`:`Complete Setup`})]})]})})}function _({preview:e}){let t=e.rows.filter(e=>!e.supported),n=e.rows.filter(e=>e.supported),r=e.exportedAt?e.exportedAt.replace(`T`,` `).slice(0,19):`unknown`;return(0,h.jsxs)(`div`,{className:`flex flex-col gap-2 p-3 border border-inner-border rounded-control bg-surface-2`,children:[(0,h.jsxs)(`div`,{className:`flex items-center flex-wrap gap-1.5`,children:[(0,h.jsx)(`span`,{className:`min-w-0 overflow-hidden whitespace-nowrap text-ellipsis text-body font-semibold`,title:e.fileName,children:e.fileName}),(0,h.jsxs)(`span`,{className:`inline-flex items-center flex-none px-3.5 py-px border border-inner-border rounded-md bg-surface-2 text-text-secondary text-badge tabular-nums`,children:[`v`,e.version]}),t.length>0?(0,h.jsxs)(`span`,{className:`inline-flex items-center flex-none px-3.5 py-px border rounded-md bg-surface-2 text-badge tabular-nums border-warning-line text-status-warning`,children:[t.length,` unsupported`]}):null]}),(0,h.jsxs)(`p`,{className:`m-0 text-text-secondary text-caption`,children:[e.total,` rows across `,e.rows.length,` tables · exported `,r]}),t.length>0?(0,h.jsx)(`p`,{className:`m-0 text-caption text-status-warning`,children:t.length===e.rows.length?`None of these tables exist in this build, so nothing can be restored.`:`This build no longer has some of these tables. The rest still restores.`}):null,e.rows.length===0?(0,h.jsx)(`p`,{className:`m-0 text-text-secondary text-caption`,children:`This backup is empty.`}):(0,h.jsx)(`div`,{className:`max-h-110 overflow-auto`,children:(0,h.jsx)(d,{headers:[`Table`,`Section`,`Rows`],dense:!0,children:[...n,...t].map(e=>(0,h.jsxs)(`tr`,{children:[(0,h.jsx)(`td`,{children:e.table}),(0,h.jsx)(`td`,{children:e.section}),(0,h.jsx)(`td`,{className:`text-right`,children:e.supported?e.count:(0,h.jsx)(`span`,{className:`inline-flex items-center flex-none px-3.5 py-px border rounded-md bg-surface-2 text-badge tabular-nums border-warning-line text-status-warning`,children:`unsupported`})})]},`${e.section}/${e.table}`))})})]})}function v({message:e}){return(0,h.jsx)(`div`,{className:`py-5 px-7 rounded-control bg-red-soft text-red text-caption font-medium`,role:`alert`,children:e})}export{g as default};
|
|
Binary file
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{n as e,o as t,r as n,t as r}from"./jsx-runtime-CXUMngI_.js";import{m as i}from"./numbers-
|
|
1
|
+
import{n as e,o as t,r as n,t as r}from"./jsx-runtime-CXUMngI_.js";import{m as i}from"./numbers-DrdA9oSM.js";import{lt as a}from"./entry-Dj0cHfEc.js";import{n as o}from"./stack-uPOwM9Hs.js";var s=e(`chevron-up`,[[`path`,{d:`m18 15-6-6-6 6`,key:`153udz`}]]),c=e(`grip-vertical`,[[`circle`,{cx:`9`,cy:`12`,r:`1`,key:`1vctgf`}],[`circle`,{cx:`9`,cy:`5`,r:`1`,key:`hp0tcf`}],[`circle`,{cx:`9`,cy:`19`,r:`1`,key:`fkjjf6`}],[`circle`,{cx:`15`,cy:`12`,r:`1`,key:`1tmaij`}],[`circle`,{cx:`15`,cy:`5`,r:`1`,key:`19l28e`}],[`circle`,{cx:`15`,cy:`19`,r:`1`,key:`f4zoj3`}]]),l=t(n(),1),u=r();function d({items:e,onReorder:t,disabled:n=!1,gap:r=`10px`,renderItem:d,label:f}){let[p,m]=(0,l.useState)(null),[h,g]=(0,l.useState)(null),_=(0,l.useRef)(null),v=()=>{_.current=null,m(null),g(null)},y=(n,r)=>{if(n===r)return;let i=e.map(e=>e.id),a=i.indexOf(n),o=i.indexOf(r);a!==-1&&o!==-1&&(i.splice(o,0,...i.splice(a,1)),t(i))};return(0,u.jsx)(`div`,{role:`list`,"aria-label":f,className:i(`flex flex-col min-w-0`,o(r)??`gap-5`),children:e.map((r,o)=>{let l=p===r.id,f=h===r.id&&p!==null&&p!==r.id,b=r=>{let i=o+r;if(n||i<0||i>=e.length)return;let a=e.map(e=>e.id),[s]=a.splice(o,1);s!==void 0&&(a.splice(i,0,s),t(a))};return(0,u.jsxs)(`div`,{role:`listitem`,className:i(`relative flex items-stretch gap-5 min-w-0 rounded-card transition-opacity duration-150 ease-spring`,l&&`opacity-50`,f&&`before:absolute before:inset-x-0 before:top-0 before:h-0.5 before:bg-accent before:content-['']`),"data-dragging":l?`true`:void 0,"data-drop-target":f?`true`:void 0,onDragOver:e=>{n||_.current===null||(e.preventDefault(),e.dataTransfer.dropEffect=`move`,h!==r.id&&g(r.id))},onDrop:e=>{e.preventDefault();let t=_.current;t!==null&&y(t,r.id),v()},children:[(0,u.jsxs)(`div`,{className:`flex flex-none flex-col items-center gap-1 pt-4 text-text-tertiary select-none`,children:[(0,u.jsxs)(`div`,{className:`flex items-center gap-1`,children:[(0,u.jsx)(`span`,{className:`font-mono text-badge tabular-nums leading-none`,children:o+1}),(0,u.jsx)(`button`,{type:`button`,draggable:!n,"aria-label":`Drag item at position ${o+1} to reorder`,title:`Drag to reorder`,disabled:n,onDragStart:e=>{_.current=r.id,m(r.id),e.dataTransfer.effectAllowed=`move`,e.dataTransfer.setData(`text/plain`,r.id)},onDragEnd:v,className:`grid size-7 cursor-grab place-items-center rounded-control text-text-tertiary hover:bg-hover active:cursor-grabbing disabled:cursor-not-allowed`,children:(0,u.jsx)(c,{size:14})})]}),(0,u.jsxs)(`div`,{className:`flex gap-1`,children:[(0,u.jsx)(`button`,{type:`button`,"aria-label":`Move item ${o+1} up`,title:`Move up`,disabled:n||o===0,onClick:()=>b(-1),className:`grid size-7 place-items-center rounded-control text-text-tertiary hover:bg-hover disabled:cursor-not-allowed disabled:opacity-40`,children:(0,u.jsx)(s,{size:14})}),(0,u.jsx)(`button`,{type:`button`,"aria-label":`Move item ${o+1} down`,title:`Move down`,disabled:n||o===e.length-1,onClick:()=>b(1),className:`grid size-7 place-items-center rounded-control text-text-tertiary hover:bg-hover disabled:cursor-not-allowed disabled:opacity-40`,children:(0,u.jsx)(a,{size:14})})]})]}),(0,u.jsx)(`div`,{className:`flex-auto min-w-0`,children:d(r,o)})]},r.id)})})}export{d as t};
|
|
Binary file
|