From 746ced33de089c30ed24bb11ac2661195a9cc901 Mon Sep 17 00:00:00 2001 From: Nathan Brake Date: Thu, 23 Jul 2026 20:58:24 +0000 Subject: [PATCH 1/3] fix(dashboard): CodeRabbit follow-ups on budgets, usage, and tool tests Address the reproducible findings from issue #377 (CodeRabbit's out-of-scope review of #367). Each was verified against current source; two of the four did not reproduce. Budgets: the custom reset-period field rounded fractional days with Math.round, so 1.5 silently became 2 days. Validate with Number.isInteger via a local draft, reject non-integer or non-positive input, flag it inline, and leave it unsaved. Usage: drilling from a breakdown row into the Activity log dropped the other active filter (drilling into a model while filtering by user lost the user, and vice versa). Merge the existing filter with the clicked value before navigating. Tools & Guardrails: a URL reachability result was gated only by an onChange reset, which misses a result stranded when the committed URL changes from a refetch (no keystroke). Track the tested URL and render a result only while it still matches the field. Verified as already-handled, no change needed: - Provider diagnostics (finding 1): ActivityPage renders a generic message, not entry.error_message; ProvidersPage test/health errors are already sanitized and capped server-side (_short_error), by design for the master-key operator. - Editing a URL while a test is pending (part of finding 3): the existing onChange reset already detaches the mutation observer and drops that result. Rebuild the committed dashboard bundle. Adds regression tests for each fix (the Tools test fails without the URL-match guard). Fixes #377 Co-Authored-By: Claude Opus 4.8 (1M context) --- ...e-BJQNqIHi.js => ActivityPage-Cw34Jlno.js} | 2 +- ...ge-C2JIWSiZ.js => AliasesPage-CCRTl9Co.js} | 2 +- .../dashboard/assets/BudgetsPage-iAjnK5BF.js | 1 + .../dashboard/assets/BudgetsPage-inMAr92N.js | 1 - ...sPage-0Svam5tu.js => KeysPage-C6eaoTUP.js} | 2 +- ...XvnvU.js => ModelScopeControl-CkKcIwGe.js} | 2 +- ...age-CN4L8fzW.js => ModelsPage-DwBDAaxV.js} | 2 +- ...e-D4ZtkmU0.js => OverviewPage-B_g2blUc.js} | 2 +- ...-CmlcXh68.js => ProvidersPage-DhHL_fxe.js} | 2 +- ...e-UC2EHTIR.js => SettingsPage-BPWZBXQE.js} | 2 +- .../assets/ToolsGuardrailsPage-Zh-JPOxJ.js | 1 + .../assets/ToolsGuardrailsPage-rcsPeR9V.js | 1 - ...Page-XCUoRhxb.js => UsagePage-Dk-t74Uz.js} | 2 +- ...Page-EoUcpZFH.js => UsersPage-D6v_0kF6.js} | 2 +- ...{index-BFG8RNrJ.css => index-CHQYSDoG.css} | 2 +- .../{index-DHQmS-9o.js => index-DAVt9uB3.js} | 4 +- src/gateway/static/dashboard/index.html | 4 +- web/src/pages/BudgetsPage.test.tsx | 24 ++++++++++ web/src/pages/BudgetsPage.tsx | 38 +++++++++++----- web/src/pages/ToolsGuardrailsPage.test.tsx | 41 ++++++++++++++++- web/src/pages/ToolsGuardrailsPage.tsx | 15 +++++-- web/src/pages/UsagePage.test.tsx | 44 +++++++++++++++++++ web/src/pages/UsagePage.tsx | 7 ++- 23 files changed, 170 insertions(+), 33 deletions(-) rename src/gateway/static/dashboard/assets/{ActivityPage-BJQNqIHi.js => ActivityPage-Cw34Jlno.js} (99%) rename src/gateway/static/dashboard/assets/{AliasesPage-C2JIWSiZ.js => AliasesPage-CCRTl9Co.js} (98%) create mode 100644 src/gateway/static/dashboard/assets/BudgetsPage-iAjnK5BF.js delete mode 100644 src/gateway/static/dashboard/assets/BudgetsPage-inMAr92N.js rename src/gateway/static/dashboard/assets/{KeysPage-0Svam5tu.js => KeysPage-C6eaoTUP.js} (99%) rename src/gateway/static/dashboard/assets/{ModelScopeControl-DTCXvnvU.js => ModelScopeControl-CkKcIwGe.js} (98%) rename src/gateway/static/dashboard/assets/{ModelsPage-CN4L8fzW.js => ModelsPage-DwBDAaxV.js} (99%) rename src/gateway/static/dashboard/assets/{OverviewPage-D4ZtkmU0.js => OverviewPage-B_g2blUc.js} (99%) rename src/gateway/static/dashboard/assets/{ProvidersPage-CmlcXh68.js => ProvidersPage-DhHL_fxe.js} (99%) rename src/gateway/static/dashboard/assets/{SettingsPage-UC2EHTIR.js => SettingsPage-BPWZBXQE.js} (99%) create mode 100644 src/gateway/static/dashboard/assets/ToolsGuardrailsPage-Zh-JPOxJ.js delete mode 100644 src/gateway/static/dashboard/assets/ToolsGuardrailsPage-rcsPeR9V.js rename src/gateway/static/dashboard/assets/{UsagePage-XCUoRhxb.js => UsagePage-Dk-t74Uz.js} (57%) rename src/gateway/static/dashboard/assets/{UsersPage-EoUcpZFH.js => UsersPage-D6v_0kF6.js} (98%) rename src/gateway/static/dashboard/assets/{index-BFG8RNrJ.css => index-CHQYSDoG.css} (95%) rename src/gateway/static/dashboard/assets/{index-DHQmS-9o.js => index-DAVt9uB3.js} (96%) diff --git a/src/gateway/static/dashboard/assets/ActivityPage-BJQNqIHi.js b/src/gateway/static/dashboard/assets/ActivityPage-Cw34Jlno.js similarity index 99% rename from src/gateway/static/dashboard/assets/ActivityPage-BJQNqIHi.js rename to src/gateway/static/dashboard/assets/ActivityPage-Cw34Jlno.js index 8d85b81f..209539cb 100644 --- a/src/gateway/static/dashboard/assets/ActivityPage-BJQNqIHi.js +++ b/src/gateway/static/dashboard/assets/ActivityPage-Cw34Jlno.js @@ -1 +1 @@ -import{j as e}from"./tanstack-query-1t81HyiD.js";import{u as le,r as n}from"./react-dgEcD0HR.js";import{u as re,a as ne,b as ie,c as oe,P as ce,E as de,F as G,d as Y}from"./index-DHQmS-9o.js";import{T as ue,a as me,b as d,L as xe,c as he,d as pe,e as u}from"./Table-CLdjdyTx.js";import{B as f,S as ge}from"./heroui-BX6JwHY-.js";const je=new Intl.NumberFormat(void 0,{style:"currency",currency:"USD",maximumFractionDigits:4});function _(t){return t===null?"—":je.format(t)}function o(t){return t===null?"—":t.toLocaleString()}function Z(t){return t===null?"—":t<1e3?`${t} ms`:`${(t/1e3).toFixed(t<1e4?2:1)} s`}function ve(t){const a=new Date(t);return Number.isNaN(a.getTime())?t:a.toLocaleString()}function be(t){const a=new Date(t).getTime();if(Number.isNaN(a))return t;const r=Math.max(0,Math.round((Date.now()-a)/1e3));if(r<60)return`${r}s ago`;const i=Math.round(r/60);if(i<60)return`${i}m ago`;const m=Math.round(i/60);return m<24?`${m}h ago`:`${Math.round(m/24)}d ago`}const fe=3600,k=86400,Ne=[{label:"Last hour",seconds:fe},{label:"24h",seconds:k},{label:"7d",seconds:7*k},{label:"All",seconds:null}],Se=[{label:"All",value:""},{label:"Success",value:"success"},{label:"Error",value:"error"}],_e=["/v1/chat/completions","/v1/messages","/v1/responses","/v1/embeddings","/v1/moderations","/v1/audio/transcriptions","/v1/audio/speech","/v1/images/generations","/v1/rerank","/v1/batches","/v1/batches/results"],N=50;function D(t){return new Date(Date.now()-t*1e3).toISOString()}function ke({status:t}){const a=t==="error"?"border-red-200 bg-red-50 text-red-700":"border-[var(--otari-line)] bg-[var(--otari-brand-tint)] text-[var(--otari-brand-dark)]";return e.jsx("span",{className:`inline-flex items-center rounded-full border px-2 py-0.5 text-xs font-medium ${a}`,children:t})}function l({label:t,children:a}){return e.jsxs("div",{className:"flex flex-col gap-0.5",children:[e.jsx("span",{className:"text-[11px] font-medium uppercase tracking-wide text-[var(--otari-muted)]",children:t}),e.jsx("span",{className:"text-sm text-[var(--otari-ink)] break-all",children:a})]})}function we({entry:t}){var a;return e.jsxs("div",{className:"flex flex-col gap-4 px-4 py-4",children:[t.error_message?e.jsxs("div",{className:"flex flex-col gap-1.5",children:[e.jsx("div",{className:"flex items-center justify-between",children:e.jsx("span",{className:"text-[11px] font-medium uppercase tracking-wide text-[var(--otari-muted)]",children:"Error"})}),e.jsx("pre",{className:"max-h-48 overflow-auto rounded-lg border border-red-200 bg-red-50 p-3 text-xs whitespace-pre-wrap break-all text-red-700",children:"The provider returned an error. Inspect gateway logs for details."})]}):null,e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2 lg:grid-cols-4",children:[e.jsx(l,{label:"Provider",children:t.provider??"—"}),e.jsx(l,{label:"Endpoint",children:t.endpoint}),e.jsx(l,{label:"User",children:t.user_id??"—"}),e.jsx(l,{label:"API key",children:t.api_key_id??"—"}),e.jsx(l,{label:"Prompt tokens",children:o(t.prompt_tokens)}),e.jsx(l,{label:"Completion tokens",children:o(t.completion_tokens)}),e.jsx(l,{label:"Total tokens",children:o(t.total_tokens)}),e.jsx(l,{label:"Cost",children:_(t.cost)}),e.jsx(l,{label:"Cache read tokens",children:o(t.cache_read_tokens)}),e.jsx(l,{label:"Cache write tokens",children:o(t.cache_write_tokens)}),e.jsx(l,{label:"1h cache writes",children:o(t.cache_write_1h_tokens??null)}),e.jsx(l,{label:"Total time",children:Z(t.latency_ms)}),e.jsx(l,{label:"Request ID",children:t.id})]}),(a=t.pricing_breakdown)!=null&&a.length?e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsx("span",{className:"text-[11px] font-medium uppercase tracking-wide text-[var(--otari-muted)]",children:"Billed meters"}),e.jsx("div",{className:"grid gap-2 sm:grid-cols-2 lg:grid-cols-3",children:t.pricing_breakdown.map(r=>e.jsxs(l,{label:r.meter.replaceAll("_"," "),children:[o(r.units)," at ",_(r.rate_per_million)," / 1M, ",_(r.cost)]},r.meter))})]}):null]})}const A=7;function Ce(){var B,z,H;const t=re(),[a]=le(),r=a.get("start_date")??void 0,[i,m]=n.useState(r?null:k),[S,w]=n.useState(()=>r??D(k)),[x,C]=n.useState(()=>a.get("status")??""),[c,M]=n.useState(()=>a.get("model")??""),[h,$]=n.useState(""),[p,U]=n.useState(()=>a.get("user_id")??""),[j,T]=n.useState(0),[J,K]=n.useState(null),P=n.useMemo(()=>({start_date:S,status:x||void 0,model:c.trim()||void 0,endpoint:h||void 0,user_id:p||void 0}),[S,x,c,h,p]);n.useEffect(()=>{T(0)},[P]);const g=ne(P,j,N),v=ie(P),Q=n.useMemo(()=>({start_date:S,status:x||void 0,endpoint:h||void 0,user_id:p||void 0}),[S,x,h,p]),F=((z=(B=oe(Q,"day").data)==null?void 0:B.by_model)==null?void 0:z.filter(s=>!s.is_other&&s.key!==null).map(s=>s.key))??[],b=g.data??[],E=((H=v.data)==null?void 0:H.total)??0,I=!!(x||c.trim()||h||p||i!==null),V=s=>{m(s),w(s===null?void 0:D(s))},W=()=>{m(null),w(void 0),C(""),M(""),$(""),U("")},X=()=>{i!==null&&w(D(i)),g.refetch(),v.refetch()},L=b.length>0,O=L?j*N+1:0,R=j*N+b.length,q=v.isSuccess&&!v.isPlaceholderData,ee=q?E===0?"0 of 0":`${O}–${R} of ${E.toLocaleString()}`:L?`${O}–${R}`:"0",se=q?(j+1)*Ne.jsx(f,{size:"sm",variant:i===s.seconds?"primary":"outline",onPress:()=>V(s.seconds),children:s.label},s.label))}),e.jsxs("div",{className:"flex flex-wrap items-end gap-3",children:[e.jsx(G,{id:"filter-status",label:"Status",value:x,onChange:C,children:Se.map(s=>e.jsx("option",{value:s.value,children:s.label},s.value))}),e.jsxs(G,{id:"filter-endpoint",label:"Endpoint",value:h,onChange:$,children:[e.jsx("option",{value:"",children:"All endpoints"}),_e.map(s=>e.jsx("option",{value:s,children:s},s))]}),e.jsx(Y,{label:"User",value:p,onChange:U,placeholder:"All users",options:(t.data??[]).map(s=>({value:s.user_id,label:s.alias?`${s.alias} (${s.user_id})`:s.user_id}))}),e.jsx(Y,{label:"Model",value:c,onChange:M,allowsCustom:!0,placeholder:"Any model",options:(c&&!F.includes(c)?[c,...F]:F).map(s=>({value:s,label:s}))}),I?e.jsx(f,{size:"sm",variant:"ghost",onPress:W,children:"Clear filters"}):null]})]}),e.jsxs(ue,{children:[e.jsx(me,{children:e.jsxs("tr",{children:[e.jsx(d,{children:"Time"}),e.jsx(d,{children:"User"}),e.jsx(d,{children:"Model"}),e.jsx(d,{className:"text-right",children:"Tokens"}),e.jsx(d,{className:"text-right",children:"Cost"}),e.jsx(d,{className:"text-right",children:"Total time"}),e.jsx(d,{children:"Status"})]})}),e.jsx("tbody",{children:g.isLoading?e.jsx(xe,{colSpan:A}):b.length===0?e.jsx(he,{colSpan:A,children:I?"No requests match these filters.":"No requests recorded yet."}):b.map(s=>{const te=s.status==="error",y=J===s.id;return e.jsxs(n.Fragment,{children:[e.jsxs(pe,{selected:y,className:te?"bg-red-50":"",onClick:()=>K(ae=>ae===s.id?null:s.id),children:[e.jsx(u,{className:"text-[var(--otari-muted)]",children:e.jsx("span",{title:ve(s.timestamp),children:be(s.timestamp)})}),e.jsx(u,{className:"text-[var(--otari-ink)]",children:s.user_id??"—"}),e.jsx(u,{className:"text-[var(--otari-ink)]",children:s.model}),e.jsx(u,{className:"text-right tabular-nums",children:o(s.total_tokens)}),e.jsx(u,{className:"text-right tabular-nums",children:_(s.cost)}),e.jsx(u,{className:"text-right tabular-nums",children:Z(s.latency_ms)}),e.jsx(u,{children:e.jsx(ke,{status:s.status})})]}),y?e.jsx("tr",{className:"border-b border-[var(--otari-line)] bg-[var(--otari-bg)]",children:e.jsx("td",{colSpan:A,children:e.jsx(we,{entry:s})})}):null]},s.id)})})]}),e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsxs("span",{className:"inline-flex items-center gap-2 text-sm text-[var(--otari-muted)]",children:[ee,g.isFetching?e.jsx(ge,{size:"sm"}):null]}),e.jsxs("span",{className:"inline-flex gap-1.5",children:[e.jsx(f,{size:"sm",variant:"outline",isDisabled:j===0,onPress:()=>T(s=>Math.max(0,s-1)),children:"Previous"}),e.jsx(f,{size:"sm",variant:"outline",isDisabled:!se,onPress:()=>T(s=>s+1),children:"Next"})]})]})]})}export{Ce as ActivityPage}; +import{j as e}from"./tanstack-query-1t81HyiD.js";import{u as le,r as n}from"./react-dgEcD0HR.js";import{u as re,a as ne,b as ie,c as oe,P as ce,E as de,F as G,d as Y}from"./index-DAVt9uB3.js";import{T as ue,a as me,b as d,L as xe,c as he,d as pe,e as u}from"./Table-CLdjdyTx.js";import{B as f,S as ge}from"./heroui-BX6JwHY-.js";const je=new Intl.NumberFormat(void 0,{style:"currency",currency:"USD",maximumFractionDigits:4});function _(t){return t===null?"—":je.format(t)}function o(t){return t===null?"—":t.toLocaleString()}function Z(t){return t===null?"—":t<1e3?`${t} ms`:`${(t/1e3).toFixed(t<1e4?2:1)} s`}function ve(t){const a=new Date(t);return Number.isNaN(a.getTime())?t:a.toLocaleString()}function be(t){const a=new Date(t).getTime();if(Number.isNaN(a))return t;const r=Math.max(0,Math.round((Date.now()-a)/1e3));if(r<60)return`${r}s ago`;const i=Math.round(r/60);if(i<60)return`${i}m ago`;const m=Math.round(i/60);return m<24?`${m}h ago`:`${Math.round(m/24)}d ago`}const fe=3600,k=86400,Ne=[{label:"Last hour",seconds:fe},{label:"24h",seconds:k},{label:"7d",seconds:7*k},{label:"All",seconds:null}],Se=[{label:"All",value:""},{label:"Success",value:"success"},{label:"Error",value:"error"}],_e=["/v1/chat/completions","/v1/messages","/v1/responses","/v1/embeddings","/v1/moderations","/v1/audio/transcriptions","/v1/audio/speech","/v1/images/generations","/v1/rerank","/v1/batches","/v1/batches/results"],N=50;function D(t){return new Date(Date.now()-t*1e3).toISOString()}function ke({status:t}){const a=t==="error"?"border-red-200 bg-red-50 text-red-700":"border-[var(--otari-line)] bg-[var(--otari-brand-tint)] text-[var(--otari-brand-dark)]";return e.jsx("span",{className:`inline-flex items-center rounded-full border px-2 py-0.5 text-xs font-medium ${a}`,children:t})}function l({label:t,children:a}){return e.jsxs("div",{className:"flex flex-col gap-0.5",children:[e.jsx("span",{className:"text-[11px] font-medium uppercase tracking-wide text-[var(--otari-muted)]",children:t}),e.jsx("span",{className:"text-sm text-[var(--otari-ink)] break-all",children:a})]})}function we({entry:t}){var a;return e.jsxs("div",{className:"flex flex-col gap-4 px-4 py-4",children:[t.error_message?e.jsxs("div",{className:"flex flex-col gap-1.5",children:[e.jsx("div",{className:"flex items-center justify-between",children:e.jsx("span",{className:"text-[11px] font-medium uppercase tracking-wide text-[var(--otari-muted)]",children:"Error"})}),e.jsx("pre",{className:"max-h-48 overflow-auto rounded-lg border border-red-200 bg-red-50 p-3 text-xs whitespace-pre-wrap break-all text-red-700",children:"The provider returned an error. Inspect gateway logs for details."})]}):null,e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2 lg:grid-cols-4",children:[e.jsx(l,{label:"Provider",children:t.provider??"—"}),e.jsx(l,{label:"Endpoint",children:t.endpoint}),e.jsx(l,{label:"User",children:t.user_id??"—"}),e.jsx(l,{label:"API key",children:t.api_key_id??"—"}),e.jsx(l,{label:"Prompt tokens",children:o(t.prompt_tokens)}),e.jsx(l,{label:"Completion tokens",children:o(t.completion_tokens)}),e.jsx(l,{label:"Total tokens",children:o(t.total_tokens)}),e.jsx(l,{label:"Cost",children:_(t.cost)}),e.jsx(l,{label:"Cache read tokens",children:o(t.cache_read_tokens)}),e.jsx(l,{label:"Cache write tokens",children:o(t.cache_write_tokens)}),e.jsx(l,{label:"1h cache writes",children:o(t.cache_write_1h_tokens??null)}),e.jsx(l,{label:"Total time",children:Z(t.latency_ms)}),e.jsx(l,{label:"Request ID",children:t.id})]}),(a=t.pricing_breakdown)!=null&&a.length?e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsx("span",{className:"text-[11px] font-medium uppercase tracking-wide text-[var(--otari-muted)]",children:"Billed meters"}),e.jsx("div",{className:"grid gap-2 sm:grid-cols-2 lg:grid-cols-3",children:t.pricing_breakdown.map(r=>e.jsxs(l,{label:r.meter.replaceAll("_"," "),children:[o(r.units)," at ",_(r.rate_per_million)," / 1M, ",_(r.cost)]},r.meter))})]}):null]})}const A=7;function Ce(){var B,z,H;const t=re(),[a]=le(),r=a.get("start_date")??void 0,[i,m]=n.useState(r?null:k),[S,w]=n.useState(()=>r??D(k)),[x,C]=n.useState(()=>a.get("status")??""),[c,M]=n.useState(()=>a.get("model")??""),[h,$]=n.useState(""),[p,U]=n.useState(()=>a.get("user_id")??""),[j,T]=n.useState(0),[J,K]=n.useState(null),P=n.useMemo(()=>({start_date:S,status:x||void 0,model:c.trim()||void 0,endpoint:h||void 0,user_id:p||void 0}),[S,x,c,h,p]);n.useEffect(()=>{T(0)},[P]);const g=ne(P,j,N),v=ie(P),Q=n.useMemo(()=>({start_date:S,status:x||void 0,endpoint:h||void 0,user_id:p||void 0}),[S,x,h,p]),F=((z=(B=oe(Q,"day").data)==null?void 0:B.by_model)==null?void 0:z.filter(s=>!s.is_other&&s.key!==null).map(s=>s.key))??[],b=g.data??[],E=((H=v.data)==null?void 0:H.total)??0,I=!!(x||c.trim()||h||p||i!==null),V=s=>{m(s),w(s===null?void 0:D(s))},W=()=>{m(null),w(void 0),C(""),M(""),$(""),U("")},X=()=>{i!==null&&w(D(i)),g.refetch(),v.refetch()},L=b.length>0,O=L?j*N+1:0,R=j*N+b.length,q=v.isSuccess&&!v.isPlaceholderData,ee=q?E===0?"0 of 0":`${O}–${R} of ${E.toLocaleString()}`:L?`${O}–${R}`:"0",se=q?(j+1)*Ne.jsx(f,{size:"sm",variant:i===s.seconds?"primary":"outline",onPress:()=>V(s.seconds),children:s.label},s.label))}),e.jsxs("div",{className:"flex flex-wrap items-end gap-3",children:[e.jsx(G,{id:"filter-status",label:"Status",value:x,onChange:C,children:Se.map(s=>e.jsx("option",{value:s.value,children:s.label},s.value))}),e.jsxs(G,{id:"filter-endpoint",label:"Endpoint",value:h,onChange:$,children:[e.jsx("option",{value:"",children:"All endpoints"}),_e.map(s=>e.jsx("option",{value:s,children:s},s))]}),e.jsx(Y,{label:"User",value:p,onChange:U,placeholder:"All users",options:(t.data??[]).map(s=>({value:s.user_id,label:s.alias?`${s.alias} (${s.user_id})`:s.user_id}))}),e.jsx(Y,{label:"Model",value:c,onChange:M,allowsCustom:!0,placeholder:"Any model",options:(c&&!F.includes(c)?[c,...F]:F).map(s=>({value:s,label:s}))}),I?e.jsx(f,{size:"sm",variant:"ghost",onPress:W,children:"Clear filters"}):null]})]}),e.jsxs(ue,{children:[e.jsx(me,{children:e.jsxs("tr",{children:[e.jsx(d,{children:"Time"}),e.jsx(d,{children:"User"}),e.jsx(d,{children:"Model"}),e.jsx(d,{className:"text-right",children:"Tokens"}),e.jsx(d,{className:"text-right",children:"Cost"}),e.jsx(d,{className:"text-right",children:"Total time"}),e.jsx(d,{children:"Status"})]})}),e.jsx("tbody",{children:g.isLoading?e.jsx(xe,{colSpan:A}):b.length===0?e.jsx(he,{colSpan:A,children:I?"No requests match these filters.":"No requests recorded yet."}):b.map(s=>{const te=s.status==="error",y=J===s.id;return e.jsxs(n.Fragment,{children:[e.jsxs(pe,{selected:y,className:te?"bg-red-50":"",onClick:()=>K(ae=>ae===s.id?null:s.id),children:[e.jsx(u,{className:"text-[var(--otari-muted)]",children:e.jsx("span",{title:ve(s.timestamp),children:be(s.timestamp)})}),e.jsx(u,{className:"text-[var(--otari-ink)]",children:s.user_id??"—"}),e.jsx(u,{className:"text-[var(--otari-ink)]",children:s.model}),e.jsx(u,{className:"text-right tabular-nums",children:o(s.total_tokens)}),e.jsx(u,{className:"text-right tabular-nums",children:_(s.cost)}),e.jsx(u,{className:"text-right tabular-nums",children:Z(s.latency_ms)}),e.jsx(u,{children:e.jsx(ke,{status:s.status})})]}),y?e.jsx("tr",{className:"border-b border-[var(--otari-line)] bg-[var(--otari-bg)]",children:e.jsx("td",{colSpan:A,children:e.jsx(we,{entry:s})})}):null]},s.id)})})]}),e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsxs("span",{className:"inline-flex items-center gap-2 text-sm text-[var(--otari-muted)]",children:[ee,g.isFetching?e.jsx(ge,{size:"sm"}):null]}),e.jsxs("span",{className:"inline-flex gap-1.5",children:[e.jsx(f,{size:"sm",variant:"outline",isDisabled:j===0,onPress:()=>T(s=>Math.max(0,s-1)),children:"Previous"}),e.jsx(f,{size:"sm",variant:"outline",isDisabled:!se,onPress:()=>T(s=>s+1),children:"Next"})]})]})]})}export{Ce as ActivityPage}; diff --git a/src/gateway/static/dashboard/assets/AliasesPage-C2JIWSiZ.js b/src/gateway/static/dashboard/assets/AliasesPage-CCRTl9Co.js similarity index 98% rename from src/gateway/static/dashboard/assets/AliasesPage-C2JIWSiZ.js rename to src/gateway/static/dashboard/assets/AliasesPage-CCRTl9Co.js index d4bd872f..362a4dfb 100644 --- a/src/gateway/static/dashboard/assets/AliasesPage-C2JIWSiZ.js +++ b/src/gateway/static/dashboard/assets/AliasesPage-CCRTl9Co.js @@ -1 +1 @@ -import{j as e}from"./tanstack-query-1t81HyiD.js";import{r as x,u as w}from"./react-dgEcD0HR.js";import{e as L,f as E,g as B,P as D,E as N,C as I,h as M,i as A}from"./index-DHQmS-9o.js";import{F}from"./Field-HzRk1KDP.js";import{C as j,L as R,I as q,a as V,b as H,B as h,f as $,d as C}from"./heroui-BX6JwHY-.js";import{T as z,a as G,d as T,b as f,L as K,c as W,e as v}from"./Table-CLdjdyTx.js";const X=50;function k({label:t,value:n,onChange:a,description:r,placeholder:m="provider:model",autoFocus:i,isRequired:c}){const l=L(),{visible:d,total:s,failed:g}=x.useMemo(()=>{var S;const o=n.trim().toLowerCase(),p=((S=l.data)==null?void 0:S.providers)??[],y=p.flatMap(u=>u.models),P=o?y.filter(u=>u.key.toLowerCase().includes(o)):y;return{visible:P.slice(0,X),total:P.length,failed:p.filter(u=>!u.ok)}},[l.data,n]),b=l.isLoading?"Loading models from your providers…":g.length>0?`Could not list models for ${g.map(p=>p.provider).join(", ")}. Check that provider's credentials, or type the model key directly.`:s>d.length?`Showing ${d.length} of ${s} matches. Keep typing to narrow them.`:r;return e.jsxs(j.Root,{allowsCustomValue:!0,allowsEmptyCollection:!0,menuTrigger:"input",inputValue:n,onInputChange:a,onSelectionChange:o=>{o!=null&&a(String(o))},isRequired:c,className:"flex max-w-md flex-col gap-1",children:[e.jsx(R,{className:"text-sm font-medium text-[var(--otari-ink)]",children:t}),e.jsxs(j.InputGroup,{children:[e.jsx(q,{placeholder:m,autoFocus:i}),e.jsx(j.Trigger,{})]}),e.jsx(j.Popover,{children:e.jsx(V,{items:d,className:"max-h-72 overflow-auto",children:o=>e.jsx(H,{id:o.key,textValue:o.key,children:o.key})})}),b?e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:b}):null]})}function _({alias:t,onClose:n}){const a=A(),[r,m]=x.useState(t.target),i=r.trim()!==""&&r.trim()!==t.target,c=()=>{i&&a.mutate({name:t.name,target:r.trim()},{onSuccess:n})};return e.jsx(C,{children:e.jsxs(C.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsxs("div",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:["Edit alias ",e.jsx("code",{children:t.name})]}),e.jsx(N,{error:a.error}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx("span",{className:"text-sm font-medium text-[var(--otari-ink)]",children:"Alias name"}),e.jsx("code",{className:"text-sm text-[var(--otari-muted)]",children:t.name}),e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"The alias name is the key and cannot be changed here. Delete and recreate to rename."})]}),e.jsx(k,{label:"Target",value:r,onChange:m,isRequired:!0,description:"The real model this resolves to. Callers never see it."})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(h,{variant:"primary",isDisabled:!i||a.isPending,onPress:c,children:a.isPending?"Saving…":"Save changes"}),e.jsx(h,{variant:"ghost",onPress:n,children:"Cancel"})]})]})})}function J({onClose:t,initialTarget:n=""}){const a=A(),[r,m]=x.useState(""),[i,c]=x.useState(n),l=/[:/]/.test(r),d=r.trim()!==""&&i.trim()!==""&&!l,s=()=>{d&&a.mutate({name:r.trim(),target:i.trim()},{onSuccess:t})};return e.jsx(C,{children:e.jsxs(C.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsx("div",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:"New alias"}),e.jsx(N,{error:a.error}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsx(F,{label:"Alias name",value:r,onChange:m,placeholder:"fast-model",isRequired:!0,autoFocus:!0,description:l?e.jsx("span",{className:"text-red-700",children:"An alias name cannot contain “:” or “/”."}):"What callers send as `model`."}),e.jsx(k,{label:"Target",value:i,onChange:c,isRequired:!0,description:"The real model this resolves to. Callers never see it."})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(h,{variant:"primary",isDisabled:!d||a.isPending,onPress:s,children:a.isPending?"Creating…":"Create alias"}),e.jsx(h,{variant:"ghost",onPress:t,children:"Cancel"})]})]})})}function se(){const t=E(),n=B(),[a]=w(),r=a.get("target")??"",[m,i]=x.useState(r!==""),[c,l]=x.useState(null),d=[...t.data??[]].sort((s,g)=>s.name.localeCompare(g.name));return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(D,{title:"Aliases",description:"Friendly names that map to a real provider:model. Callers send the alias as the model; pricing, budgets, and usage key on the target.",action:m||c?null:e.jsx(h,{variant:"primary",onPress:()=>{l(null),i(!0)},children:"New alias"})}),e.jsx(N,{error:t.error}),m?e.jsx(J,{initialTarget:r,onClose:()=>i(!1)}):null,c?e.jsx(_,{alias:c,onClose:()=>l(null)}):null,e.jsxs(z,{children:[e.jsx(G,{children:e.jsxs(T,{children:[e.jsx(f,{children:"Alias"}),e.jsx(f,{children:"Target"}),e.jsx(f,{children:"Source"}),e.jsx(f,{className:"text-right",children:"Actions"})]})}),e.jsx("tbody",{children:t.isLoading?e.jsx(K,{colSpan:4}):d.length===0?e.jsx(W,{colSpan:4,children:"No aliases yet. Create one to give a model a friendly name."}):d.map(s=>e.jsxs(T,{children:[e.jsx(v,{className:"font-medium break-all text-[var(--otari-ink)]",children:s.name}),e.jsx(v,{className:"break-all text-[var(--otari-muted)]",children:s.target}),e.jsx(v,{children:e.jsx($,{size:"sm",color:s.source==="stored"?"accent":"default",children:s.source})}),e.jsx(v,{className:"text-right whitespace-nowrap",children:s.source==="stored"?e.jsxs("span",{className:"inline-flex items-center gap-2",children:[e.jsx(h,{size:"sm",variant:"ghost",onPress:()=>{i(!1),l(s)},children:"Edit"}),e.jsx(I,{confirmLabel:"Delete",isPending:n.isPending,onConfirm:()=>n.mutate(s.name),children:"Delete"}),n.error?e.jsx("span",{className:"text-xs text-red-700",children:M(n.error)}):null]}):e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"set in config.yml"})})]},s.name))})]})]})}export{se as AliasesPage}; +import{j as e}from"./tanstack-query-1t81HyiD.js";import{r as x,u as w}from"./react-dgEcD0HR.js";import{e as L,f as E,g as B,P as D,E as N,C as I,h as M,i as A}from"./index-DAVt9uB3.js";import{F}from"./Field-HzRk1KDP.js";import{C as j,L as R,I as q,a as V,b as H,B as h,f as $,d as C}from"./heroui-BX6JwHY-.js";import{T as z,a as G,d as T,b as f,L as K,c as W,e as v}from"./Table-CLdjdyTx.js";const X=50;function k({label:t,value:n,onChange:a,description:r,placeholder:m="provider:model",autoFocus:i,isRequired:c}){const l=L(),{visible:d,total:s,failed:g}=x.useMemo(()=>{var S;const o=n.trim().toLowerCase(),p=((S=l.data)==null?void 0:S.providers)??[],y=p.flatMap(u=>u.models),P=o?y.filter(u=>u.key.toLowerCase().includes(o)):y;return{visible:P.slice(0,X),total:P.length,failed:p.filter(u=>!u.ok)}},[l.data,n]),b=l.isLoading?"Loading models from your providers…":g.length>0?`Could not list models for ${g.map(p=>p.provider).join(", ")}. Check that provider's credentials, or type the model key directly.`:s>d.length?`Showing ${d.length} of ${s} matches. Keep typing to narrow them.`:r;return e.jsxs(j.Root,{allowsCustomValue:!0,allowsEmptyCollection:!0,menuTrigger:"input",inputValue:n,onInputChange:a,onSelectionChange:o=>{o!=null&&a(String(o))},isRequired:c,className:"flex max-w-md flex-col gap-1",children:[e.jsx(R,{className:"text-sm font-medium text-[var(--otari-ink)]",children:t}),e.jsxs(j.InputGroup,{children:[e.jsx(q,{placeholder:m,autoFocus:i}),e.jsx(j.Trigger,{})]}),e.jsx(j.Popover,{children:e.jsx(V,{items:d,className:"max-h-72 overflow-auto",children:o=>e.jsx(H,{id:o.key,textValue:o.key,children:o.key})})}),b?e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:b}):null]})}function _({alias:t,onClose:n}){const a=A(),[r,m]=x.useState(t.target),i=r.trim()!==""&&r.trim()!==t.target,c=()=>{i&&a.mutate({name:t.name,target:r.trim()},{onSuccess:n})};return e.jsx(C,{children:e.jsxs(C.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsxs("div",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:["Edit alias ",e.jsx("code",{children:t.name})]}),e.jsx(N,{error:a.error}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx("span",{className:"text-sm font-medium text-[var(--otari-ink)]",children:"Alias name"}),e.jsx("code",{className:"text-sm text-[var(--otari-muted)]",children:t.name}),e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"The alias name is the key and cannot be changed here. Delete and recreate to rename."})]}),e.jsx(k,{label:"Target",value:r,onChange:m,isRequired:!0,description:"The real model this resolves to. Callers never see it."})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(h,{variant:"primary",isDisabled:!i||a.isPending,onPress:c,children:a.isPending?"Saving…":"Save changes"}),e.jsx(h,{variant:"ghost",onPress:n,children:"Cancel"})]})]})})}function J({onClose:t,initialTarget:n=""}){const a=A(),[r,m]=x.useState(""),[i,c]=x.useState(n),l=/[:/]/.test(r),d=r.trim()!==""&&i.trim()!==""&&!l,s=()=>{d&&a.mutate({name:r.trim(),target:i.trim()},{onSuccess:t})};return e.jsx(C,{children:e.jsxs(C.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsx("div",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:"New alias"}),e.jsx(N,{error:a.error}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsx(F,{label:"Alias name",value:r,onChange:m,placeholder:"fast-model",isRequired:!0,autoFocus:!0,description:l?e.jsx("span",{className:"text-red-700",children:"An alias name cannot contain “:” or “/”."}):"What callers send as `model`."}),e.jsx(k,{label:"Target",value:i,onChange:c,isRequired:!0,description:"The real model this resolves to. Callers never see it."})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(h,{variant:"primary",isDisabled:!d||a.isPending,onPress:s,children:a.isPending?"Creating…":"Create alias"}),e.jsx(h,{variant:"ghost",onPress:t,children:"Cancel"})]})]})})}function se(){const t=E(),n=B(),[a]=w(),r=a.get("target")??"",[m,i]=x.useState(r!==""),[c,l]=x.useState(null),d=[...t.data??[]].sort((s,g)=>s.name.localeCompare(g.name));return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(D,{title:"Aliases",description:"Friendly names that map to a real provider:model. Callers send the alias as the model; pricing, budgets, and usage key on the target.",action:m||c?null:e.jsx(h,{variant:"primary",onPress:()=>{l(null),i(!0)},children:"New alias"})}),e.jsx(N,{error:t.error}),m?e.jsx(J,{initialTarget:r,onClose:()=>i(!1)}):null,c?e.jsx(_,{alias:c,onClose:()=>l(null)}):null,e.jsxs(z,{children:[e.jsx(G,{children:e.jsxs(T,{children:[e.jsx(f,{children:"Alias"}),e.jsx(f,{children:"Target"}),e.jsx(f,{children:"Source"}),e.jsx(f,{className:"text-right",children:"Actions"})]})}),e.jsx("tbody",{children:t.isLoading?e.jsx(K,{colSpan:4}):d.length===0?e.jsx(W,{colSpan:4,children:"No aliases yet. Create one to give a model a friendly name."}):d.map(s=>e.jsxs(T,{children:[e.jsx(v,{className:"font-medium break-all text-[var(--otari-ink)]",children:s.name}),e.jsx(v,{className:"break-all text-[var(--otari-muted)]",children:s.target}),e.jsx(v,{children:e.jsx($,{size:"sm",color:s.source==="stored"?"accent":"default",children:s.source})}),e.jsx(v,{className:"text-right whitespace-nowrap",children:s.source==="stored"?e.jsxs("span",{className:"inline-flex items-center gap-2",children:[e.jsx(h,{size:"sm",variant:"ghost",onPress:()=>{i(!1),l(s)},children:"Edit"}),e.jsx(I,{confirmLabel:"Delete",isPending:n.isPending,onConfirm:()=>n.mutate(s.name),children:"Delete"}),n.error?e.jsx("span",{className:"text-xs text-red-700",children:M(n.error)}):null]}):e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"set in config.yml"})})]},s.name))})]})]})}export{se as AliasesPage}; diff --git a/src/gateway/static/dashboard/assets/BudgetsPage-iAjnK5BF.js b/src/gateway/static/dashboard/assets/BudgetsPage-iAjnK5BF.js new file mode 100644 index 00000000..1cc6d4f7 --- /dev/null +++ b/src/gateway/static/dashboard/assets/BudgetsPage-iAjnK5BF.js @@ -0,0 +1 @@ +import{j as e}from"./tanstack-query-1t81HyiD.js";import{r as d}from"./react-dgEcD0HR.js";import{j as Y,u as G,k as K,l as Q,m as X,n as J,P as Z,E as R,I as ee,o as se}from"./index-DAVt9uB3.js";import{F as L}from"./Field-HzRk1KDP.js";import{T as te,a as re,b as S,L as ae,c as ne,d as ie,e as C}from"./Table-CLdjdyTx.js";import{C as U,I as le,a as de,b as oe,B as g,d as E,S as ue}from"./heroui-BX6JwHY-.js";const ce=50;function me({value:s,onChange:r,users:a,label:i,description:l}){const[m,x]=d.useState(""),o=d.useMemo(()=>a.filter(t=>!t.user_id.startsWith("apikey-")).map(t=>({id:t.user_id,label:t.alias?`${t.user_id} (${t.alias})`:t.user_id})),[a]),h=d.useMemo(()=>{const t=m.trim().toLowerCase();return o.filter(u=>!s.includes(u.id)).filter(u=>!t||u.id.toLowerCase().includes(t)||u.label.toLowerCase().includes(t)).slice(0,ce)},[o,s,m]),c=t=>{s.includes(t)||r([...s,t]),x("")},p=t=>r(s.filter(u=>u!==t));return e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsxs("div",{children:[e.jsx("span",{className:"text-sm font-medium text-[var(--otari-ink)]",children:i}),l?e.jsx("p",{className:"text-xs text-[var(--otari-muted)]",children:l}):null]}),s.length>0?e.jsx("div",{className:"flex flex-wrap gap-1.5",children:s.map(t=>e.jsxs("span",{className:"inline-flex items-center gap-1 rounded-full bg-[var(--otari-brand-tint)] px-2.5 py-1 font-mono text-xs text-[var(--otari-brand-dark)]",children:[t,e.jsx("button",{type:"button","aria-label":`Remove ${t}`,onClick:()=>p(t),className:"text-[var(--otari-brand-dark)] hover:text-red-700",children:"×"})]},t))}):null,o.length===0?e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"No users yet. Create users first, then assign them here or from the Users page."}):e.jsxs(U.Root,{allowsEmptyCollection:!0,menuTrigger:"input",inputValue:m,onInputChange:x,selectedKey:null,onSelectionChange:t=>{t!=null&&c(String(t))},className:"flex flex-col gap-1",children:[e.jsxs(U.InputGroup,{children:[e.jsx(le,{"aria-label":"Add a user",placeholder:"Search users…",autoComplete:"off"}),e.jsx(U.Trigger,{})]}),e.jsx(U.Popover,{children:e.jsx(de,{items:h,className:"max-h-72 overflow-auto",children:t=>e.jsx(oe,{id:t.id,textValue:t.label,children:t.label})})})]})]})}const xe=new Intl.NumberFormat(void 0,{style:"currency",currency:"USD",maximumFractionDigits:2});function w(s){return xe.format(s)}const b=86400,$=3600,I=[{label:"No reset",seconds:null},{label:"Daily",seconds:b},{label:"Weekly",seconds:7*b},{label:"Monthly",seconds:30*b}];function ge(s){if(s===null)return"No reset";const r=I.find(a=>a.seconds===s);return r?r.label:s%b===0?`Every ${s/b} days`:s%$===0?`Every ${s/$} hours`:`Every ${s}s`}function F(s){if(!s)return"—";const r=new Date(s);return Number.isNaN(r.getTime())?"—":r.toLocaleString()}function he(s){const r=s.trim();if(r==="")return{value:null,valid:!0};const a=Number(r);return!Number.isFinite(a)||a<0?{value:null,valid:!1}:{value:a,valid:!0}}function pe({value:s,onChange:r}){const a=I.some(t=>t.seconds===s),[i,l]=d.useState(!a),m=s!==null&&s%b===0?String(s/b):"",[x,o]=d.useState(m);d.useEffect(()=>{o(m)},[m]);const h=x.trim(),c=Number(h),p=h!==""&&(!Number.isInteger(c)||c<=0);return e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsx("span",{className:"text-sm font-medium text-[var(--otari-ink)]",children:"Reset period"}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[I.map(t=>e.jsx(g,{size:"sm",variant:!i&&s===t.seconds?"primary":"outline",onPress:()=>{l(!1),r(t.seconds)},children:t.label},t.label)),e.jsx(g,{size:"sm",variant:i?"primary":"outline",onPress:()=>l(!0),children:"Custom"})]}),i?e.jsx("div",{className:"flex items-end gap-2",children:e.jsx(L,{label:"Every N days",value:x,onChange:t=>{o(t);const u=Number(t.trim());r(t.trim()===""||!Number.isInteger(u)||u<=0?null:u*b)},placeholder:"14",description:p?e.jsx("span",{className:"text-red-700",children:"Enter a whole number of days."}):"Whole days between resets."})}):null,e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"Spend returns to zero each period. A user’s clock starts when the budget is assigned to them."})]})}function O({title:s,submitLabel:r,initial:a,error:i,isPending:l,onSubmit:m,onClose:x,assignUsers:o}){const[h,c]=d.useState(a.name??""),[p,t]=d.useState(a.max_budget===null?"":String(a.max_budget)),[u,j]=d.useState(a.budget_duration_sec),[v,N]=d.useState([]),_=he(p),P=()=>{l||!_.valid||m({name:h.trim()||null,max_budget:_.value,budget_duration_sec:u},v)};return e.jsx(E,{children:e.jsxs(E.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsx("div",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:s}),e.jsx(R,{error:i}),e.jsx(L,{label:"Name (optional)",value:h,onChange:c,autoFocus:!0,placeholder:"team-free-tier",description:"A label to recognize this budget later."}),e.jsx(L,{label:"Spending limit (USD)",value:p,onChange:t,placeholder:"100.00",description:_.valid?"The most a single user on this budget may spend per period. Leave blank for no limit.":e.jsx("span",{className:"text-red-700",children:"Enter a non-negative number, or leave blank for no limit."})}),e.jsx(pe,{value:u,onChange:j}),o?e.jsx(me,{label:"Assign to users (optional)",description:"Attach this budget to existing users now. You can also manage assignments later on the Users page.",value:v,onChange:N,users:o}):null,e.jsxs("div",{className:"flex gap-2",children:[e.jsx(g,{variant:"primary",isDisabled:l||!_.valid,onPress:P,children:l?"Saving…":r}),e.jsx(g,{variant:"ghost",isDisabled:l,onPress:x,children:"Cancel"})]})]})})}function fe({budget:s}){if(s.user_count===0)return e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"No users assigned"});const r=s.total_spend;if(s.max_budget===null)return e.jsxs("span",{className:"text-xs text-[var(--otari-ink)]",children:[w(r)," spent",e.jsx("span",{className:"text-[var(--otari-muted)]",children:" · no limit"})]});const a=s.max_budget*s.user_count,i=a>0?Math.min(100,r/a*100):0,l=r>a;return e.jsxs("div",{className:"flex min-w-[140px] flex-col gap-1",children:[e.jsxs("div",{className:"flex items-baseline justify-between gap-2 text-xs",children:[e.jsx("span",{className:"text-[var(--otari-ink)]",children:w(r)}),e.jsxs("span",{className:"text-[var(--otari-muted)]",children:["of ",w(a)]})]}),e.jsx("div",{className:"h-1.5 w-full overflow-hidden rounded-full bg-[var(--otari-line)]",role:"progressbar","aria-valuenow":Math.round(i),"aria-valuemin":0,"aria-valuemax":100,"aria-label":"Aggregate spend against total allocation",children:e.jsx("div",{className:`h-full rounded-full ${l?"bg-red-500":"bg-[var(--otari-brand)]"}`,style:{width:`${Math.max(i,l?100:2)}%`}})})]})}function je({budgetId:s}){const r=se(s);if(r.isLoading)return e.jsxs("div",{className:"flex items-center gap-2 px-4 py-4 text-sm text-[var(--otari-muted)]",children:[e.jsx(ue,{size:"sm"})," Loading reset history…"]});if(r.error)return e.jsx("div",{className:"px-4 py-4",children:e.jsx(R,{error:r.error})});const a=r.data??[];return a.length===0?e.jsx("div",{className:"px-4 py-4 text-sm text-[var(--otari-muted)]",children:"No resets recorded yet for this budget."}):e.jsx("div",{className:"overflow-x-auto px-4 py-3",children:e.jsxs("table",{className:"w-full border-collapse text-xs",children:[e.jsx("thead",{className:"text-left text-[var(--otari-muted)]",children:e.jsxs("tr",{children:[e.jsx("th",{className:"py-1.5 pr-4 font-medium",children:"User"}),e.jsx("th",{className:"py-1.5 pr-4 font-medium",children:"Spend cleared"}),e.jsx("th",{className:"py-1.5 pr-4 font-medium",children:"Reset at"}),e.jsx("th",{className:"py-1.5 font-medium",children:"Next reset"})]})}),e.jsx("tbody",{children:a.map(i=>e.jsxs("tr",{className:"border-t border-[var(--otari-line)]",children:[e.jsx("td",{className:"py-1.5 pr-4",children:e.jsx("code",{children:i.user_id??"—"})}),e.jsx("td",{className:"py-1.5 pr-4 text-[var(--otari-ink)]",children:w(i.previous_spend)}),e.jsx("td",{className:"py-1.5 pr-4 text-[var(--otari-muted)]",children:F(i.reset_at)}),e.jsx("td",{className:"py-1.5 text-[var(--otari-muted)]",children:F(i.next_reset_at)})]},i.id))})]})})}function be({onCreate:s}){return e.jsx(E,{children:e.jsxs(E.Content,{className:"flex flex-col gap-4 p-6",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-semibold text-[var(--otari-ink)]",children:"No budgets yet"}),e.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:"A budget caps how much a user may spend and, optionally, resets that spend on a schedule. Create one, then assign it to users to enforce a limit."})]}),e.jsx("div",{children:e.jsx(g,{variant:"primary",onPress:s,children:"Create your first budget"})})]})})}function ve({label:s,isPending:r,onConfirm:a}){const[i,l]=d.useState(!1);return i?e.jsxs("div",{className:"flex flex-col items-end gap-1.5 rounded-lg border border-amber-200 bg-amber-50 p-2 text-right",children:[e.jsxs("span",{className:"max-w-xs text-xs text-amber-800",children:["Delete ",e.jsx("strong",{children:s}),"? Users keep their spend but lose this limit. Cannot be undone."]}),e.jsxs("span",{className:"inline-flex gap-1",children:[e.jsx(g,{size:"sm",variant:"danger",isDisabled:r,onPress:a,children:"Delete permanently"}),e.jsx(g,{size:"sm",variant:"ghost",isDisabled:r,onPress:()=>l(!1),children:"Cancel"})]})]}):e.jsx(g,{size:"sm",variant:"danger-soft",onPress:()=>l(!0),children:"Delete"})}function V(s){return s.split("-")[0]}function H(s){return s.name??V(s.budget_id)}function Pe(){const s=Y(),r=G(),a=K(),i=Q(),l=X(),m=J(),[x,o]=d.useState(!1),[h,c]=d.useState(null),[p,t]=d.useState(null),[u,j]=d.useState(null),[v,N]=d.useState(null),[_,P]=d.useState(!1),D=s.data??[],T=s.isLoading,y=D.find(n=>n.budget_id===h)??null,z=!T&&D.length===0&&!x,M=async(n,f)=>{P(!0),j(null);const B=await Promise.allSettled(f.map(k=>m.mutateAsync({id:k,body:{budget_id:n}})));P(!1);const A=B.flatMap((k,q)=>k.status==="rejected"?[f[q]]:[]);if(A.length>0){N({budgetId:n,userIds:A}),j(new Error(`Budget created, but could not assign it to: ${A.join(", ")}. Retry to try again.`));return}N(null),o(!1)},W=(n,f)=>{if(v){M(v.budgetId,v.userIds);return}j(null),a.mutate(n,{onSuccess:async B=>{if(f.length>0){await M(B.budget_id,f);return}o(!1)}})};return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(Z,{title:"Budgets",description:"Define spending limits and reset schedules. Assign a budget to users to enforce it.",action:x||z?null:e.jsx(g,{variant:"primary",onPress:()=>{c(null),j(null),N(null),o(!0)},children:"Create budget"})}),e.jsx(R,{error:s.error??a.error??i.error??l.error??m.error}),e.jsx(ee,{children:"Assign a budget to users when you create it, or later from the Users page. Each row’s usage aggregates the spend of the users currently on that budget."}),z?e.jsx(be,{onCreate:()=>{c(null),j(null),N(null),o(!0)}}):null,x?e.jsx(O,{title:"Create budget",submitLabel:v?"Retry assignments":"Create budget",initial:{name:null,max_budget:null,budget_duration_sec:null},error:a.error??u,isPending:a.isPending||_,assignUsers:r.data??[],onSubmit:W,onClose:()=>{j(null),N(null),o(!1)}}):null,y?e.jsx(O,{title:`Edit budget ${H(y)}`,submitLabel:"Save changes",initial:{name:y.name,max_budget:y.max_budget,budget_duration_sec:y.budget_duration_sec},error:i.error,isPending:i.isPending,onSubmit:n=>i.mutate({id:y.budget_id,body:n},{onSuccess:()=>c(null)}),onClose:()=>c(null)},y.budget_id):null,e.jsxs(te,{children:[e.jsx(re,{children:e.jsxs("tr",{children:[e.jsx(S,{children:"Budget"}),e.jsx(S,{children:"Limit (per user)"}),e.jsx(S,{children:"Reset"}),e.jsx(S,{children:"Users"}),e.jsx(S,{children:"Usage"}),e.jsx(S,{className:"text-right",children:"Actions"})]})}),e.jsx("tbody",{children:T?e.jsx(ae,{colSpan:6}):D.length===0?e.jsx(ne,{colSpan:6,children:"No budgets yet. Create one to cap spending."}):D.map(n=>e.jsxs(d.Fragment,{children:[e.jsxs(ie,{selected:h===n.budget_id,onClick:()=>{o(!1),c(n.budget_id)},children:[e.jsx(C,{className:"font-medium text-[var(--otari-ink)]",children:e.jsxs("div",{className:"flex flex-col gap-0.5",children:[e.jsx("span",{children:n.name??e.jsx("span",{className:"text-[var(--otari-muted)]",children:"(unnamed)"})}),e.jsx("code",{className:"text-[11px] text-[var(--otari-muted)]",title:n.budget_id,children:V(n.budget_id)})]})}),e.jsx(C,{children:n.max_budget===null?e.jsx("span",{className:"text-[var(--otari-muted)]",children:"Unlimited"}):w(n.max_budget)}),e.jsx(C,{className:"text-[var(--otari-muted)]",children:ge(n.budget_duration_sec)}),e.jsx(C,{className:"text-[var(--otari-muted)]",children:n.user_count}),e.jsx(C,{children:e.jsx(fe,{budget:n})}),e.jsx(C,{children:e.jsxs("div",{className:"flex items-center justify-end gap-1.5",onClick:f=>f.stopPropagation(),children:[e.jsx(g,{size:"sm",variant:"ghost",onPress:()=>t(f=>f===n.budget_id?null:n.budget_id),children:p===n.budget_id?"Hide history":"History"}),e.jsx(g,{size:"sm",variant:"ghost",onPress:()=>{o(!1),c(n.budget_id)},children:"Edit"}),e.jsx(ve,{label:H(n),isPending:l.isPending,onConfirm:()=>l.mutate(n.budget_id)})]})})]}),p===n.budget_id?e.jsx("tr",{className:"border-b border-[var(--otari-line)] bg-[var(--otari-bg)]",children:e.jsx("td",{colSpan:6,children:e.jsx(je,{budgetId:n.budget_id})})}):null]},n.budget_id))})]})]})}export{Pe as BudgetsPage}; diff --git a/src/gateway/static/dashboard/assets/BudgetsPage-inMAr92N.js b/src/gateway/static/dashboard/assets/BudgetsPage-inMAr92N.js deleted file mode 100644 index 3a0a7b5c..00000000 --- a/src/gateway/static/dashboard/assets/BudgetsPage-inMAr92N.js +++ /dev/null @@ -1 +0,0 @@ -import{j as e}from"./tanstack-query-1t81HyiD.js";import{r as u}from"./react-dgEcD0HR.js";import{j as Y,u as G,k as K,l as Q,m as X,n as J,P as Z,E as R,I as ee,o as se}from"./index-DHQmS-9o.js";import{F as L}from"./Field-HzRk1KDP.js";import{T as te,a as re,b as S,L as ae,c as ne,d as ie,e as C}from"./Table-CLdjdyTx.js";import{C as B,I as le,a as de,b as oe,B as x,d as A,S as ue}from"./heroui-BX6JwHY-.js";const ce=50;function me({value:s,onChange:r,users:a,label:i,description:l}){const[g,d]=u.useState(""),o=u.useMemo(()=>a.filter(t=>!t.user_id.startsWith("apikey-")).map(t=>({id:t.user_id,label:t.alias?`${t.user_id} (${t.alias})`:t.user_id})),[a]),c=u.useMemo(()=>{const t=g.trim().toLowerCase();return o.filter(m=>!s.includes(m.id)).filter(m=>!t||m.id.toLowerCase().includes(t)||m.label.toLowerCase().includes(t)).slice(0,ce)},[o,s,g]),h=t=>{s.includes(t)||r([...s,t]),d("")},b=t=>r(s.filter(m=>m!==t));return e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsxs("div",{children:[e.jsx("span",{className:"text-sm font-medium text-[var(--otari-ink)]",children:i}),l?e.jsx("p",{className:"text-xs text-[var(--otari-muted)]",children:l}):null]}),s.length>0?e.jsx("div",{className:"flex flex-wrap gap-1.5",children:s.map(t=>e.jsxs("span",{className:"inline-flex items-center gap-1 rounded-full bg-[var(--otari-brand-tint)] px-2.5 py-1 font-mono text-xs text-[var(--otari-brand-dark)]",children:[t,e.jsx("button",{type:"button","aria-label":`Remove ${t}`,onClick:()=>b(t),className:"text-[var(--otari-brand-dark)] hover:text-red-700",children:"×"})]},t))}):null,o.length===0?e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"No users yet. Create users first, then assign them here or from the Users page."}):e.jsxs(B.Root,{allowsEmptyCollection:!0,menuTrigger:"input",inputValue:g,onInputChange:d,selectedKey:null,onSelectionChange:t=>{t!=null&&h(String(t))},className:"flex flex-col gap-1",children:[e.jsxs(B.InputGroup,{children:[e.jsx(le,{"aria-label":"Add a user",placeholder:"Search users…",autoComplete:"off"}),e.jsx(B.Trigger,{})]}),e.jsx(B.Popover,{children:e.jsx(de,{items:c,className:"max-h-72 overflow-auto",children:t=>e.jsx(oe,{id:t.id,textValue:t.label,children:t.label})})})]})]})}const xe=new Intl.NumberFormat(void 0,{style:"currency",currency:"USD",maximumFractionDigits:2});function w(s){return xe.format(s)}const j=86400,F=3600,I=[{label:"No reset",seconds:null},{label:"Daily",seconds:j},{label:"Weekly",seconds:7*j},{label:"Monthly",seconds:30*j}];function ge(s){if(s===null)return"No reset";const r=I.find(a=>a.seconds===s);return r?r.label:s%j===0?`Every ${s/j} days`:s%F===0?`Every ${s/F} hours`:`Every ${s}s`}function $(s){if(!s)return"—";const r=new Date(s);return Number.isNaN(r.getTime())?"—":r.toLocaleString()}function he(s){const r=s.trim();if(r==="")return{value:null,valid:!0};const a=Number(r);return!Number.isFinite(a)||a<0?{value:null,valid:!1}:{value:a,valid:!0}}function pe({value:s,onChange:r}){const a=I.some(d=>d.seconds===s),[i,l]=u.useState(!a),g=s!==null&&s%j===0?String(s/j):"";return e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsx("span",{className:"text-sm font-medium text-[var(--otari-ink)]",children:"Reset period"}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[I.map(d=>e.jsx(x,{size:"sm",variant:!i&&s===d.seconds?"primary":"outline",onPress:()=>{l(!1),r(d.seconds)},children:d.label},d.label)),e.jsx(x,{size:"sm",variant:i?"primary":"outline",onPress:()=>l(!0),children:"Custom"})]}),i?e.jsx("div",{className:"flex items-end gap-2",children:e.jsx(L,{label:"Every N days",value:g,onChange:d=>{const o=Number(d.trim()),c=Math.round(o)*j;r(d.trim()===""||!Number.isFinite(o)||o<=0||!Number.isFinite(c)||c<=0?null:c)},placeholder:"14",description:"Whole days between resets."})}):null,e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"Spend returns to zero each period. A user’s clock starts when the budget is assigned to them."})]})}function O({title:s,submitLabel:r,initial:a,error:i,isPending:l,onSubmit:g,onClose:d,assignUsers:o}){const[c,h]=u.useState(a.name??""),[b,t]=u.useState(a.max_budget===null?"":String(a.max_budget)),[m,f]=u.useState(a.budget_duration_sec),[v,N]=u.useState([]),_=he(b),P=()=>{l||!_.valid||g({name:c.trim()||null,max_budget:_.value,budget_duration_sec:m},v)};return e.jsx(A,{children:e.jsxs(A.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsx("div",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:s}),e.jsx(R,{error:i}),e.jsx(L,{label:"Name (optional)",value:c,onChange:h,autoFocus:!0,placeholder:"team-free-tier",description:"A label to recognize this budget later."}),e.jsx(L,{label:"Spending limit (USD)",value:b,onChange:t,placeholder:"100.00",description:_.valid?"The most a single user on this budget may spend per period. Leave blank for no limit.":e.jsx("span",{className:"text-red-700",children:"Enter a non-negative number, or leave blank for no limit."})}),e.jsx(pe,{value:m,onChange:f}),o?e.jsx(me,{label:"Assign to users (optional)",description:"Attach this budget to existing users now. You can also manage assignments later on the Users page.",value:v,onChange:N,users:o}):null,e.jsxs("div",{className:"flex gap-2",children:[e.jsx(x,{variant:"primary",isDisabled:l||!_.valid,onPress:P,children:l?"Saving…":r}),e.jsx(x,{variant:"ghost",isDisabled:l,onPress:d,children:"Cancel"})]})]})})}function fe({budget:s}){if(s.user_count===0)return e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"No users assigned"});const r=s.total_spend;if(s.max_budget===null)return e.jsxs("span",{className:"text-xs text-[var(--otari-ink)]",children:[w(r)," spent",e.jsx("span",{className:"text-[var(--otari-muted)]",children:" · no limit"})]});const a=s.max_budget*s.user_count,i=a>0?Math.min(100,r/a*100):0,l=r>a;return e.jsxs("div",{className:"flex min-w-[140px] flex-col gap-1",children:[e.jsxs("div",{className:"flex items-baseline justify-between gap-2 text-xs",children:[e.jsx("span",{className:"text-[var(--otari-ink)]",children:w(r)}),e.jsxs("span",{className:"text-[var(--otari-muted)]",children:["of ",w(a)]})]}),e.jsx("div",{className:"h-1.5 w-full overflow-hidden rounded-full bg-[var(--otari-line)]",role:"progressbar","aria-valuenow":Math.round(i),"aria-valuemin":0,"aria-valuemax":100,"aria-label":"Aggregate spend against total allocation",children:e.jsx("div",{className:`h-full rounded-full ${l?"bg-red-500":"bg-[var(--otari-brand)]"}`,style:{width:`${Math.max(i,l?100:2)}%`}})})]})}function je({budgetId:s}){const r=se(s);if(r.isLoading)return e.jsxs("div",{className:"flex items-center gap-2 px-4 py-4 text-sm text-[var(--otari-muted)]",children:[e.jsx(ue,{size:"sm"})," Loading reset history…"]});if(r.error)return e.jsx("div",{className:"px-4 py-4",children:e.jsx(R,{error:r.error})});const a=r.data??[];return a.length===0?e.jsx("div",{className:"px-4 py-4 text-sm text-[var(--otari-muted)]",children:"No resets recorded yet for this budget."}):e.jsx("div",{className:"overflow-x-auto px-4 py-3",children:e.jsxs("table",{className:"w-full border-collapse text-xs",children:[e.jsx("thead",{className:"text-left text-[var(--otari-muted)]",children:e.jsxs("tr",{children:[e.jsx("th",{className:"py-1.5 pr-4 font-medium",children:"User"}),e.jsx("th",{className:"py-1.5 pr-4 font-medium",children:"Spend cleared"}),e.jsx("th",{className:"py-1.5 pr-4 font-medium",children:"Reset at"}),e.jsx("th",{className:"py-1.5 font-medium",children:"Next reset"})]})}),e.jsx("tbody",{children:a.map(i=>e.jsxs("tr",{className:"border-t border-[var(--otari-line)]",children:[e.jsx("td",{className:"py-1.5 pr-4",children:e.jsx("code",{children:i.user_id??"—"})}),e.jsx("td",{className:"py-1.5 pr-4 text-[var(--otari-ink)]",children:w(i.previous_spend)}),e.jsx("td",{className:"py-1.5 pr-4 text-[var(--otari-muted)]",children:$(i.reset_at)}),e.jsx("td",{className:"py-1.5 text-[var(--otari-muted)]",children:$(i.next_reset_at)})]},i.id))})]})})}function be({onCreate:s}){return e.jsx(A,{children:e.jsxs(A.Content,{className:"flex flex-col gap-4 p-6",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-semibold text-[var(--otari-ink)]",children:"No budgets yet"}),e.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:"A budget caps how much a user may spend and, optionally, resets that spend on a schedule. Create one, then assign it to users to enforce a limit."})]}),e.jsx("div",{children:e.jsx(x,{variant:"primary",onPress:s,children:"Create your first budget"})})]})})}function ve({label:s,isPending:r,onConfirm:a}){const[i,l]=u.useState(!1);return i?e.jsxs("div",{className:"flex flex-col items-end gap-1.5 rounded-lg border border-amber-200 bg-amber-50 p-2 text-right",children:[e.jsxs("span",{className:"max-w-xs text-xs text-amber-800",children:["Delete ",e.jsx("strong",{children:s}),"? Users keep their spend but lose this limit. Cannot be undone."]}),e.jsxs("span",{className:"inline-flex gap-1",children:[e.jsx(x,{size:"sm",variant:"danger",isDisabled:r,onPress:a,children:"Delete permanently"}),e.jsx(x,{size:"sm",variant:"ghost",isDisabled:r,onPress:()=>l(!1),children:"Cancel"})]})]}):e.jsx(x,{size:"sm",variant:"danger-soft",onPress:()=>l(!0),children:"Delete"})}function V(s){return s.split("-")[0]}function H(s){return s.name??V(s.budget_id)}function Pe(){const s=Y(),r=G(),a=K(),i=Q(),l=X(),g=J(),[d,o]=u.useState(!1),[c,h]=u.useState(null),[b,t]=u.useState(null),[m,f]=u.useState(null),[v,N]=u.useState(null),[_,P]=u.useState(!1),U=s.data??[],T=s.isLoading,y=U.find(n=>n.budget_id===c)??null,M=!T&&U.length===0&&!d,z=async(n,p)=>{P(!0),f(null);const D=await Promise.allSettled(p.map(k=>g.mutateAsync({id:k,body:{budget_id:n}})));P(!1);const E=D.flatMap((k,q)=>k.status==="rejected"?[p[q]]:[]);if(E.length>0){N({budgetId:n,userIds:E}),f(new Error(`Budget created, but could not assign it to: ${E.join(", ")}. Retry to try again.`));return}N(null),o(!1)},W=(n,p)=>{if(v){z(v.budgetId,v.userIds);return}f(null),a.mutate(n,{onSuccess:async D=>{if(p.length>0){await z(D.budget_id,p);return}o(!1)}})};return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(Z,{title:"Budgets",description:"Define spending limits and reset schedules. Assign a budget to users to enforce it.",action:d||M?null:e.jsx(x,{variant:"primary",onPress:()=>{h(null),f(null),N(null),o(!0)},children:"Create budget"})}),e.jsx(R,{error:s.error??a.error??i.error??l.error??g.error}),e.jsx(ee,{children:"Assign a budget to users when you create it, or later from the Users page. Each row’s usage aggregates the spend of the users currently on that budget."}),M?e.jsx(be,{onCreate:()=>{h(null),f(null),N(null),o(!0)}}):null,d?e.jsx(O,{title:"Create budget",submitLabel:v?"Retry assignments":"Create budget",initial:{name:null,max_budget:null,budget_duration_sec:null},error:a.error??m,isPending:a.isPending||_,assignUsers:r.data??[],onSubmit:W,onClose:()=>{f(null),N(null),o(!1)}}):null,y?e.jsx(O,{title:`Edit budget ${H(y)}`,submitLabel:"Save changes",initial:{name:y.name,max_budget:y.max_budget,budget_duration_sec:y.budget_duration_sec},error:i.error,isPending:i.isPending,onSubmit:n=>i.mutate({id:y.budget_id,body:n},{onSuccess:()=>h(null)}),onClose:()=>h(null)},y.budget_id):null,e.jsxs(te,{children:[e.jsx(re,{children:e.jsxs("tr",{children:[e.jsx(S,{children:"Budget"}),e.jsx(S,{children:"Limit (per user)"}),e.jsx(S,{children:"Reset"}),e.jsx(S,{children:"Users"}),e.jsx(S,{children:"Usage"}),e.jsx(S,{className:"text-right",children:"Actions"})]})}),e.jsx("tbody",{children:T?e.jsx(ae,{colSpan:6}):U.length===0?e.jsx(ne,{colSpan:6,children:"No budgets yet. Create one to cap spending."}):U.map(n=>e.jsxs(u.Fragment,{children:[e.jsxs(ie,{selected:c===n.budget_id,onClick:()=>{o(!1),h(n.budget_id)},children:[e.jsx(C,{className:"font-medium text-[var(--otari-ink)]",children:e.jsxs("div",{className:"flex flex-col gap-0.5",children:[e.jsx("span",{children:n.name??e.jsx("span",{className:"text-[var(--otari-muted)]",children:"(unnamed)"})}),e.jsx("code",{className:"text-[11px] text-[var(--otari-muted)]",title:n.budget_id,children:V(n.budget_id)})]})}),e.jsx(C,{children:n.max_budget===null?e.jsx("span",{className:"text-[var(--otari-muted)]",children:"Unlimited"}):w(n.max_budget)}),e.jsx(C,{className:"text-[var(--otari-muted)]",children:ge(n.budget_duration_sec)}),e.jsx(C,{className:"text-[var(--otari-muted)]",children:n.user_count}),e.jsx(C,{children:e.jsx(fe,{budget:n})}),e.jsx(C,{children:e.jsxs("div",{className:"flex items-center justify-end gap-1.5",onClick:p=>p.stopPropagation(),children:[e.jsx(x,{size:"sm",variant:"ghost",onPress:()=>t(p=>p===n.budget_id?null:n.budget_id),children:b===n.budget_id?"Hide history":"History"}),e.jsx(x,{size:"sm",variant:"ghost",onPress:()=>{o(!1),h(n.budget_id)},children:"Edit"}),e.jsx(ve,{label:H(n),isPending:l.isPending,onConfirm:()=>l.mutate(n.budget_id)})]})})]}),b===n.budget_id?e.jsx("tr",{className:"border-b border-[var(--otari-line)] bg-[var(--otari-bg)]",children:e.jsx("td",{colSpan:6,children:e.jsx(je,{budgetId:n.budget_id})})}):null]},n.budget_id))})]})]})}export{Pe as BudgetsPage}; diff --git a/src/gateway/static/dashboard/assets/KeysPage-0Svam5tu.js b/src/gateway/static/dashboard/assets/KeysPage-C6eaoTUP.js similarity index 99% rename from src/gateway/static/dashboard/assets/KeysPage-0Svam5tu.js rename to src/gateway/static/dashboard/assets/KeysPage-C6eaoTUP.js index ea4b6556..3e4a1297 100644 --- a/src/gateway/static/dashboard/assets/KeysPage-0Svam5tu.js +++ b/src/gateway/static/dashboard/assets/KeysPage-C6eaoTUP.js @@ -1,4 +1,4 @@ -import{j as e}from"./tanstack-query-1t81HyiD.js";import{r as m}from"./react-dgEcD0HR.js";import{p as $,q as E,r as z,s as K,P as H,E as T,t as B,u as M,I as V}from"./index-DHQmS-9o.js";import{F as k}from"./Field-HzRk1KDP.js";import{M as O,a as A}from"./ModelScopeControl-DTCXvnvU.js";import{C as _,L as U,I as q,a as W,b as G,D as Y,B as g,f as P,d as C}from"./heroui-BX6JwHY-.js";import{T as J,a as Q,b as v,L as X,c as Z,d as ee,e as y}from"./Table-CLdjdyTx.js";function te({value:t,onChange:s,users:n,description:i}){const c=n.filter(a=>!a.user_id.startsWith("apikey-")).map(a=>({id:a.user_id,name:a.alias?`${a.user_id} (${a.alias})`:a.user_id})),[l,o]=m.useState(t),u=l.trim().toLowerCase(),j=c.filter(a=>!u||a.id.toLowerCase().includes(u)||a.name.toLowerCase().includes(u)).slice(0,50),p=a=>{const x=a.trim(),w=c.find(N=>N.id===x||N.name===x);return w?w.id:x},d=p(l),h=c.some(a=>a.id===d),f=d!==""&&!h?e.jsxs("span",{children:["Creates a new user ",e.jsx("code",{children:d}),"."]}):i??"Spend and budgets track against this user.";return e.jsxs(_.Root,{allowsCustomValue:!0,allowsEmptyCollection:!0,menuTrigger:"focus",inputValue:l,onInputChange:a=>{o(a),s(p(a))},onSelectionChange:a=>{if(a!=null){const x=String(a);o(x),s(x)}},className:"flex max-w-md flex-col gap-1",children:[e.jsx(U,{className:"text-sm font-medium text-[var(--otari-ink)]",children:"Owner"}),e.jsxs(_.InputGroup,{children:[e.jsx(q,{placeholder:"Pick a user, or type a new id…",autoComplete:"off","data-1p-ignore":!0,"data-lpignore":"true",onFocus:a=>a.currentTarget.select()}),e.jsx(_.Trigger,{})]}),e.jsx(_.Popover,{children:e.jsx(W,{items:j,className:"max-h-72 overflow-auto",children:a=>e.jsx(G,{id:a.id,textValue:a.name,children:a.name})})}),e.jsx(Y,{className:"text-xs text-[var(--otari-muted)]",children:f})]})}function L(t){if(!t)return"—";const s=new Date(t);return Number.isNaN(s.getTime())?"—":s.toLocaleDateString()}function se(t){if(!t)return null;const s=new Date(t).getTime();if(Number.isNaN(s))return null;const n=Math.round((s-Date.now())/1e3),i=Math.abs(n),c=[["day",86400],["hour",3600],["minute",60]],l=new Intl.RelativeTimeFormat(void 0,{numeric:"auto"});for(const[o,u]of c)if(i>=u)return l.format(Math.round(n/u),o);return l.format(n,"second")}function ne(t){if(!t.expires_at)return!1;const s=new Date(t.expires_at).getTime();return!Number.isNaN(s)&&sString(i).padStart(2,"0");return`${s.getFullYear()}-${n(s.getMonth()+1)}-${n(s.getDate())}T${n(s.getHours())}:${n(s.getMinutes())}`}const ae=t=>(t??"").startsWith("apikey-");function I({label:t,value:s,multiline:n=!1,fieldRef:i}){const c=m.useRef(null),l=i??c,[o,u]=m.useState(!1),[j,p]=m.useState(!1),d=async()=>{var f,a,x;(f=l.current)==null||f.focus(),(a=l.current)==null||a.select();try{if((x=navigator.clipboard)!=null&&x.writeText){await navigator.clipboard.writeText(s),u(!0),p(!1),window.setTimeout(()=>u(!1),2e3);return}}catch{}p(!0)},h="w-full rounded-lg border border-[var(--otari-line)] bg-[var(--otari-bg)] px-3 py-2 font-mono text-xs text-[var(--otari-ink)]";return e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-xs font-medium text-[var(--otari-muted)]",children:t}),e.jsx(g,{size:"sm",variant:"outline",onPress:d,children:o?"Copied":"Copy"})]}),n?e.jsx("textarea",{ref:l,readOnly:!0,rows:s.split(` +import{j as e}from"./tanstack-query-1t81HyiD.js";import{r as m}from"./react-dgEcD0HR.js";import{p as $,q as E,r as z,s as K,P as H,E as T,t as B,u as M,I as V}from"./index-DAVt9uB3.js";import{F as k}from"./Field-HzRk1KDP.js";import{M as O,a as A}from"./ModelScopeControl-CkKcIwGe.js";import{C as _,L as U,I as q,a as W,b as G,D as Y,B as g,f as P,d as C}from"./heroui-BX6JwHY-.js";import{T as J,a as Q,b as v,L as X,c as Z,d as ee,e as y}from"./Table-CLdjdyTx.js";function te({value:t,onChange:s,users:n,description:i}){const c=n.filter(a=>!a.user_id.startsWith("apikey-")).map(a=>({id:a.user_id,name:a.alias?`${a.user_id} (${a.alias})`:a.user_id})),[l,o]=m.useState(t),u=l.trim().toLowerCase(),j=c.filter(a=>!u||a.id.toLowerCase().includes(u)||a.name.toLowerCase().includes(u)).slice(0,50),p=a=>{const x=a.trim(),w=c.find(N=>N.id===x||N.name===x);return w?w.id:x},d=p(l),h=c.some(a=>a.id===d),f=d!==""&&!h?e.jsxs("span",{children:["Creates a new user ",e.jsx("code",{children:d}),"."]}):i??"Spend and budgets track against this user.";return e.jsxs(_.Root,{allowsCustomValue:!0,allowsEmptyCollection:!0,menuTrigger:"focus",inputValue:l,onInputChange:a=>{o(a),s(p(a))},onSelectionChange:a=>{if(a!=null){const x=String(a);o(x),s(x)}},className:"flex max-w-md flex-col gap-1",children:[e.jsx(U,{className:"text-sm font-medium text-[var(--otari-ink)]",children:"Owner"}),e.jsxs(_.InputGroup,{children:[e.jsx(q,{placeholder:"Pick a user, or type a new id…",autoComplete:"off","data-1p-ignore":!0,"data-lpignore":"true",onFocus:a=>a.currentTarget.select()}),e.jsx(_.Trigger,{})]}),e.jsx(_.Popover,{children:e.jsx(W,{items:j,className:"max-h-72 overflow-auto",children:a=>e.jsx(G,{id:a.id,textValue:a.name,children:a.name})})}),e.jsx(Y,{className:"text-xs text-[var(--otari-muted)]",children:f})]})}function L(t){if(!t)return"—";const s=new Date(t);return Number.isNaN(s.getTime())?"—":s.toLocaleDateString()}function se(t){if(!t)return null;const s=new Date(t).getTime();if(Number.isNaN(s))return null;const n=Math.round((s-Date.now())/1e3),i=Math.abs(n),c=[["day",86400],["hour",3600],["minute",60]],l=new Intl.RelativeTimeFormat(void 0,{numeric:"auto"});for(const[o,u]of c)if(i>=u)return l.format(Math.round(n/u),o);return l.format(n,"second")}function ne(t){if(!t.expires_at)return!1;const s=new Date(t.expires_at).getTime();return!Number.isNaN(s)&&sString(i).padStart(2,"0");return`${s.getFullYear()}-${n(s.getMonth()+1)}-${n(s.getDate())}T${n(s.getHours())}:${n(s.getMinutes())}`}const ae=t=>(t??"").startsWith("apikey-");function I({label:t,value:s,multiline:n=!1,fieldRef:i}){const c=m.useRef(null),l=i??c,[o,u]=m.useState(!1),[j,p]=m.useState(!1),d=async()=>{var f,a,x;(f=l.current)==null||f.focus(),(a=l.current)==null||a.select();try{if((x=navigator.clipboard)!=null&&x.writeText){await navigator.clipboard.writeText(s),u(!0),p(!1),window.setTimeout(()=>u(!1),2e3);return}}catch{}p(!0)},h="w-full rounded-lg border border-[var(--otari-line)] bg-[var(--otari-bg)] px-3 py-2 font-mono text-xs text-[var(--otari-ink)]";return e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-xs font-medium text-[var(--otari-muted)]",children:t}),e.jsx(g,{size:"sm",variant:"outline",onPress:d,children:o?"Copied":"Copy"})]}),n?e.jsx("textarea",{ref:l,readOnly:!0,rows:s.split(` `).length,value:s,onFocus:f=>f.currentTarget.select(),className:`${h} resize-none whitespace-pre`}):e.jsx("input",{ref:l,readOnly:!0,value:s,onFocus:f=>f.currentTarget.select(),className:h}),e.jsx("span",{"aria-live":"polite",className:"text-xs text-green-700",children:o?"Copied to clipboard.":""}),j?e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"Selected. Press Ctrl/Cmd-C to copy."}):null]})}function ie({title:t,result:s,onClose:n}){const i=m.useRef(null),c=m.useRef(null),l=typeof window<"u"?window.location.origin:"",o=s.key;m.useEffect(()=>{var d,h;(d=c.current)==null||d.focus(),(h=c.current)==null||h.select()},[]);const u=d=>{var x;if(d.key!=="Tab")return;const h=(x=i.current)==null?void 0:x.querySelectorAll('button, input, textarea, a[href], [tabindex]:not([tabindex="-1"])');if(!h||h.length===0)return;const f=h[0],a=h[h.length-1];d.shiftKey&&document.activeElement===f?(d.preventDefault(),a.focus()):!d.shiftKey&&document.activeElement===a&&(d.preventDefault(),f.focus())},j=[`curl ${l}/v1/chat/completions \\`,` -H "Otari-Key: ${o}" \\`,' -H "Content-Type: application/json" \\',` -d '{"model": "your-model", "messages": [{"role": "user", "content": "Hello"}]}'`].join(` `),p=["from openai import OpenAI","",`client = OpenAI(base_url="${l}/v1", api_key="${o}")`,"resp = client.chat.completions.create(",' model="your-model",',' messages=[{"role": "user", "content": "Hello"}],',")","print(resp.choices[0].message.content)"].join(` `);return e.jsx("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4",role:"presentation",children:e.jsxs("div",{ref:i,role:"dialog","aria-modal":"true","aria-labelledby":"reveal-title",onKeyDown:u,className:"flex max-h-[90vh] w-full max-w-2xl flex-col gap-4 overflow-y-auto rounded-xl bg-[var(--otari-surface)] p-6 shadow-xl",children:[e.jsx("h2",{id:"reveal-title",className:"text-lg font-semibold text-[var(--otari-ink)]",children:t}),e.jsx(V,{tone:"warning",children:"Copy this key now. For security it is shown only once and cannot be retrieved later. If you lose it, use Regenerate to issue a new secret."}),e.jsxs("p",{className:"text-xs text-[var(--otari-muted)]",children:["Model access: ",A(s.allowed_models).text,"."]}),e.jsx(I,{label:"Secret key",value:o,fieldRef:c}),e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-sm font-medium text-[var(--otari-ink)]",children:"Make your first call"}),e.jsxs("p",{className:"text-xs text-[var(--otari-muted)]",children:["Replace ",e.jsx("code",{children:"your-model"})," with a model from the Models page."]})]}),e.jsx(I,{label:"curl",value:j,multiline:!0}),e.jsx(I,{label:"Python (OpenAI SDK)",value:p,multiline:!0})]}),e.jsx("div",{className:"flex justify-end",children:e.jsx(g,{variant:"primary",onPress:n,children:"I’ve saved this key"})})]})})}function R({trigger:t,message:s,confirmLabel:n,isPending:i,onConfirm:c}){const[l,o]=m.useState(!1);return l?e.jsxs("div",{className:"flex flex-col items-end gap-1.5 rounded-lg border border-amber-200 bg-amber-50 p-2 text-right",children:[e.jsx("span",{className:"max-w-xs text-xs text-amber-800",children:s}),e.jsxs("span",{className:"inline-flex gap-1",children:[e.jsx(g,{size:"sm",variant:"danger",isDisabled:i,onPress:c,children:n}),e.jsx(g,{size:"sm",variant:"ghost",isDisabled:i,onPress:()=>o(!1),children:"Cancel"})]})]}):e.jsx(g,{size:"sm",variant:"danger-soft",onPress:()=>o(!0),children:t})}function F({userId:t,users:s}){const n=t.trim();if(n==="")return e.jsx("p",{className:"text-xs text-[var(--otari-muted)]",children:"Choose an owner above to see the models this key can inherit."});const i=s.find(o=>o.user_id===n);if(!i)return e.jsxs("p",{className:"text-xs text-[var(--otari-muted)]",children:["New user ",e.jsx("code",{children:n})," starts unrestricted, so this key may allow any model."]});const{text:c}=A(i.allowed_models),l=i.allowed_models&&i.allowed_models.length>0?i.allowed_models.join(", "):null;return e.jsxs("p",{className:"text-xs text-[var(--otari-muted)]",children:["Owner ",e.jsx("code",{children:n})," allows ",e.jsx("span",{className:"font-medium text-[var(--otari-ink)]",children:c.toLowerCase()}),l?e.jsxs(e.Fragment,{children:[" (",e.jsx("span",{className:"font-mono",children:l}),")"]}):null,". This key inherits that, or narrows within it."]})}function le({onClose:t,onCreated:s}){const n=B(),i=M(),[c,l]=m.useState(""),[o,u]=m.useState(""),[j,p]=m.useState(!1),[d,h]=m.useState(""),[f,a]=m.useState(null),[x,w]=m.useState(!0),N=o!==""&&new Date(o).getTime(){if(n.isPending||!x||r)return;const S={key_name:c.trim()||null,user_id:d.trim(),expires_at:o?new Date(o).toISOString():null,allowed_models:f};n.mutate(S,{onSuccess:D=>{s(D),t()}})};return e.jsx(C,{children:e.jsxs(C.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsx("div",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:"Create API key"}),e.jsx(T,{error:n.error}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsx(k,{label:"Name",value:c,onChange:l,placeholder:"ci-bot",autoFocus:!0,description:"A label to recognize this key later."}),e.jsx(k,{label:"Expires (optional)",value:o,onChange:u,type:"datetime-local",description:N?e.jsx("span",{className:"text-red-700",children:"That time is in the past; the key would be rejected immediately."}):"Leave blank for a key that never expires."})]}),e.jsx(te,{value:d,onChange:h,users:i.data??[]}),e.jsx("button",{type:"button",className:"self-start text-xs font-medium text-[var(--otari-brand-dark)]",onClick:()=>p(S=>!S),children:j?"Hide advanced":"Advanced (restrict models)"}),j?e.jsxs("div",{className:"flex flex-col gap-4 rounded-lg border border-[var(--otari-line)] p-4",children:[e.jsx(F,{userId:d,users:i.data??[]}),e.jsx(O,{title:"Restrict this key's models",description:"By default this key inherits its owner's access. Optionally narrow it to a subset; a key can never exceed its owner's allowed models.",anyLabel:"Inherit owner access",initial:null,onChange:(S,D)=>{a(S),w(D)}})]}):null,e.jsxs("div",{className:"flex gap-2",children:[e.jsx(g,{variant:"primary",isDisabled:n.isPending||!x||r,onPress:b,children:n.isPending?"Creating…":"Create key"}),e.jsx(g,{variant:"ghost",onPress:t,children:"Cancel"})]})]})})}function oe({apiKey:t,onClose:s}){const n=E(),i=M(),[c,l]=m.useState(t.key_name??""),[o,u]=m.useState(re(t.expires_at)),[j,p]=m.useState(t.allowed_models),[d,h]=m.useState(!0),f=()=>{n.isPending||!d||n.mutate({id:t.id,body:{key_name:c.trim()||null,expires_at:o?new Date(o).toISOString():null,allowed_models:j}},{onSuccess:s})};return e.jsx(C,{children:e.jsxs(C.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsxs("div",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:["Edit ",e.jsx("code",{children:t.key_name??t.id})]}),e.jsx(T,{error:n.error}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsx(k,{label:"Name",value:c,onChange:l,placeholder:"ci-bot"}),e.jsx(k,{label:"Expires",value:o,onChange:u,type:"datetime-local",description:"Blank clears the expiry."})]}),t.user_id?e.jsx(F,{userId:t.user_id,users:i.data??[]}):null,e.jsx(O,{title:"Restrict this key's models",description:"This key inherits its owner's access by default. Narrow it to a subset here; it can never exceed the owner's allowed models.",anyLabel:"Inherit owner access",initial:t.allowed_models,onChange:(a,x)=>{p(a),h(x)}}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(g,{variant:"primary",isDisabled:n.isPending||!d,onPress:f,children:n.isPending?"Saving…":"Save changes"}),e.jsx(g,{variant:"ghost",onPress:s,children:"Cancel"})]})]})})}function ce({apiKey:t}){return t.is_active?ne(t)?e.jsx(P,{size:"sm",color:"warning",children:"Expired"}):e.jsx(P,{size:"sm",color:"accent",children:"Active"}):e.jsx(P,{size:"sm",color:"default",children:"Disabled"})}function de({allowed:t}){const{text:s,tone:n}=A(t),i=n==="danger"?"text-red-700 font-medium":n==="muted"?"text-[var(--otari-muted)]":"text-[var(--otari-brand-dark)] font-medium",c=t&&t.length>0?t.join(", "):void 0;return e.jsx("span",{className:`text-xs ${i}`,title:c,children:s})}function ue({onCreate:t}){return e.jsx(C,{children:e.jsxs(C.Content,{className:"flex flex-col gap-4 p-6",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-semibold text-[var(--otari-ink)]",children:"No API keys yet"}),e.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:"An API key authenticates callers to this gateway. Create one to make your first request; the secret is shown once, so keep it somewhere safe."})]}),e.jsx("div",{children:e.jsx(g,{variant:"primary",onPress:t,children:"Create your first key"})})]})})}function ve(){const t=$(),s=E(),n=z(),i=K(),[c,l]=m.useState(!1),[o,u]=m.useState(null),[j,p]=m.useState(null),d=t.data??[],h=t.isLoading,f=d.find(r=>r.id===o)??null,a=!h&&d.length===0&&!c,x=r=>r.key_name??r.id,w=(r,b)=>s.mutate({id:r.id,body:{is_active:b}}),N=r=>n.mutate(r.id,{onSuccess:b=>p({title:`New secret for ${x(r)}`,result:b})});return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(H,{title:"API keys",description:"Issue and revoke the keys that authenticate callers to this gateway. Secrets are shown once at creation.",action:c?null:e.jsx(g,{variant:"primary",onPress:()=>{u(null),l(!0)},children:"Create key"})}),e.jsx(T,{error:t.error??s.error??n.error??i.error}),a?e.jsx(ue,{onCreate:()=>{u(null),l(!0)}}):null,c?e.jsx(le,{onClose:()=>l(!1),onCreated:r=>p({title:"API key created",result:r})}):null,f?e.jsx(oe,{apiKey:f,onClose:()=>u(null)},f.id):null,e.jsxs(J,{children:[e.jsx(Q,{children:e.jsxs("tr",{children:[e.jsx(v,{children:"Name"}),e.jsx(v,{children:"Status"}),e.jsx(v,{children:"Owner"}),e.jsx(v,{children:"Key"}),e.jsx(v,{children:"Created"}),e.jsx(v,{children:"Last used"}),e.jsx(v,{children:"Expires"}),e.jsx(v,{className:"text-right",children:"Actions"})]})}),e.jsx("tbody",{children:h?e.jsx(X,{colSpan:8}):d.length===0?e.jsx(Z,{colSpan:8,children:"No API keys yet. Create one to authenticate a caller."}):d.map(r=>e.jsxs(ee,{selected:o===r.id,onClick:()=>{l(!1),u(r.id)},children:[e.jsx(y,{className:"font-medium text-[var(--otari-ink)]",children:e.jsxs("div",{className:"flex flex-col gap-0.5",children:[e.jsx("span",{children:r.key_name??e.jsx("span",{className:"text-[var(--otari-muted)]",children:"(unnamed)"})}),e.jsx(de,{allowed:r.allowed_models})]})}),e.jsx(y,{children:e.jsx(ce,{apiKey:r})}),e.jsx(y,{className:"text-[var(--otari-muted)]",children:ae(r.user_id)?e.jsx("span",{className:"inline-flex items-center gap-1.5",children:e.jsx(P,{size:"sm",color:"default",children:"virtual"})}):e.jsx("code",{className:"text-xs",children:r.user_id??"—"})}),e.jsx(y,{children:e.jsx("code",{className:"text-xs text-[var(--otari-muted)]",children:r.key_prefix?`${r.key_prefix}…`:"—"})}),e.jsx(y,{className:"text-[var(--otari-muted)]",children:L(r.created_at)}),e.jsx(y,{className:"text-[var(--otari-muted)]",children:se(r.last_used_at)??"never"}),e.jsx(y,{className:"text-[var(--otari-muted)]",children:e.jsx("span",{title:r.expires_at?new Date(r.expires_at).toLocaleString():void 0,children:r.expires_at?L(r.expires_at):"never"})}),e.jsx(y,{children:e.jsxs("div",{className:"flex items-center justify-end gap-1.5",onClick:b=>b.stopPropagation(),children:[r.is_active?e.jsx(g,{size:"sm",variant:"outline",isDisabled:s.isPending,onPress:()=>w(r,!1),children:"Disable"}):e.jsx(g,{size:"sm",variant:"outline",isDisabled:s.isPending,onPress:()=>w(r,!0),children:"Enable"}),e.jsx(g,{size:"sm",variant:"ghost",onPress:()=>{l(!1),u(r.id)},children:"Edit"}),e.jsx(R,{trigger:"Regenerate",confirmLabel:"Regenerate",isPending:n.isPending,message:e.jsxs(e.Fragment,{children:["Regenerate the secret for ",e.jsx("strong",{children:x(r)}),"? The current secret stops working immediately, with no grace period."]}),onConfirm:()=>N(r)}),r.is_active?null:e.jsx(R,{trigger:"Delete",confirmLabel:"Delete permanently",isPending:i.isPending,message:e.jsxs(e.Fragment,{children:["Permanently delete ",e.jsx("strong",{children:x(r)}),"? This removes the key and unlinks its usage history. Cannot be undone."]}),onConfirm:()=>i.mutate(r.id)})]})})]},r.id))})]}),j?e.jsx(ie,{title:j.title,result:j.result,onClose:()=>{p(null),n.reset()}}):null]})}export{ve as KeysPage}; diff --git a/src/gateway/static/dashboard/assets/ModelScopeControl-DTCXvnvU.js b/src/gateway/static/dashboard/assets/ModelScopeControl-CkKcIwGe.js similarity index 98% rename from src/gateway/static/dashboard/assets/ModelScopeControl-DTCXvnvU.js rename to src/gateway/static/dashboard/assets/ModelScopeControl-CkKcIwGe.js index e8b444df..9466aec5 100644 --- a/src/gateway/static/dashboard/assets/ModelScopeControl-DTCXvnvU.js +++ b/src/gateway/static/dashboard/assets/ModelScopeControl-CkKcIwGe.js @@ -1 +1 @@ -import{j as t}from"./tanstack-query-1t81HyiD.js";import{r as n}from"./react-dgEcD0HR.js";import{J as A,e as $,f as P}from"./index-DHQmS-9o.js";import{C as d,I as R,a as T,b as V}from"./heroui-BX6JwHY-.js";function q(r){return r===null?"any":r.length===0?"block":"only"}const O=50;function Q({initial:r,onChange:m,title:N="Model access",description:w,anyLabel:C="Any model"}){const x=A(),u=$(),v=P(),[i,S]=n.useState(q(r)),[a,g]=n.useState(r??[]),[p,y]=n.useState(""),f=n.useMemo(()=>{var j,k;const e=new Set,s=[],l=(o,c)=>{o&&!e.has(o)&&(e.add(o),s.push({id:o,label:c}))};for(const o of((j=x.data)==null?void 0:j.providers)??[])l(`${o.instance}:*`,`${o.instance}:* · all ${o.instance} models`);for(const o of((k=u.data)==null?void 0:k.providers)??[])for(const c of o.models)l(c.key,c.key);for(const o of v.data??[])l(o.target,`${o.name} · alias`);return s},[x.data,u.data,v.data]),L=n.useMemo(()=>{const e=p.trim().toLowerCase();return f.filter(s=>!a.includes(s.id)).filter(s=>!e||s.id.toLowerCase().includes(e)||s.label.toLowerCase().includes(e)).slice(0,O)},[f,a,p]),h=(e,s)=>{e==="any"?m(null,!0):e==="block"?m([],!0):m(s,s.length>0)},B=e=>{S(e),h(e,a)},M=e=>{const s=a.includes(e)?a:[...a,e];g(s),y(""),h("only",s)},E=e=>{const s=a.filter(l=>l!==e);g(s),h("only",s)},b=(e,s)=>t.jsx("button",{type:"button","aria-pressed":i===e,onClick:()=>B(e),className:i===e?"rounded-md bg-white px-3 py-1.5 text-sm font-medium text-[var(--otari-ink)] shadow-sm":"rounded-md px-3 py-1.5 text-sm text-[var(--otari-muted)] hover:text-[var(--otari-ink)]",children:s}),I=!u.isLoading&&!x.isLoading&&f.length===0;return t.jsxs("div",{className:"flex flex-col gap-3",children:[t.jsxs("div",{children:[t.jsx("span",{className:"text-sm font-medium text-[var(--otari-ink)]",children:N}),t.jsx("p",{className:"text-xs text-[var(--otari-muted)]",children:w??"Which models this key may list and call. The master key is never restricted, so blocking a key cannot lock you out of the dashboard."})]}),t.jsxs("div",{className:"flex w-fit items-center gap-1 rounded-lg bg-[var(--otari-bg)] p-1",children:[b("any",C),b("only","Only selected"),b("block","Block all")]}),i==="block"?t.jsxs("div",{className:"rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-xs text-amber-800",children:["Blocked from ",t.jsx("strong",{children:"every"})," model until you change this access."]}):null,i==="only"?t.jsxs("div",{className:"flex flex-col gap-2",children:[t.jsx("div",{className:"flex flex-wrap gap-1.5",children:a.length===0?t.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"Pick at least one model below, or choose “Block all”."}):a.map(e=>t.jsxs("span",{className:"inline-flex items-center gap-1 rounded-full bg-[var(--otari-brand-tint)] px-2.5 py-1 font-mono text-xs text-[var(--otari-brand-dark)]",children:[e,t.jsx("button",{type:"button","aria-label":`Remove ${e}`,onClick:()=>E(e),className:"text-[var(--otari-brand-dark)] hover:text-red-700",children:"×"})]},e))}),I?t.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"No providers or models discovered yet. Configure a provider first, then scope this key."}):t.jsxs(d.Root,{allowsEmptyCollection:!0,menuTrigger:"input",inputValue:p,onInputChange:y,selectedKey:null,onSelectionChange:e=>{e!=null&&M(String(e))},className:"flex max-w-md flex-col gap-1",children:[t.jsxs(d.InputGroup,{children:[t.jsx(R,{"aria-label":"Add a model",placeholder:"Search providers, models, aliases…",autoComplete:"off"}),t.jsx(d.Trigger,{})]}),t.jsx(d.Popover,{children:t.jsx(T,{items:L,className:"max-h-72 overflow-auto",children:e=>t.jsx(V,{id:e.id,textValue:e.label,children:e.label})})})]})]}):null]})}function W(r){return r===null?{text:"All models",tone:"muted"}:r.length===0?{text:"No models",tone:"danger"}:{text:"Selected models",tone:"normal"}}export{Q as M,W as a}; +import{j as t}from"./tanstack-query-1t81HyiD.js";import{r as n}from"./react-dgEcD0HR.js";import{J as A,e as $,f as P}from"./index-DAVt9uB3.js";import{C as d,I as R,a as T,b as V}from"./heroui-BX6JwHY-.js";function q(r){return r===null?"any":r.length===0?"block":"only"}const O=50;function Q({initial:r,onChange:m,title:N="Model access",description:w,anyLabel:C="Any model"}){const x=A(),u=$(),v=P(),[i,S]=n.useState(q(r)),[a,g]=n.useState(r??[]),[p,y]=n.useState(""),f=n.useMemo(()=>{var j,k;const e=new Set,s=[],l=(o,c)=>{o&&!e.has(o)&&(e.add(o),s.push({id:o,label:c}))};for(const o of((j=x.data)==null?void 0:j.providers)??[])l(`${o.instance}:*`,`${o.instance}:* · all ${o.instance} models`);for(const o of((k=u.data)==null?void 0:k.providers)??[])for(const c of o.models)l(c.key,c.key);for(const o of v.data??[])l(o.target,`${o.name} · alias`);return s},[x.data,u.data,v.data]),L=n.useMemo(()=>{const e=p.trim().toLowerCase();return f.filter(s=>!a.includes(s.id)).filter(s=>!e||s.id.toLowerCase().includes(e)||s.label.toLowerCase().includes(e)).slice(0,O)},[f,a,p]),h=(e,s)=>{e==="any"?m(null,!0):e==="block"?m([],!0):m(s,s.length>0)},B=e=>{S(e),h(e,a)},M=e=>{const s=a.includes(e)?a:[...a,e];g(s),y(""),h("only",s)},E=e=>{const s=a.filter(l=>l!==e);g(s),h("only",s)},b=(e,s)=>t.jsx("button",{type:"button","aria-pressed":i===e,onClick:()=>B(e),className:i===e?"rounded-md bg-white px-3 py-1.5 text-sm font-medium text-[var(--otari-ink)] shadow-sm":"rounded-md px-3 py-1.5 text-sm text-[var(--otari-muted)] hover:text-[var(--otari-ink)]",children:s}),I=!u.isLoading&&!x.isLoading&&f.length===0;return t.jsxs("div",{className:"flex flex-col gap-3",children:[t.jsxs("div",{children:[t.jsx("span",{className:"text-sm font-medium text-[var(--otari-ink)]",children:N}),t.jsx("p",{className:"text-xs text-[var(--otari-muted)]",children:w??"Which models this key may list and call. The master key is never restricted, so blocking a key cannot lock you out of the dashboard."})]}),t.jsxs("div",{className:"flex w-fit items-center gap-1 rounded-lg bg-[var(--otari-bg)] p-1",children:[b("any",C),b("only","Only selected"),b("block","Block all")]}),i==="block"?t.jsxs("div",{className:"rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-xs text-amber-800",children:["Blocked from ",t.jsx("strong",{children:"every"})," model until you change this access."]}):null,i==="only"?t.jsxs("div",{className:"flex flex-col gap-2",children:[t.jsx("div",{className:"flex flex-wrap gap-1.5",children:a.length===0?t.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"Pick at least one model below, or choose “Block all”."}):a.map(e=>t.jsxs("span",{className:"inline-flex items-center gap-1 rounded-full bg-[var(--otari-brand-tint)] px-2.5 py-1 font-mono text-xs text-[var(--otari-brand-dark)]",children:[e,t.jsx("button",{type:"button","aria-label":`Remove ${e}`,onClick:()=>E(e),className:"text-[var(--otari-brand-dark)] hover:text-red-700",children:"×"})]},e))}),I?t.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"No providers or models discovered yet. Configure a provider first, then scope this key."}):t.jsxs(d.Root,{allowsEmptyCollection:!0,menuTrigger:"input",inputValue:p,onInputChange:y,selectedKey:null,onSelectionChange:e=>{e!=null&&M(String(e))},className:"flex max-w-md flex-col gap-1",children:[t.jsxs(d.InputGroup,{children:[t.jsx(R,{"aria-label":"Add a model",placeholder:"Search providers, models, aliases…",autoComplete:"off"}),t.jsx(d.Trigger,{})]}),t.jsx(d.Popover,{children:t.jsx(T,{items:L,className:"max-h-72 overflow-auto",children:e=>t.jsx(V,{id:e.id,textValue:e.label,children:e.label})})})]})]}):null]})}function W(r){return r===null?{text:"All models",tone:"muted"}:r.length===0?{text:"No models",tone:"danger"}:{text:"Selected models",tone:"normal"}}export{Q as M,W as a}; diff --git a/src/gateway/static/dashboard/assets/ModelsPage-CN4L8fzW.js b/src/gateway/static/dashboard/assets/ModelsPage-DwBDAaxV.js similarity index 99% rename from src/gateway/static/dashboard/assets/ModelsPage-CN4L8fzW.js rename to src/gateway/static/dashboard/assets/ModelsPage-DwBDAaxV.js index eff728f2..cb5da755 100644 --- a/src/gateway/static/dashboard/assets/ModelsPage-CN4L8fzW.js +++ b/src/gateway/static/dashboard/assets/ModelsPage-DwBDAaxV.js @@ -1 +1 @@ -import{j as e}from"./tanstack-query-1t81HyiD.js";import{i as rt,u as nt,r as c}from"./react-dgEcD0HR.js";import{v as at,w as st,e as lt,x as ct,P as ot,E as ut,F as E,I as dt,y as ne,z as pt,A as ht,B as xt,D as A,G as $e,H as Ee,C as Ae,h as me}from"./index-DHQmS-9o.js";import{T as mt,a as ft,d as Ce,b as re,L as vt,e as U,c as bt}from"./Table-CLdjdyTx.js";import{B as L,d as ke,f as K}from"./heroui-BX6JwHY-.js";function We(t){const i=t.indexOf(":");return i>0?t.slice(0,i):"—"}function gt(t,i=Date.now()){const r=new Map;for(const n of t){const a=r.get(n.model_key)??[];a.push(n),r.set(n.model_key,a)}const s=[];for(const n of r.values()){const a=[...n].sort((h,p)=>Date.parse(h.effective_at)-Date.parse(p.effective_at)),d=[...a].reverse().find(h=>Date.parse(h.effective_at)<=i);s.push(d??a[0])}return s.sort((n,a)=>n.model_key.localeCompare(a.model_key))}const _t="otari",Me=[{value:"vision",label:"Vision",test:t=>Array.isArray(t.input_modalities)&&t.input_modalities.includes("image")},{value:"tool_call",label:"Tool calling",test:t=>!!t.tool_call},{value:"reasoning",label:"Reasoning",test:t=>!!t.reasoning},{value:"structured_output",label:"Structured output",test:t=>!!t.structured_output},{value:"attachment",label:"Attachments",test:t=>!!t.attachment},{value:"audio",label:"Audio",test:t=>Array.isArray(t.input_modalities)&&t.input_modalities.includes("audio")},{value:"pdf",label:"PDF",test:t=>Array.isArray(t.input_modalities)&&t.input_modalities.includes("pdf")}],jt=[{key:"reasoning",label:"Reasoning"},{key:"tool_call",label:"Tool calling"},{key:"structured_output",label:"Structured output"},{key:"attachment",label:"Attachments"},{key:"temperature",label:"Temperature"}],Te={text:"Text",image:"Image",audio:"Audio",video:"Video",pdf:"PDF"},Pt=[{value:"0",label:"Any context"},{value:"8000",label:"≥ 8K"},{value:"32000",label:"≥ 32K"},{value:"128000",label:"≥ 128K"},{value:"200000",label:"≥ 200K"},{value:"1000000",label:"≥ 1M"}],yt=[{value:"",label:"Any price"},{value:"1",label:"≤ $1 / 1M in"},{value:"3",label:"≤ $3 / 1M in"},{value:"10",label:"≤ $10 / 1M in"},{value:"30",label:"≤ $30 / 1M in"}],Nt=[{value:"",label:"Base prices"},{value:"8000",label:"Compare at 8K"},{value:"128000",label:"Compare at 128K"},{value:"200000",label:"Compare at 200K"},{value:"500000",label:"Compare at 500K"},{value:"1000000",label:"Compare at 1M"}],St=[{value:"all",label:"Any release date"},{value:"365",label:"Past year"},{value:"730",label:"Past 2 years"},{value:"1095",label:"Past 3 years"}],Ct=1440*60*1e3;function Ie(t,i){const r=`${i}:`;return t.startsWith(r)?t.slice(r.length):t}function kt(t,i){const r={inputPrice:t.inputPrice,outputPrice:t.outputPrice,cacheReadPrice:t.cacheReadPrice,cacheWritePrice:t.cacheWritePrice,cacheWrite1hPrice:t.cacheWrite1hPrice};if(i==null)return r;const s=t.pricingTiers.filter(n=>n.min_input_tokens<=i).sort((n,a)=>a.min_input_tokens-n.min_input_tokens)[0];return s?{inputPrice:s.input_price_per_million??r.inputPrice,outputPrice:s.output_price_per_million??r.outputPrice,cacheReadPrice:s.cache_read_price_per_million??r.cacheReadPrice,cacheWritePrice:s.cache_write_price_per_million??r.cacheWritePrice,cacheWrite1hPrice:s.cache_write_1h_price_per_million??r.cacheWrite1hPrice}:r}function ae(t){const i=Number(t);return t.trim()!==""&&Number.isFinite(i)&&i>=0}function R(t){if(t.trim()==="")return!0;const i=Number(t);return Number.isFinite(i)&&i>=0}function V(t){return t.trim()===""?null:Number(t)}function De(t){return t.map((i,r)=>({id:r,minInputTokens:String(i.min_input_tokens),input:i.input_price_per_million==null?"":String(i.input_price_per_million),output:i.output_price_per_million==null?"":String(i.output_price_per_million),cacheRead:i.cache_read_price_per_million==null?"":String(i.cache_read_price_per_million),cacheWrite:i.cache_write_price_per_million==null?"":String(i.cache_write_price_per_million),cacheWrite1h:i.cache_write_1h_price_per_million==null?"":String(i.cache_write_1h_price_per_million)}))}function Oe(t){const i=new Set;return t.every(r=>{const s=Number(r.minInputTokens),n=[r.input,r.output,r.cacheRead,r.cacheWrite,r.cacheWrite1h].some(a=>a.trim()!=="");return!Number.isInteger(s)||s<=0||i.has(s)||!n?!1:(i.add(s),[r.input,r.output,r.cacheRead,r.cacheWrite,r.cacheWrite1h].every(R))})}function Fe(t){return t.map(i=>({min_input_tokens:Number(i.minInputTokens),...i.input.trim()===""?{}:{input_price_per_million:Number(i.input)},...i.output.trim()===""?{}:{output_price_per_million:Number(i.output)},...i.cacheRead.trim()===""?{}:{cache_read_price_per_million:Number(i.cacheRead)},...i.cacheWrite.trim()===""?{}:{cache_write_price_per_million:Number(i.cacheWrite)},...i.cacheWrite1h.trim()===""?{}:{cache_write_1h_price_per_million:Number(i.cacheWrite1h)}}))}function j({value:t,onChange:i,ariaLabel:r}){return e.jsx("input",{type:"number",step:"any",min:"0",inputMode:"decimal","aria-label":r,value:t,onChange:s=>i(s.target.value),className:"w-28 rounded-md border border-[var(--otari-line)] bg-white px-2 py-1 text-right text-sm tabular-nums focus:border-[var(--otari-brand)] focus:outline-none"})}function ze({tiers:t,onChange:i}){const r=(n,a,d)=>{i(t.map(h=>h.id===n?{...h,[a]:d}:h))},s=()=>{const n=t.reduce((a,d)=>Math.max(a,d.id),-1)+1;i([...t,{id:n,minInputTokens:"128000",input:"",output:"",cacheRead:"",cacheWrite:"",cacheWrite1h:""}])};return e.jsxs("div",{className:"flex flex-col gap-2 rounded-lg border border-[var(--otari-line)] p-3",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-xs font-medium text-[var(--otari-ink)]",children:"Long-context price tiers"}),e.jsx("p",{className:"text-xs text-[var(--otari-muted)]",children:"At a threshold, listed rates replace the base rate for the whole request."})]}),e.jsx(L,{size:"sm",variant:"outline",onPress:s,children:"Add tier"})]}),t.map(n=>e.jsxs("div",{className:"flex flex-wrap items-end gap-2 border-t border-[var(--otari-line)] pt-2",children:[e.jsxs("label",{className:"flex flex-col gap-1 text-xs text-[var(--otari-muted)]",children:["Context ≥ tokens",e.jsx("input",{type:"number",min:"1",step:"1",inputMode:"numeric","aria-label":"Tier context threshold",value:n.minInputTokens,onChange:a=>r(n.id,"minInputTokens",a.target.value),className:"w-28 rounded-md border border-[var(--otari-line)] bg-white px-2 py-1 text-right text-sm tabular-nums focus:border-[var(--otari-brand)] focus:outline-none"})]}),e.jsxs("label",{className:"flex flex-col gap-1 text-xs text-[var(--otari-muted)]",children:["Input",e.jsx(j,{value:n.input,onChange:a=>r(n.id,"input",a),ariaLabel:"Tier input price"})]}),e.jsxs("label",{className:"flex flex-col gap-1 text-xs text-[var(--otari-muted)]",children:["Output",e.jsx(j,{value:n.output,onChange:a=>r(n.id,"output",a),ariaLabel:"Tier output price"})]}),e.jsxs("label",{className:"flex flex-col gap-1 text-xs text-[var(--otari-muted)]",children:["Cache read",e.jsx(j,{value:n.cacheRead,onChange:a=>r(n.id,"cacheRead",a),ariaLabel:"Tier cache read price"})]}),e.jsxs("label",{className:"flex flex-col gap-1 text-xs text-[var(--otari-muted)]",children:["Cache write",e.jsx(j,{value:n.cacheWrite,onChange:a=>r(n.id,"cacheWrite",a),ariaLabel:"Tier cache write price"})]}),e.jsxs("label",{className:"flex flex-col gap-1 text-xs text-[var(--otari-muted)]",children:["1h write",e.jsx(j,{value:n.cacheWrite1h,onChange:a=>r(n.id,"cacheWrite1h",a),ariaLabel:"Tier 1 hour cache write price"})]}),e.jsx(L,{size:"sm",variant:"ghost",onPress:()=>i(t.filter(a=>a.id!==n.id)),children:"Remove"})]},n.id))]})}function Wt({source:t}){return t==="configured"?e.jsx(K,{size:"sm",color:"default",children:"configured"}):t==="default"||t==="alias"?e.jsx(K,{size:"sm",color:"accent",children:t}):e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"not priced"})}function se({label:t,tone:i="info",children:r}){const s=c.useId();return e.jsxs("span",{className:"group relative inline-flex items-center font-normal normal-case",children:[e.jsx("button",{type:"button","aria-label":t,"aria-describedby":s,className:`inline-flex h-4 w-4 items-center justify-center rounded-full border text-[10px] leading-none ${i==="warning"?"border-[#c2843a] text-[#b45309]":"border-[var(--otari-line)] text-[var(--otari-muted)] hover:border-[var(--otari-brand)] hover:text-[var(--otari-brand)]"}`,children:"i"}),e.jsx("span",{id:s,role:"tooltip",className:"pointer-events-none absolute top-full right-0 z-20 mt-1.5 w-72 rounded-lg border border-[var(--otari-line)] bg-[var(--otari-surface)] px-3 py-2 text-left text-xs font-normal whitespace-normal break-words text-[var(--otari-ink)] opacity-0 shadow-lg transition-opacity group-hover:opacity-100 group-focus-within:opacity-100",children:r})]})}function Mt(){const t=xt();return t.data?t.data.default_pricing?e.jsx(se,{label:"How unpriced models are metered",tone:"info",children:"Default pricing is on: models without a configured price are metered using community-maintained rates (the bundled genai-prices dataset). Set a price to override the fallback."}):e.jsxs(se,{label:"How unpriced models are metered",tone:"warning",children:["Default pricing is off: only models with a configured price are metered.",t.data.require_pricing?" Requests for any other model are rejected (HTTP 402) because require_pricing is on.":" Other models are served without cost tracking."]}):null}function T({label:t,value:i}){return e.jsxs("div",{className:"flex items-baseline justify-between gap-3",children:[e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:t}),e.jsx("span",{className:"text-right text-sm text-[var(--otari-ink)] tabular-nums",children:i})]})}function ie({title:t,children:i}){return e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsx("span",{className:"text-xs font-semibold uppercase tracking-wide text-[var(--otari-muted)]",children:t}),i]})}function Tt({row:t}){const i=$e(),r=Ee(),[s,n]=c.useState(!1),[a,d]=c.useState(""),[h,p]=c.useState(""),[v,P]=c.useState(""),[m,S]=c.useState(""),[k,W]=c.useState(""),[D,y]=c.useState([]),Y=()=>{d(t.inputPrice==null?"":String(t.inputPrice)),p(t.outputPrice==null?"":String(t.outputPrice)),P(t.cacheReadPrice==null?"":String(t.cacheReadPrice)),S(t.cacheWritePrice==null?"":String(t.cacheWritePrice)),W(t.cacheWrite1hPrice==null?"":String(t.cacheWrite1hPrice)),y(De(t.pricingTiers)),n(!0)},M=ae(a)&&ae(h)&&R(v)&&R(m)&&R(k)&&Oe(D),G=()=>{M&&i.mutate({model_key:t.key,input_price_per_million:Number(a),output_price_per_million:Number(h),cache_read_price_per_million:V(v),cache_write_price_per_million:V(m),cache_write_1h_price_per_million:V(k),pricing_tiers:Fe(D)},{onSuccess:()=>n(!1)})};return s?e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"Input $ / 1M"}),e.jsx(j,{value:a,onChange:d,ariaLabel:`Input price for ${t.key}`})]}),e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"Output $ / 1M"}),e.jsx(j,{value:h,onChange:p,ariaLabel:`Output price for ${t.key}`})]}),e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"Cache read $ / 1M"}),e.jsx(j,{value:v,onChange:P,ariaLabel:`Cache read price for ${t.key}`})]}),e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"Cache write $ / 1M"}),e.jsx(j,{value:m,onChange:S,ariaLabel:`Cache write price for ${t.key}`})]}),e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"1h cache write $ / 1M"}),e.jsx(j,{value:k,onChange:W,ariaLabel:`1 hour cache write price for ${t.key}`})]}),e.jsx(ze,{tiers:D,onChange:y}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(L,{size:"sm",variant:"primary",isDisabled:i.isPending||!M,onPress:G,children:"Save"}),e.jsx(L,{size:"sm",variant:"ghost",isDisabled:i.isPending,onPress:()=>n(!1),children:"Cancel"})]}),i.error?e.jsx("span",{className:"text-xs text-red-700",children:me(i.error)}):null]}):e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsx(T,{label:"Input",value:t.inputPrice==null?"—":`${A(t.inputPrice)} / 1M`}),e.jsx(T,{label:"Output",value:t.outputPrice==null?"—":`${A(t.outputPrice)} / 1M`}),e.jsx(T,{label:"Cache read",value:t.cacheReadPrice==null?"—":`${A(t.cacheReadPrice)} / 1M`}),e.jsx(T,{label:"Cache write",value:t.cacheWritePrice==null?"—":`${A(t.cacheWritePrice)} / 1M`}),e.jsx(T,{label:"1h cache write",value:t.cacheWrite1hPrice==null?"—":`${A(t.cacheWrite1hPrice)} / 1M`}),e.jsx(T,{label:"Context tiers",value:t.pricingTiers.length?`${t.pricingTiers.length} configured`:"—"}),e.jsxs("div",{className:"flex items-center gap-2 pt-1",children:[e.jsx(L,{size:"sm",variant:"outline",onPress:Y,children:t.source==="configured"?"Edit price":"Set price"}),t.source==="configured"?e.jsxs(e.Fragment,{children:[e.jsx(Ae,{confirmLabel:"Reset",isPending:r.isPending,onConfirm:()=>r.mutate(t.key),children:"Reset"}),e.jsx(se,{label:"What reset does",children:"Removes the custom price. The model reverts to the default rate (genai-prices) when default pricing is on, otherwise it is metered at no cost."})]}):null,r.error?e.jsx("span",{className:"text-xs text-red-700",children:me(r.error)}):null]})]})}function It({row:t,metadata:i,metadataAvailable:r,onMakeAlias:s,onClose:n}){const a=(i==null?void 0:i.input_modalities)??[],d=(i==null?void 0:i.output_modalities)??[],h=jt.filter(({key:p})=>i==null?void 0:i[p]);return e.jsx(ke,{children:e.jsxs(ke.Content,{className:"flex flex-col gap-5 p-5",children:[e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("h2",{className:"text-base font-semibold break-all text-[var(--otari-ink)]",children:t.model}),i!=null&&i.deprecated?e.jsx(K,{size:"sm",color:"danger",children:"deprecated"}):null]}),e.jsxs("p",{className:"mt-1 text-xs break-all text-[var(--otari-muted)]",children:["Selector: ",e.jsx("code",{children:t.key})]}),i!=null&&i.family?e.jsx("p",{className:"text-xs text-[var(--otari-muted)]",children:i.family}):null]}),e.jsx("button",{type:"button","aria-label":"Close model details",onClick:n,className:"-mt-1 -mr-1 shrink-0 rounded-md px-1.5 py-0.5 text-lg leading-none text-[var(--otari-muted)] hover:bg-[var(--otari-bg)] hover:text-[var(--otari-ink)]",children:"✕"})]}),i!=null&&i.description?e.jsx("p",{className:"text-sm text-[var(--otari-ink)]",children:i.description}):null,e.jsxs(ie,{title:"Pricing",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Wt,{source:t.source}),t.isDiscovered?null:e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"not discovered"})]}),e.jsx(Tt,{row:t},t.key),e.jsx(L,{size:"sm",variant:"outline",onPress:()=>s(t.key),children:"Make an alias"})]}),e.jsxs(ie,{title:"Specs",children:[e.jsx(T,{label:"Context window",value:ne(t.contextWindow)}),e.jsx(T,{label:"Max output",value:ne((i==null?void 0:i.max_output_tokens)??null)}),e.jsx(T,{label:"Knowledge cutoff",value:(i==null?void 0:i.knowledge_cutoff)??"—"}),e.jsx(T,{label:"Released",value:ht(i==null?void 0:i.release_date)}),e.jsx(T,{label:"Open weights",value:i?i.open_weights?"Yes":"No":"—"})]}),e.jsx(ie,{title:"Modalities",children:a.length===0&&d.length===0?e.jsx("span",{className:"text-sm text-[var(--otari-muted)]",children:"Unknown."}):e.jsxs("div",{className:"flex flex-col gap-1.5 text-xs text-[var(--otari-muted)]",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-1",children:[e.jsx("span",{children:"In:"}),a.map(p=>e.jsx(K,{size:"sm",color:"default",children:Te[p]??p},p))]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-1",children:[e.jsx("span",{children:"Out:"}),d.map(p=>e.jsx(K,{size:"sm",color:"default",children:Te[p]??p},p))]})]})}),e.jsx(ie,{title:"Capabilities",children:h.length>0?e.jsx("div",{className:"flex flex-wrap gap-1.5",children:h.map(({key:p,label:v})=>e.jsx(K,{size:"sm",color:"default",children:v},p))}):e.jsx("span",{className:"text-sm text-[var(--otari-muted)]",children:r?"None reported.":"Extended metadata unavailable (models.dev disabled or unreachable)."})})]})})}const Lt=15,$t=[{value:"15",label:"15 per page"},{value:"25",label:"25 per page"},{value:"50",label:"50 per page"}];function Et({value:t,onChange:i,placeholder:r}){return e.jsx("input",{type:"search",value:t,onChange:s=>i(s.target.value),placeholder:r,"aria-label":r,className:"w-full max-w-xs rounded-md border border-[var(--otari-line)] bg-white px-3 py-1.5 text-sm focus:border-[var(--otari-brand)] focus:outline-none"})}function At({page:t,pageCount:i,total:r,pageSize:s,onPage:n,onPageSize:a}){return e.jsxs("div",{className:"flex items-center justify-between px-1 pt-1 text-sm text-[var(--otari-muted)]",children:[e.jsxs("span",{children:[i>1?`Page ${t+1} of ${i} · `:"",pt(r)," model",r===1?"":"s"]}),e.jsxs("span",{className:"inline-flex gap-2",children:[e.jsx(E,{ariaLabel:"Rows per page",value:String(s),onChange:d=>a(Number(d)),options:$t}),i>1?e.jsxs(e.Fragment,{children:[e.jsx(L,{size:"sm",variant:"outline",isDisabled:t===0,onPress:()=>n(t-1),children:"Prev"}),e.jsx(L,{size:"sm",variant:"outline",isDisabled:t>=i-1,onPress:()=>n(t+1),children:"Next"})]}):null]})]})}const Be="otari.dashboard.modelsSort",xe={col:"model",dir:"asc"},Dt=["model","released","input","output"];function Ot(){if(typeof window>"u")return xe;try{const t=window.localStorage.getItem(Be);if(!t)return xe;const i=JSON.parse(t);if(Dt.includes(i.col)&&(i.dir==="asc"||i.dir==="desc"))return{col:i.col,dir:i.dir}}catch{}return xe}function Le({label:t,col:i,sort:r,onSort:s,align:n="left",info:a}){const d=r.col===i;return e.jsx(re,{className:n==="right"?"text-right":void 0,ariaSort:d?r.dir==="asc"?"ascending":"descending":"none",children:e.jsxs("span",{className:`inline-flex items-center gap-1.5 ${n==="right"?"flex-row-reverse":""}`,children:[e.jsxs("button",{type:"button",onClick:()=>s(i),className:`inline-flex items-center gap-1 ${n==="right"?"flex-row-reverse":""} hover:text-[var(--otari-ink)]`,children:[t,e.jsx("span",{className:"text-[10px] text-[var(--otari-muted)]",children:d?r.dir==="asc"?"▲":"▼":"↕"})]}),a]})})}function Ft({row:t,onClose:i}){const r=$e(),s=Ee(),[n,a]=c.useState(t.inputPrice==null?"":String(t.inputPrice)),[d,h]=c.useState(t.outputPrice==null?"":String(t.outputPrice)),[p,v]=c.useState(t.cacheReadPrice==null?"":String(t.cacheReadPrice)),[P,m]=c.useState(t.cacheWritePrice==null?"":String(t.cacheWritePrice)),[S,k]=c.useState(t.cacheWrite1hPrice==null?"":String(t.cacheWrite1hPrice)),[W,D]=c.useState(De(t.pricingTiers)),y=ae(n)&&ae(d)&&R(p)&&R(P)&&R(S)&&Oe(W),Y=()=>{y&&r.mutate({model_key:t.key,input_price_per_million:Number(n),output_price_per_million:Number(d),cache_read_price_per_million:V(p),cache_write_price_per_million:V(P),cache_write_1h_price_per_million:V(S),pricing_tiers:Fe(W)},{onSuccess:i})};return e.jsxs("div",{className:"flex flex-col gap-3 px-4 py-3",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsx("span",{className:"text-xs font-medium break-all text-[var(--otari-muted)]",children:t.key}),e.jsxs("label",{className:"flex items-center gap-1.5 text-xs text-[var(--otari-muted)]",children:["Input $ / 1M",e.jsx(j,{value:n,onChange:a,ariaLabel:`Input price for ${t.key}`})]}),e.jsxs("label",{className:"flex items-center gap-1.5 text-xs text-[var(--otari-muted)]",children:["Output $ / 1M",e.jsx(j,{value:d,onChange:h,ariaLabel:`Output price for ${t.key}`})]}),e.jsxs("label",{className:"flex items-center gap-1.5 text-xs text-[var(--otari-muted)]",children:["Cache read $ / 1M",e.jsx(j,{value:p,onChange:v,ariaLabel:`Cache read price for ${t.key}`})]}),e.jsxs("label",{className:"flex items-center gap-1.5 text-xs text-[var(--otari-muted)]",children:["Cache write $ / 1M",e.jsx(j,{value:P,onChange:m,ariaLabel:`Cache write price for ${t.key}`})]}),e.jsxs("label",{className:"flex items-center gap-1.5 text-xs text-[var(--otari-muted)]",children:["1h cache write $ / 1M",e.jsx(j,{value:S,onChange:k,ariaLabel:`1 hour cache write price for ${t.key}`})]}),e.jsx(L,{size:"sm",variant:"primary",isDisabled:r.isPending||!y,onPress:Y,children:r.isPending?"Saving…":"Save"}),e.jsx(L,{size:"sm",variant:"ghost",isDisabled:r.isPending,onPress:i,children:"Cancel"}),t.source==="configured"?e.jsxs("span",{className:"inline-flex items-center gap-1",children:[e.jsx(Ae,{confirmLabel:"Reset",isPending:s.isPending,onConfirm:()=>s.mutate(t.key,{onSuccess:i}),children:"Reset"}),e.jsx(se,{label:"What reset does",children:"Removes the custom price. The model reverts to the default rate (genai-prices) when default pricing is on, otherwise it is metered at no cost."})]}):null,r.error||s.error?e.jsx("span",{className:"text-xs text-red-700",children:me(r.error??s.error)}):null]}),e.jsx(ze,{tiers:W,onChange:D})]})}function zt({primary:t,secondary:i,rowKey:r,primaryLabel:s,secondaryLabel:n,onEdit:a}){const d=(h,p)=>e.jsx("button",{type:"button","aria-label":`Edit ${p} price for ${r}`,className:"tabular-nums hover:text-[var(--otari-brand-dark)] hover:underline",onClick:v=>{v.stopPropagation(),a()},children:h==null?"—":A(h)});return e.jsxs("span",{className:"inline-flex items-center justify-end gap-1",children:[d(t,s),e.jsx("span",{className:"text-[var(--otari-muted)]",children:"/"}),d(i,n)]})}function Bt({rates:t,rowKey:i,onEdit:r}){const s=[t.cacheReadPrice==null?null:`R ${A(t.cacheReadPrice)}`,t.cacheWritePrice==null?null:`W ${A(t.cacheWritePrice)}`,t.cacheWrite1hPrice==null?null:`1h ${A(t.cacheWrite1hPrice)}`].filter(n=>n!==null);return e.jsx("button",{type:"button","aria-label":`Edit caching price for ${i}`,className:"max-w-44 text-right text-xs leading-5 text-[var(--otari-muted)] hover:text-[var(--otari-brand-dark)] hover:underline",onClick:n=>{n.stopPropagation(),r()},children:s.length>0?s.join(" · "):"Input-rate fallback"})}function Rt({row:t,onEdit:i}){const r=[...t.pricingTiers].sort((n,a)=>n.min_input_tokens-a.min_input_tokens).map(n=>ne(n.min_input_tokens)),s=r.length===0?"Base only":`${r.length} tier${r.length===1?"":"s"} · ≥ ${r.join(", ")}`;return e.jsx("button",{type:"button","aria-label":`Edit pricing policy for ${t.key}`,className:"max-w-40 text-right text-xs leading-5 text-[var(--otari-muted)] hover:text-[var(--otari-brand-dark)] hover:underline",onClick:n=>{n.stopPropagation(),i()},children:s})}function Kt({rows:t,isLoading:i,empty:r,sort:s,onSort:n,selectedKey:a,onSelect:d,pricingKey:h,onSetPricingKey:p,comparisonContextTokens:v}){const P=v==null?"Base":`at ${ne(v)}`;return e.jsxs(mt,{children:[e.jsx(ft,{children:e.jsxs(Ce,{children:[e.jsx(Le,{label:"Model",col:"model",sort:s,onSort:n}),e.jsx(re,{children:"Provider"}),e.jsx(Le,{label:`${P} in / out $ / 1M`,col:"input",sort:s,onSort:n,align:"right",info:e.jsx(Mt,{})}),e.jsxs(re,{className:"text-right",children:["Caching ",v==null?"policy":P]}),e.jsx(re,{className:"text-right",children:"Pricing policy"})]})}),e.jsx("tbody",{children:i?e.jsx(vt,{colSpan:5}):t.length>0?t.map(m=>{const S=()=>p(h===m.key?null:m.key),k=kt(m,v);return e.jsxs(c.Fragment,{children:[e.jsxs(Ce,{onClick:()=>d(m.key),selected:m.key===a,children:[e.jsxs(U,{className:"font-medium break-all",children:[m.model,e.jsx("span",{className:"sr-only",children:m.key})]}),e.jsx(U,{className:"text-[var(--otari-muted)]",children:m.provider}),e.jsx(U,{className:"text-right",children:e.jsx(zt,{primary:k.inputPrice,secondary:k.outputPrice,rowKey:m.key,primaryLabel:"input",secondaryLabel:"output",onEdit:S})}),e.jsx(U,{className:"text-right",children:e.jsx(Bt,{rates:k,rowKey:m.key,onEdit:S})}),e.jsx(U,{className:"text-right",children:e.jsx(Rt,{row:m,onEdit:S})})]}),h===m.key?e.jsx("tr",{className:"border-b border-[var(--otari-line)] bg-[var(--otari-bg)] last:border-b-0",children:e.jsx("td",{colSpan:5,children:e.jsx(Ft,{row:m,onClose:()=>p(null)})})}):null]},m.key)}):e.jsx(bt,{colSpan:5,children:r})})]})}function Vt({providers:t}){return t.length===0?null:e.jsxs(dt,{tone:"warning",children:["Could not list ",t.map(i=>i.provider).join(", "),". Check that provider's credentials in config.yml; its models are missing from the list below."]})}function Jt(){var je,Pe,ye;const t=rt(),[i]=nt(),r=at(),s=st(),n=lt(),a=ct(),[d,h]=c.useState(""),[p,v]=c.useState(0),[P,m]=c.useState(Lt),[S,k]=c.useState(null),[W,D]=c.useState(null),[y,Y]=c.useState(Ot);c.useEffect(()=>{try{window.localStorage.setItem(Be,JSON.stringify(y))}catch{}},[y]);const[M,G]=c.useState(i.get("provider")||"all"),[F,Re]=c.useState("all"),[H,Ke]=c.useState("all"),[q,Ve]=c.useState("all"),[le,Ye]=c.useState("0"),[J,He]=c.useState(""),[Z,qe]=c.useState("all"),[ce,we]=c.useState(""),O=((je=a.data)==null?void 0:je.models)??{},Ue=((Pe=a.data)==null?void 0:Pe.available)??!1,fe=c.useMemo(()=>{var l;return new Set((((l=n.data)==null?void 0:l.providers)??[]).flatMap(f=>f.models.map(o=>o.key)))},[n.data]),Ge=l=>{h(l),v(0)},z=l=>f=>{l(f),v(0)},Je=l=>{Y(f=>f.col===l?{col:l,dir:f.dir==="asc"?"desc":"asc"}:{col:l,dir:l==="released"?"desc":"asc"}),v(0)},X=c.useMemo(()=>{var C,g,_,$,I,B,Ne;const l=new Map(gt(s.data??[]).map(u=>[u.model_key,u])),f=[],o=new Set,b=(u,he,Se,x)=>{if(o.has(u))return;o.add(u);const N=l.get(u);f.push({key:u,model:Ie(he,Se),provider:Se,isDiscovered:fe.has(u),contextWindow:(x==null?void 0:x.contextWindow)??null,inputPrice:N?N.input_price_per_million:(x==null?void 0:x.inputPrice)??null,outputPrice:N?N.output_price_per_million:(x==null?void 0:x.outputPrice)??null,cacheReadPrice:N?N.cache_read_price_per_million:(x==null?void 0:x.cacheReadPrice)??null,cacheWritePrice:N?N.cache_write_price_per_million:(x==null?void 0:x.cacheWritePrice)??null,cacheWrite1hPrice:N?N.cache_write_1h_price_per_million??null:(x==null?void 0:x.cacheWrite1hPrice)??null,pricingTiers:N?N.pricing_tiers??[]:(x==null?void 0:x.pricingTiers)??[],source:N?"configured":(x==null?void 0:x.source)??"none"})};for(const u of((C=r.data)==null?void 0:C.data)??[]){if(u.owned_by===_t)continue;const he=u.pricing_source==="default"?"default":u.pricing?"configured":"none";b(u.id,u.id,u.owned_by||We(u.id),{key:u.id,model:u.id,provider:u.owned_by,contextWindow:u.context_window,inputPrice:((g=u.pricing)==null?void 0:g.input_price_per_million)??null,outputPrice:((_=u.pricing)==null?void 0:_.output_price_per_million)??null,cacheReadPrice:(($=u.pricing)==null?void 0:$.cache_read_price_per_million)??null,cacheWritePrice:((I=u.pricing)==null?void 0:I.cache_write_price_per_million)??null,cacheWrite1hPrice:((B=u.pricing)==null?void 0:B.cache_write_1h_price_per_million)??null,pricingTiers:((Ne=u.pricing)==null?void 0:Ne.pricing_tiers)??[],source:he})}for(const u of l.keys())b(u,u,We(u));return f},[r.data,s.data,fe]),Ze=c.useMemo(()=>new Map(X.map(l=>[l.key,l])),[X]),Q=c.useMemo(()=>{var o,b,C;const l=X.map(g=>{var _,$;return{...g,contextWindow:g.contextWindow??((_=O[g.key])==null?void 0:_.context_window)??null,releaseDate:(($=O[g.key])==null?void 0:$.release_date)??null}}),f=new Set(l.map(g=>g.key));for(const g of((o=n.data)==null?void 0:o.providers)??[])for(const _ of g.models)f.has(_.key)||(f.add(_.key),l.push({key:_.key,model:Ie(_.key,g.provider),provider:g.provider,isDiscovered:!0,contextWindow:((b=O[_.key])==null?void 0:b.context_window)??null,releaseDate:((C=O[_.key])==null?void 0:C.release_date)??null,inputPrice:null,outputPrice:null,cacheReadPrice:null,cacheWritePrice:null,cacheWrite1hPrice:null,pricingTiers:[],source:"none"}));return l},[X,n.data,O]),Xe=(((ye=n.data)==null?void 0:ye.providers)??[]).filter(l=>!l.ok),ee=c.useMemo(()=>{const l=Array.from(new Set(Q.map(f=>f.provider))).sort((f,o)=>f.localeCompare(o));return[{value:"all",label:"All providers"},...l.map(f=>({value:f,label:f}))]},[Q]);c.useEffect(()=>{M==="all"||ee.length<=1||ee.some(l=>l.value===M)||G("all")},[ee,M]);const w=d.trim().toLowerCase(),oe=Number(le)||0,ue=J===""?Number.POSITIVE_INFINITY:Number(J),Qe=ce===""?null:Number(ce),de=Z==="all"?null:Date.now()-Number(Z)*Ct,pe=c.useMemo(()=>{const l=o=>{if(w&&!o.key.toLowerCase().includes(w)&&!o.provider.toLowerCase().includes(w)||M!=="all"&&o.provider!==M||F==="configured"&&o.source!=="configured"||F==="default"&&o.source!=="default"||F==="priced"&&o.inputPrice==null||F==="unpriced"&&o.inputPrice!=null||H==="discovered"&&!o.isDiscovered||H==="custom"&&o.isDiscovered)return!1;if(q!=="all"){const b=Me.find(g=>g.value===q),C=O[o.key];if(!b||!C||!b.test(C))return!1}if(oe>0&&(o.contextWindow==null||o.contextWindowue))return!1;if(de!=null){const b=o.releaseDate?Date.parse(o.releaseDate):Number.NaN;if(Number.isNaN(b)||b{const C=y.dir==="asc"?1:-1;if(y.col==="model")return o.model.localeCompare(b.model)*C;if(y.col==="released"){const I=o.releaseDate??null,B=b.releaseDate??null;return!I&&!B?o.model.localeCompare(b.model):I?B?(IB?1:0)*C||o.model.localeCompare(b.model):-1:1}const g=I=>y.col==="input"?I.inputPrice:I.outputPrice,_=g(o),$=g(b);return _==null&&$==null?o.model.localeCompare(b.model):_==null?1:$==null?-1:(_-$)*C||o.model.localeCompare(b.model)};return Q.filter(l).sort(f)},[Q,w,M,F,H,q,oe,ue,de,O,y]),ve=pe.length,be=Math.max(1,Math.ceil(ve/P)),ge=Math.min(p,be-1),_e=ge*P,et=pe.slice(_e,_e+P),tt=r.isLoading||s.isLoading||n.isLoading,it=w!==""||M!=="all"||F!=="all"||H!=="all"||q!=="all"||le!=="0"||J!==""||Z!=="all"?"No models match your filters.":"No models yet. Add a provider on the Providers page, or price a model below.",te=W?pe.find(l=>l.key===W)??Ze.get(W)??null:null;return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(ot,{title:"Models",description:"Every model your providers can serve. Set a price on any model so budgets and usage tracking work."}),e.jsx(ut,{error:r.error??s.error??n.error??a.error}),e.jsxs("div",{className:`grid gap-4 lg:items-start ${te?"lg:grid-cols-[minmax(0,1fr)_360px]":"grid-cols-1"}`,children:[e.jsxs("div",{className:"flex min-w-0 flex-col gap-3",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx(Et,{value:d,onChange:Ge,placeholder:"Search models…"}),e.jsx(E,{ariaLabel:"Filter by provider",value:M,onChange:z(G),options:ee}),e.jsx(E,{ariaLabel:"Filter by pricing",value:F,onChange:z(Re),options:[{value:"all",label:"Any pricing"},{value:"configured",label:"Custom price"},{value:"default",label:"Default price"},{value:"priced",label:"Priced"},{value:"unpriced",label:"Unpriced"}]}),e.jsx(E,{ariaLabel:"Filter by source",value:H,onChange:z(Ke),options:[{value:"all",label:"Any source"},{value:"discovered",label:"Discovered"},{value:"custom",label:"Custom (not discovered)"}]}),e.jsx(E,{ariaLabel:"Filter by capability",value:q,onChange:z(Ve),options:[{value:"all",label:"Any capability"},...Me.map(l=>({value:l.value,label:l.label}))]}),e.jsx(E,{ariaLabel:"Minimum context window",value:le,onChange:z(Ye),options:Pt}),e.jsx(E,{ariaLabel:"Maximum input price",value:J,onChange:z(He),options:yt}),e.jsx(E,{ariaLabel:"Compare prices at context",value:ce,onChange:we,options:Nt}),e.jsx(E,{ariaLabel:"Filter by release date",value:Z,onChange:z(qe),options:St})]}),e.jsx(Vt,{providers:Xe}),e.jsx(Kt,{rows:et,isLoading:tt,empty:it,sort:y,onSort:Je,selectedKey:W,onSelect:D,pricingKey:S,onSetPricingKey:k,comparisonContextTokens:Qe}),e.jsx("div",{className:"flex flex-wrap items-center justify-between gap-2",children:e.jsx(At,{page:ge,pageCount:be,total:ve,pageSize:P,onPage:v,onPageSize:l=>{m(l),v(0)}})})]}),te?e.jsx("aside",{className:"lg:sticky lg:top-4",children:e.jsx(It,{row:te,metadata:O[te.key],metadataAvailable:Ue,onMakeAlias:l=>t(`/aliases?target=${encodeURIComponent(l)}`),onClose:()=>D(null)})}):null]})]})}export{Jt as ModelsPage}; +import{j as e}from"./tanstack-query-1t81HyiD.js";import{i as rt,u as nt,r as c}from"./react-dgEcD0HR.js";import{v as at,w as st,e as lt,x as ct,P as ot,E as ut,F as E,I as dt,y as ne,z as pt,A as ht,B as xt,D as A,G as $e,H as Ee,C as Ae,h as me}from"./index-DAVt9uB3.js";import{T as mt,a as ft,d as Ce,b as re,L as vt,e as U,c as bt}from"./Table-CLdjdyTx.js";import{B as L,d as ke,f as K}from"./heroui-BX6JwHY-.js";function We(t){const i=t.indexOf(":");return i>0?t.slice(0,i):"—"}function gt(t,i=Date.now()){const r=new Map;for(const n of t){const a=r.get(n.model_key)??[];a.push(n),r.set(n.model_key,a)}const s=[];for(const n of r.values()){const a=[...n].sort((h,p)=>Date.parse(h.effective_at)-Date.parse(p.effective_at)),d=[...a].reverse().find(h=>Date.parse(h.effective_at)<=i);s.push(d??a[0])}return s.sort((n,a)=>n.model_key.localeCompare(a.model_key))}const _t="otari",Me=[{value:"vision",label:"Vision",test:t=>Array.isArray(t.input_modalities)&&t.input_modalities.includes("image")},{value:"tool_call",label:"Tool calling",test:t=>!!t.tool_call},{value:"reasoning",label:"Reasoning",test:t=>!!t.reasoning},{value:"structured_output",label:"Structured output",test:t=>!!t.structured_output},{value:"attachment",label:"Attachments",test:t=>!!t.attachment},{value:"audio",label:"Audio",test:t=>Array.isArray(t.input_modalities)&&t.input_modalities.includes("audio")},{value:"pdf",label:"PDF",test:t=>Array.isArray(t.input_modalities)&&t.input_modalities.includes("pdf")}],jt=[{key:"reasoning",label:"Reasoning"},{key:"tool_call",label:"Tool calling"},{key:"structured_output",label:"Structured output"},{key:"attachment",label:"Attachments"},{key:"temperature",label:"Temperature"}],Te={text:"Text",image:"Image",audio:"Audio",video:"Video",pdf:"PDF"},Pt=[{value:"0",label:"Any context"},{value:"8000",label:"≥ 8K"},{value:"32000",label:"≥ 32K"},{value:"128000",label:"≥ 128K"},{value:"200000",label:"≥ 200K"},{value:"1000000",label:"≥ 1M"}],yt=[{value:"",label:"Any price"},{value:"1",label:"≤ $1 / 1M in"},{value:"3",label:"≤ $3 / 1M in"},{value:"10",label:"≤ $10 / 1M in"},{value:"30",label:"≤ $30 / 1M in"}],Nt=[{value:"",label:"Base prices"},{value:"8000",label:"Compare at 8K"},{value:"128000",label:"Compare at 128K"},{value:"200000",label:"Compare at 200K"},{value:"500000",label:"Compare at 500K"},{value:"1000000",label:"Compare at 1M"}],St=[{value:"all",label:"Any release date"},{value:"365",label:"Past year"},{value:"730",label:"Past 2 years"},{value:"1095",label:"Past 3 years"}],Ct=1440*60*1e3;function Ie(t,i){const r=`${i}:`;return t.startsWith(r)?t.slice(r.length):t}function kt(t,i){const r={inputPrice:t.inputPrice,outputPrice:t.outputPrice,cacheReadPrice:t.cacheReadPrice,cacheWritePrice:t.cacheWritePrice,cacheWrite1hPrice:t.cacheWrite1hPrice};if(i==null)return r;const s=t.pricingTiers.filter(n=>n.min_input_tokens<=i).sort((n,a)=>a.min_input_tokens-n.min_input_tokens)[0];return s?{inputPrice:s.input_price_per_million??r.inputPrice,outputPrice:s.output_price_per_million??r.outputPrice,cacheReadPrice:s.cache_read_price_per_million??r.cacheReadPrice,cacheWritePrice:s.cache_write_price_per_million??r.cacheWritePrice,cacheWrite1hPrice:s.cache_write_1h_price_per_million??r.cacheWrite1hPrice}:r}function ae(t){const i=Number(t);return t.trim()!==""&&Number.isFinite(i)&&i>=0}function R(t){if(t.trim()==="")return!0;const i=Number(t);return Number.isFinite(i)&&i>=0}function V(t){return t.trim()===""?null:Number(t)}function De(t){return t.map((i,r)=>({id:r,minInputTokens:String(i.min_input_tokens),input:i.input_price_per_million==null?"":String(i.input_price_per_million),output:i.output_price_per_million==null?"":String(i.output_price_per_million),cacheRead:i.cache_read_price_per_million==null?"":String(i.cache_read_price_per_million),cacheWrite:i.cache_write_price_per_million==null?"":String(i.cache_write_price_per_million),cacheWrite1h:i.cache_write_1h_price_per_million==null?"":String(i.cache_write_1h_price_per_million)}))}function Oe(t){const i=new Set;return t.every(r=>{const s=Number(r.minInputTokens),n=[r.input,r.output,r.cacheRead,r.cacheWrite,r.cacheWrite1h].some(a=>a.trim()!=="");return!Number.isInteger(s)||s<=0||i.has(s)||!n?!1:(i.add(s),[r.input,r.output,r.cacheRead,r.cacheWrite,r.cacheWrite1h].every(R))})}function Fe(t){return t.map(i=>({min_input_tokens:Number(i.minInputTokens),...i.input.trim()===""?{}:{input_price_per_million:Number(i.input)},...i.output.trim()===""?{}:{output_price_per_million:Number(i.output)},...i.cacheRead.trim()===""?{}:{cache_read_price_per_million:Number(i.cacheRead)},...i.cacheWrite.trim()===""?{}:{cache_write_price_per_million:Number(i.cacheWrite)},...i.cacheWrite1h.trim()===""?{}:{cache_write_1h_price_per_million:Number(i.cacheWrite1h)}}))}function j({value:t,onChange:i,ariaLabel:r}){return e.jsx("input",{type:"number",step:"any",min:"0",inputMode:"decimal","aria-label":r,value:t,onChange:s=>i(s.target.value),className:"w-28 rounded-md border border-[var(--otari-line)] bg-white px-2 py-1 text-right text-sm tabular-nums focus:border-[var(--otari-brand)] focus:outline-none"})}function ze({tiers:t,onChange:i}){const r=(n,a,d)=>{i(t.map(h=>h.id===n?{...h,[a]:d}:h))},s=()=>{const n=t.reduce((a,d)=>Math.max(a,d.id),-1)+1;i([...t,{id:n,minInputTokens:"128000",input:"",output:"",cacheRead:"",cacheWrite:"",cacheWrite1h:""}])};return e.jsxs("div",{className:"flex flex-col gap-2 rounded-lg border border-[var(--otari-line)] p-3",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-xs font-medium text-[var(--otari-ink)]",children:"Long-context price tiers"}),e.jsx("p",{className:"text-xs text-[var(--otari-muted)]",children:"At a threshold, listed rates replace the base rate for the whole request."})]}),e.jsx(L,{size:"sm",variant:"outline",onPress:s,children:"Add tier"})]}),t.map(n=>e.jsxs("div",{className:"flex flex-wrap items-end gap-2 border-t border-[var(--otari-line)] pt-2",children:[e.jsxs("label",{className:"flex flex-col gap-1 text-xs text-[var(--otari-muted)]",children:["Context ≥ tokens",e.jsx("input",{type:"number",min:"1",step:"1",inputMode:"numeric","aria-label":"Tier context threshold",value:n.minInputTokens,onChange:a=>r(n.id,"minInputTokens",a.target.value),className:"w-28 rounded-md border border-[var(--otari-line)] bg-white px-2 py-1 text-right text-sm tabular-nums focus:border-[var(--otari-brand)] focus:outline-none"})]}),e.jsxs("label",{className:"flex flex-col gap-1 text-xs text-[var(--otari-muted)]",children:["Input",e.jsx(j,{value:n.input,onChange:a=>r(n.id,"input",a),ariaLabel:"Tier input price"})]}),e.jsxs("label",{className:"flex flex-col gap-1 text-xs text-[var(--otari-muted)]",children:["Output",e.jsx(j,{value:n.output,onChange:a=>r(n.id,"output",a),ariaLabel:"Tier output price"})]}),e.jsxs("label",{className:"flex flex-col gap-1 text-xs text-[var(--otari-muted)]",children:["Cache read",e.jsx(j,{value:n.cacheRead,onChange:a=>r(n.id,"cacheRead",a),ariaLabel:"Tier cache read price"})]}),e.jsxs("label",{className:"flex flex-col gap-1 text-xs text-[var(--otari-muted)]",children:["Cache write",e.jsx(j,{value:n.cacheWrite,onChange:a=>r(n.id,"cacheWrite",a),ariaLabel:"Tier cache write price"})]}),e.jsxs("label",{className:"flex flex-col gap-1 text-xs text-[var(--otari-muted)]",children:["1h write",e.jsx(j,{value:n.cacheWrite1h,onChange:a=>r(n.id,"cacheWrite1h",a),ariaLabel:"Tier 1 hour cache write price"})]}),e.jsx(L,{size:"sm",variant:"ghost",onPress:()=>i(t.filter(a=>a.id!==n.id)),children:"Remove"})]},n.id))]})}function Wt({source:t}){return t==="configured"?e.jsx(K,{size:"sm",color:"default",children:"configured"}):t==="default"||t==="alias"?e.jsx(K,{size:"sm",color:"accent",children:t}):e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"not priced"})}function se({label:t,tone:i="info",children:r}){const s=c.useId();return e.jsxs("span",{className:"group relative inline-flex items-center font-normal normal-case",children:[e.jsx("button",{type:"button","aria-label":t,"aria-describedby":s,className:`inline-flex h-4 w-4 items-center justify-center rounded-full border text-[10px] leading-none ${i==="warning"?"border-[#c2843a] text-[#b45309]":"border-[var(--otari-line)] text-[var(--otari-muted)] hover:border-[var(--otari-brand)] hover:text-[var(--otari-brand)]"}`,children:"i"}),e.jsx("span",{id:s,role:"tooltip",className:"pointer-events-none absolute top-full right-0 z-20 mt-1.5 w-72 rounded-lg border border-[var(--otari-line)] bg-[var(--otari-surface)] px-3 py-2 text-left text-xs font-normal whitespace-normal break-words text-[var(--otari-ink)] opacity-0 shadow-lg transition-opacity group-hover:opacity-100 group-focus-within:opacity-100",children:r})]})}function Mt(){const t=xt();return t.data?t.data.default_pricing?e.jsx(se,{label:"How unpriced models are metered",tone:"info",children:"Default pricing is on: models without a configured price are metered using community-maintained rates (the bundled genai-prices dataset). Set a price to override the fallback."}):e.jsxs(se,{label:"How unpriced models are metered",tone:"warning",children:["Default pricing is off: only models with a configured price are metered.",t.data.require_pricing?" Requests for any other model are rejected (HTTP 402) because require_pricing is on.":" Other models are served without cost tracking."]}):null}function T({label:t,value:i}){return e.jsxs("div",{className:"flex items-baseline justify-between gap-3",children:[e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:t}),e.jsx("span",{className:"text-right text-sm text-[var(--otari-ink)] tabular-nums",children:i})]})}function ie({title:t,children:i}){return e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsx("span",{className:"text-xs font-semibold uppercase tracking-wide text-[var(--otari-muted)]",children:t}),i]})}function Tt({row:t}){const i=$e(),r=Ee(),[s,n]=c.useState(!1),[a,d]=c.useState(""),[h,p]=c.useState(""),[v,P]=c.useState(""),[m,S]=c.useState(""),[k,W]=c.useState(""),[D,y]=c.useState([]),Y=()=>{d(t.inputPrice==null?"":String(t.inputPrice)),p(t.outputPrice==null?"":String(t.outputPrice)),P(t.cacheReadPrice==null?"":String(t.cacheReadPrice)),S(t.cacheWritePrice==null?"":String(t.cacheWritePrice)),W(t.cacheWrite1hPrice==null?"":String(t.cacheWrite1hPrice)),y(De(t.pricingTiers)),n(!0)},M=ae(a)&&ae(h)&&R(v)&&R(m)&&R(k)&&Oe(D),G=()=>{M&&i.mutate({model_key:t.key,input_price_per_million:Number(a),output_price_per_million:Number(h),cache_read_price_per_million:V(v),cache_write_price_per_million:V(m),cache_write_1h_price_per_million:V(k),pricing_tiers:Fe(D)},{onSuccess:()=>n(!1)})};return s?e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"Input $ / 1M"}),e.jsx(j,{value:a,onChange:d,ariaLabel:`Input price for ${t.key}`})]}),e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"Output $ / 1M"}),e.jsx(j,{value:h,onChange:p,ariaLabel:`Output price for ${t.key}`})]}),e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"Cache read $ / 1M"}),e.jsx(j,{value:v,onChange:P,ariaLabel:`Cache read price for ${t.key}`})]}),e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"Cache write $ / 1M"}),e.jsx(j,{value:m,onChange:S,ariaLabel:`Cache write price for ${t.key}`})]}),e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"1h cache write $ / 1M"}),e.jsx(j,{value:k,onChange:W,ariaLabel:`1 hour cache write price for ${t.key}`})]}),e.jsx(ze,{tiers:D,onChange:y}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(L,{size:"sm",variant:"primary",isDisabled:i.isPending||!M,onPress:G,children:"Save"}),e.jsx(L,{size:"sm",variant:"ghost",isDisabled:i.isPending,onPress:()=>n(!1),children:"Cancel"})]}),i.error?e.jsx("span",{className:"text-xs text-red-700",children:me(i.error)}):null]}):e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsx(T,{label:"Input",value:t.inputPrice==null?"—":`${A(t.inputPrice)} / 1M`}),e.jsx(T,{label:"Output",value:t.outputPrice==null?"—":`${A(t.outputPrice)} / 1M`}),e.jsx(T,{label:"Cache read",value:t.cacheReadPrice==null?"—":`${A(t.cacheReadPrice)} / 1M`}),e.jsx(T,{label:"Cache write",value:t.cacheWritePrice==null?"—":`${A(t.cacheWritePrice)} / 1M`}),e.jsx(T,{label:"1h cache write",value:t.cacheWrite1hPrice==null?"—":`${A(t.cacheWrite1hPrice)} / 1M`}),e.jsx(T,{label:"Context tiers",value:t.pricingTiers.length?`${t.pricingTiers.length} configured`:"—"}),e.jsxs("div",{className:"flex items-center gap-2 pt-1",children:[e.jsx(L,{size:"sm",variant:"outline",onPress:Y,children:t.source==="configured"?"Edit price":"Set price"}),t.source==="configured"?e.jsxs(e.Fragment,{children:[e.jsx(Ae,{confirmLabel:"Reset",isPending:r.isPending,onConfirm:()=>r.mutate(t.key),children:"Reset"}),e.jsx(se,{label:"What reset does",children:"Removes the custom price. The model reverts to the default rate (genai-prices) when default pricing is on, otherwise it is metered at no cost."})]}):null,r.error?e.jsx("span",{className:"text-xs text-red-700",children:me(r.error)}):null]})]})}function It({row:t,metadata:i,metadataAvailable:r,onMakeAlias:s,onClose:n}){const a=(i==null?void 0:i.input_modalities)??[],d=(i==null?void 0:i.output_modalities)??[],h=jt.filter(({key:p})=>i==null?void 0:i[p]);return e.jsx(ke,{children:e.jsxs(ke.Content,{className:"flex flex-col gap-5 p-5",children:[e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("h2",{className:"text-base font-semibold break-all text-[var(--otari-ink)]",children:t.model}),i!=null&&i.deprecated?e.jsx(K,{size:"sm",color:"danger",children:"deprecated"}):null]}),e.jsxs("p",{className:"mt-1 text-xs break-all text-[var(--otari-muted)]",children:["Selector: ",e.jsx("code",{children:t.key})]}),i!=null&&i.family?e.jsx("p",{className:"text-xs text-[var(--otari-muted)]",children:i.family}):null]}),e.jsx("button",{type:"button","aria-label":"Close model details",onClick:n,className:"-mt-1 -mr-1 shrink-0 rounded-md px-1.5 py-0.5 text-lg leading-none text-[var(--otari-muted)] hover:bg-[var(--otari-bg)] hover:text-[var(--otari-ink)]",children:"✕"})]}),i!=null&&i.description?e.jsx("p",{className:"text-sm text-[var(--otari-ink)]",children:i.description}):null,e.jsxs(ie,{title:"Pricing",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Wt,{source:t.source}),t.isDiscovered?null:e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"not discovered"})]}),e.jsx(Tt,{row:t},t.key),e.jsx(L,{size:"sm",variant:"outline",onPress:()=>s(t.key),children:"Make an alias"})]}),e.jsxs(ie,{title:"Specs",children:[e.jsx(T,{label:"Context window",value:ne(t.contextWindow)}),e.jsx(T,{label:"Max output",value:ne((i==null?void 0:i.max_output_tokens)??null)}),e.jsx(T,{label:"Knowledge cutoff",value:(i==null?void 0:i.knowledge_cutoff)??"—"}),e.jsx(T,{label:"Released",value:ht(i==null?void 0:i.release_date)}),e.jsx(T,{label:"Open weights",value:i?i.open_weights?"Yes":"No":"—"})]}),e.jsx(ie,{title:"Modalities",children:a.length===0&&d.length===0?e.jsx("span",{className:"text-sm text-[var(--otari-muted)]",children:"Unknown."}):e.jsxs("div",{className:"flex flex-col gap-1.5 text-xs text-[var(--otari-muted)]",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-1",children:[e.jsx("span",{children:"In:"}),a.map(p=>e.jsx(K,{size:"sm",color:"default",children:Te[p]??p},p))]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-1",children:[e.jsx("span",{children:"Out:"}),d.map(p=>e.jsx(K,{size:"sm",color:"default",children:Te[p]??p},p))]})]})}),e.jsx(ie,{title:"Capabilities",children:h.length>0?e.jsx("div",{className:"flex flex-wrap gap-1.5",children:h.map(({key:p,label:v})=>e.jsx(K,{size:"sm",color:"default",children:v},p))}):e.jsx("span",{className:"text-sm text-[var(--otari-muted)]",children:r?"None reported.":"Extended metadata unavailable (models.dev disabled or unreachable)."})})]})})}const Lt=15,$t=[{value:"15",label:"15 per page"},{value:"25",label:"25 per page"},{value:"50",label:"50 per page"}];function Et({value:t,onChange:i,placeholder:r}){return e.jsx("input",{type:"search",value:t,onChange:s=>i(s.target.value),placeholder:r,"aria-label":r,className:"w-full max-w-xs rounded-md border border-[var(--otari-line)] bg-white px-3 py-1.5 text-sm focus:border-[var(--otari-brand)] focus:outline-none"})}function At({page:t,pageCount:i,total:r,pageSize:s,onPage:n,onPageSize:a}){return e.jsxs("div",{className:"flex items-center justify-between px-1 pt-1 text-sm text-[var(--otari-muted)]",children:[e.jsxs("span",{children:[i>1?`Page ${t+1} of ${i} · `:"",pt(r)," model",r===1?"":"s"]}),e.jsxs("span",{className:"inline-flex gap-2",children:[e.jsx(E,{ariaLabel:"Rows per page",value:String(s),onChange:d=>a(Number(d)),options:$t}),i>1?e.jsxs(e.Fragment,{children:[e.jsx(L,{size:"sm",variant:"outline",isDisabled:t===0,onPress:()=>n(t-1),children:"Prev"}),e.jsx(L,{size:"sm",variant:"outline",isDisabled:t>=i-1,onPress:()=>n(t+1),children:"Next"})]}):null]})]})}const Be="otari.dashboard.modelsSort",xe={col:"model",dir:"asc"},Dt=["model","released","input","output"];function Ot(){if(typeof window>"u")return xe;try{const t=window.localStorage.getItem(Be);if(!t)return xe;const i=JSON.parse(t);if(Dt.includes(i.col)&&(i.dir==="asc"||i.dir==="desc"))return{col:i.col,dir:i.dir}}catch{}return xe}function Le({label:t,col:i,sort:r,onSort:s,align:n="left",info:a}){const d=r.col===i;return e.jsx(re,{className:n==="right"?"text-right":void 0,ariaSort:d?r.dir==="asc"?"ascending":"descending":"none",children:e.jsxs("span",{className:`inline-flex items-center gap-1.5 ${n==="right"?"flex-row-reverse":""}`,children:[e.jsxs("button",{type:"button",onClick:()=>s(i),className:`inline-flex items-center gap-1 ${n==="right"?"flex-row-reverse":""} hover:text-[var(--otari-ink)]`,children:[t,e.jsx("span",{className:"text-[10px] text-[var(--otari-muted)]",children:d?r.dir==="asc"?"▲":"▼":"↕"})]}),a]})})}function Ft({row:t,onClose:i}){const r=$e(),s=Ee(),[n,a]=c.useState(t.inputPrice==null?"":String(t.inputPrice)),[d,h]=c.useState(t.outputPrice==null?"":String(t.outputPrice)),[p,v]=c.useState(t.cacheReadPrice==null?"":String(t.cacheReadPrice)),[P,m]=c.useState(t.cacheWritePrice==null?"":String(t.cacheWritePrice)),[S,k]=c.useState(t.cacheWrite1hPrice==null?"":String(t.cacheWrite1hPrice)),[W,D]=c.useState(De(t.pricingTiers)),y=ae(n)&&ae(d)&&R(p)&&R(P)&&R(S)&&Oe(W),Y=()=>{y&&r.mutate({model_key:t.key,input_price_per_million:Number(n),output_price_per_million:Number(d),cache_read_price_per_million:V(p),cache_write_price_per_million:V(P),cache_write_1h_price_per_million:V(S),pricing_tiers:Fe(W)},{onSuccess:i})};return e.jsxs("div",{className:"flex flex-col gap-3 px-4 py-3",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsx("span",{className:"text-xs font-medium break-all text-[var(--otari-muted)]",children:t.key}),e.jsxs("label",{className:"flex items-center gap-1.5 text-xs text-[var(--otari-muted)]",children:["Input $ / 1M",e.jsx(j,{value:n,onChange:a,ariaLabel:`Input price for ${t.key}`})]}),e.jsxs("label",{className:"flex items-center gap-1.5 text-xs text-[var(--otari-muted)]",children:["Output $ / 1M",e.jsx(j,{value:d,onChange:h,ariaLabel:`Output price for ${t.key}`})]}),e.jsxs("label",{className:"flex items-center gap-1.5 text-xs text-[var(--otari-muted)]",children:["Cache read $ / 1M",e.jsx(j,{value:p,onChange:v,ariaLabel:`Cache read price for ${t.key}`})]}),e.jsxs("label",{className:"flex items-center gap-1.5 text-xs text-[var(--otari-muted)]",children:["Cache write $ / 1M",e.jsx(j,{value:P,onChange:m,ariaLabel:`Cache write price for ${t.key}`})]}),e.jsxs("label",{className:"flex items-center gap-1.5 text-xs text-[var(--otari-muted)]",children:["1h cache write $ / 1M",e.jsx(j,{value:S,onChange:k,ariaLabel:`1 hour cache write price for ${t.key}`})]}),e.jsx(L,{size:"sm",variant:"primary",isDisabled:r.isPending||!y,onPress:Y,children:r.isPending?"Saving…":"Save"}),e.jsx(L,{size:"sm",variant:"ghost",isDisabled:r.isPending,onPress:i,children:"Cancel"}),t.source==="configured"?e.jsxs("span",{className:"inline-flex items-center gap-1",children:[e.jsx(Ae,{confirmLabel:"Reset",isPending:s.isPending,onConfirm:()=>s.mutate(t.key,{onSuccess:i}),children:"Reset"}),e.jsx(se,{label:"What reset does",children:"Removes the custom price. The model reverts to the default rate (genai-prices) when default pricing is on, otherwise it is metered at no cost."})]}):null,r.error||s.error?e.jsx("span",{className:"text-xs text-red-700",children:me(r.error??s.error)}):null]}),e.jsx(ze,{tiers:W,onChange:D})]})}function zt({primary:t,secondary:i,rowKey:r,primaryLabel:s,secondaryLabel:n,onEdit:a}){const d=(h,p)=>e.jsx("button",{type:"button","aria-label":`Edit ${p} price for ${r}`,className:"tabular-nums hover:text-[var(--otari-brand-dark)] hover:underline",onClick:v=>{v.stopPropagation(),a()},children:h==null?"—":A(h)});return e.jsxs("span",{className:"inline-flex items-center justify-end gap-1",children:[d(t,s),e.jsx("span",{className:"text-[var(--otari-muted)]",children:"/"}),d(i,n)]})}function Bt({rates:t,rowKey:i,onEdit:r}){const s=[t.cacheReadPrice==null?null:`R ${A(t.cacheReadPrice)}`,t.cacheWritePrice==null?null:`W ${A(t.cacheWritePrice)}`,t.cacheWrite1hPrice==null?null:`1h ${A(t.cacheWrite1hPrice)}`].filter(n=>n!==null);return e.jsx("button",{type:"button","aria-label":`Edit caching price for ${i}`,className:"max-w-44 text-right text-xs leading-5 text-[var(--otari-muted)] hover:text-[var(--otari-brand-dark)] hover:underline",onClick:n=>{n.stopPropagation(),r()},children:s.length>0?s.join(" · "):"Input-rate fallback"})}function Rt({row:t,onEdit:i}){const r=[...t.pricingTiers].sort((n,a)=>n.min_input_tokens-a.min_input_tokens).map(n=>ne(n.min_input_tokens)),s=r.length===0?"Base only":`${r.length} tier${r.length===1?"":"s"} · ≥ ${r.join(", ")}`;return e.jsx("button",{type:"button","aria-label":`Edit pricing policy for ${t.key}`,className:"max-w-40 text-right text-xs leading-5 text-[var(--otari-muted)] hover:text-[var(--otari-brand-dark)] hover:underline",onClick:n=>{n.stopPropagation(),i()},children:s})}function Kt({rows:t,isLoading:i,empty:r,sort:s,onSort:n,selectedKey:a,onSelect:d,pricingKey:h,onSetPricingKey:p,comparisonContextTokens:v}){const P=v==null?"Base":`at ${ne(v)}`;return e.jsxs(mt,{children:[e.jsx(ft,{children:e.jsxs(Ce,{children:[e.jsx(Le,{label:"Model",col:"model",sort:s,onSort:n}),e.jsx(re,{children:"Provider"}),e.jsx(Le,{label:`${P} in / out $ / 1M`,col:"input",sort:s,onSort:n,align:"right",info:e.jsx(Mt,{})}),e.jsxs(re,{className:"text-right",children:["Caching ",v==null?"policy":P]}),e.jsx(re,{className:"text-right",children:"Pricing policy"})]})}),e.jsx("tbody",{children:i?e.jsx(vt,{colSpan:5}):t.length>0?t.map(m=>{const S=()=>p(h===m.key?null:m.key),k=kt(m,v);return e.jsxs(c.Fragment,{children:[e.jsxs(Ce,{onClick:()=>d(m.key),selected:m.key===a,children:[e.jsxs(U,{className:"font-medium break-all",children:[m.model,e.jsx("span",{className:"sr-only",children:m.key})]}),e.jsx(U,{className:"text-[var(--otari-muted)]",children:m.provider}),e.jsx(U,{className:"text-right",children:e.jsx(zt,{primary:k.inputPrice,secondary:k.outputPrice,rowKey:m.key,primaryLabel:"input",secondaryLabel:"output",onEdit:S})}),e.jsx(U,{className:"text-right",children:e.jsx(Bt,{rates:k,rowKey:m.key,onEdit:S})}),e.jsx(U,{className:"text-right",children:e.jsx(Rt,{row:m,onEdit:S})})]}),h===m.key?e.jsx("tr",{className:"border-b border-[var(--otari-line)] bg-[var(--otari-bg)] last:border-b-0",children:e.jsx("td",{colSpan:5,children:e.jsx(Ft,{row:m,onClose:()=>p(null)})})}):null]},m.key)}):e.jsx(bt,{colSpan:5,children:r})})]})}function Vt({providers:t}){return t.length===0?null:e.jsxs(dt,{tone:"warning",children:["Could not list ",t.map(i=>i.provider).join(", "),". Check that provider's credentials in config.yml; its models are missing from the list below."]})}function Jt(){var je,Pe,ye;const t=rt(),[i]=nt(),r=at(),s=st(),n=lt(),a=ct(),[d,h]=c.useState(""),[p,v]=c.useState(0),[P,m]=c.useState(Lt),[S,k]=c.useState(null),[W,D]=c.useState(null),[y,Y]=c.useState(Ot);c.useEffect(()=>{try{window.localStorage.setItem(Be,JSON.stringify(y))}catch{}},[y]);const[M,G]=c.useState(i.get("provider")||"all"),[F,Re]=c.useState("all"),[H,Ke]=c.useState("all"),[q,Ve]=c.useState("all"),[le,Ye]=c.useState("0"),[J,He]=c.useState(""),[Z,qe]=c.useState("all"),[ce,we]=c.useState(""),O=((je=a.data)==null?void 0:je.models)??{},Ue=((Pe=a.data)==null?void 0:Pe.available)??!1,fe=c.useMemo(()=>{var l;return new Set((((l=n.data)==null?void 0:l.providers)??[]).flatMap(f=>f.models.map(o=>o.key)))},[n.data]),Ge=l=>{h(l),v(0)},z=l=>f=>{l(f),v(0)},Je=l=>{Y(f=>f.col===l?{col:l,dir:f.dir==="asc"?"desc":"asc"}:{col:l,dir:l==="released"?"desc":"asc"}),v(0)},X=c.useMemo(()=>{var C,g,_,$,I,B,Ne;const l=new Map(gt(s.data??[]).map(u=>[u.model_key,u])),f=[],o=new Set,b=(u,he,Se,x)=>{if(o.has(u))return;o.add(u);const N=l.get(u);f.push({key:u,model:Ie(he,Se),provider:Se,isDiscovered:fe.has(u),contextWindow:(x==null?void 0:x.contextWindow)??null,inputPrice:N?N.input_price_per_million:(x==null?void 0:x.inputPrice)??null,outputPrice:N?N.output_price_per_million:(x==null?void 0:x.outputPrice)??null,cacheReadPrice:N?N.cache_read_price_per_million:(x==null?void 0:x.cacheReadPrice)??null,cacheWritePrice:N?N.cache_write_price_per_million:(x==null?void 0:x.cacheWritePrice)??null,cacheWrite1hPrice:N?N.cache_write_1h_price_per_million??null:(x==null?void 0:x.cacheWrite1hPrice)??null,pricingTiers:N?N.pricing_tiers??[]:(x==null?void 0:x.pricingTiers)??[],source:N?"configured":(x==null?void 0:x.source)??"none"})};for(const u of((C=r.data)==null?void 0:C.data)??[]){if(u.owned_by===_t)continue;const he=u.pricing_source==="default"?"default":u.pricing?"configured":"none";b(u.id,u.id,u.owned_by||We(u.id),{key:u.id,model:u.id,provider:u.owned_by,contextWindow:u.context_window,inputPrice:((g=u.pricing)==null?void 0:g.input_price_per_million)??null,outputPrice:((_=u.pricing)==null?void 0:_.output_price_per_million)??null,cacheReadPrice:(($=u.pricing)==null?void 0:$.cache_read_price_per_million)??null,cacheWritePrice:((I=u.pricing)==null?void 0:I.cache_write_price_per_million)??null,cacheWrite1hPrice:((B=u.pricing)==null?void 0:B.cache_write_1h_price_per_million)??null,pricingTiers:((Ne=u.pricing)==null?void 0:Ne.pricing_tiers)??[],source:he})}for(const u of l.keys())b(u,u,We(u));return f},[r.data,s.data,fe]),Ze=c.useMemo(()=>new Map(X.map(l=>[l.key,l])),[X]),Q=c.useMemo(()=>{var o,b,C;const l=X.map(g=>{var _,$;return{...g,contextWindow:g.contextWindow??((_=O[g.key])==null?void 0:_.context_window)??null,releaseDate:(($=O[g.key])==null?void 0:$.release_date)??null}}),f=new Set(l.map(g=>g.key));for(const g of((o=n.data)==null?void 0:o.providers)??[])for(const _ of g.models)f.has(_.key)||(f.add(_.key),l.push({key:_.key,model:Ie(_.key,g.provider),provider:g.provider,isDiscovered:!0,contextWindow:((b=O[_.key])==null?void 0:b.context_window)??null,releaseDate:((C=O[_.key])==null?void 0:C.release_date)??null,inputPrice:null,outputPrice:null,cacheReadPrice:null,cacheWritePrice:null,cacheWrite1hPrice:null,pricingTiers:[],source:"none"}));return l},[X,n.data,O]),Xe=(((ye=n.data)==null?void 0:ye.providers)??[]).filter(l=>!l.ok),ee=c.useMemo(()=>{const l=Array.from(new Set(Q.map(f=>f.provider))).sort((f,o)=>f.localeCompare(o));return[{value:"all",label:"All providers"},...l.map(f=>({value:f,label:f}))]},[Q]);c.useEffect(()=>{M==="all"||ee.length<=1||ee.some(l=>l.value===M)||G("all")},[ee,M]);const w=d.trim().toLowerCase(),oe=Number(le)||0,ue=J===""?Number.POSITIVE_INFINITY:Number(J),Qe=ce===""?null:Number(ce),de=Z==="all"?null:Date.now()-Number(Z)*Ct,pe=c.useMemo(()=>{const l=o=>{if(w&&!o.key.toLowerCase().includes(w)&&!o.provider.toLowerCase().includes(w)||M!=="all"&&o.provider!==M||F==="configured"&&o.source!=="configured"||F==="default"&&o.source!=="default"||F==="priced"&&o.inputPrice==null||F==="unpriced"&&o.inputPrice!=null||H==="discovered"&&!o.isDiscovered||H==="custom"&&o.isDiscovered)return!1;if(q!=="all"){const b=Me.find(g=>g.value===q),C=O[o.key];if(!b||!C||!b.test(C))return!1}if(oe>0&&(o.contextWindow==null||o.contextWindowue))return!1;if(de!=null){const b=o.releaseDate?Date.parse(o.releaseDate):Number.NaN;if(Number.isNaN(b)||b{const C=y.dir==="asc"?1:-1;if(y.col==="model")return o.model.localeCompare(b.model)*C;if(y.col==="released"){const I=o.releaseDate??null,B=b.releaseDate??null;return!I&&!B?o.model.localeCompare(b.model):I?B?(IB?1:0)*C||o.model.localeCompare(b.model):-1:1}const g=I=>y.col==="input"?I.inputPrice:I.outputPrice,_=g(o),$=g(b);return _==null&&$==null?o.model.localeCompare(b.model):_==null?1:$==null?-1:(_-$)*C||o.model.localeCompare(b.model)};return Q.filter(l).sort(f)},[Q,w,M,F,H,q,oe,ue,de,O,y]),ve=pe.length,be=Math.max(1,Math.ceil(ve/P)),ge=Math.min(p,be-1),_e=ge*P,et=pe.slice(_e,_e+P),tt=r.isLoading||s.isLoading||n.isLoading,it=w!==""||M!=="all"||F!=="all"||H!=="all"||q!=="all"||le!=="0"||J!==""||Z!=="all"?"No models match your filters.":"No models yet. Add a provider on the Providers page, or price a model below.",te=W?pe.find(l=>l.key===W)??Ze.get(W)??null:null;return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(ot,{title:"Models",description:"Every model your providers can serve. Set a price on any model so budgets and usage tracking work."}),e.jsx(ut,{error:r.error??s.error??n.error??a.error}),e.jsxs("div",{className:`grid gap-4 lg:items-start ${te?"lg:grid-cols-[minmax(0,1fr)_360px]":"grid-cols-1"}`,children:[e.jsxs("div",{className:"flex min-w-0 flex-col gap-3",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx(Et,{value:d,onChange:Ge,placeholder:"Search models…"}),e.jsx(E,{ariaLabel:"Filter by provider",value:M,onChange:z(G),options:ee}),e.jsx(E,{ariaLabel:"Filter by pricing",value:F,onChange:z(Re),options:[{value:"all",label:"Any pricing"},{value:"configured",label:"Custom price"},{value:"default",label:"Default price"},{value:"priced",label:"Priced"},{value:"unpriced",label:"Unpriced"}]}),e.jsx(E,{ariaLabel:"Filter by source",value:H,onChange:z(Ke),options:[{value:"all",label:"Any source"},{value:"discovered",label:"Discovered"},{value:"custom",label:"Custom (not discovered)"}]}),e.jsx(E,{ariaLabel:"Filter by capability",value:q,onChange:z(Ve),options:[{value:"all",label:"Any capability"},...Me.map(l=>({value:l.value,label:l.label}))]}),e.jsx(E,{ariaLabel:"Minimum context window",value:le,onChange:z(Ye),options:Pt}),e.jsx(E,{ariaLabel:"Maximum input price",value:J,onChange:z(He),options:yt}),e.jsx(E,{ariaLabel:"Compare prices at context",value:ce,onChange:we,options:Nt}),e.jsx(E,{ariaLabel:"Filter by release date",value:Z,onChange:z(qe),options:St})]}),e.jsx(Vt,{providers:Xe}),e.jsx(Kt,{rows:et,isLoading:tt,empty:it,sort:y,onSort:Je,selectedKey:W,onSelect:D,pricingKey:S,onSetPricingKey:k,comparisonContextTokens:Qe}),e.jsx("div",{className:"flex flex-wrap items-center justify-between gap-2",children:e.jsx(At,{page:ge,pageCount:be,total:ve,pageSize:P,onPage:v,onPageSize:l=>{m(l),v(0)}})})]}),te?e.jsx("aside",{className:"lg:sticky lg:top-4",children:e.jsx(It,{row:te,metadata:O[te.key],metadataAvailable:Ue,onMakeAlias:l=>t(`/aliases?target=${encodeURIComponent(l)}`),onClose:()=>D(null)})}):null]})]})}export{Jt as ModelsPage}; diff --git a/src/gateway/static/dashboard/assets/OverviewPage-D4ZtkmU0.js b/src/gateway/static/dashboard/assets/OverviewPage-B_g2blUc.js similarity index 99% rename from src/gateway/static/dashboard/assets/OverviewPage-D4ZtkmU0.js rename to src/gateway/static/dashboard/assets/OverviewPage-B_g2blUc.js index d5c54a60..7cd4e993 100644 --- a/src/gateway/static/dashboard/assets/OverviewPage-D4ZtkmU0.js +++ b/src/gateway/static/dashboard/assets/OverviewPage-B_g2blUc.js @@ -1 +1 @@ -import{j as t}from"./tanstack-query-1t81HyiD.js";import{r as f,i as Z,N as G}from"./react-dgEcD0HR.js";import{J as tt,c as N,K as et,j as rt,p as at,u as st,a as nt,L as _,P as ot,E as Y,S as p,M as D,N as R,z as E,O as k,Q as it}from"./index-DHQmS-9o.js";import{S as H}from"./charts-Cr3Dij9t.js";import{T as lt,a as dt,b,L as ct,c as ut,d as xt,e as j}from"./Table-CLdjdyTx.js";import{d as B,B as mt}from"./heroui-BX6JwHY-.js";import"./recharts-CR3TAEof.js";function U(e){return e==="neutral"?void 0:e}const vt=.02,ht=.1;function F(e){if(!e||e.request_count===0)return{rate:null,status:"neutral"};const n=e.error_count/e.request_count,a=n>=ht?"alert":n>=vt?"warn":"ok";return{rate:n,status:a}}function pt(e){return!e||e.total===0?"neutral":e.healthy>=e.total?"ok":e.healthy===0?"alert":"warn"}const ft=.8;function gt(e){if(e.length===0)return{status:"neutral",label:"No budgets configured",overCount:0,nearCount:0,cappedCount:0};const n=e.filter(s=>s.max_budget!==null&&s.user_count>0);if(n.length===0)return{status:"neutral",label:"No capped budgets",overCount:0,nearCount:0,cappedCount:0};let a=0,r=0,c,m=-1;for(const s of n){const o=s.max_budget*s.user_count,i=o>0?s.total_spend/o:0;i>=1?a+=1:i>=ft&&(r+=1),i>m&&(m=i,c={name:s.name??s.budget_id,spent:s.total_spend,allocated:o,pct:i})}const u=a>0?"alert":r>0?"warn":"ok",g=a>0?`${a} over limit`:r>0?`${r} near limit`:"All within budget";return{status:u,label:g,overCount:a,nearCount:r,cappedCount:n.length,worst:c}}const K=864e5,W=30;function I(){const e=new Date;return`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,"0")}-${String(e.getDate()).padStart(2,"0")}`}function bt(){const[e,n]=f.useState(I);return f.useEffect(()=>{const a=()=>{if(document.visibilityState==="visible"){const r=I();n(c=>c===r?c:r)}};return document.addEventListener("visibilitychange",a),window.addEventListener("focus",a),()=>{document.removeEventListener("visibilitychange",a),window.removeEventListener("focus",a)}},[]),f.useMemo(()=>{const a=Date.now(),r=new Date(a);return{today:new Date(r.getFullYear(),r.getMonth(),r.getDate()).toISOString(),periodStart:new Date(a-W*K).toISOString(),prevStart:new Date(a-2*W*K).toISOString()}},[e])}const jt={ok:"Healthy",warn:"Elevated",alert:"High"},St={ok:"On track",warn:"Near limit",alert:"Over budget"};function Pt(){const e=tt();return e.isLoading?null:t.jsx(yt,{needsSetup:e.isSuccess&&e.data.providers.length===0})}function yt({needsSetup:e=!1}){var $,A,P,T,M,q;const n=bt(),a=f.useMemo(()=>({start_date:n.today}),[n]),r=f.useMemo(()=>({start_date:n.periodStart}),[n]),c=f.useMemo(()=>({start_date:n.prevStart,end_date:n.periodStart}),[n]),m=N(a,"hour"),u=N(r,"day"),g=N(c,"day"),s=et(),o=rt(),i=at(),S=st(),y=nt({},0,5),C=($=m.data)==null?void 0:$.totals,x=(A=u.data)==null?void 0:A.totals,v=(P=g.data)==null?void 0:P.totals,w=((T=u.data)==null?void 0:T.series)??[],O=w.length>1,l=F(x),L=F(v),z=l.rate!==null&&L.rate!==null?_(l.rate,L.rate):null,d=gt(o.data??[]),J=pt(s.data),Q=(i.data??[]).filter(h=>h.is_active).length,V=(S.data??[]).filter(h=>!h.blocked).length,X=m.error??u.error??s.error??o.error??i.error??S.error;return t.jsxs("div",{className:"flex flex-col gap-6",children:[t.jsx(ot,{title:"Overview",description:"At-a-glance spend, traffic, and health across the gateway."}),e?t.jsx(wt,{}):null,t.jsx(Y,{error:X}),t.jsx(_t,{providerHealth:J,healthy:((M=s.data)==null?void 0:M.healthy)??0,total:((q=s.data)==null?void 0:q.total)??0,budget:d,errStatus:l.status,errRate:l.rate,ready:s.isSuccess&&o.isSuccess&&u.isSuccess,failed:s.isError||o.isError||u.isError}),t.jsxs("div",{className:"grid grid-cols-2 gap-4 sm:grid-cols-3 xl:grid-cols-4",children:[t.jsx(p,{label:"Spend today",value:C?D(C.cost):"—"}),t.jsx(p,{label:"Spend, last 30 days",value:x?D(x.cost):"—",hint:x?t.jsx(R,{fraction:_(x.cost,v==null?void 0:v.cost)}):null,chart:O?t.jsx(H,{values:w.map(h=>h.cost),ariaLabel:"Spend trend over the last 30 days"}):void 0}),t.jsx(p,{label:"Requests, last 30 days",value:x?E(x.request_count):"—",hint:x?t.jsx(R,{fraction:_(x.request_count,v==null?void 0:v.request_count)}):null,chart:O?t.jsx(H,{values:w.map(h=>h.requests),ariaLabel:"Request volume trend over the last 30 days"}):void 0}),t.jsx(p,{label:"Error rate, last 30 days",value:l.rate===null?"—":k(l.rate),status:U(l.status),statusLabel:l.status==="neutral"?void 0:jt[l.status],hint:l.rate!==null?t.jsx(R,{fraction:z}):null}),t.jsx(p,{label:"Budget health",value:o.data&&d.worst?k(d.worst.pct):"—",status:o.data?U(d.status):void 0,statusLabel:o.data&&d.status!=="neutral"?St[d.status]:void 0,hint:o.data?d.worst?`${d.label} · worst: ${d.worst.name}`:d.label:void 0,to:"/budgets"}),t.jsx(p,{label:"Active keys",value:i.data?E(Q):"—",to:"/keys"}),t.jsx(p,{label:"Active users",value:S.data?E(V):"—",to:"/users"})]}),t.jsx(Et,{entries:y.data??[],loading:y.isLoading,error:y.error})]})}function wt(){const e=Z();return t.jsx(B,{children:t.jsxs(B.Content,{className:"flex flex-col gap-3 p-6",children:[t.jsxs("div",{children:[t.jsx("h2",{className:"text-lg font-semibold text-[var(--otari-ink)]",children:"Get started with Otari"}),t.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:"Add a provider to begin serving models. Once it is configured, this page will show your gateway’s traffic, spend, and health."})]}),t.jsx("div",{children:t.jsx(mt,{variant:"primary",onPress:()=>e("/providers"),children:"Add your first provider"})})]})})}function Nt({text:e}){return t.jsx("div",{role:"status",className:"flex items-center gap-2 rounded-xl border border-[var(--otari-line)] bg-[var(--otari-bg)] px-4 py-3 text-sm text-[var(--otari-muted)]",children:e})}function _t({providerHealth:e,healthy:n,total:a,budget:r,errStatus:c,errRate:m,ready:u,failed:g}){if(g)return t.jsx(Nt,{text:"Some status data could not be loaded."});if(!u)return null;const s=[];if((e==="warn"||e==="alert")&&a>0){const o=a-n;s.push({text:`${o} provider${o===1?"":"s"} unreachable`,to:"/providers"})}return r.overCount>0?s.push({text:`${r.overCount} budget${r.overCount===1?"":"s"} over limit`,to:"/budgets"}):r.nearCount>0&&s.push({text:`${r.nearCount} budget${r.nearCount===1?"":"s"} near limit`,to:"/budgets"}),c==="alert"&&m!==null&&s.push({text:`error rate ${k(m)}`,to:"/activity?status=error"}),s.length===0?null:t.jsxs("div",{role:"alert",className:"flex flex-col gap-2 rounded-xl border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-900 sm:flex-row sm:flex-wrap sm:items-center",children:[t.jsx("span",{className:"font-medium",children:"Needs attention:"}),s.map((o,i)=>t.jsxs("span",{className:"flex items-center gap-2",children:[i>0?t.jsx("span",{"aria-hidden":!0,className:"text-amber-400",children:"·"}):null,t.jsx(G,{to:o.to,className:"underline underline-offset-2 hover:text-amber-950",children:o.text})]},o.to+o.text))]})}function Rt(e){return e==="error"?"error":"ok"}function Et({entries:e,loading:n,error:a}){return t.jsxs("div",{className:"flex flex-col gap-3",children:[t.jsxs("div",{className:"flex items-center justify-between",children:[t.jsx("h2",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:"Recent activity"}),t.jsx(G,{to:"/activity",className:"text-sm text-[var(--otari-brand-dark)] hover:underline",children:"View all →"})]}),t.jsx(Y,{error:a}),t.jsxs(lt,{children:[t.jsx(dt,{children:t.jsxs("tr",{children:[t.jsx(b,{children:"Time"}),t.jsx(b,{children:"Model"}),t.jsx(b,{className:"text-right",children:"Cost"}),t.jsx(b,{children:"Status"})]})}),t.jsx("tbody",{children:n?t.jsx(ct,{colSpan:4}):e.length===0?t.jsx(ut,{colSpan:4,children:"No requests yet. Once the gateway serves traffic, it appears here."}):e.map(r=>t.jsxs(xt,{children:[t.jsx(j,{className:"text-[var(--otari-muted)]",children:t.jsx("span",{title:new Date(r.timestamp).toLocaleString(),children:it(r.timestamp)})}),t.jsx(j,{className:"text-[var(--otari-ink)]",children:r.model}),t.jsx(j,{className:"text-right tabular-nums",children:r.cost===null?"—":D(r.cost)}),t.jsx(j,{children:t.jsx("span",{className:`inline-flex items-center rounded-full border px-2 py-0.5 text-xs font-medium ${r.status==="error"?"border-red-200 bg-red-50 text-red-700":"border-[var(--otari-line)] bg-[var(--otari-brand-tint)] text-[var(--otari-brand-dark)]"}`,children:Rt(r.status)})})]},r.id))})]})]})}export{Pt as OverviewIndex,yt as OverviewPage,I as localDayKey}; +import{j as t}from"./tanstack-query-1t81HyiD.js";import{r as f,i as Z,N as G}from"./react-dgEcD0HR.js";import{J as tt,c as N,K as et,j as rt,p as at,u as st,a as nt,L as _,P as ot,E as Y,S as p,M as D,N as R,z as E,O as k,Q as it}from"./index-DAVt9uB3.js";import{S as H}from"./charts-Cr3Dij9t.js";import{T as lt,a as dt,b,L as ct,c as ut,d as xt,e as j}from"./Table-CLdjdyTx.js";import{d as B,B as mt}from"./heroui-BX6JwHY-.js";import"./recharts-CR3TAEof.js";function U(e){return e==="neutral"?void 0:e}const vt=.02,ht=.1;function F(e){if(!e||e.request_count===0)return{rate:null,status:"neutral"};const n=e.error_count/e.request_count,a=n>=ht?"alert":n>=vt?"warn":"ok";return{rate:n,status:a}}function pt(e){return!e||e.total===0?"neutral":e.healthy>=e.total?"ok":e.healthy===0?"alert":"warn"}const ft=.8;function gt(e){if(e.length===0)return{status:"neutral",label:"No budgets configured",overCount:0,nearCount:0,cappedCount:0};const n=e.filter(s=>s.max_budget!==null&&s.user_count>0);if(n.length===0)return{status:"neutral",label:"No capped budgets",overCount:0,nearCount:0,cappedCount:0};let a=0,r=0,c,m=-1;for(const s of n){const o=s.max_budget*s.user_count,i=o>0?s.total_spend/o:0;i>=1?a+=1:i>=ft&&(r+=1),i>m&&(m=i,c={name:s.name??s.budget_id,spent:s.total_spend,allocated:o,pct:i})}const u=a>0?"alert":r>0?"warn":"ok",g=a>0?`${a} over limit`:r>0?`${r} near limit`:"All within budget";return{status:u,label:g,overCount:a,nearCount:r,cappedCount:n.length,worst:c}}const K=864e5,W=30;function I(){const e=new Date;return`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,"0")}-${String(e.getDate()).padStart(2,"0")}`}function bt(){const[e,n]=f.useState(I);return f.useEffect(()=>{const a=()=>{if(document.visibilityState==="visible"){const r=I();n(c=>c===r?c:r)}};return document.addEventListener("visibilitychange",a),window.addEventListener("focus",a),()=>{document.removeEventListener("visibilitychange",a),window.removeEventListener("focus",a)}},[]),f.useMemo(()=>{const a=Date.now(),r=new Date(a);return{today:new Date(r.getFullYear(),r.getMonth(),r.getDate()).toISOString(),periodStart:new Date(a-W*K).toISOString(),prevStart:new Date(a-2*W*K).toISOString()}},[e])}const jt={ok:"Healthy",warn:"Elevated",alert:"High"},St={ok:"On track",warn:"Near limit",alert:"Over budget"};function Pt(){const e=tt();return e.isLoading?null:t.jsx(yt,{needsSetup:e.isSuccess&&e.data.providers.length===0})}function yt({needsSetup:e=!1}){var $,A,P,T,M,q;const n=bt(),a=f.useMemo(()=>({start_date:n.today}),[n]),r=f.useMemo(()=>({start_date:n.periodStart}),[n]),c=f.useMemo(()=>({start_date:n.prevStart,end_date:n.periodStart}),[n]),m=N(a,"hour"),u=N(r,"day"),g=N(c,"day"),s=et(),o=rt(),i=at(),S=st(),y=nt({},0,5),C=($=m.data)==null?void 0:$.totals,x=(A=u.data)==null?void 0:A.totals,v=(P=g.data)==null?void 0:P.totals,w=((T=u.data)==null?void 0:T.series)??[],O=w.length>1,l=F(x),L=F(v),z=l.rate!==null&&L.rate!==null?_(l.rate,L.rate):null,d=gt(o.data??[]),J=pt(s.data),Q=(i.data??[]).filter(h=>h.is_active).length,V=(S.data??[]).filter(h=>!h.blocked).length,X=m.error??u.error??s.error??o.error??i.error??S.error;return t.jsxs("div",{className:"flex flex-col gap-6",children:[t.jsx(ot,{title:"Overview",description:"At-a-glance spend, traffic, and health across the gateway."}),e?t.jsx(wt,{}):null,t.jsx(Y,{error:X}),t.jsx(_t,{providerHealth:J,healthy:((M=s.data)==null?void 0:M.healthy)??0,total:((q=s.data)==null?void 0:q.total)??0,budget:d,errStatus:l.status,errRate:l.rate,ready:s.isSuccess&&o.isSuccess&&u.isSuccess,failed:s.isError||o.isError||u.isError}),t.jsxs("div",{className:"grid grid-cols-2 gap-4 sm:grid-cols-3 xl:grid-cols-4",children:[t.jsx(p,{label:"Spend today",value:C?D(C.cost):"—"}),t.jsx(p,{label:"Spend, last 30 days",value:x?D(x.cost):"—",hint:x?t.jsx(R,{fraction:_(x.cost,v==null?void 0:v.cost)}):null,chart:O?t.jsx(H,{values:w.map(h=>h.cost),ariaLabel:"Spend trend over the last 30 days"}):void 0}),t.jsx(p,{label:"Requests, last 30 days",value:x?E(x.request_count):"—",hint:x?t.jsx(R,{fraction:_(x.request_count,v==null?void 0:v.request_count)}):null,chart:O?t.jsx(H,{values:w.map(h=>h.requests),ariaLabel:"Request volume trend over the last 30 days"}):void 0}),t.jsx(p,{label:"Error rate, last 30 days",value:l.rate===null?"—":k(l.rate),status:U(l.status),statusLabel:l.status==="neutral"?void 0:jt[l.status],hint:l.rate!==null?t.jsx(R,{fraction:z}):null}),t.jsx(p,{label:"Budget health",value:o.data&&d.worst?k(d.worst.pct):"—",status:o.data?U(d.status):void 0,statusLabel:o.data&&d.status!=="neutral"?St[d.status]:void 0,hint:o.data?d.worst?`${d.label} · worst: ${d.worst.name}`:d.label:void 0,to:"/budgets"}),t.jsx(p,{label:"Active keys",value:i.data?E(Q):"—",to:"/keys"}),t.jsx(p,{label:"Active users",value:S.data?E(V):"—",to:"/users"})]}),t.jsx(Et,{entries:y.data??[],loading:y.isLoading,error:y.error})]})}function wt(){const e=Z();return t.jsx(B,{children:t.jsxs(B.Content,{className:"flex flex-col gap-3 p-6",children:[t.jsxs("div",{children:[t.jsx("h2",{className:"text-lg font-semibold text-[var(--otari-ink)]",children:"Get started with Otari"}),t.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:"Add a provider to begin serving models. Once it is configured, this page will show your gateway’s traffic, spend, and health."})]}),t.jsx("div",{children:t.jsx(mt,{variant:"primary",onPress:()=>e("/providers"),children:"Add your first provider"})})]})})}function Nt({text:e}){return t.jsx("div",{role:"status",className:"flex items-center gap-2 rounded-xl border border-[var(--otari-line)] bg-[var(--otari-bg)] px-4 py-3 text-sm text-[var(--otari-muted)]",children:e})}function _t({providerHealth:e,healthy:n,total:a,budget:r,errStatus:c,errRate:m,ready:u,failed:g}){if(g)return t.jsx(Nt,{text:"Some status data could not be loaded."});if(!u)return null;const s=[];if((e==="warn"||e==="alert")&&a>0){const o=a-n;s.push({text:`${o} provider${o===1?"":"s"} unreachable`,to:"/providers"})}return r.overCount>0?s.push({text:`${r.overCount} budget${r.overCount===1?"":"s"} over limit`,to:"/budgets"}):r.nearCount>0&&s.push({text:`${r.nearCount} budget${r.nearCount===1?"":"s"} near limit`,to:"/budgets"}),c==="alert"&&m!==null&&s.push({text:`error rate ${k(m)}`,to:"/activity?status=error"}),s.length===0?null:t.jsxs("div",{role:"alert",className:"flex flex-col gap-2 rounded-xl border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-900 sm:flex-row sm:flex-wrap sm:items-center",children:[t.jsx("span",{className:"font-medium",children:"Needs attention:"}),s.map((o,i)=>t.jsxs("span",{className:"flex items-center gap-2",children:[i>0?t.jsx("span",{"aria-hidden":!0,className:"text-amber-400",children:"·"}):null,t.jsx(G,{to:o.to,className:"underline underline-offset-2 hover:text-amber-950",children:o.text})]},o.to+o.text))]})}function Rt(e){return e==="error"?"error":"ok"}function Et({entries:e,loading:n,error:a}){return t.jsxs("div",{className:"flex flex-col gap-3",children:[t.jsxs("div",{className:"flex items-center justify-between",children:[t.jsx("h2",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:"Recent activity"}),t.jsx(G,{to:"/activity",className:"text-sm text-[var(--otari-brand-dark)] hover:underline",children:"View all →"})]}),t.jsx(Y,{error:a}),t.jsxs(lt,{children:[t.jsx(dt,{children:t.jsxs("tr",{children:[t.jsx(b,{children:"Time"}),t.jsx(b,{children:"Model"}),t.jsx(b,{className:"text-right",children:"Cost"}),t.jsx(b,{children:"Status"})]})}),t.jsx("tbody",{children:n?t.jsx(ct,{colSpan:4}):e.length===0?t.jsx(ut,{colSpan:4,children:"No requests yet. Once the gateway serves traffic, it appears here."}):e.map(r=>t.jsxs(xt,{children:[t.jsx(j,{className:"text-[var(--otari-muted)]",children:t.jsx("span",{title:new Date(r.timestamp).toLocaleString(),children:it(r.timestamp)})}),t.jsx(j,{className:"text-[var(--otari-ink)]",children:r.model}),t.jsx(j,{className:"text-right tabular-nums",children:r.cost===null?"—":D(r.cost)}),t.jsx(j,{children:t.jsx("span",{className:`inline-flex items-center rounded-full border px-2 py-0.5 text-xs font-medium ${r.status==="error"?"border-red-200 bg-red-50 text-red-700":"border-[var(--otari-line)] bg-[var(--otari-brand-tint)] text-[var(--otari-brand-dark)]"}`,children:Rt(r.status)})})]},r.id))})]})]})}export{Pt as OverviewIndex,yt as OverviewPage,I as localDayKey}; diff --git a/src/gateway/static/dashboard/assets/ProvidersPage-CmlcXh68.js b/src/gateway/static/dashboard/assets/ProvidersPage-DhHL_fxe.js similarity index 99% rename from src/gateway/static/dashboard/assets/ProvidersPage-CmlcXh68.js rename to src/gateway/static/dashboard/assets/ProvidersPage-DhHL_fxe.js index c59f53b5..e7ade3bc 100644 --- a/src/gateway/static/dashboard/assets/ProvidersPage-CmlcXh68.js +++ b/src/gateway/static/dashboard/assets/ProvidersPage-DhHL_fxe.js @@ -1 +1 @@ -import{j as e}from"./tanstack-query-1t81HyiD.js";import{r as x,L as Q}from"./react-dgEcD0HR.js";import{J as X,R as Z,B as ee,K as se,T as te,U as ae,V as ne,P as re,E as R,I as ie,C as oe,W as de,X as le,Q as U,h as M,Y,Z as ce,_ as me,$ as ue}from"./index-DHQmS-9o.js";import{F as A}from"./Field-HzRk1KDP.js";import{T as xe,a as pe,b as _,L as he,c as ve,d as ge,e as C}from"./Table-CLdjdyTx.js";import{B as g,f as z,d as T,S as fe,T as je,L as V,I as W,D as be,C as E,a as ye,b as ke}from"./heroui-BX6JwHY-.js";function B({value:t,onChange:a,label:s,placeholder:n,description:i}){return e.jsxs(je,{value:t,onChange:a,className:"flex max-w-md flex-col gap-1",children:[e.jsx(V,{className:"text-sm font-medium text-[var(--otari-ink)]",children:s}),e.jsx(W,{type:"password",placeholder:n??"sk-…",autoComplete:"off",autoCorrect:"off",autoCapitalize:"off",spellCheck:!1,"data-1p-ignore":!0,"data-lpignore":"true"}),i?e.jsx(be,{className:"text-xs text-[var(--otari-muted)]",children:i}):null]})}function G({label:t,value:a,onChange:s,description:n,placeholder:i,extra:l=[],includeCatalog:m=!0}){var y;const v=me(),u=x.useMemo(()=>m?[...l,...(v.data??[]).map(o=>({id:o.id,name:o.name}))]:l,[v.data,l,m]),[p,c]=x.useState(()=>{var o;return((o=u.find(j=>j.id===a))==null?void 0:o.name)??""}),f=((y=u.find(o=>o.id===a))==null?void 0:y.name)??"",h=p.trim()===f.trim()?"":p.trim().toLowerCase(),d=u.filter(o=>!h||o.name.toLowerCase().includes(h)||o.id.toLowerCase().includes(h)).slice(0,50);return e.jsxs(E.Root,{allowsEmptyCollection:!0,menuTrigger:"focus",inputValue:p,onInputChange:c,onSelectionChange:o=>{var j;o!=null?(s(String(o)),c(((j=u.find(P=>P.id===String(o)))==null?void 0:j.name)??"")):(s(""),c(""))},className:"flex max-w-md flex-col gap-1",children:[e.jsx(V,{className:"text-sm font-medium text-[var(--otari-ink)]",children:t}),e.jsxs(E.InputGroup,{children:[e.jsx(W,{placeholder:i??"Search providers…",autoComplete:"off","data-1p-ignore":!0,"data-lpignore":"true",onFocus:o=>o.currentTarget.select()}),e.jsx(E.Trigger,{})]}),e.jsx(E.Popover,{children:e.jsx(ye,{items:d,className:"max-h-72 overflow-auto",children:o=>e.jsx(ke,{id:o.id,textValue:o.name,children:o.name})})}),n?e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:n}):null]})}function J({getPayload:t}){const a=ue(),s=t();return e.jsxs("div",{className:"flex flex-col gap-1.5",children:[e.jsx(g,{variant:"outline",isDisabled:s===null||a.isPending,onPress:()=>{s&&a.mutate(s)},children:a.isPending?"Testing…":"Test connection"}),e.jsx("span",{role:"status","aria-live":"polite",children:a.isPending?null:a.error?e.jsx("span",{className:"text-xs text-red-700",children:M(a.error)}):a.data?a.data.ok?e.jsxs("span",{className:"text-xs font-medium text-green-700",children:["Connected. ",a.data.model_count," model",a.data.model_count===1?"":"s"," available."]}):e.jsx("span",{className:"block max-w-md break-words text-xs text-red-700",children:a.data.error??"Connection failed."}):null})]})}function Pe({onClose:t}){var I;const a=Y(),[s,n]=x.useState(""),[i,l]=x.useState(""),[m,v]=x.useState(!1),[u,p]=x.useState(""),[c,f]=x.useState(""),h=ce(s),d=((I=h.data)==null?void 0:I.id)===s?h.data:void 0;x.useEffect(()=>{d&&p(d.default_api_base??"")},[d]);const y=(d==null?void 0:d.env_key_present)??!1,o=((d==null?void 0:d.requires_api_key)??!0)&&!y,j=c.trim()!==""&&c.trim()!==s,P=/[:/]/.test(c),k=s!==""&&!P&&(!o||i.trim()!=="")&&!a.isPending,w=()=>{k&&a.mutate({instance:j?c.trim():s,provider_type:j?s:null,api_base:u.trim()||null,api_key:i.trim()||null},{onSuccess:t})};return e.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsx(R,{error:a.error}),e.jsx(G,{label:"Provider",value:s,onChange:N=>{n(N),f(""),p("")},description:"Its endpoint is built in."}),e.jsx(B,{value:i,onChange:l,label:d&&!o?"API key (optional)":"API key",description:d?o?`${d.name}'s endpoint is built in — just add your key.`:y?`${d.env_key} is set on the server, so a key is optional here. Paste one to override it.`:`${d.name} needs no API key.`:"Stored encrypted. Requires OTARI_SECRET_KEY on the server."}),e.jsx("button",{type:"button",className:"self-start text-xs font-medium text-[var(--otari-brand-dark)]",onClick:()=>v(N=>!N),children:m?"Hide advanced":"Advanced (API base, rename)"}),m?e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsx(A,{label:"API base",value:u,onChange:p,placeholder:(d==null?void 0:d.default_api_base)??"https://…/v1",description:"Only if you route through a proxy. Blank uses the built-in default."}),e.jsx(A,{label:"Name",value:c,onChange:f,placeholder:s||"instance name",description:P?e.jsx("span",{className:"text-red-700",children:"A name cannot contain “:” or “/”."}):"Rename to run two instances of the same provider."})]}):null,e.jsxs("div",{className:"flex flex-wrap items-start gap-2",children:[e.jsx(g,{variant:"primary",isDisabled:!k,onPress:w,children:a.isPending?"Adding…":"Add provider"}),e.jsx(g,{variant:"ghost",onPress:t,children:"Cancel"}),e.jsx(J,{getPayload:()=>s===""?null:{instance:j?c.trim():s,provider_type:j?s:null,api_base:u.trim()||null,api_key:i.trim()||null}})]})]})}function Ne({onClose:t}){const a=Y(),[s,n]=x.useState(""),[i,l]=x.useState("openai-compatible"),[m,v]=x.useState(""),[u,p]=x.useState(""),c=/[:/]/.test(s),f=s.trim()!==""&&!c&&m.trim()!==""&&!a.isPending,h=()=>{f&&a.mutate({instance:s.trim(),provider_type:i||"openai-compatible",api_base:m.trim(),api_key:u.trim()||null},{onSuccess:t})};return e.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsx(R,{error:a.error}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsx(A,{label:"Name",value:s,onChange:n,placeholder:"my-local-llm",isRequired:!0,autoFocus:!0,description:c?e.jsx("span",{className:"text-red-700",children:"A name cannot contain “:” or “/”."}):"Call it whatever you want."}),e.jsx(G,{label:"Compatible with",value:i,onChange:l,includeCatalog:!1,description:"The API this endpoint speaks.",extra:[{id:"openai-compatible",name:"OpenAI"},{id:"anthropic-compatible",name:"Anthropic"}]})]}),e.jsx(A,{label:"API base",value:m,onChange:v,placeholder:"http://localhost:8000/v1",isRequired:!0,description:"The endpoint URL of your server."}),e.jsx(B,{value:u,onChange:p,label:"API key (optional)",description:"Many local backends need none. Stored encrypted."}),e.jsxs("div",{className:"flex flex-wrap items-start gap-2",children:[e.jsx(g,{variant:"primary",isDisabled:!f,onPress:h,children:a.isPending?"Adding…":"Add provider"}),e.jsx(g,{variant:"ghost",onPress:t,children:"Cancel"}),e.jsx(J,{getPayload:()=>s.trim()===""||m.trim()===""?null:{instance:s.trim(),provider_type:i||"openai-compatible",api_base:m.trim(),api_key:u.trim()||null}})]})]})}function Se({onClose:t}){const[a,s]=x.useState("known");return e.jsx(T,{children:e.jsxs(T.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsx("div",{className:"flex items-center justify-between",children:e.jsx("div",{className:"flex items-center gap-1 rounded-lg bg-[var(--otari-bg)] p-1",children:[["known","Known provider"],["custom","Custom endpoint"]].map(([n,i])=>e.jsx("button",{type:"button","aria-pressed":a===n,onClick:()=>s(n),className:a===n?"rounded-md bg-white px-3 py-1.5 text-sm font-medium text-[var(--otari-ink)] shadow-sm":"rounded-md px-3 py-1.5 text-sm text-[var(--otari-muted)] hover:text-[var(--otari-ink)]",children:i},n))})}),a==="known"?e.jsx(Pe,{onClose:t}):e.jsx(Ne,{onClose:t})]})})}function _e({provider:t,onClose:a}){const s=de(),[n,i]=x.useState(t.provider_type??""),[l,m]=x.useState(t.api_base??""),[v,u]=x.useState(!1),[p,c]=x.useState(""),f=()=>{if(s.isPending)return;const h={provider_type:n.trim()||null,api_base:l.trim()||null,expected_updated_at:t.updated_at};v&&p.trim()&&(h.api_key=p.trim()),s.mutate({instance:t.instance,body:h},{onSuccess:a})};return e.jsx(T,{children:e.jsxs(T.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsxs("div",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:["Edit ",e.jsx("code",{children:t.instance})]}),e.jsx(R,{error:s.error}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsx(A,{label:"Provider type",value:n,onChange:i,placeholder:"openai"}),e.jsx(A,{label:"API base",value:l,onChange:m,placeholder:"https://api.openai.com/v1"})]}),e.jsx("div",{className:"flex flex-col gap-2",children:v?e.jsxs(e.Fragment,{children:[e.jsx(B,{value:p,onChange:c,label:"New API key",description:"Stored encrypted. The old key is replaced when you save."}),e.jsx("button",{type:"button",className:"self-start text-xs font-medium text-[var(--otari-brand-dark)]",onClick:()=>{u(!1),c("")},children:"Keep the current key"})]}):e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsxs("span",{className:"text-sm text-[var(--otari-muted)]",children:["API key: ",e.jsx("code",{children:t.last4?`••••${t.last4}`:"none set"})]}),e.jsx(g,{size:"sm",variant:"outline",onPress:()=>u(!0),children:"Replace key"})]})}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(g,{variant:"primary",isDisabled:s.isPending,onPress:f,children:s.isPending?"Saving…":"Save changes"}),e.jsx(g,{variant:"ghost",onPress:a,children:"Cancel"})]})]})})}function Ce(t,a){const s=new Map((a??[]).map(l=>[l.instance,l])),n=new Map((t??[]).map(l=>[l.instance,l]));return[...new Set([...s.keys(),...n.keys()])].sort().map(l=>{const m=s.get(l);return{instance:l,source:m?"stored":"config",stored:m,meta:n.get(l)}})}function Ae({state:t}){return t?t.status==="pending"?e.jsxs("span",{className:"inline-flex items-center gap-1.5 text-xs text-[var(--otari-muted)]",children:[e.jsx(fe,{size:"sm"})," Testing…"]}):t.ok?e.jsxs("span",{className:"text-xs font-medium text-green-700",children:["Connected. ",t.model_count," model",t.model_count===1?"":"s"," available."]}):e.jsx("span",{className:"block max-w-xs break-words text-xs text-red-700",children:t.error??"Connection failed."}):null}function Te({health:t}){if(!t)return e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"—"});const a=t.ok?"border-green-200 bg-green-50 text-green-700":"border-red-200 bg-red-50 text-red-700",s=t.checked_at?`Last checked ${U(t.checked_at)}`:"Not checked yet",n=t.ok?s:`${t.error??"Unreachable"} · ${s}`;return e.jsxs("span",{title:n,className:`inline-flex items-center gap-1.5 rounded-full border px-2.5 py-0.5 text-xs font-medium ${a}`,children:[e.jsx("span",{"aria-hidden":!0,className:`h-1.5 w-1.5 rounded-full ${t.ok?"bg-green-500":"bg-red-500"}`}),t.ok?"Reachable":"Unreachable"]})}function we({healthy:t,total:a,checkedAt:s}){const n=t===a,i=le();return e.jsxs("div",{className:"flex flex-wrap items-center gap-3 rounded-xl border border-[var(--otari-line)] bg-[var(--otari-surface)] px-4 py-2.5 text-sm",children:[e.jsx("span",{"aria-hidden":!0,className:`h-2 w-2 rounded-full ${n?"bg-green-500":"bg-red-500"}`}),e.jsxs("span",{className:"font-medium text-[var(--otari-ink)]",children:[t," of ",a," provider",a===1?"":"s"," reachable"]}),s?e.jsxs("span",{className:"text-[var(--otari-muted)]",children:["Last checked ",U(s)]}):null,e.jsx(g,{size:"sm",variant:"ghost",className:"ml-auto",isDisabled:i.isPending,onPress:()=>i.mutate(),children:i.isPending?"Re-checking…":"Re-check all"})]})}function K({n:t,title:a,children:s}){return e.jsxs("li",{className:"flex gap-3",children:[e.jsx("span",{className:"flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-[var(--otari-brand-tint)] text-xs font-semibold text-[var(--otari-brand-dark)]",children:t}),e.jsxs("div",{className:"text-sm",children:[e.jsx("div",{className:"font-medium text-[var(--otari-ink)]",children:a}),e.jsx("div",{className:"text-[var(--otari-muted)]",children:s})]})]})}function Ie({onAddProvider:t,needsPricing:a,onEnablePricing:s,enabling:n,secretKeyConfigured:i}){return e.jsx(T,{children:e.jsxs(T.Content,{className:"flex flex-col gap-4 p-6",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-semibold text-[var(--otari-ink)]",children:"Welcome to Otari"}),e.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:"You are signed in. Add a provider to start serving models: three quick steps."})]}),e.jsxs("ol",{className:"flex flex-col gap-3",children:[e.jsxs(K,{n:1,title:"Add a provider",children:["Enter a provider name (like ",e.jsx("code",{children:"openai"}),") and its API key. Keys are encrypted at rest."]}),e.jsxs(K,{n:2,title:"Test the connection",children:["Use ",e.jsx("strong",{children:"Test"})," on the provider row to confirm the key works and see how many models it serves."]}),e.jsxs(K,{n:3,title:"Send your first request",children:["Point your app at ",e.jsx("code",{children:"/v1"})," on this gateway with the API key printed in the server logs (",e.jsx("code",{children:"gw-…"}),"). See the"," ",e.jsx("a",{href:"/welcome",className:"font-medium text-[var(--otari-brand-dark)]",children:"quickstart"}),"."]})]}),a?e.jsxs("p",{className:"text-sm text-[var(--otari-muted)]",children:["Tip: ",e.jsx("code",{children:"require_pricing"})," is on, so requests are rejected until pricing is set."," ",e.jsx("button",{type:"button",className:"font-medium text-[var(--otari-brand-dark)] disabled:opacity-50",disabled:n,onClick:s,children:"Enable default pricing"})," ","to meter new models with public rates."]}):null,e.jsx("div",{children:e.jsx(g,{variant:"primary",isDisabled:!i,onPress:t,children:"Add your first provider"})})]})})}function $e(){var N,L,D,$;const t=X(),a=Z(),s=ee(),n=se(),i=te(),l=ae(),m=ne(),[v,u]=x.useState(!1),[p,c]=x.useState(null),[f,h]=x.useState({}),d=Ce((N=t.data)==null?void 0:N.providers,a.data),y=new Map((((L=n.data)==null?void 0:L.providers)??[]).map(r=>[r.instance,r])),o=t.isLoading||a.isLoading,j=((D=a.data)==null?void 0:D.find(r=>r.instance===p))??null,P=(($=s.data)==null?void 0:$.require_pricing)===!0&&s.data.default_pricing===!1,k=s.data?s.data.secret_key_configured!==!1:!s.isError,w=!o&&d.length===0&&!v,I=r=>{h(b=>({...b,[r]:{status:"pending"}})),l.mutate(r,{onSuccess:b=>h(S=>({...S,[r]:{status:"done",...b}})),onError:b=>h(S=>({...S,[r]:{status:"done",ok:!1,model_count:0,error:M(b)}}))})};return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(re,{title:"Providers",description:"Add provider API keys here to serve models without editing config.yml. Keys are encrypted at rest.",action:v||w?null:e.jsx(g,{variant:"primary",isDisabled:!k,onPress:()=>{c(null),u(!0)},children:"Add provider"})}),e.jsx(R,{error:t.error??a.error??s.error??n.error??m.error??i.error}),k?null:e.jsxs(ie,{tone:"warning",children:[e.jsx("code",{children:"OTARI_SECRET_KEY"})," is not set, so provider keys can't be encrypted at rest and adding providers from the dashboard is disabled. Set it on the server and restart to add providers here. Providers defined in"," ",e.jsx("code",{children:"config.yml"})," keep working without it."]}),w?e.jsx(Ie,{onAddProvider:()=>{c(null),u(!0)},needsPricing:P,onEnablePricing:()=>m.mutate({default_pricing:!0}),enabling:m.isPending,secretKeyConfigured:k}):null,v&&k?e.jsx(Se,{onClose:()=>u(!1)}):null,j?e.jsx(_e,{provider:j,onClose:()=>c(null)}):null,!o&&d.length>0&&n.data&&n.data.total>0?e.jsx(we,{healthy:n.data.healthy,total:n.data.total,checkedAt:n.data.checked_at}):null,e.jsxs(xe,{children:[e.jsx(pe,{children:e.jsxs("tr",{children:[e.jsx(_,{children:"Provider"}),e.jsx(_,{children:"Type"}),e.jsx(_,{children:"Source"}),e.jsx(_,{children:"API key"}),e.jsx(_,{children:"Status"}),e.jsx(_,{className:"text-right",children:"Actions"})]})}),e.jsx("tbody",{children:o?e.jsx(he,{colSpan:6}):d.length===0?e.jsx(ve,{colSpan:6,children:"No providers yet. Add your first provider to start serving models."}):d.map(r=>{var b,S,O,q,F,H;return e.jsxs(ge,{children:[e.jsx(C,{className:"font-medium",children:e.jsx(Q,{to:`/models?provider=${encodeURIComponent(r.instance)}`,className:"text-[var(--otari-ink)] hover:text-[var(--otari-brand-dark)] hover:underline",children:r.instance})}),e.jsx(C,{className:"text-[var(--otari-muted)]",children:((b=r.meta)==null?void 0:b.provider_type)??((S=r.stored)==null?void 0:S.provider_type)??r.instance}),e.jsx(C,{children:r.source==="stored"?e.jsx(z,{size:"sm",color:"accent",children:"stored"}):e.jsx(z,{size:"sm",color:"default",children:"config"})}),e.jsx(C,{className:"text-[var(--otari-muted)]",children:r.source==="stored"?r.stored&&!r.stored.decryptable?e.jsx("span",{className:"text-amber-700",title:"This key can't be decrypted with the current OTARI_SECRET_KEY. Replace the key, or restore the original OTARI_SECRET_KEY.",children:"⚠ key unreadable"}):e.jsx("code",{children:(O=r.stored)!=null&&O.last4?`••••${r.stored.last4}`:"none set"}):(q=r.meta)!=null&&q.env_key?e.jsxs("span",{children:["via ",e.jsx("code",{children:r.meta.env_key})]}):"config.yml"}),e.jsx(C,{children:e.jsx(Te,{health:y.get(r.instance)})}),e.jsx(C,{children:r.source==="stored"?e.jsxs("div",{className:"flex flex-col items-end gap-1.5",children:[e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx(g,{size:"sm",variant:"outline",isDisabled:((F=f[r.instance])==null?void 0:F.status)==="pending"||((H=r.stored)==null?void 0:H.decryptable)===!1,onPress:()=>I(r.instance),children:"Test"}),e.jsx(g,{size:"sm",variant:"ghost",onPress:()=>{u(!1),c(r.instance)},children:"Edit"}),e.jsx(oe,{confirmLabel:"Delete",isPending:i.isPending,onConfirm:()=>i.mutate(r.instance),children:"Delete"})]}),e.jsx(Ae,{state:f[r.instance]})]}):e.jsx("span",{className:"block text-right text-xs text-[var(--otari-muted)]",children:"managed in config.yml"})})]},r.instance)})})]})]})}export{$e as ProvidersPage}; +import{j as e}from"./tanstack-query-1t81HyiD.js";import{r as x,L as Q}from"./react-dgEcD0HR.js";import{J as X,R as Z,B as ee,K as se,T as te,U as ae,V as ne,P as re,E as R,I as ie,C as oe,W as de,X as le,Q as U,h as M,Y,Z as ce,_ as me,$ as ue}from"./index-DAVt9uB3.js";import{F as A}from"./Field-HzRk1KDP.js";import{T as xe,a as pe,b as _,L as he,c as ve,d as ge,e as C}from"./Table-CLdjdyTx.js";import{B as g,f as z,d as T,S as fe,T as je,L as V,I as W,D as be,C as E,a as ye,b as ke}from"./heroui-BX6JwHY-.js";function B({value:t,onChange:a,label:s,placeholder:n,description:i}){return e.jsxs(je,{value:t,onChange:a,className:"flex max-w-md flex-col gap-1",children:[e.jsx(V,{className:"text-sm font-medium text-[var(--otari-ink)]",children:s}),e.jsx(W,{type:"password",placeholder:n??"sk-…",autoComplete:"off",autoCorrect:"off",autoCapitalize:"off",spellCheck:!1,"data-1p-ignore":!0,"data-lpignore":"true"}),i?e.jsx(be,{className:"text-xs text-[var(--otari-muted)]",children:i}):null]})}function G({label:t,value:a,onChange:s,description:n,placeholder:i,extra:l=[],includeCatalog:m=!0}){var y;const v=me(),u=x.useMemo(()=>m?[...l,...(v.data??[]).map(o=>({id:o.id,name:o.name}))]:l,[v.data,l,m]),[p,c]=x.useState(()=>{var o;return((o=u.find(j=>j.id===a))==null?void 0:o.name)??""}),f=((y=u.find(o=>o.id===a))==null?void 0:y.name)??"",h=p.trim()===f.trim()?"":p.trim().toLowerCase(),d=u.filter(o=>!h||o.name.toLowerCase().includes(h)||o.id.toLowerCase().includes(h)).slice(0,50);return e.jsxs(E.Root,{allowsEmptyCollection:!0,menuTrigger:"focus",inputValue:p,onInputChange:c,onSelectionChange:o=>{var j;o!=null?(s(String(o)),c(((j=u.find(P=>P.id===String(o)))==null?void 0:j.name)??"")):(s(""),c(""))},className:"flex max-w-md flex-col gap-1",children:[e.jsx(V,{className:"text-sm font-medium text-[var(--otari-ink)]",children:t}),e.jsxs(E.InputGroup,{children:[e.jsx(W,{placeholder:i??"Search providers…",autoComplete:"off","data-1p-ignore":!0,"data-lpignore":"true",onFocus:o=>o.currentTarget.select()}),e.jsx(E.Trigger,{})]}),e.jsx(E.Popover,{children:e.jsx(ye,{items:d,className:"max-h-72 overflow-auto",children:o=>e.jsx(ke,{id:o.id,textValue:o.name,children:o.name})})}),n?e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:n}):null]})}function J({getPayload:t}){const a=ue(),s=t();return e.jsxs("div",{className:"flex flex-col gap-1.5",children:[e.jsx(g,{variant:"outline",isDisabled:s===null||a.isPending,onPress:()=>{s&&a.mutate(s)},children:a.isPending?"Testing…":"Test connection"}),e.jsx("span",{role:"status","aria-live":"polite",children:a.isPending?null:a.error?e.jsx("span",{className:"text-xs text-red-700",children:M(a.error)}):a.data?a.data.ok?e.jsxs("span",{className:"text-xs font-medium text-green-700",children:["Connected. ",a.data.model_count," model",a.data.model_count===1?"":"s"," available."]}):e.jsx("span",{className:"block max-w-md break-words text-xs text-red-700",children:a.data.error??"Connection failed."}):null})]})}function Pe({onClose:t}){var I;const a=Y(),[s,n]=x.useState(""),[i,l]=x.useState(""),[m,v]=x.useState(!1),[u,p]=x.useState(""),[c,f]=x.useState(""),h=ce(s),d=((I=h.data)==null?void 0:I.id)===s?h.data:void 0;x.useEffect(()=>{d&&p(d.default_api_base??"")},[d]);const y=(d==null?void 0:d.env_key_present)??!1,o=((d==null?void 0:d.requires_api_key)??!0)&&!y,j=c.trim()!==""&&c.trim()!==s,P=/[:/]/.test(c),k=s!==""&&!P&&(!o||i.trim()!=="")&&!a.isPending,w=()=>{k&&a.mutate({instance:j?c.trim():s,provider_type:j?s:null,api_base:u.trim()||null,api_key:i.trim()||null},{onSuccess:t})};return e.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsx(R,{error:a.error}),e.jsx(G,{label:"Provider",value:s,onChange:N=>{n(N),f(""),p("")},description:"Its endpoint is built in."}),e.jsx(B,{value:i,onChange:l,label:d&&!o?"API key (optional)":"API key",description:d?o?`${d.name}'s endpoint is built in — just add your key.`:y?`${d.env_key} is set on the server, so a key is optional here. Paste one to override it.`:`${d.name} needs no API key.`:"Stored encrypted. Requires OTARI_SECRET_KEY on the server."}),e.jsx("button",{type:"button",className:"self-start text-xs font-medium text-[var(--otari-brand-dark)]",onClick:()=>v(N=>!N),children:m?"Hide advanced":"Advanced (API base, rename)"}),m?e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsx(A,{label:"API base",value:u,onChange:p,placeholder:(d==null?void 0:d.default_api_base)??"https://…/v1",description:"Only if you route through a proxy. Blank uses the built-in default."}),e.jsx(A,{label:"Name",value:c,onChange:f,placeholder:s||"instance name",description:P?e.jsx("span",{className:"text-red-700",children:"A name cannot contain “:” or “/”."}):"Rename to run two instances of the same provider."})]}):null,e.jsxs("div",{className:"flex flex-wrap items-start gap-2",children:[e.jsx(g,{variant:"primary",isDisabled:!k,onPress:w,children:a.isPending?"Adding…":"Add provider"}),e.jsx(g,{variant:"ghost",onPress:t,children:"Cancel"}),e.jsx(J,{getPayload:()=>s===""?null:{instance:j?c.trim():s,provider_type:j?s:null,api_base:u.trim()||null,api_key:i.trim()||null}})]})]})}function Ne({onClose:t}){const a=Y(),[s,n]=x.useState(""),[i,l]=x.useState("openai-compatible"),[m,v]=x.useState(""),[u,p]=x.useState(""),c=/[:/]/.test(s),f=s.trim()!==""&&!c&&m.trim()!==""&&!a.isPending,h=()=>{f&&a.mutate({instance:s.trim(),provider_type:i||"openai-compatible",api_base:m.trim(),api_key:u.trim()||null},{onSuccess:t})};return e.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsx(R,{error:a.error}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsx(A,{label:"Name",value:s,onChange:n,placeholder:"my-local-llm",isRequired:!0,autoFocus:!0,description:c?e.jsx("span",{className:"text-red-700",children:"A name cannot contain “:” or “/”."}):"Call it whatever you want."}),e.jsx(G,{label:"Compatible with",value:i,onChange:l,includeCatalog:!1,description:"The API this endpoint speaks.",extra:[{id:"openai-compatible",name:"OpenAI"},{id:"anthropic-compatible",name:"Anthropic"}]})]}),e.jsx(A,{label:"API base",value:m,onChange:v,placeholder:"http://localhost:8000/v1",isRequired:!0,description:"The endpoint URL of your server."}),e.jsx(B,{value:u,onChange:p,label:"API key (optional)",description:"Many local backends need none. Stored encrypted."}),e.jsxs("div",{className:"flex flex-wrap items-start gap-2",children:[e.jsx(g,{variant:"primary",isDisabled:!f,onPress:h,children:a.isPending?"Adding…":"Add provider"}),e.jsx(g,{variant:"ghost",onPress:t,children:"Cancel"}),e.jsx(J,{getPayload:()=>s.trim()===""||m.trim()===""?null:{instance:s.trim(),provider_type:i||"openai-compatible",api_base:m.trim(),api_key:u.trim()||null}})]})]})}function Se({onClose:t}){const[a,s]=x.useState("known");return e.jsx(T,{children:e.jsxs(T.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsx("div",{className:"flex items-center justify-between",children:e.jsx("div",{className:"flex items-center gap-1 rounded-lg bg-[var(--otari-bg)] p-1",children:[["known","Known provider"],["custom","Custom endpoint"]].map(([n,i])=>e.jsx("button",{type:"button","aria-pressed":a===n,onClick:()=>s(n),className:a===n?"rounded-md bg-white px-3 py-1.5 text-sm font-medium text-[var(--otari-ink)] shadow-sm":"rounded-md px-3 py-1.5 text-sm text-[var(--otari-muted)] hover:text-[var(--otari-ink)]",children:i},n))})}),a==="known"?e.jsx(Pe,{onClose:t}):e.jsx(Ne,{onClose:t})]})})}function _e({provider:t,onClose:a}){const s=de(),[n,i]=x.useState(t.provider_type??""),[l,m]=x.useState(t.api_base??""),[v,u]=x.useState(!1),[p,c]=x.useState(""),f=()=>{if(s.isPending)return;const h={provider_type:n.trim()||null,api_base:l.trim()||null,expected_updated_at:t.updated_at};v&&p.trim()&&(h.api_key=p.trim()),s.mutate({instance:t.instance,body:h},{onSuccess:a})};return e.jsx(T,{children:e.jsxs(T.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsxs("div",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:["Edit ",e.jsx("code",{children:t.instance})]}),e.jsx(R,{error:s.error}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsx(A,{label:"Provider type",value:n,onChange:i,placeholder:"openai"}),e.jsx(A,{label:"API base",value:l,onChange:m,placeholder:"https://api.openai.com/v1"})]}),e.jsx("div",{className:"flex flex-col gap-2",children:v?e.jsxs(e.Fragment,{children:[e.jsx(B,{value:p,onChange:c,label:"New API key",description:"Stored encrypted. The old key is replaced when you save."}),e.jsx("button",{type:"button",className:"self-start text-xs font-medium text-[var(--otari-brand-dark)]",onClick:()=>{u(!1),c("")},children:"Keep the current key"})]}):e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsxs("span",{className:"text-sm text-[var(--otari-muted)]",children:["API key: ",e.jsx("code",{children:t.last4?`••••${t.last4}`:"none set"})]}),e.jsx(g,{size:"sm",variant:"outline",onPress:()=>u(!0),children:"Replace key"})]})}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(g,{variant:"primary",isDisabled:s.isPending,onPress:f,children:s.isPending?"Saving…":"Save changes"}),e.jsx(g,{variant:"ghost",onPress:a,children:"Cancel"})]})]})})}function Ce(t,a){const s=new Map((a??[]).map(l=>[l.instance,l])),n=new Map((t??[]).map(l=>[l.instance,l]));return[...new Set([...s.keys(),...n.keys()])].sort().map(l=>{const m=s.get(l);return{instance:l,source:m?"stored":"config",stored:m,meta:n.get(l)}})}function Ae({state:t}){return t?t.status==="pending"?e.jsxs("span",{className:"inline-flex items-center gap-1.5 text-xs text-[var(--otari-muted)]",children:[e.jsx(fe,{size:"sm"})," Testing…"]}):t.ok?e.jsxs("span",{className:"text-xs font-medium text-green-700",children:["Connected. ",t.model_count," model",t.model_count===1?"":"s"," available."]}):e.jsx("span",{className:"block max-w-xs break-words text-xs text-red-700",children:t.error??"Connection failed."}):null}function Te({health:t}){if(!t)return e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"—"});const a=t.ok?"border-green-200 bg-green-50 text-green-700":"border-red-200 bg-red-50 text-red-700",s=t.checked_at?`Last checked ${U(t.checked_at)}`:"Not checked yet",n=t.ok?s:`${t.error??"Unreachable"} · ${s}`;return e.jsxs("span",{title:n,className:`inline-flex items-center gap-1.5 rounded-full border px-2.5 py-0.5 text-xs font-medium ${a}`,children:[e.jsx("span",{"aria-hidden":!0,className:`h-1.5 w-1.5 rounded-full ${t.ok?"bg-green-500":"bg-red-500"}`}),t.ok?"Reachable":"Unreachable"]})}function we({healthy:t,total:a,checkedAt:s}){const n=t===a,i=le();return e.jsxs("div",{className:"flex flex-wrap items-center gap-3 rounded-xl border border-[var(--otari-line)] bg-[var(--otari-surface)] px-4 py-2.5 text-sm",children:[e.jsx("span",{"aria-hidden":!0,className:`h-2 w-2 rounded-full ${n?"bg-green-500":"bg-red-500"}`}),e.jsxs("span",{className:"font-medium text-[var(--otari-ink)]",children:[t," of ",a," provider",a===1?"":"s"," reachable"]}),s?e.jsxs("span",{className:"text-[var(--otari-muted)]",children:["Last checked ",U(s)]}):null,e.jsx(g,{size:"sm",variant:"ghost",className:"ml-auto",isDisabled:i.isPending,onPress:()=>i.mutate(),children:i.isPending?"Re-checking…":"Re-check all"})]})}function K({n:t,title:a,children:s}){return e.jsxs("li",{className:"flex gap-3",children:[e.jsx("span",{className:"flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-[var(--otari-brand-tint)] text-xs font-semibold text-[var(--otari-brand-dark)]",children:t}),e.jsxs("div",{className:"text-sm",children:[e.jsx("div",{className:"font-medium text-[var(--otari-ink)]",children:a}),e.jsx("div",{className:"text-[var(--otari-muted)]",children:s})]})]})}function Ie({onAddProvider:t,needsPricing:a,onEnablePricing:s,enabling:n,secretKeyConfigured:i}){return e.jsx(T,{children:e.jsxs(T.Content,{className:"flex flex-col gap-4 p-6",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-semibold text-[var(--otari-ink)]",children:"Welcome to Otari"}),e.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:"You are signed in. Add a provider to start serving models: three quick steps."})]}),e.jsxs("ol",{className:"flex flex-col gap-3",children:[e.jsxs(K,{n:1,title:"Add a provider",children:["Enter a provider name (like ",e.jsx("code",{children:"openai"}),") and its API key. Keys are encrypted at rest."]}),e.jsxs(K,{n:2,title:"Test the connection",children:["Use ",e.jsx("strong",{children:"Test"})," on the provider row to confirm the key works and see how many models it serves."]}),e.jsxs(K,{n:3,title:"Send your first request",children:["Point your app at ",e.jsx("code",{children:"/v1"})," on this gateway with the API key printed in the server logs (",e.jsx("code",{children:"gw-…"}),"). See the"," ",e.jsx("a",{href:"/welcome",className:"font-medium text-[var(--otari-brand-dark)]",children:"quickstart"}),"."]})]}),a?e.jsxs("p",{className:"text-sm text-[var(--otari-muted)]",children:["Tip: ",e.jsx("code",{children:"require_pricing"})," is on, so requests are rejected until pricing is set."," ",e.jsx("button",{type:"button",className:"font-medium text-[var(--otari-brand-dark)] disabled:opacity-50",disabled:n,onClick:s,children:"Enable default pricing"})," ","to meter new models with public rates."]}):null,e.jsx("div",{children:e.jsx(g,{variant:"primary",isDisabled:!i,onPress:t,children:"Add your first provider"})})]})})}function $e(){var N,L,D,$;const t=X(),a=Z(),s=ee(),n=se(),i=te(),l=ae(),m=ne(),[v,u]=x.useState(!1),[p,c]=x.useState(null),[f,h]=x.useState({}),d=Ce((N=t.data)==null?void 0:N.providers,a.data),y=new Map((((L=n.data)==null?void 0:L.providers)??[]).map(r=>[r.instance,r])),o=t.isLoading||a.isLoading,j=((D=a.data)==null?void 0:D.find(r=>r.instance===p))??null,P=(($=s.data)==null?void 0:$.require_pricing)===!0&&s.data.default_pricing===!1,k=s.data?s.data.secret_key_configured!==!1:!s.isError,w=!o&&d.length===0&&!v,I=r=>{h(b=>({...b,[r]:{status:"pending"}})),l.mutate(r,{onSuccess:b=>h(S=>({...S,[r]:{status:"done",...b}})),onError:b=>h(S=>({...S,[r]:{status:"done",ok:!1,model_count:0,error:M(b)}}))})};return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(re,{title:"Providers",description:"Add provider API keys here to serve models without editing config.yml. Keys are encrypted at rest.",action:v||w?null:e.jsx(g,{variant:"primary",isDisabled:!k,onPress:()=>{c(null),u(!0)},children:"Add provider"})}),e.jsx(R,{error:t.error??a.error??s.error??n.error??m.error??i.error}),k?null:e.jsxs(ie,{tone:"warning",children:[e.jsx("code",{children:"OTARI_SECRET_KEY"})," is not set, so provider keys can't be encrypted at rest and adding providers from the dashboard is disabled. Set it on the server and restart to add providers here. Providers defined in"," ",e.jsx("code",{children:"config.yml"})," keep working without it."]}),w?e.jsx(Ie,{onAddProvider:()=>{c(null),u(!0)},needsPricing:P,onEnablePricing:()=>m.mutate({default_pricing:!0}),enabling:m.isPending,secretKeyConfigured:k}):null,v&&k?e.jsx(Se,{onClose:()=>u(!1)}):null,j?e.jsx(_e,{provider:j,onClose:()=>c(null)}):null,!o&&d.length>0&&n.data&&n.data.total>0?e.jsx(we,{healthy:n.data.healthy,total:n.data.total,checkedAt:n.data.checked_at}):null,e.jsxs(xe,{children:[e.jsx(pe,{children:e.jsxs("tr",{children:[e.jsx(_,{children:"Provider"}),e.jsx(_,{children:"Type"}),e.jsx(_,{children:"Source"}),e.jsx(_,{children:"API key"}),e.jsx(_,{children:"Status"}),e.jsx(_,{className:"text-right",children:"Actions"})]})}),e.jsx("tbody",{children:o?e.jsx(he,{colSpan:6}):d.length===0?e.jsx(ve,{colSpan:6,children:"No providers yet. Add your first provider to start serving models."}):d.map(r=>{var b,S,O,q,F,H;return e.jsxs(ge,{children:[e.jsx(C,{className:"font-medium",children:e.jsx(Q,{to:`/models?provider=${encodeURIComponent(r.instance)}`,className:"text-[var(--otari-ink)] hover:text-[var(--otari-brand-dark)] hover:underline",children:r.instance})}),e.jsx(C,{className:"text-[var(--otari-muted)]",children:((b=r.meta)==null?void 0:b.provider_type)??((S=r.stored)==null?void 0:S.provider_type)??r.instance}),e.jsx(C,{children:r.source==="stored"?e.jsx(z,{size:"sm",color:"accent",children:"stored"}):e.jsx(z,{size:"sm",color:"default",children:"config"})}),e.jsx(C,{className:"text-[var(--otari-muted)]",children:r.source==="stored"?r.stored&&!r.stored.decryptable?e.jsx("span",{className:"text-amber-700",title:"This key can't be decrypted with the current OTARI_SECRET_KEY. Replace the key, or restore the original OTARI_SECRET_KEY.",children:"⚠ key unreadable"}):e.jsx("code",{children:(O=r.stored)!=null&&O.last4?`••••${r.stored.last4}`:"none set"}):(q=r.meta)!=null&&q.env_key?e.jsxs("span",{children:["via ",e.jsx("code",{children:r.meta.env_key})]}):"config.yml"}),e.jsx(C,{children:e.jsx(Te,{health:y.get(r.instance)})}),e.jsx(C,{children:r.source==="stored"?e.jsxs("div",{className:"flex flex-col items-end gap-1.5",children:[e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx(g,{size:"sm",variant:"outline",isDisabled:((F=f[r.instance])==null?void 0:F.status)==="pending"||((H=r.stored)==null?void 0:H.decryptable)===!1,onPress:()=>I(r.instance),children:"Test"}),e.jsx(g,{size:"sm",variant:"ghost",onPress:()=>{u(!1),c(r.instance)},children:"Edit"}),e.jsx(oe,{confirmLabel:"Delete",isPending:i.isPending,onConfirm:()=>i.mutate(r.instance),children:"Delete"})]}),e.jsx(Ae,{state:f[r.instance]})]}):e.jsx("span",{className:"block text-right text-xs text-[var(--otari-muted)]",children:"managed in config.yml"})})]},r.instance)})})]})]})}export{$e as ProvidersPage}; diff --git a/src/gateway/static/dashboard/assets/SettingsPage-UC2EHTIR.js b/src/gateway/static/dashboard/assets/SettingsPage-BPWZBXQE.js similarity index 99% rename from src/gateway/static/dashboard/assets/SettingsPage-UC2EHTIR.js rename to src/gateway/static/dashboard/assets/SettingsPage-BPWZBXQE.js index 009e4f01..17e45e67 100644 --- a/src/gateway/static/dashboard/assets/SettingsPage-UC2EHTIR.js +++ b/src/gateway/static/dashboard/assets/SettingsPage-BPWZBXQE.js @@ -1 +1 @@ -import{j as e}from"./tanstack-query-1t81HyiD.js";import{r as u}from"./react-dgEcD0HR.js";import{B as R,V as C,P,E as y,a0 as E,a1 as T,a2 as _,F as D,a3 as A,R as O,a4 as F,I as w}from"./index-DHQmS-9o.js";import{d as v,B as h,A as d,g as I,I as K}from"./heroui-BX6JwHY-.js";function b(t,r){return{[t]:r}}function z(t,r){let s=0;for(const a of r)if(a===t[s]&&(s+=1),s===t.length)return!0;return t.length===0}function M(t,r){const s=r.trim().toLowerCase();if(s==="")return!0;const a=`${t.key} ${t.description??""} ${t.group}`.toLowerCase(),n=t.key.toLowerCase().replace(/[^a-z0-9]/g,"");return s.split(/\s+/).every(i=>a.includes(i)||z(i,n))}function B({checked:t,onChange:r,label:s,disabled:a}){return e.jsx("button",{type:"button",role:"switch","aria-checked":t,"aria-label":s,disabled:a,onClick:()=>r(!t),className:`relative inline-flex h-6 w-11 shrink-0 items-center rounded-full transition-colors disabled:opacity-50 ${t?"bg-[var(--otari-brand)]":"bg-[var(--otari-line)]"}`,children:e.jsx("span",{className:`inline-block h-5 w-5 transform rounded-full bg-white shadow transition-transform ${t?"translate-x-5":"translate-x-0.5"}`})})}function L({field:t,onSave:r,disabled:s}){const a=typeof t.value=="number"?t.value:0,[n,i]=u.useState(String(a)),o=t.type==="float";u.useEffect(()=>{i(String(a))},[a]);const c=Number(n),p=n.trim()!==""&&Number.isFinite(c)&&(o||Number.isInteger(c)),m=t.minimum??void 0,x=t.exclusive_minimum??void 0,g=x!==void 0?c>x:m!==void 0?c>=m:c>=0,l=p&&g&&c!==a;return e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(K,{type:"number",min:"0",step:o?"any":"1",inputMode:o?"decimal":"numeric","aria-label":t.key,value:n,disabled:s,onChange:f=>i(f.target.value),className:"w-28 rounded-md border border-[var(--otari-line)] bg-white px-2 py-1 text-right text-sm tabular-nums focus:border-[var(--otari-brand)] focus:outline-none disabled:opacity-50"}),e.jsx(h,{size:"sm",variant:"primary","aria-label":`Save ${t.key}`,isDisabled:s||!l,onPress:()=>r(c),children:"Save"})]})}function $({field:t,onSave:r,disabled:s}){const a=typeof t.value=="string"?t.value:"",[n,i]=u.useState(a);u.useEffect(()=>{i(a)},[a]);const o=n!==a;return e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("input",{type:"text","aria-label":t.key,value:n,disabled:s,placeholder:"unset",onChange:c=>i(c.target.value),className:"w-56 rounded-md border border-[var(--otari-line)] bg-white px-2 py-1 text-sm focus:border-[var(--otari-brand)] focus:outline-none disabled:opacity-50"}),e.jsx(h,{size:"sm",variant:"primary","aria-label":`Save ${t.key}`,isDisabled:s||!o,onPress:()=>r(n.trim()===""?null:n),children:"Save"})]})}function H(t){const{value:r}=t;return r==null?"unset":typeof r=="boolean"?r?"on":"off":Array.isArray(r)?r.length?r.join(", "):"none":String(r)}function Y({field:t,patch:r,disabled:s}){return t.settable?t.type==="bool"?e.jsx(B,{checked:t.value===!0,onChange:a=>r(b(t.key,a)),label:t.key,disabled:s}):t.options&&t.options.length>0?e.jsx(D,{ariaLabel:t.key,value:String(t.value??""),onChange:a=>r(b(t.key,a)),options:t.options.map(a=>({value:a,label:a}))}):t.type==="int"||t.type==="float"?e.jsx(L,{field:t,onSave:a=>r(b(t.key,a)),disabled:s}):e.jsx($,{field:t,onSave:a=>r(b(t.key,a)),disabled:s}):e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-sm tabular-nums text-[var(--otari-ink)]",children:H(t)}),e.jsx("span",{className:"rounded-full border border-[var(--otari-line)] px-2 py-0.5 text-xs text-[var(--otari-muted)]",children:"startup-only"})]})}function q({field:t,patch:r,disabled:s}){return e.jsxs("div",{className:"flex items-start justify-between gap-6 py-4",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("code",{className:"text-sm font-medium text-[var(--otari-ink)]",children:t.key}),t.description?e.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:t.description}):null]}),e.jsx("div",{className:"shrink-0 pt-0.5",children:e.jsx(Y,{field:t,patch:r,disabled:s})})]})}function V({value:t,fieldRef:r}){const s=u.useRef(null),a=r??s,[n,i]=u.useState(!1),[o,c]=u.useState(!1),p=async()=>{var m,x,g;(m=a.current)==null||m.focus(),(x=a.current)==null||x.select();try{if((g=navigator.clipboard)!=null&&g.writeText){await navigator.clipboard.writeText(t),i(!0),c(!1),window.setTimeout(()=>i(!1),2e3);return}}catch{}c(!0)};return e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-xs font-medium text-[var(--otari-muted)]",children:"New master key"}),e.jsx(h,{size:"sm",variant:"outline",onPress:p,children:n?"Copied":"Copy"})]}),e.jsx("input",{ref:a,readOnly:!0,value:t,onFocus:m=>m.currentTarget.select(),autoComplete:"off",autoCorrect:"off",autoCapitalize:"off",spellCheck:!1,"data-1p-ignore":!0,"data-lpignore":"true"}),e.jsx("span",{"aria-live":"polite",className:"text-xs text-[var(--otari-brand-dark)]",children:n?"Copied to clipboard.":""}),o?e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"Selected. Press Ctrl/Cmd-C to copy."}):null]})}function U({masterKey:t,error:r,isPending:s,onRegenerate:a,onClose:n}){const i=u.useRef(null);return u.useEffect(()=>{var o,c;t!==void 0&&((o=i.current)==null||o.focus(),(c=i.current)==null||c.select())},[t]),e.jsx(d.Backdrop,{children:e.jsx(d.Container,{placement:"center",size:"lg",children:e.jsxs(d.Dialog,{children:[e.jsx(d.Header,{children:e.jsx(d.Heading,{children:t!==void 0?"Master key regenerated":"Regenerate master key?"})}),e.jsx(d.Body,{className:"flex flex-col gap-4",children:t!==void 0?e.jsxs(e.Fragment,{children:[e.jsx(w,{tone:"warning",children:"Copy this key now. It is shown once and cannot be retrieved again after you close this dialog."}),e.jsx("p",{className:"text-sm text-[var(--otari-muted)]",children:"The previous master key has stopped working. This browser tab now uses the new key."}),e.jsx(V,{value:t,fieldRef:i})]}):e.jsxs(e.Fragment,{children:[e.jsx(w,{tone:"warning",children:"This immediately invalidates the current dashboard master key. Other signed-in dashboard sessions will need the new key to continue."}),e.jsx("p",{className:"text-sm text-[var(--otari-muted)]",children:"The replacement key will be shown once. Save it before closing the next screen."}),e.jsx(y,{error:r})]})}),e.jsx(d.Footer,{children:t!==void 0?e.jsx(h,{variant:"primary",onPress:n,children:"I’ve saved this key"}):e.jsxs(e.Fragment,{children:[e.jsx(h,{variant:"ghost",isDisabled:s,onPress:n,children:"Cancel"}),e.jsx(h,{variant:"danger",isPending:s,onPress:a,children:"Regenerate key"})]})})]})})})}function G({source:t}){const r=A(),[s,a]=u.useState(!1),[n,i]=u.useState(),o=t==="generated",c=()=>r.mutate(void 0,{onSuccess:x=>{i(x.master_key)}}),p=()=>{a(!1),i(void 0),r.reset()},m=x=>{x?(r.reset(),a(!0)):n===void 0&&p()};return e.jsx("div",{className:"flex flex-col gap-4 py-4",children:e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("code",{className:"text-sm font-medium text-[var(--otari-ink)]",children:"master_key"}),e.jsx("p",{className:"mt-1 max-w-3xl text-sm text-[var(--otari-muted)]",children:o?"This gateway uses its first-run generated dashboard key. Regeneration invalidates the current key immediately.":"This gateway uses a key managed through OTARI_MASTER_KEY or config.yml. Rotate it in configuration, then restart the gateway."})]}),e.jsxs(d,{isOpen:s,onOpenChange:m,children:[o?e.jsx(d.Trigger,{className:I({size:"sm",variant:"danger-soft"}),children:"Regenerate"}):e.jsx(h,{size:"sm",variant:"danger-soft",isDisabled:!0,children:"Managed in configuration"}),s?e.jsx(U,{masterKey:n,error:r.error,isPending:r.isPending,onRegenerate:c,onClose:p}):null]})]})})}function X(){var o;const t=O(),r=F(),s=r.data,a=((o=t.data)==null?void 0:o.length)??0,n=(t.data??[]).filter(c=>!c.decryptable).length,i=a>0;return e.jsxs("div",{className:"flex flex-col gap-4 py-4",children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("code",{className:"text-sm font-medium text-[var(--otari-ink)]",children:"OTARI_SECRET_KEY"}),e.jsxs("p",{className:"mt-1 max-w-3xl text-sm text-[var(--otari-muted)]",children:["Generate a new key with ",e.jsx("code",{children:"uv run otari gen-secret-key"}),", then restart with"," ",e.jsx("code",{children:"OTARI_SECRET_KEY=,"}),". Re-encrypt the stored provider keys, then restart with ",e.jsx("code",{children:"OTARI_SECRET_KEY="})," once none are unreadable."]})]}),e.jsx("div",{className:"shrink-0",children:e.jsx(h,{size:"sm",variant:"outline",isDisabled:!i||r.isPending,onPress:()=>r.mutate(),children:r.isPending?"Re-encrypting…":"Re-encrypt provider keys"})})]}),e.jsx(y,{error:t.error??r.error}),n>0?e.jsxs(w,{tone:"warning",children:[n," stored provider key",n===1?"":"s"," cannot be decrypted with the current"," ",e.jsx("code",{children:"OTARI_SECRET_KEY"}),". Restore the old secret key and re-encrypt, or edit each affected provider and replace its key."]}):null,s?e.jsxs("p",{className:"text-sm text-[var(--otari-muted)]",role:"status","aria-live":"polite",children:["Re-encrypted ",s.reencrypted," provider key",s.reencrypted===1?"":"s",".",s.unreadable>0?` ${s.unreadable} still need replacement.`:" All decryptable stored keys now use the primary secret key."]}):!t.isLoading&&!i?e.jsx("p",{className:"text-sm text-[var(--otari-muted)]",children:"No stored provider keys need re-encryption."}):null]})}function J({masterKeySource:t}){return e.jsxs("section",{className:"flex flex-col gap-2",children:[e.jsxs("h2",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:["Credential security ",e.jsx("span",{className:"font-normal text-[var(--otari-muted)]",children:"(2)"})]}),e.jsx(v,{children:e.jsxs(v.Content,{className:"flex flex-col divide-y divide-[var(--otari-line)] px-5 py-1",children:[e.jsx(G,{source:t}),e.jsx(X,{})]})})]})}function Q({preview:t,error:r,isPending:s,onAccept:a,onReject:n}){return e.jsx(d.Backdrop,{children:e.jsx(d.Container,{placement:"center",size:"lg",children:e.jsxs(d.Dialog,{children:[e.jsx(d.Header,{children:e.jsx(d.Heading,{children:"Review default price updates"})}),e.jsxs(d.Body,{className:"flex flex-col gap-4",children:[e.jsxs("p",{className:"text-sm text-[var(--otari-muted)]",children:[t.added_count," added, ",t.changed_count," changed, and ",t.removed_count," removed upstream model prices. The accepted catalog is saved in the database with source ",e.jsx("code",{children:"genai-prices"})," and reloads after a restart. Your ",t.protected_model_count," custom model price",t.protected_model_count===1?"":"s"," remain unchanged."]}),t.changes.length>0?e.jsx("ul",{className:"max-h-60 list-disc overflow-auto pl-5 text-sm text-[var(--otari-ink)]",children:t.changes.map(i=>e.jsxs("li",{children:[i.model_key,": ",i.change]},i.model_key))}):null,t.changes_truncated?e.jsx("p",{className:"text-xs text-[var(--otari-muted)]",children:"Only the first 100 changes are shown."}):null,e.jsx(y,{error:r})]}),e.jsxs(d.Footer,{children:[e.jsx(h,{variant:"ghost",isDisabled:s,onPress:n,children:"Reject changes"}),e.jsx(h,{variant:"primary",isPending:s,onPress:a,children:"Accept price updates"})]})]})})})}function W(){const t=E(),r=T(),s=_(),a=t.data,n=r.isPending||s.isPending,i=()=>{a===void 0||n||s.mutate(void 0,{onSuccess:t.reset})};return e.jsxs("section",{className:"flex flex-col gap-2",children:[e.jsx("h2",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:"Default pricing catalog"}),e.jsx(v,{children:e.jsxs(v.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"text-sm font-medium text-[var(--otari-ink)]",children:"genai-prices defaults"}),e.jsxs("p",{className:"mt-1 max-w-3xl text-sm text-[var(--otari-muted)]",children:["Fetch the latest upstream catalog, review the proposed change summary, then accept or reject it. Accepted data is stored as ",e.jsx("code",{children:"genai-prices"}),"; custom prices remain separate and always take precedence."]})]}),e.jsx(h,{size:"sm",variant:"outline",isDisabled:t.isPending||n,onPress:()=>t.mutate(),children:t.isPending?"Checking prices…":"Check for price updates"})]}),e.jsx(y,{error:t.error})]})}),e.jsxs(d,{isOpen:a!==void 0,onOpenChange:o=>o?void 0:i(),children:[e.jsx(d.Trigger,{className:"hidden",children:"Review price updates"}),a?e.jsx(Q,{preview:a,error:r.error??s.error,isPending:n,onAccept:()=>r.mutate(void 0,{onSuccess:t.reset}),onReject:i}):null]})]})}function Z(t){const r=[],s=new Map;for(const a of t){let n=s.get(a.group);n||(n={name:a.group,fields:[]},s.set(a.group,n),r.push(n)),n.fields.push(a)}return r}function ae(){const t=R(),r=C(),s=t.data,a=r.isPending,[n,i]=u.useState(""),[o,c]=u.useState(!1),p=u.useRef(null);u.useEffect(()=>{function l(f){var N;const j=f.target,S=j&&(j.tagName==="INPUT"||j.tagName==="TEXTAREA"||j.tagName==="SELECT");f.key==="/"&&!S&&(f.preventDefault(),(N=p.current)==null||N.focus())}return window.addEventListener("keydown",l),()=>window.removeEventListener("keydown",l)},[]);const m=l=>r.mutate(l),x=(s==null?void 0:s.config)??[],g=x.filter(l=>(o?l.settable:!0)&&M(l,n)),k=Z(g);return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(P,{title:"Settings",description:"Every effective gateway setting. Settable fields apply immediately and persist across restarts; startup-only fields are shown for reference and change only via config.yml or environment variables (then a restart)."}),e.jsx(y,{error:t.error??r.error}),e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsx("input",{ref:p,type:"search","aria-label":"Search settings",placeholder:"Search settings (press / to focus)…",value:n,onChange:l=>i(l.target.value),onKeyDown:l=>{l.key==="Escape"&&i("")},className:"min-w-0 flex-1 rounded-lg border border-[var(--otari-line)] bg-[var(--otari-bg)] px-3 py-2 text-sm text-[var(--otari-ink)] focus:border-[var(--otari-brand)] focus:outline-none"}),e.jsxs("label",{className:"flex items-center gap-2 text-sm text-[var(--otari-muted)]",children:[e.jsx("input",{type:"checkbox",checked:o,onChange:l=>c(l.target.checked),className:"h-4 w-4 accent-[var(--otari-brand)]"}),"Settable only"]})]}),s?e.jsxs("p",{className:"text-xs text-[var(--otari-muted)]",children:["Showing ",g.length," of ",x.length," settings"]}):null,s&&g.length===0?e.jsx("p",{className:"text-sm text-[var(--otari-muted)]",children:"No settings match your search."}):null,k.map(l=>e.jsxs("section",{className:"flex flex-col gap-2",children:[e.jsxs("h2",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:[l.name," ",e.jsxs("span",{className:"font-normal text-[var(--otari-muted)]",children:["(",l.fields.length,")"]})]}),e.jsx(v,{children:e.jsx(v.Content,{className:"flex flex-col divide-y divide-[var(--otari-line)] px-5 py-1",children:l.fields.map(f=>e.jsx(q,{field:f,patch:m,disabled:!s||a},f.key))})})]},l.name)),s?e.jsx(W,{}):null,s?e.jsx(J,{masterKeySource:s.master_key_source}):null,s?e.jsxs("p",{className:"text-xs text-[var(--otari-muted)]",children:["Mode: ",s.mode," · Version ",s.version,s.require_pricing?" · require_pricing on":""]}):null]})}export{ae as SettingsPage,M as fieldMatches}; +import{j as e}from"./tanstack-query-1t81HyiD.js";import{r as u}from"./react-dgEcD0HR.js";import{B as R,V as C,P,E as y,a0 as E,a1 as T,a2 as _,F as D,a3 as A,R as O,a4 as F,I as w}from"./index-DAVt9uB3.js";import{d as v,B as h,A as d,g as I,I as K}from"./heroui-BX6JwHY-.js";function b(t,r){return{[t]:r}}function z(t,r){let s=0;for(const a of r)if(a===t[s]&&(s+=1),s===t.length)return!0;return t.length===0}function M(t,r){const s=r.trim().toLowerCase();if(s==="")return!0;const a=`${t.key} ${t.description??""} ${t.group}`.toLowerCase(),n=t.key.toLowerCase().replace(/[^a-z0-9]/g,"");return s.split(/\s+/).every(i=>a.includes(i)||z(i,n))}function B({checked:t,onChange:r,label:s,disabled:a}){return e.jsx("button",{type:"button",role:"switch","aria-checked":t,"aria-label":s,disabled:a,onClick:()=>r(!t),className:`relative inline-flex h-6 w-11 shrink-0 items-center rounded-full transition-colors disabled:opacity-50 ${t?"bg-[var(--otari-brand)]":"bg-[var(--otari-line)]"}`,children:e.jsx("span",{className:`inline-block h-5 w-5 transform rounded-full bg-white shadow transition-transform ${t?"translate-x-5":"translate-x-0.5"}`})})}function L({field:t,onSave:r,disabled:s}){const a=typeof t.value=="number"?t.value:0,[n,i]=u.useState(String(a)),o=t.type==="float";u.useEffect(()=>{i(String(a))},[a]);const c=Number(n),p=n.trim()!==""&&Number.isFinite(c)&&(o||Number.isInteger(c)),m=t.minimum??void 0,x=t.exclusive_minimum??void 0,g=x!==void 0?c>x:m!==void 0?c>=m:c>=0,l=p&&g&&c!==a;return e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(K,{type:"number",min:"0",step:o?"any":"1",inputMode:o?"decimal":"numeric","aria-label":t.key,value:n,disabled:s,onChange:f=>i(f.target.value),className:"w-28 rounded-md border border-[var(--otari-line)] bg-white px-2 py-1 text-right text-sm tabular-nums focus:border-[var(--otari-brand)] focus:outline-none disabled:opacity-50"}),e.jsx(h,{size:"sm",variant:"primary","aria-label":`Save ${t.key}`,isDisabled:s||!l,onPress:()=>r(c),children:"Save"})]})}function $({field:t,onSave:r,disabled:s}){const a=typeof t.value=="string"?t.value:"",[n,i]=u.useState(a);u.useEffect(()=>{i(a)},[a]);const o=n!==a;return e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("input",{type:"text","aria-label":t.key,value:n,disabled:s,placeholder:"unset",onChange:c=>i(c.target.value),className:"w-56 rounded-md border border-[var(--otari-line)] bg-white px-2 py-1 text-sm focus:border-[var(--otari-brand)] focus:outline-none disabled:opacity-50"}),e.jsx(h,{size:"sm",variant:"primary","aria-label":`Save ${t.key}`,isDisabled:s||!o,onPress:()=>r(n.trim()===""?null:n),children:"Save"})]})}function H(t){const{value:r}=t;return r==null?"unset":typeof r=="boolean"?r?"on":"off":Array.isArray(r)?r.length?r.join(", "):"none":String(r)}function Y({field:t,patch:r,disabled:s}){return t.settable?t.type==="bool"?e.jsx(B,{checked:t.value===!0,onChange:a=>r(b(t.key,a)),label:t.key,disabled:s}):t.options&&t.options.length>0?e.jsx(D,{ariaLabel:t.key,value:String(t.value??""),onChange:a=>r(b(t.key,a)),options:t.options.map(a=>({value:a,label:a}))}):t.type==="int"||t.type==="float"?e.jsx(L,{field:t,onSave:a=>r(b(t.key,a)),disabled:s}):e.jsx($,{field:t,onSave:a=>r(b(t.key,a)),disabled:s}):e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-sm tabular-nums text-[var(--otari-ink)]",children:H(t)}),e.jsx("span",{className:"rounded-full border border-[var(--otari-line)] px-2 py-0.5 text-xs text-[var(--otari-muted)]",children:"startup-only"})]})}function q({field:t,patch:r,disabled:s}){return e.jsxs("div",{className:"flex items-start justify-between gap-6 py-4",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("code",{className:"text-sm font-medium text-[var(--otari-ink)]",children:t.key}),t.description?e.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:t.description}):null]}),e.jsx("div",{className:"shrink-0 pt-0.5",children:e.jsx(Y,{field:t,patch:r,disabled:s})})]})}function V({value:t,fieldRef:r}){const s=u.useRef(null),a=r??s,[n,i]=u.useState(!1),[o,c]=u.useState(!1),p=async()=>{var m,x,g;(m=a.current)==null||m.focus(),(x=a.current)==null||x.select();try{if((g=navigator.clipboard)!=null&&g.writeText){await navigator.clipboard.writeText(t),i(!0),c(!1),window.setTimeout(()=>i(!1),2e3);return}}catch{}c(!0)};return e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-xs font-medium text-[var(--otari-muted)]",children:"New master key"}),e.jsx(h,{size:"sm",variant:"outline",onPress:p,children:n?"Copied":"Copy"})]}),e.jsx("input",{ref:a,readOnly:!0,value:t,onFocus:m=>m.currentTarget.select(),autoComplete:"off",autoCorrect:"off",autoCapitalize:"off",spellCheck:!1,"data-1p-ignore":!0,"data-lpignore":"true"}),e.jsx("span",{"aria-live":"polite",className:"text-xs text-[var(--otari-brand-dark)]",children:n?"Copied to clipboard.":""}),o?e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"Selected. Press Ctrl/Cmd-C to copy."}):null]})}function U({masterKey:t,error:r,isPending:s,onRegenerate:a,onClose:n}){const i=u.useRef(null);return u.useEffect(()=>{var o,c;t!==void 0&&((o=i.current)==null||o.focus(),(c=i.current)==null||c.select())},[t]),e.jsx(d.Backdrop,{children:e.jsx(d.Container,{placement:"center",size:"lg",children:e.jsxs(d.Dialog,{children:[e.jsx(d.Header,{children:e.jsx(d.Heading,{children:t!==void 0?"Master key regenerated":"Regenerate master key?"})}),e.jsx(d.Body,{className:"flex flex-col gap-4",children:t!==void 0?e.jsxs(e.Fragment,{children:[e.jsx(w,{tone:"warning",children:"Copy this key now. It is shown once and cannot be retrieved again after you close this dialog."}),e.jsx("p",{className:"text-sm text-[var(--otari-muted)]",children:"The previous master key has stopped working. This browser tab now uses the new key."}),e.jsx(V,{value:t,fieldRef:i})]}):e.jsxs(e.Fragment,{children:[e.jsx(w,{tone:"warning",children:"This immediately invalidates the current dashboard master key. Other signed-in dashboard sessions will need the new key to continue."}),e.jsx("p",{className:"text-sm text-[var(--otari-muted)]",children:"The replacement key will be shown once. Save it before closing the next screen."}),e.jsx(y,{error:r})]})}),e.jsx(d.Footer,{children:t!==void 0?e.jsx(h,{variant:"primary",onPress:n,children:"I’ve saved this key"}):e.jsxs(e.Fragment,{children:[e.jsx(h,{variant:"ghost",isDisabled:s,onPress:n,children:"Cancel"}),e.jsx(h,{variant:"danger",isPending:s,onPress:a,children:"Regenerate key"})]})})]})})})}function G({source:t}){const r=A(),[s,a]=u.useState(!1),[n,i]=u.useState(),o=t==="generated",c=()=>r.mutate(void 0,{onSuccess:x=>{i(x.master_key)}}),p=()=>{a(!1),i(void 0),r.reset()},m=x=>{x?(r.reset(),a(!0)):n===void 0&&p()};return e.jsx("div",{className:"flex flex-col gap-4 py-4",children:e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("code",{className:"text-sm font-medium text-[var(--otari-ink)]",children:"master_key"}),e.jsx("p",{className:"mt-1 max-w-3xl text-sm text-[var(--otari-muted)]",children:o?"This gateway uses its first-run generated dashboard key. Regeneration invalidates the current key immediately.":"This gateway uses a key managed through OTARI_MASTER_KEY or config.yml. Rotate it in configuration, then restart the gateway."})]}),e.jsxs(d,{isOpen:s,onOpenChange:m,children:[o?e.jsx(d.Trigger,{className:I({size:"sm",variant:"danger-soft"}),children:"Regenerate"}):e.jsx(h,{size:"sm",variant:"danger-soft",isDisabled:!0,children:"Managed in configuration"}),s?e.jsx(U,{masterKey:n,error:r.error,isPending:r.isPending,onRegenerate:c,onClose:p}):null]})]})})}function X(){var o;const t=O(),r=F(),s=r.data,a=((o=t.data)==null?void 0:o.length)??0,n=(t.data??[]).filter(c=>!c.decryptable).length,i=a>0;return e.jsxs("div",{className:"flex flex-col gap-4 py-4",children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("code",{className:"text-sm font-medium text-[var(--otari-ink)]",children:"OTARI_SECRET_KEY"}),e.jsxs("p",{className:"mt-1 max-w-3xl text-sm text-[var(--otari-muted)]",children:["Generate a new key with ",e.jsx("code",{children:"uv run otari gen-secret-key"}),", then restart with"," ",e.jsx("code",{children:"OTARI_SECRET_KEY=,"}),". Re-encrypt the stored provider keys, then restart with ",e.jsx("code",{children:"OTARI_SECRET_KEY="})," once none are unreadable."]})]}),e.jsx("div",{className:"shrink-0",children:e.jsx(h,{size:"sm",variant:"outline",isDisabled:!i||r.isPending,onPress:()=>r.mutate(),children:r.isPending?"Re-encrypting…":"Re-encrypt provider keys"})})]}),e.jsx(y,{error:t.error??r.error}),n>0?e.jsxs(w,{tone:"warning",children:[n," stored provider key",n===1?"":"s"," cannot be decrypted with the current"," ",e.jsx("code",{children:"OTARI_SECRET_KEY"}),". Restore the old secret key and re-encrypt, or edit each affected provider and replace its key."]}):null,s?e.jsxs("p",{className:"text-sm text-[var(--otari-muted)]",role:"status","aria-live":"polite",children:["Re-encrypted ",s.reencrypted," provider key",s.reencrypted===1?"":"s",".",s.unreadable>0?` ${s.unreadable} still need replacement.`:" All decryptable stored keys now use the primary secret key."]}):!t.isLoading&&!i?e.jsx("p",{className:"text-sm text-[var(--otari-muted)]",children:"No stored provider keys need re-encryption."}):null]})}function J({masterKeySource:t}){return e.jsxs("section",{className:"flex flex-col gap-2",children:[e.jsxs("h2",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:["Credential security ",e.jsx("span",{className:"font-normal text-[var(--otari-muted)]",children:"(2)"})]}),e.jsx(v,{children:e.jsxs(v.Content,{className:"flex flex-col divide-y divide-[var(--otari-line)] px-5 py-1",children:[e.jsx(G,{source:t}),e.jsx(X,{})]})})]})}function Q({preview:t,error:r,isPending:s,onAccept:a,onReject:n}){return e.jsx(d.Backdrop,{children:e.jsx(d.Container,{placement:"center",size:"lg",children:e.jsxs(d.Dialog,{children:[e.jsx(d.Header,{children:e.jsx(d.Heading,{children:"Review default price updates"})}),e.jsxs(d.Body,{className:"flex flex-col gap-4",children:[e.jsxs("p",{className:"text-sm text-[var(--otari-muted)]",children:[t.added_count," added, ",t.changed_count," changed, and ",t.removed_count," removed upstream model prices. The accepted catalog is saved in the database with source ",e.jsx("code",{children:"genai-prices"})," and reloads after a restart. Your ",t.protected_model_count," custom model price",t.protected_model_count===1?"":"s"," remain unchanged."]}),t.changes.length>0?e.jsx("ul",{className:"max-h-60 list-disc overflow-auto pl-5 text-sm text-[var(--otari-ink)]",children:t.changes.map(i=>e.jsxs("li",{children:[i.model_key,": ",i.change]},i.model_key))}):null,t.changes_truncated?e.jsx("p",{className:"text-xs text-[var(--otari-muted)]",children:"Only the first 100 changes are shown."}):null,e.jsx(y,{error:r})]}),e.jsxs(d.Footer,{children:[e.jsx(h,{variant:"ghost",isDisabled:s,onPress:n,children:"Reject changes"}),e.jsx(h,{variant:"primary",isPending:s,onPress:a,children:"Accept price updates"})]})]})})})}function W(){const t=E(),r=T(),s=_(),a=t.data,n=r.isPending||s.isPending,i=()=>{a===void 0||n||s.mutate(void 0,{onSuccess:t.reset})};return e.jsxs("section",{className:"flex flex-col gap-2",children:[e.jsx("h2",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:"Default pricing catalog"}),e.jsx(v,{children:e.jsxs(v.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"text-sm font-medium text-[var(--otari-ink)]",children:"genai-prices defaults"}),e.jsxs("p",{className:"mt-1 max-w-3xl text-sm text-[var(--otari-muted)]",children:["Fetch the latest upstream catalog, review the proposed change summary, then accept or reject it. Accepted data is stored as ",e.jsx("code",{children:"genai-prices"}),"; custom prices remain separate and always take precedence."]})]}),e.jsx(h,{size:"sm",variant:"outline",isDisabled:t.isPending||n,onPress:()=>t.mutate(),children:t.isPending?"Checking prices…":"Check for price updates"})]}),e.jsx(y,{error:t.error})]})}),e.jsxs(d,{isOpen:a!==void 0,onOpenChange:o=>o?void 0:i(),children:[e.jsx(d.Trigger,{className:"hidden",children:"Review price updates"}),a?e.jsx(Q,{preview:a,error:r.error??s.error,isPending:n,onAccept:()=>r.mutate(void 0,{onSuccess:t.reset}),onReject:i}):null]})]})}function Z(t){const r=[],s=new Map;for(const a of t){let n=s.get(a.group);n||(n={name:a.group,fields:[]},s.set(a.group,n),r.push(n)),n.fields.push(a)}return r}function ae(){const t=R(),r=C(),s=t.data,a=r.isPending,[n,i]=u.useState(""),[o,c]=u.useState(!1),p=u.useRef(null);u.useEffect(()=>{function l(f){var N;const j=f.target,S=j&&(j.tagName==="INPUT"||j.tagName==="TEXTAREA"||j.tagName==="SELECT");f.key==="/"&&!S&&(f.preventDefault(),(N=p.current)==null||N.focus())}return window.addEventListener("keydown",l),()=>window.removeEventListener("keydown",l)},[]);const m=l=>r.mutate(l),x=(s==null?void 0:s.config)??[],g=x.filter(l=>(o?l.settable:!0)&&M(l,n)),k=Z(g);return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(P,{title:"Settings",description:"Every effective gateway setting. Settable fields apply immediately and persist across restarts; startup-only fields are shown for reference and change only via config.yml or environment variables (then a restart)."}),e.jsx(y,{error:t.error??r.error}),e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsx("input",{ref:p,type:"search","aria-label":"Search settings",placeholder:"Search settings (press / to focus)…",value:n,onChange:l=>i(l.target.value),onKeyDown:l=>{l.key==="Escape"&&i("")},className:"min-w-0 flex-1 rounded-lg border border-[var(--otari-line)] bg-[var(--otari-bg)] px-3 py-2 text-sm text-[var(--otari-ink)] focus:border-[var(--otari-brand)] focus:outline-none"}),e.jsxs("label",{className:"flex items-center gap-2 text-sm text-[var(--otari-muted)]",children:[e.jsx("input",{type:"checkbox",checked:o,onChange:l=>c(l.target.checked),className:"h-4 w-4 accent-[var(--otari-brand)]"}),"Settable only"]})]}),s?e.jsxs("p",{className:"text-xs text-[var(--otari-muted)]",children:["Showing ",g.length," of ",x.length," settings"]}):null,s&&g.length===0?e.jsx("p",{className:"text-sm text-[var(--otari-muted)]",children:"No settings match your search."}):null,k.map(l=>e.jsxs("section",{className:"flex flex-col gap-2",children:[e.jsxs("h2",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:[l.name," ",e.jsxs("span",{className:"font-normal text-[var(--otari-muted)]",children:["(",l.fields.length,")"]})]}),e.jsx(v,{children:e.jsx(v.Content,{className:"flex flex-col divide-y divide-[var(--otari-line)] px-5 py-1",children:l.fields.map(f=>e.jsx(q,{field:f,patch:m,disabled:!s||a},f.key))})})]},l.name)),s?e.jsx(W,{}):null,s?e.jsx(J,{masterKeySource:s.master_key_source}):null,s?e.jsxs("p",{className:"text-xs text-[var(--otari-muted)]",children:["Mode: ",s.mode," · Version ",s.version,s.require_pricing?" · require_pricing on":""]}):null]})}export{ae as SettingsPage,M as fieldMatches}; diff --git a/src/gateway/static/dashboard/assets/ToolsGuardrailsPage-Zh-JPOxJ.js b/src/gateway/static/dashboard/assets/ToolsGuardrailsPage-Zh-JPOxJ.js new file mode 100644 index 00000000..d57862df --- /dev/null +++ b/src/gateway/static/dashboard/assets/ToolsGuardrailsPage-Zh-JPOxJ.js @@ -0,0 +1 @@ +import{j as e}from"./tanstack-query-1t81HyiD.js";import{r as x}from"./react-dgEcD0HR.js";import{a5 as C,a6 as L,P as E,E as P,h as w,a7 as R,F as D}from"./index-DAVt9uB3.js";import{d as N,B as b}from"./heroui-BX6JwHY-.js";function M(s,t){return{[s]:t}}const U=[{key:"web_search",label:"Web search",blurb:"Backend for otari_web_search tools (a SearXNG instance or a search adapter).",order:["web_search_url","web_search_engines","web_search_max_results","web_search_extract","web_search_purpose_hint"]},{key:"sandbox",label:"Code execution",blurb:"Backend for otari_code_execution tools (the sandbox that runs generated code).",order:["sandbox_url","sandbox_purpose_hint"]},{key:"guardrails",label:"Guardrails",blurb:"Default input-guardrails service used when a request does not pass its own guardrail URL.",order:["guardrails_url"]}];function B(){const[s,t]=x.useState(null),a=x.useRef(void 0),n=r=>{t(r),window.clearTimeout(a.current),a.current=window.setTimeout(()=>t(null),2500)};return x.useEffect(()=>()=>window.clearTimeout(a.current),[]),[s,n]}function $({message:s}){return s?e.jsxs("div",{role:"status","aria-live":"polite",className:"fixed right-4 bottom-4 z-50 flex items-center gap-2 rounded-lg border border-green-200 bg-green-50 px-4 py-3 text-sm font-medium text-green-700 shadow-lg",children:[e.jsx("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2","aria-hidden":!0,className:"h-5 w-5",children:e.jsx("path",{d:"M20 6 9 17l-5-5",strokeLinecap:"round",strokeLinejoin:"round"})}),s]}):null}const S="rounded-md border border-[var(--otari-line)] bg-[var(--otari-surface)] px-2 py-1 text-sm focus:border-[var(--otari-brand)] focus:outline-none disabled:opacity-50",g="grid gap-x-4 gap-y-1.5 py-4 sm:grid-cols-[minmax(0,1fr)_16rem_10rem] sm:items-start",_=`w-full sm:col-start-2 ${S}`,k="flex items-center gap-2 sm:col-start-3",f="flex flex-col gap-1 sm:col-span-2 sm:col-start-2";function j({message:s}){return s?e.jsx("span",{className:"break-words text-xs text-red-700",children:s}):null}function y({field:s,help:t}){return e.jsxs("div",{className:"min-w-0 sm:col-start-1",children:[e.jsx("code",{className:"text-sm font-medium text-[var(--otari-ink)]",children:s.key}),s.description?e.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:s.description}):null,t?e.jsx("p",{className:"mt-1 text-xs text-[var(--otari-muted)]",children:t}):null]})}function z({field:s,onSave:t,saveError:a,disabled:n}){const r=typeof s.value=="string"?s.value:"",[l,i]=x.useState(r),[m,p]=x.useState(null),c=R();x.useEffect(()=>{i(r)},[r]);const o=l.trim()!==r,d=l.trim(),h=m!==null&&m===d;return e.jsxs("div",{className:g,children:[e.jsx(y,{field:s,help:"Leave blank and Save to fall back to the configured default."}),e.jsx("input",{type:"text",inputMode:"url","aria-label":s.key,value:l,disabled:n,placeholder:"unset",onChange:v=>{i(v.target.value),c.reset()},className:_}),e.jsxs("div",{className:k,children:[e.jsx(b,{size:"sm",variant:"primary","aria-label":`Save ${s.key}`,isDisabled:n||!o,onPress:()=>t(d===""?null:d),children:"Save"}),e.jsx(b,{size:"sm",variant:"outline","aria-label":`Test ${s.service}`,isDisabled:d===""||c.isPending,onPress:()=>{p(d),c.mutate({service:s.service,url:d})},children:c.isPending?"Testing…":"Test"})]}),e.jsxs("div",{className:f,children:[e.jsx("span",{role:"status","aria-live":"polite",className:"block break-words text-xs",children:c.isPending||!h?null:c.error?e.jsx("span",{className:"text-red-700",children:w(c.error)}):c.data?e.jsx("span",{className:c.data.ok?"font-medium text-green-700":"text-red-700",children:c.data.reason}):null}),e.jsx(j,{message:a})]})]})}function G({field:s,onSave:t,saveError:a,disabled:n}){const r=typeof s.value=="string"?s.value:"",[l,i]=x.useState(r);x.useEffect(()=>{i(r)},[r]);const m=l!==r;return e.jsxs("div",{className:g,children:[e.jsx(y,{field:s}),e.jsx("input",{type:"text","aria-label":s.key,value:l,disabled:n,placeholder:"default",onChange:p=>i(p.target.value),className:_}),e.jsx("div",{className:k,children:e.jsx(b,{size:"sm",variant:"primary","aria-label":`Save ${s.key}`,isDisabled:n||!m,onPress:()=>t(l.trim()===""?null:l.trim()),children:"Save"})}),a?e.jsx("div",{className:f,children:e.jsx(j,{message:a})}):null]})}function I({field:s,onSave:t,saveError:a,disabled:n}){const r=typeof s.value=="number"?String(s.value):"",[l,i]=x.useState(r);x.useEffect(()=>{i(r)},[r]);const m=l.trim(),p=Number(m),o=(m===""||Number.isInteger(p)&&p>=1)&&m!==r;return e.jsxs("div",{className:g,children:[e.jsx(y,{field:s,help:"Leave blank to use the backend default."}),e.jsx("input",{type:"number",min:"1",step:"1",inputMode:"numeric","aria-label":s.key,value:l,disabled:n,placeholder:"default",onChange:d=>i(d.target.value),className:`w-full text-right tabular-nums sm:col-start-2 sm:w-28 sm:justify-self-end ${S}`}),e.jsx("div",{className:k,children:e.jsx(b,{size:"sm",variant:"primary","aria-label":`Save ${s.key}`,isDisabled:n||!o,onPress:()=>t(m===""?null:p),children:"Save"})}),a?e.jsx("div",{className:f,children:e.jsx(j,{message:a})}):null]})}function A({field:s,onSave:t,saveError:a,disabled:n}){const r=s.value===!0?"on":s.value===!1?"off":"default";return e.jsxs("div",{className:g,children:[e.jsx(y,{field:s}),e.jsx("div",{className:"sm:col-start-2 sm:justify-self-start",children:e.jsx(D,{ariaLabel:s.key,value:r,onChange:l=>t(l==="default"?null:l==="on"),options:[{value:"default",label:"Default"},{value:"on",label:"On"},{value:"off",label:"Off"}],disabled:n})}),a?e.jsx("div",{className:f,children:e.jsx(j,{message:a})}):null]})}function F({field:s,onSave:t,saveError:a,disabled:n}){return s.type==="url"?e.jsx(z,{field:s,onSave:t,saveError:a,disabled:n}):s.type==="int"?e.jsx(I,{field:s,onSave:t,saveError:a,disabled:n}):s.type==="bool"?e.jsx(A,{field:s,onSave:t,saveError:a,disabled:n}):e.jsx(G,{field:s,onSave:t,saveError:a,disabled:n})}function K(){const s=C(),t=L(),[a,n]=B(),[r,l]=x.useState({}),i=s.data,m=!i||t.isPending,p=new Map(((i==null?void 0:i.fields)??[]).map(o=>[o.key,o])),c=(o,d)=>{l(h=>{const{[o.key]:v,...u}=h;return u}),t.mutate(M(o.key,d),{onSuccess:()=>n(`${o.key} saved`),onError:h=>l(v=>({...v,[o.key]:w(h)}))})};return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(E,{title:"Tools & Guardrails",description:"Configure the built-in tool and guardrail service endpoints without a restart. Changes apply immediately and persist. URLs are validated for shape (http/https) and can be tested for reachability before saving; the network-safety gates for these services live on the Settings page."}),e.jsx(P,{error:s.error}),U.map(o=>{const d=o.order.map(u=>p.get(u)).filter(u=>u!==void 0),h=((i==null?void 0:i.fields)??[]).filter(u=>u.service===o.key&&!o.order.includes(u.key)),v=[...d,...h];return v.length===0?null:e.jsxs("section",{className:"flex flex-col gap-2",children:[e.jsx("h2",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:o.label}),e.jsx("p",{className:"text-sm text-[var(--otari-muted)]",children:o.blurb}),e.jsx(N,{children:e.jsx(N.Content,{className:"flex flex-col divide-y divide-[var(--otari-line)] px-5 py-1",children:v.map(u=>e.jsx(F,{field:u,onSave:T=>c(u,T),saveError:r[u.key],disabled:m},u.key))})})]},o.key)}),e.jsx($,{message:a})]})}export{K as ToolsGuardrailsPage}; diff --git a/src/gateway/static/dashboard/assets/ToolsGuardrailsPage-rcsPeR9V.js b/src/gateway/static/dashboard/assets/ToolsGuardrailsPage-rcsPeR9V.js deleted file mode 100644 index 470a67c8..00000000 --- a/src/gateway/static/dashboard/assets/ToolsGuardrailsPage-rcsPeR9V.js +++ /dev/null @@ -1 +0,0 @@ -import{j as e}from"./tanstack-query-1t81HyiD.js";import{r as d}from"./react-dgEcD0HR.js";import{a5 as C,a6 as L,P as E,E as P,h as w,a7 as R,F as D}from"./index-DHQmS-9o.js";import{d as N,B as b}from"./heroui-BX6JwHY-.js";function B(s,t){return{[s]:t}}const M=[{key:"web_search",label:"Web search",blurb:"Backend for otari_web_search tools (a SearXNG instance or a search adapter).",order:["web_search_url","web_search_engines","web_search_max_results","web_search_extract","web_search_purpose_hint"]},{key:"sandbox",label:"Code execution",blurb:"Backend for otari_code_execution tools (the sandbox that runs generated code).",order:["sandbox_url","sandbox_purpose_hint"]},{key:"guardrails",label:"Guardrails",blurb:"Default input-guardrails service used when a request does not pass its own guardrail URL.",order:["guardrails_url"]}];function $(){const[s,t]=d.useState(null),a=d.useRef(void 0),n=r=>{t(r),window.clearTimeout(a.current),a.current=window.setTimeout(()=>t(null),2500)};return d.useEffect(()=>()=>window.clearTimeout(a.current),[]),[s,n]}function U({message:s}){return s?e.jsxs("div",{role:"status","aria-live":"polite",className:"fixed right-4 bottom-4 z-50 flex items-center gap-2 rounded-lg border border-green-200 bg-green-50 px-4 py-3 text-sm font-medium text-green-700 shadow-lg",children:[e.jsx("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2","aria-hidden":!0,className:"h-5 w-5",children:e.jsx("path",{d:"M20 6 9 17l-5-5",strokeLinecap:"round",strokeLinejoin:"round"})}),s]}):null}const S="rounded-md border border-[var(--otari-line)] bg-[var(--otari-surface)] px-2 py-1 text-sm focus:border-[var(--otari-brand)] focus:outline-none disabled:opacity-50",g="grid gap-x-4 gap-y-1.5 py-4 sm:grid-cols-[minmax(0,1fr)_16rem_10rem] sm:items-start",_=`w-full sm:col-start-2 ${S}`,k="flex items-center gap-2 sm:col-start-3",f="flex flex-col gap-1 sm:col-span-2 sm:col-start-2";function j({message:s}){return s?e.jsx("span",{className:"break-words text-xs text-red-700",children:s}):null}function y({field:s,help:t}){return e.jsxs("div",{className:"min-w-0 sm:col-start-1",children:[e.jsx("code",{className:"text-sm font-medium text-[var(--otari-ink)]",children:s.key}),s.description?e.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:s.description}):null,t?e.jsx("p",{className:"mt-1 text-xs text-[var(--otari-muted)]",children:t}):null]})}function z({field:s,onSave:t,saveError:a,disabled:n}){const r=typeof s.value=="string"?s.value:"",[i,c]=d.useState(r),o=R();d.useEffect(()=>{c(r)},[r]);const m=i.trim()!==r,x=i.trim();return e.jsxs("div",{className:g,children:[e.jsx(y,{field:s,help:"Leave blank and Save to fall back to the configured default."}),e.jsx("input",{type:"text",inputMode:"url","aria-label":s.key,value:i,disabled:n,placeholder:"unset",onChange:l=>{c(l.target.value),o.reset()},className:_}),e.jsxs("div",{className:k,children:[e.jsx(b,{size:"sm",variant:"primary","aria-label":`Save ${s.key}`,isDisabled:n||!m,onPress:()=>t(x===""?null:x),children:"Save"}),e.jsx(b,{size:"sm",variant:"outline","aria-label":`Test ${s.service}`,isDisabled:x===""||o.isPending,onPress:()=>o.mutate({service:s.service,url:x}),children:o.isPending?"Testing…":"Test"})]}),e.jsxs("div",{className:f,children:[e.jsx("span",{role:"status","aria-live":"polite",className:"block break-words text-xs",children:o.isPending?null:o.error?e.jsx("span",{className:"text-red-700",children:w(o.error)}):o.data?e.jsx("span",{className:o.data.ok?"font-medium text-green-700":"text-red-700",children:o.data.reason}):null}),e.jsx(j,{message:a})]})]})}function G({field:s,onSave:t,saveError:a,disabled:n}){const r=typeof s.value=="string"?s.value:"",[i,c]=d.useState(r);d.useEffect(()=>{c(r)},[r]);const o=i!==r;return e.jsxs("div",{className:g,children:[e.jsx(y,{field:s}),e.jsx("input",{type:"text","aria-label":s.key,value:i,disabled:n,placeholder:"default",onChange:m=>c(m.target.value),className:_}),e.jsx("div",{className:k,children:e.jsx(b,{size:"sm",variant:"primary","aria-label":`Save ${s.key}`,isDisabled:n||!o,onPress:()=>t(i.trim()===""?null:i.trim()),children:"Save"})}),a?e.jsx("div",{className:f,children:e.jsx(j,{message:a})}):null]})}function I({field:s,onSave:t,saveError:a,disabled:n}){const r=typeof s.value=="number"?String(s.value):"",[i,c]=d.useState(r);d.useEffect(()=>{c(r)},[r]);const o=i.trim(),m=Number(o),l=(o===""||Number.isInteger(m)&&m>=1)&&o!==r;return e.jsxs("div",{className:g,children:[e.jsx(y,{field:s,help:"Leave blank to use the backend default."}),e.jsx("input",{type:"number",min:"1",step:"1",inputMode:"numeric","aria-label":s.key,value:i,disabled:n,placeholder:"default",onChange:p=>c(p.target.value),className:`w-full text-right tabular-nums sm:col-start-2 sm:w-28 sm:justify-self-end ${S}`}),e.jsx("div",{className:k,children:e.jsx(b,{size:"sm",variant:"primary","aria-label":`Save ${s.key}`,isDisabled:n||!l,onPress:()=>t(o===""?null:m),children:"Save"})}),a?e.jsx("div",{className:f,children:e.jsx(j,{message:a})}):null]})}function A({field:s,onSave:t,saveError:a,disabled:n}){const r=s.value===!0?"on":s.value===!1?"off":"default";return e.jsxs("div",{className:g,children:[e.jsx(y,{field:s}),e.jsx("div",{className:"sm:col-start-2 sm:justify-self-start",children:e.jsx(D,{ariaLabel:s.key,value:r,onChange:i=>t(i==="default"?null:i==="on"),options:[{value:"default",label:"Default"},{value:"on",label:"On"},{value:"off",label:"Off"}],disabled:n})}),a?e.jsx("div",{className:f,children:e.jsx(j,{message:a})}):null]})}function F({field:s,onSave:t,saveError:a,disabled:n}){return s.type==="url"?e.jsx(z,{field:s,onSave:t,saveError:a,disabled:n}):s.type==="int"?e.jsx(I,{field:s,onSave:t,saveError:a,disabled:n}):s.type==="bool"?e.jsx(A,{field:s,onSave:t,saveError:a,disabled:n}):e.jsx(G,{field:s,onSave:t,saveError:a,disabled:n})}function K(){const s=C(),t=L(),[a,n]=$(),[r,i]=d.useState({}),c=s.data,o=!c||t.isPending,m=new Map(((c==null?void 0:c.fields)??[]).map(l=>[l.key,l])),x=(l,p)=>{i(h=>{const{[l.key]:v,...u}=h;return u}),t.mutate(B(l.key,p),{onSuccess:()=>n(`${l.key} saved`),onError:h=>i(v=>({...v,[l.key]:w(h)}))})};return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(E,{title:"Tools & Guardrails",description:"Configure the built-in tool and guardrail service endpoints without a restart. Changes apply immediately and persist. URLs are validated for shape (http/https) and can be tested for reachability before saving; the network-safety gates for these services live on the Settings page."}),e.jsx(P,{error:s.error}),M.map(l=>{const p=l.order.map(u=>m.get(u)).filter(u=>u!==void 0),h=((c==null?void 0:c.fields)??[]).filter(u=>u.service===l.key&&!l.order.includes(u.key)),v=[...p,...h];return v.length===0?null:e.jsxs("section",{className:"flex flex-col gap-2",children:[e.jsx("h2",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:l.label}),e.jsx("p",{className:"text-sm text-[var(--otari-muted)]",children:l.blurb}),e.jsx(N,{children:e.jsx(N.Content,{className:"flex flex-col divide-y divide-[var(--otari-line)] px-5 py-1",children:v.map(u=>e.jsx(F,{field:u,onSave:T=>x(u,T),saveError:r[u.key],disabled:o},u.key))})})]},l.key)}),e.jsx(U,{message:a})]})}export{K as ToolsGuardrailsPage}; diff --git a/src/gateway/static/dashboard/assets/UsagePage-XCUoRhxb.js b/src/gateway/static/dashboard/assets/UsagePage-Dk-t74Uz.js similarity index 57% rename from src/gateway/static/dashboard/assets/UsagePage-XCUoRhxb.js rename to src/gateway/static/dashboard/assets/UsagePage-Dk-t74Uz.js index 7de11975..93b25f17 100644 --- a/src/gateway/static/dashboard/assets/UsagePage-XCUoRhxb.js +++ b/src/gateway/static/dashboard/assets/UsagePage-Dk-t74Uz.js @@ -1 +1 @@ -import{j as e}from"./tanstack-query-1t81HyiD.js";import{i as ie,r as x}from"./react-dgEcD0HR.js";import{u as ce,c as D,P as de,E as ue,d as J,S as j,N as v,L as p,M as $,O as he,a8 as S}from"./index-DHQmS-9o.js";import{S as E,B as me}from"./charts-Cr3Dij9t.js";import{T as xe,a as ge,b as M,L as fe,c as je,d as be,e as O}from"./Table-CLdjdyTx.js";import{B as k,S as K}from"./heroui-BX6JwHY-.js";import"./recharts-CR3TAEof.js";function z(a){return a.toLocaleString()}function ve(a){return a===null?"—":a<1e3?`${Math.round(a)} ms`:`${(a/1e3).toFixed(2)} s`}const pe=3600,R=86400,L=[{label:"Last hour",seconds:pe,bucket:"hour"},{label:"24h",seconds:R,bucket:"hour"},{label:"7d",seconds:7*R,bucket:"day"},{label:"30d",seconds:30*R,bucket:"day"},{label:"All",seconds:null,bucket:"day"}],U=L[3],A=15;function B(a){return new Date(Date.now()-a*1e3).toISOString()}function Q({title:a,rows:r,totalCost:n,emptyLabel:g,onDrill:c,loading:d}){const[u,_]=x.useState(!1),f=u?r:r.slice(0,A),N=r.length-f.length;return e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsx("h2",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:a}),e.jsxs(xe,{children:[e.jsx(ge,{children:e.jsxs("tr",{children:[e.jsx(M,{children:a.replace("Spend by ","")}),e.jsx(M,{className:"text-right",children:"Requests"}),e.jsx(M,{className:"text-right",children:"Spend"})]})}),e.jsx("tbody",{children:d?e.jsx(fe,{colSpan:3}):r.length===0?e.jsx(je,{colSpan:3,children:g}):f.map((o,T)=>{const m=o.is_other,y=!m&&o.key!==null,h=n>0?o.cost/n:0;return e.jsxs(be,{onClick:y?()=>c(o.key):void 0,children:[e.jsx(O,{className:"text-[var(--otari-ink)]",children:e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx("span",{className:"truncate",children:m?`Other (${o.requests.toLocaleString()} req)`:o.key??"(unknown)"}),e.jsx("span",{className:"h-1 w-full overflow-hidden rounded-full bg-[var(--otari-line)]",children:e.jsx("span",{className:"block h-full rounded-full bg-[var(--otari-brand)]",style:{width:`${Math.min(100,h*100)}%`}})})]})}),e.jsx(O,{className:"text-right tabular-nums text-[var(--otari-muted)]",children:z(o.requests)}),e.jsx(O,{className:"text-right tabular-nums text-[var(--otari-ink)]",children:$(o.cost)})]},o.key??`__null_${T}`)})})]}),!d&&N>0?e.jsxs(k,{size:"sm",variant:"ghost",onPress:()=>_(!0),children:["Show all ",r.length]}):null,!d&&u&&r.length>A?e.jsxs(k,{size:"sm",variant:"ghost",onPress:()=>_(!1),children:["Show top ",A]}):null]})}const ke=[{key:"cost",label:"Cost"},{key:"tokens",label:"Tokens"},{key:"requests",label:"Requests"}];function _e(a,r){return r==="cost"?a.cost:r==="tokens"?a.tokens:a.requests}function W(a,r){return r==="cost"?$(a):r==="tokens"?S(a):z(a)}function ye(a,r){const n=new Date(a);return Number.isNaN(n.getTime())?a:r==="hour"?n.toLocaleTimeString(void 0,{hour:"2-digit",minute:"2-digit",timeZone:"UTC"}):n.toLocaleDateString(void 0,{month:"short",day:"numeric",timeZone:"UTC"})}function Se(a,r,n){const g=a.map(d=>({label:ye(d.bucket_start,n),value:_e(d,r)})),c=g.length?Math.max(...g.map(d=>d.value)):0;return{points:g,peak:c,count:a.length}}function De(){var V,Z,Y;const a=ie(),r=ce(),[n,g]=x.useState(U),[c,d]=x.useState(()=>U.seconds===null?void 0:B(U.seconds)),[u,_]=x.useState(""),[f,N]=x.useState(""),[o,T]=x.useState("cost"),m=x.useMemo(()=>({start_date:c,model:u.trim()||void 0,user_id:f||void 0}),[c,u,f]),y=x.useMemo(()=>n.seconds===null||!c?null:{...m,start_date:new Date(new Date(c).getTime()-n.seconds*1e3).toISOString(),end_date:c},[m,n.seconds,c]),h=D(m,n.bucket),X=D(y??m,n.bucket,y!==null),i=h.data,t=i==null?void 0:i.totals,l=y!==null?(V=X.data)==null?void 0:V.totals:void 0,ee=x.useMemo(()=>({...m,model:void 0}),[m]),q=((Y=(Z=D(ee,n.bucket).data)==null?void 0:Z.by_model)==null?void 0:Y.filter(s=>!s.is_other&&s.key!==null).map(s=>s.key))??[],se=(r.data??[]).map(s=>({value:s.user_id,label:s.alias?`${s.alias} (${s.user_id})`:s.user_id})),te=(u&&!q.includes(u)?[u,...q]:q).map(s=>({value:s,label:s})),w=!!(u.trim()||f||n.seconds!==null),ae=!!(i&&t&&t.request_count===0&&!w),H=s=>{g(s),d(s.seconds===null?void 0:B(s.seconds))},ne=()=>{H(L[L.length-1]),_(""),N("")},re=()=>{n.seconds!==null&&d(B(n.seconds)),h.refetch()},I=s=>{const P=new URLSearchParams;c&&P.set("start_date",c);for(const[oe,G]of Object.entries(s))G&&P.set(oe,G);a(`/activity?${P.toString()}`)},le=t&&t.request_count>0?t.error_count/t.request_count:0,b=(i==null?void 0:i.series)??[],C=b.length>1,F=Se(b,o,n.bucket);return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(de,{title:"Usage & analytics",description:"Aggregate spend, tokens, and request volume over time. Click a model or user to drill into the request log.",action:e.jsx(k,{variant:"outline",onPress:re,isDisabled:h.isFetching,children:"Refresh"})}),e.jsx(ue,{error:h.error}),e.jsxs("div",{className:"flex flex-wrap items-end gap-3",children:[e.jsx("div",{className:"flex flex-wrap gap-2",children:L.map(s=>e.jsx(k,{size:"sm",variant:n.label===s.label?"primary":"outline",onPress:()=>H(s),children:s.label},s.label))}),e.jsxs("div",{className:"flex flex-wrap items-end gap-3",children:[e.jsx(J,{label:"User",value:f,onChange:N,options:se,placeholder:"All users"}),e.jsx(J,{label:"Model",value:u,onChange:_,options:te,placeholder:"All models"}),w?e.jsx(k,{size:"sm",variant:"ghost",onPress:ne,children:"Clear filters"}):null]})]}),ae?e.jsx("div",{className:"rounded-xl border border-[var(--otari-line)] bg-[var(--otari-surface)] px-4 py-10 text-center text-sm text-[var(--otari-muted)]",children:"No usage yet. Once the gateway serves requests, spend and volume appear here."}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex flex-wrap gap-4",children:[e.jsx(j,{label:"Spend",value:t?$(t.cost):"—",hint:t?e.jsx(v,{fraction:p(t.cost,l==null?void 0:l.cost)}):null,chart:C?e.jsx(E,{values:b.map(s=>s.cost),ariaLabel:"Spend trend over the selected window"}):void 0}),e.jsx(j,{label:"Requests",value:t?z(t.request_count):"—",hint:t?e.jsxs("span",{className:"text-[var(--otari-muted)]",children:[he(le)," errors",l?e.jsxs(e.Fragment,{children:[" · ",e.jsx(v,{fraction:p(t.request_count,l.request_count)})]}):null]}):null,chart:C?e.jsx(E,{values:b.map(s=>s.requests),ariaLabel:"Request volume trend over the selected window"}):void 0}),e.jsx(j,{label:"Tokens",value:t?S(t.total_tokens):"—",hint:t?e.jsx(v,{fraction:p(t.total_tokens,l==null?void 0:l.total_tokens)}):null,chart:C?e.jsx(E,{values:b.map(s=>s.tokens),ariaLabel:"Token usage trend over the selected window"}):void 0}),e.jsx(j,{label:"Cache read",value:t?S(t.cache_read_tokens):"—",hint:t?e.jsx(v,{fraction:p(t.cache_read_tokens,l==null?void 0:l.cache_read_tokens)}):null}),e.jsx(j,{label:"Cache write",value:t?S(t.cache_write_tokens):"—",hint:t?e.jsx(v,{fraction:p(t.cache_write_tokens,l==null?void 0:l.cache_write_tokens)}):null}),e.jsx(j,{label:"1h cache write",value:t?S(t.cache_write_1h_tokens??0):"—",hint:t?e.jsx(v,{fraction:p(t.cache_write_1h_tokens??0,(l==null?void 0:l.cache_write_1h_tokens)??0)}):null}),e.jsx(j,{label:"Avg latency",value:t?ve(t.avg_latency_ms):"—"})]}),e.jsxs("div",{className:"grid gap-6 lg:grid-cols-2",children:[e.jsx(Q,{title:"Spend by model",rows:(i==null?void 0:i.by_model)??[],totalCost:(t==null?void 0:t.cost)??0,emptyLabel:w?"No usage matches these filters.":"No usage recorded yet.",onDrill:s=>I({model:s}),loading:h.isLoading}),e.jsx(Q,{title:"Spend by user",rows:(i==null?void 0:i.by_user)??[],totalCost:(t==null?void 0:t.cost)??0,emptyLabel:w?"No usage matches these filters.":"No usage recorded yet.",onDrill:s=>I({user_id:s}),loading:h.isLoading})]}),e.jsxs("div",{className:"flex flex-col gap-3 rounded-xl border border-[var(--otari-line)] bg-[var(--otari-surface)] p-4",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsx("h2",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:"Over time"}),e.jsxs("div",{className:"inline-flex gap-1.5",children:[ke.map(s=>e.jsx(k,{size:"sm",variant:o===s.key?"primary":"outline",onPress:()=>T(s.key),children:s.label},s.key)),h.isFetching?e.jsx(K,{size:"sm"}):null]})]}),h.isLoading?e.jsx("div",{className:"flex h-48 items-center justify-center",children:e.jsx(K,{size:"sm"})}):b.length===0?e.jsx("div",{className:"flex h-48 items-center justify-center text-sm text-[var(--otari-muted)]",children:"No data in this range."}):e.jsxs("figure",{className:"flex flex-col gap-2",children:[e.jsx(me,{data:F.points,formatValue:s=>W(s,o),ariaLabel:`${o} per ${n.bucket}`}),e.jsxs("figcaption",{className:"text-xs text-[var(--otari-muted)]",children:[W(F.peak,o)," peak · ",F.count," ",n.bucket==="hour"?"hours":"days"," (times in UTC)"]})]})]})]})]})}export{De as UsagePage}; +import{j as e}from"./tanstack-query-1t81HyiD.js";import{i as ie,r as x}from"./react-dgEcD0HR.js";import{u as ce,c as D,P as de,E as ue,d as J,S as v,N as b,L as p,M as $,O as he,a8 as S}from"./index-DAVt9uB3.js";import{S as E,B as me}from"./charts-Cr3Dij9t.js";import{T as xe,a as ge,b as M,L as fe,c as ve,d as je,e as O}from"./Table-CLdjdyTx.js";import{B as k,S as K}from"./heroui-BX6JwHY-.js";import"./recharts-CR3TAEof.js";function z(a){return a.toLocaleString()}function be(a){return a===null?"—":a<1e3?`${Math.round(a)} ms`:`${(a/1e3).toFixed(2)} s`}const pe=3600,R=86400,L=[{label:"Last hour",seconds:pe,bucket:"hour"},{label:"24h",seconds:R,bucket:"hour"},{label:"7d",seconds:7*R,bucket:"day"},{label:"30d",seconds:30*R,bucket:"day"},{label:"All",seconds:null,bucket:"day"}],U=L[3],A=15;function B(a){return new Date(Date.now()-a*1e3).toISOString()}function Q({title:a,rows:r,totalCost:n,emptyLabel:f,onDrill:c,loading:d}){const[u,_]=x.useState(!1),g=u?r:r.slice(0,A),N=r.length-g.length;return e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsx("h2",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:a}),e.jsxs(xe,{children:[e.jsx(ge,{children:e.jsxs("tr",{children:[e.jsx(M,{children:a.replace("Spend by ","")}),e.jsx(M,{className:"text-right",children:"Requests"}),e.jsx(M,{className:"text-right",children:"Spend"})]})}),e.jsx("tbody",{children:d?e.jsx(fe,{colSpan:3}):r.length===0?e.jsx(ve,{colSpan:3,children:f}):g.map((o,T)=>{const m=o.is_other,y=!m&&o.key!==null,h=n>0?o.cost/n:0;return e.jsxs(je,{onClick:y?()=>c(o.key):void 0,children:[e.jsx(O,{className:"text-[var(--otari-ink)]",children:e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx("span",{className:"truncate",children:m?`Other (${o.requests.toLocaleString()} req)`:o.key??"(unknown)"}),e.jsx("span",{className:"h-1 w-full overflow-hidden rounded-full bg-[var(--otari-line)]",children:e.jsx("span",{className:"block h-full rounded-full bg-[var(--otari-brand)]",style:{width:`${Math.min(100,h*100)}%`}})})]})}),e.jsx(O,{className:"text-right tabular-nums text-[var(--otari-muted)]",children:z(o.requests)}),e.jsx(O,{className:"text-right tabular-nums text-[var(--otari-ink)]",children:$(o.cost)})]},o.key??`__null_${T}`)})})]}),!d&&N>0?e.jsxs(k,{size:"sm",variant:"ghost",onPress:()=>_(!0),children:["Show all ",r.length]}):null,!d&&u&&r.length>A?e.jsxs(k,{size:"sm",variant:"ghost",onPress:()=>_(!1),children:["Show top ",A]}):null]})}const ke=[{key:"cost",label:"Cost"},{key:"tokens",label:"Tokens"},{key:"requests",label:"Requests"}];function _e(a,r){return r==="cost"?a.cost:r==="tokens"?a.tokens:a.requests}function W(a,r){return r==="cost"?$(a):r==="tokens"?S(a):z(a)}function ye(a,r){const n=new Date(a);return Number.isNaN(n.getTime())?a:r==="hour"?n.toLocaleTimeString(void 0,{hour:"2-digit",minute:"2-digit",timeZone:"UTC"}):n.toLocaleDateString(void 0,{month:"short",day:"numeric",timeZone:"UTC"})}function Se(a,r,n){const f=a.map(d=>({label:ye(d.bucket_start,n),value:_e(d,r)})),c=f.length?Math.max(...f.map(d=>d.value)):0;return{points:f,peak:c,count:a.length}}function De(){var V,Z,Y;const a=ie(),r=ce(),[n,f]=x.useState(U),[c,d]=x.useState(()=>U.seconds===null?void 0:B(U.seconds)),[u,_]=x.useState(""),[g,N]=x.useState(""),[o,T]=x.useState("cost"),m=x.useMemo(()=>({start_date:c,model:u.trim()||void 0,user_id:g||void 0}),[c,u,g]),y=x.useMemo(()=>n.seconds===null||!c?null:{...m,start_date:new Date(new Date(c).getTime()-n.seconds*1e3).toISOString(),end_date:c},[m,n.seconds,c]),h=D(m,n.bucket),X=D(y??m,n.bucket,y!==null),i=h.data,t=i==null?void 0:i.totals,l=y!==null?(V=X.data)==null?void 0:V.totals:void 0,ee=x.useMemo(()=>({...m,model:void 0}),[m]),q=((Y=(Z=D(ee,n.bucket).data)==null?void 0:Z.by_model)==null?void 0:Y.filter(s=>!s.is_other&&s.key!==null).map(s=>s.key))??[],se=(r.data??[]).map(s=>({value:s.user_id,label:s.alias?`${s.alias} (${s.user_id})`:s.user_id})),te=(u&&!q.includes(u)?[u,...q]:q).map(s=>({value:s,label:s})),w=!!(u.trim()||g||n.seconds!==null),ae=!!(i&&t&&t.request_count===0&&!w),H=s=>{f(s),d(s.seconds===null?void 0:B(s.seconds))},ne=()=>{H(L[L.length-1]),_(""),N("")},re=()=>{n.seconds!==null&&d(B(n.seconds)),h.refetch()},I=s=>{const P=new URLSearchParams;c&&P.set("start_date",c);for(const[oe,G]of Object.entries(s))G&&P.set(oe,G);a(`/activity?${P.toString()}`)},le=t&&t.request_count>0?t.error_count/t.request_count:0,j=(i==null?void 0:i.series)??[],C=j.length>1,F=Se(j,o,n.bucket);return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(de,{title:"Usage & analytics",description:"Aggregate spend, tokens, and request volume over time. Click a model or user to drill into the request log.",action:e.jsx(k,{variant:"outline",onPress:re,isDisabled:h.isFetching,children:"Refresh"})}),e.jsx(ue,{error:h.error}),e.jsxs("div",{className:"flex flex-wrap items-end gap-3",children:[e.jsx("div",{className:"flex flex-wrap gap-2",children:L.map(s=>e.jsx(k,{size:"sm",variant:n.label===s.label?"primary":"outline",onPress:()=>H(s),children:s.label},s.label))}),e.jsxs("div",{className:"flex flex-wrap items-end gap-3",children:[e.jsx(J,{label:"User",value:g,onChange:N,options:se,placeholder:"All users"}),e.jsx(J,{label:"Model",value:u,onChange:_,options:te,placeholder:"All models"}),w?e.jsx(k,{size:"sm",variant:"ghost",onPress:ne,children:"Clear filters"}):null]})]}),ae?e.jsx("div",{className:"rounded-xl border border-[var(--otari-line)] bg-[var(--otari-surface)] px-4 py-10 text-center text-sm text-[var(--otari-muted)]",children:"No usage yet. Once the gateway serves requests, spend and volume appear here."}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex flex-wrap gap-4",children:[e.jsx(v,{label:"Spend",value:t?$(t.cost):"—",hint:t?e.jsx(b,{fraction:p(t.cost,l==null?void 0:l.cost)}):null,chart:C?e.jsx(E,{values:j.map(s=>s.cost),ariaLabel:"Spend trend over the selected window"}):void 0}),e.jsx(v,{label:"Requests",value:t?z(t.request_count):"—",hint:t?e.jsxs("span",{className:"text-[var(--otari-muted)]",children:[he(le)," errors",l?e.jsxs(e.Fragment,{children:[" · ",e.jsx(b,{fraction:p(t.request_count,l.request_count)})]}):null]}):null,chart:C?e.jsx(E,{values:j.map(s=>s.requests),ariaLabel:"Request volume trend over the selected window"}):void 0}),e.jsx(v,{label:"Tokens",value:t?S(t.total_tokens):"—",hint:t?e.jsx(b,{fraction:p(t.total_tokens,l==null?void 0:l.total_tokens)}):null,chart:C?e.jsx(E,{values:j.map(s=>s.tokens),ariaLabel:"Token usage trend over the selected window"}):void 0}),e.jsx(v,{label:"Cache read",value:t?S(t.cache_read_tokens):"—",hint:t?e.jsx(b,{fraction:p(t.cache_read_tokens,l==null?void 0:l.cache_read_tokens)}):null}),e.jsx(v,{label:"Cache write",value:t?S(t.cache_write_tokens):"—",hint:t?e.jsx(b,{fraction:p(t.cache_write_tokens,l==null?void 0:l.cache_write_tokens)}):null}),e.jsx(v,{label:"1h cache write",value:t?S(t.cache_write_1h_tokens??0):"—",hint:t?e.jsx(b,{fraction:p(t.cache_write_1h_tokens??0,(l==null?void 0:l.cache_write_1h_tokens)??0)}):null}),e.jsx(v,{label:"Avg latency",value:t?be(t.avg_latency_ms):"—"})]}),e.jsxs("div",{className:"grid gap-6 lg:grid-cols-2",children:[e.jsx(Q,{title:"Spend by model",rows:(i==null?void 0:i.by_model)??[],totalCost:(t==null?void 0:t.cost)??0,emptyLabel:w?"No usage matches these filters.":"No usage recorded yet.",onDrill:s=>I({model:s,user_id:g||void 0}),loading:h.isLoading}),e.jsx(Q,{title:"Spend by user",rows:(i==null?void 0:i.by_user)??[],totalCost:(t==null?void 0:t.cost)??0,emptyLabel:w?"No usage matches these filters.":"No usage recorded yet.",onDrill:s=>I({user_id:s,model:u.trim()||void 0}),loading:h.isLoading})]}),e.jsxs("div",{className:"flex flex-col gap-3 rounded-xl border border-[var(--otari-line)] bg-[var(--otari-surface)] p-4",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsx("h2",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:"Over time"}),e.jsxs("div",{className:"inline-flex gap-1.5",children:[ke.map(s=>e.jsx(k,{size:"sm",variant:o===s.key?"primary":"outline",onPress:()=>T(s.key),children:s.label},s.key)),h.isFetching?e.jsx(K,{size:"sm"}):null]})]}),h.isLoading?e.jsx("div",{className:"flex h-48 items-center justify-center",children:e.jsx(K,{size:"sm"})}):j.length===0?e.jsx("div",{className:"flex h-48 items-center justify-center text-sm text-[var(--otari-muted)]",children:"No data in this range."}):e.jsxs("figure",{className:"flex flex-col gap-2",children:[e.jsx(me,{data:F.points,formatValue:s=>W(s,o),ariaLabel:`${o} per ${n.bucket}`}),e.jsxs("figcaption",{className:"text-xs text-[var(--otari-muted)]",children:[W(F.peak,o)," peak · ",F.count," ",n.bucket==="hour"?"hours":"days"," (times in UTC)"]})]})]})]})]})}export{De as UsagePage}; diff --git a/src/gateway/static/dashboard/assets/UsersPage-EoUcpZFH.js b/src/gateway/static/dashboard/assets/UsersPage-D6v_0kF6.js similarity index 98% rename from src/gateway/static/dashboard/assets/UsersPage-EoUcpZFH.js rename to src/gateway/static/dashboard/assets/UsersPage-D6v_0kF6.js index cb676528..8d417142 100644 --- a/src/gateway/static/dashboard/assets/UsersPage-EoUcpZFH.js +++ b/src/gateway/static/dashboard/assets/UsersPage-D6v_0kF6.js @@ -1 +1 @@ -import{j as e}from"./tanstack-query-1t81HyiD.js";import{r as n}from"./react-dgEcD0HR.js";import{u as E,j as w,n as I,a9 as V,P as L,E as A,aa as O}from"./index-DHQmS-9o.js";import{F as N}from"./Field-HzRk1KDP.js";import{M as B,a as R}from"./ModelScopeControl-DTCXvnvU.js";import{T as H,a as $,b as f,L as q,c as W,d as G,e as b}from"./Table-CLdjdyTx.js";import{B as o,f as P,d as v}from"./heroui-BX6JwHY-.js";const J=new Intl.NumberFormat(void 0,{style:"currency",currency:"USD",maximumFractionDigits:4});function S(t){return J.format(t)}const _=t=>t.startsWith("apikey-");function D(t){return t.split("-")[0]}function M(t){return t.name??D(t.budget_id)}function T({value:t,onChange:i,budgets:r}){return e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx("label",{htmlFor:"user-budget",className:"text-sm font-medium text-[var(--otari-ink)]",children:"Budget"}),e.jsxs("select",{id:"user-budget",value:t??"",onChange:a=>i(a.target.value||null),className:"w-full rounded-lg border border-[var(--otari-line)] bg-[var(--otari-bg)] px-3 py-2 text-sm text-[var(--otari-ink)]",children:[e.jsx("option",{value:"",children:"No budget (unlimited)"}),r.map(a=>e.jsxs("option",{value:a.budget_id,children:[M(a),a.max_budget===null?" · no limit":` · ${S(a.max_budget)}`]},a.budget_id))]}),e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"The spending limit this user is held to. Manage budgets on the Budgets page."})]})}function K({onClose:t}){const i=O(),r=w(),[a,l]=n.useState(""),[d,c]=n.useState(""),[u,j]=n.useState(null),[y,x]=n.useState(null),[g,p]=n.useState(!0),m=()=>{if(i.isPending||!g||a.trim()==="")return;const h={user_id:a.trim(),alias:d.trim()||null,budget_id:u,allowed_models:y};i.mutate(h,{onSuccess:t})};return e.jsx(v,{children:e.jsxs(v.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsx("div",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:"Create user"}),e.jsx(A,{error:i.error}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsx(N,{label:"User ID",value:a,onChange:l,placeholder:"alice@example.com",isRequired:!0,autoFocus:!0,description:"The identifier callers send as the `user` field; spend and budgets track against it."}),e.jsx(N,{label:"Alias (optional)",value:d,onChange:c,placeholder:"Alice"})]}),e.jsx(T,{value:u,onChange:j,budgets:r.data??[]}),e.jsx(B,{title:"Model access (default for this user's keys)",description:"The models this user's keys may list and call by default. A key can narrow this, but never exceed it.",initial:null,onChange:(h,C)=>{x(h),p(C)}}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(o,{variant:"primary",isDisabled:i.isPending||!g||a.trim()==="",onPress:m,children:i.isPending?"Creating…":"Create user"}),e.jsx(o,{variant:"ghost",onPress:t,children:"Cancel"})]})]})})}function Q({user:t,onClose:i}){const r=I(),a=w(),[l,d]=n.useState(t.alias??""),[c,u]=n.useState(t.budget_id),[j,y]=n.useState(t.allowed_models),[x,g]=n.useState(!0),p=()=>{if(r.isPending||!x)return;const m={alias:l.trim()||null,budget_id:c,allowed_models:j};r.mutate({id:t.user_id,body:m},{onSuccess:i})};return e.jsx(v,{children:e.jsxs(v.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsxs("div",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:["Edit ",e.jsx("code",{children:t.user_id})]}),e.jsx(A,{error:r.error}),e.jsx(N,{label:"Alias",value:l,onChange:d,placeholder:"Alice"}),e.jsx(T,{value:c,onChange:u,budgets:a.data??[]}),e.jsx(B,{title:"Model access (default for this user's keys)",description:"The models this user's keys may list and call by default. A key can narrow this, but never exceed it.",initial:t.allowed_models,onChange:(m,h)=>{y(m),g(h)}}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(o,{variant:"primary",isDisabled:r.isPending||!x,onPress:p,children:r.isPending?"Saving…":"Save changes"}),e.jsx(o,{variant:"ghost",onPress:i,children:"Cancel"})]})]})})}function X({trigger:t,message:i,confirmLabel:r,isPending:a,onConfirm:l}){const[d,c]=n.useState(!1);return d?e.jsxs("div",{className:"flex flex-col items-end gap-1.5 rounded-lg border border-amber-200 bg-amber-50 p-2 text-right",children:[e.jsx("span",{className:"max-w-xs text-xs text-amber-800",children:i}),e.jsxs("span",{className:"inline-flex gap-1",children:[e.jsx(o,{size:"sm",variant:"danger",isDisabled:a,onPress:l,children:r}),e.jsx(o,{size:"sm",variant:"ghost",isDisabled:a,onPress:()=>c(!1),children:"Cancel"})]})]}):e.jsx(o,{size:"sm",variant:"danger-soft",onPress:()=>c(!0),children:t})}function Y({user:t}){return t.blocked?e.jsx(P,{size:"sm",color:"warning",children:"Blocked"}):e.jsx(P,{size:"sm",color:"accent",children:"Active"})}function Z({allowed:t}){const{text:i,tone:r}=R(t),a=r==="danger"?"text-red-700 font-medium":r==="muted"?"text-[var(--otari-muted)]":"text-[var(--otari-brand-dark)] font-medium",l=t&&t.length>0?t.join(", "):void 0;return e.jsx("span",{className:`text-xs ${a}`,title:l,children:i})}function ee({onCreate:t}){return e.jsx(v,{children:e.jsxs(v.Content,{className:"flex flex-col gap-4 p-6",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-semibold text-[var(--otari-ink)]",children:"No users yet"}),e.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:"A user owns API keys and carries the budget and default model access those keys inherit. Create a user here, then issue its keys on the API keys page."})]}),e.jsx("div",{children:e.jsx(o,{variant:"primary",onPress:t,children:"Create your first user"})})]})})}function de(){const t=E(),i=w(),r=I(),a=V(),[l,d]=n.useState(!1),[c,u]=n.useState(null),[j,y]=n.useState(!1),x=t.data??[],g=t.isLoading,p=x.filter(s=>_(s.user_id)).length,m=j?x:x.filter(s=>!_(s.user_id)),h=x.find(s=>s.user_id===c)??null,C=!g&&m.length===0&&!l,z=new Map((i.data??[]).map(s=>[s.budget_id,s])),U=(s,k)=>r.mutate({id:s.user_id,body:{blocked:k}});return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(L,{title:"Users",description:"People and teams that own API keys. Set each one's budget and default model access here; issue their keys on the API keys page.",action:l?null:e.jsx(o,{variant:"primary",onPress:()=>{u(null),d(!0)},children:"Create user"})}),e.jsx(A,{error:t.error??r.error??a.error}),C?e.jsx(ee,{onCreate:()=>{u(null),d(!0)}}):null,p>0?e.jsxs("label",{className:"flex w-fit items-center gap-2 text-xs text-[var(--otari-muted)]",children:[e.jsx("input",{type:"checkbox",checked:j,onChange:s=>y(s.target.checked)}),"Show auto-created (virtual) users (",p,")"]}):null,l?e.jsx(K,{onClose:()=>d(!1)}):null,h?e.jsx(Q,{user:h,onClose:()=>u(null)},h.user_id):null,e.jsxs(H,{children:[e.jsx($,{children:e.jsxs("tr",{children:[e.jsx(f,{children:"User"}),e.jsx(f,{children:"Status"}),e.jsx(f,{children:"Budget"}),e.jsx(f,{children:"Spend"}),e.jsx(f,{children:"Model access"}),e.jsx(f,{className:"text-right",children:"Actions"})]})}),e.jsx("tbody",{children:g?e.jsx(q,{colSpan:6}):m.length===0?e.jsx(W,{colSpan:6,children:"No users yet. Create one, or create an API key to auto-create one."}):m.map(s=>{const k=s.budget_id?z.get(s.budget_id):void 0;return e.jsxs(G,{selected:c===s.user_id,onClick:()=>{d(!1),u(s.user_id)},children:[e.jsx(b,{className:"font-medium text-[var(--otari-ink)]",children:e.jsxs("div",{className:"flex flex-col gap-0.5",children:[e.jsxs("span",{className:"inline-flex items-center gap-1.5",children:[e.jsx("code",{className:"text-xs",children:s.user_id}),_(s.user_id)?e.jsx(P,{size:"sm",color:"default",children:"virtual"}):null]}),s.alias?e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:s.alias}):null]})}),e.jsx(b,{children:e.jsx(Y,{user:s})}),e.jsx(b,{className:"text-[var(--otari-muted)]",children:s.budget_id?e.jsx("span",{title:s.budget_id,children:k?M(k):D(s.budget_id)}):"—"}),e.jsxs(b,{className:"text-[var(--otari-muted)]",children:[S(s.spend),s.reserved>0?e.jsxs("span",{className:"text-[var(--otari-muted)]",children:[" (+",S(s.reserved)," held)"]}):null]}),e.jsx(b,{children:e.jsx(Z,{allowed:s.allowed_models})}),e.jsx(b,{children:e.jsxs("div",{className:"flex items-center justify-end gap-1.5",onClick:F=>F.stopPropagation(),children:[s.blocked?e.jsx(o,{size:"sm",variant:"outline",isDisabled:r.isPending,onPress:()=>U(s,!1),children:"Unblock"}):e.jsx(o,{size:"sm",variant:"outline",isDisabled:r.isPending,onPress:()=>U(s,!0),children:"Block"}),e.jsx(o,{size:"sm",variant:"ghost",onPress:()=>{d(!1),u(s.user_id)},children:"Edit"}),e.jsx(X,{trigger:"Delete",confirmLabel:"Delete user",isPending:a.isPending,message:e.jsxs(e.Fragment,{children:["Delete ",e.jsx("strong",{children:s.user_id}),"? This deactivates its API keys and hides the user; usage history is preserved."]}),onConfirm:()=>a.mutate(s.user_id)})]})})]},s.user_id)})})]})]})}export{de as UsersPage}; +import{j as e}from"./tanstack-query-1t81HyiD.js";import{r as n}from"./react-dgEcD0HR.js";import{u as E,j as w,n as I,a9 as V,P as L,E as A,aa as O}from"./index-DAVt9uB3.js";import{F as N}from"./Field-HzRk1KDP.js";import{M as B,a as R}from"./ModelScopeControl-CkKcIwGe.js";import{T as H,a as $,b as f,L as q,c as W,d as G,e as b}from"./Table-CLdjdyTx.js";import{B as o,f as P,d as v}from"./heroui-BX6JwHY-.js";const J=new Intl.NumberFormat(void 0,{style:"currency",currency:"USD",maximumFractionDigits:4});function S(t){return J.format(t)}const _=t=>t.startsWith("apikey-");function D(t){return t.split("-")[0]}function M(t){return t.name??D(t.budget_id)}function T({value:t,onChange:i,budgets:r}){return e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx("label",{htmlFor:"user-budget",className:"text-sm font-medium text-[var(--otari-ink)]",children:"Budget"}),e.jsxs("select",{id:"user-budget",value:t??"",onChange:a=>i(a.target.value||null),className:"w-full rounded-lg border border-[var(--otari-line)] bg-[var(--otari-bg)] px-3 py-2 text-sm text-[var(--otari-ink)]",children:[e.jsx("option",{value:"",children:"No budget (unlimited)"}),r.map(a=>e.jsxs("option",{value:a.budget_id,children:[M(a),a.max_budget===null?" · no limit":` · ${S(a.max_budget)}`]},a.budget_id))]}),e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"The spending limit this user is held to. Manage budgets on the Budgets page."})]})}function K({onClose:t}){const i=O(),r=w(),[a,l]=n.useState(""),[d,c]=n.useState(""),[u,j]=n.useState(null),[y,x]=n.useState(null),[g,p]=n.useState(!0),m=()=>{if(i.isPending||!g||a.trim()==="")return;const h={user_id:a.trim(),alias:d.trim()||null,budget_id:u,allowed_models:y};i.mutate(h,{onSuccess:t})};return e.jsx(v,{children:e.jsxs(v.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsx("div",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:"Create user"}),e.jsx(A,{error:i.error}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsx(N,{label:"User ID",value:a,onChange:l,placeholder:"alice@example.com",isRequired:!0,autoFocus:!0,description:"The identifier callers send as the `user` field; spend and budgets track against it."}),e.jsx(N,{label:"Alias (optional)",value:d,onChange:c,placeholder:"Alice"})]}),e.jsx(T,{value:u,onChange:j,budgets:r.data??[]}),e.jsx(B,{title:"Model access (default for this user's keys)",description:"The models this user's keys may list and call by default. A key can narrow this, but never exceed it.",initial:null,onChange:(h,C)=>{x(h),p(C)}}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(o,{variant:"primary",isDisabled:i.isPending||!g||a.trim()==="",onPress:m,children:i.isPending?"Creating…":"Create user"}),e.jsx(o,{variant:"ghost",onPress:t,children:"Cancel"})]})]})})}function Q({user:t,onClose:i}){const r=I(),a=w(),[l,d]=n.useState(t.alias??""),[c,u]=n.useState(t.budget_id),[j,y]=n.useState(t.allowed_models),[x,g]=n.useState(!0),p=()=>{if(r.isPending||!x)return;const m={alias:l.trim()||null,budget_id:c,allowed_models:j};r.mutate({id:t.user_id,body:m},{onSuccess:i})};return e.jsx(v,{children:e.jsxs(v.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsxs("div",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:["Edit ",e.jsx("code",{children:t.user_id})]}),e.jsx(A,{error:r.error}),e.jsx(N,{label:"Alias",value:l,onChange:d,placeholder:"Alice"}),e.jsx(T,{value:c,onChange:u,budgets:a.data??[]}),e.jsx(B,{title:"Model access (default for this user's keys)",description:"The models this user's keys may list and call by default. A key can narrow this, but never exceed it.",initial:t.allowed_models,onChange:(m,h)=>{y(m),g(h)}}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(o,{variant:"primary",isDisabled:r.isPending||!x,onPress:p,children:r.isPending?"Saving…":"Save changes"}),e.jsx(o,{variant:"ghost",onPress:i,children:"Cancel"})]})]})})}function X({trigger:t,message:i,confirmLabel:r,isPending:a,onConfirm:l}){const[d,c]=n.useState(!1);return d?e.jsxs("div",{className:"flex flex-col items-end gap-1.5 rounded-lg border border-amber-200 bg-amber-50 p-2 text-right",children:[e.jsx("span",{className:"max-w-xs text-xs text-amber-800",children:i}),e.jsxs("span",{className:"inline-flex gap-1",children:[e.jsx(o,{size:"sm",variant:"danger",isDisabled:a,onPress:l,children:r}),e.jsx(o,{size:"sm",variant:"ghost",isDisabled:a,onPress:()=>c(!1),children:"Cancel"})]})]}):e.jsx(o,{size:"sm",variant:"danger-soft",onPress:()=>c(!0),children:t})}function Y({user:t}){return t.blocked?e.jsx(P,{size:"sm",color:"warning",children:"Blocked"}):e.jsx(P,{size:"sm",color:"accent",children:"Active"})}function Z({allowed:t}){const{text:i,tone:r}=R(t),a=r==="danger"?"text-red-700 font-medium":r==="muted"?"text-[var(--otari-muted)]":"text-[var(--otari-brand-dark)] font-medium",l=t&&t.length>0?t.join(", "):void 0;return e.jsx("span",{className:`text-xs ${a}`,title:l,children:i})}function ee({onCreate:t}){return e.jsx(v,{children:e.jsxs(v.Content,{className:"flex flex-col gap-4 p-6",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-semibold text-[var(--otari-ink)]",children:"No users yet"}),e.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:"A user owns API keys and carries the budget and default model access those keys inherit. Create a user here, then issue its keys on the API keys page."})]}),e.jsx("div",{children:e.jsx(o,{variant:"primary",onPress:t,children:"Create your first user"})})]})})}function de(){const t=E(),i=w(),r=I(),a=V(),[l,d]=n.useState(!1),[c,u]=n.useState(null),[j,y]=n.useState(!1),x=t.data??[],g=t.isLoading,p=x.filter(s=>_(s.user_id)).length,m=j?x:x.filter(s=>!_(s.user_id)),h=x.find(s=>s.user_id===c)??null,C=!g&&m.length===0&&!l,z=new Map((i.data??[]).map(s=>[s.budget_id,s])),U=(s,k)=>r.mutate({id:s.user_id,body:{blocked:k}});return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(L,{title:"Users",description:"People and teams that own API keys. Set each one's budget and default model access here; issue their keys on the API keys page.",action:l?null:e.jsx(o,{variant:"primary",onPress:()=>{u(null),d(!0)},children:"Create user"})}),e.jsx(A,{error:t.error??r.error??a.error}),C?e.jsx(ee,{onCreate:()=>{u(null),d(!0)}}):null,p>0?e.jsxs("label",{className:"flex w-fit items-center gap-2 text-xs text-[var(--otari-muted)]",children:[e.jsx("input",{type:"checkbox",checked:j,onChange:s=>y(s.target.checked)}),"Show auto-created (virtual) users (",p,")"]}):null,l?e.jsx(K,{onClose:()=>d(!1)}):null,h?e.jsx(Q,{user:h,onClose:()=>u(null)},h.user_id):null,e.jsxs(H,{children:[e.jsx($,{children:e.jsxs("tr",{children:[e.jsx(f,{children:"User"}),e.jsx(f,{children:"Status"}),e.jsx(f,{children:"Budget"}),e.jsx(f,{children:"Spend"}),e.jsx(f,{children:"Model access"}),e.jsx(f,{className:"text-right",children:"Actions"})]})}),e.jsx("tbody",{children:g?e.jsx(q,{colSpan:6}):m.length===0?e.jsx(W,{colSpan:6,children:"No users yet. Create one, or create an API key to auto-create one."}):m.map(s=>{const k=s.budget_id?z.get(s.budget_id):void 0;return e.jsxs(G,{selected:c===s.user_id,onClick:()=>{d(!1),u(s.user_id)},children:[e.jsx(b,{className:"font-medium text-[var(--otari-ink)]",children:e.jsxs("div",{className:"flex flex-col gap-0.5",children:[e.jsxs("span",{className:"inline-flex items-center gap-1.5",children:[e.jsx("code",{className:"text-xs",children:s.user_id}),_(s.user_id)?e.jsx(P,{size:"sm",color:"default",children:"virtual"}):null]}),s.alias?e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:s.alias}):null]})}),e.jsx(b,{children:e.jsx(Y,{user:s})}),e.jsx(b,{className:"text-[var(--otari-muted)]",children:s.budget_id?e.jsx("span",{title:s.budget_id,children:k?M(k):D(s.budget_id)}):"—"}),e.jsxs(b,{className:"text-[var(--otari-muted)]",children:[S(s.spend),s.reserved>0?e.jsxs("span",{className:"text-[var(--otari-muted)]",children:[" (+",S(s.reserved)," held)"]}):null]}),e.jsx(b,{children:e.jsx(Z,{allowed:s.allowed_models})}),e.jsx(b,{children:e.jsxs("div",{className:"flex items-center justify-end gap-1.5",onClick:F=>F.stopPropagation(),children:[s.blocked?e.jsx(o,{size:"sm",variant:"outline",isDisabled:r.isPending,onPress:()=>U(s,!1),children:"Unblock"}):e.jsx(o,{size:"sm",variant:"outline",isDisabled:r.isPending,onPress:()=>U(s,!0),children:"Block"}),e.jsx(o,{size:"sm",variant:"ghost",onPress:()=>{d(!1),u(s.user_id)},children:"Edit"}),e.jsx(X,{trigger:"Delete",confirmLabel:"Delete user",isPending:a.isPending,message:e.jsxs(e.Fragment,{children:["Delete ",e.jsx("strong",{children:s.user_id}),"? This deactivates its API keys and hides the user; usage history is preserved."]}),onConfirm:()=>a.mutate(s.user_id)})]})})]},s.user_id)})})]})]})}export{de as UsersPage}; diff --git a/src/gateway/static/dashboard/assets/index-BFG8RNrJ.css b/src/gateway/static/dashboard/assets/index-CHQYSDoG.css similarity index 95% rename from src/gateway/static/dashboard/assets/index-BFG8RNrJ.css rename to src/gateway/static/dashboard/assets/index-CHQYSDoG.css index e71e4fb9..d9e174ed 100644 --- a/src/gateway/static/dashboard/assets/index-BFG8RNrJ.css +++ b/src/gateway/static/dashboard/assets/index-CHQYSDoG.css @@ -1 +1 @@ -/*! tailwindcss v4.3.1 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-duration:initial;--tw-animation-delay:0s;--tw-animation-direction:normal;--tw-animation-duration:initial;--tw-animation-fill-mode:none;--tw-animation-iteration-count:1;--tw-enter-blur:0;--tw-enter-opacity:1;--tw-enter-rotate:0;--tw-enter-scale:1;--tw-enter-translate-x:0;--tw-enter-translate-y:0;--tw-exit-blur:0;--tw-exit-opacity:1;--tw-exit-rotate:0;--tw-exit-scale:1;--tw-exit-translate-x:0;--tw-exit-translate-y:0;--tw-content:"";--tw-ease:initial;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1;--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-space-y-reverse:0;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-space-x-reverse:0}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-red-50:oklch(97.1% .013 17.38);--color-red-200:oklch(88.5% .062 18.334);--color-red-500:oklch(63.7% .237 25.331);--color-red-700:oklch(50.5% .213 27.518);--color-amber-50:oklch(98.7% .022 95.277);--color-amber-200:oklch(92.4% .12 95.746);--color-amber-400:oklch(82.8% .189 84.429);--color-amber-500:oklch(76.9% .188 70.08);--color-amber-700:oklch(55.5% .163 48.998);--color-amber-800:oklch(47.3% .137 46.201);--color-amber-900:oklch(41.4% .112 45.904);--color-amber-950:oklch(27.9% .077 45.635);--color-green-50:oklch(98.2% .018 155.826);--color-green-200:oklch(92.5% .084 155.995);--color-green-500:oklch(72.3% .219 149.579);--color-green-700:oklch(52.7% .154 150.069);--color-emerald-50:oklch(97.9% .021 166.113);--color-emerald-200:oklch(90.5% .093 164.15);--color-emerald-500:oklch(69.6% .17 162.48);--color-emerald-700:oklch(50.8% .118 165.612);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-xs:20rem;--container-sm:24rem;--container-md:28rem;--container-lg:32rem;--container-2xl:42rem;--container-3xl:48rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height: 1.5 ;--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--text-3xl:1.875rem;--text-3xl--line-height: 1.2 ;--text-4xl:2.25rem;--text-4xl--line-height:calc(2.5 / 2.25);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-tight:-.025em;--tracking-wide:.025em;--tracking-wider:.05em;--leading-relaxed:1.625;--radius-xl:calc(var(--radius) * 1.5);--radius-2xl:calc(var(--radius) * 2);--radius-3xl:calc(var(--radius) * 3);--ease-out:cubic-bezier(0, 0, .2, 1);--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--blur-md:12px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--shadow-surface:var(--surface-shadow);--shadow-overlay:var(--overlay-shadow);--border-width-field:var(--field-border-width,var(--border-width));--ease-smooth:ease;--ease-out-quad:cubic-bezier(.25, .46, .45, .94);--ease-out-quart:cubic-bezier(.165, .84, .44, 1);--ease-out-fluid:cubic-bezier(.32, .72, 0, 1);--ease-linear:linear}@layer theme.base{:root,.light,.default,[data-theme=light],[data-theme=default]{color-scheme:light;--white:oklch(100% 0 0);--black:oklch(0% 0 0);--snow:oklch(99.11% 0 0);--eclipse:oklch(21.03% .0059 285.89);--spacing:.25rem;--border-width:1px;--field-border-width:0px;--disabled-opacity:.5;--ring-offset-width:2px;--cursor-interactive:pointer;--cursor-disabled:not-allowed;--radius:.5rem;--field-radius:calc(var(--radius) * 1.5);--background:oklch(97.02% 0 0);--foreground:var(--eclipse);--surface:var(--white);--surface-foreground:var(--foreground);--surface-secondary:oklch(95.24% .0013 286.37);--surface-secondary-foreground:var(--foreground);--surface-tertiary:oklch(93.73% .0013 286.37);--surface-tertiary-foreground:var(--foreground);--overlay:var(--white);--overlay-foreground:var(--foreground);--muted:oklch(55.17% .0138 285.94);--scrollbar:var(--scrollbar-thumb);--scrollbar-thumb:var(--foreground)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--scrollbar-thumb:color-mix(in oklch, var(--foreground) 15%, transparent)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--scrollbar-track:transparent;--scrollbar-gutter:auto;--scrollbar-width:thin;--scrollbar-color:var(--scrollbar-thumb) var(--scrollbar-track);--default:oklch(94% .001 286.375);--default-foreground:var(--eclipse);--accent:oklch(62.04% .195 253.83);--accent-foreground:var(--snow);--field-background:var(--white);--field-foreground:oklch(21.03% .0059 285.89);--field-placeholder:var(--muted);--field-border:transparent;--success:oklch(73.29% .1935 150.81);--success-foreground:var(--eclipse);--warning:oklch(78.19% .1585 72.33);--warning-foreground:var(--eclipse);--danger:oklch(65.32% .2328 25.74);--danger-foreground:var(--snow);--segment:var(--white);--segment-foreground:var(--eclipse);--border:oklch(90% .004 286.32);--separator:oklch(92% .004 286.32);--focus:var(--accent);--link:var(--foreground);--backdrop:#00000080;--surface-hover:var(--surface)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--surface-hover:color-mix(in oklab, var(--surface) 92%, var(--surface-foreground) 8%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--background-secondary:var(--background)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--background-secondary:color-mix(in oklab, var(--background) 96%, var(--foreground) 4%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--background-tertiary:var(--background)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--background-tertiary:color-mix(in oklab, var(--background) 92%, var(--foreground) 8%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--background-inverse:var(--foreground);--default-hover:var(--default)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--default-hover:color-mix(in oklab, var(--default) 96%, var(--default-foreground) 4%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--accent-hover:var(--accent)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--accent-hover:color-mix(in oklab, var(--accent) 90%, var(--accent-foreground) 10%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--success-hover:var(--success)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--success-hover:color-mix(in oklab, var(--success) 90%, var(--success-foreground) 10%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--warning-hover:var(--warning)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--warning-hover:color-mix(in oklab, var(--warning) 90%, var(--warning-foreground) 10%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--danger-hover:var(--danger)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--danger-hover:color-mix(in oklab, var(--danger) 90%, var(--danger-foreground) 10%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--field-hover:var(--field-background,var(--default))}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--field-hover:color-mix(in oklab, var(--field-background,var(--default)) 90%, var(--field-foreground,var(--foreground)) 2%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--field-focus:var(--field-background,var(--default));--field-border-hover:var(--field-border,var(--border))}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--field-border-hover:color-mix(in oklab, var(--field-border,var(--border)) 88%, var(--field-foreground,var(--foreground)) 10%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--field-border-focus:var(--field-border,var(--border))}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--field-border-focus:color-mix(in oklab, var(--field-border,var(--border)) 74%, var(--field-foreground,var(--foreground)) 22%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--default-soft:var(--default)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--default-soft:color-mix(in oklab, var(--default) 50%, transparent)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--default-soft-foreground:var(--default-foreground);--default-soft-hover:var(--default)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--default-soft-hover:color-mix(in oklab, var(--default) 60%, transparent)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--accent-soft:var(--accent)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--accent-soft:color-mix(in oklab, var(--accent) 15%, transparent)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--accent-soft-foreground:var(--accent)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--accent-soft-foreground:color-mix(in oklab, var(--accent) 70%, var(--foreground) 30%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--accent-soft-hover:var(--accent)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--accent-soft-hover:color-mix(in oklab, var(--accent) 20%, transparent)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--danger-soft:var(--danger)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--danger-soft:color-mix(in oklab, var(--danger) 15%, transparent)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--danger-soft-foreground:var(--danger)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--danger-soft-foreground:color-mix(in oklab, var(--danger) 70%, var(--foreground) 40%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--danger-soft-hover:var(--danger)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--danger-soft-hover:color-mix(in oklab, var(--danger) 20%, transparent)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--warning-soft:var(--warning)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--warning-soft:color-mix(in oklab, var(--warning) 15%, transparent)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--warning-soft-foreground:var(--warning)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--warning-soft-foreground:color-mix(in oklab, var(--warning) 80%, var(--foreground) 70%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--warning-soft-hover:var(--warning)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--warning-soft-hover:color-mix(in oklab, var(--warning) 20%, transparent)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--success-soft:var(--success)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--success-soft:color-mix(in oklab, var(--success) 15%, transparent)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--success-soft-foreground:var(--success)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--success-soft-foreground:color-mix(in oklab, var(--success) 80%, var(--foreground) 60%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--success-soft-hover:var(--success)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--success-soft-hover:color-mix(in oklab, var(--success) 20%, transparent)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--separator-secondary:var(--surface)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--separator-secondary:color-mix(in oklab, var(--surface) 85%, var(--surface-foreground) 15%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--separator-tertiary:var(--surface)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--separator-tertiary:color-mix(in oklab, var(--surface) 81%, var(--surface-foreground) 19%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--border-secondary:var(--surface)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--border-secondary:color-mix(in oklab, var(--surface) 78%, var(--surface-foreground) 22%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--border-tertiary:var(--surface)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--border-tertiary:color-mix(in oklab, var(--surface) 66%, var(--surface-foreground) 34%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--surface-shadow:0 2px 4px 0 #0000000a, 0 1px 2px 0 #0000000f, 0 0 1px 0 #0000000f;--overlay-shadow:0 2px 8px 0 #0000000f, 0 -6px 12px 0 #00000008, 0 14px 28px 0 #00000014;--field-shadow:0 2px 4px 0 #0000000a, 0 1px 2px 0 #0000000f, 0 0 1px 0 #0000000f;--skeleton-animation:shimmer;--tooltip-delay:1.5s;--tooltip-close-delay:.5s}.dark,[data-theme=dark]{color-scheme:dark;--background:oklch(12% .005 285.823);--foreground:var(--snow);--surface:oklch(21.03% .0059 285.89);--surface-foreground:var(--foreground);--surface-secondary:oklch(25.7% .0037 286.14);--surface-tertiary:oklch(27.21% .0024 247.91);--overlay:oklch(21.03% .0059 285.89);--overlay-foreground:var(--foreground);--muted:oklch(70.5% .015 286.067);--scrollbar:var(--scrollbar-thumb);--scrollbar-thumb:var(--foreground)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--scrollbar-thumb:color-mix(in oklch, var(--foreground) 15%, transparent)}}.dark,[data-theme=dark]{--scrollbar-track:transparent;--scrollbar-gutter:auto;--scrollbar-width:thin;--scrollbar-color:var(--scrollbar-thumb) var(--scrollbar-track);--default:oklch(27.4% .006 286.033);--default-foreground:var(--snow);--field-background:oklch(21.03% .0059 285.89);--field-foreground:var(--foreground);--warning:oklch(82.03% .1388 76.34);--warning-foreground:var(--eclipse);--danger:oklch(59.4% .1967 24.63);--danger-foreground:var(--snow);--segment:oklch(39.64% .01 285.93);--segment-foreground:var(--foreground);--border:oklch(28% .006 286.033);--separator:oklch(25% .006 286.033);--focus:var(--accent);--link:var(--foreground);--backdrop:#0009;--surface-shadow:0 0 0 0 transparent inset;--overlay-shadow:0 0 1px 0 #ffffff4d inset;--field-shadow:0 0 0 0 transparent inset;--surface-hover:var(--surface)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--surface-hover:color-mix(in oklab, var(--surface) 92%, var(--surface-foreground) 8%)}}.dark,[data-theme=dark]{--background-secondary:var(--background)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--background-secondary:color-mix(in oklab, var(--background) 96%, var(--foreground) 4%)}}.dark,[data-theme=dark]{--background-tertiary:var(--background)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--background-tertiary:color-mix(in oklab, var(--background) 92%, var(--foreground) 8%)}}.dark,[data-theme=dark]{--background-inverse:var(--foreground);--default-hover:var(--default)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--default-hover:color-mix(in oklab, var(--default) 96%, var(--default-foreground) 4%)}}.dark,[data-theme=dark]{--accent-hover:var(--accent)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--accent-hover:color-mix(in oklab, var(--accent) 90%, var(--accent-foreground) 10%)}}.dark,[data-theme=dark]{--success-hover:var(--success)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--success-hover:color-mix(in oklab, var(--success) 90%, var(--success-foreground) 10%)}}.dark,[data-theme=dark]{--warning-hover:var(--warning)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--warning-hover:color-mix(in oklab, var(--warning) 90%, var(--warning-foreground) 10%)}}.dark,[data-theme=dark]{--danger-hover:var(--danger)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--danger-hover:color-mix(in oklab, var(--danger) 90%, var(--danger-foreground) 10%)}}.dark,[data-theme=dark]{--field-hover:var(--field-background,var(--default))}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--field-hover:color-mix(in oklab, var(--field-background,var(--default)) 90%, var(--field-foreground,var(--foreground)) 2%)}}.dark,[data-theme=dark]{--field-focus:var(--field-background,var(--default));--field-border-hover:var(--field-border,var(--border))}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--field-border-hover:color-mix(in oklab, var(--field-border,var(--border)) 88%, var(--field-foreground,var(--foreground)) 10%)}}.dark,[data-theme=dark]{--field-border-focus:var(--field-border,var(--border))}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--field-border-focus:color-mix(in oklab, var(--field-border,var(--border)) 74%, var(--field-foreground,var(--foreground)) 22%)}}.dark,[data-theme=dark]{--default-soft:var(--default)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--default-soft:color-mix(in oklab, var(--default) 50%, transparent)}}.dark,[data-theme=dark]{--default-soft-foreground:var(--default-foreground);--default-soft-hover:var(--default)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--default-soft-hover:color-mix(in oklab, var(--default) 60%, transparent)}}.dark,[data-theme=dark]{--accent-soft:var(--accent)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--accent-soft:color-mix(in oklab, var(--accent) 12%, transparent)}}.dark,[data-theme=dark]{--accent-soft-foreground:var(--accent)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--accent-soft-foreground:color-mix(in oklab, var(--accent) 80%, var(--foreground) 30%)}}.dark,[data-theme=dark]{--accent-soft-hover:var(--accent)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--accent-soft-hover:color-mix(in oklab, var(--accent) 16%, transparent)}}.dark,[data-theme=dark]{--danger-soft:var(--danger)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--danger-soft:color-mix(in oklab, var(--danger) 15%, transparent)}}.dark,[data-theme=dark]{--danger-soft-foreground:var(--danger)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--danger-soft-foreground:color-mix(in oklab, var(--danger) 80%, var(--foreground) 30%)}}.dark,[data-theme=dark]{--danger-soft-hover:var(--danger)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--danger-soft-hover:color-mix(in oklab, var(--danger) 20%, transparent)}}.dark,[data-theme=dark]{--warning-soft:var(--warning)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--warning-soft:color-mix(in oklab, var(--warning) 12%, transparent)}}.dark,[data-theme=dark]{--warning-soft-foreground:var(--warning)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--warning-soft-foreground:color-mix(in oklab, var(--warning) 80%, var(--foreground) 30%)}}.dark,[data-theme=dark]{--warning-soft-hover:var(--warning)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--warning-soft-hover:color-mix(in oklab, var(--warning) 16%, transparent)}}.dark,[data-theme=dark]{--success-soft:var(--success)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--success-soft:color-mix(in oklab, var(--success) 12%, transparent)}}.dark,[data-theme=dark]{--success-soft-foreground:var(--success)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--success-soft-foreground:color-mix(in oklab, var(--success) 80%, var(--foreground) 30%)}}.dark,[data-theme=dark]{--success-soft-hover:var(--success)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--success-soft-hover:color-mix(in oklab, var(--success) 16%, transparent)}}.dark,[data-theme=dark]{--separator-secondary:var(--surface)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--separator-secondary:color-mix(in oklab, var(--surface) 85%, var(--surface-foreground) 15%)}}.dark,[data-theme=dark]{--separator-tertiary:var(--surface)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--separator-tertiary:color-mix(in oklab, var(--surface) 81%, var(--surface-foreground) 19%)}}.dark,[data-theme=dark]{--border-secondary:var(--surface)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--border-secondary:color-mix(in oklab, var(--surface) 78%, var(--surface-foreground) 22%)}}.dark,[data-theme=dark]{--border-tertiary:var(--surface)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--border-tertiary:color-mix(in oklab, var(--surface) 66%, var(--surface-foreground) 34%)}}[data-vibrant-palette=true]:not(.dark):not([data-theme=dark]){--accent-soft-foreground:var(--accent)}@supports (color:color-mix(in lab,red,red)){[data-vibrant-palette=true]:not(.dark):not([data-theme=dark]){--accent-soft-foreground:color-mix(in oklab, var(--accent) 92%, var(--foreground) 8%)}}[data-vibrant-palette=true]:not(.dark):not([data-theme=dark]){--danger-soft-foreground:var(--danger)}@supports (color:color-mix(in lab,red,red)){[data-vibrant-palette=true]:not(.dark):not([data-theme=dark]){--danger-soft-foreground:color-mix(in oklab, var(--danger) 92%, var(--foreground) 8%)}}[data-vibrant-palette=true]:not(.dark):not([data-theme=dark]){--warning-soft-foreground:var(--warning)}@supports (color:color-mix(in lab,red,red)){[data-vibrant-palette=true]:not(.dark):not([data-theme=dark]){--warning-soft-foreground:color-mix(in oklab, var(--warning) 92%, var(--foreground) 8%)}}[data-vibrant-palette=true]:not(.dark):not([data-theme=dark]){--success-soft-foreground:var(--success)}@supports (color:color-mix(in lab,red,red)){[data-vibrant-palette=true]:not(.dark):not([data-theme=dark]){--success-soft-foreground:color-mix(in oklab, var(--success) 92%, var(--foreground) 8%)}}[data-vibrant-palette=true].dark,[data-vibrant-palette=true][data-theme=dark]{--accent-soft-foreground:var(--accent)}@supports (color:color-mix(in lab,red,red)){[data-vibrant-palette=true].dark,[data-vibrant-palette=true][data-theme=dark]{--accent-soft-foreground:color-mix(in oklab, var(--accent) 92%, var(--foreground) 8%)}}[data-vibrant-palette=true].dark,[data-vibrant-palette=true][data-theme=dark]{--danger-soft-foreground:var(--danger)}@supports (color:color-mix(in lab,red,red)){[data-vibrant-palette=true].dark,[data-vibrant-palette=true][data-theme=dark]{--danger-soft-foreground:color-mix(in oklab, var(--danger) 92%, var(--foreground) 8%)}}[data-vibrant-palette=true].dark,[data-vibrant-palette=true][data-theme=dark]{--warning-soft-foreground:var(--warning)}@supports (color:color-mix(in lab,red,red)){[data-vibrant-palette=true].dark,[data-vibrant-palette=true][data-theme=dark]{--warning-soft-foreground:color-mix(in oklab, var(--warning) 92%, var(--foreground) 8%)}}[data-vibrant-palette=true].dark,[data-vibrant-palette=true][data-theme=dark]{--success-soft-foreground:var(--success)}@supports (color:color-mix(in lab,red,red)){[data-vibrant-palette=true].dark,[data-vibrant-palette=true][data-theme=dark]{--success-soft-foreground:color-mix(in oklab, var(--success) 92%, var(--foreground) 8%)}}}@layer components;}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}*,:after,:before,::backdrop{border-color:var(--border,currentColor)}::file-selector-button{border-color:var(--border,currentColor)}:root{view-transition-name:none}::view-transition{pointer-events:none}[data-scrollbar=thin]{--scrollbar-width:thin;--scrollbar-color:var(--scrollbar-thumb) var(--scrollbar-track);--scrollbar-gutter:auto}[data-scrollbar=default]{--scrollbar-width:auto;--scrollbar-color:auto;--scrollbar-gutter:auto}[data-scrollbar=none]{--scrollbar-width:none;--scrollbar-color:auto;--scrollbar-gutter:auto}}@layer components{.close-button{isolation:isolate;height:calc(var(--spacing) * 6);width:calc(var(--spacing) * 6);transform-origin:50%;border-radius:calc(var(--radius) * 1.5);padding:var(--spacing);-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;cursor:var(--cursor-interactive);transition:transform .25s var(--ease-out-quart),color .15s var(--ease-out),background-color .1s var(--ease-out),box-shadow .15s var(--ease-out);transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);flex-shrink:0;justify-content:center;align-items:center;display:inline-flex;position:relative}.close-button:is([data-reduce-motion=true],[data-reduce-motion=true] *),.close-button:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.close-button:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.close-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.close-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.close-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.close-button:focus-visible:not(:focus),.close-button[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.close-button:disabled,.close-button[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.close-button[data-pending=true]{pointer-events:none}.close-button svg{pointer-events:none;width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4);margin-inline:calc(var(--spacing) * -.5);margin-block:calc(var(--spacing) * .5);flex-shrink:0;align-self:center}.close-button--default{background-color:var(--default);color:var(--muted)}@media(hover:hover){.close-button--default:hover,.close-button--default[data-hovered=true]{background-color:var(--default-hover)}}.close-button--default:active,.close-button--default[data-pressed=true]{transform:scale(.93)}.description{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));text-wrap:wrap;overflow-wrap:break-word;color:var(--muted)}.error-message{height:auto;font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));overflow-wrap:break-word;color:var(--danger);transition:opacity .15s var(--ease-out),height .35s var(--ease-smooth)}.error-message:is([data-reduce-motion=true],[data-reduce-motion=true] *),.error-message:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.error-message:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.error-message:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.error-message:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.error-message:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.field-error{height:0;padding-inline:var(--spacing);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));overflow-wrap:break-word;color:var(--danger);opacity:0}.field-error[data-visible]{opacity:1;height:auto}.field-error{transition:opacity .15s var(--ease-out),height .35s var(--ease-smooth)}.field-error:is([data-reduce-motion=true],[data-reduce-motion=true] *),.field-error:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.field-error:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.field-error:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.field-error:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.field-error:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.checkbox>.field-error,.checkbox>[data-slot=field-error],.switch>.field-error,.switch>[data-slot=field-error],.radio>.field-error,.radio>[data-slot=field-error]{height:auto;min-height:0;color:var(--muted);opacity:1;margin:0;padding:0;transition:none}.label{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--foreground)}:is(.label--required,[data-required=true]:not([role=group]):not([role=radiogroup]):not([role=checkboxgroup])>.label,[data-required=true]:not([data-slot=radio]):not([data-slot=checkbox])>.label):after{margin-left:calc(var(--spacing) * .5);color:var(--danger);--tw-content:"*";content:var(--tw-content)}.label--disabled,[data-disabled=true] .label{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.label--invalid,[data-invalid=true] .label,[aria-invalid=true] .label{color:var(--danger)}.accordion{contain:layout style;width:100%}.accordion__body{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.accordion__body-inner{padding-inline:calc(var(--spacing) * 4);padding-top:0;padding-bottom:calc(var(--spacing) * 4);color:var(--muted)}.accordion__indicator{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4);color:var(--muted);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.25s;flex-shrink:0;margin-left:auto;transition-duration:.25s}.accordion__indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *),.accordion__indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.accordion__indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.accordion__indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.accordion__indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.accordion__indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.accordion__indicator[data-expanded=true]{rotate:-180deg}.accordion__item{--tw-border-style:none;border-style:none;position:relative}.accordion__item:after{content:"";border-radius:calc(var(--radius) * .25);background-color:var(--separator);width:100%;height:1px;position:absolute;bottom:0;left:0}.accordion__item:last-child:after{content:none}.accordion__item[data-hide-separator=true]:after{display:none}.accordion__trigger{cursor:var(--cursor-interactive);padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 4);text-align:left;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);-webkit-tap-highlight-color:transparent;transition:opacity .15s var(--ease-out),box-shadow .15s var(--ease-out);flex:1;justify-content:space-between;align-items:center;display:flex}.accordion__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *),.accordion__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.accordion__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.accordion__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.accordion__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.accordion__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}@media(hover:hover){.accordion__trigger:hover:not([aria-expanded=true]),.accordion__trigger[data-hovered=true]:not([aria-expanded=true]){background-color:var(--foreground)}@supports (color:color-mix(in lab,red,red)){.accordion__trigger:hover:not([aria-expanded=true]),.accordion__trigger[data-hovered=true]:not([aria-expanded=true]){background-color:color-mix(in oklab,var(--foreground) 3%,transparent 90%)}}}.accordion__trigger:focus-visible:not(:focus),.accordion__trigger[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.accordion__trigger:disabled,.accordion__trigger[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.accordion__panel{opacity:0;height:var(--disclosure-panel-height);transition:height .2s var(--ease-out-quad),opacity .2s var(--ease-out);overflow:clip}.accordion__panel:is([data-reduce-motion=true],[data-reduce-motion=true] *),.accordion__panel:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.accordion__panel:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.accordion__panel:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.accordion__panel:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.accordion__panel:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.accordion__panel[data-expanded=true]{will-change:height,opacity;opacity:1}.accordion--surface{background-color:var(--surface);border-radius:min(32px,var(--radius-3xl))}@media(hover:hover){.accordion--surface .accordion__trigger:hover:not([aria-expanded=true]),.accordion--surface .accordion__trigger[data-hovered=true]:not([aria-expanded=true]){background-color:var(--default)}}.accordion--surface .accordion__item:after{background-color:var(--surface-foreground)}@supports (color:color-mix(in lab,red,red)){.accordion--surface .accordion__item:after{background-color:color-mix(in oklab,var(--surface-foreground) 6%,transparent)}}.accordion--surface .accordion__item:after{width:94%;left:3%}.accordion--surface .accordion__item:first-child [data-slot=accordion-trigger]{border-top-left-radius:min(32px,var(--radius-3xl));border-top-right-radius:min(32px,var(--radius-3xl))}.accordion--surface .accordion__item:last-child:not(:has([data-slot=accordion-trigger][aria-expanded=true])) [data-slot=accordion-trigger]{border-bottom-left-radius:min(32px,var(--radius-3xl));border-bottom-right-radius:min(32px,var(--radius-3xl))}.breadcrumbs{align-items:center;display:flex}.breadcrumbs .breadcrumbs__link{padding-inline:calc(var(--spacing) * .5);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-leading:calc(var(--spacing) * 5);line-height:calc(var(--spacing) * 5);--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--muted);opacity:1;text-decoration-line:none;position:relative}.breadcrumbs .breadcrumbs__link:hover,.breadcrumbs .breadcrumbs__link[data-hovered=true]{text-decoration-line:underline}.breadcrumbs .breadcrumbs__link[data-current=true]{color:var(--link);opacity:1}.breadcrumbs .breadcrumbs__item{justify-content:center;align-items:center;gap:calc(var(--spacing) * .5);padding-inline:calc(var(--spacing) * .5);flex-shrink:0;display:flex}.breadcrumbs .breadcrumbs__separator{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3);color:var(--muted)}.breadcrumbs .breadcrumbs__separator:where(:dir(rtl),[dir=rtl],[dir=rtl] *){rotate:180deg}.disclosure-group{contain:layout style;width:100%}.disclosure{position:relative}.accordion__heading{display:flex}.disclosure__trigger{cursor:var(--cursor-interactive);-webkit-tap-highlight-color:transparent;display:inline-block}.disclosure__trigger:focus-visible:not(:focus),.disclosure__trigger[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.disclosure__trigger:disabled,.disclosure__trigger[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.disclosure__indicator{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4);color:inherit;transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.25s;flex-shrink:0;margin-left:auto;transition-duration:.25s}.disclosure__indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *),.disclosure__indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.disclosure__indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.disclosure__indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.disclosure__indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.disclosure__indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.disclosure__indicator[data-expanded=true]{rotate:-180deg}.disclosure__content{opacity:0;height:var(--disclosure-panel-height);transition:height .2s var(--ease-out-quad),opacity .2s var(--ease-out);overflow:clip}.disclosure__content:is([data-reduce-motion=true],[data-reduce-motion=true] *),.disclosure__content:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.disclosure__content:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.disclosure__content:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.disclosure__content:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.disclosure__content:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.disclosure__content[data-expanded=true]{will-change:height,opacity;opacity:1}.disclosure__body{padding:calc(var(--spacing) * 2)}.link{border-radius:calc(var(--radius) * 1.5);--tw-font-weight:var(--font-weight-medium);width:fit-content;height:fit-content;font-weight:var(--font-weight-medium);color:var(--link);text-decoration-line:none;-webkit-text-decoration-color:var(--separator-tertiary);text-decoration-color:var(--separator-tertiary);text-underline-offset:4px;-webkit-tap-highlight-color:transparent;transition:color .1s var(--ease-smooth),background-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out),opacity .1s var(--ease-out);align-items:center;text-decoration-thickness:1.5px;display:inline-flex;position:relative}.link:is([data-reduce-motion=true],[data-reduce-motion=true] *),.link:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.link:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.link:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.link:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.link:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.link{cursor:var(--cursor-interactive)}@media(hover:hover){.link:hover,.link[data-hovered=true]{text-decoration-line:underline;-webkit-text-decoration-color:var(--muted);text-decoration-color:var(--muted)}@supports (color:color-mix(in lab,red,red)){.link:hover,.link[data-hovered=true]{-webkit-text-decoration-color:color-mix(in oklab,var(--muted) 50%,transparent);text-decoration-color:color-mix(in oklab,var(--muted) 50%,transparent)}}:is(.link:hover,.link[data-hovered=true]) .link__icon{opacity:1}}.link:active,.link[data-pressed=true]{text-decoration-line:underline;-webkit-text-decoration-color:var(--muted);text-decoration-color:var(--muted)}:is(.link:active,.link[data-pressed=true]) .link__icon{opacity:1}.link:focus-visible:not(:focus),.link[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}:is(.link:focus-visible:not(:focus),.link[data-focus-visible=true]) .link__icon{opacity:1}.link[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.link .link__icon{pointer-events:none;color:currentColor;opacity:.6;width:.75em;height:.75em;transition:opacity .15s var(--ease-out);flex-shrink:0;justify-content:center;align-items:center;display:inline-flex}.link .link__icon:is([data-reduce-motion=true],[data-reduce-motion=true] *),.link .link__icon:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.link .link__icon:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.link .link__icon:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.link .link__icon:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.link .link__icon:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.link .link__icon svg{transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.link .link__icon[data-default-icon=true]{margin-left:var(--spacing);padding-bottom:calc(var(--spacing) * 1.5)}.link.button{gap:0;text-decoration-line:none}.pagination{justify-content:space-between;align-items:center;gap:calc(var(--spacing) * 4);flex-direction:column;width:100%;display:flex}@media(min-width:40rem){.pagination{flex-direction:row}}.pagination__summary{align-items:center;gap:calc(var(--spacing) * 2);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--muted);align-self:flex-start;display:flex}@media(min-width:40rem){.pagination__summary{align-self:center}}.pagination__content{align-items:center;gap:var(--spacing);align-self:flex-start;display:flex}@media(min-width:40rem){.pagination__content{align-self:center}}.pagination__item{display:inline-flex}.pagination__link{isolation:isolate;width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9);transform-origin:50%;border-radius:calc(var(--radius) * 3);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);white-space:nowrap;--tw-outline-style:none;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;outline-style:none;justify-content:center;align-items:center;display:inline-flex;position:relative}@media(min-width:48rem){.pagination__link{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8)}}.pagination__link{cursor:var(--cursor-interactive);transition:transform .25s var(--ease-smooth),background-color .1s var(--ease-out),box-shadow .1s var(--ease-out);transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.pagination__link:is([data-reduce-motion=true],[data-reduce-motion=true] *),.pagination__link:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.pagination__link:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.pagination__link:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.pagination__link:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.pagination__link:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.pagination__link{--pagination-link-bg:transparent;--pagination-link-bg-hover:var(--default-hover);--pagination-link-bg-pressed:var(--default-hover);--pagination-link-fg:var(--default-foreground);background-color:var(--pagination-link-bg);color:var(--pagination-link-fg)}.pagination__link:focus-visible,.pagination__link[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.pagination__link:disabled,.pagination__link[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}@media(hover:hover){.pagination__link:hover,.pagination__link[data-hovered=true]{background-color:var(--pagination-link-bg-hover)}}.pagination__link:active,.pagination__link[data-pressed=true]{background-color:var(--pagination-link-bg-pressed);transform:scale(.97)}.pagination__link[data-active=true]{--pagination-link-bg:var(--default);--pagination-link-bg-hover:var(--default-hover);--pagination-link-bg-pressed:var(--default-hover)}.pagination__ellipsis{width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--muted);-webkit-user-select:none;user-select:none;justify-content:center;align-items:center;display:inline-flex}@media(min-width:48rem){.pagination__ellipsis{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8)}}.pagination__link--nav{gap:calc(var(--spacing) * 1.5);width:auto;padding-inline:calc(var(--spacing) * 2.5)}.pagination--sm .pagination__link{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}@media(min-width:48rem){.pagination--sm .pagination__link{width:calc(var(--spacing) * 7);height:calc(var(--spacing) * 7)}}.pagination--sm .pagination__link:active,.pagination--sm .pagination__link[data-pressed=true]{transform:scale(.98)}.pagination--sm .pagination__link--nav{width:auto;padding-inline:calc(var(--spacing) * 2)}.pagination--sm .pagination__ellipsis{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}@media(min-width:48rem){.pagination--sm .pagination__ellipsis{width:calc(var(--spacing) * 7);height:calc(var(--spacing) * 7)}}.pagination--sm .pagination__summary{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.pagination--lg .pagination__link{width:calc(var(--spacing) * 10);height:calc(var(--spacing) * 10);font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}@media(min-width:48rem){.pagination--lg .pagination__link{width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9)}}.pagination--lg .pagination__link:active,.pagination--lg .pagination__link[data-pressed=true]{transform:scale(.96)}.pagination--lg .pagination__link--nav{width:auto;padding-inline:calc(var(--spacing) * 3)}.pagination--lg .pagination__ellipsis{width:calc(var(--spacing) * 10);height:calc(var(--spacing) * 10);font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}@media(min-width:48rem){.pagination--lg .pagination__ellipsis{width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9)}}.pagination--lg .pagination__summary{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.tabs{gap:calc(var(--spacing) * 2);display:flex}.tabs[data-orientation=horizontal]{flex-direction:column}.tabs[data-orientation=vertical]{flex-direction:row}.tabs__list-container{position:relative}.tabs__list{background-color:var(--default);padding:var(--spacing);border-radius:calc(var(--radius) * 2.5);display:inline-flex}.tabs__list[data-orientation=horizontal]{flex-direction:row;width:100%}.tabs__list[data-orientation=vertical]{gap:var(--spacing);flex-direction:column}.tabs__list[data-orientation=vertical] .tabs__tab{min-width:calc(var(--spacing) * 20)}.tabs__tab{z-index:1;cursor:var(--cursor-interactive);height:calc(var(--spacing) * 8);border-radius:calc(var(--radius) * 3);width:100%;padding-inline:calc(var(--spacing) * 4);text-align:center;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--muted);--tw-outline-style:none;-webkit-tap-highlight-color:transparent;transition:color .15s var(--ease-smooth),background-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out),opacity .15s var(--ease-smooth);outline-style:none;justify-content:center;align-items:center;display:flex;position:relative}.tabs__tab:is([data-reduce-motion=true],[data-reduce-motion=true] *),.tabs__tab:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.tabs__tab:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.tabs__tab:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.tabs__tab:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.tabs__tab:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.tabs__tab[data-selected=true]{color:var(--segment-foreground)}.tabs__tab[data-selected=true] .tabs__separator,.tabs__tab[data-selected=true]+.tabs__tab .tabs__separator{opacity:0}.tabs__tab:disabled,.tabs__tab[data-disabled=true],.tabs__tab[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}@media(hover:hover){.tabs__tab:not([data-selected=true]):not([data-disabled=true]):hover,.tabs__tab[data-hovered=true]:not([data-selected=true]):not([data-disabled=true]){opacity:.7}}.tabs__tab:focus-visible:not(:focus),.tabs__tab[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.tabs__separator{border-radius:calc(var(--radius) * .5);background-color:var(--muted)}@supports (color:color-mix(in lab,red,red)){.tabs__separator{background-color:color-mix(in oklab,var(--muted) 25%,transparent)}}.tabs__separator{pointer-events:none;transition:opacity .15s var(--ease-smooth);position:absolute}.tabs__separator:is([data-reduce-motion=true],[data-reduce-motion=true] *),.tabs__separator:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.tabs__separator:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.tabs__separator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.tabs__separator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.tabs__separator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.tabs__list[data-orientation=horizontal] .tabs__separator{width:1px;height:50%;top:25%;left:0}.tabs__list[data-orientation=vertical] .tabs__separator{width:90%;height:1px;top:0;left:5%}.tabs__panel{width:100%;padding:calc(var(--spacing) * 2);--tw-outline-style:none;outline-style:none}.tabs__panel[data-exiting=true]{width:100%;position:absolute;top:0;left:0}.tabs__panel[data-orientation=horizontal]{margin-top:calc(var(--spacing) * 4)}.tabs__panel[data-orientation=vertical]{margin-left:calc(var(--spacing) * 4)}.tabs__indicator{box-shadow:var(--shadow-surface);z-index:-1;border-radius:var(--radius-3xl);background-color:var(--segment);width:100%;height:100%;transition-property:translate,width,height;transition-duration:.25s;transition-timing-function:var(--ease-out-fluid);position:absolute;top:0;left:0}.tabs__indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *),.tabs__indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.tabs__indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.tabs__indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.tabs__indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.tabs__indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.tabs--secondary>.tabs__list-container>.tabs__list{background-color:#0000;border-radius:0;padding:0}.tabs--secondary>.tabs__list-container>.tabs__list[data-orientation=horizontal]{scrollbar-color:auto;scrollbar-gutter:auto;-ms-overflow-style:none;scrollbar-width:none;border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--border);max-width:100%;overflow:auto clip}.tabs--secondary>.tabs__list-container>.tabs__list[data-orientation=vertical]{border-left-style:var(--tw-border-style);border-left-width:1px;border-color:var(--border)}.tabs--secondary>.tabs__list-container .tabs__tab{border-radius:0}.tabs--secondary>.tabs__list-container .tabs__tab[data-selected=true]{color:var(--foreground)}.tabs--secondary>.tabs__list-container .tabs__separator{display:none}.tabs--secondary>.tabs__list-container .tabs__indicator{background-color:var(--accent);box-shadow:none;border-radius:0}.tabs--secondary[data-orientation=horizontal]>.tabs__list-container .tabs__indicator{height:2px;top:auto;bottom:0}.tabs--secondary[data-orientation=vertical]>.tabs__list-container .tabs__indicator{width:2px;height:100%;top:0;left:0}.button{isolation:isolate;height:calc(var(--spacing) * 10);transform-origin:50%;justify-content:center;align-items:center;gap:calc(var(--spacing) * 2);border-radius:calc(var(--radius) * 3);width:fit-content;padding-inline:calc(var(--spacing) * 4);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);white-space:nowrap;--tw-outline-style:none;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;outline-style:none;display:inline-flex;position:relative}@media(min-width:48rem){.button{height:calc(var(--spacing) * 9)}}.button{transition:transform .25s var(--ease-smooth),background-color .1s var(--ease-out),box-shadow .1s var(--ease-out);transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.button:is([data-reduce-motion=true],[data-reduce-motion=true] *),.button:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.button:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.button{cursor:var(--cursor-interactive);--button-bg:transparent;--button-bg-hover:var(--button-bg);--button-bg-pressed:var(--button-bg-hover);--button-fg:currentColor;background-color:var(--button-bg);color:var(--button-fg)}.button:focus-visible:not(:focus),.button[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.button:disabled,.button[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.button[data-pending=true]{pointer-events:none}.button:active,.button[data-pressed=true]{background-color:var(--button-bg-pressed);transform:scale(.97)}@media(hover:hover){.button:hover,.button[data-hovered=true]{background-color:var(--button-bg-hover)}}.button svg:not([data-slot=spinner] svg,[data-slot=link-icon] svg){pointer-events:none;margin-inline:calc(var(--spacing) * -.5);margin-block:calc(var(--spacing) * .5);width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5);flex-shrink:0;align-self:center}@media(min-width:40rem){.button svg:not([data-slot=spinner] svg,[data-slot=link-icon] svg){margin-block:var(--spacing);width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}}.button--sm{height:calc(var(--spacing) * 9);padding-inline:calc(var(--spacing) * 3)}@media(min-width:48rem){.button--sm{height:calc(var(--spacing) * 8)}}.button--sm svg:not([data-slot=spinner] svg,[data-slot=link-icon] svg){width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.button--sm:active,.button--sm[data-pressed=true]{transform:scale(.98)}.button--lg{height:calc(var(--spacing) * 11);font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}@media(min-width:48rem){.button--lg{height:calc(var(--spacing) * 10)}}.button--lg:active,.button--lg[data-pressed=true]{transform:scale(.96)}.button--primary{--button-bg:var(--accent);--button-bg-hover:var(--accent-hover);--button-bg-pressed:var(--accent-hover);--button-fg:var(--accent-foreground)}.button--secondary{--button-bg:var(--default);--button-bg-hover:var(--default-hover);--button-bg-pressed:var(--default-hover);--button-fg:var(--accent-soft-foreground)}.button--tertiary{--button-bg:var(--default);--button-bg-hover:var(--default-hover);--button-bg-pressed:var(--default-hover)}.button--ghost,.button--outline{--button-bg:transparent;--button-bg-hover:var(--default);--button-bg-pressed:var(--default);--button-fg:var(--default-foreground)}.button--outline{border-style:var(--tw-border-style);border-width:1px;border-color:var(--border);--button-bg-hover:var(--default)}@supports (color:color-mix(in lab,red,red)){.button--outline{--button-bg-hover:color-mix(in srgb, var(--default) 60%, transparent)}}.button--danger{--button-bg:var(--danger);--button-bg-hover:var(--danger-hover);--button-bg-pressed:var(--danger-hover);--button-fg:var(--danger-foreground)}.button--danger-soft{--button-bg:var(--danger-soft);--button-bg-hover:var(--danger-soft-hover);--button-bg-pressed:var(--danger-soft-hover);--button-fg:var(--danger-soft-foreground)}.button--icon-only{width:calc(var(--spacing) * 10);padding:0}@media(min-width:48rem){.button--icon-only{width:calc(var(--spacing) * 9)}}.button--icon-only.button--sm{width:calc(var(--spacing) * 9)}@media(min-width:48rem){.button--icon-only.button--sm{width:calc(var(--spacing) * 8)}}.button--icon-only.button--lg{width:calc(var(--spacing) * 11)}@media(min-width:48rem){.button--icon-only.button--lg{width:calc(var(--spacing) * 10)}}.button--full-width{width:100%}.button-group{justify-content:center;align-items:center;gap:0;height:auto;display:inline-flex}.button-group--horizontal{flex-direction:row}.button-group--vertical{flex-direction:column}.button-group .button{border-radius:0}.button-group--horizontal .button:first-child{border-start-start-radius:calc(var(--radius) * 3);border-end-start-radius:calc(var(--radius) * 3)}.button-group--horizontal .button:last-child{border-start-end-radius:calc(var(--radius) * 3);border-end-end-radius:calc(var(--radius) * 3)}.button-group--horizontal .button:first-child:last-child{border-radius:calc(var(--radius) * 3)}.button-group--vertical .button:first-child{border-top-left-radius:calc(var(--radius) * 3);border-top-right-radius:calc(var(--radius) * 3)}.button-group--vertical .button:last-child{border-bottom-right-radius:calc(var(--radius) * 3);border-bottom-left-radius:calc(var(--radius) * 3)}.button-group--vertical .button:first-child:last-child{border-radius:calc(var(--radius) * 3)}.button-group .button:active,.button-group .button[data-pressed=true]{transform:none}.button-group .button:focus-visible:not(:focus),.button-group .button[data-focus-visible=true]{--tw-ring-offset-width:0px;--tw-ring-inset:inset}.button-group__separator{border-radius:calc(var(--radius) * .5);opacity:.15;pointer-events:none;transition:opacity .15s var(--ease-smooth);background-color:currentColor;position:absolute}.button-group__separator:is([data-reduce-motion=true],[data-reduce-motion=true] *),.button-group__separator:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.button-group__separator:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.button-group__separator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.button-group__separator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.button-group__separator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.button-group--horizontal .button-group__separator{width:1px;height:50%;top:25%;left:-1px}.button-group--vertical .button-group__separator{width:50%;height:1px;top:-1px;left:25%}.button-group--horizontal .button--outline:first-child{border-inline-end-style:var(--tw-border-style);border-inline-end-width:0}.button-group--horizontal .button--outline:last-child{border-inline-start-style:var(--tw-border-style);border-inline-start-width:0}.button-group--horizontal .button--outline:not(:first-child):not(:last-child){border-inline-style:var(--tw-border-style);border-inline-width:0}.button-group--vertical .button--outline:first-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}.button-group--vertical .button--outline:last-child{border-top-style:var(--tw-border-style);border-top-width:0}.button-group--vertical .button--outline:not(:first-child):not(:last-child){border-block-style:var(--tw-border-style);border-block-width:0}.button-group--full-width{width:100%}.toggle-button{isolation:isolate;height:calc(var(--spacing) * 10);transform-origin:50%;justify-content:center;align-items:center;gap:calc(var(--spacing) * 2);border-radius:calc(var(--radius) * 3);width:fit-content;padding-inline:calc(var(--spacing) * 4);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);white-space:nowrap;--tw-outline-style:none;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;outline-style:none;display:inline-flex;position:relative}@media(min-width:48rem){.toggle-button{height:calc(var(--spacing) * 9)}}.toggle-button{transition:transform .25s var(--ease-smooth),background-color .1s var(--ease-out),box-shadow .1s var(--ease-out);transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.toggle-button:is([data-reduce-motion=true],[data-reduce-motion=true] *),.toggle-button:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.toggle-button:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.toggle-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.toggle-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.toggle-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.toggle-button{cursor:var(--cursor-interactive);--toggle-button-bg:var(--default);--toggle-button-bg-hover:var(--default-hover);--toggle-button-bg-pressed:var(--default-hover);--toggle-button-fg:currentColor;--toggle-button-bg-selected:var(--accent-soft);--toggle-button-bg-selected-hover:var(--accent-soft-hover);--toggle-button-bg-selected-pressed:var(--accent-soft-hover);--toggle-button-fg-selected:var(--accent-soft-foreground);background-color:var(--toggle-button-bg);color:var(--toggle-button-fg)}.toggle-button:focus-visible:not(:focus),.toggle-button[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.toggle-button:disabled,.toggle-button[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}@media(hover:hover){.toggle-button:hover,.toggle-button[data-hovered=true]{background-color:var(--toggle-button-bg-hover)}}.toggle-button:active,.toggle-button[data-pressed=true]{background-color:var(--toggle-button-bg-pressed);transform:scale(.97)}.toggle-button[data-selected=true]{background-color:var(--toggle-button-bg-selected);color:var(--toggle-button-fg-selected)}@media(hover:hover){.toggle-button[data-selected=true]:hover,.toggle-button[data-selected=true][data-hovered=true]{background-color:var(--toggle-button-bg-selected-hover)}}.toggle-button[data-selected=true]:active,.toggle-button[data-selected=true][data-pressed=true]{background-color:var(--toggle-button-bg-selected-pressed)}.toggle-button svg{pointer-events:none;margin-inline:calc(var(--spacing) * -.5);margin-block:calc(var(--spacing) * .5);width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5);flex-shrink:0;align-self:center}@media(min-width:40rem){.toggle-button svg{margin-block:var(--spacing);width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}}.toggle-button--sm{height:calc(var(--spacing) * 9);padding-inline:calc(var(--spacing) * 3)}@media(min-width:48rem){.toggle-button--sm{height:calc(var(--spacing) * 8)}}.toggle-button--sm svg{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.toggle-button--sm:active,.toggle-button--sm[data-pressed=true]{transform:scale(.98)}.toggle-button--lg{height:calc(var(--spacing) * 11);font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}@media(min-width:48rem){.toggle-button--lg{height:calc(var(--spacing) * 10)}}.toggle-button--lg:active,.toggle-button--lg[data-pressed=true]{transform:scale(.96)}.toggle-button--default{--toggle-button-bg:var(--default);--toggle-button-bg-hover:var(--default-hover);--toggle-button-bg-pressed:var(--default-hover)}.toggle-button--ghost{--toggle-button-bg:transparent;--toggle-button-bg-hover:var(--default);--toggle-button-bg-pressed:var(--default);--toggle-button-fg:var(--default-foreground)}.toggle-button--icon-only{width:calc(var(--spacing) * 10);padding:0}@media(min-width:48rem){.toggle-button--icon-only{width:calc(var(--spacing) * 9)}}.toggle-button--icon-only.toggle-button--sm{width:calc(var(--spacing) * 9)}@media(min-width:48rem){.toggle-button--icon-only.toggle-button--sm{width:calc(var(--spacing) * 8)}}.toggle-button--icon-only.toggle-button--lg{width:calc(var(--spacing) * 11)}@media(min-width:48rem){.toggle-button--icon-only.toggle-button--lg{width:calc(var(--spacing) * 10)}}.toggle-button-group{justify-content:center;align-items:center;gap:0;width:fit-content;height:auto;display:inline-flex}.toggle-button-group--horizontal{flex-direction:row}.toggle-button-group--vertical{flex-direction:column}.toggle-button-group--full-width{width:100%}.toggle-button-group .toggle-button{border-radius:0}.toggle-button-group--horizontal .toggle-button:first-child{border-start-start-radius:calc(var(--radius) * 3);border-end-start-radius:calc(var(--radius) * 3)}.toggle-button-group--horizontal .toggle-button:last-child{border-start-end-radius:calc(var(--radius) * 3);border-end-end-radius:calc(var(--radius) * 3)}.toggle-button-group--horizontal .toggle-button:first-child:last-child{border-radius:calc(var(--radius) * 3)}.toggle-button-group--vertical .toggle-button:first-child{border-top-left-radius:calc(var(--radius) * 3);border-top-right-radius:calc(var(--radius) * 3)}.toggle-button-group--vertical .toggle-button:last-child{border-bottom-right-radius:calc(var(--radius) * 3);border-bottom-left-radius:calc(var(--radius) * 3)}.toggle-button-group--vertical .toggle-button:first-child:last-child{border-radius:calc(var(--radius) * 3)}.toggle-button-group .toggle-button:active,.toggle-button-group .toggle-button[data-pressed=true]{transform:none}.toggle-button-group .toggle-button:focus-visible:not(:focus),.toggle-button-group .toggle-button[data-focus-visible=true]{--tw-ring-offset-width:0px;--tw-ring-inset:inset}.toggle-button-group--full-width .toggle-button{flex:1}.toggle-button-group__separator{border-radius:calc(var(--radius) * .5);opacity:.15;pointer-events:none;transition:opacity .15s var(--ease-smooth);background-color:currentColor;position:absolute}.toggle-button-group__separator:is([data-reduce-motion=true],[data-reduce-motion=true] *),.toggle-button-group__separator:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.toggle-button-group__separator:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.toggle-button-group__separator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.toggle-button-group__separator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.toggle-button-group__separator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.toggle-button-group--horizontal .toggle-button-group__separator{width:1px;height:50%;top:25%;left:-1px}.toggle-button-group--vertical .toggle-button-group__separator{width:50%;height:1px;top:-1px;left:25%}.toggle-button-group--detached{gap:var(--spacing)}.toggle-button-group--detached .toggle-button{border-radius:calc(var(--radius) * 3)}.toggle-button-group--detached .toggle-button-group__separator{display:none}.toolbar{align-items:center;gap:calc(var(--spacing) * 2);grid-auto-flow:column;width:fit-content;display:grid}.toolbar .separator--vertical{align-self:center;height:50%}.toolbar .separator--horizontal{justify-content:center;justify-self:center;width:50%}.toolbar--vertical{grid-auto-flow:row;justify-content:flex-start;align-items:flex-start}.toolbar--vertical .button-group{justify-content:flex-start}.toolbar--attached{border-radius:calc(var(--radius) * 3);background-color:var(--surface);padding:var(--spacing);--tw-shadow:var(--overlay-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.dropdown{gap:var(--spacing);flex-direction:column;display:flex}.dropdown__trigger{--tw-outline-style:none;transition:transform .25s var(--ease-out-quart),background-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out);transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);outline-style:none;display:inline-block}.dropdown__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *),.dropdown__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.dropdown__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.dropdown__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.dropdown__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.dropdown__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.dropdown__trigger{cursor:var(--cursor-interactive)}.dropdown__trigger:focus-visible:not(:focus),.dropdown__trigger[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.dropdown__trigger:disabled,.dropdown__trigger[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.dropdown__trigger[data-pending=true]{pointer-events:none}.dropdown__trigger:active,.dropdown__trigger[data-pressed=true]{transform:scale(.97)}.dropdown__popover{max-width:48svw;transform-origin:var(--trigger-anchor-point);scroll-padding-block:var(--spacing);scrollbar-width:var(--scrollbar-width);scrollbar-color:var(--scrollbar-color);scrollbar-gutter:var(--scrollbar-gutter);overscroll-behavior:contain;background-color:var(--overlay);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));padding:0;overflow-y:auto}@media(min-width:48rem){.dropdown__popover{min-width:calc(var(--spacing) * 55)}}.dropdown__popover{border-radius:min(32px,var(--radius-3xl));box-shadow:var(--shadow-overlay)}.dropdown__popover:focus-visible:not(:focus),.dropdown__popover[data-focus-visible=true]{--tw-outline-style:none;outline-style:none}.dropdown__popover[data-entering=true]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.15s;--tw-ease:ease;--tw-enter-opacity:0;--tw-enter-scale:.9;transition-duration:.15s;transition-timing-function:ease}.dropdown__popover[data-entering=true][data-placement=top]{--tw-enter-translate-y:calc(1*var(--spacing))}.dropdown__popover[data-entering=true][data-placement=bottom]{--tw-enter-translate-y:calc(1*var(--spacing)*-1)}.dropdown__popover[data-entering=true][data-placement=left]{--tw-enter-translate-x:calc(1*var(--spacing))}.dropdown__popover[data-entering=true][data-placement=right]{--tw-enter-translate-x:calc(1*var(--spacing)*-1)}.dropdown__popover[data-exiting=true]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.1s;--tw-ease:ease;--tw-exit-scale:.95;--tw-exit-opacity:0;transition-duration:.1s;transition-timing-function:ease}.dropdown__popover[data-exiting=true],.dropdown__popover[data-entering=true]{transition-property:opacity,transform;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));will-change:opacity,transform}.dropdown__popover [data-slot=popover-overlay-arrow]{fill:var(--overlay)}.dropdown__popover[data-placement=bottom] [data-slot=popover-overlay-arrow]{rotate:180deg}.dropdown__popover[data-placement=left] [data-slot=popover-overlay-arrow]{rotate:-90deg}.dropdown__popover[data-placement=right] [data-slot=popover-overlay-arrow]{rotate:90deg}.dropdown__popover [data-slot=dropdown-menu]{padding:calc(var(--spacing) * 1.5);--tw-outline-style:none;outline-style:none}.dropdown__popover [data-slot=menu-item]{padding-inline:calc(var(--spacing) * 2.5)}.dropdown__menu{gap:calc(var(--spacing) * .5);width:100%;padding:var(--spacing);flex-direction:column;display:flex;position:relative;overflow:clip}.dropdown__menu [data-slot=separator]{width:94%;margin-left:3%}.list-box-item{min-height:calc(var(--spacing) * 9);justify-content:flex-start;align-items:center;gap:calc(var(--spacing) * 3);border-radius:calc(var(--radius) * 2);width:100%;padding-inline:calc(var(--spacing) * 2);padding-block:calc(var(--spacing) * 1.5);--tw-outline-style:none;-webkit-tap-highlight-color:transparent;transition:transform .25s var(--ease-out-quart),box-shadow .15s var(--ease-out);outline-style:none;display:flex;position:relative}.list-box-item:is([data-reduce-motion=true],[data-reduce-motion=true] *),.list-box-item:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.list-box-item:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.list-box-item:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.list-box-item:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.list-box-item:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.list-box-item{cursor:var(--cursor-interactive)}.list-box-item [data-slot=label]{pointer-events:none;-webkit-user-select:none;user-select:none;width:fit-content}.list-box-item [data-slot=description]{pointer-events:none;text-wrap:wrap;-webkit-user-select:none;user-select:none}.list-box-item:has(.list-box-item__indicator){padding-inline-end:calc(var(--spacing) * 7)}.list-box-item:focus-visible:not(:focus),.list-box-item[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.list-box-item:active,.list-box-item[data-pressed=true]{transform:scale(.98)}@media(hover:hover){.list-box-item:hover,.list-box-item[data-hovered=true]{background-color:var(--default)}}.list-box-item[data-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.list-box-item__indicator{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4);--tw-translate-y: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y);color:var(--default-foreground);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.25s;inset-inline-end:calc(var(--spacing) * 2);flex-shrink:0;justify-content:center;align-items:center;transition-duration:.25s;display:flex;position:absolute;top:50%}.list-box-item__indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *),.list-box-item__indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.list-box-item__indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.list-box-item__indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.list-box-item__indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.list-box-item__indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.list-box-item__indicator [data-slot=list-box-item-indicator--checkmark]{width:calc(var(--spacing) * 2.5);height:calc(var(--spacing) * 2.5);transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.3s;transition-duration:.3s}.list-box-item__indicator [data-slot=list-box-item-indicator--checkmark]:is([data-reduce-motion=true],[data-reduce-motion=true] *),.list-box-item__indicator [data-slot=list-box-item-indicator--checkmark]:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.list-box-item__indicator [data-slot=list-box-item-indicator--checkmark]:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.list-box-item__indicator [data-slot=list-box-item-indicator--checkmark]:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.list-box-item__indicator [data-slot=list-box-item-indicator--checkmark]:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.list-box-item__indicator [data-slot=list-box-item-indicator--checkmark]:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.list-box-item__indicator .list-box-item[aria-selected=true] [data-slot=list-box-item-indicator--checkmark],.list-box-item__indicator .list-box-item[data-selected=true] [data-slot=list-box-item-indicator--checkmark]{transition:stroke-dashoffset .25s linear}:is(.list-box-item__indicator .list-box-item[aria-selected=true] [data-slot=list-box-item-indicator--checkmark],.list-box-item__indicator .list-box-item[data-selected=true] [data-slot=list-box-item-indicator--checkmark]):is([data-reduce-motion=true],[data-reduce-motion=true] *),:is(.list-box-item__indicator .list-box-item[aria-selected=true] [data-slot=list-box-item-indicator--checkmark],.list-box-item__indicator .list-box-item[data-selected=true] [data-slot=list-box-item-indicator--checkmark]):is([data-reduce-motion=true],[data-reduce-motion=true] *):before,:is(.list-box-item__indicator .list-box-item[aria-selected=true] [data-slot=list-box-item-indicator--checkmark],.list-box-item__indicator .list-box-item[data-selected=true] [data-slot=list-box-item-indicator--checkmark]):is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){:is(.list-box-item__indicator .list-box-item[aria-selected=true] [data-slot=list-box-item-indicator--checkmark],.list-box-item__indicator .list-box-item[data-selected=true] [data-slot=list-box-item-indicator--checkmark]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),:is(.list-box-item__indicator .list-box-item[aria-selected=true] [data-slot=list-box-item-indicator--checkmark],.list-box-item__indicator .list-box-item[data-selected=true] [data-slot=list-box-item-indicator--checkmark]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,:is(.list-box-item__indicator .list-box-item[aria-selected=true] [data-slot=list-box-item-indicator--checkmark],.list-box-item__indicator .list-box-item[data-selected=true] [data-slot=list-box-item-indicator--checkmark]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.list-box-item--danger .list-box-item__indicator,.list-box-item--danger [data-slot=label]{color:var(--danger)}.list-box-section{flex-direction:column;align-items:flex-start;gap:0;display:flex}.list-box{width:100%;padding:var(--spacing);position:relative;overflow:clip}.list-box>*+*{margin-top:var(--spacing)}.list-box [data-slot=separator][data-orientation=horizontal]{width:94%;margin-left:3%}.menu-item{min-height:calc(var(--spacing) * 9);justify-content:flex-start;align-items:center;gap:calc(var(--spacing) * 3);border-radius:calc(var(--radius) * 2);width:100%;padding-inline:calc(var(--spacing) * 2);padding-block:calc(var(--spacing) * 1.5);--tw-outline-style:none;-webkit-tap-highlight-color:transparent;transition:transform .25s var(--ease-out-quart),box-shadow .15s var(--ease-out);outline-style:none;display:flex;position:relative}.menu-item:is([data-reduce-motion=true],[data-reduce-motion=true] *),.menu-item:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.menu-item:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.menu-item:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.menu-item:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.menu-item:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.menu-item{cursor:var(--cursor-interactive)}.menu-item [data-slot=label]{pointer-events:none;-webkit-user-select:none;user-select:none;width:fit-content}.menu-item [data-slot=description]{pointer-events:none;text-wrap:wrap;-webkit-user-select:none;user-select:none}.menu-item [data-slot=submenu-indicator] svg{width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5)}.menu-item:has(.menu-item__indicator){padding-inline-start:calc(var(--spacing) * 7)}.menu-item[data-has-submenu=true]:has(.menu-item__indicator){padding-inline-start:calc(var(--spacing) * 2);padding-inline-end:calc(var(--spacing) * 7)}.menu-item:focus-visible:not(:focus),.menu-item[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.menu-item:active,.menu-item[data-pressed=true]{transform:scale(.98)}@media(hover:hover){.menu-item:hover,.menu-item[data-hovered=true]{background-color:var(--default)}}:is(.menu-item[aria-checked=true],.menu-item[aria-selected=true],.menu-item[data-selected=true]) [data-slot=menu-item-indicator--checkmark]{transition:stroke-dashoffset .1s linear}:is(.menu-item[aria-checked=true],.menu-item[aria-selected=true],.menu-item[data-selected=true]) [data-slot=menu-item-indicator--checkmark]:is([data-reduce-motion=true],[data-reduce-motion=true] *),:is(.menu-item[aria-checked=true],.menu-item[aria-selected=true],.menu-item[data-selected=true]) [data-slot=menu-item-indicator--checkmark]:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,:is(.menu-item[aria-checked=true],.menu-item[aria-selected=true],.menu-item[data-selected=true]) [data-slot=menu-item-indicator--checkmark]:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){:is(.menu-item[aria-checked=true],.menu-item[aria-selected=true],.menu-item[data-selected=true]) [data-slot=menu-item-indicator--checkmark]:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),:is(.menu-item[aria-checked=true],.menu-item[aria-selected=true],.menu-item[data-selected=true]) [data-slot=menu-item-indicator--checkmark]:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,:is(.menu-item[aria-checked=true],.menu-item[aria-selected=true],.menu-item[data-selected=true]) [data-slot=menu-item-indicator--checkmark]:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}:is(.menu-item[aria-checked=true],.menu-item[aria-selected=true],.menu-item[data-selected=true]) [data-slot=menu-item-indicator--dot]{--tw-scale-x:100%;--tw-scale-y:100%;--tw-scale-z:100%;scale:var(--tw-scale-x) var(--tw-scale-y);opacity:1}.menu-item[data-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.menu-item__indicator{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4);--tw-translate-y: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y);color:var(--muted);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.25s;inset-inline-start:calc(var(--spacing) * 2);flex-shrink:0;justify-content:center;align-items:center;transition-duration:.25s;display:flex;position:absolute;top:50%}.menu-item__indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *),.menu-item__indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.menu-item__indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.menu-item__indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.menu-item__indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.menu-item__indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.menu-item[data-has-submenu=true] .menu-item__indicator{inset-inline-start:auto;inset-inline-end:calc(var(--spacing) * 2)}.menu-item__indicator [data-slot=menu-item-indicator--checkmark]{width:calc(var(--spacing) * 2.5);height:calc(var(--spacing) * 2.5)}.menu-item[data-selection-mode=multiple] :is(.menu-item__indicator [data-slot=menu-item-indicator--checkmark]){transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.3s;transition-duration:.3s}.menu-item[data-selection-mode=multiple] :is(.menu-item__indicator [data-slot=menu-item-indicator--checkmark]):is([data-reduce-motion=true],[data-reduce-motion=true] *),.menu-item[data-selection-mode=multiple] :is(.menu-item__indicator [data-slot=menu-item-indicator--checkmark]):is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.menu-item[data-selection-mode=multiple] :is(.menu-item__indicator [data-slot=menu-item-indicator--checkmark]):is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.menu-item[data-selection-mode=multiple] :is(.menu-item__indicator [data-slot=menu-item-indicator--checkmark]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.menu-item[data-selection-mode=multiple] :is(.menu-item__indicator [data-slot=menu-item-indicator--checkmark]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.menu-item[data-selection-mode=multiple] :is(.menu-item__indicator [data-slot=menu-item-indicator--checkmark]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.menu-item__indicator [data-slot=menu-item-indicator--dot]{width:calc(var(--spacing) * 2);height:calc(var(--spacing) * 2)}.menu-item[data-selection-mode=multiple] :is(.menu-item__indicator [data-slot=menu-item-indicator--dot]){transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.25s;transition-duration:.25s}.menu-item[data-selection-mode=multiple] :is(.menu-item__indicator [data-slot=menu-item-indicator--dot]):is([data-reduce-motion=true],[data-reduce-motion=true] *),.menu-item[data-selection-mode=multiple] :is(.menu-item__indicator [data-slot=menu-item-indicator--dot]):is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.menu-item[data-selection-mode=multiple] :is(.menu-item__indicator [data-slot=menu-item-indicator--dot]):is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.menu-item[data-selection-mode=multiple] :is(.menu-item__indicator [data-slot=menu-item-indicator--dot]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.menu-item[data-selection-mode=multiple] :is(.menu-item__indicator [data-slot=menu-item-indicator--dot]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.menu-item[data-selection-mode=multiple] :is(.menu-item__indicator [data-slot=menu-item-indicator--dot]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.menu-item__indicator [data-slot=menu-item-indicator--dot]{--tw-scale-x:70%;--tw-scale-y:70%;--tw-scale-z:70%;scale:var(--tw-scale-x) var(--tw-scale-y);opacity:0}.menu-item__indicator--submenu{color:var(--muted)}.menu-item__indicator--submenu svg{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.menu-item--danger .menu-item__indicator,.menu-item--danger [data-slot=label]{color:var(--danger)}.menu-section{flex-direction:column;align-items:flex-start;gap:0;display:flex}.menu{gap:var(--spacing);width:100%;padding:var(--spacing);flex-direction:column;display:flex;position:relative;overflow:clip}.menu [data-slot=separator]{width:94%;margin-left:3%}.tag-group{gap:var(--spacing);flex-direction:column;display:flex;position:relative}.tag-group__list{gap:calc(var(--spacing) * 1.5);flex-wrap:wrap;display:flex;position:relative}.tag-group [slot=description],.tag-group [data-slot=description],.tag-group [slot=errorMessage],.tag-group [data-slot=error-message]{padding:var(--spacing)}.tag{--optical-offset:.031em;align-items:center;gap:var(--spacing);border-radius:calc(var(--radius) * 1.5);--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;transition:color .1s var(--ease-smooth),scale .1s var(--ease-smooth),opacity .1s var(--ease-smooth),background-color .1s var(--ease-smooth),box-shadow .1s var(--ease-out);transform-origin:50%;transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);display:inline-flex;position:relative}.tag:is([data-reduce-motion=true],[data-reduce-motion=true] *),.tag:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.tag:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.tag:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.tag:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.tag:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.tag{cursor:var(--cursor-interactive)}.tag svg{pointer-events:none;width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3);color:currentColor;flex-shrink:0;align-self:center}.tag:is([data-disabled=true],[aria-disabled=true]){opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.tag:is(:focus-visible,[data-focus-visible]){--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.tag:is([data-selected=true],[aria-selected=true]){background-color:var(--accent-soft);color:var(--accent-soft-foreground)}@media(hover:hover){.tag:is([data-selected=true],[aria-selected=true]):is(:hover,[data-hovered=true]){background-color:var(--accent-soft-hover)}}.tag--sm{padding-inline:calc(var(--spacing) * 2);padding-block:calc(var(--spacing) * .5);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.tag--md{padding-inline:calc(var(--spacing) * 2);padding-block:var(--spacing);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.tag--lg{border-radius:calc(var(--radius) * 2);padding-inline:calc(var(--spacing) * 2.5);padding-block:calc(var(--spacing) * 1.5);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.tag--default{background-color:var(--default);color:var(--default-foreground)}@media(hover:hover){.tag--default:is(:hover,[data-hovered=true]):not([data-selected=true]):not([data-disabled=true]){background-color:var(--default-hover)}}.tag--surface{background-color:var(--surface);color:var(--surface-foreground)}@media(hover:hover){.tag--surface:is(:hover,[data-hovered=true]):not([data-selected=true]):not([data-disabled=true]){background-color:var(--surface-hover)}}.tag__remove-button{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3);color:inherit}.tag__remove-button svg{width:inherit;height:inherit;color:currentColor;flex-shrink:0;align-self:center}.color-area{width:100%;max-width:calc(var(--spacing) * 56);border-radius:calc(var(--radius) * 2);-webkit-tap-highlight-color:transparent;aspect-ratio:1;background:var(--color-area-background);flex-shrink:0;position:relative;box-shadow:inset 0 0 0 1px #0000001a}.color-area[data-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.color-area--show-dots:after{content:"";pointer-events:none;border-radius:inherit;background-image:radial-gradient(circle,#fff3 1px,#0000 1px);background-size:8px 8px;position:absolute;top:0;right:0;bottom:0;left:0}.color-area__thumb{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4);border-radius:calc(var(--radius) * 1.5);will-change:width,height;background-color:var(--color-area-thumb-color);transition:width .15s var(--ease-out),height .15s var(--ease-out);border:3px solid #fff;box-shadow:0 0 0 1px #0000001a,inset 0 0 0 1px #0000001a}.color-area__thumb:is([data-reduce-motion=true],[data-reduce-motion=true] *),.color-area__thumb:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.color-area__thumb:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.color-area__thumb:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.color-area__thumb:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.color-area__thumb:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.color-area__thumb[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.color-area__thumb[data-dragging=true]{width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5)}.color-area__thumb[data-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.color-picker{display:inline-flex}.color-picker__trigger{align-items:center;gap:calc(var(--spacing) * 3);border-radius:calc(var(--radius) * .5);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));-webkit-tap-highlight-color:transparent;cursor:var(--cursor-interactive);transition:background-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out);display:inline-flex}.color-picker__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *),.color-picker__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.color-picker__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.color-picker__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.color-picker__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.color-picker__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.color-picker__trigger [data-slot=label]{cursor:var(--cursor-interactive)}.color-picker__trigger:focus-visible:not(:focus),.color-picker__trigger[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.color-picker__trigger:disabled,.color-picker__trigger[data-disabled=true],.color-picker__trigger[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.color-picker__popover{min-width:calc(var(--spacing) * 62);transform-origin:var(--trigger-anchor-point);scrollbar-color:auto;scrollbar-gutter:auto;-ms-overflow-style:none;scrollbar-width:none;overscroll-behavior:contain;background-color:var(--overlay);padding-inline:calc(var(--spacing) * 2);padding-top:calc(var(--spacing) * 2);padding-bottom:calc(var(--spacing) * 3);box-shadow:var(--shadow-overlay);border-radius:min(32px,calc(var(--radius) * 2.5));gap:calc(var(--spacing) * 3);flex-direction:column;display:flex;overflow:hidden auto}.color-picker__popover:focus-visible:not(:focus),.color-picker__popover[data-focus-visible=true]{--tw-outline-style:none;outline-style:none}.color-picker__popover[data-entering=true]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.15s;--tw-ease:ease;--tw-enter-opacity:0;--tw-enter-scale:.95;transition-duration:.15s;transition-timing-function:ease}.color-picker__popover[data-entering=true][data-placement^=top]{--tw-enter-translate-y:calc(1*var(--spacing))}.color-picker__popover[data-entering=true][data-placement^=bottom]{--tw-enter-translate-y:calc(1*var(--spacing)*-1)}.color-picker__popover[data-entering=true][data-placement^=left]{--tw-enter-translate-x:calc(1*var(--spacing))}.color-picker__popover[data-entering=true][data-placement^=right]{--tw-enter-translate-x:calc(1*var(--spacing)*-1)}.color-picker__popover[data-exiting=true]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.1s;--tw-ease:ease;--tw-exit-scale:.95;--tw-exit-opacity:0;transition-duration:.1s;transition-timing-function:ease}.color-picker__popover[data-exiting=true],.color-picker__popover[data-entering=true]{transition-property:opacity,transform;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));will-change:opacity,transform}.color-slider{gap:var(--spacing);grid-template:"label output""track track"/1fr auto;width:100%;display:grid}.color-slider:not(:has([data-slot=label])):not(:has(.color-slider__output)){grid-template:"track"/1fr;gap:0}.color-slider:has([data-slot=label]):not(:has(.color-slider__output)){grid-template-columns:1fr;grid-template-areas:"label""track"}.color-slider:not(:has([data-slot=label])):has(.color-slider__output){grid-template-columns:1fr;grid-template-areas:"output""track"}.color-slider:not(:has([data-slot=label])):has(.color-slider__output) .color-slider__output{justify-self:end}.color-slider [data-slot=label]{width:fit-content;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);grid-area:label}.color-slider .color-slider__output{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,);grid-area:output}.color-slider .color-slider__track{border-radius:calc(var(--radius) * 2);grid-area:track;position:relative}.color-slider .color-slider__track:before,.color-slider .color-slider__track:after{content:"";z-index:0;pointer-events:none;position:absolute}.color-slider .color-slider__thumb{cursor:grab;border-radius:calc(var(--radius) * 2);-webkit-tap-highlight-color:transparent;border-style:var(--tw-border-style);border-width:3px;border-color:var(--color-white);--tw-shadow:var(--overlay-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);z-index:1;transition:transform .25s var(--ease-out),box-shadow .15s var(--ease-out);justify-content:center;align-items:center;display:flex;position:absolute}.color-slider .color-slider__thumb:is([data-reduce-motion=true],[data-reduce-motion=true] *),.color-slider .color-slider__thumb:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.color-slider .color-slider__thumb:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.color-slider .color-slider__thumb:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.color-slider .color-slider__thumb:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.color-slider .color-slider__thumb:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.color-slider .color-slider__thumb[data-dragging=true]{cursor:grabbing}.color-slider .color-slider__thumb[data-focus-visible=true]{z-index:10;--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.color-slider .color-slider__thumb[data-disabled=true]{cursor:default;background-color:var(--default)}.color-slider:disabled,.color-slider[data-disabled=true],.color-slider[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}:is(.color-slider:disabled,.color-slider[data-disabled=true],.color-slider[aria-disabled=true]) [data-slot=label]{opacity:1}.color-slider[data-orientation=horizontal]{flex-direction:column}.color-slider[data-orientation=horizontal] .color-slider__track{height:calc(var(--spacing) * 5);border-radius:0;justify-self:center;width:calc(100% - 1.25rem);box-shadow:inset 0 1px #0000001a,inset 0 -1px #0000001a}.color-slider[data-orientation=horizontal] .color-slider__track:before,.color-slider[data-orientation=horizontal] .color-slider__track:after{width:.625rem;height:100%;top:0}.color-slider[data-orientation=horizontal] .color-slider__track:before{border-top-left-radius:calc(var(--radius) * 2);border-bottom-left-radius:calc(var(--radius) * 2);background:linear-gradient(var(--track-start-color,transparent)),repeating-conic-gradient(#efefef,#efefef 25%,#f7f7f7 0%,#f7f7f7 50%) 50% / 16px 16px;left:-.625rem;box-shadow:inset 1px 0 #0000001a,inset 0 1px #0000001a,inset 0 -1px #0000001a}.color-slider[data-orientation=horizontal] .color-slider__track:after{border-top-right-radius:calc(var(--radius) * 2);border-bottom-right-radius:calc(var(--radius) * 2);background-color:var(--track-end-color,transparent);right:-.625rem;box-shadow:inset -1px 0 #0000001a,inset 0 1px #0000001a,inset 0 -1px #0000001a}.color-slider[data-orientation=horizontal] .color-slider__thumb{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4);top:50%}.color-slider[data-orientation=vertical]{gap:calc(var(--spacing) * 2);flex-direction:row;grid-template:"output""track"1fr"label"/1fr;place-items:center;height:100%}.color-slider[data-orientation=vertical]:not(:has([data-slot=label])):not(:has(.color-slider__output)){grid-template-rows:1fr;grid-template-areas:"track";gap:0}.color-slider[data-orientation=vertical]:has([data-slot=label]):not(:has(.color-slider__output)){grid-template-rows:1fr auto;grid-template-areas:"track""label"}.color-slider[data-orientation=vertical]:not(:has([data-slot=label])):has(.color-slider__output){grid-template-rows:auto 1fr;grid-template-areas:"output""track"}.color-slider[data-orientation=vertical] .color-slider__output,.color-slider[data-orientation=vertical] [data-slot=label]{text-align:center}.color-slider[data-orientation=vertical] .color-slider__track{width:calc(var(--spacing) * 5);border-radius:0;justify-self:center;height:calc(100% - 1.25rem);box-shadow:inset 1px 0 #0000001a,inset -1px 0 #0000001a}.color-slider[data-orientation=vertical] .color-slider__track:before,.color-slider[data-orientation=vertical] .color-slider__track:after{width:100%;height:.625rem;left:0}.color-slider[data-orientation=vertical] .color-slider__track:before{background:linear-gradient(var(--track-start-color,transparent)),repeating-conic-gradient(#efefef,#efefef 25%,#f7f7f7 0%,#f7f7f7 50%) 50% / 16px 16px;border-bottom-right-radius:999px;border-bottom-left-radius:999px;bottom:-.625rem;box-shadow:inset 1px 0 #0000001a,inset -1px 0 #0000001a,inset 0 -1px #0000001a}.color-slider[data-orientation=vertical] .color-slider__track:after{background-color:var(--track-end-color,transparent);border-top-left-radius:999px;border-top-right-radius:999px;top:-.625rem;box-shadow:inset 1px 0 #0000001a,inset -1px 0 #0000001a,inset 0 1px #0000001a}.color-slider[data-orientation=vertical] .color-slider__thumb{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4);left:50%}.color-swatch{box-sizing:border-box;width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8);background:linear-gradient(var(--color-swatch-current),var(--color-swatch-current)),repeating-conic-gradient(#efefef,#efefef 25%,#f7f7f7 0%,#f7f7f7 50%) 50% / 16px 16px;flex-shrink:0;position:relative;box-shadow:inset 0 0 0 1px #0000001a}.color-swatch--circle{border-radius:calc(var(--radius) * 2)}.color-swatch--square{border-radius:calc(var(--radius) * .75)}.color-swatch--xs{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.color-swatch--xs.color-swatch--circle{border-radius:calc(var(--radius) * 1)}.color-swatch--sm{width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6)}.color-swatch--sm.color-swatch--circle{border-radius:calc(var(--radius) * 1.5)}.color-swatch--lg{width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9)}.color-swatch--lg.color-swatch--circle{border-radius:calc(var(--radius) * 3)}.color-swatch--xl{width:calc(var(--spacing) * 10);height:calc(var(--spacing) * 10)}.color-swatch--xl.color-swatch--circle{border-radius:calc(var(--radius) * 3)}.color-swatch-picker{align-items:center;gap:calc(var(--spacing) * 2);flex-wrap:wrap;display:flex}.color-swatch-picker__item{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8);border-radius:calc(var(--radius) * 2);border-style:var(--tw-border-style);--tw-outline-style:none;-webkit-tap-highlight-color:transparent;cursor:var(--cursor-interactive);transition:border-color .1s var(--ease-out),box-shadow .1s var(--ease-out);transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);border-width:2px;border-color:#0000;outline-style:none;justify-content:center;align-items:center;display:flex;position:relative}.color-swatch-picker__item:is([data-reduce-motion=true],[data-reduce-motion=true] *),.color-swatch-picker__item:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.color-swatch-picker__item:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.color-swatch-picker__item:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.color-swatch-picker__item:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.color-swatch-picker__item:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.color-swatch-picker__item:focus-visible,.color-swatch-picker__item[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.color-swatch-picker__item[data-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.color-swatch-picker__item[data-selected=true]{border-color:var(--color-swatch-current);box-shadow:var(--field-shadow)}.color-swatch-picker__item[data-selected=true] .color-swatch-picker__swatch{transform:scale(.77)}.color-swatch-picker__swatch{border-radius:inherit;width:100%;height:100%;transition:transform .1s var(--ease-out);transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);display:block}.color-swatch-picker__swatch:is([data-reduce-motion=true],[data-reduce-motion=true] *),.color-swatch-picker__swatch:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.color-swatch-picker__swatch:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.color-swatch-picker__swatch:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.color-swatch-picker__swatch:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.color-swatch-picker__swatch:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}@media(hover:hover){.color-swatch-picker__swatch:hover{transform:scale(1.1)}}.color-swatch-picker__indicator{pointer-events:none;z-index:10;justify-content:center;align-items:center;display:flex;position:absolute;top:0;right:0;bottom:0;left:0}.color-swatch-picker__indicator>*{width:33.3333%;height:33.3333%;color:var(--color-white);transition:transform .15s var(--ease-out);transform:scale(0)translateZ(0)}.color-swatch-picker__indicator>:is([data-reduce-motion=true],[data-reduce-motion=true] *),.color-swatch-picker__indicator>:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.color-swatch-picker__indicator>:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.color-swatch-picker__indicator>:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.color-swatch-picker__indicator>:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.color-swatch-picker__indicator>:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.color-swatch-picker__indicator[data-light-color=true] .color-swatch-picker__indicator>*{color:var(--color-black)}.color-swatch-picker__item[data-selected=true] .color-swatch-picker__indicator>*{transform:scale(1)translateZ(0)}.color-swatch-picker--stack{flex-direction:column}.color-swatch-picker--xs .color-swatch-picker__item{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4);border-radius:calc(var(--radius) * 1);border-style:var(--tw-border-style);border-width:1px}.color-swatch-picker--sm .color-swatch-picker__item{width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6);border-radius:calc(var(--radius) * 1.5);border-style:var(--tw-border-style);border-width:2px}.color-swatch-picker--lg .color-swatch-picker__item{width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9);border-radius:calc(var(--radius) * 3);border-style:var(--tw-border-style);border-width:3px}.color-swatch-picker--xl .color-swatch-picker__item{width:calc(var(--spacing) * 10);height:calc(var(--spacing) * 10);border-radius:calc(var(--radius) * 3);border-style:var(--tw-border-style);border-width:3px}.color-swatch-picker--square .color-swatch-picker__item{border-radius:calc(var(--radius) * 1.5)}.color-swatch-picker--square .color-swatch-picker__item .color-swatch-picker__swatch,.color-swatch-picker--square .color-swatch-picker__item[data-selected=true] .color-swatch-picker__swatch{border-radius:calc(var(--radius) * 1)}.color-swatch-picker--square.color-swatch-picker--xs .color-swatch-picker__item,.color-swatch-picker--square.color-swatch-picker--xs .color-swatch-picker__item .color-swatch-picker__swatch,.color-swatch-picker--square.color-swatch-picker--xs .color-swatch-picker__item[data-selected=true] .color-swatch-picker__swatch{border-radius:calc(var(--radius) * .75)}.color-swatch-picker--square.color-swatch-picker--sm .color-swatch-picker__item,.color-swatch-picker--square.color-swatch-picker--sm .color-swatch-picker__item .color-swatch-picker__swatch{border-radius:calc(var(--radius) * 1)}.color-swatch-picker--square.color-swatch-picker--sm .color-swatch-picker__item[data-selected=true] .color-swatch-picker__swatch{border-radius:calc(var(--radius) * .75)}.color-swatch-picker--square.color-swatch-picker--lg .color-swatch-picker__item{border-radius:calc(var(--radius) * 1.5)}.color-swatch-picker--square.color-swatch-picker--lg .color-swatch-picker__item .color-swatch-picker__swatch,.color-swatch-picker--square.color-swatch-picker--lg .color-swatch-picker__item[data-selected=true] .color-swatch-picker__swatch{border-radius:calc(var(--radius) * 1)}.color-swatch-picker--square.color-swatch-picker--xl .color-swatch-picker__item{border-radius:calc(var(--radius) * 1.5)}.color-swatch-picker--square.color-swatch-picker--xl .color-swatch-picker__item .color-swatch-picker__swatch,.color-swatch-picker--square.color-swatch-picker--xl .color-swatch-picker__item[data-selected=true] .color-swatch-picker__swatch{border-radius:calc(var(--radius) * 1)}.color-input-group{height:calc(var(--spacing) * 9);border-radius:var(--field-radius,calc(var(--radius) * 1.5));border-style:var(--tw-border-style);background-color:var(--field-background,var(--default));font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--field-foreground,var(--foreground));--tw-shadow:var(--field-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;border-width:1px;border-width:var(--border-width-field);border-color:var(--field-border);transition:background-color .15s var(--ease-smooth),border-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out);outline-style:none;align-items:center;display:inline-flex;overflow:hidden}.color-input-group:is([data-reduce-motion=true],[data-reduce-motion=true] *),.color-input-group:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.color-input-group:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.color-input-group:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.color-input-group:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.color-input-group:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}@media(hover:hover){.color-input-group:hover:not(:focus-within),.color-input-group[data-hovered=true]:not([data-focus-within=true]){background-color:var(--field-hover);border-color:var(--field-border-hover)}}.color-input-group[data-focus-within=true],.color-input-group:focus-within{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-outline-style:none;--tw-ring-offset-width:0px;outline-style:none}.color-input-group[data-invalid=true]{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}.color-input-group[data-invalid=true]:focus,.color-input-group[data-invalid=true]:focus-visible,.color-input-group[data-invalid=true][data-focused=true],.color-input-group[data-invalid=true][data-focus-visible=true],.color-input-group[data-invalid=true]:focus-within,.color-input-group[data-invalid=true][data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.color-input-group[data-invalid=true]{background-color:var(--field-focus);border-color:var(--color-field-border-invalid)}.color-input-group[data-disabled=true],.color-input-group[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.color-input-group__input{cursor:text;border-style:var(--tw-border-style);height:100%;padding-inline:calc(var(--spacing) * 3);padding-block:calc(var(--spacing) * 2);font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;background-color:#0000;border-width:0;border-radius:0;outline-style:none;flex:1;align-items:center;display:flex}@media(min-width:40rem){.color-input-group__input{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}.color-input-group__input::placeholder{color:var(--field-placeholder,var(--muted))}.color-input-group:has([data-slot=color-input-group-prefix]) .color-input-group__input{padding-left:calc(var(--spacing) * 2);border-top-left-radius:0;border-bottom-left-radius:0}.color-input-group:has([data-slot=color-input-group-suffix]) .color-input-group__input{padding-right:calc(var(--spacing) * 2);border-top-right-radius:0;border-bottom-right-radius:0}.color-input-group__input:focus,.color-input-group__input:focus-visible{--tw-outline-style:none;outline-style:none}.color-input-group__prefix{color:var(--field-placeholder,var(--muted));margin-right:0;margin-left:calc(var(--spacing) * 3);flex-shrink:0;align-items:center;display:flex}.color-input-group__suffix{color:var(--field-placeholder,var(--muted));margin-right:calc(var(--spacing) * 3);flex-shrink:0;align-items:center;display:flex}.color-input-group--secondary{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);background-color:var(--color-input-group-bg);--color-input-group-bg:var(--default);--color-input-group-bg-hover:var(--default-hover);--color-input-group-bg-focus:var(--default)}@media(hover:hover){.color-input-group--secondary:hover:not(:focus-within),.color-input-group--secondary[data-hovered=true]:not([data-focus-within=true]){background-color:var(--color-input-group-bg-hover)}}.color-input-group--secondary:focus-within,.color-input-group--secondary[data-focus-within=true]{background-color:var(--color-input-group-bg-focus)}.color-input-group--secondary[data-invalid=true]{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}.color-input-group--secondary[data-invalid=true]:focus,.color-input-group--secondary[data-invalid=true]:focus-visible,.color-input-group--secondary[data-invalid=true][data-focused=true],.color-input-group--secondary[data-invalid=true][data-focus-visible=true],.color-input-group--secondary[data-invalid=true]:focus-within,.color-input-group--secondary[data-invalid=true][data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.color-input-group--secondary[data-invalid=true]{border-color:var(--color-field-border-invalid);background-color:var(--color-input-group-bg-focus)}.color-input-group--secondary [data-slot=color-input-group-input]{background-color:#0000}.color-input-group--full-width{width:100%}.color-field{gap:var(--spacing);flex-direction:column;display:flex}:is(.color-field[data-invalid=true],.color-field[aria-invalid=true]) [data-slot=description]{display:none}.color-field [data-slot=label]{width:fit-content}.color-field--full-width{width:100%}.slider{gap:var(--spacing);grid-template-columns:1fr auto;grid-template-areas:"label output""track track";width:100%;display:grid}.slider [data-slot=label]{width:fit-content;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);grid-area:label}.slider .slider__output{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,);grid-area:output}.slider .slider__track{border-radius:calc(var(--radius) * 1.5);background-color:var(--default);grid-area:track;position:relative}.slider .slider__fill{pointer-events:none;background-color:var(--accent);position:absolute}.slider .slider__thumb{cursor:grab;border-radius:calc(var(--radius) * 1.5);background-color:var(--accent);-webkit-tap-highlight-color:transparent;transition:background-color .25s var(--ease-smooth),transform .25s var(--ease-out),box-shadow .15s var(--ease-out);justify-content:center;align-items:center;display:flex;position:absolute}.slider .slider__thumb:is([data-reduce-motion=true],[data-reduce-motion=true] *),.slider .slider__thumb:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.slider .slider__thumb:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.slider .slider__thumb:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.slider .slider__thumb:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.slider .slider__thumb:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.slider .slider__thumb:after{z-index:10;border-radius:calc(var(--radius) * 1);background-color:var(--accent-foreground);color:var(--color-black);--tw-shadow:var(--field-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);content:"";transform-origin:50%;transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));position:relative}@media(prefers-reduced-motion:reduce){.slider .slider__thumb:after:not(:is()){transition-property:none}}.slider .slider__thumb[data-dragging=true]{cursor:grabbing}.slider .slider__thumb[data-dragging=true]:after{scale:.9}@media(prefers-reduced-motion:reduce){.slider .slider__thumb[data-dragging=true]:after:not(:is()){--tw-scale-x:100%;--tw-scale-y:100%;--tw-scale-z:100%;scale:var(--tw-scale-x) var(--tw-scale-y)}}.slider .slider__thumb[data-focus-visible=true]{z-index:10;--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.slider .slider__thumb[data-disabled=true]{cursor:default}.slider:disabled,.slider[data-disabled=true],.slider[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}:is(.slider:disabled,.slider[data-disabled=true],.slider[aria-disabled=true]) [data-slot=label]{opacity:1}.slider[data-orientation=horizontal]{flex-direction:column}.slider[data-orientation=horizontal] .slider__track{height:calc(var(--spacing) * 5);border-inline-style:var(--tw-border-style);border-inline-width:.75rem;border-inline-color:#0000;width:100%}.slider[data-orientation=horizontal] .slider__track[data-fill-start=true]{border-inline-start-color:var(--accent)}.slider[data-orientation=horizontal] .slider__track[data-fill-end=true]{border-inline-end-color:var(--accent)}.slider[data-orientation=horizontal] .slider__fill,.slider[data-orientation=horizontal] .slider__thumb{height:100%}.slider[data-orientation=horizontal] .slider__thumb{width:1.75rem;top:50%}.slider[data-orientation=horizontal] .slider__thumb:after{width:1.5rem;height:1rem}.slider[data-orientation=vertical]{gap:calc(var(--spacing) * 2);flex-direction:row;grid-template:"output""track"1fr"label"/1fr;height:100%}.slider[data-orientation=vertical] .slider__output,.slider[data-orientation=vertical] [data-slot=label]{text-align:center}.slider[data-orientation=vertical] .slider__track{height:100%;width:calc(var(--spacing) * 5);border-block-style:var(--tw-border-style);border-block-width:.75rem;border-block-color:#0000;justify-self:center}.slider[data-orientation=vertical] .slider__track[data-fill-start=true]{border-bottom-color:var(--accent)}.slider[data-orientation=vertical] .slider__track[data-fill-end=true]{border-top-color:var(--accent)}.slider[data-orientation=vertical] .slider__fill,.slider[data-orientation=vertical] .slider__thumb{width:100%}.slider[data-orientation=vertical] .slider__thumb{height:1.75rem;left:50%}.slider[data-orientation=vertical] .slider__thumb:after{width:1rem;height:1.5rem}.switch{align-items:flex-start;gap:var(--spacing);-webkit-tap-highlight-color:transparent;cursor:var(--cursor-interactive);--switch-control-bg:var(--default);--switch-control-bg-hover:var(--switch-control-bg);flex-direction:column;display:flex}@supports (color:color-mix(in lab,red,red)){.switch{--switch-control-bg-hover:color-mix(in oklab, var(--switch-control-bg), transparent 20%)}}.switch{--switch-control-bg-pressed:var(--switch-control-bg-hover);--switch-control-bg-checked:var(--accent);--switch-control-bg-checked-hover:var(--accent-hover)}.switch[data-disabled=true],.switch[data-disabled=true] [data-slot=description],.switch[data-disabled=true] [data-slot=field-error]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.switch[data-disabled=true] .switch__thumb{background-color:var(--default-foreground)}@supports (color:color-mix(in lab,red,red)){.switch[data-disabled=true] .switch__thumb{background-color:color-mix(in oklab,var(--default-foreground) 20%,transparent)}}.switch>[data-slot=description]{width:100%;min-width:0;padding-inline-start:3.25rem}.switch>[data-slot=field-error]{width:100%;min-width:0;font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));color:var(--muted);padding-inline-start:3.25rem}.switch.switch--sm>[data-slot=description],.switch.switch--sm>[data-slot=field-error]{padding-inline-start:2.75rem}.switch.switch--lg>[data-slot=description],.switch.switch--lg>[data-slot=field-error]{padding-inline-start:3.75rem}:is(.switch:disabled[aria-checked=true],.switch:disabled[data-selected=true],.switch[data-disabled=true][aria-checked=true],.switch[data-disabled=true][data-selected=true],.switch[aria-disabled=true][aria-checked=true],.switch[aria-disabled=true][data-selected=true]) .switch__thumb{opacity:.4}.switch__control{border-radius:calc(var(--radius) * 1.5);background-color:var(--switch-control-bg);width:2.5rem;height:1.25rem;transition:background-color .25s var(--ease-smooth),box-shadow .15s var(--ease-out);flex-shrink:0;align-items:center;display:flex;position:relative;overflow:hidden}.switch__control:is([data-reduce-motion=true],[data-reduce-motion=true] *),.switch__control:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.switch__control:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.switch__control:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.switch__control:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.switch__control:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.switch:focus-visible .switch__control,.switch:has([data-slot=switch-content][data-focus-visible=true]) .switch__control,.switch [data-slot=switch-content][data-focus-visible=true] .switch__control{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.switch:hover .switch__control,.switch:has([data-slot=switch-content][data-hovered=true]) .switch__control,.switch [data-slot=switch-content][data-hovered=true] .switch__control{background-color:var(--switch-control-bg-hover)}.switch:active .switch__control,.switch:has([data-slot=switch-content][data-pressed=true]) .switch__control,.switch [data-slot=switch-content][data-pressed=true] .switch__control{background-color:var(--switch-control-bg-pressed)}:is(.switch:active .switch__control,.switch:has([data-slot=switch-content][data-pressed=true]) .switch__control,.switch [data-slot=switch-content][data-pressed=true] .switch__control):is([data-reduce-motion=true],[data-reduce-motion=true] *),:is(.switch:active .switch__control,.switch:has([data-slot=switch-content][data-pressed=true]) .switch__control,.switch [data-slot=switch-content][data-pressed=true] .switch__control):is([data-reduce-motion=true],[data-reduce-motion=true] *):before,:is(.switch:active .switch__control,.switch:has([data-slot=switch-content][data-pressed=true]) .switch__control,.switch [data-slot=switch-content][data-pressed=true] .switch__control):is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transform:none}@media(prefers-reduced-motion:reduce){:is(.switch:active .switch__control,.switch:has([data-slot=switch-content][data-pressed=true]) .switch__control,.switch [data-slot=switch-content][data-pressed=true] .switch__control):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),:is(.switch:active .switch__control,.switch:has([data-slot=switch-content][data-pressed=true]) .switch__control,.switch [data-slot=switch-content][data-pressed=true] .switch__control):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,:is(.switch:active .switch__control,.switch:has([data-slot=switch-content][data-pressed=true]) .switch__control,.switch [data-slot=switch-content][data-pressed=true] .switch__control):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transform:none}}.switch[aria-checked=true] .switch__control,.switch[data-selected=true] .switch__control{background-color:var(--switch-control-bg-checked)}.switch[aria-checked=true]:hover .switch__control,.switch[data-selected=true]:hover .switch__control,.switch[aria-checked=true][data-hovered=true] .switch__control,.switch[data-selected=true][data-hovered=true] .switch__control,.switch:has([data-slot=switch-content][data-hovered=true])[data-selected=true] .switch__control,.switch[aria-checked=true]:active .switch__control,.switch[data-selected=true]:active .switch__control,.switch[aria-checked=true][data-pressed=true] .switch__control,.switch[data-selected=true][data-pressed=true] .switch__control,.switch:has([data-slot=switch-content][data-pressed=true])[data-selected=true] .switch__control{background-color:var(--switch-control-bg-checked-hover)}.switch__content{cursor:inherit;align-items:center;gap:calc(var(--spacing) * 3);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--foreground);--tw-outline-style:none;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;outline-style:none;display:inline-flex}.switch--sm .switch__control{border-radius:calc(var(--radius) * 1);width:2rem;height:1rem}.switch--lg .switch__control{width:3rem;height:1.5rem}.switch__thumb{transform-origin:50%;border-radius:calc(var(--radius) * 1);background-color:var(--color-white);color:var(--color-black);--tw-shadow:var(--field-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);width:1.375rem;height:1rem;transition:margin .3s var(--ease-out-fluid),background-color .2s var(--ease-out);margin-inline-start:calc(var(--spacing) * .5);display:flex}.switch__thumb:is([data-reduce-motion=true],[data-reduce-motion=true] *),.switch__thumb:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.switch__thumb:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.switch__thumb:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.switch__thumb:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.switch__thumb:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.switch[aria-checked=true] .switch__thumb,.switch[data-selected=true] .switch__thumb{background-color:var(--accent-foreground);color:var(--accent);margin-inline-start:calc(100% - 1.5rem);box-shadow:0 0 5px #00000005,0 2px 10px #0000000f,0 0 1px #0000004d}.switch--sm .switch__thumb{border-radius:calc(var(--radius) * .75);width:1.03125rem;height:.75rem}.switch[aria-checked=true] :is(.switch--sm .switch__thumb),.switch[data-selected=true] :is(.switch--sm .switch__thumb){margin-inline-start:calc(100% - 1.15625rem)}.switch--lg .switch__thumb{border-radius:calc(var(--radius) * 1.5);width:1.71875rem;height:1.25rem}.switch[aria-checked=true] :is(.switch--lg .switch__thumb),.switch[data-selected=true] :is(.switch--lg .switch__thumb){margin-inline-start:calc(100% - 1.84375rem)}.switch__thumb>*{justify-content:center;align-items:center;width:100%;height:100%;display:flex}.switch__label{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--foreground)}.switch [data-slot=label]{-webkit-user-select:none;user-select:none}.switch__content [data-slot=label]{cursor:var(--cursor-interactive)}.switch [data-slot=description]{cursor:default;-webkit-user-select:none;user-select:none}.switch-group{gap:calc(var(--spacing) * 6);flex-direction:column;display:flex}.switch-group__items{gap:calc(var(--spacing) * 4);display:flex}.switch-group--horizontal .switch-group__items{flex-direction:row}.switch-group--vertical .switch-group__items{flex-direction:column}.badge{justify-content:center;align-items:center;gap:calc(var(--spacing) * .5);--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);min-height:calc(var(--spacing) * 7);min-width:calc(var(--spacing) * 7);border-radius:calc(var(--radius) * 3);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));--tw-leading:1.34;--badge-bg:var(--default);--badge-fg:var(--default-foreground);--badge-border:var(--background);background-color:var(--badge-bg);color:var(--badge-fg);border:1px solid var(--badge-border);flex-shrink:0;line-height:1.34;display:inline-flex}.badge__label{padding-inline:calc(var(--spacing) * .5)}.badge-anchor{flex-shrink:0;display:inline-flex;position:relative}.badge--lg{min-height:calc(var(--spacing) * 8);min-width:calc(var(--spacing) * 8);border-radius:calc(var(--radius) * 2);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-leading:1.43;line-height:1.43}.badge--sm{min-height:calc(var(--spacing) * 4);min-width:calc(var(--spacing) * 4);border-radius:calc(var(--radius) * 1.5);--tw-leading:1.34;font-size:10px;line-height:1.34}.badge--accent{--badge-fg:var(--accent-soft-foreground)}.badge--default{--badge-fg:var(--default-foreground)}.badge--success{--badge-fg:var(--success-soft-foreground)}.badge--warning{--badge-fg:var(--warning-soft-foreground)}.badge--danger{--badge-fg:var(--danger-soft-foreground)}.badge--top-right{position:absolute;top:0;right:0;transform:translate(25%,-25%)}.badge--top-left{position:absolute;top:0;left:0;transform:translate(-25%,-25%)}.badge--bottom-right{position:absolute;bottom:0;right:0;transform:translate(25%,25%)}.badge--bottom-left{position:absolute;bottom:0;left:0;transform:translate(-25%,25%)}.badge--primary.badge--accent{--badge-bg:var(--accent);--badge-fg:var(--accent-foreground)}.badge--primary.badge--default{--badge-bg:var(--default);--badge-fg:var(--default-foreground)}.badge--primary.badge--success{--badge-bg:var(--success);--badge-fg:var(--success-foreground)}.badge--primary.badge--warning{--badge-bg:var(--warning);--badge-fg:var(--warning-foreground)}.badge--primary.badge--danger{--badge-bg:var(--danger);--badge-fg:var(--danger-foreground)}.badge--soft.badge--accent{--badge-bg:var(--accent-soft);--badge-fg:var(--accent-soft-foreground)}.badge--soft.badge--default{--badge-bg:var(--default-soft);--badge-fg:var(--default-soft-foreground)}.badge--soft.badge--success{--badge-bg:var(--success-soft);--badge-fg:var(--success-soft-foreground)}.badge--soft.badge--warning{--badge-bg:var(--warning-soft);--badge-fg:var(--warning-soft-foreground)}.badge--soft.badge--danger{--badge-bg:var(--danger-soft);--badge-fg:var(--danger-soft-foreground)}.chip{align-items:center;gap:calc(var(--spacing) * .5);border-radius:calc(var(--radius) * 2);padding-inline:calc(var(--spacing) * 2);padding-block:calc(var(--spacing) * .5);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));--tw-leading:calc(var(--spacing) * 5);line-height:calc(var(--spacing) * 5);--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);--chip-bg:var(--default);--chip-fg:currentColor;background-color:var(--chip-bg);color:var(--chip-fg);flex-shrink:0;display:inline-flex}.chip__label{padding-inline:calc(var(--spacing) * .5)}.chip--accent{--chip-fg:var(--accent-soft-foreground)}.chip--danger{--chip-fg:var(--danger-soft-foreground)}.chip--default{--chip-fg:var(--default-foreground)}.chip--success{--chip-fg:var(--success-soft-foreground)}.chip--warning{--chip-fg:var(--warning-soft-foreground)}.chip--tertiary{--chip-bg:transparent}.chip--sm{padding-inline:var(--spacing);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));padding-block:0}.chip--md{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.chip--lg{padding-inline:calc(var(--spacing) * 3);padding-block:var(--spacing);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.chip--primary.chip--accent{--chip-bg:var(--accent);--chip-fg:var(--accent-foreground)}.chip--primary.chip--success{--chip-bg:var(--success);--chip-fg:var(--success-foreground)}.chip--primary.chip--warning{--chip-bg:var(--warning);--chip-fg:var(--warning-foreground)}.chip--primary.chip--danger{--chip-bg:var(--danger);--chip-fg:var(--danger-foreground)}.chip--accent.chip--soft{--chip-bg:var(--accent-soft);--chip-fg:var(--accent-soft-foreground)}.chip--success.chip--soft{--chip-bg:var(--success-soft);--chip-fg:var(--success-soft-foreground)}.chip--warning.chip--soft{--chip-bg:var(--warning-soft);--chip-fg:var(--warning-soft-foreground)}.chip--danger.chip--soft{--chip-bg:var(--danger-soft);--chip-fg:var(--danger-soft-foreground)}.chip--default.chip--soft{--chip-bg:var(--default-soft);--chip-fg:var(--default-soft-foreground)}.table-root{grid-template-columns:minmax(0,1fr);width:100%;display:grid;position:relative;overflow:clip}.table__scroll-container{scrollbar-width:var(--scrollbar-width);scrollbar-color:var(--scrollbar-color);scrollbar-gutter:var(--scrollbar-gutter);scrollbar-gutter:auto;overflow-x:auto}.table-root--primary{background-color:var(--surface-secondary);padding-inline:var(--spacing);padding-bottom:var(--spacing);border-radius:min(32px,calc(var(--radius) * 2.5))}.table-root--secondary .table__header{border-bottom-style:var(--tw-border-style);background-color:#0000;border-bottom-width:0}.table-root--secondary .table__column{background-color:var(--surface-secondary)}.table-root--secondary :is(th.table__column:first-child,[role=row]>[role=presentation]:first-of-type>.table__column){border-start-start-radius:min(32px,var(--radius-2xl));border-end-start-radius:min(32px,var(--radius-2xl))}.table-root--secondary :is(th.table__column:last-child,[role=row]>[role=presentation]:last-of-type>.table__column){border-start-end-radius:min(32px,var(--radius-2xl));border-end-end-radius:min(32px,var(--radius-2xl))}.table-root--secondary .table__body{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.table-root--secondary .table__body tr:first-child td:first-child,.table-root--secondary .table__body tr:first-child td:last-child,.table-root--secondary .table__body tr:last-child td:first-child,.table-root--secondary .table__body tr:last-child td:last-child{border-radius:0}.table-root--secondary .table__body:not(tbody){border-radius:0;overflow:visible}.table-root--secondary .table__row .table__cell{border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--separator-tertiary)}@supports (color:color-mix(in lab,red,red)){.table-root--secondary .table__row .table__cell{border-color:color-mix(in oklab,var(--separator-tertiary) 50%,transparent)}}.table-root--secondary .table__row .table__cell{background-color:#0000}@media(hover:hover){.table-root--secondary .table__row:hover .table__cell,.table-root--secondary .table__row[data-hovered=true] .table__cell{background-color:var(--default)}@supports (color:color-mix(in lab,red,red)){.table-root--secondary .table__row:hover .table__cell,.table-root--secondary .table__row[data-hovered=true] .table__cell{background-color:color-mix(in oklab,var(--default) 50%,transparent)}}}.table__content{border-collapse:separate;--tw-border-spacing-x:0;--tw-border-spacing-y:0;width:100%;border-spacing:var(--tw-border-spacing-x) var(--tw-border-spacing-y);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.table-root--primary .table__content{overflow:clip}.table__header{border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--separator)}@supports (color:color-mix(in lab,red,red)){.table__header{border-color:color-mix(in oklab,var(--separator) 50%,transparent)}}.table__header{background-color:var(--surface-secondary)}.table__column{padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 2.5);text-align:left;font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--muted);position:relative}.table__column:after{content:"";pointer-events:none;height:calc(var(--spacing) * 4);--tw-translate-y: -50% ;width:1px;translate:var(--tw-translate-x) var(--tw-translate-y);border-radius:calc(var(--radius) * .5);background-color:var(--separator);inset-inline-end:calc(var(--spacing) * 0);position:absolute;top:50%}.table__column:last-child:not(:only-child):after{content:none}.table__column[data-allows-sorting=true]{cursor:var(--cursor-interactive)}@media(hover:hover){.table__column[data-allows-sorting=true]:hover,.table__column[data-allows-sorting=true][data-hovered=true]{color:var(--foreground)}}.table__column:focus-visible,.table__column[data-focus-visible=true]{border-radius:calc(var(--radius) * 1);--tw-outline-style:none;box-shadow:inset 0 0 0 2px var(--focus);outline-style:none}[role=row]>[role=presentation]:last-of-type:not(:only-of-type)>.table__column:after{content:none}.table__sortable-column-header{justify-content:space-between;align-items:center;display:flex}.table__sortable-column-indicator{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3);transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.1s;--tw-ease:var(--ease-out);transition-duration:.1s;transition-timing-function:var(--ease-out)}.table__sortable-column-indicator[data-direction=descending]{rotate:180deg}.table__body tr:first-child td:first-child{border-start-start-radius:min(32px,var(--radius-2xl))}.table__body tr:first-child td:last-child{border-start-end-radius:min(32px,var(--radius-2xl))}.table__body tr:last-child td:first-child{border-end-start-radius:min(32px,var(--radius-2xl))}.table__body tr:last-child td:last-child{border-end-end-radius:min(32px,var(--radius-2xl))}.table__body:not(tbody){border-radius:min(32px,var(--radius-2xl));height:100%;position:relative;overflow:clip}.table__row{border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--separator);height:100%;position:relative}@supports (color:color-mix(in lab,red,red)){.table__row{border-color:color-mix(in oklab,var(--separator) 50%,transparent)}}.table__row:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}@media(hover:hover){.table__row:hover .table__cell,.table__row[data-hovered=true] .table__cell{background-color:var(--surface)}@supports (color:color-mix(in lab,red,red)){.table__row:hover .table__cell,.table__row[data-hovered=true] .table__cell{background-color:color-mix(in oklab,var(--surface) 40%,transparent)}}}.table__row[data-selected=true] .table__cell{background-color:var(--surface)}@supports (color:color-mix(in lab,red,red)){.table__row[data-selected=true] .table__cell{background-color:color-mix(in oklab,var(--surface) 10%,transparent)}}.table__row[aria-disabled=true],.table__row[data-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.table__row:focus-visible,.table__row[data-focus-visible=true]{--tw-outline-style:none;outline-style:none}.table__row[data-dragging=true]{opacity:.5}.table__row[data-drop-target=true] .table__cell{background-color:var(--accent-soft)}.table__cell{background-color:var(--surface);height:100%;padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 3);vertical-align:middle;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--foreground);border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--separator-tertiary)}@supports (color:color-mix(in lab,red,red)){.table__cell{border-color:color-mix(in oklab,var(--separator-tertiary) 50%,transparent)}}.table__cell:focus-visible,.table__cell[data-focus-visible=true]{border-radius:calc(var(--radius) * 1);--tw-outline-style:none;box-shadow:inset 0 0 0 2px var(--focus);outline-style:none}.table__row:is(:focus-visible,[data-focus-visible=true]) :is(.table__cell,.table__column){--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.table__row:is(:focus-visible,[data-focus-visible=true])>:is(.table__cell,.table__column):only-child,.table__row:is(:focus-visible,[data-focus-visible=true])>:only-child :is(.table__cell,.table__column){border-radius:calc(var(--radius) * 1);--tw-shadow:inset 0 0 0 2px var(--tw-shadow-color,var(--focus));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;outline-style:none}.table__row:is(:focus-visible,[data-focus-visible=true])>:is(.table__cell,.table__column):first-child:not(:only-child),.table__row:is(:focus-visible,[data-focus-visible=true])>:first-child:not(:only-child) :is(.table__cell,.table__column){border-top-left-radius:calc(var(--radius) * 1);border-bottom-left-radius:calc(var(--radius) * 1);--tw-shadow:inset 2px 0 0 0 var(--tw-shadow-color,var(--focus)), inset 0 2px 0 0 var(--tw-shadow-color,var(--focus)), inset 0 -2px 0 0 var(--tw-shadow-color,var(--focus));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;outline-style:none}.table__row:is(:focus-visible,[data-focus-visible=true])>:is(.table__cell,.table__column):last-child:not(:only-child),.table__row:is(:focus-visible,[data-focus-visible=true])>:last-child:not(:only-child) :is(.table__cell,.table__column){border-top-right-radius:calc(var(--radius) * 1);border-bottom-right-radius:calc(var(--radius) * 1);--tw-shadow:inset -2px 0 0 0 var(--tw-shadow-color,var(--focus)), inset 0 2px 0 0 var(--tw-shadow-color,var(--focus)), inset 0 -2px 0 0 var(--tw-shadow-color,var(--focus));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;outline-style:none}.table__row:is(:focus-visible,[data-focus-visible=true])>:is(.table__cell,.table__column):not(:first-child):not(:last-child):not(:only-child),.table__row:is(:focus-visible,[data-focus-visible=true])>:not(:first-child):not(:last-child):not(:only-child) :is(.table__cell,.table__column){--tw-shadow:inset 0 2px 0 0 var(--tw-shadow-color,var(--focus)), inset 0 -2px 0 0 var(--tw-shadow-color,var(--focus));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;outline-style:none}.table__cell[data-tree-column]{padding-inline-start:calc(1rem * var(--table-row-level,1))}.table__footer{padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 2.5);align-items:center;display:flex}.table__resizable-container{scrollbar-width:var(--scrollbar-width);scrollbar-color:var(--scrollbar-color);scrollbar-gutter:var(--scrollbar-gutter);scrollbar-gutter:auto;position:relative;overflow:auto}.table__column-resizer{height:calc(var(--spacing) * 4);--tw-translate-y: -50% ;border-radius:calc(var(--radius) * .5);background-color:var(--separator);box-sizing:content-box;--tw-translate-x: 50% ;width:1px;translate:var(--tw-translate-x) var(--tw-translate-y);cursor:col-resize;touch-action:none;padding-inline:calc(var(--spacing) * 2);--tw-border-style:none;--tw-outline-style:none;inset-inline-end:calc(var(--spacing) * 0);background-clip:content-box;border-style:none;outline-style:none;position:absolute;top:50%}.table__column-resizer[data-hovered=true],.table__column-resizer:hover,.table__column-resizer[data-resizing=true]{height:100%;width:calc(var(--spacing) * .5);background-color:var(--accent)}.table__column-resizer[data-focus-visible=true],.table__column-resizer:focus-visible{height:100%;width:calc(var(--spacing) * .5);background-color:var(--focus)}.table__column:has(.table__column-resizer):after{content:none}.table__load-more td,.table__load-more [role=rowheader]{padding-block:calc(var(--spacing) * 3);text-align:center}:is(.table__load-more td,.table__load-more [role=rowheader])>*{margin-inline:auto}.table__load-more-content{justify-content:center;align-items:center;gap:calc(var(--spacing) * 2);padding-block:calc(var(--spacing) * 2);display:flex}.alert{justify-content:flex-start;align-items:flex-start;gap:calc(var(--spacing) * 4);background-color:var(--surface);width:100%;padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 3);--tw-shadow:var(--surface-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);border-radius:min(32px,var(--radius-3xl));flex-direction:row;display:flex}.alert__content{flex-direction:column;flex-grow:1;align-items:flex-start;height:100%;display:flex}.alert__indicator{padding:var(--spacing);-webkit-user-select:none;user-select:none;justify-content:center;align-items:center;display:flex}.alert__indicator [data-slot=alert-default-icon]{box-sizing:content-box;width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.alert__title{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-leading:calc(var(--spacing) * 6);line-height:calc(var(--spacing) * 6);--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.alert__description{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--muted)}.alert--default .alert__indicator,.alert--default .alert__title{color:var(--foreground)}.alert--accent .alert__indicator,.alert--accent .alert__title{color:var(--accent-soft-foreground)}.alert--success .alert__indicator,.alert--success .alert__title{color:var(--success-soft-foreground)}.alert--warning .alert__indicator,.alert--warning .alert__title{color:var(--warning-soft-foreground)}.alert--danger .alert__indicator,.alert--danger .alert__title{color:var(--danger-soft-foreground)}.empty-state{padding:calc(var(--spacing) * 2);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--muted)}.skeleton{pointer-events:none;border-radius:calc(var(--radius) * .5);background-color:var(--surface-tertiary);position:relative;overflow:hidden}@supports (color:color-mix(in lab,red,red)){.skeleton{background-color:color-mix(in oklab,var(--surface-tertiary) 70%,transparent)}}.skeleton--shimmer:after{--tw-translate-x:-100%;translate:var(--tw-translate-x) var(--tw-translate-y);--tw-gradient-position:to right;animation:2s linear infinite skeleton;position:absolute;top:0;right:0;bottom:0;left:0}@supports (background-image:linear-gradient(in lab,red,red)){.skeleton--shimmer:after{--tw-gradient-position:to right in oklab}}.skeleton--shimmer:after{background-image:linear-gradient(var(--tw-gradient-stops));--tw-gradient-from:transparent;--tw-gradient-via:var(--surface-tertiary);--tw-gradient-via-stops:var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));--tw-gradient-to:transparent;--tw-content:"";content:var(--tw-content)}.skeleton--shimmer:has(.skeleton):after{content:none}.skeleton--shimmer:has(.skeleton):before{--tw-translate-x:-100%;translate:var(--tw-translate-x) var(--tw-translate-y);--tw-content:"";content:var(--tw-content);z-index:10;pointer-events:none;mix-blend-mode:overlay;background:linear-gradient(90deg,#0000,#ffffff80,#0000);animation:2s linear infinite skeleton;position:absolute;top:0;right:0;bottom:0;left:0}.skeleton--shimmer:has(.skeleton) .skeleton:after{content:none}.skeleton--pulse{animation:var(--animate-pulse)}.meter{gap:var(--spacing);--meter-fill:var(--accent);grid-template-columns:1fr auto;grid-template-areas:"label output""track track";width:100%;display:grid}.meter [data-slot=label]{width:fit-content;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);grid-area:label}.meter .meter__output{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,);grid-area:output}.meter .meter__track{border-radius:calc(var(--radius) * .5);background-color:var(--default);height:calc(var(--spacing) * 2);grid-area:track;position:relative;overflow:hidden}.meter .meter__fill{border-radius:calc(var(--radius) * .5);background-color:var(--meter-fill);height:100%;transition:width .3s var(--ease-out);position:absolute;top:0;left:0}.meter .meter__fill:is([data-reduce-motion=true],[data-reduce-motion=true] *),.meter .meter__fill:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.meter .meter__fill:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.meter .meter__fill:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.meter .meter__fill:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.meter .meter__fill:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.meter:disabled,.meter[data-disabled=true],.meter[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}:is(.meter:disabled,.meter[data-disabled=true],.meter[aria-disabled=true]) [data-slot=label]{opacity:1}.meter--sm .meter__track{height:var(--spacing);border-radius:calc(var(--radius) * .25)}.meter--sm .meter__fill{border-radius:calc(var(--radius) * .25)}.meter--lg .meter__track{height:calc(var(--spacing) * 3);border-radius:calc(var(--radius) * .75)}.meter--lg .meter__fill{border-radius:calc(var(--radius) * .75)}.meter--default{--meter-fill:var(--default-foreground)}.meter--accent{--meter-fill:var(--accent)}.meter--success{--meter-fill:var(--success)}.meter--warning{--meter-fill:var(--warning)}.meter--danger{--meter-fill:var(--danger)}.progress-bar{gap:var(--spacing);--progress-bar-fill:var(--accent);grid-template-columns:1fr auto;grid-template-areas:"label output""track track";width:100%;display:grid}.progress-bar [data-slot=label]{width:fit-content;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);grid-area:label}.progress-bar .progress-bar__output{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,);grid-area:output}.progress-bar .progress-bar__track{border-radius:calc(var(--radius) * .5);background-color:var(--default);height:calc(var(--spacing) * 2);grid-area:track;position:relative;overflow:hidden}.progress-bar .progress-bar__fill{border-radius:calc(var(--radius) * .5);background-color:var(--progress-bar-fill);height:100%;transition:width .3s var(--ease-out);position:absolute;top:0;left:0}.progress-bar .progress-bar__fill:is([data-reduce-motion=true],[data-reduce-motion=true] *),.progress-bar .progress-bar__fill:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.progress-bar .progress-bar__fill:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.progress-bar .progress-bar__fill:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.progress-bar .progress-bar__fill:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.progress-bar .progress-bar__fill:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.progress-bar:not([aria-valuenow]) .progress-bar__fill{width:40%;animation:1.5s cubic-bezier(.65,0,.35,1) infinite progress-bar-indeterminate}.progress-bar:not([aria-valuenow]) .progress-bar__fill:is([data-reduce-motion=true],[data-reduce-motion=true] *),.progress-bar:not([aria-valuenow]) .progress-bar__fill:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.progress-bar:not([aria-valuenow]) .progress-bar__fill:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{animation:none}@media(prefers-reduced-motion:reduce){.progress-bar:not([aria-valuenow]) .progress-bar__fill:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.progress-bar:not([aria-valuenow]) .progress-bar__fill:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.progress-bar:not([aria-valuenow]) .progress-bar__fill:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{animation:none}}.progress-bar:disabled,.progress-bar[data-disabled=true],.progress-bar[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}:is(.progress-bar:disabled,.progress-bar[data-disabled=true],.progress-bar[aria-disabled=true]) [data-slot=label]{opacity:1}@keyframes progress-bar-indeterminate{0%{transform:translate(-100%)}to{transform:translate(350%)}}.progress-bar--sm .progress-bar__track{height:var(--spacing);border-radius:calc(var(--radius) * .25)}.progress-bar--sm .progress-bar__fill{border-radius:calc(var(--radius) * .25)}.progress-bar--lg .progress-bar__track{height:calc(var(--spacing) * 3);border-radius:calc(var(--radius) * .75)}.progress-bar--lg .progress-bar__fill{border-radius:calc(var(--radius) * .75)}.progress-bar--default{--progress-bar-fill:var(--default-foreground)}.progress-bar--accent{--progress-bar-fill:var(--accent)}.progress-bar--success{--progress-bar-fill:var(--success)}.progress-bar--warning{--progress-bar-fill:var(--warning)}.progress-bar--danger{--progress-bar-fill:var(--danger)}.progress-circle{--progress-circle-stroke:var(--accent);--progress-circle-track-stroke:var(--default);justify-content:center;align-items:center;display:inline-flex}.progress-circle .progress-circle__track{width:calc(var(--spacing) * 7);height:calc(var(--spacing) * 7)}.progress-circle .progress-circle__track-circle{stroke:var(--progress-circle-track-stroke)}.progress-circle .progress-circle__fill-circle{stroke:var(--progress-circle-stroke);transition:stroke-dashoffset .3s var(--ease-out)}.progress-circle .progress-circle__fill-circle:is([data-reduce-motion=true],[data-reduce-motion=true] *),.progress-circle .progress-circle__fill-circle:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.progress-circle .progress-circle__fill-circle:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.progress-circle .progress-circle__fill-circle:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.progress-circle .progress-circle__fill-circle:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.progress-circle .progress-circle__fill-circle:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.progress-circle:not([aria-valuenow]) .progress-circle__track{animation:1s linear infinite progress-circle-spin}.progress-circle:not([aria-valuenow]) .progress-circle__track:is([data-reduce-motion=true],[data-reduce-motion=true] *),.progress-circle:not([aria-valuenow]) .progress-circle__track:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.progress-circle:not([aria-valuenow]) .progress-circle__track:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{animation:none}@media(prefers-reduced-motion:reduce){.progress-circle:not([aria-valuenow]) .progress-circle__track:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.progress-circle:not([aria-valuenow]) .progress-circle__track:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.progress-circle:not([aria-valuenow]) .progress-circle__track:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{animation:none}}.progress-circle:disabled,.progress-circle[data-disabled=true],.progress-circle[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}@keyframes progress-circle-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.progress-circle--sm .progress-circle__track{width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5)}.progress-circle--lg .progress-circle__track{width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9)}.progress-circle--default{--progress-circle-stroke:var(--default-foreground)}.progress-circle--accent{--progress-circle-stroke:var(--accent)}.progress-circle--success{--progress-circle-stroke:var(--success)}.progress-circle--warning{--progress-circle-stroke:var(--warning)}.progress-circle--danger{--progress-circle-stroke:var(--danger)}.spinner{pointer-events:none;width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6);flex-shrink:0;animation:.75s linear infinite spin;display:inline-flex}.spinner:is([data-reduce-motion=true],[data-reduce-motion=true] *),.spinner:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.spinner:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{animation:none}@media(prefers-reduced-motion:reduce){.spinner:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.spinner:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.spinner:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{animation:none}}.spinner--sm{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.spinner--lg{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8)}.spinner--xl{width:calc(var(--spacing) * 10);height:calc(var(--spacing) * 10)}.spinner--current{color:inherit}.spinner--accent{color:var(--accent)}.spinner--danger{color:var(--danger)}.spinner--success{color:var(--success)}.spinner--warning{color:var(--warning)}.toast-region{pointer-events:none;z-index:50;--tw-outline-style:none;outline-style:none;width:calc(100vw - 2rem);position:fixed}@media(min-width:40rem){.toast-region{width:auto;min-width:var(--toast-width)}}.toast-region{display:block}.toast-region--bottom{bottom:calc(var(--spacing) * 4);--tw-translate-x: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y);left:50%}.toast-region--bottom-start{bottom:calc(var(--spacing) * 4);left:calc(var(--spacing) * 4)}.toast-region--bottom-end{right:calc(var(--spacing) * 4);bottom:calc(var(--spacing) * 4)}.toast-region--top{top:calc(var(--spacing) * 4);--tw-translate-x: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y);left:50%}.toast-region--top-start{top:calc(var(--spacing) * 4);left:calc(var(--spacing) * 4)}.toast-region--top-end{top:calc(var(--spacing) * 4);right:calc(var(--spacing) * 4)}.toast-region:focus-visible{outline-style:var(--tw-outline-style);outline-offset:2px;outline-width:2px;outline-color:var(--focus)}.toast{pointer-events:auto;justify-content:flex-start;align-items:flex-start;gap:calc(var(--spacing) * 1.5);background-color:var(--surface);padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 3);--tw-shadow:var(--overlay-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);border-radius:min(32px,var(--radius-3xl));flex-direction:row;display:flex;position:absolute;left:0;right:0}.toast--bottom,.toast--bottom-start,.toast--bottom-end{bottom:0}.toast--top,.toast--top-start,.toast--top-end{top:0}.toast:not([data-frontmost=true]){pointer-events:none;height:var(--front-height);overflow:hidden}.toast:not([data-frontmost=true]) .toast__close-button{pointer-events:none;opacity:0;outline:none}.toast[data-hidden=true]{pointer-events:none;opacity:0;display:flex}.toast:focus-visible{outline-style:var(--tw-outline-style);outline-offset:2px;outline-width:2px;outline-color:var(--focus)}.toast--bottom,.toast--bottom-start,.toast--bottom-end{view-transition-class:toast-bottom}.toast--top,.toast--top-start,.toast--top-end{view-transition-class:toast-top}.toast__content{flex-direction:column;flex-grow:1;align-self:center;align-items:flex-start;height:100%;display:flex}.toast__indicator{padding:var(--spacing);color:var(--overlay-foreground);-webkit-user-select:none;user-select:none;flex-shrink:0;justify-content:center;align-items:center;display:flex}.toast__indicator [data-slot=toast-default-icon]{box-sizing:content-box;width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.toast__indicator [data-slot=spinner],.toast__indicator [data-slot=spinner-icon]{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.toast__title{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-leading:calc(var(--spacing) * 5);line-height:calc(var(--spacing) * 5);--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--overlay-foreground)}.toast__description{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--muted)}.toast__close-button{pointer-events:none;top:calc(var(--spacing) * -1);right:calc(var(--spacing) * -1);width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5);border-color:var(--border);background-color:var(--default);opacity:0;position:absolute}@media(min-width:40rem){.toast__close-button{border-style:var(--tw-border-style);background-color:var(--overlay);border-width:1px}}.toast__close-button{transition:opacity .15s var(--ease-smooth)}.toast__close-button:is([data-reduce-motion=true],[data-reduce-motion=true] *),.toast__close-button:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.toast__close-button:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.toast__close-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.toast__close-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.toast__close-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.toast__close-button [data-slot=close-button-icon]{width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5)}@media(min-width:40rem){.toast__close-button [data-slot=close-button-icon]{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}}@media(hover:hover){.toast__close-button:hover,.toast__close-button[data-hovered=true]{background-color:var(--default)}}.toast[data-frontmost=true]:hover .toast__close-button{pointer-events:auto;opacity:1}.toast__action{margin-top:calc(var(--spacing) * 2)}@media(min-width:40rem){.toast__action{margin-top:0}}.toast--accent .toast__title{color:var(--accent-soft-foreground)}.toast--success .toast__title,.toast--success .toast__indicator{color:var(--success-soft-foreground)}.toast--warning .toast__title,.toast--warning .toast__indicator{color:var(--warning-soft-foreground)}.toast--danger .toast__title,.toast--danger .toast__indicator{color:var(--danger-soft-foreground)}::view-transition-old(*){will-change:translate,opacity}::view-transition-new(*){will-change:translate,opacity}::view-transition-new(.toast-bottom):only-child{animation:.35s toast-slide-bottom-in}::view-transition-old(.toast-bottom):only-child{animation:.35s forwards toast-slide-bottom-out}::view-transition-new(.toast-top):only-child{animation:.35s toast-slide-top-in}::view-transition-old(.toast-top):only-child{animation:.35s forwards toast-slide-top-out}@keyframes toast-slide-bottom-in{0%{opacity:0;translate:0 100%}}@keyframes toast-slide-bottom-out{to{opacity:0;translate:0 100%}}@keyframes toast-slide-top-in{0%{opacity:0;translate:0 -100%}}@keyframes toast-slide-top-out{to{opacity:0;translate:0 -100%}}.checkbox-group{flex-direction:column;display:flex}.checkbox-group [data-slot=checkbox]{margin-top:calc(var(--spacing) * 4)}.checkbox{align-items:flex-start;gap:var(--spacing);--tw-outline-style:none;-webkit-tap-highlight-color:transparent;cursor:var(--cursor-interactive);outline-style:none;flex-direction:column;display:flex}.checkbox>[data-slot=description],.checkbox>[data-slot=field-error]{cursor:default;width:100%;min-width:0;font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));text-wrap:wrap;overflow-wrap:break-word;color:var(--muted);-webkit-user-select:none;user-select:none;padding-inline-start:calc(var(--spacing) * 7)}.checkbox [data-slot=label]{-webkit-user-select:none;user-select:none}.checkbox .checkbox__content [data-slot=label]{cursor:var(--cursor-interactive)}.checkbox[data-disabled=true],.checkbox[data-disabled=true] [data-slot=description],.checkbox[data-disabled=true] [data-slot=field-error]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}:is(.checkbox[data-selected=true],.checkbox[data-indeterminate=true]) .checkbox__indicator{border-color:var(--accent-foreground)}.checkbox [data-slot=checkbox-default-indicator--checkmark]{width:calc(var(--spacing) * 2.5);height:calc(var(--spacing) * 2.5);stroke-width:2.5px;color:var(--accent-foreground);transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.2s;transition-duration:.2s}.checkbox [data-slot=checkbox-default-indicator--checkmark]:is([data-reduce-motion=true],[data-reduce-motion=true] *),.checkbox [data-slot=checkbox-default-indicator--checkmark]:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.checkbox [data-slot=checkbox-default-indicator--checkmark]:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.checkbox [data-slot=checkbox-default-indicator--checkmark]:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.checkbox [data-slot=checkbox-default-indicator--checkmark]:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.checkbox [data-slot=checkbox-default-indicator--checkmark]:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.checkbox[data-selected=true] [data-slot=checkbox-default-indicator--checkmark]{transition:stroke-dashoffset .15s linear 15ms}.checkbox[data-invalid=true][data-selected=true] [data-slot=checkbox-default-indicator--checkmark],.checkbox[data-invalid=true][aria-checked=true] [data-slot=checkbox-default-indicator--checkmark],.checkbox[aria-invalid=true][data-selected=true] [data-slot=checkbox-default-indicator--checkmark],.checkbox[aria-invalid=true][aria-checked=true] [data-slot=checkbox-default-indicator--checkmark]{color:var(--danger-foreground)}.checkbox[data-indeterminate=true] [data-slot=checkbox-default-indicator--indeterminate]{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.checkbox[data-indeterminate=true][data-invalid=true] [data-slot=checkbox-default-indicator--indeterminate],.checkbox[data-indeterminate=true][aria-invalid=true] [data-slot=checkbox-default-indicator--indeterminate]{color:var(--danger-foreground)}.checkbox__control{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4);border-radius:calc(var(--radius) * .75);border-style:var(--tw-border-style);border-width:1px;border-width:var(--border-width-field);border-color:var(--field-border,var(--border));background-color:var(--field-background,var(--default));--tw-shadow:var(--field-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;-webkit-tap-highlight-color:transparent;transition:background-color .2s var(--ease-out),border-color .2s var(--ease-out),transform .1s var(--ease-out);outline-style:none;flex-shrink:0;justify-content:center;align-items:center;display:inline-flex;position:relative;overflow:hidden}.checkbox__control:is([data-reduce-motion=true],[data-reduce-motion=true] *),.checkbox__control:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.checkbox__control:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.checkbox__control:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.checkbox__control:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.checkbox__control:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.checkbox__control{cursor:var(--cursor-interactive)}.checkbox__control:before{pointer-events:none;z-index:0;transform-origin:50%;--tw-scale-x:70%;--tw-scale-y:70%;--tw-scale-z:70%;scale:var(--tw-scale-x) var(--tw-scale-y);border-radius:calc(var(--radius) * .75);background-color:var(--accent);opacity:0;--tw-content:"";content:var(--tw-content);transition:scale .1s var(--ease-linear),opacity .2s var(--ease-linear),background-color .2s var(--ease-out);position:absolute;top:0;right:0;bottom:0;left:0}@media(prefers-reduced-motion:reduce){.checkbox__control:before:not(:is()){transition-property:none}}.checkbox:focus-visible .checkbox__control,.checkbox:has([data-slot=checkbox-content][data-focus-visible=true]) .checkbox__control,.checkbox [data-slot=checkbox-content][data-focus-visible=true] .checkbox__control{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.checkbox:hover .checkbox__control,.checkbox:has([data-slot=checkbox-content][data-hovered=true]) .checkbox__control,.checkbox [data-slot=checkbox-content][data-hovered=true] .checkbox__control{border-color:var(--field-border-hover)}:is(.checkbox:hover .checkbox__control,.checkbox:has([data-slot=checkbox-content][data-hovered=true]) .checkbox__control,.checkbox [data-slot=checkbox-content][data-hovered=true] .checkbox__control):before{background-color:var(--accent-hover)}.checkbox[aria-checked=true] .checkbox__control,.checkbox[data-selected=true] .checkbox__control{color:var(--accent-foreground);border-color:#0000}:is(.checkbox[aria-checked=true] .checkbox__control,.checkbox[data-selected=true] .checkbox__control):before{--tw-scale-x:100%;--tw-scale-y:100%;--tw-scale-z:100%;scale:var(--tw-scale-x) var(--tw-scale-y);opacity:1}.checkbox[data-indeterminate=true] .checkbox__control{background-color:var(--accent);color:var(--accent-foreground)}.checkbox:active[data-indeterminate=true] .checkbox__control,.checkbox[data-pressed=true][data-indeterminate=true] .checkbox__control,.checkbox:has([data-slot=checkbox-content][data-pressed=true])[data-indeterminate=true] .checkbox__control{background-color:var(--accent-hover)}.checkbox[data-invalid=true]:not([aria-checked=true]):not([data-selected=true]):not([data-indeterminate=true]) .checkbox__control,.checkbox[aria-invalid=true]:not([aria-checked=true]):not([data-selected=true]):not([data-indeterminate=true]) .checkbox__control{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}:is(.checkbox[data-invalid=true]:not([aria-checked=true]):not([data-selected=true]):not([data-indeterminate=true]) .checkbox__control,.checkbox[aria-invalid=true]:not([aria-checked=true]):not([data-selected=true]):not([data-indeterminate=true]) .checkbox__control):focus,:is(.checkbox[data-invalid=true]:not([aria-checked=true]):not([data-selected=true]):not([data-indeterminate=true]) .checkbox__control,.checkbox[aria-invalid=true]:not([aria-checked=true]):not([data-selected=true]):not([data-indeterminate=true]) .checkbox__control):focus-visible,:is(.checkbox[data-invalid=true]:not([aria-checked=true]):not([data-selected=true]):not([data-indeterminate=true]) .checkbox__control,.checkbox[aria-invalid=true]:not([aria-checked=true]):not([data-selected=true]):not([data-indeterminate=true]) .checkbox__control)[data-focused=true],:is(.checkbox[data-invalid=true]:not([aria-checked=true]):not([data-selected=true]):not([data-indeterminate=true]) .checkbox__control,.checkbox[aria-invalid=true]:not([aria-checked=true]):not([data-selected=true]):not([data-indeterminate=true]) .checkbox__control)[data-focus-visible=true],:is(.checkbox[data-invalid=true]:not([aria-checked=true]):not([data-selected=true]):not([data-indeterminate=true]) .checkbox__control,.checkbox[aria-invalid=true]:not([aria-checked=true]):not([data-selected=true]):not([data-indeterminate=true]) .checkbox__control):focus-within,:is(.checkbox[data-invalid=true]:not([aria-checked=true]):not([data-selected=true]):not([data-indeterminate=true]) .checkbox__control,.checkbox[aria-invalid=true]:not([aria-checked=true]):not([data-selected=true]):not([data-indeterminate=true]) .checkbox__control)[data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.checkbox[data-invalid=true][aria-checked=true] .checkbox__control,.checkbox[data-invalid=true][data-selected=true] .checkbox__control,.checkbox[aria-invalid=true][aria-checked=true] .checkbox__control,.checkbox[aria-invalid=true][data-selected=true] .checkbox__control{background-color:var(--danger);color:var(--danger-foreground);border-color:#0000}:is(.checkbox[data-invalid=true][aria-checked=true] .checkbox__control,.checkbox[data-invalid=true][data-selected=true] .checkbox__control,.checkbox[aria-invalid=true][aria-checked=true] .checkbox__control,.checkbox[aria-invalid=true][data-selected=true] .checkbox__control):before{--tw-scale-x:100%;--tw-scale-y:100%;--tw-scale-z:100%;scale:var(--tw-scale-x) var(--tw-scale-y);background-color:var(--danger);opacity:1}.checkbox[data-indeterminate=true][aria-invalid=true] .checkbox__control,.checkbox[data-indeterminate=true][data-invalid=true] .checkbox__control{background-color:var(--danger);color:var(--danger-foreground)}.checkbox__indicator{z-index:10;width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3);justify-content:center;align-items:center;display:flex;position:relative}.checkbox__indicator svg{width:100%;height:100%;transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.checkbox--disabled{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.checkbox--secondary .checkbox__control{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);background-color:var(--checkbox-control-bg);--checkbox-control-bg:var(--default)}.checkbox:hover :is(.checkbox--secondary .checkbox__control),.checkbox:has([data-slot=checkbox-content][data-hovered=true]) :is(.checkbox--secondary .checkbox__control),.checkbox [data-slot=checkbox-content][data-hovered=true] :is(.checkbox--secondary .checkbox__control){border-color:var(--field-border-hover)}.checkbox__content{cursor:inherit;align-items:center;gap:calc(var(--spacing) * 3);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--foreground);--tw-outline-style:none;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;outline-style:none;display:inline-flex}.checkbox--secondary:not([aria-checked=true]):not([data-selected=true]):not([data-indeterminate=true]) .checkbox__control{background-color:var(--checkbox-control-bg)}:is(.checkbox--secondary[aria-checked=true] .checkbox__control,.checkbox--secondary[data-selected=true] .checkbox__control):before,.checkbox--secondary[data-indeterminate=true] .checkbox__control,.checkbox--secondary[data-indeterminate=true] .checkbox__control:before{background-color:var(--accent)}.fieldset{gap:calc(var(--spacing) * 6);flex-direction:column;flex:1 1 0;display:flex}.fieldset__legend{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--foreground)}.fieldset__field_group{width:100%}:where(.fieldset__field_group>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}.fieldset__actions{align-items:center;gap:calc(var(--spacing) * 2);padding-top:var(--spacing);display:flex}.input-otp{align-items:center;gap:calc(var(--spacing) * 2);display:flex;position:relative}.input-otp[data-disabled=true]{cursor:not-allowed;opacity:.5}.input-otp__group{align-items:center;gap:calc(var(--spacing) * 2);display:flex}.input-otp__slot{height:calc(var(--spacing) * 10);width:calc(var(--spacing) * 9.5);border-style:var(--tw-border-style);background-color:var(--field-background,var(--default));color:var(--field-foreground,var(--foreground));--tw-shadow:var(--field-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);border-radius:var(--field-radius,calc(var(--radius) * 1.5));font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);--tw-outline-style:none;border-width:1px;border-width:var(--border-width-field);border-color:var(--field-border);transition:background-color .15s var(--ease-smooth),border-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out);outline-style:none;flex:1;justify-content:center;align-items:center;display:flex;position:relative}.input-otp__slot:is([data-reduce-motion=true],[data-reduce-motion=true] *),.input-otp__slot:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.input-otp__slot:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.input-otp__slot:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.input-otp__slot:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.input-otp__slot:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}@media(hover:hover){.input-otp__slot:hover,.input-otp__slot[data-hovered=true]{background-color:var(--field-hover);border-color:var(--field-border-hover)}}.input-otp__slot[data-active=true]{z-index:10;background-color:var(--field-focus);--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-outline-style:none;--tw-ring-offset-width:0px;outline-style:none}.input-otp__slot[data-filled=true]{background-color:var(--field-focus)}.input-otp__slot[data-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.input-otp__slot[data-invalid=true]{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}.input-otp__slot[data-invalid=true]:focus,.input-otp__slot[data-invalid=true]:focus-visible,.input-otp__slot[data-invalid=true][data-focused=true],.input-otp__slot[data-invalid=true][data-focus-visible=true],.input-otp__slot[data-invalid=true]:focus-within,.input-otp__slot[data-invalid=true][data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.input-otp__slot[data-invalid=true]{background-color:var(--field-focus)}.input-otp__slot-value{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height));--tw-leading:calc(var(--spacing) * 6);line-height:calc(var(--spacing) * 6);--tw-tracking:-.27px;letter-spacing:-.27px;animation:slot-value-in .25s var(--ease-smooth) both;transform-origin:bottom}.input-otp__slot-value:is([data-reduce-motion=true],[data-reduce-motion=true] *),.input-otp__slot-value:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.input-otp__slot-value:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{animation:none}@media(prefers-reduced-motion:reduce){.input-otp__slot-value:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.input-otp__slot-value:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.input-otp__slot-value:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{animation:none}}.input-otp__caret{height:calc(var(--spacing) * 4);border-radius:calc(var(--radius) * .5);background-color:var(--field-placeholder,var(--muted));width:2px;animation:1.2s ease-out infinite caret-blink;position:absolute}.input-otp__separator{border-radius:calc(var(--radius) * .5);background-color:var(--separator);flex-shrink:0;width:6px;height:2px}.input-otp--secondary .input-otp__slot{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);background-color:var(--input-otp-slot-bg);--input-otp-slot-bg:var(--default);--input-otp-slot-bg-hover:var(--default-hover);--input-otp-slot-bg-focus:var(--default)}@media(hover:hover){.input-otp--secondary .input-otp__slot:hover,.input-otp--secondary .input-otp__slot[data-hovered=true]{background-color:var(--input-otp-slot-bg-hover)}}.input-otp--secondary .input-otp__slot[data-active=true],.input-otp--secondary .input-otp__slot[data-filled=true]{background-color:var(--input-otp-slot-bg-focus)}@keyframes slot-value-in{0%{opacity:0;transform:translateY(8px)scale(.8)}to{opacity:1;transform:translateY(0)scale(1)}}.input{border-radius:var(--field-radius,calc(var(--radius) * 1.5));border-style:var(--tw-border-style);background-color:var(--field-background,var(--default));padding-inline:calc(var(--spacing) * 3);padding-block:calc(var(--spacing) * 2);font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));color:var(--field-foreground,var(--foreground));--tw-shadow:var(--field-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;border-width:1px;outline-style:none}.input::placeholder{color:var(--field-placeholder,var(--muted))}@media(min-width:40rem){.input{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}.input{border-width:var(--border-width-field);border-color:var(--field-border);transition:background-color .15s var(--ease-smooth),border-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out)}.input:is([data-reduce-motion=true],[data-reduce-motion=true] *),.input:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.input:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.input:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.input:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.input:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}@media(hover:hover){.input:hover:not(:focus):not(:focus-visible),.input[data-hovered=true]:not([data-focused=true]):not([data-focus-visible=true]){background-color:var(--field-hover);border-color:var(--field-border-hover)}}.input:focus,.input[data-focused=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-outline-style:none;--tw-ring-offset-width:0px;border-color:var(--field-border-focus);background-color:var(--field-focus);outline-style:none}.input[data-invalid=true]{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}.input[data-invalid=true]:focus,.input[data-invalid=true]:focus-visible,.input[data-invalid=true][data-focused=true],.input[data-invalid=true][data-focus-visible=true],.input[data-invalid=true]:focus-within,.input[data-invalid=true][data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.input[data-invalid=true]{background-color:var(--field-focus)}.input:disabled,.input[data-disabled=true],.input[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.input--secondary{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);background-color:var(--input-bg);--input-bg:var(--default);--input-bg-hover:var(--default-hover);--input-bg-focus:var(--default)}@media(hover:hover){.input--secondary:hover:not(:focus):not(:focus-visible),.input--secondary[data-hovered=true]:not([data-focus-visible=true]):not([data-focused=true]){background-color:var(--input-bg-hover)}}.input--secondary:focus,.input--secondary[data-focused=true]{background-color:var(--input-bg-focus)}.input--secondary[data-invalid=true]{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}.input--secondary[data-invalid=true]:focus,.input--secondary[data-invalid=true]:focus-visible,.input--secondary[data-invalid=true][data-focused=true],.input--secondary[data-invalid=true][data-focus-visible=true],.input--secondary[data-invalid=true]:focus-within,.input--secondary[data-invalid=true][data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.input--secondary[data-invalid=true]{background-color:var(--input-bg-focus)}.input--full-width{width:100%}.input-group{min-height:calc(var(--spacing) * 9);border-radius:var(--field-radius,calc(var(--radius) * 1.5));border-style:var(--tw-border-style);background-color:var(--field-background,var(--default));font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--field-foreground,var(--foreground));--tw-shadow:var(--field-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;border-width:1px;border-width:var(--border-width-field);border-color:var(--field-border);outline-style:none;align-items:center;display:inline-flex}.input-group:has([data-slot=input-group-textarea]){align-items:flex-start;height:auto}.input-group{transition:background-color .15s var(--ease-smooth),border-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out)}.input-group:is([data-reduce-motion=true],[data-reduce-motion=true] *),.input-group:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.input-group:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.input-group:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.input-group:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.input-group:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}@media(hover:hover){.input-group:hover:not(:focus-within),.input-group[data-hovered=true]:not([data-focus-within=true]){background-color:var(--field-hover);border-color:var(--field-border-hover)}}.input-group:has([data-slot=input-group-input]:focus),.input-group:has([data-slot=input-group-textarea]:focus){--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-outline-style:none;--tw-ring-offset-width:0px;border-color:var(--field-border-focus);background-color:var(--field-focus);outline-style:none}.input-group[data-invalid=true]{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}.input-group[data-invalid=true]:focus,.input-group[data-invalid=true]:focus-visible,.input-group[data-invalid=true][data-focused=true],.input-group[data-invalid=true][data-focus-visible=true],.input-group[data-invalid=true]:focus-within,.input-group[data-invalid=true][data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.input-group[data-invalid=true]{background-color:var(--field-focus);border-color:var(--color-field-border-invalid)}.input-group[data-disabled=true],.input-group[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}:-webkit-any(.input-group:has([data-slot=input-group-input]:-webkit-autofill),.input-group:has([data-slot=input-group-input]:autofill)){background-color:var(--field-focus);border-color:var(--field-border-focus)}:is(.input-group:has([data-slot=input-group-input]:autofill)){background-color:var(--field-focus);border-color:var(--field-border-focus)}.input-group__input{border-style:var(--tw-border-style);padding-inline:calc(var(--spacing) * 3);padding-block:calc(var(--spacing) * 2);font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;background-color:#0000;border-width:0;border-radius:0;outline-style:none;flex:1}.input-group__input::placeholder{color:var(--field-placeholder,var(--muted))}@media(min-width:40rem){.input-group__input{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}.input-group:has([data-slot=input-group-prefix]) .input-group__input{border-top-left-radius:0;border-bottom-left-radius:0;padding-left:0}.input-group:has([data-slot=input-group-suffix]) .input-group__input{border-top-right-radius:0;border-bottom-right-radius:0;padding-right:0}.input-group__input:focus,.input-group__input:focus-visible{--tw-outline-style:none;outline-style:none}.input-group__input:-webkit-autofill{-webkit-text-fill-color:var(--field-foreground);caret-color:var(--field-foreground);transition:background-color 9999s ease-in-out;box-shadow:inset 0 0 0 1000px #0000}.input-group__input:-webkit-autofill:hover{-webkit-text-fill-color:var(--field-foreground);caret-color:var(--field-foreground);transition:background-color 9999s ease-in-out;box-shadow:inset 0 0 0 1000px #0000}.input-group__input:-webkit-autofill:focus{-webkit-text-fill-color:var(--field-foreground);caret-color:var(--field-foreground);transition:background-color 9999s ease-in-out;box-shadow:inset 0 0 0 1000px #0000}.input-group__input:-webkit-autofill:active{-webkit-text-fill-color:var(--field-foreground);caret-color:var(--field-foreground);transition:background-color 9999s ease-in-out;box-shadow:inset 0 0 0 1000px #0000}.input-group__input:autofill{-webkit-text-fill-color:var(--field-foreground);caret-color:var(--field-foreground);transition:background-color 9999s ease-in-out;box-shadow:inset 0 0 0 1000px #0000}.input-group__input[data-slot=input-group-textarea]{resize:vertical;min-height:38px}.input-group__prefix{border-top-left-radius:var(--field-radius,calc(var(--radius) * 1.5));border-bottom-left-radius:var(--field-radius,calc(var(--radius) * 1.5));height:100%;padding-inline:calc(var(--spacing) * 3);color:var(--field-placeholder,var(--muted));border-width:var(--border-width-field);border-color:var(--field-border);border-style:solid;border-right-color:var(--field-border);background-color:#0000;border-top:none;border-bottom:none;border-left:none;border-top-right-radius:0;border-bottom-right-radius:0;justify-content:center;align-items:center;display:flex}.input-group:has([data-slot=input-group-textarea]) .input-group__prefix{align-items:flex-start;padding-top:.5rem}.input-group__prefix{transition:background-color .15s var(--ease-smooth),border-color .15s var(--ease-smooth)}.input-group__prefix:is([data-reduce-motion=true],[data-reduce-motion=true] *),.input-group__prefix:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.input-group__prefix:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.input-group__prefix:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.input-group__prefix:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.input-group__prefix:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.input-group__suffix{border-top-left-radius:0;border-bottom-left-radius:0;border-top-right-radius:var(--field-radius,calc(var(--radius) * 1.5));border-bottom-right-radius:var(--field-radius,calc(var(--radius) * 1.5));height:100%;padding-inline:calc(var(--spacing) * 3);color:var(--field-placeholder,var(--muted));border-width:var(--border-width-field);border-color:var(--field-border);border-style:solid;border-left-color:var(--field-border);background-color:#0000;border-top:none;border-bottom:none;border-right:none;justify-content:center;align-items:center;display:flex}.input-group:has([data-slot=input-group-textarea]) .input-group__suffix{align-items:flex-start;padding-top:.5rem}.input-group__suffix{transition:background-color .15s var(--ease-smooth),border-color .15s var(--ease-smooth)}.input-group__suffix:is([data-reduce-motion=true],[data-reduce-motion=true] *),.input-group__suffix:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.input-group__suffix:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.input-group__suffix:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.input-group__suffix:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.input-group__suffix:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.input-group--secondary{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);background-color:var(--input-group-bg);--input-group-bg:var(--default);--input-group-bg-hover:var(--default-hover);--input-group-bg-focus:var(--default)}@media(hover:hover){.input-group--secondary:hover:not(:focus-within),.input-group--secondary[data-hovered=true]:not([data-focus-within=true]){background-color:var(--input-group-bg-hover)}}.input-group--secondary:has([data-slot=input-group-input]:focus),.input-group--secondary:has([data-slot=input-group-textarea]:focus){background-color:var(--input-group-bg-focus)}.input-group--secondary[data-invalid=true]{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}.input-group--secondary[data-invalid=true]:focus,.input-group--secondary[data-invalid=true]:focus-visible,.input-group--secondary[data-invalid=true][data-focused=true],.input-group--secondary[data-invalid=true][data-focus-visible=true],.input-group--secondary[data-invalid=true]:focus-within,.input-group--secondary[data-invalid=true][data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.input-group--secondary[data-invalid=true]{border-color:var(--color-field-border-invalid);background-color:var(--input-group-bg-focus)}.input-group--secondary [data-slot=input-group-input],.input-group--secondary [data-slot=input-group-textarea]{background-color:#0000}.input-group--full-width{width:100%}.number-field{gap:var(--spacing);flex-direction:column;display:flex}:is(.number-field[data-invalid=true],.number-field[aria-invalid=true]) [data-slot=description]{display:none}.number-field [data-slot=label]{width:fit-content}.number-field__group{height:calc(var(--spacing) * 9);border-radius:var(--field-radius,calc(var(--radius) * 1.5));border-style:var(--tw-border-style);background-color:var(--field-background,var(--default));font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--field-foreground,var(--foreground));--tw-shadow:var(--field-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;border-width:1px;border-width:var(--border-width-field);border-color:var(--field-border);transition:background-color .15s var(--ease-smooth),border-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out);outline-style:none;grid-template-columns:40px 1fr 40px;align-items:center;display:grid;overflow:hidden}.number-field__group:is([data-reduce-motion=true],[data-reduce-motion=true] *),.number-field__group:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.number-field__group:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.number-field__group:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.number-field__group:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.number-field__group:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}@media(hover:hover){.number-field__group:hover:not(:focus-within),.number-field__group[data-hovered=true]:not([data-focus-within=true]){background-color:var(--field-hover);border-color:var(--field-border-hover)}}.number-field__group[data-focus-within=true],.number-field__group:focus-within{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-outline-style:none;--tw-ring-offset-width:0px;border-color:var(--field-border-focus);background-color:var(--field-focus);outline-style:none}.number-field__group[data-invalid=true]{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}.number-field__group[data-invalid=true]:focus,.number-field__group[data-invalid=true]:focus-visible,.number-field__group[data-invalid=true][data-focused=true],.number-field__group[data-invalid=true][data-focus-visible=true],.number-field__group[data-invalid=true]:focus-within,.number-field__group[data-invalid=true][data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.number-field__group[data-invalid=true]{background-color:var(--field-focus);border-color:var(--color-field-border-invalid)}.number-field__group[data-disabled=true],.number-field__group[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}:-webkit-any(.number-field__group:has([data-slot=number-field-input]:-webkit-autofill),.number-field__group:has([data-slot=number-field-input]:autofill)){background-color:var(--field-focus);border-color:var(--field-border-focus)}:is(.number-field__group:has([data-slot=number-field-input]:autofill)){background-color:var(--field-focus);border-color:var(--field-border-focus)}.number-field__input{border-style:var(--tw-border-style);min-width:0;padding-inline:calc(var(--spacing) * 3);padding-block:calc(var(--spacing) * 2);font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,);--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;background-color:#0000;border-width:0;border-radius:0;outline-style:none}@media(min-width:40rem){.number-field__input{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}.number-field__group:has([slot=decrement]) .number-field__input{border-top-left-radius:0;border-bottom-left-radius:0}.number-field__group:has([slot=increment]) .number-field__input{border-top-right-radius:0;border-bottom-right-radius:0}.number-field__input:focus,.number-field__input:focus-visible{--tw-outline-style:none;outline-style:none}.number-field__input:-webkit-autofill{-webkit-text-fill-color:var(--field-foreground);caret-color:var(--field-foreground);transition:background-color 9999s ease-in-out;box-shadow:inset 0 0 0 1000px #0000}.number-field__input:-webkit-autofill:hover{-webkit-text-fill-color:var(--field-foreground);caret-color:var(--field-foreground);transition:background-color 9999s ease-in-out;box-shadow:inset 0 0 0 1000px #0000}.number-field__input:-webkit-autofill:focus{-webkit-text-fill-color:var(--field-foreground);caret-color:var(--field-foreground);transition:background-color 9999s ease-in-out;box-shadow:inset 0 0 0 1000px #0000}.number-field__input:-webkit-autofill:active{-webkit-text-fill-color:var(--field-foreground);caret-color:var(--field-foreground);transition:background-color 9999s ease-in-out;box-shadow:inset 0 0 0 1000px #0000}.number-field__input:autofill{-webkit-text-fill-color:var(--field-foreground);caret-color:var(--field-foreground);transition:background-color 9999s ease-in-out;box-shadow:inset 0 0 0 1000px #0000}.number-field__increment-button,.number-field__decrement-button{height:100%;width:calc(var(--spacing) * 10);color:var(--field-foreground,var(--foreground));--tw-outline-style:none;border-width:var(--border-width-field);border-color:var(--field-border);transition:background-color .15s var(--ease-smooth),border-color .15s var(--ease-smooth);background-color:#0000;border-style:solid;border-radius:0;outline-style:none;justify-content:center;align-items:center;display:flex}:is(.number-field__increment-button,.number-field__decrement-button):is([data-reduce-motion=true],[data-reduce-motion=true] *),:is(.number-field__increment-button,.number-field__decrement-button):is([data-reduce-motion=true],[data-reduce-motion=true] *):before,:is(.number-field__increment-button,.number-field__decrement-button):is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){:is(.number-field__increment-button,.number-field__decrement-button):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),:is(.number-field__increment-button,.number-field__decrement-button):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,:is(.number-field__increment-button,.number-field__decrement-button):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.number-field__increment-button,.number-field__decrement-button{cursor:var(--cursor-interactive)}:is(.number-field__increment-button,.number-field__decrement-button):active,:is(.number-field__increment-button,.number-field__decrement-button)[data-pressed=true]{background-color:var(--field-foreground,var(--foreground))}@supports (color:color-mix(in lab,red,red)){:is(.number-field__increment-button,.number-field__decrement-button):active,:is(.number-field__increment-button,.number-field__decrement-button)[data-pressed=true]{background-color:color-mix(in oklab,var(--field-foreground,var(--foreground)) 10%,transparent)}}:is(.number-field__increment-button,.number-field__decrement-button):active,:is(.number-field__increment-button,.number-field__decrement-button)[data-pressed=true]{transform:scale(.97)}:is(.number-field__increment-button,.number-field__decrement-button):disabled,:is(.number-field__increment-button,.number-field__decrement-button)[data-disabled=true],:is(.number-field__increment-button,.number-field__decrement-button)[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}:is(.number-field__increment-button,.number-field__decrement-button) [data-slot=number-field-increment-button-icon],:is(.number-field__increment-button,.number-field__decrement-button) [data-slot=number-field-decrement-button-icon]{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.number-field__increment-button{border-top-left-radius:0;border-bottom-left-radius:0;border-top-right-radius:var(--field-radius,calc(var(--radius) * 1.5));border-bottom-right-radius:var(--field-radius,calc(var(--radius) * 1.5));border-left-style:var(--tw-border-style);border-left-width:1px;border-color:var(--field-placeholder,var(--muted))}@supports (color:color-mix(in lab,red,red)){.number-field__increment-button{border-color:color-mix(in oklab,var(--field-placeholder,var(--muted)) 15%,transparent)}}.number-field__decrement-button{border-top-left-radius:var(--field-radius,calc(var(--radius) * 1.5));border-bottom-left-radius:var(--field-radius,calc(var(--radius) * 1.5));border-right-style:var(--tw-border-style);border-right-width:1px;border-color:var(--field-placeholder,var(--muted));border-top-right-radius:0;border-bottom-right-radius:0}@supports (color:color-mix(in lab,red,red)){.number-field__decrement-button{border-color:color-mix(in oklab,var(--field-placeholder,var(--muted)) 15%,transparent)}}.number-field--secondary .number-field__group{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);background-color:var(--number-field-group-bg);--number-field-group-bg:var(--default);--number-field-group-bg-hover:var(--default-hover);--number-field-group-bg-focus:var(--default)}@media(hover:hover){.number-field--secondary .number-field__group:hover:not(:focus-within),.number-field--secondary .number-field__group[data-hovered=true]:not([data-focus-within=true]){background-color:var(--number-field-group-bg-hover)}}.number-field--secondary .number-field__group:focus-within,.number-field--secondary .number-field__group[data-focus-within=true]{background-color:var(--number-field-group-bg-focus)}.number-field--secondary .number-field__group[data-invalid=true]{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}.number-field--secondary .number-field__group[data-invalid=true]:focus,.number-field--secondary .number-field__group[data-invalid=true]:focus-visible,.number-field--secondary .number-field__group[data-invalid=true][data-focused=true],.number-field--secondary .number-field__group[data-invalid=true][data-focus-visible=true],.number-field--secondary .number-field__group[data-invalid=true]:focus-within,.number-field--secondary .number-field__group[data-invalid=true][data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.number-field--secondary .number-field__group[data-invalid=true]{border-color:var(--color-field-border-invalid);background-color:var(--number-field-group-bg-focus)}.number-field--secondary .number-field__group [data-slot=number-field-input]{background-color:#0000}.number-field--full-width,.number-field__group--full-width{width:100%}.radio-group{flex-direction:column;display:flex}.radio-group[data-orientation=vertical] [data-slot=radio]{margin-top:calc(var(--spacing) * 4)}.radio-group[data-orientation=horizontal]{gap:calc(var(--spacing) * 4);flex-flow:wrap}.radio-group--secondary .radio__control{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);background-color:var(--radio-control-bg);--radio-control-bg:var(--default);--radio-control-bg-hover:var(--default-hover)}.radio:has([data-slot=radio-content][data-hovered=true]) :is(.radio-group--secondary .radio__control),.radio [data-slot=radio-content][data-hovered=true] :is(.radio-group--secondary .radio__control){border-color:var(--field-border-hover)}.radio:not([data-selected]):not(:has(input:checked)) :is(.radio-group--secondary .radio__control) .radio__indicator:empty:before{background-color:var(--radio-control-bg)}.radio:has([data-slot=radio-content][data-hovered=true]):not([data-selected]):not(:has(input:checked)) :is(.radio-group--secondary .radio__control) .radio__indicator:empty:before{background-color:var(--radio-control-bg-hover)}.radio{align-items:flex-start;gap:var(--spacing);--tw-outline-style:none;-webkit-tap-highlight-color:transparent;cursor:var(--cursor-interactive);outline-style:none;flex-direction:column;display:flex}.radio [data-slot=label]{-webkit-user-select:none;user-select:none}.radio .radio__content [data-slot=label]{cursor:var(--cursor-interactive)}.radio>[data-slot=description],.radio>[data-slot=field-error]{cursor:default;width:100%;min-width:0;font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));text-wrap:wrap;overflow-wrap:break-word;color:var(--muted);-webkit-user-select:none;user-select:none;padding-inline-start:calc(var(--spacing) * 7)}.radio:disabled,.radio[data-disabled=true],.radio[aria-disabled=true],:is(.radio:disabled,.radio[data-disabled=true],.radio[aria-disabled=true]) [data-slot=description],:is(.radio:disabled,.radio[data-disabled=true],.radio[aria-disabled=true]) [data-slot=field-error]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.radio__content{cursor:inherit;align-items:center;gap:calc(var(--spacing) * 3);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--foreground);--tw-outline-style:none;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;outline-style:none;display:inline-flex}.radio__control{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4);border-radius:calc(var(--radius) * 1);border-style:var(--tw-border-style);border-width:1px;border-width:var(--border-width-field);border-color:var(--field-border,var(--border));background-color:var(--field-background,var(--default));--tw-shadow:var(--field-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;-webkit-tap-highlight-color:transparent;transition:background-color .2s var(--ease-out),border-color .2s var(--ease-out),transform .1s var(--ease-out);outline-style:none;flex-shrink:0;justify-content:center;align-items:center;display:inline-flex;position:relative}.radio__control:is([data-reduce-motion=true],[data-reduce-motion=true] *),.radio__control:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.radio__control:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.radio__control:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.radio__control:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.radio__control:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.radio__control{cursor:var(--cursor-interactive)}.radio:has([data-slot=radio-content][data-focus-visible=true]) .radio__control,.radio [data-slot=radio-content][data-focus-visible=true] .radio__control{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.radio:has([data-slot=radio-content][data-hovered=true]) .radio__control,.radio [data-slot=radio-content][data-hovered=true] .radio__control{border-color:var(--field-border-hover)}.radio:has([data-slot=radio-content][data-hovered=true]):not([data-selected]):not(:has(input:checked)) .radio__control .radio__indicator:empty:before{background-color:var(--field-hover)}.radio:has([data-slot=radio-content][data-pressed=true]) .radio__control,.radio [data-slot=radio-content][data-pressed=true] .radio__control{--tw-scale-x:95%;--tw-scale-y:95%;--tw-scale-z:95%;scale:var(--tw-scale-x) var(--tw-scale-y)}.radio[data-selected] .radio__control,.radio:has([data-slot=radio-content][aria-checked=true]) .radio__control,.radio:has(input:checked) .radio__control{background-color:var(--accent);border-color:#0000}.radio[data-selected]:has([data-slot=radio-content][data-pressed=true]) .radio__control,.radio:has([data-slot=radio-content][data-pressed=true][aria-checked=true]) .radio__control,.radio:has(input:checked):has([data-slot=radio-content][data-pressed=true]) .radio__control{background-color:var(--accent-hover)}.radio[data-invalid=true] .radio__control,.radio[aria-invalid=true] .radio__control{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}:is(.radio[data-invalid=true] .radio__control,.radio[aria-invalid=true] .radio__control):focus,:is(.radio[data-invalid=true] .radio__control,.radio[aria-invalid=true] .radio__control):focus-visible,:is(.radio[data-invalid=true] .radio__control,.radio[aria-invalid=true] .radio__control)[data-focused=true],:is(.radio[data-invalid=true] .radio__control,.radio[aria-invalid=true] .radio__control)[data-focus-visible=true],:is(.radio[data-invalid=true] .radio__control,.radio[aria-invalid=true] .radio__control):focus-within,:is(.radio[data-invalid=true] .radio__control,.radio[aria-invalid=true] .radio__control)[data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.radio[data-invalid=true][data-selected] .radio__control,.radio[aria-invalid=true][data-selected] .radio__control,.radio[data-invalid=true]:has(input:checked) .radio__control,.radio[aria-invalid=true]:has(input:checked) .radio__control{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}:is(.radio[data-invalid=true][data-selected] .radio__control,.radio[aria-invalid=true][data-selected] .radio__control,.radio[data-invalid=true]:has(input:checked) .radio__control,.radio[aria-invalid=true]:has(input:checked) .radio__control):focus,:is(.radio[data-invalid=true][data-selected] .radio__control,.radio[aria-invalid=true][data-selected] .radio__control,.radio[data-invalid=true]:has(input:checked) .radio__control,.radio[aria-invalid=true]:has(input:checked) .radio__control):focus-visible,:is(.radio[data-invalid=true][data-selected] .radio__control,.radio[aria-invalid=true][data-selected] .radio__control,.radio[data-invalid=true]:has(input:checked) .radio__control,.radio[aria-invalid=true]:has(input:checked) .radio__control)[data-focused=true],:is(.radio[data-invalid=true][data-selected] .radio__control,.radio[aria-invalid=true][data-selected] .radio__control,.radio[data-invalid=true]:has(input:checked) .radio__control,.radio[aria-invalid=true]:has(input:checked) .radio__control)[data-focus-visible=true],:is(.radio[data-invalid=true][data-selected] .radio__control,.radio[aria-invalid=true][data-selected] .radio__control,.radio[data-invalid=true]:has(input:checked) .radio__control,.radio[aria-invalid=true]:has(input:checked) .radio__control):focus-within,:is(.radio[data-invalid=true][data-selected] .radio__control,.radio[aria-invalid=true][data-selected] .radio__control,.radio[data-invalid=true]:has(input:checked) .radio__control,.radio[aria-invalid=true]:has(input:checked) .radio__control)[data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.radio__indicator{pointer-events:none;justify-content:center;align-items:center;display:flex;position:absolute;top:0;right:0;bottom:0;left:0}.radio__indicator:empty:before{content:"";border-radius:calc(var(--radius) * 1);background-color:var(--field-background,var(--default));width:100%;height:100%;transition:scale .2s var(--ease-out),background-color .2s var(--ease-out);scale:1}@media(prefers-reduced-motion:reduce){.radio__indicator:empty:before:not(:is()){transition-property:none}}.radio[data-selected] .radio__indicator:empty:before,.radio:has([data-slot=radio-content][aria-checked=true]) .radio__indicator:empty:before,.radio:has(input:checked) .radio__indicator:empty:before{background-color:var(--accent-foreground);scale:.4286}.radio[data-selected]:has([data-slot=radio-content][data-pressed=true]) .radio__indicator:empty:before,.radio:has([data-slot=radio-content][data-pressed=true][aria-checked=true]) .radio__indicator:empty:before,.radio:has(input:checked):has([data-slot=radio-content][data-pressed=true]) .radio__indicator:empty:before{scale:.5714}.radio--disabled{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.textfield{gap:var(--spacing);flex-direction:column;display:flex}:is(.textfield[data-invalid=true],.textfield[aria-invalid=true]) [data-slot=description]{display:none}.textfield--full-width,.textfield--full-width [data-slot=input],.textfield--full-width [data-slot=textarea]{width:100%}.search-field{gap:var(--spacing);flex-direction:column;display:flex}:is(.search-field[data-invalid=true],.search-field[aria-invalid=true]) [data-slot=description]{display:none}.search-field [data-slot=label]{width:fit-content}.search-field[data-empty=true] [data-slot=search-field-clear-button]{pointer-events:none;opacity:0}.search-field__group{height:calc(var(--spacing) * 9);border-radius:var(--field-radius,calc(var(--radius) * 1.5));border-style:var(--tw-border-style);background-color:var(--field-background,var(--default));font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--field-foreground,var(--foreground));--tw-shadow:var(--field-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;border-width:1px;border-width:var(--border-width-field);border-color:var(--field-border);transition:background-color .15s var(--ease-smooth),border-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out);outline-style:none;align-items:center;display:inline-flex;position:relative;overflow:hidden}.search-field__group:is([data-reduce-motion=true],[data-reduce-motion=true] *),.search-field__group:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.search-field__group:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.search-field__group:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.search-field__group:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.search-field__group:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}@media(hover:hover){.search-field__group:hover:not(:focus-within),.search-field__group[data-hovered=true]:not([data-focus-within=true]){background-color:var(--field-hover);border-color:var(--field-border-hover)}}.search-field__group[data-focus-within=true],.search-field__group:focus-within{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-outline-style:none;--tw-ring-offset-width:0px;outline-style:none}.search-field__group[data-invalid=true]{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}.search-field__group[data-invalid=true]:focus,.search-field__group[data-invalid=true]:focus-visible,.search-field__group[data-invalid=true][data-focused=true],.search-field__group[data-invalid=true][data-focus-visible=true],.search-field__group[data-invalid=true]:focus-within,.search-field__group[data-invalid=true][data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.search-field__group[data-invalid=true]{background-color:var(--field-focus);border-color:var(--color-field-border-invalid)}.search-field__group[data-disabled=true],.search-field__group[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}:-webkit-any(.search-field__group:has([data-slot=search-field-input]:-webkit-autofill),.search-field__group:has([data-slot=search-field-input]:autofill)){background-color:var(--field-focus);border-color:var(--field-border-focus)}:is(.search-field__group:has([data-slot=search-field-input]:autofill)){background-color:var(--field-focus);border-color:var(--field-border-focus)}.search-field__input{border-style:var(--tw-border-style);padding-inline:calc(var(--spacing) * 3);padding-block:calc(var(--spacing) * 2);font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;background-color:#0000;border-width:0;border-radius:0;outline-style:none;flex:1}@media(min-width:40rem){.search-field__input{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}.search-field__input::-webkit-search-cancel-button{-webkit-appearance:none;-moz-appearance:none;appearance:none}.search-field__input::-webkit-search-decoration{-webkit-appearance:none;-moz-appearance:none;appearance:none}.search-field__group:has([data-slot=search-field-search-icon]) .search-field__input{padding-left:calc(var(--spacing) * 2);border-top-left-radius:0;border-bottom-left-radius:0}.search-field__group:has([slot=clear]) .search-field__input{padding-right:calc(var(--spacing) * 2);border-top-right-radius:0;border-bottom-right-radius:0}.search-field__input:focus,.search-field__input:focus-visible{--tw-outline-style:none;outline-style:none}.search-field__input:-webkit-autofill{-webkit-text-fill-color:var(--field-foreground);caret-color:var(--field-foreground);transition:background-color 9999s ease-in-out;box-shadow:inset 0 0 0 1000px #0000}.search-field__input:-webkit-autofill:hover{-webkit-text-fill-color:var(--field-foreground);caret-color:var(--field-foreground);transition:background-color 9999s ease-in-out;box-shadow:inset 0 0 0 1000px #0000}.search-field__input:-webkit-autofill:focus{-webkit-text-fill-color:var(--field-foreground);caret-color:var(--field-foreground);transition:background-color 9999s ease-in-out;box-shadow:inset 0 0 0 1000px #0000}.search-field__input:-webkit-autofill:active{-webkit-text-fill-color:var(--field-foreground);caret-color:var(--field-foreground);transition:background-color 9999s ease-in-out;box-shadow:inset 0 0 0 1000px #0000}.search-field__input:autofill{-webkit-text-fill-color:var(--field-foreground);caret-color:var(--field-foreground);transition:background-color 9999s ease-in-out;box-shadow:inset 0 0 0 1000px #0000}.search-field__search-icon{pointer-events:none;color:var(--field-placeholder,var(--muted));margin-right:0;margin-left:calc(var(--spacing) * 3);width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4);flex-shrink:0}.search-field__clear-button{margin-right:calc(var(--spacing) * 2);width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5);flex-shrink:0}.search-field__clear-button [data-slot=close-button-icon]{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.search-field--secondary .search-field__group{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);background-color:var(--search-field-group-bg);--search-field-group-bg:var(--default);--search-field-group-bg-hover:var(--default-hover);--search-field-group-bg-focus:var(--default)}@media(hover:hover){.search-field--secondary .search-field__group:hover:not(:focus-within),.search-field--secondary .search-field__group[data-hovered=true]:not([data-focus-within=true]){background-color:var(--search-field-group-bg-hover)}}.search-field--secondary .search-field__group:focus-within,.search-field--secondary .search-field__group[data-focus-within=true]{background-color:var(--search-field-group-bg-focus)}.search-field--secondary .search-field__group[data-invalid=true]{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}.search-field--secondary .search-field__group[data-invalid=true]:focus,.search-field--secondary .search-field__group[data-invalid=true]:focus-visible,.search-field--secondary .search-field__group[data-invalid=true][data-focused=true],.search-field--secondary .search-field__group[data-invalid=true][data-focus-visible=true],.search-field--secondary .search-field__group[data-invalid=true]:focus-within,.search-field--secondary .search-field__group[data-invalid=true][data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.search-field--secondary .search-field__group[data-invalid=true]{border-color:var(--color-field-border-invalid);background-color:var(--search-field-group-bg-focus)}.search-field--secondary .search-field__group [data-slot=search-field-input]{background-color:#0000}.search-field--full-width,.search-field__group--full-width{width:100%}.textarea{border-radius:var(--field-radius,calc(var(--radius) * 1.5));border-style:var(--tw-border-style);background-color:var(--field-background,var(--default));padding-inline:calc(var(--spacing) * 3);padding-block:calc(var(--spacing) * 2);font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));color:var(--field-foreground,var(--foreground));--tw-shadow:var(--field-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;border-width:1px;outline-style:none}.textarea::placeholder{color:var(--field-placeholder,var(--muted))}@media(min-width:40rem){.textarea{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}.textarea{border-width:var(--border-width-field);border-color:var(--field-border);min-height:38px;transition:background-color .15s var(--ease-smooth),border-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out)}.textarea:is([data-reduce-motion=true],[data-reduce-motion=true] *),.textarea:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.textarea:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.textarea:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.textarea:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.textarea:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}@media(hover:hover){.textarea:hover:not(:focus):not(:focus-visible),.textarea[data-hovered=true]:not([data-focused=true]):not([data-focus-visible=true]){background-color:var(--field-hover);border-color:var(--field-border-hover)}}.textarea:focus,.textarea[data-focused=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-outline-style:none;--tw-ring-offset-width:0px;border-color:var(--field-border-focus);background-color:var(--field-focus);outline-style:none}.textarea[data-invalid=true]{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}.textarea[data-invalid=true]:focus,.textarea[data-invalid=true]:focus-visible,.textarea[data-invalid=true][data-focused=true],.textarea[data-invalid=true][data-focus-visible=true],.textarea[data-invalid=true]:focus-within,.textarea[data-invalid=true][data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.textarea[data-invalid=true]{background-color:var(--field-focus)}.textarea:disabled,.textarea[data-disabled=true],.textarea[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.textarea--secondary{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);background-color:var(--textarea-bg);--textarea-bg:var(--default);--textarea-bg-hover:var(--default-hover);--textarea-bg-focus:var(--default)}@media(hover:hover){.textarea--secondary:hover:not(:focus):not(:focus-visible),.textarea--secondary[data-hovered=true]:not([data-focused=true]):not([data-focus-visible=true]){background-color:var(--textarea-bg-hover)}}.textarea--secondary:focus,.textarea--secondary[data-focused=true]{background-color:var(--textarea-bg-focus)}.textarea--secondary[data-invalid=true]{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}.textarea--secondary[data-invalid=true]:focus,.textarea--secondary[data-invalid=true]:focus-visible,.textarea--secondary[data-invalid=true][data-focused=true],.textarea--secondary[data-invalid=true][data-focus-visible=true],.textarea--secondary[data-invalid=true]:focus-within,.textarea--secondary[data-invalid=true][data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.textarea--secondary[data-invalid=true]{background-color:var(--textarea-bg-focus)}.textarea--full-width{width:100%}.calendar{width:calc(var(--spacing) * 63);max-width:calc(var(--spacing) * 63);container-type:inline-size}.calendar--week-view .calendar__cell,.calendar--day-view .calendar__cell{aspect-ratio:1;place-self:center;width:100%;height:auto}.calendar--day-view .calendar__grid{flex-direction:column;display:flex}.calendar--day-view .calendar__grid-header{grid-template-columns:repeat(7,1fr);width:100%;display:grid}.calendar--day-view .calendar__grid-header>tr{display:contents}.calendar--day-view .calendar__grid-body{margin-top:var(--spacing);grid-template-columns:repeat(7,1fr);width:100%;display:grid}.calendar--day-view .calendar__grid-body>tr{display:contents}.calendar--day-view .calendar__grid-body>tr:first-child>td{margin-top:0}.calendar__header{padding-inline:calc(var(--spacing) * .5);padding-bottom:calc(var(--spacing) * 4);justify-content:space-between;align-items:center;display:flex}.calendar__header:has(.calendar-year-picker__trigger[data-open=true]) .calendar__nav-button{pointer-events:none;opacity:0}.calendar__heading{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);flex:1}.calendar__nav-button{width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6);border-radius:calc(var(--radius) * 2);color:var(--accent-soft-foreground);will-change:scale;transition:transform .25s var(--ease-out),background-color .1s var(--ease-out),box-shadow .1s var(--ease-out),opacity .15s var(--ease-out);transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);justify-content:center;align-items:center;display:flex}.calendar__nav-button:is([data-reduce-motion=true],[data-reduce-motion=true] *),.calendar__nav-button:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.calendar__nav-button:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.calendar__nav-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.calendar__nav-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.calendar__nav-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.calendar__nav-button{cursor:var(--cursor-interactive)}@media(hover:hover){.calendar__nav-button:hover,.calendar__nav-button[data-hovered=true]{background-color:var(--default);color:var(--accent-soft-foreground)}}.calendar__nav-button:active,.calendar__nav-button[data-pressed=true]{transform:scale(.95)}.calendar__nav-button:focus-visible,.calendar__nav-button[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.calendar__nav-button:disabled,.calendar__nav-button[data-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.calendar__nav-button-icon{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.calendar__grid{grid-template-columns:repeat(7,1fr);width:100%;display:grid}.calendar__grid[aria-readonly=true] .calendar__cell{pointer-events:none}.calendar__grid-header,.calendar__grid-header>tr,.calendar__grid-body,.calendar__grid-body>tr{display:contents}.calendar__grid-body>tr:first-child>td{margin-top:var(--spacing)}.calendar__grid-row{display:contents}.calendar__header-cell{padding-bottom:calc(var(--spacing) * 2);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--muted);justify-content:center;align-items:center;display:flex}.calendar__cell{aspect-ratio:1;border-radius:calc(var(--radius) * 3);text-align:center;width:100%;height:100%;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);--tw-outline-style:none;-webkit-tap-highlight-color:transparent;will-change:scale;transition:transform .25s var(--ease-out),box-shadow .1s var(--ease-out);transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);outline-style:none;justify-content:center;align-items:center;display:flex;position:relative}.calendar__cell:is([data-reduce-motion=true],[data-reduce-motion=true] *),.calendar__cell:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.calendar__cell:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.calendar__cell:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.calendar__cell:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.calendar__cell:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.calendar__cell{cursor:var(--cursor-interactive)}.calendar__cell:focus-visible:not(:focus),.calendar__cell[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.calendar__cell[data-today=true]{background-color:var(--accent-soft);color:var(--accent-soft-foreground)}@media(hover:hover){.calendar__cell[data-today=true]:hover:not([data-selected=true]),.calendar__cell[data-today=true][data-hovered=true]:not([data-selected=true]){background-color:var(--accent-soft-hover)}}.calendar__cell[data-selected=true]{background-color:var(--accent);color:var(--accent-foreground)}.calendar__cell:active,.calendar__cell[data-pressed=true]{background-color:var(--default);transform:scale(.95)}:is(.calendar__cell:active,.calendar__cell[data-pressed=true])[data-selected=true]{background-color:var(--accent-hover)}@media(hover:hover){.calendar__cell:hover:not([data-selected=true]),.calendar__cell[data-hovered=true]:not([data-selected=true]){background-color:var(--default)}}.calendar__cell[data-outside-month=true]{color:var(--muted);opacity:.5}.calendar__cell[data-selected=true][data-outside-month=true]{background-color:var(--default)}.calendar__cell[data-unavailable=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.calendar__cell:disabled:not([data-outside-month=true]),.calendar__cell[data-disabled=true]:not([data-outside-month=true]){opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none;text-decoration:line-through}.calendar__cell-indicator{bottom:var(--spacing);--tw-translate-x: -50% ;width:3px;height:3px;translate:var(--tw-translate-x) var(--tw-translate-y);border-radius:calc(var(--radius) * .25);background-color:var(--muted);position:absolute;left:50%}[data-selected=true]>.calendar__cell-indicator{background-color:var(--accent-foreground)}.range-calendar{width:calc(var(--spacing) * 63);max-width:calc(var(--spacing) * 63);container-type:inline-size}.range-calendar--week-view .range-calendar__cell,.range-calendar--day-view .range-calendar__cell{aspect-ratio:1;place-self:center;width:100%;height:auto}.range-calendar--day-view .range-calendar__grid{flex-direction:column;display:flex}.range-calendar--day-view .range-calendar__grid-header{grid-template-columns:repeat(7,1fr);width:100%;display:grid}.range-calendar--day-view .range-calendar__grid-header>tr{display:contents}.range-calendar--day-view .range-calendar__grid-body{margin-top:var(--spacing);grid-template-columns:repeat(7,1fr);width:100%;display:grid}.range-calendar--day-view .range-calendar__grid-body>tr{display:contents}.range-calendar--day-view .range-calendar__grid-body>tr:first-child>td{margin-top:0}.range-calendar__header{padding-inline:calc(var(--spacing) * .5);padding-bottom:calc(var(--spacing) * 4);justify-content:space-between;align-items:center;display:flex}.range-calendar__header:has(.calendar-year-picker__trigger[data-open=true]) .range-calendar__nav-button{pointer-events:none;opacity:0}.range-calendar__heading{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);flex:1}.range-calendar__nav-button{width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6);border-radius:calc(var(--radius) * 1.5);color:var(--accent-soft-foreground);will-change:scale;transition:transform .25s var(--ease-out),background-color .1s var(--ease-out),box-shadow .1s var(--ease-out),opacity .15s var(--ease-out);transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);justify-content:center;align-items:center;display:flex}.range-calendar__nav-button:is([data-reduce-motion=true],[data-reduce-motion=true] *),.range-calendar__nav-button:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.range-calendar__nav-button:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.range-calendar__nav-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.range-calendar__nav-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.range-calendar__nav-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.range-calendar__nav-button{cursor:var(--cursor-interactive)}@media(hover:hover){.range-calendar__nav-button:hover,.range-calendar__nav-button[data-hovered=true]{background-color:var(--default);color:var(--accent-soft-foreground)}}.range-calendar__nav-button:active,.range-calendar__nav-button[data-pressed=true]{transform:scale(.95)}.range-calendar__nav-button:focus-visible,.range-calendar__nav-button[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.range-calendar__nav-button:disabled,.range-calendar__nav-button[data-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.range-calendar__nav-button-icon{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.range-calendar__grid{grid-template-columns:repeat(7,1fr);width:100%;display:grid}.range-calendar__grid[aria-readonly=true] .range-calendar__cell{pointer-events:none}.range-calendar__grid-header,.range-calendar__grid-header>tr,.range-calendar__grid-body,.range-calendar__grid-body>tr{display:contents}.range-calendar__grid-body>tr:first-child>td{margin-top:var(--spacing)}.range-calendar__grid-row{display:contents}.range-calendar__header-cell{padding-bottom:calc(var(--spacing) * 2);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--muted);justify-content:center;align-items:center;display:flex}.range-calendar__cell{z-index:1;border-radius:calc(var(--radius) * 3);--tw-outline-style:none;cursor:var(--cursor-interactive);will-change:background-color,border-color;transition:box-shadow .1s var(--ease-out),border-color .1s var(--ease-out);transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);outline-style:none;margin-block:2px;margin-inline:0;padding:0;position:relative}.range-calendar__cell:is([data-reduce-motion=true],[data-reduce-motion=true] *),.range-calendar__cell:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.range-calendar__cell:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.range-calendar__cell:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.range-calendar__cell:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.range-calendar__cell:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.range-calendar__cell .range-calendar__cell-button{aspect-ratio:1;border-radius:calc(var(--radius) * 3);width:100%;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--foreground);-webkit-tap-highlight-color:transparent;will-change:scale;transition:scale .2s var(--ease-out);transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);justify-content:center;align-items:center;display:flex}.range-calendar__cell .range-calendar__cell-button:is([data-reduce-motion=true],[data-reduce-motion=true] *),.range-calendar__cell .range-calendar__cell-button:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.range-calendar__cell .range-calendar__cell-button:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.range-calendar__cell .range-calendar__cell-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.range-calendar__cell .range-calendar__cell-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.range-calendar__cell .range-calendar__cell-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.range-calendar__cell:focus-visible:not(:focus),.range-calendar__cell[data-focus-visible=true]{z-index:2}:is(.range-calendar__cell:focus-visible:not(:focus),.range-calendar__cell[data-focus-visible=true]) .range-calendar__cell-button{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.range-calendar__cell[data-today=true] .range-calendar__cell-button{background-color:var(--accent-soft);color:var(--accent-soft-foreground)}@media(hover:hover){:is(.range-calendar__cell[data-today=true]:hover:not([data-selected=true]),.range-calendar__cell[data-today=true][data-hovered=true]:not([data-selected=true])) .range-calendar__cell-button{background-color:var(--accent-soft-hover)}}.range-calendar__cell[data-selected=true]:not([data-outside-month=true]){background-color:var(--accent-soft);border-radius:0}.range-calendar__cell[data-selected=true]:is(td:first-child>*,[aria-disabled]+td>*){border-start-start-radius:calc(var(--radius) * 1);border-end-start-radius:calc(var(--radius) * 1)}.range-calendar__cell[data-selected=true]:is(td:first-child>*,[aria-disabled]+td>*)[data-selection-start=true]{border-start-start-radius:calc(var(--radius) * 3);border-end-start-radius:calc(var(--radius) * 3)}.range-calendar__cell[data-selected=true]:is(td:last-child>*,td:has(+[aria-disabled])>*){border-start-end-radius:calc(var(--radius) * 1);border-end-end-radius:calc(var(--radius) * 1)}.range-calendar__cell[data-selected=true]:is(td:last-child>*,td:has(+[aria-disabled])>*)[data-selection-end=true]{border-start-end-radius:calc(var(--radius) * 3);border-end-end-radius:calc(var(--radius) * 3)}.range-calendar__cell[data-selection-start=true]:not([data-outside-month=true]),.range-calendar__cell[data-selection-end=true]:not([data-outside-month=true]){z-index:2}:is(.range-calendar__cell[data-selection-start=true]:not([data-outside-month=true]),.range-calendar__cell[data-selection-end=true]:not([data-outside-month=true])) .range-calendar__cell-button{background-color:var(--accent);color:var(--accent-foreground)}.range-calendar__cell[data-selection-start=true]:not([data-outside-month=true]){border-top-left-radius:calc(var(--radius) * 3);border-bottom-left-radius:calc(var(--radius) * 3)}.range-calendar__cell[data-selection-end=true]:not([data-outside-month=true]){border-top-right-radius:calc(var(--radius) * 3);border-bottom-right-radius:calc(var(--radius) * 3)}:is(.range-calendar__cell:active,.range-calendar__cell[data-pressed=true]) .range-calendar__cell-button{scale:.9}:is(:is(.range-calendar__cell:active,.range-calendar__cell[data-pressed=true])[data-selection-start=true],:is(.range-calendar__cell:active,.range-calendar__cell[data-pressed=true])[data-selection-end=true]) .range-calendar__cell-button{background-color:var(--accent-hover)}@media(hover:hover){:is(.range-calendar__cell:hover:not([data-selected=true]),.range-calendar__cell[data-hovered=true]:not([data-selected=true])) .range-calendar__cell-button{background-color:var(--default)}}.range-calendar__cell[data-outside-month=true]{color:var(--muted);opacity:.5}.range-calendar__cell[data-selected=true][data-outside-month=true]:not([data-selection-start=true],[data-selection-end=true]){background-color:var(--default)}@supports (color:color-mix(in lab,red,red)){.range-calendar__cell[data-selected=true][data-outside-month=true]:not([data-selection-start=true],[data-selection-end=true]){background-color:color-mix(in oklab,var(--default) 20%,transparent)}}.range-calendar__cell[data-unavailable=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.range-calendar__cell:disabled:not([data-outside-month=true]),.range-calendar__cell[data-disabled=true]:not([data-outside-month=true]){opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none;text-decoration:line-through}.range-calendar__grid-body td:has(>.range-calendar__cell[data-outside-month=true])+td>.range-calendar__cell[data-selected=true]{border-start-start-radius:calc(var(--radius) * 1);border-end-start-radius:calc(var(--radius) * 1)}.range-calendar__grid-body td:has(>.range-calendar__cell[data-outside-month=true])+td>.range-calendar__cell[data-selected=true][data-outside-month=true],.range-calendar__grid-body td:has(>.range-calendar__cell[data-outside-month=true])+td>.range-calendar__cell[data-selected=true][data-selection-start=true]{border-start-start-radius:calc(var(--radius) * 3);border-end-start-radius:calc(var(--radius) * 3)}.range-calendar__grid-body td:has(>.range-calendar__cell[data-selected=true]):has(+td>.range-calendar__cell[data-outside-month=true])>.range-calendar__cell[data-selected=true]{border-start-end-radius:calc(var(--radius) * 1);border-end-end-radius:calc(var(--radius) * 1)}.range-calendar__grid-body td:has(>.range-calendar__cell[data-selected=true]):has(+td>.range-calendar__cell[data-outside-month=true])>.range-calendar__cell[data-selected=true][data-outside-month=true],.range-calendar__grid-body td:has(>.range-calendar__cell[data-selected=true]):has(+td>.range-calendar__cell[data-outside-month=true])>.range-calendar__cell[data-selected=true][data-selection-end=true]{border-start-end-radius:calc(var(--radius) * 3);border-end-end-radius:calc(var(--radius) * 3)}.range-calendar__cell-indicator{bottom:var(--spacing);--tw-translate-x: -50% ;width:3px;height:3px;translate:var(--tw-translate-x) var(--tw-translate-y);border-radius:calc(var(--radius) * .25);background-color:var(--muted);position:absolute;left:50%}[data-selected=true]>.range-calendar__cell-indicator{background-color:var(--accent-foreground)}.calendar:has(.calendar-year-picker__year-grid),.range-calendar:has(.calendar-year-picker__year-grid){position:relative}.calendar:has(.calendar-year-picker__year-grid)>[data-slot=calendar-grid],.range-calendar:has(.calendar-year-picker__year-grid)>[data-slot=range-calendar-grid]{will-change:opacity;transition:opacity .15s var(--ease-out),visibility 0s linear}:is(.calendar:has(.calendar-year-picker__year-grid)>[data-slot=calendar-grid],.range-calendar:has(.calendar-year-picker__year-grid)>[data-slot=range-calendar-grid]):is([data-reduce-motion=true],[data-reduce-motion=true] *),:is(.calendar:has(.calendar-year-picker__year-grid)>[data-slot=calendar-grid],.range-calendar:has(.calendar-year-picker__year-grid)>[data-slot=range-calendar-grid]):is([data-reduce-motion=true],[data-reduce-motion=true] *):before,:is(.calendar:has(.calendar-year-picker__year-grid)>[data-slot=calendar-grid],.range-calendar:has(.calendar-year-picker__year-grid)>[data-slot=range-calendar-grid]):is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){:is(.calendar:has(.calendar-year-picker__year-grid)>[data-slot=calendar-grid],.range-calendar:has(.calendar-year-picker__year-grid)>[data-slot=range-calendar-grid]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),:is(.calendar:has(.calendar-year-picker__year-grid)>[data-slot=calendar-grid],.range-calendar:has(.calendar-year-picker__year-grid)>[data-slot=range-calendar-grid]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,:is(.calendar:has(.calendar-year-picker__year-grid)>[data-slot=calendar-grid],.range-calendar:has(.calendar-year-picker__year-grid)>[data-slot=range-calendar-grid]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.calendar:has(.calendar-year-picker__year-grid[data-open=true])>[data-slot=calendar-grid],.range-calendar:has(.calendar-year-picker__year-grid[data-open=true])>[data-slot=range-calendar-grid]{pointer-events:none;opacity:0;visibility:hidden;transition:opacity .15s var(--ease-out),visibility 0s linear .15s}:is(.calendar:has(.calendar-year-picker__year-grid[data-open=true])>[data-slot=calendar-grid],.range-calendar:has(.calendar-year-picker__year-grid[data-open=true])>[data-slot=range-calendar-grid]):is([data-reduce-motion=true],[data-reduce-motion=true] *),:is(.calendar:has(.calendar-year-picker__year-grid[data-open=true])>[data-slot=calendar-grid],.range-calendar:has(.calendar-year-picker__year-grid[data-open=true])>[data-slot=range-calendar-grid]):is([data-reduce-motion=true],[data-reduce-motion=true] *):before,:is(.calendar:has(.calendar-year-picker__year-grid[data-open=true])>[data-slot=calendar-grid],.range-calendar:has(.calendar-year-picker__year-grid[data-open=true])>[data-slot=range-calendar-grid]):is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){:is(.calendar:has(.calendar-year-picker__year-grid[data-open=true])>[data-slot=calendar-grid],.range-calendar:has(.calendar-year-picker__year-grid[data-open=true])>[data-slot=range-calendar-grid]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),:is(.calendar:has(.calendar-year-picker__year-grid[data-open=true])>[data-slot=calendar-grid],.range-calendar:has(.calendar-year-picker__year-grid[data-open=true])>[data-slot=range-calendar-grid]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,:is(.calendar:has(.calendar-year-picker__year-grid[data-open=true])>[data-slot=calendar-grid],.range-calendar:has(.calendar-year-picker__year-grid[data-open=true])>[data-slot=range-calendar-grid]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.calendar-year-picker__trigger{justify-content:flex-start;align-items:center;gap:var(--spacing);border-radius:calc(var(--radius) * 1);--tw-outline-style:none;cursor:var(--cursor-interactive);touch-action:manipulation;outline-style:none;flex:1;display:flex}.calendar-year-picker__trigger:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.calendar-year-picker__trigger-heading{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);transition:color .15s var(--ease-out)}.calendar-year-picker__trigger-heading:is([data-reduce-motion=true],[data-reduce-motion=true] *),.calendar-year-picker__trigger-heading:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.calendar-year-picker__trigger-heading:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.calendar-year-picker__trigger-heading:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.calendar-year-picker__trigger-heading:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.calendar-year-picker__trigger-heading:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.calendar-year-picker__trigger-indicator{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));color:var(--accent-soft-foreground);transition:transform .15s var(--ease-out)}.calendar-year-picker__trigger-indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *),.calendar-year-picker__trigger-indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.calendar-year-picker__trigger-indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.calendar-year-picker__trigger-indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.calendar-year-picker__trigger-indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.calendar-year-picker__trigger-indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.calendar-year-picker__trigger[data-open=true] .calendar-year-picker__trigger-indicator{transform:rotate(90deg)}.calendar-year-picker__trigger[data-open=true] .calendar-year-picker__trigger-heading{color:var(--accent-soft-foreground)}.calendar-year-picker__year-grid{pointer-events:none;scrollbar-width:var(--scrollbar-width);scrollbar-color:var(--scrollbar-color);scrollbar-gutter:var(--scrollbar-gutter);align-content:flex-start;gap:var(--spacing);padding:var(--spacing);opacity:0;will-change:opacity;grid-template-columns:repeat(3,1fr);display:grid;position:absolute;left:0;right:0;overflow-y:auto}.calendar-year-picker__year-grid[data-open=true]{pointer-events:auto;opacity:1;transition:opacity .2s var(--ease-out) 50ms}.calendar-year-picker__year-grid[data-open=true]:is([data-reduce-motion=true],[data-reduce-motion=true] *),.calendar-year-picker__year-grid[data-open=true]:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.calendar-year-picker__year-grid[data-open=true]:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.calendar-year-picker__year-grid[data-open=true]:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.calendar-year-picker__year-grid[data-open=true]:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.calendar-year-picker__year-grid[data-open=true]:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.calendar-year-picker__year-cell{height:calc(var(--spacing) * 8);border-radius:calc(var(--radius) * 3);padding-inline:calc(var(--spacing) * 2.5);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);--tw-outline-style:none;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;touch-action:manipulation;transition:color .1s var(--ease-smooth),scale .1s var(--ease-smooth),opacity .1s var(--ease-smooth),background-color .1s var(--ease-smooth),box-shadow .1s var(--ease-out);transform-origin:50%;transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);outline-style:none;justify-content:center;align-items:center;display:inline-flex;position:relative}.calendar-year-picker__year-cell:is([data-reduce-motion=true],[data-reduce-motion=true] *),.calendar-year-picker__year-cell:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.calendar-year-picker__year-cell:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.calendar-year-picker__year-cell:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.calendar-year-picker__year-cell:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.calendar-year-picker__year-cell:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.calendar-year-picker__year-cell{cursor:var(--cursor-interactive)}@media(hover:hover)and (pointer:fine){.calendar-year-picker__year-cell:is(:hover,[data-hovered=true]):not([data-selected=true]){background-color:var(--default);color:var(--default-foreground)}}.calendar-year-picker__year-cell[data-selected=true],.calendar-year-picker__year-cell[aria-selected=true]{background-color:var(--accent);color:var(--accent-foreground)}@media(hover:hover)and (pointer:fine){:is(.calendar-year-picker__year-cell[data-selected=true],.calendar-year-picker__year-cell[aria-selected=true]):is(:hover,[data-hovered=true]){background-color:var(--accent-hover)}}.calendar-year-picker__year-cell:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.date-field{gap:var(--spacing);flex-direction:column;display:flex}:is(.date-field[data-invalid=true],.date-field[aria-invalid=true]) [data-slot=description]{display:none}.date-field [data-slot=label]{width:fit-content}.date-field--full-width{width:100%}.time-field{gap:var(--spacing);flex-direction:column;display:flex}:is(.time-field[data-invalid=true],.time-field[aria-invalid=true]) [data-slot=description]{display:none}.time-field [data-slot=label]{width:fit-content}.time-field--full-width{width:100%}.date-input-group{height:calc(var(--spacing) * 9);border-radius:var(--field-radius,calc(var(--radius) * 1.5));border-style:var(--tw-border-style);background-color:var(--field-background,var(--default));font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--field-foreground,var(--foreground));--tw-shadow:var(--field-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;border-width:1px;border-width:var(--border-width-field);border-color:var(--field-border);transition:background-color .15s var(--ease-smooth),border-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out);outline-style:none;align-items:center;display:inline-flex;overflow:hidden}.date-input-group:is([data-reduce-motion=true],[data-reduce-motion=true] *),.date-input-group:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.date-input-group:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.date-input-group:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.date-input-group:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.date-input-group:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}@media(hover:hover){.date-input-group:hover:not(:focus-within),.date-input-group[data-hovered=true]:not([data-focus-within=true]){background-color:var(--field-hover);border-color:var(--field-border-hover)}}.date-input-group[data-focus-within=true]:not(:has([data-slot=date-picker-trigger]:focus,[data-slot=date-picker-trigger][data-focused=true],[data-slot=date-range-picker-trigger]:focus,[data-slot=date-range-picker-trigger][data-focused=true])),.date-input-group:focus-within:not(:has([data-slot=date-picker-trigger]:focus,[data-slot=date-picker-trigger][data-focused=true],[data-slot=date-range-picker-trigger]:focus,[data-slot=date-range-picker-trigger][data-focused=true])){--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-outline-style:none;--tw-ring-offset-width:0px;outline-style:none}.date-input-group[data-invalid=true]{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}.date-input-group[data-invalid=true]:focus,.date-input-group[data-invalid=true]:focus-visible,.date-input-group[data-invalid=true][data-focused=true],.date-input-group[data-invalid=true][data-focus-visible=true],.date-input-group[data-invalid=true]:focus-within,.date-input-group[data-invalid=true][data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.date-input-group[data-invalid=true]{background-color:var(--field-focus);border-color:var(--color-field-border-invalid)}.date-input-group[data-disabled=true],.date-input-group[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.date-input-group__input{cursor:text;border-style:var(--tw-border-style);padding-inline:calc(var(--spacing) * 3);padding-block:calc(var(--spacing) * 2);font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;background-color:#0000;border-width:0;border-radius:0;outline-style:none;flex:1;align-items:center;gap:1px;display:flex}@media(min-width:40rem){.date-input-group__input{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}.date-input-group:has([data-slot=date-input-group-prefix]) .date-input-group__input{padding-left:calc(var(--spacing) * 2);border-top-left-radius:0;border-bottom-left-radius:0}.date-input-group:has([data-slot=date-input-group-suffix]) .date-input-group__input{padding-right:calc(var(--spacing) * 2);border-top-right-radius:0;border-bottom-right-radius:0}.date-input-group:has(.date-range-picker__range-separator) .date-input-group__input[slot=start]{flex:none;padding-right:0}.date-input-group:has(.date-range-picker__range-separator) .date-input-group__input[slot=end]{padding-left:0}.date-input-group__input:focus,.date-input-group__input:focus-visible{--tw-outline-style:none;outline-style:none}.date-input-group__input-container{scrollbar-color:auto;scrollbar-gutter:auto;-ms-overflow-style:none;scrollbar-width:none;flex:1;align-items:center;width:fit-content;display:flex;overflow:auto clip}.date-input-group__segment{border-radius:calc(var(--radius) * .75);padding-inline:calc(var(--spacing) * .5);text-align:end;text-wrap:nowrap;--tw-outline-style:none;outline-style:none;display:inline-block}.date-input-group__segment[data-type=literal]{color:var(--muted);padding:0}.date-input-group__segment[data-placeholder=true]{color:var(--field-placeholder,var(--muted))}.date-input-group__segment:focus,.date-input-group__segment[data-focused=true]{background-color:var(--accent-soft);color:var(--accent-soft-foreground)}.date-input-group__segment[data-disabled=true]{opacity:.5}.date-input-group__segment[data-invalid=true]{color:var(--danger)}.date-input-group__segment[data-invalid=true]:focus,.date-input-group__segment[data-invalid=true][data-focused=true]{background-color:var(--danger-soft);color:var(--danger-soft-foreground)}.date-input-group__prefix{pointer-events:none;color:var(--field-placeholder,var(--muted));margin-right:0;margin-left:calc(var(--spacing) * 3);flex-shrink:0;align-items:center;display:flex}.date-input-group__suffix{pointer-events:none;color:var(--field-placeholder,var(--muted));margin-right:calc(var(--spacing) * 3);flex-shrink:0;align-items:center;display:flex}.date-input-group--secondary{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);background-color:var(--date-input-group-bg);--date-input-group-bg:var(--default);--date-input-group-bg-hover:var(--default-hover);--date-input-group-bg-focus:var(--default)}@media(hover:hover){.date-input-group--secondary:hover:not(:focus-within),.date-input-group--secondary[data-hovered=true]:not([data-focus-within=true]){background-color:var(--date-input-group-bg-hover)}}.date-input-group--secondary:focus-within,.date-input-group--secondary[data-focus-within=true]{background-color:var(--date-input-group-bg-focus)}.date-input-group--secondary[data-invalid=true]{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}.date-input-group--secondary[data-invalid=true]:focus,.date-input-group--secondary[data-invalid=true]:focus-visible,.date-input-group--secondary[data-invalid=true][data-focused=true],.date-input-group--secondary[data-invalid=true][data-focus-visible=true],.date-input-group--secondary[data-invalid=true]:focus-within,.date-input-group--secondary[data-invalid=true][data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.date-input-group--secondary[data-invalid=true]{border-color:var(--color-field-border-invalid);background-color:var(--date-input-group-bg-focus)}.date-input-group--secondary [data-slot=date-input-group-input]{background-color:#0000}.date-input-group--full-width{width:100%}.date-picker{gap:var(--spacing);flex-direction:column;display:inline-flex}.date-picker .date-input-group__suffix,.date-picker .date-input-group__prefix{pointer-events:auto}.date-picker__trigger{border-radius:var(--field-radius,calc(var(--radius) * 1.5));width:100%;padding:var(--spacing);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));-webkit-tap-highlight-color:transparent;cursor:var(--cursor-interactive);transition:box-shadow .15s var(--ease-out);align-items:center;display:inline-flex}.date-picker__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *),.date-picker__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.date-picker__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.date-picker__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.date-picker__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.date-picker__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.date-picker__trigger:focus-visible:not(:focus),.date-picker__trigger[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.date-picker__trigger:disabled,.date-picker__trigger[data-disabled=true],.date-picker__trigger[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.date-picker__trigger-indicator{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4);color:var(--field-placeholder,var(--muted));justify-content:center;align-items:center;display:inline-flex}.date-picker__popover{min-width:var(--trigger-width);transform-origin:var(--trigger-anchor-point);scrollbar-color:auto;scrollbar-gutter:auto;-ms-overflow-style:none;scrollbar-width:none;overscroll-behavior:contain;background-color:var(--overlay);padding:calc(var(--spacing) * 3);overflow-y:auto}.date-picker__popover:is([data-reduce-motion=true],[data-reduce-motion=true] *),.date-picker__popover:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.date-picker__popover:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.date-picker__popover:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.date-picker__popover:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.date-picker__popover:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.date-picker__popover{box-shadow:var(--shadow-overlay);border-radius:min(32px,calc(var(--radius) * 2.5))}.date-picker__popover:focus-visible:not(:focus),.date-picker__popover[data-focus-visible=true]{--tw-outline-style:none;outline-style:none}.date-picker__popover[data-entering=true]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.15s;--tw-ease:ease;--tw-enter-opacity:0;--tw-enter-scale:.95;transition-duration:.15s;transition-timing-function:ease}.date-picker__popover[data-entering=true][data-placement^=top]{--tw-enter-translate-y:calc(1*var(--spacing))}.date-picker__popover[data-entering=true][data-placement^=bottom]{--tw-enter-translate-y:calc(1*var(--spacing)*-1)}.date-picker__popover[data-entering=true][data-placement^=left]{--tw-enter-translate-x:calc(1*var(--spacing))}.date-picker__popover[data-entering=true][data-placement^=right]{--tw-enter-translate-x:calc(1*var(--spacing)*-1)}.date-picker__popover[data-exiting=true]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.1s;--tw-ease:ease;--tw-exit-scale:.95;--tw-exit-opacity:0;transition-duration:.1s;transition-timing-function:ease}.date-picker__popover[data-exiting=true],.date-picker__popover[data-entering=true]{transition-property:opacity,transform;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));will-change:opacity,transform}.date-range-picker{gap:var(--spacing);flex-direction:column;display:inline-flex}.date-range-picker .date-input-group__suffix,.date-range-picker .date-input-group__prefix{pointer-events:auto}.date-range-picker__trigger{border-radius:var(--field-radius,calc(var(--radius) * 1.5));width:100%;padding:var(--spacing);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));-webkit-tap-highlight-color:transparent;cursor:var(--cursor-interactive);transition:box-shadow .15s var(--ease-out);align-items:center;display:inline-flex}.date-range-picker__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *),.date-range-picker__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.date-range-picker__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.date-range-picker__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.date-range-picker__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.date-range-picker__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.date-range-picker__trigger:focus-visible:not(:focus),.date-range-picker__trigger[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.date-range-picker__trigger:disabled,.date-range-picker__trigger[data-disabled=true],.date-range-picker__trigger[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.date-range-picker__trigger-indicator{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4);color:var(--field-placeholder,var(--muted));justify-content:center;align-items:center;display:inline-flex}.date-range-picker__range-separator{padding-inline:var(--spacing);color:var(--field-placeholder,var(--muted));-webkit-user-select:none;user-select:none}.date-range-picker__popover{min-width:var(--trigger-width);transform-origin:var(--trigger-anchor-point);scrollbar-color:auto;scrollbar-gutter:auto;-ms-overflow-style:none;scrollbar-width:none;overscroll-behavior:contain;background-color:var(--overlay);padding:calc(var(--spacing) * 3);overflow-y:auto}.date-range-picker__popover:is([data-reduce-motion=true],[data-reduce-motion=true] *),.date-range-picker__popover:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.date-range-picker__popover:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.date-range-picker__popover:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.date-range-picker__popover:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.date-range-picker__popover:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.date-range-picker__popover{box-shadow:var(--shadow-overlay);border-radius:min(32px,calc(var(--radius) * 2.5))}.date-range-picker__popover:focus-visible:not(:focus),.date-range-picker__popover[data-focus-visible=true]{--tw-outline-style:none;outline-style:none}.date-range-picker__popover[data-entering=true]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.15s;--tw-ease:ease;--tw-enter-opacity:0;--tw-enter-scale:.95;transition-duration:.15s;transition-timing-function:ease}.date-range-picker__popover[data-entering=true][data-placement^=top]{--tw-enter-translate-y:calc(1*var(--spacing))}.date-range-picker__popover[data-entering=true][data-placement^=bottom]{--tw-enter-translate-y:calc(1*var(--spacing)*-1)}.date-range-picker__popover[data-entering=true][data-placement^=left]{--tw-enter-translate-x:calc(1*var(--spacing))}.date-range-picker__popover[data-entering=true][data-placement^=right]{--tw-enter-translate-x:calc(1*var(--spacing)*-1)}.date-range-picker__popover[data-exiting=true]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.1s;--tw-ease:ease;--tw-exit-scale:.95;--tw-exit-opacity:0;transition-duration:.1s;transition-timing-function:ease}.date-range-picker__popover[data-exiting=true],.date-range-picker__popover[data-entering=true]{transition-property:opacity,transform;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));will-change:opacity,transform}.card{gap:calc(var(--spacing) * 3);padding:calc(var(--spacing) * 4);--tw-shadow:var(--surface-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);border-radius:min(32px,var(--radius-3xl));flex-direction:column;display:flex;position:relative;overflow:visible}.card__header{flex-direction:column;display:flex}.card__title{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-leading:calc(var(--spacing) * 6);line-height:calc(var(--spacing) * 6);--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--foreground)}.card__description{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-leading:calc(var(--spacing) * 5);line-height:calc(var(--spacing) * 5);color:var(--muted)}.card__content{gap:var(--spacing);flex-direction:column;flex:1;display:flex}.card__footer{flex-direction:row;align-items:center;display:flex}.card--transparent{--tw-border-style:none;--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);background-color:#0000;border-style:none}.card--default{background-color:var(--surface)}.card--secondary{background-color:var(--surface-secondary)}.card--tertiary{background-color:var(--surface-tertiary)}.header{width:100%;padding-inline:calc(var(--spacing) * 2);padding-top:calc(var(--spacing) * 1.5);padding-bottom:var(--spacing);text-align:left;font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--muted)}.separator{border-radius:calc(var(--radius) * .5);border-top-style:var(--tw-border-style);border-top-width:0;border-bottom-style:var(--tw-border-style);background-color:var(--separator);border-bottom-width:0;flex-shrink:0;width:100%;height:1px}.separator--horizontal{width:100%;height:1px}.separator--vertical{height:auto;min-height:calc(var(--spacing) * 2);align-self:stretch;width:1px}.separator--default{background-color:var(--separator)}.separator--secondary{background-color:var(--separator-secondary)}.separator--tertiary{background-color:var(--separator-tertiary)}.separator__container{align-items:center;gap:calc(var(--spacing) * 3);display:flex}.separator__container--horizontal{flex-direction:row;width:100%}.separator__container--vertical{flex-direction:column;justify-content:center;height:100%}.separator__line{flex-grow:1;flex-shrink:0}.separator__content{text-align:center;white-space:nowrap;color:var(--muted);justify-content:center;align-items:center;display:inline-flex}.separator__content--horizontal,.separator__content--vertical{text-align:center}.surface{color:var(--foreground);position:relative}.surface--transparent{background-color:#0000}.surface--default{background-color:var(--surface);color:var(--surface-foreground)}.surface--secondary{background-color:var(--surface-secondary);color:var(--surface-secondary-foreground)}.surface--tertiary{background-color:var(--surface-tertiary);color:var(--surface-tertiary-foreground)}.avatar{width:calc(var(--spacing) * 10);height:calc(var(--spacing) * 10);border-radius:calc(var(--radius) * 3);background-color:var(--default);flex-shrink:0;justify-content:center;align-items:center;display:flex;position:relative;overflow:hidden}.avatar__fallback{background-color:var(--default);width:100%;height:100%;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);justify-content:center;align-items:center;display:flex}.avatar__image{aspect-ratio:1;width:100%;height:100%;transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.25s;transition-duration:.25s;position:absolute;top:0;right:0;bottom:0;left:0}.avatar__image:is([data-reduce-motion=true],[data-reduce-motion=true] *),.avatar__image:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.avatar__image:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.avatar__image:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.avatar__image:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.avatar__image:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.avatar--sm{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8);border-radius:calc(var(--radius) * 2)}.avatar--lg{width:calc(var(--spacing) * 12);height:calc(var(--spacing) * 12);border-radius:calc(var(--radius) * 3)}.avatar--lg .avatar__fallback{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.avatar__fallback--accent{color:var(--accent-soft-foreground)}.avatar__fallback--default{color:var(--default-soft-foreground)}.avatar__fallback--success{color:var(--success-soft-foreground)}.avatar__fallback--warning{color:var(--warning-soft-foreground)}.avatar__fallback--danger{color:var(--danger-soft-foreground)}.avatar--soft{background-color:#0000}.avatar--soft .avatar__fallback--accent{background-color:var(--accent-soft);color:var(--accent-soft-foreground)}.avatar--soft .avatar__fallback--success{background-color:var(--success-soft);color:var(--success-soft-foreground)}.avatar--soft .avatar__fallback--warning{background-color:var(--warning-soft);color:var(--warning-soft-foreground)}.avatar--soft .avatar__fallback--default{background-color:var(--default-soft);color:var(--default-soft-foreground)}.avatar--soft .avatar__fallback--danger{background-color:var(--danger-soft);color:var(--danger-soft-foreground)}.alert-dialog__trigger{cursor:var(--cursor-interactive);transition:transform .25s var(--ease-out-quart),background-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out);display:inline-block}.alert-dialog__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *),.alert-dialog__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.alert-dialog__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.alert-dialog__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.alert-dialog__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.alert-dialog__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.alert-dialog__trigger:focus-visible:not(:focus),.alert-dialog__trigger[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.alert-dialog__trigger:disabled,.alert-dialog__trigger[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.alert-dialog__trigger:active,.alert-dialog__trigger[data-pressed=true]{transform:scale(.97)}.alert-dialog__backdrop{z-index:50;height:var(--visual-viewport-height);flex-direction:row;justify-content:center;align-items:center;width:100%;display:flex;position:fixed;top:0;right:0;bottom:0;left:0}.alert-dialog__backdrop[data-entering=true]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.15s;--tw-ease:var(--ease-out);transition-duration:.15s;transition-timing-function:var(--ease-out);--tw-enter-opacity:0}.alert-dialog__backdrop[data-exiting=true]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.1s;--tw-ease:var(--ease-out);transition-duration:.1s;transition-timing-function:var(--ease-out);--tw-exit-opacity:0}.alert-dialog__backdrop[data-exiting=true],.alert-dialog__backdrop[data-entering=true]{will-change:opacity}:is(.alert-dialog__backdrop[data-exiting=true],.alert-dialog__backdrop[data-entering=true]):is([data-reduce-motion=true],[data-reduce-motion=true] *),:is(.alert-dialog__backdrop[data-exiting=true],.alert-dialog__backdrop[data-entering=true]):is([data-reduce-motion=true],[data-reduce-motion=true] *):before,:is(.alert-dialog__backdrop[data-exiting=true],.alert-dialog__backdrop[data-entering=true]):is([data-reduce-motion=true],[data-reduce-motion=true] *):after{animation:none}@media(prefers-reduced-motion:reduce){:is(.alert-dialog__backdrop[data-exiting=true],.alert-dialog__backdrop[data-entering=true]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),:is(.alert-dialog__backdrop[data-exiting=true],.alert-dialog__backdrop[data-entering=true]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,:is(.alert-dialog__backdrop[data-exiting=true],.alert-dialog__backdrop[data-entering=true]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{animation:none}}.alert-dialog__backdrop--transparent{background-color:#0000}.alert-dialog__backdrop--opaque{background-color:var(--backdrop)}.alert-dialog__backdrop--blur{background-color:var(--backdrop);--tw-backdrop-blur:blur(var(--blur-md));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.alert-dialog__container{height:var(--visual-viewport-height);width:100%;min-width:0;padding:calc(var(--spacing) * 4);flex-direction:column;flex:1;align-items:center;display:flex}@media(min-width:40rem){.alert-dialog__container{width:fit-content;padding:calc(var(--spacing) * 10)}}.alert-dialog__container{pointer-events:none}.alert-dialog__container[data-entering=true]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.25s;--tw-ease:cubic-bezier(.25, .46, .45, .94);--tw-enter-opacity:0;--tw-enter-scale: 105% ;transition-duration:.25s;transition-timing-function:cubic-bezier(.25,.46,.45,.94)}.alert-dialog__container[data-entering=true][data-placement=auto]{--tw-enter-translate-y:calc(1*var(--spacing))}@media(min-width:40rem){.alert-dialog__container[data-entering=true][data-placement=auto]{--tw-enter-translate-y: 0% }}.alert-dialog__container[data-entering=true][data-placement=top]{--tw-enter-translate-y:calc(1*var(--spacing)*-1)}.alert-dialog__container[data-entering=true][data-placement=center]{--tw-enter-translate-y: -0% }.alert-dialog__container[data-entering=true][data-placement=bottom]{--tw-enter-translate-y:calc(1*var(--spacing))}.alert-dialog__container[data-exiting=true]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.1s;--tw-ease:cubic-bezier(.25, .46, .45, .94);--tw-exit-opacity:0;--tw-exit-scale:.95;transition-duration:.1s;transition-timing-function:cubic-bezier(.25,.46,.45,.94)}.alert-dialog__container[data-exiting=true],.alert-dialog__container[data-entering=true]{will-change:opacity,transform}:is(.alert-dialog__container[data-exiting=true],.alert-dialog__container[data-entering=true]):is([data-reduce-motion=true],[data-reduce-motion=true] *),:is(.alert-dialog__container[data-exiting=true],.alert-dialog__container[data-entering=true]):is([data-reduce-motion=true],[data-reduce-motion=true] *):before,:is(.alert-dialog__container[data-exiting=true],.alert-dialog__container[data-entering=true]):is([data-reduce-motion=true],[data-reduce-motion=true] *):after{animation:none}@media(prefers-reduced-motion:reduce){:is(.alert-dialog__container[data-exiting=true],.alert-dialog__container[data-entering=true]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),:is(.alert-dialog__container[data-exiting=true],.alert-dialog__container[data-entering=true]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,:is(.alert-dialog__container[data-exiting=true],.alert-dialog__container[data-entering=true]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{animation:none}}.alert-dialog__dialog{background-color:var(--overlay);--tw-shadow:var(--overlay-shadow);width:100%;min-height:0;max-height:100%;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;border-radius:min(32px,var(--radius-3xl));padding:calc(var(--spacing) * 6);pointer-events:auto;outline-style:none;flex-direction:column;display:flex;position:relative;overflow:clip}.alert-dialog__dialog[data-placement=auto]{margin-top:auto}@media(min-width:40rem){.alert-dialog__dialog[data-placement=auto]{margin-block:auto}}.alert-dialog__dialog[data-placement=center]{margin-block:auto}.alert-dialog__dialog[data-placement=bottom]{margin-top:auto}.alert-dialog__dialog[data-placement=top]{margin-top:0}.alert-dialog__dialog--xs{max-width:var(--container-xs)}.alert-dialog__dialog--sm{max-width:var(--container-sm)}.alert-dialog__dialog--md{max-width:var(--container-md)}.alert-dialog__dialog--lg{max-width:var(--container-lg)}.alert-dialog__dialog--cover{width:100%;height:100%;min-height:100%}.alert-dialog__header{gap:calc(var(--spacing) * 3);flex-direction:column;margin-bottom:0;display:flex}.alert-dialog__header>.modal__icon{margin-bottom:0}.alert-dialog__heading{vertical-align:middle;font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--foreground)}.alert-dialog__icon{width:calc(var(--spacing) * 10);height:calc(var(--spacing) * 10);border-radius:calc(var(--radius) * 3);-webkit-user-select:none;user-select:none;flex-shrink:0;justify-content:center;align-items:center;display:flex}.alert-dialog__icon [data-slot=alert-dialog-default-icon]{box-sizing:content-box;width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5)}.alert-dialog__icon--default{background-color:var(--default);color:var(--foreground)}.alert-dialog__icon--accent{background-color:var(--accent-soft);color:var(--accent-soft-foreground)}.alert-dialog__icon--success{background-color:var(--success-soft);color:var(--success-soft-foreground)}.alert-dialog__icon--warning{background-color:var(--warning-soft);color:var(--warning-soft-foreground)}.alert-dialog__icon--danger{background-color:var(--danger-soft);color:var(--danger-soft-foreground)}.alert-dialog__body{scrollbar-width:var(--scrollbar-width);scrollbar-color:var(--scrollbar-color);scrollbar-gutter:var(--scrollbar-gutter);min-height:0;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-leading:1.43;color:var(--muted);overscroll-behavior:contain;-webkit-overflow-scrolling:touch;margin:-3px;flex:1;margin-block:0;padding:3px;line-height:1.43;overflow-y:auto}.alert-dialog__footer{justify-content:flex-end;align-items:center;gap:calc(var(--spacing) * 2);flex-direction:row;margin-top:0;display:flex}.alert-dialog__close-trigger{top:calc(var(--spacing) * 4);right:calc(var(--spacing) * 4);position:absolute}.alert-dialog__header+.alert-dialog__body{margin-top:calc(var(--spacing) * 2)}.alert-dialog__header+.alert-dialog__footer,.alert-dialog__body+.alert-dialog__footer{margin-top:calc(var(--spacing) * 5)}.drawer__trigger{cursor:var(--cursor-interactive);transition:transform .25s var(--ease-out-quart),background-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out);display:inline-block}.drawer__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *),.drawer__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.drawer__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.drawer__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.drawer__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.drawer__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.drawer__trigger:focus-visible:not(:focus),.drawer__trigger[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.drawer__trigger:disabled,.drawer__trigger[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.drawer__trigger:active,.drawer__trigger[data-pressed=true]{transform:scale(.97)}.drawer__backdrop{z-index:50;height:var(--visual-viewport-height);opacity:1;width:100%;transition:opacity .25s cubic-bezier(.32,.72,0,1);position:fixed;top:0;right:0;bottom:0;left:0}.drawer__backdrop[data-entering=true]{opacity:0}.drawer__backdrop[data-exiting=true]{opacity:0;transition-duration:.2s;transition-timing-function:cubic-bezier(.32,.72,0,1)}.drawer__backdrop[data-exiting=true],.drawer__backdrop[data-entering=true]{will-change:opacity}@media(prefers-reduced-motion:reduce){.drawer__backdrop{transition:none}}.drawer__backdrop--transparent{background-color:#0000}.drawer__backdrop--opaque{background-color:var(--backdrop)}.drawer__backdrop--blur{background-color:var(--backdrop);--tw-backdrop-blur:blur(var(--blur-md));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.drawer__content{pointer-events:none;z-index:50;height:var(--visual-viewport-height);width:100%;min-width:0;display:flex;position:fixed;top:0;right:0;bottom:0;left:0}.drawer__content--bottom{align-items:flex-end}.drawer__content--top{align-items:flex-start}.drawer__content--left{justify-content:flex-start}.drawer__content--right{justify-content:flex-end}.drawer__dialog{background-color:var(--overlay);--tw-shadow:var(--overlay-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;padding:calc(var(--spacing) * 6);pointer-events:auto;--drawer-enter-duration:.25s;--drawer-exit-duration:.2s;--drawer-enter-ease:cubic-bezier(.32, .72, 0, 1);--drawer-exit-ease:cubic-bezier(.32, .72, 0, 1);will-change:translate;transition:translate var(--drawer-enter-duration) var(--drawer-enter-ease);outline-style:none;flex-direction:column;display:flex;position:relative}@media(prefers-reduced-motion:reduce){.drawer__dialog{transition:none}}.drawer__dialog[data-placement=bottom]{border-top-left-radius:min(32px,var(--radius-2xl));border-top-right-radius:min(32px,var(--radius-2xl));width:100%;max-height:85vh}.drawer__dialog[data-placement=top]{border-bottom-left-radius:min(32px,var(--radius-2xl));border-bottom-right-radius:min(32px,var(--radius-2xl));width:100%;max-height:85vh}.drawer__dialog[data-placement=left]{height:100%;width:calc(var(--spacing) * 80);border-radius:0;max-width:85vw}@media(min-width:40rem){.drawer__dialog[data-placement=left]{width:calc(var(--spacing) * 96)}}.drawer__dialog[data-placement=right]{height:100%;width:calc(var(--spacing) * 80);border-radius:0;max-width:85vw}@media(min-width:40rem){.drawer__dialog[data-placement=right]{width:calc(var(--spacing) * 96)}}[data-exiting=true] .drawer__dialog{transition-duration:var(--drawer-exit-duration);transition-timing-function:var(--drawer-exit-ease)}.drawer__content--left .drawer__dialog,.drawer__content--right .drawer__dialog,.drawer__content--top .drawer__dialog,.drawer__content--bottom .drawer__dialog{translate:0}.drawer__content--left[data-entering=true] .drawer__dialog,.drawer__content--left[data-exiting=true] .drawer__dialog{translate:-100%}.drawer__content--right[data-entering=true] .drawer__dialog,.drawer__content--right[data-exiting=true] .drawer__dialog{translate:100%}.drawer__content--top[data-entering=true] .drawer__dialog,.drawer__content--top[data-exiting=true] .drawer__dialog{translate:0 -100%}.drawer__content--bottom[data-entering=true] .drawer__dialog,.drawer__content--bottom[data-exiting=true] .drawer__dialog{translate:0 100%}.drawer__dialog--top{padding-bottom:calc(var(--spacing) * 2)}.drawer__dialog--top .drawer__handle{padding-bottom:0}.drawer__header{gap:calc(var(--spacing) * 3);flex-direction:column;margin-bottom:0;display:flex}.drawer__heading{vertical-align:middle;font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--foreground)}.drawer__body{scrollbar-width:var(--scrollbar-width);scrollbar-color:var(--scrollbar-color);scrollbar-gutter:var(--scrollbar-gutter);min-height:0;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-leading:1.43;color:var(--muted);overscroll-behavior:contain;-webkit-overflow-scrolling:touch;margin:-3px;flex:1;margin-block:0;padding:3px;line-height:1.43;overflow-y:auto}.drawer__footer{justify-content:flex-end;align-items:center;gap:calc(var(--spacing) * 2);flex-direction:row;margin-top:0;display:flex}.drawer__handle{padding-bottom:calc(var(--spacing) * 2);justify-content:center;align-items:center;display:flex}.drawer__handle>[data-slot=drawer-handle-bar]{height:var(--spacing);width:calc(var(--spacing) * 9);border-radius:calc(var(--radius) * .25);background-color:var(--separator)}.drawer__close-trigger{top:calc(var(--spacing) * 4);right:calc(var(--spacing) * 4);position:absolute}.drawer__header+.drawer__body{margin-top:calc(var(--spacing) * 2)}.drawer__header+.drawer__footer,.drawer__body+.drawer__footer{margin-top:calc(var(--spacing) * 5)}.drawer__handle+.drawer__header,.drawer__handle+.drawer__body{margin-top:0}.modal__trigger{cursor:var(--cursor-interactive);transition:transform .25s var(--ease-out-quart),background-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out);display:inline-block}.modal__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *),.modal__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.modal__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.modal__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.modal__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.modal__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.modal__trigger:focus-visible:not(:focus),.modal__trigger[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.modal__trigger:disabled,.modal__trigger[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.modal__trigger:active,.modal__trigger[data-pressed=true]{transform:scale(.97)}.modal__backdrop{z-index:50;height:var(--visual-viewport-height);flex-direction:row;justify-content:center;align-items:center;width:100%;display:flex;position:fixed;top:0;right:0;bottom:0;left:0}.modal__backdrop[data-entering=true]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.15s;--tw-ease:var(--ease-out);transition-duration:.15s;transition-timing-function:var(--ease-out);--tw-enter-opacity:0}.modal__backdrop[data-exiting=true]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.1s;--tw-ease:var(--ease-out);transition-duration:.1s;transition-timing-function:var(--ease-out);--tw-exit-opacity:0}.modal__backdrop[data-exiting=true],.modal__backdrop[data-entering=true]{will-change:opacity}:is(.modal__backdrop[data-exiting=true],.modal__backdrop[data-entering=true]):is([data-reduce-motion=true],[data-reduce-motion=true] *),:is(.modal__backdrop[data-exiting=true],.modal__backdrop[data-entering=true]):is([data-reduce-motion=true],[data-reduce-motion=true] *):before,:is(.modal__backdrop[data-exiting=true],.modal__backdrop[data-entering=true]):is([data-reduce-motion=true],[data-reduce-motion=true] *):after{animation:none}@media(prefers-reduced-motion:reduce){:is(.modal__backdrop[data-exiting=true],.modal__backdrop[data-entering=true]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),:is(.modal__backdrop[data-exiting=true],.modal__backdrop[data-entering=true]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,:is(.modal__backdrop[data-exiting=true],.modal__backdrop[data-entering=true]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{animation:none}}.modal__backdrop--transparent{background-color:#0000}.modal__backdrop--opaque{background-color:var(--backdrop)}.modal__backdrop--blur{background-color:var(--backdrop);--tw-backdrop-blur:blur(var(--blur-md));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.modal__container{height:var(--visual-viewport-height);width:100%;min-width:0;padding:calc(var(--spacing) * 4);flex-direction:column;flex:1;align-items:center;display:flex}@media(min-width:40rem){.modal__container{width:fit-content;padding:calc(var(--spacing) * 10)}}.modal__container{pointer-events:none}.modal__container[data-entering=true]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.25s;--tw-ease:cubic-bezier(.25, .46, .45, .94);--tw-enter-opacity:0;--tw-enter-scale: 105% ;transition-duration:.25s;transition-timing-function:cubic-bezier(.25,.46,.45,.94)}.modal__container[data-entering=true][data-placement=auto]{--tw-enter-translate-y:calc(1*var(--spacing))}@media(min-width:40rem){.modal__container[data-entering=true][data-placement=auto]{--tw-enter-translate-y: 0% }}.modal__container[data-entering=true][data-placement=top]{--tw-enter-translate-y:calc(1*var(--spacing)*-1)}.modal__container[data-entering=true][data-placement=center]{--tw-enter-translate-y: -0% }.modal__container[data-entering=true][data-placement=bottom]{--tw-enter-translate-y:calc(1*var(--spacing))}.modal__container[data-exiting=true]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.1s;--tw-ease:cubic-bezier(.25, .46, .45, .94);--tw-exit-opacity:0;--tw-exit-scale:.95;transition-duration:.1s;transition-timing-function:cubic-bezier(.25,.46,.45,.94)}.modal__container[data-exiting=true],.modal__container[data-entering=true]{will-change:opacity,transform}:is(.modal__container[data-exiting=true],.modal__container[data-entering=true]):is([data-reduce-motion=true],[data-reduce-motion=true] *),:is(.modal__container[data-exiting=true],.modal__container[data-entering=true]):is([data-reduce-motion=true],[data-reduce-motion=true] *):before,:is(.modal__container[data-exiting=true],.modal__container[data-entering=true]):is([data-reduce-motion=true],[data-reduce-motion=true] *):after{animation:none}@media(prefers-reduced-motion:reduce){:is(.modal__container[data-exiting=true],.modal__container[data-entering=true]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),:is(.modal__container[data-exiting=true],.modal__container[data-entering=true]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,:is(.modal__container[data-exiting=true],.modal__container[data-entering=true]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{animation:none}}.modal__container--scroll-outside{scrollbar-width:var(--scrollbar-width);scrollbar-color:var(--scrollbar-color);scrollbar-gutter:var(--scrollbar-gutter);pointer-events:auto;-webkit-overflow-scrolling:touch;overflow-y:auto}.modal__container--full{padding:0}@media(min-width:40rem){.modal__container--full{padding:0}}.modal__container--full[data-entering=true]{--tw-enter-translate-y: 0% ;--tw-enter-scale:1}@media(min-width:40rem){.modal__container--full[data-entering=true]{--tw-enter-translate-y: 0% }}.modal__container--full[data-exiting=true]{--tw-exit-scale:1}.modal__dialog{background-color:var(--overlay);--tw-shadow:var(--overlay-shadow);width:100%;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;border-radius:min(32px,var(--radius-3xl));padding:calc(var(--spacing) * 6);pointer-events:auto;outline-style:none;flex-direction:column;display:flex;position:relative}.modal__dialog[data-placement=auto]{margin-top:auto}@media(min-width:40rem){.modal__dialog[data-placement=auto]{margin-block:auto}}.modal__dialog[data-placement=center]{margin-block:auto}.modal__dialog[data-placement=bottom]{margin-top:auto}.modal__dialog[data-placement=top]{margin-top:0}.modal__dialog--scroll-inside{min-height:0;max-height:100%;overflow:clip}.modal__dialog--scroll-outside{flex-shrink:0;height:auto;min-height:0}.modal__dialog--xs{max-width:var(--container-xs)}.modal__dialog--sm{max-width:var(--container-sm)}.modal__dialog--md{max-width:var(--container-md)}.modal__dialog--lg{max-width:var(--container-lg)}.modal__dialog--cover{width:100%;height:100%;min-height:100%}.modal__dialog--full{--tw-shadow:0 0 #0000;width:100%;height:100%;min-height:100%;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);border-radius:0}.modal__header{gap:calc(var(--spacing) * 3);flex-direction:column;margin-bottom:0;display:flex}.modal__header>.modal__icon{margin-bottom:0}.modal__heading{vertical-align:middle;font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--foreground)}.modal__icon{width:calc(var(--spacing) * 10);height:calc(var(--spacing) * 10);border-radius:calc(var(--radius) * 3);-webkit-user-select:none;user-select:none;flex-shrink:0;justify-content:center;align-items:center;display:flex}.modal__body{min-height:0;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-leading:1.43;color:var(--muted);margin:-3px;flex:1;margin-block:0;padding:3px;line-height:1.43;overflow:visible}.modal__body--scroll-inside{scrollbar-width:var(--scrollbar-width);scrollbar-color:var(--scrollbar-color);scrollbar-gutter:var(--scrollbar-gutter);overscroll-behavior:contain;-webkit-overflow-scrolling:touch;overflow-y:auto}.modal__body--scroll-outside{overflow-y:visible}.modal__footer{justify-content:flex-end;align-items:center;gap:calc(var(--spacing) * 2);flex-direction:row;margin-top:0;display:flex}.modal__close-trigger{top:calc(var(--spacing) * 4);right:calc(var(--spacing) * 4);position:absolute}.modal__header+.modal__body{margin-top:calc(var(--spacing) * 2)}.modal__header+.modal__footer,.modal__body+.modal__footer{margin-top:calc(var(--spacing) * 5)}.popover{transform-origin:var(--trigger-anchor-point);background-color:var(--overlay);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));border-radius:min(32px,var(--radius-3xl));box-shadow:var(--shadow-overlay);padding:0}.popover[data-entering=true]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.15s;--tw-ease:ease;--tw-enter-opacity:0;--tw-enter-scale:.9;transition-duration:.15s;transition-timing-function:ease}.popover[data-entering=true][data-placement=top]{--tw-enter-translate-y:calc(1*var(--spacing))}.popover[data-entering=true][data-placement=bottom]{--tw-enter-translate-y:calc(1*var(--spacing)*-1)}.popover[data-entering=true][data-placement=left]{--tw-enter-translate-x:calc(1*var(--spacing))}.popover[data-entering=true][data-placement=right]{--tw-enter-translate-x:calc(1*var(--spacing)*-1)}.popover[data-exiting=true]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.1s;--tw-ease:ease;--tw-exit-scale:.95;--tw-exit-opacity:0;transition-duration:.1s;transition-timing-function:ease}.popover[data-exiting=true],.popover[data-entering=true]{transition-property:opacity,transform;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));will-change:opacity,transform}.popover [data-slot=popover-overlay-arrow]{fill:var(--overlay)}.popover[data-placement=bottom] [data-slot=popover-overlay-arrow]{rotate:180deg}.popover[data-placement=left] [data-slot=popover-overlay-arrow]{rotate:-90deg}.popover[data-placement=right] [data-slot=popover-overlay-arrow]{rotate:90deg}.popover__dialog{padding:calc(var(--spacing) * 4);--tw-outline-style:none;outline-style:none}.popover__heading{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.popover__trigger{transition:color .15s var(--ease-smooth),background-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out);display:inline-block}.popover__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *),.popover__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.popover__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.popover__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.popover__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.popover__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.popover__trigger{cursor:var(--cursor-interactive)}.popover__trigger:focus-visible:not(:focus),.popover__trigger[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.popover__trigger:disabled,.popover__trigger[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.tooltip{max-width:var(--container-xs);transform-origin:var(--trigger-anchor-point);background-color:var(--overlay);padding:calc(var(--spacing) * 2);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));word-break:break-all;border-radius:min(32px,var(--radius-xl));box-shadow:var(--shadow-overlay)}.tooltip[data-entering=true]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.15s;--tw-ease:ease;--tw-enter-opacity:0;--tw-enter-scale:.9;transition-duration:.15s;transition-timing-function:ease}.tooltip[data-entering=true][data-placement=top]{--tw-enter-translate-y:calc(1*var(--spacing))}.tooltip[data-entering=true][data-placement=bottom]{--tw-enter-translate-y:calc(1*var(--spacing)*-1)}.tooltip[data-entering=true][data-placement=left]{--tw-enter-translate-x:calc(1*var(--spacing))}.tooltip[data-entering=true][data-placement=right]{--tw-enter-translate-x:calc(1*var(--spacing)*-1)}.tooltip[data-exiting=true]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.1s;--tw-ease:ease;--tw-exit-scale:.95;--tw-exit-opacity:0;transition-duration:.1s;transition-timing-function:ease}.tooltip[data-exiting=true],.tooltip[data-entering=true]{transition-property:opacity,transform;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));will-change:opacity,transform}.tooltip [data-slot=overlay-arrow]{stroke:var(--border)}@supports (color:color-mix(in lab,red,red)){.tooltip [data-slot=overlay-arrow]{stroke:color-mix(in oklab,var(--border) 40%,transparent)}}.tooltip [data-slot=overlay-arrow]{fill:var(--overlay)}.tooltip[data-placement=bottom] [data-slot=overlay-arrow]{rotate:180deg}.tooltip[data-placement=left] [data-slot=overlay-arrow]{rotate:-90deg}.tooltip[data-placement=right] [data-slot=overlay-arrow]{rotate:90deg}.tooltip__trigger{transition:color .15s var(--ease-smooth),background-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out);display:inline-block}.tooltip__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *),.tooltip__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.tooltip__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.tooltip__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.tooltip__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.tooltip__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.tooltip__trigger:focus-visible:not(:focus),.tooltip__trigger[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.combo-box{gap:var(--spacing);flex-direction:column;display:flex}:is(.combo-box[data-invalid=true],.combo-box[aria-invalid=true]) [data-slot=description]{display:none}.combo-box [data-slot=label]{width:fit-content}.combo-box [data-slot=input]{flex:1;min-width:0}.combo-box [data-slot=input]:has(+.combo-box__trigger){padding-inline-end:calc(var(--spacing) * 7)}.combo-box [data-slot=input]:focus,.combo-box [data-slot=input][data-focus]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-outline-style:none;--tw-ring-offset-width:0px;border-color:var(--field-border-focus);background-color:var(--field-focus);outline-style:none}.combo-box [data-slot=input]:disabled,.combo-box [data-slot=input][data-disabled],.combo-box [data-slot=input][aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.combo-box__input-group{isolation:isolate;align-items:center;display:inline-flex;position:relative}.combo-box__trigger{--tw-translate-y: -50% ;height:100%;translate:var(--tw-translate-x) var(--tw-translate-y);cursor:pointer;color:var(--field-placeholder,var(--muted));transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.15s;-webkit-tap-highlight-color:transparent;--tw-border-style:none;--tw-outline-style:none;inset-inline-end:calc(var(--spacing) * 0);background-color:#0000;border-style:none;outline-style:none;flex-shrink:0;justify-content:center;align-items:center;padding-inline-end:calc(var(--spacing) * 2);transition-duration:.15s;display:flex;position:absolute;top:50%}@media(hover:hover){.combo-box__trigger:hover,.combo-box__trigger[data-hovered=true]{color:var(--field-foreground,var(--foreground))}}.combo-box__trigger:focus-visible:not(:focus),.combo-box__trigger[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;border-radius:.25rem;outline-style:none}.combo-box__trigger[data-pressed=true]{opacity:.7}.combo-box__trigger:disabled,.combo-box__trigger[data-disabled],.combo-box__trigger[aria-disabled=true]{cursor:not-allowed;opacity:.5}.combo-box__trigger [data-slot=combo-box-trigger-default-icon]{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4);transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.15s;transition-duration:.15s}.combo-box__trigger [data-slot=combo-box-trigger-default-icon]:is([data-reduce-motion=true],[data-reduce-motion=true] *),.combo-box__trigger [data-slot=combo-box-trigger-default-icon]:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.combo-box__trigger [data-slot=combo-box-trigger-default-icon]:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.combo-box__trigger [data-slot=combo-box-trigger-default-icon]:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.combo-box__trigger [data-slot=combo-box-trigger-default-icon]:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.combo-box__trigger [data-slot=combo-box-trigger-default-icon]:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.combo-box__trigger[data-open=true] [data-slot=combo-box-trigger-default-icon]{rotate:180deg}.combo-box__popover{min-width:var(--trigger-width);transform-origin:var(--trigger-anchor-point);scroll-padding-block:var(--spacing);scrollbar-width:var(--scrollbar-width);scrollbar-color:var(--scrollbar-color);scrollbar-gutter:var(--scrollbar-gutter);overscroll-behavior:contain;background-color:var(--overlay);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));border-radius:min(32px,var(--radius-3xl));box-shadow:var(--shadow-overlay);padding:0;overflow-y:auto}.combo-box__popover:focus-visible:not(:focus),.combo-box__popover[data-focus-visible=true]{--tw-outline-style:none;outline-style:none}.combo-box__popover[data-entering=true]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.15s;--tw-ease:ease;--tw-enter-opacity:0;--tw-enter-scale:.95;transition-duration:.15s;transition-timing-function:ease}.combo-box__popover[data-entering=true][data-placement=top]{--tw-enter-translate-y:calc(1*var(--spacing))}.combo-box__popover[data-entering=true][data-placement=bottom]{--tw-enter-translate-y:calc(1*var(--spacing)*-1)}.combo-box__popover[data-entering=true][data-placement=left]{--tw-enter-translate-x:calc(1*var(--spacing))}.combo-box__popover[data-entering=true][data-placement=right]{--tw-enter-translate-x:calc(1*var(--spacing)*-1)}.combo-box__popover[data-exiting=true]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.1s;--tw-ease:ease;--tw-exit-scale:.95;--tw-exit-opacity:0;transition-duration:.1s;transition-timing-function:ease}.combo-box__popover[data-exiting=true],.combo-box__popover[data-entering=true]{transition-property:opacity,transform;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));will-change:opacity,transform}.combo-box__popover [data-slot=popover-overlay-arrow]{fill:var(--overlay)}.combo-box__popover[data-placement=bottom] [data-slot=popover-overlay-arrow]{rotate:180deg}.combo-box__popover[data-placement=left] [data-slot=popover-overlay-arrow]{rotate:-90deg}.combo-box__popover[data-placement=right] [data-slot=popover-overlay-arrow]{rotate:90deg}.combo-box__popover [data-slot=list-box]{padding:calc(var(--spacing) * 1.5);--tw-outline-style:none;outline-style:none}.combo-box__popover [data-slot=list-box-item]{padding-inline:calc(var(--spacing) * 2.5)}.combo-box__popover [data-slot=list-box-item] [data-slot=list-box-item-indicator--checkmark]{transition-property:none}.combo-box--full-width,.combo-box__input-group--full-width{width:100%}.select{gap:var(--spacing);flex-direction:column;display:flex}:is(.select[data-invalid=true],.select[aria-invalid=true]) [data-slot=description]{display:none}.select [data-slot=label]{width:fit-content}.select__trigger{isolation:isolate;min-height:calc(var(--spacing) * 9);border-radius:var(--field-radius,calc(var(--radius) * 1.5));border-style:var(--tw-border-style);background-color:var(--field-background,var(--default));padding-inline:calc(var(--spacing) * 3);padding-block:calc(var(--spacing) * 2);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--field-foreground,var(--foreground));--tw-shadow:var(--field-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;transition:background-color .15s var(--ease-smooth),border-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out);border-width:1px;outline-style:none;display:inline-flex;position:relative}.select__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *),.select__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.select__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.select__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.select__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.select__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.select__trigger{cursor:var(--cursor-interactive);border-width:var(--border-width-field);border-color:var(--field-border)}.select__trigger:has(.select__indicator){padding-inline-end:calc(var(--spacing) * 7)}@media(hover:hover){.select__trigger:hover,.select__trigger[data-hovered=true]{background-color:var(--field-hover);border-color:var(--field-border-hover)}}.select__trigger:focus-visible:not(:focus),.select__trigger[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;border-color:var(--field-border-focus);background-color:var(--field-focus);outline-style:none}.select[data-invalid=true] .select__trigger,.select[aria-invalid=true] .select__trigger{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}:is(.select[data-invalid=true] .select__trigger,.select[aria-invalid=true] .select__trigger):focus,:is(.select[data-invalid=true] .select__trigger,.select[aria-invalid=true] .select__trigger):focus-visible,:is(.select[data-invalid=true] .select__trigger,.select[aria-invalid=true] .select__trigger)[data-focused=true],:is(.select[data-invalid=true] .select__trigger,.select[aria-invalid=true] .select__trigger)[data-focus-visible=true],:is(.select[data-invalid=true] .select__trigger,.select[aria-invalid=true] .select__trigger):focus-within,:is(.select[data-invalid=true] .select__trigger,.select[aria-invalid=true] .select__trigger)[data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.select[data-invalid=true] .select__trigger,.select[aria-invalid=true] .select__trigger{background-color:var(--field-focus)}.select__trigger:disabled,.select__trigger[data-disabled=true],.select__trigger[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.select--secondary .select__trigger{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);background-color:var(--select-trigger-bg);--select-trigger-bg:var(--default);--select-trigger-bg-hover:var(--default-hover);--select-trigger-bg-focus:var(--default)}@media(hover:hover){.select--secondary .select__trigger:hover,.select--secondary .select__trigger[data-hovered=true]{background-color:var(--select-trigger-bg-hover)}}.select--secondary .select__trigger:focus-visible:not(:focus),.select--secondary .select__trigger[data-focus-visible=true],.select[data-invalid=true] :is(.select--secondary .select__trigger),.select[aria-invalid=true] :is(.select--secondary .select__trigger){background-color:var(--select-trigger-bg-focus)}.select__value{text-align:start;font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));overflow-wrap:break-word;color:currentColor;flex:1}@media(min-width:40rem){.select__value{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}.select__value[data-placeholder=true]{color:var(--field-placeholder,var(--muted))}.select__value [data-slot=list-box-item-indicator]{display:none}.select__indicator{color:var(--field-placeholder,var(--muted));transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.15s;flex-shrink:0;justify-content:center;align-items:center;margin-block:auto;transition-duration:.15s;display:flex;position:absolute;inset-block:0;inset-inline-end:calc(var(--spacing) * 2)}.select__indicator[data-open=true]{rotate:180deg}.select__indicator[data-slot=select-default-indicator]{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.select__popover{min-width:var(--trigger-width);transform-origin:var(--trigger-anchor-point);scroll-padding-block:var(--spacing);scrollbar-width:var(--scrollbar-width);scrollbar-color:var(--scrollbar-color);scrollbar-gutter:var(--scrollbar-gutter);overscroll-behavior:contain;background-color:var(--overlay);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));border-radius:min(32px,var(--radius-3xl));box-shadow:var(--shadow-overlay);padding:0;overflow-y:auto}.select__popover:focus-visible:not(:focus),.select__popover[data-focus-visible=true]{--tw-outline-style:none;outline-style:none}.select__popover[data-entering=true]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.15s;--tw-ease:ease;--tw-enter-opacity:0;--tw-enter-scale:.95;transition-duration:.15s;transition-timing-function:ease}.select__popover[data-entering=true][data-placement=top]{--tw-enter-translate-y:calc(1*var(--spacing))}.select__popover[data-entering=true][data-placement=bottom]{--tw-enter-translate-y:calc(1*var(--spacing)*-1)}.select__popover[data-entering=true][data-placement=left]{--tw-enter-translate-x:calc(1*var(--spacing))}.select__popover[data-entering=true][data-placement=right]{--tw-enter-translate-x:calc(1*var(--spacing)*-1)}.select__popover[data-exiting=true]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.1s;--tw-ease:ease;--tw-exit-scale:.95;--tw-exit-opacity:0;transition-duration:.1s;transition-timing-function:ease}.select__popover[data-exiting=true],.select__popover[data-entering=true]{transition-property:opacity,transform;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));will-change:opacity,transform}.select__popover [data-slot=popover-overlay-arrow]{fill:var(--overlay)}.select__popover[data-placement=bottom] [data-slot=popover-overlay-arrow]{rotate:180deg}.select__popover[data-placement=left] [data-slot=popover-overlay-arrow]{rotate:-90deg}.select__popover[data-placement=right] [data-slot=popover-overlay-arrow]{rotate:90deg}.select__popover [data-slot=list-box]{padding:calc(var(--spacing) * 1.5);--tw-outline-style:none;outline-style:none}.select__popover [data-slot=list-box-item]{padding-inline:calc(var(--spacing) * 2.5)}.select__popover [data-slot=list-box]:not([aria-multiselectable=true]) [data-slot=list-box-item-indicator],.select__popover [data-slot=list-box]:not([aria-multiselectable=true]) [data-slot=list-box-item-indicator] [data-slot=list-box-item-indicator--checkmark]{transition-property:none}.select--full-width,.select__trigger--full-width{width:100%}.autocomplete{gap:var(--spacing);flex-direction:column;display:flex}.autocomplete__trigger{isolation:isolate;min-height:calc(var(--spacing) * 9);border-radius:var(--field-radius,calc(var(--radius) * 1.5));border-style:var(--tw-border-style);background-color:var(--field-background,var(--default));padding-inline:calc(var(--spacing) * 3);padding-block:calc(var(--spacing) * 2);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--field-foreground,var(--foreground));--tw-shadow:var(--field-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;transition:background-color .15s var(--ease-smooth),border-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out);border-width:1px;outline-style:none;display:inline-flex;position:relative}.autocomplete__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *),.autocomplete__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.autocomplete__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.autocomplete__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.autocomplete__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.autocomplete__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.autocomplete__trigger{cursor:var(--cursor-interactive);border-width:var(--border-width-field);border-color:var(--field-border)}.autocomplete__trigger:has(.autocomplete__indicator){padding-inline-end:calc(var(--spacing) * 7)}@media(hover:hover){.autocomplete__trigger:hover:not(:has(.autocomplete__clear-button:hover)),.autocomplete__trigger[data-hovered=true]:not(:has(.autocomplete__clear-button:hover)){background-color:var(--field-hover);border-color:var(--field-border-hover)}}.autocomplete__trigger:focus-visible:not(:focus),.autocomplete__trigger[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;border-color:var(--field-border-focus);background-color:var(--field-focus);outline-style:none}.autocomplete[data-invalid=true] .autocomplete__trigger,.autocomplete[aria-invalid=true] .autocomplete__trigger{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}:is(.autocomplete[data-invalid=true] .autocomplete__trigger,.autocomplete[aria-invalid=true] .autocomplete__trigger):focus,:is(.autocomplete[data-invalid=true] .autocomplete__trigger,.autocomplete[aria-invalid=true] .autocomplete__trigger):focus-visible,:is(.autocomplete[data-invalid=true] .autocomplete__trigger,.autocomplete[aria-invalid=true] .autocomplete__trigger)[data-focused=true],:is(.autocomplete[data-invalid=true] .autocomplete__trigger,.autocomplete[aria-invalid=true] .autocomplete__trigger)[data-focus-visible=true],:is(.autocomplete[data-invalid=true] .autocomplete__trigger,.autocomplete[aria-invalid=true] .autocomplete__trigger):focus-within,:is(.autocomplete[data-invalid=true] .autocomplete__trigger,.autocomplete[aria-invalid=true] .autocomplete__trigger)[data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.autocomplete[data-invalid=true] .autocomplete__trigger,.autocomplete[aria-invalid=true] .autocomplete__trigger{background-color:var(--field-focus)}.autocomplete__trigger:disabled,.autocomplete__trigger[data-disabled=true],.autocomplete__trigger[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.autocomplete--secondary .autocomplete__trigger{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);background-color:var(--autocomplete-trigger-bg);--autocomplete-trigger-bg:var(--default);--autocomplete-trigger-bg-hover:var(--default-hover);--autocomplete-trigger-bg-focus:var(--default)}@media(hover:hover){.autocomplete--secondary .autocomplete__trigger:hover:not(:has(.autocomplete__clear-button:hover)),.autocomplete--secondary .autocomplete__trigger[data-hovered=true]:not(:has(.autocomplete__clear-button:hover)){background-color:var(--autocomplete-trigger-bg-hover)}}.autocomplete--secondary .autocomplete__trigger:focus-visible:not(:focus),.autocomplete--secondary .autocomplete__trigger[data-focus-visible=true],.autocomplete[data-invalid=true] :is(.autocomplete--secondary .autocomplete__trigger),.autocomplete[aria-invalid=true] :is(.autocomplete--secondary .autocomplete__trigger){background-color:var(--autocomplete-trigger-bg-focus)}.autocomplete__value{text-align:start;font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));overflow-wrap:break-word;color:currentColor;flex:1}@media(min-width:40rem){.autocomplete__value{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}.autocomplete__value[data-placeholder=true]{color:var(--field-placeholder,var(--muted))}.autocomplete__value [data-slot=list-box-item-indicator]{display:none}.autocomplete__indicator{color:var(--field-placeholder,var(--muted));transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.15s;cursor:var(--cursor-interactive);flex-shrink:0;justify-content:center;align-items:center;margin-block:auto;transition-duration:.15s;display:flex;position:absolute;inset-block:0;inset-inline-end:calc(var(--spacing) * 2)}.autocomplete__indicator[data-open=true]{rotate:180deg}.autocomplete__indicator[data-slot=autocomplete-default-indicator]{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.autocomplete__popover{width:var(--trigger-width);max-width:var(--trigger-width);transform-origin:var(--trigger-anchor-point);scroll-padding-block:var(--spacing);overscroll-behavior:contain;background-color:var(--overlay);padding:0;padding-top:calc(var(--spacing) * 2);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));border-radius:min(32px,var(--radius-3xl));box-shadow:var(--shadow-overlay);overflow:hidden}.autocomplete__popover:focus-visible:not(:focus),.autocomplete__popover[data-focus-visible=true]{--tw-outline-style:none;outline-style:none}.autocomplete__popover[data-entering=true]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.25s;--tw-ease:cubic-bezier(.32, .72, 0, 1);--tw-enter-opacity:0;--tw-enter-scale:.95;transition-duration:.25s;transition-timing-function:cubic-bezier(.32,.72,0,1)}.autocomplete__popover[data-entering=true][data-placement=top]{--tw-enter-translate-y:calc(1*var(--spacing))}.autocomplete__popover[data-entering=true][data-placement=bottom]{--tw-enter-translate-y:calc(1*var(--spacing)*-1)}.autocomplete__popover[data-entering=true][data-placement=left]{--tw-enter-translate-x:calc(1*var(--spacing))}.autocomplete__popover[data-entering=true][data-placement=right]{--tw-enter-translate-x:calc(1*var(--spacing)*-1)}.autocomplete__popover[data-exiting=true]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.1s;--tw-ease:cubic-bezier(.25, .46, .45, .94);--tw-exit-scale:.95;--tw-exit-opacity:0;transition-duration:.1s;transition-timing-function:cubic-bezier(.25,.46,.45,.94)}.autocomplete__popover[data-exiting=true],.autocomplete__popover[data-entering=true]{transition-property:opacity,transform;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));will-change:opacity,transform}.autocomplete__popover [data-slot=popover-overlay-arrow]{fill:var(--overlay)}.autocomplete__popover[data-placement=bottom] [data-slot=popover-overlay-arrow]{rotate:180deg}.autocomplete__popover[data-placement=left] [data-slot=popover-overlay-arrow]{rotate:-90deg}.autocomplete__popover[data-placement=right] [data-slot=popover-overlay-arrow]{rotate:90deg}.autocomplete__popover [data-slot=list-box]{scrollbar-width:var(--scrollbar-width);scrollbar-color:var(--scrollbar-color);scrollbar-gutter:var(--scrollbar-gutter);max-height:320px;padding:calc(var(--spacing) * 1.5);--tw-outline-style:none;outline-style:none;overflow-y:auto}.autocomplete__popover [data-slot=list-box-item]{padding-inline:calc(var(--spacing) * 2.5)}.autocomplete__popover [data-slot=list-box]:not([aria-multiselectable=true]) [data-slot=list-box-item-indicator],.autocomplete__popover [data-slot=list-box]:not([aria-multiselectable=true]) [data-slot=list-box-item-indicator] [data-slot=list-box-item-indicator--checkmark]{transition-property:none}.autocomplete__popover [data-slot=search-field]{padding-inline:calc(var(--spacing) * 3);padding-block:var(--spacing);--tw-outline-style:none;outline-style:none}.autocomplete__popover [data-slot=empty-state]{text-align:center;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--overlay-foreground)}@supports (color:color-mix(in lab,red,red)){.autocomplete__popover [data-slot=empty-state]{color:color-mix(in oklab,var(--overlay-foreground) 60%,transparent)}}.autocomplete__popover-dialog,.autocomplete__popover-dialog:focus,.autocomplete__popover-dialog:focus-visible,.autocomplete__popover-dialog[data-focus-visible=true]{--tw-outline-style:none;outline-style:none}.autocomplete--full-width,.autocomplete__trigger--full-width{width:100%}.autocomplete__clear-button{isolation:isolate;height:calc(var(--spacing) * 6);width:calc(var(--spacing) * 6);transform-origin:50%;border-radius:calc(var(--radius) * 1.5);padding:var(--spacing);color:var(--muted);-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5);cursor:var(--cursor-interactive);transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);background-color:#0000;flex-shrink:0;justify-content:center;align-self:center;align-items:center;margin-inline-end:0;display:inline-flex;position:relative}.autocomplete__clear-button:not([data-empty=true]){transition:opacity .15s var(--ease-smooth)}.autocomplete__clear-button:not([data-empty=true]):is([data-reduce-motion=true],[data-reduce-motion=true] *),.autocomplete__clear-button:not([data-empty=true]):is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.autocomplete__clear-button:not([data-empty=true]):is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.autocomplete__clear-button:not([data-empty=true]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.autocomplete__clear-button:not([data-empty=true]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.autocomplete__clear-button:not([data-empty=true]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.autocomplete__clear-button[data-empty=true]{pointer-events:none;opacity:0}.autocomplete__clear-button [data-slot=autocomplete-clear-button-icon]{width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5)}@media(hover:hover){.autocomplete__clear-button:hover,.autocomplete__clear-button[data-hovered=true]{background-color:var(--default-hover)}}.autocomplete__clear-button:active,.autocomplete__clear-button[data-pressed=true]{transform:scale(.93)}.kbd{height:calc(var(--spacing) * 6);align-items:center;display:inline-flex}:where(.kbd>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing) * .5) * var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing) * .5) * calc(1 - var(--tw-space-x-reverse)))}.kbd{border-radius:calc(var(--radius) * 1);background-color:var(--default);padding-inline:calc(var(--spacing) * 2);text-align:center;font-family:var(--font-sans);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);white-space:nowrap;color:var(--muted)}:where(.kbd:where(:dir(rtl),[dir=rtl],[dir=rtl] *)>:not(:last-child)){--tw-space-x-reverse:1}.kbd{word-spacing:-.25rem}.kbd__abbr{justify-content:center;align-items:center;width:100%;height:100%;text-decoration:none;display:flex}.kbd__content{justify-content:center;align-items:center;display:flex}.kbd--light{background-color:#0000}.typography,.typography-prose{color:var(--foreground)}.typography-prose h1{font-size:var(--text-4xl);line-height:var(--tw-leading,var(--text-4xl--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.typography-prose h2{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.typography-prose h3{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.typography-prose h4{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.typography-prose h5{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.typography-prose h6{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.typography-prose p{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-leading:calc(var(--spacing) * 7);line-height:calc(var(--spacing) * 7)}.typography-prose code{border-radius:calc(var(--radius) * .75);background-color:var(--default);padding-inline:calc(var(--spacing) * 1.5);padding-block:calc(var(--spacing) * .5);font-family:var(--font-mono);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--foreground)}.typography-prose a{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--link);text-underline-offset:4px;text-decoration-line:underline}.typography-prose blockquote{margin-top:calc(var(--spacing) * 4);border-left-style:var(--tw-border-style);border-left-width:4px;border-color:var(--border);padding-left:calc(var(--spacing) * 4);color:var(--muted);font-style:italic}.typography-prose ul{margin-block:calc(var(--spacing) * 4);list-style-type:disc}:where(.typography-prose ul>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}.typography-prose ul{padding-left:calc(var(--spacing) * 6)}.typography-prose ol{margin-block:calc(var(--spacing) * 4);list-style-type:decimal}:where(.typography-prose ol>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}.typography-prose ol{padding-left:calc(var(--spacing) * 6)}.typography-prose li{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-leading:calc(var(--spacing) * 7);line-height:calc(var(--spacing) * 7)}.typography-prose hr{margin-block:calc(var(--spacing) * 8);border-color:var(--separator)}.typography-prose pre{margin-block:calc(var(--spacing) * 4);border-radius:calc(var(--radius) * 1.5);background-color:var(--default);padding:calc(var(--spacing) * 4);font-family:var(--font-mono);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed);overflow-x:auto}.typography-prose strong{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);color:var(--foreground)}.typography-prose em{font-style:italic}.typography-prose img{margin-block:calc(var(--spacing) * 4);border-radius:calc(var(--radius) * 1.5)}.typography--h1{font-size:var(--text-4xl);line-height:var(--tw-leading,var(--text-4xl--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.typography--h2{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.typography--h3{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.typography--h4{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.typography--h5{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.typography--h6{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.typography--body{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-leading:calc(var(--spacing) * 7);line-height:calc(var(--spacing) * 7)}.typography--body-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-leading:calc(var(--spacing) * 6);line-height:calc(var(--spacing) * 6)}.typography--body-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));--tw-leading:calc(var(--spacing) * 5);line-height:calc(var(--spacing) * 5)}.typography--code{border-radius:calc(var(--radius) * .75);background-color:var(--default);padding-inline:calc(var(--spacing) * 1.5);padding-block:calc(var(--spacing) * .5);font-family:var(--font-mono);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--foreground)}.typography--align-start{text-align:left}.typography--align-start:where(:dir(rtl),[dir=rtl],[dir=rtl] *){text-align:right}.typography--align-center{text-align:center}.typography--align-end{text-align:right}.typography--align-end:where(:dir(rtl),[dir=rtl],[dir=rtl] *){text-align:left}.typography--align-justify{text-align:justify}.typography--color-default{color:var(--foreground)}.typography--color-muted{color:var(--muted)}.typography--truncate{text-overflow:ellipsis;white-space:nowrap;display:block;overflow:hidden}.typography--weight-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.typography--weight-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.typography--weight-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.typography--weight-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.scroll-shadow{--scroll-shadow-size:40px;--scroll-shadow-scrollbar-size:10px;position:relative}.scroll-shadow--vertical{scrollbar-width:var(--scrollbar-width);scrollbar-color:var(--scrollbar-color);scrollbar-gutter:var(--scrollbar-gutter);overflow-y:auto}.scroll-shadow--horizontal{scrollbar-width:var(--scrollbar-width);scrollbar-color:var(--scrollbar-color);scrollbar-gutter:var(--scrollbar-gutter);overflow-x:auto}.scroll-shadow--fade.scroll-shadow--vertical:where([data-top-scroll=true],[data-bottom-scroll=true],[data-top-bottom-scroll=true]){mask-image:linear-gradient(var(--scroll-linear-gradient)),linear-gradient(#000,#000);mask-position:0 0,100% 0;mask-repeat:no-repeat;mask-size:calc(100% - var(--scroll-shadow-scrollbar-size)) 100%,var(--scroll-shadow-scrollbar-size) 100%;-webkit-mask-image:linear-gradient(var(--scroll-linear-gradient)),linear-gradient(#000,#000);-webkit-mask-position:0 0,100% 0;-webkit-mask-repeat:no-repeat;-webkit-mask-size:calc(100% - var(--scroll-shadow-scrollbar-size)) 100%,var(--scroll-shadow-scrollbar-size) 100%}.scroll-shadow--fade.scroll-shadow--vertical[data-top-scroll=true]{--scroll-linear-gradient:0deg, #000 calc(100% - var(--scroll-shadow-size)), transparent}.scroll-shadow--fade.scroll-shadow--vertical[data-bottom-scroll=true]{--scroll-linear-gradient:180deg, #000 calc(100% - var(--scroll-shadow-size)), transparent}.scroll-shadow--fade.scroll-shadow--vertical[data-top-bottom-scroll=true]{--scroll-linear-gradient:#000, #000, transparent 0, #000 var(--scroll-shadow-size), #000 calc(100% - var(--scroll-shadow-size)), transparent}.scroll-shadow--fade.scroll-shadow--horizontal:where([data-left-scroll=true],[data-right-scroll=true],[data-left-right-scroll=true]){mask-image:linear-gradient(var(--scroll-linear-gradient)),linear-gradient(#000,#000);mask-position:0 0,0 100%;mask-repeat:no-repeat;mask-size:100% calc(100% - var(--scroll-shadow-scrollbar-size)),100% var(--scroll-shadow-scrollbar-size);-webkit-mask-image:linear-gradient(var(--scroll-linear-gradient)),linear-gradient(#000,#000);-webkit-mask-position:0 0,0 100%;-webkit-mask-repeat:no-repeat;-webkit-mask-size:100% calc(100% - var(--scroll-shadow-scrollbar-size)),100% var(--scroll-shadow-scrollbar-size)}.scroll-shadow--fade.scroll-shadow--horizontal[data-left-scroll=true]{--scroll-linear-gradient:270deg, #000 calc(100% - var(--scroll-shadow-size)), transparent}.scroll-shadow--fade.scroll-shadow--horizontal[data-right-scroll=true]{--scroll-linear-gradient:90deg, #000 calc(100% - var(--scroll-shadow-size)), transparent}.scroll-shadow--fade.scroll-shadow--horizontal[data-left-right-scroll=true]{--scroll-linear-gradient:to right, #000, #000, transparent 0, #000 var(--scroll-shadow-size), #000 calc(100% - var(--scroll-shadow-size)), transparent}.scroll-shadow--hide-scrollbar{scrollbar-color:auto;scrollbar-gutter:auto;-ms-overflow-style:none;scrollbar-width:none;--scroll-shadow-scrollbar-size:0px}}@layer utilities{.pointer-events-auto{pointer-events:auto}.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.inset-0{top:0;right:0;bottom:0;left:0}.inset-x-0{inset-inline:0}.top-0{top:0}.top-4{top:calc(var(--spacing) * 4)}.top-full{top:100%}.-right-3{right:calc(var(--spacing) * -3)}.right-0{right:0}.right-4{right:calc(var(--spacing) * 4)}.bottom-4{bottom:calc(var(--spacing) * 4)}.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:30}.z-50{z-index:50}.container{width:100%}@media(min-width:40rem){.container{max-width:40rem}}@media(min-width:48rem){.container{max-width:48rem}}@media(min-width:64rem){.container{max-width:64rem}}@media(min-width:80rem){.container{max-width:80rem}}@media(min-width:96rem){.container{max-width:96rem}}.mx-1{margin-inline:var(--spacing)}.mx-2{margin-inline:calc(var(--spacing) * 2)}.mx-3{margin-inline:calc(var(--spacing) * 3)}.mx-auto{margin-inline:auto}.-mt-1{margin-top:calc(var(--spacing) * -1)}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:var(--spacing)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-auto{margin-top:auto}.-mr-1{margin-right:calc(var(--spacing) * -1)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.ml-auto{margin-left:auto}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.h-1{height:var(--spacing)}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-2{height:calc(var(--spacing) * 2)}.h-3\.5{height:calc(var(--spacing) * 3.5)}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-7{height:calc(var(--spacing) * 7)}.h-12{height:calc(var(--spacing) * 12)}.h-48{height:calc(var(--spacing) * 48)}.h-full{height:100%}.max-h-48{max-height:calc(var(--spacing) * 48)}.max-h-60{max-height:calc(var(--spacing) * 60)}.max-h-72{max-height:calc(var(--spacing) * 72)}.max-h-\[90vh\]{max-height:90vh}.min-h-0{min-height:0}.min-h-full{min-height:100%}.w-1\.5{width:calc(var(--spacing) * 1.5)}.w-2{width:calc(var(--spacing) * 2)}.w-3\.5{width:calc(var(--spacing) * 3.5)}.w-4{width:calc(var(--spacing) * 4)}.w-5{width:calc(var(--spacing) * 5)}.w-6{width:calc(var(--spacing) * 6)}.w-7{width:calc(var(--spacing) * 7)}.w-11{width:calc(var(--spacing) * 11)}.w-12{width:calc(var(--spacing) * 12)}.w-28{width:calc(var(--spacing) * 28)}.w-56{width:calc(var(--spacing) * 56)}.w-64{width:calc(var(--spacing) * 64)}.w-72{width:calc(var(--spacing) * 72)}.w-fit{width:fit-content}.w-full{width:100%}.w-px{width:1px}.max-w-2xl{max-width:var(--container-2xl)}.max-w-3xl{max-width:var(--container-3xl)}.max-w-40{max-width:calc(var(--spacing) * 40)}.max-w-44{max-width:calc(var(--spacing) * 44)}.max-w-\[1800px\]{max-width:1800px}.max-w-md{max-width:var(--container-md)}.max-w-sm{max-width:var(--container-sm)}.max-w-xs{max-width:var(--container-xs)}.min-w-0{min-width:0}.min-w-\[140px\]{min-width:140px}.min-w-\[180px\]{min-width:180px}.flex-1{flex:1}.shrink-0{flex-shrink:0}.table-fixed{table-layout:fixed}.border-collapse{border-collapse:collapse}.translate-x-0\.5{--tw-translate-x:calc(var(--spacing) * .5);translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-x-5{--tw-translate-x:calc(var(--spacing) * 5);translate:var(--tw-translate-x) var(--tw-translate-y)}.rotate-180{rotate:180deg}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.cursor-col-resize{cursor:col-resize}.cursor-pointer{cursor:pointer}.touch-none{touch-action:none}.resize{resize:both}.resize-none{resize:none}.list-disc{list-style-type:disc}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-row-reverse{flex-direction:row-reverse}.flex-wrap{flex-wrap:wrap}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-0\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:var(--spacing)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-5{gap:calc(var(--spacing) * 5)}.gap-6{gap:calc(var(--spacing) * 6)}.gap-x-4{column-gap:calc(var(--spacing) * 4)}.gap-y-1\.5{row-gap:calc(var(--spacing) * 1.5)}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-\[var\(--otari-line\)\]>:not(:last-child)){border-color:var(--otari-line)}.self-start{align-self:flex-start}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded-\[inherit\]{border-radius:inherit}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:calc(var(--radius) * 1)}.rounded-md{border-radius:calc(var(--radius) * .75)}.rounded-xl{border-radius:calc(var(--radius) * 1.5)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l-4{border-left-style:var(--tw-border-style);border-left-width:4px}.border-\[\#c2843a\]{border-color:#c2843a}.border-\[var\(--otari-brand\)\]{border-color:var(--otari-brand)}.border-\[var\(--otari-line\)\]{border-color:var(--otari-line)}.border-amber-200{border-color:var(--color-amber-200)}.border-emerald-200{border-color:var(--color-emerald-200)}.border-green-200{border-color:var(--color-green-200)}.border-red-200{border-color:var(--color-red-200)}.border-l-amber-500{border-left-color:var(--color-amber-500)}.border-l-emerald-500{border-left-color:var(--color-emerald-500)}.border-l-red-500{border-left-color:var(--color-red-500)}.bg-\[var\(--otari-bg\)\]{background-color:var(--otari-bg)}.bg-\[var\(--otari-brand\)\]{background-color:var(--otari-brand)}.bg-\[var\(--otari-brand-tint\)\]{background-color:var(--otari-brand-tint)}.bg-\[var\(--otari-line\)\]{background-color:var(--otari-line)}.bg-\[var\(--otari-surface\)\]{background-color:var(--otari-surface)}.bg-amber-50{background-color:var(--color-amber-50)}.bg-black\/40{background-color:#0006}@supports (color:color-mix(in lab,red,red)){.bg-black\/40{background-color:color-mix(in oklab,var(--color-black) 40%,transparent)}}.bg-emerald-50{background-color:var(--color-emerald-50)}.bg-green-50{background-color:var(--color-green-50)}.bg-green-500{background-color:var(--color-green-500)}.bg-red-50{background-color:var(--color-red-50)}.bg-red-500{background-color:var(--color-red-500)}.bg-transparent{background-color:#0000}.bg-white{background-color:var(--color-white)}.p-1{padding:var(--spacing)}.p-2{padding:calc(var(--spacing) * 2)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.p-6{padding:calc(var(--spacing) * 6)}.p-7{padding:calc(var(--spacing) * 7)}.px-0{padding-inline:0}.px-1{padding-inline:var(--spacing)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.px-6{padding-inline:calc(var(--spacing) * 6)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:var(--spacing)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-6{padding-block:calc(var(--spacing) * 6)}.py-10{padding-block:calc(var(--spacing) * 10)}.pt-0\.5{padding-top:calc(var(--spacing) * .5)}.pt-1{padding-top:var(--spacing)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-3{padding-top:calc(var(--spacing) * 3)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pr-1\.5{padding-right:calc(var(--spacing) * 1.5)}.pr-4{padding-right:calc(var(--spacing) * 4)}.pb-1{padding-bottom:var(--spacing)}.pl-4{padding-left:calc(var(--spacing) * 4)}.pl-5{padding-left:calc(var(--spacing) * 5)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.align-middle{vertical-align:middle}.font-mono{font-family:var(--font-mono)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.leading-5{--tw-leading:calc(var(--spacing) * 5);line-height:calc(var(--spacing) * 5)}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.whitespace-normal{white-space:normal}.whitespace-nowrap{white-space:nowrap}.whitespace-pre{white-space:pre}.whitespace-pre-wrap{white-space:pre-wrap}.text-\[\#b45309\]{color:#b45309}.text-\[var\(--otari-brand-dark\)\]{color:var(--otari-brand-dark)}.text-\[var\(--otari-ink\)\]{color:var(--otari-ink)}.text-\[var\(--otari-muted\)\]{color:var(--otari-muted)}.text-amber-400{color:var(--color-amber-400)}.text-amber-700{color:var(--color-amber-700)}.text-amber-800{color:var(--color-amber-800)}.text-amber-900{color:var(--color-amber-900)}.text-emerald-700{color:var(--color-emerald-700)}.text-green-700{color:var(--color-green-700)}.text-red-700{color:var(--color-red-700)}.normal-case{text-transform:none}.uppercase{text-transform:uppercase}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.underline{text-decoration-line:underline}.underline-offset-2{text-underline-offset:2px}.accent-\[var\(--otari-brand\)\]{accent-color:var(--otari-brand)}.opacity-0{opacity:0}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a), 0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a), 0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.transition-\[width\]{transition-property:width;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-150{--tw-duration:.15s;transition-duration:.15s}.select-none{-webkit-user-select:none;user-select:none}.running{animation-play-state:running}.group-focus-within\:opacity-100:is(:where(.group):focus-within *){opacity:1}@media(hover:hover){.group-hover\:w-0\.5:is(:where(.group):hover *){width:calc(var(--spacing) * .5)}.group-hover\:bg-\[var\(--otari-brand\)\]:is(:where(.group):hover *){background-color:var(--otari-brand)}.group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}}.last\:border-b-0:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}@media(hover:hover){.hover\:border-\[var\(--otari-brand\)\]:hover{border-color:var(--otari-brand)}.hover\:bg-\[var\(--otari-bg\)\]:hover{background-color:var(--otari-bg)}.hover\:bg-\[var\(--otari-brand\)\]:hover{background-color:var(--otari-brand)}.hover\:text-\[var\(--otari-brand\)\]:hover{color:var(--otari-brand)}.hover\:text-\[var\(--otari-brand-dark\)\]:hover{color:var(--otari-brand-dark)}.hover\:text-\[var\(--otari-ink\)\]:hover{color:var(--otari-ink)}.hover\:text-amber-950:hover{color:var(--color-amber-950)}.hover\:text-red-700:hover{color:var(--color-red-700)}.hover\:underline:hover{text-decoration-line:underline}}.focus\:border-\[var\(--otari-brand\)\]:focus{border-color:var(--otari-brand)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.focus-visible\:bg-\[var\(--otari-brand\)\]:focus-visible{background-color:var(--otari-brand)}.focus-visible\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-visible\:ring-\[var\(--otari-brand\)\]:focus-visible{--tw-ring-color:var(--otari-brand)}.focus-visible\:outline-2:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px}.focus-visible\:-outline-offset-2:focus-visible{outline-offset:-2px}.focus-visible\:outline-\[var\(--otari-brand\)\]:focus-visible{outline-color:var(--otari-brand)}.disabled\:opacity-50:disabled{opacity:.5}@media(min-width:40rem){.sm\:col-span-2{grid-column:span 2/span 2}.sm\:col-start-1{grid-column-start:1}.sm\:col-start-2{grid-column-start:2}.sm\:col-start-3{grid-column-start:3}.sm\:w-28{width:calc(var(--spacing) * 28)}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.sm\:grid-cols-\[minmax\(0\,1fr\)_16rem_10rem\]{grid-template-columns:minmax(0,1fr) 16rem 10rem}.sm\:flex-row{flex-direction:row}.sm\:flex-wrap{flex-wrap:wrap}.sm\:items-center{align-items:center}.sm\:items-start{align-items:flex-start}.sm\:justify-self-end{justify-self:flex-end}.sm\:justify-self-start{justify-self:flex-start}}@media(min-width:64rem){.lg\:sticky{position:sticky}.lg\:top-4{top:calc(var(--spacing) * 4)}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lg\:grid-cols-\[minmax\(0\,1fr\)_360px\]{grid-template-columns:minmax(0,1fr) 360px}.lg\:items-start{align-items:flex-start}}@media(min-width:80rem){.xl\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}}@property --tw-animation-delay{syntax:"*";inherits:false;initial-value:0s}@property --tw-animation-direction{syntax:"*";inherits:false;initial-value:normal}@property --tw-animation-duration{syntax:"*";inherits:false}@property --tw-animation-fill-mode{syntax:"*";inherits:false;initial-value:none}@property --tw-animation-iteration-count{syntax:"*";inherits:false;initial-value:1}@property --tw-enter-blur{syntax:"*";inherits:false;initial-value:0}@property --tw-enter-opacity{syntax:"*";inherits:false;initial-value:1}@property --tw-enter-rotate{syntax:"*";inherits:false;initial-value:0}@property --tw-enter-scale{syntax:"*";inherits:false;initial-value:1}@property --tw-enter-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-enter-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-blur{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-opacity{syntax:"*";inherits:false;initial-value:1}@property --tw-exit-rotate{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-scale{syntax:"*";inherits:false;initial-value:1}@property --tw-exit-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-translate-y{syntax:"*";inherits:false;initial-value:0}:root{--otari-brand:#4e8295;--otari-brand-dark:#3c6678;--otari-brand-tint:#eaf1f3;--otari-ink:#14242c;--otari-muted:#5b6b73;--otari-line:#dbe5e8;--otari-surface:#fff;--otari-bg:#f6f9fa}html,body,#root{height:100%}body{background-color:var(--otari-bg);color:var(--otari-ink);margin:0;font-family:ui-sans-serif,system-ui,-apple-system,Segoe UI,Roboto,sans-serif}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-content{syntax:"*";inherits:false;initial-value:""}@property --tw-ease{syntax:"*";inherits:false}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@property --tw-border-spacing-x{syntax:"";inherits:false;initial-value:0}@property --tw-border-spacing-y{syntax:"";inherits:false;initial-value:0}@property --tw-gradient-position{syntax:"*";inherits:false}@property --tw-gradient-from{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:"*";inherits:false}@property --tw-gradient-via-stops{syntax:"*";inherits:false}@property --tw-gradient-from-position{syntax:"";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:"";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:"";inherits:false;initial-value:100%}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-space-x-reverse{syntax:"*";inherits:false;initial-value:0}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{50%{opacity:.5}}@keyframes enter{0%{opacity:var(--tw-enter-opacity,1);transform:translate3d(var(--tw-enter-translate-x,0),var(--tw-enter-translate-y,0),0)scale3d(var(--tw-enter-scale,1),var(--tw-enter-scale,1),var(--tw-enter-scale,1))rotate(var(--tw-enter-rotate,0));filter:blur(var(--tw-enter-blur,0))}}@keyframes exit{to{opacity:var(--tw-exit-opacity,1);transform:translate3d(var(--tw-exit-translate-x,0),var(--tw-exit-translate-y,0),0)scale3d(var(--tw-exit-scale,1),var(--tw-exit-scale,1),var(--tw-exit-scale,1))rotate(var(--tw-exit-rotate,0));filter:blur(var(--tw-exit-blur,0))}}@keyframes caret-blink{0%,70%,to{opacity:1}20%,50%{opacity:0}}@keyframes skeleton{to{transform:translate(200%)}} +/*! tailwindcss v4.3.1 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-duration:initial;--tw-animation-delay:0s;--tw-animation-direction:normal;--tw-animation-duration:initial;--tw-animation-fill-mode:none;--tw-animation-iteration-count:1;--tw-enter-blur:0;--tw-enter-opacity:1;--tw-enter-rotate:0;--tw-enter-scale:1;--tw-enter-translate-x:0;--tw-enter-translate-y:0;--tw-exit-blur:0;--tw-exit-opacity:1;--tw-exit-rotate:0;--tw-exit-scale:1;--tw-exit-translate-x:0;--tw-exit-translate-y:0;--tw-content:"";--tw-ease:initial;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1;--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-space-y-reverse:0;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-space-x-reverse:0}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-red-50:oklch(97.1% .013 17.38);--color-red-200:oklch(88.5% .062 18.334);--color-red-500:oklch(63.7% .237 25.331);--color-red-700:oklch(50.5% .213 27.518);--color-amber-50:oklch(98.7% .022 95.277);--color-amber-200:oklch(92.4% .12 95.746);--color-amber-400:oklch(82.8% .189 84.429);--color-amber-500:oklch(76.9% .188 70.08);--color-amber-700:oklch(55.5% .163 48.998);--color-amber-800:oklch(47.3% .137 46.201);--color-amber-900:oklch(41.4% .112 45.904);--color-amber-950:oklch(27.9% .077 45.635);--color-green-50:oklch(98.2% .018 155.826);--color-green-200:oklch(92.5% .084 155.995);--color-green-500:oklch(72.3% .219 149.579);--color-green-700:oklch(52.7% .154 150.069);--color-emerald-50:oklch(97.9% .021 166.113);--color-emerald-200:oklch(90.5% .093 164.15);--color-emerald-500:oklch(69.6% .17 162.48);--color-emerald-700:oklch(50.8% .118 165.612);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-xs:20rem;--container-sm:24rem;--container-md:28rem;--container-lg:32rem;--container-2xl:42rem;--container-3xl:48rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height: 1.5 ;--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--text-3xl:1.875rem;--text-3xl--line-height: 1.2 ;--text-4xl:2.25rem;--text-4xl--line-height:calc(2.5 / 2.25);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-tight:-.025em;--tracking-wide:.025em;--tracking-wider:.05em;--leading-relaxed:1.625;--radius-xl:calc(var(--radius) * 1.5);--radius-2xl:calc(var(--radius) * 2);--radius-3xl:calc(var(--radius) * 3);--ease-out:cubic-bezier(0, 0, .2, 1);--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--blur-md:12px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--shadow-surface:var(--surface-shadow);--shadow-overlay:var(--overlay-shadow);--border-width-field:var(--field-border-width,var(--border-width));--ease-smooth:ease;--ease-out-quad:cubic-bezier(.25, .46, .45, .94);--ease-out-quart:cubic-bezier(.165, .84, .44, 1);--ease-out-fluid:cubic-bezier(.32, .72, 0, 1);--ease-linear:linear}@layer theme.base{:root,.light,.default,[data-theme=light],[data-theme=default]{color-scheme:light;--white:oklch(100% 0 0);--black:oklch(0% 0 0);--snow:oklch(99.11% 0 0);--eclipse:oklch(21.03% .0059 285.89);--spacing:.25rem;--border-width:1px;--field-border-width:0px;--disabled-opacity:.5;--ring-offset-width:2px;--cursor-interactive:pointer;--cursor-disabled:not-allowed;--radius:.5rem;--field-radius:calc(var(--radius) * 1.5);--background:oklch(97.02% 0 0);--foreground:var(--eclipse);--surface:var(--white);--surface-foreground:var(--foreground);--surface-secondary:oklch(95.24% .0013 286.37);--surface-secondary-foreground:var(--foreground);--surface-tertiary:oklch(93.73% .0013 286.37);--surface-tertiary-foreground:var(--foreground);--overlay:var(--white);--overlay-foreground:var(--foreground);--muted:oklch(55.17% .0138 285.94);--scrollbar:var(--scrollbar-thumb);--scrollbar-thumb:var(--foreground)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--scrollbar-thumb:color-mix(in oklch, var(--foreground) 15%, transparent)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--scrollbar-track:transparent;--scrollbar-gutter:auto;--scrollbar-width:thin;--scrollbar-color:var(--scrollbar-thumb) var(--scrollbar-track);--default:oklch(94% .001 286.375);--default-foreground:var(--eclipse);--accent:oklch(62.04% .195 253.83);--accent-foreground:var(--snow);--field-background:var(--white);--field-foreground:oklch(21.03% .0059 285.89);--field-placeholder:var(--muted);--field-border:transparent;--success:oklch(73.29% .1935 150.81);--success-foreground:var(--eclipse);--warning:oklch(78.19% .1585 72.33);--warning-foreground:var(--eclipse);--danger:oklch(65.32% .2328 25.74);--danger-foreground:var(--snow);--segment:var(--white);--segment-foreground:var(--eclipse);--border:oklch(90% .004 286.32);--separator:oklch(92% .004 286.32);--focus:var(--accent);--link:var(--foreground);--backdrop:#00000080;--surface-hover:var(--surface)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--surface-hover:color-mix(in oklab, var(--surface) 92%, var(--surface-foreground) 8%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--background-secondary:var(--background)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--background-secondary:color-mix(in oklab, var(--background) 96%, var(--foreground) 4%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--background-tertiary:var(--background)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--background-tertiary:color-mix(in oklab, var(--background) 92%, var(--foreground) 8%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--background-inverse:var(--foreground);--default-hover:var(--default)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--default-hover:color-mix(in oklab, var(--default) 96%, var(--default-foreground) 4%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--accent-hover:var(--accent)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--accent-hover:color-mix(in oklab, var(--accent) 90%, var(--accent-foreground) 10%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--success-hover:var(--success)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--success-hover:color-mix(in oklab, var(--success) 90%, var(--success-foreground) 10%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--warning-hover:var(--warning)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--warning-hover:color-mix(in oklab, var(--warning) 90%, var(--warning-foreground) 10%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--danger-hover:var(--danger)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--danger-hover:color-mix(in oklab, var(--danger) 90%, var(--danger-foreground) 10%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--field-hover:var(--field-background,var(--default))}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--field-hover:color-mix(in oklab, var(--field-background,var(--default)) 90%, var(--field-foreground,var(--foreground)) 2%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--field-focus:var(--field-background,var(--default));--field-border-hover:var(--field-border,var(--border))}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--field-border-hover:color-mix(in oklab, var(--field-border,var(--border)) 88%, var(--field-foreground,var(--foreground)) 10%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--field-border-focus:var(--field-border,var(--border))}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--field-border-focus:color-mix(in oklab, var(--field-border,var(--border)) 74%, var(--field-foreground,var(--foreground)) 22%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--default-soft:var(--default)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--default-soft:color-mix(in oklab, var(--default) 50%, transparent)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--default-soft-foreground:var(--default-foreground);--default-soft-hover:var(--default)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--default-soft-hover:color-mix(in oklab, var(--default) 60%, transparent)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--accent-soft:var(--accent)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--accent-soft:color-mix(in oklab, var(--accent) 15%, transparent)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--accent-soft-foreground:var(--accent)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--accent-soft-foreground:color-mix(in oklab, var(--accent) 70%, var(--foreground) 30%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--accent-soft-hover:var(--accent)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--accent-soft-hover:color-mix(in oklab, var(--accent) 20%, transparent)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--danger-soft:var(--danger)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--danger-soft:color-mix(in oklab, var(--danger) 15%, transparent)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--danger-soft-foreground:var(--danger)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--danger-soft-foreground:color-mix(in oklab, var(--danger) 70%, var(--foreground) 40%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--danger-soft-hover:var(--danger)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--danger-soft-hover:color-mix(in oklab, var(--danger) 20%, transparent)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--warning-soft:var(--warning)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--warning-soft:color-mix(in oklab, var(--warning) 15%, transparent)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--warning-soft-foreground:var(--warning)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--warning-soft-foreground:color-mix(in oklab, var(--warning) 80%, var(--foreground) 70%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--warning-soft-hover:var(--warning)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--warning-soft-hover:color-mix(in oklab, var(--warning) 20%, transparent)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--success-soft:var(--success)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--success-soft:color-mix(in oklab, var(--success) 15%, transparent)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--success-soft-foreground:var(--success)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--success-soft-foreground:color-mix(in oklab, var(--success) 80%, var(--foreground) 60%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--success-soft-hover:var(--success)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--success-soft-hover:color-mix(in oklab, var(--success) 20%, transparent)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--separator-secondary:var(--surface)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--separator-secondary:color-mix(in oklab, var(--surface) 85%, var(--surface-foreground) 15%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--separator-tertiary:var(--surface)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--separator-tertiary:color-mix(in oklab, var(--surface) 81%, var(--surface-foreground) 19%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--border-secondary:var(--surface)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--border-secondary:color-mix(in oklab, var(--surface) 78%, var(--surface-foreground) 22%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--border-tertiary:var(--surface)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--border-tertiary:color-mix(in oklab, var(--surface) 66%, var(--surface-foreground) 34%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--surface-shadow:0 2px 4px 0 #0000000a, 0 1px 2px 0 #0000000f, 0 0 1px 0 #0000000f;--overlay-shadow:0 2px 8px 0 #0000000f, 0 -6px 12px 0 #00000008, 0 14px 28px 0 #00000014;--field-shadow:0 2px 4px 0 #0000000a, 0 1px 2px 0 #0000000f, 0 0 1px 0 #0000000f;--skeleton-animation:shimmer;--tooltip-delay:1.5s;--tooltip-close-delay:.5s}.dark,[data-theme=dark]{color-scheme:dark;--background:oklch(12% .005 285.823);--foreground:var(--snow);--surface:oklch(21.03% .0059 285.89);--surface-foreground:var(--foreground);--surface-secondary:oklch(25.7% .0037 286.14);--surface-tertiary:oklch(27.21% .0024 247.91);--overlay:oklch(21.03% .0059 285.89);--overlay-foreground:var(--foreground);--muted:oklch(70.5% .015 286.067);--scrollbar:var(--scrollbar-thumb);--scrollbar-thumb:var(--foreground)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--scrollbar-thumb:color-mix(in oklch, var(--foreground) 15%, transparent)}}.dark,[data-theme=dark]{--scrollbar-track:transparent;--scrollbar-gutter:auto;--scrollbar-width:thin;--scrollbar-color:var(--scrollbar-thumb) var(--scrollbar-track);--default:oklch(27.4% .006 286.033);--default-foreground:var(--snow);--field-background:oklch(21.03% .0059 285.89);--field-foreground:var(--foreground);--warning:oklch(82.03% .1388 76.34);--warning-foreground:var(--eclipse);--danger:oklch(59.4% .1967 24.63);--danger-foreground:var(--snow);--segment:oklch(39.64% .01 285.93);--segment-foreground:var(--foreground);--border:oklch(28% .006 286.033);--separator:oklch(25% .006 286.033);--focus:var(--accent);--link:var(--foreground);--backdrop:#0009;--surface-shadow:0 0 0 0 transparent inset;--overlay-shadow:0 0 1px 0 #ffffff4d inset;--field-shadow:0 0 0 0 transparent inset;--surface-hover:var(--surface)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--surface-hover:color-mix(in oklab, var(--surface) 92%, var(--surface-foreground) 8%)}}.dark,[data-theme=dark]{--background-secondary:var(--background)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--background-secondary:color-mix(in oklab, var(--background) 96%, var(--foreground) 4%)}}.dark,[data-theme=dark]{--background-tertiary:var(--background)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--background-tertiary:color-mix(in oklab, var(--background) 92%, var(--foreground) 8%)}}.dark,[data-theme=dark]{--background-inverse:var(--foreground);--default-hover:var(--default)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--default-hover:color-mix(in oklab, var(--default) 96%, var(--default-foreground) 4%)}}.dark,[data-theme=dark]{--accent-hover:var(--accent)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--accent-hover:color-mix(in oklab, var(--accent) 90%, var(--accent-foreground) 10%)}}.dark,[data-theme=dark]{--success-hover:var(--success)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--success-hover:color-mix(in oklab, var(--success) 90%, var(--success-foreground) 10%)}}.dark,[data-theme=dark]{--warning-hover:var(--warning)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--warning-hover:color-mix(in oklab, var(--warning) 90%, var(--warning-foreground) 10%)}}.dark,[data-theme=dark]{--danger-hover:var(--danger)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--danger-hover:color-mix(in oklab, var(--danger) 90%, var(--danger-foreground) 10%)}}.dark,[data-theme=dark]{--field-hover:var(--field-background,var(--default))}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--field-hover:color-mix(in oklab, var(--field-background,var(--default)) 90%, var(--field-foreground,var(--foreground)) 2%)}}.dark,[data-theme=dark]{--field-focus:var(--field-background,var(--default));--field-border-hover:var(--field-border,var(--border))}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--field-border-hover:color-mix(in oklab, var(--field-border,var(--border)) 88%, var(--field-foreground,var(--foreground)) 10%)}}.dark,[data-theme=dark]{--field-border-focus:var(--field-border,var(--border))}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--field-border-focus:color-mix(in oklab, var(--field-border,var(--border)) 74%, var(--field-foreground,var(--foreground)) 22%)}}.dark,[data-theme=dark]{--default-soft:var(--default)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--default-soft:color-mix(in oklab, var(--default) 50%, transparent)}}.dark,[data-theme=dark]{--default-soft-foreground:var(--default-foreground);--default-soft-hover:var(--default)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--default-soft-hover:color-mix(in oklab, var(--default) 60%, transparent)}}.dark,[data-theme=dark]{--accent-soft:var(--accent)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--accent-soft:color-mix(in oklab, var(--accent) 12%, transparent)}}.dark,[data-theme=dark]{--accent-soft-foreground:var(--accent)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--accent-soft-foreground:color-mix(in oklab, var(--accent) 80%, var(--foreground) 30%)}}.dark,[data-theme=dark]{--accent-soft-hover:var(--accent)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--accent-soft-hover:color-mix(in oklab, var(--accent) 16%, transparent)}}.dark,[data-theme=dark]{--danger-soft:var(--danger)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--danger-soft:color-mix(in oklab, var(--danger) 15%, transparent)}}.dark,[data-theme=dark]{--danger-soft-foreground:var(--danger)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--danger-soft-foreground:color-mix(in oklab, var(--danger) 80%, var(--foreground) 30%)}}.dark,[data-theme=dark]{--danger-soft-hover:var(--danger)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--danger-soft-hover:color-mix(in oklab, var(--danger) 20%, transparent)}}.dark,[data-theme=dark]{--warning-soft:var(--warning)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--warning-soft:color-mix(in oklab, var(--warning) 12%, transparent)}}.dark,[data-theme=dark]{--warning-soft-foreground:var(--warning)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--warning-soft-foreground:color-mix(in oklab, var(--warning) 80%, var(--foreground) 30%)}}.dark,[data-theme=dark]{--warning-soft-hover:var(--warning)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--warning-soft-hover:color-mix(in oklab, var(--warning) 16%, transparent)}}.dark,[data-theme=dark]{--success-soft:var(--success)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--success-soft:color-mix(in oklab, var(--success) 12%, transparent)}}.dark,[data-theme=dark]{--success-soft-foreground:var(--success)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--success-soft-foreground:color-mix(in oklab, var(--success) 80%, var(--foreground) 30%)}}.dark,[data-theme=dark]{--success-soft-hover:var(--success)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--success-soft-hover:color-mix(in oklab, var(--success) 16%, transparent)}}.dark,[data-theme=dark]{--separator-secondary:var(--surface)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--separator-secondary:color-mix(in oklab, var(--surface) 85%, var(--surface-foreground) 15%)}}.dark,[data-theme=dark]{--separator-tertiary:var(--surface)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--separator-tertiary:color-mix(in oklab, var(--surface) 81%, var(--surface-foreground) 19%)}}.dark,[data-theme=dark]{--border-secondary:var(--surface)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--border-secondary:color-mix(in oklab, var(--surface) 78%, var(--surface-foreground) 22%)}}.dark,[data-theme=dark]{--border-tertiary:var(--surface)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--border-tertiary:color-mix(in oklab, var(--surface) 66%, var(--surface-foreground) 34%)}}[data-vibrant-palette=true]:not(.dark):not([data-theme=dark]){--accent-soft-foreground:var(--accent)}@supports (color:color-mix(in lab,red,red)){[data-vibrant-palette=true]:not(.dark):not([data-theme=dark]){--accent-soft-foreground:color-mix(in oklab, var(--accent) 92%, var(--foreground) 8%)}}[data-vibrant-palette=true]:not(.dark):not([data-theme=dark]){--danger-soft-foreground:var(--danger)}@supports (color:color-mix(in lab,red,red)){[data-vibrant-palette=true]:not(.dark):not([data-theme=dark]){--danger-soft-foreground:color-mix(in oklab, var(--danger) 92%, var(--foreground) 8%)}}[data-vibrant-palette=true]:not(.dark):not([data-theme=dark]){--warning-soft-foreground:var(--warning)}@supports (color:color-mix(in lab,red,red)){[data-vibrant-palette=true]:not(.dark):not([data-theme=dark]){--warning-soft-foreground:color-mix(in oklab, var(--warning) 92%, var(--foreground) 8%)}}[data-vibrant-palette=true]:not(.dark):not([data-theme=dark]){--success-soft-foreground:var(--success)}@supports (color:color-mix(in lab,red,red)){[data-vibrant-palette=true]:not(.dark):not([data-theme=dark]){--success-soft-foreground:color-mix(in oklab, var(--success) 92%, var(--foreground) 8%)}}[data-vibrant-palette=true].dark,[data-vibrant-palette=true][data-theme=dark]{--accent-soft-foreground:var(--accent)}@supports (color:color-mix(in lab,red,red)){[data-vibrant-palette=true].dark,[data-vibrant-palette=true][data-theme=dark]{--accent-soft-foreground:color-mix(in oklab, var(--accent) 92%, var(--foreground) 8%)}}[data-vibrant-palette=true].dark,[data-vibrant-palette=true][data-theme=dark]{--danger-soft-foreground:var(--danger)}@supports (color:color-mix(in lab,red,red)){[data-vibrant-palette=true].dark,[data-vibrant-palette=true][data-theme=dark]{--danger-soft-foreground:color-mix(in oklab, var(--danger) 92%, var(--foreground) 8%)}}[data-vibrant-palette=true].dark,[data-vibrant-palette=true][data-theme=dark]{--warning-soft-foreground:var(--warning)}@supports (color:color-mix(in lab,red,red)){[data-vibrant-palette=true].dark,[data-vibrant-palette=true][data-theme=dark]{--warning-soft-foreground:color-mix(in oklab, var(--warning) 92%, var(--foreground) 8%)}}[data-vibrant-palette=true].dark,[data-vibrant-palette=true][data-theme=dark]{--success-soft-foreground:var(--success)}@supports (color:color-mix(in lab,red,red)){[data-vibrant-palette=true].dark,[data-vibrant-palette=true][data-theme=dark]{--success-soft-foreground:color-mix(in oklab, var(--success) 92%, var(--foreground) 8%)}}}@layer components;}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}*,:after,:before,::backdrop{border-color:var(--border,currentColor)}::file-selector-button{border-color:var(--border,currentColor)}:root{view-transition-name:none}::view-transition{pointer-events:none}[data-scrollbar=thin]{--scrollbar-width:thin;--scrollbar-color:var(--scrollbar-thumb) var(--scrollbar-track);--scrollbar-gutter:auto}[data-scrollbar=default]{--scrollbar-width:auto;--scrollbar-color:auto;--scrollbar-gutter:auto}[data-scrollbar=none]{--scrollbar-width:none;--scrollbar-color:auto;--scrollbar-gutter:auto}}@layer components{.close-button{isolation:isolate;height:calc(var(--spacing) * 6);width:calc(var(--spacing) * 6);transform-origin:50%;border-radius:calc(var(--radius) * 1.5);padding:var(--spacing);-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;cursor:var(--cursor-interactive);transition:transform .25s var(--ease-out-quart),color .15s var(--ease-out),background-color .1s var(--ease-out),box-shadow .15s var(--ease-out);transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);flex-shrink:0;justify-content:center;align-items:center;display:inline-flex;position:relative}.close-button:is([data-reduce-motion=true],[data-reduce-motion=true] *),.close-button:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.close-button:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.close-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.close-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.close-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.close-button:focus-visible:not(:focus),.close-button[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.close-button:disabled,.close-button[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.close-button[data-pending=true]{pointer-events:none}.close-button svg{pointer-events:none;width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4);margin-inline:calc(var(--spacing) * -.5);margin-block:calc(var(--spacing) * .5);flex-shrink:0;align-self:center}.close-button--default{background-color:var(--default);color:var(--muted)}@media(hover:hover){.close-button--default:hover,.close-button--default[data-hovered=true]{background-color:var(--default-hover)}}.close-button--default:active,.close-button--default[data-pressed=true]{transform:scale(.93)}.description{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));text-wrap:wrap;overflow-wrap:break-word;color:var(--muted)}.error-message{height:auto;font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));overflow-wrap:break-word;color:var(--danger);transition:opacity .15s var(--ease-out),height .35s var(--ease-smooth)}.error-message:is([data-reduce-motion=true],[data-reduce-motion=true] *),.error-message:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.error-message:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.error-message:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.error-message:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.error-message:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.field-error{height:0;padding-inline:var(--spacing);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));overflow-wrap:break-word;color:var(--danger);opacity:0}.field-error[data-visible]{opacity:1;height:auto}.field-error{transition:opacity .15s var(--ease-out),height .35s var(--ease-smooth)}.field-error:is([data-reduce-motion=true],[data-reduce-motion=true] *),.field-error:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.field-error:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.field-error:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.field-error:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.field-error:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.checkbox>.field-error,.checkbox>[data-slot=field-error],.switch>.field-error,.switch>[data-slot=field-error],.radio>.field-error,.radio>[data-slot=field-error]{height:auto;min-height:0;color:var(--muted);opacity:1;margin:0;padding:0;transition:none}.label{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--foreground)}:is(.label--required,[data-required=true]:not([role=group]):not([role=radiogroup]):not([role=checkboxgroup])>.label,[data-required=true]:not([data-slot=radio]):not([data-slot=checkbox])>.label):after{margin-left:calc(var(--spacing) * .5);color:var(--danger);--tw-content:"*";content:var(--tw-content)}.label--disabled,[data-disabled=true] .label{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.label--invalid,[data-invalid=true] .label,[aria-invalid=true] .label{color:var(--danger)}.accordion{contain:layout style;width:100%}.accordion__body{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.accordion__body-inner{padding-inline:calc(var(--spacing) * 4);padding-top:0;padding-bottom:calc(var(--spacing) * 4);color:var(--muted)}.accordion__indicator{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4);color:var(--muted);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.25s;flex-shrink:0;margin-left:auto;transition-duration:.25s}.accordion__indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *),.accordion__indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.accordion__indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.accordion__indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.accordion__indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.accordion__indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.accordion__indicator[data-expanded=true]{rotate:-180deg}.accordion__item{--tw-border-style:none;border-style:none;position:relative}.accordion__item:after{content:"";border-radius:calc(var(--radius) * .25);background-color:var(--separator);width:100%;height:1px;position:absolute;bottom:0;left:0}.accordion__item:last-child:after{content:none}.accordion__item[data-hide-separator=true]:after{display:none}.accordion__trigger{cursor:var(--cursor-interactive);padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 4);text-align:left;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);-webkit-tap-highlight-color:transparent;transition:opacity .15s var(--ease-out),box-shadow .15s var(--ease-out);flex:1;justify-content:space-between;align-items:center;display:flex}.accordion__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *),.accordion__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.accordion__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.accordion__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.accordion__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.accordion__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}@media(hover:hover){.accordion__trigger:hover:not([aria-expanded=true]),.accordion__trigger[data-hovered=true]:not([aria-expanded=true]){background-color:var(--foreground)}@supports (color:color-mix(in lab,red,red)){.accordion__trigger:hover:not([aria-expanded=true]),.accordion__trigger[data-hovered=true]:not([aria-expanded=true]){background-color:color-mix(in oklab,var(--foreground) 3%,transparent 90%)}}}.accordion__trigger:focus-visible:not(:focus),.accordion__trigger[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.accordion__trigger:disabled,.accordion__trigger[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.accordion__panel{opacity:0;height:var(--disclosure-panel-height);transition:height .2s var(--ease-out-quad),opacity .2s var(--ease-out);overflow:clip}.accordion__panel:is([data-reduce-motion=true],[data-reduce-motion=true] *),.accordion__panel:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.accordion__panel:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.accordion__panel:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.accordion__panel:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.accordion__panel:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.accordion__panel[data-expanded=true]{will-change:height,opacity;opacity:1}.accordion--surface{background-color:var(--surface);border-radius:min(32px,var(--radius-3xl))}@media(hover:hover){.accordion--surface .accordion__trigger:hover:not([aria-expanded=true]),.accordion--surface .accordion__trigger[data-hovered=true]:not([aria-expanded=true]){background-color:var(--default)}}.accordion--surface .accordion__item:after{background-color:var(--surface-foreground)}@supports (color:color-mix(in lab,red,red)){.accordion--surface .accordion__item:after{background-color:color-mix(in oklab,var(--surface-foreground) 6%,transparent)}}.accordion--surface .accordion__item:after{width:94%;left:3%}.accordion--surface .accordion__item:first-child [data-slot=accordion-trigger]{border-top-left-radius:min(32px,var(--radius-3xl));border-top-right-radius:min(32px,var(--radius-3xl))}.accordion--surface .accordion__item:last-child:not(:has([data-slot=accordion-trigger][aria-expanded=true])) [data-slot=accordion-trigger]{border-bottom-left-radius:min(32px,var(--radius-3xl));border-bottom-right-radius:min(32px,var(--radius-3xl))}.breadcrumbs{align-items:center;display:flex}.breadcrumbs .breadcrumbs__link{padding-inline:calc(var(--spacing) * .5);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-leading:calc(var(--spacing) * 5);line-height:calc(var(--spacing) * 5);--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--muted);opacity:1;text-decoration-line:none;position:relative}.breadcrumbs .breadcrumbs__link:hover,.breadcrumbs .breadcrumbs__link[data-hovered=true]{text-decoration-line:underline}.breadcrumbs .breadcrumbs__link[data-current=true]{color:var(--link);opacity:1}.breadcrumbs .breadcrumbs__item{justify-content:center;align-items:center;gap:calc(var(--spacing) * .5);padding-inline:calc(var(--spacing) * .5);flex-shrink:0;display:flex}.breadcrumbs .breadcrumbs__separator{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3);color:var(--muted)}.breadcrumbs .breadcrumbs__separator:where(:dir(rtl),[dir=rtl],[dir=rtl] *){rotate:180deg}.disclosure-group{contain:layout style;width:100%}.disclosure{position:relative}.accordion__heading{display:flex}.disclosure__trigger{cursor:var(--cursor-interactive);-webkit-tap-highlight-color:transparent;display:inline-block}.disclosure__trigger:focus-visible:not(:focus),.disclosure__trigger[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.disclosure__trigger:disabled,.disclosure__trigger[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.disclosure__indicator{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4);color:inherit;transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.25s;flex-shrink:0;margin-left:auto;transition-duration:.25s}.disclosure__indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *),.disclosure__indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.disclosure__indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.disclosure__indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.disclosure__indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.disclosure__indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.disclosure__indicator[data-expanded=true]{rotate:-180deg}.disclosure__content{opacity:0;height:var(--disclosure-panel-height);transition:height .2s var(--ease-out-quad),opacity .2s var(--ease-out);overflow:clip}.disclosure__content:is([data-reduce-motion=true],[data-reduce-motion=true] *),.disclosure__content:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.disclosure__content:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.disclosure__content:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.disclosure__content:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.disclosure__content:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.disclosure__content[data-expanded=true]{will-change:height,opacity;opacity:1}.disclosure__body{padding:calc(var(--spacing) * 2)}.link{border-radius:calc(var(--radius) * 1.5);--tw-font-weight:var(--font-weight-medium);width:fit-content;height:fit-content;font-weight:var(--font-weight-medium);color:var(--link);text-decoration-line:none;-webkit-text-decoration-color:var(--separator-tertiary);text-decoration-color:var(--separator-tertiary);text-underline-offset:4px;-webkit-tap-highlight-color:transparent;transition:color .1s var(--ease-smooth),background-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out),opacity .1s var(--ease-out);align-items:center;text-decoration-thickness:1.5px;display:inline-flex;position:relative}.link:is([data-reduce-motion=true],[data-reduce-motion=true] *),.link:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.link:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.link:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.link:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.link:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.link{cursor:var(--cursor-interactive)}@media(hover:hover){.link:hover,.link[data-hovered=true]{text-decoration-line:underline;-webkit-text-decoration-color:var(--muted);text-decoration-color:var(--muted)}@supports (color:color-mix(in lab,red,red)){.link:hover,.link[data-hovered=true]{-webkit-text-decoration-color:color-mix(in oklab,var(--muted) 50%,transparent);text-decoration-color:color-mix(in oklab,var(--muted) 50%,transparent)}}:is(.link:hover,.link[data-hovered=true]) .link__icon{opacity:1}}.link:active,.link[data-pressed=true]{text-decoration-line:underline;-webkit-text-decoration-color:var(--muted);text-decoration-color:var(--muted)}:is(.link:active,.link[data-pressed=true]) .link__icon{opacity:1}.link:focus-visible:not(:focus),.link[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}:is(.link:focus-visible:not(:focus),.link[data-focus-visible=true]) .link__icon{opacity:1}.link[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.link .link__icon{pointer-events:none;color:currentColor;opacity:.6;width:.75em;height:.75em;transition:opacity .15s var(--ease-out);flex-shrink:0;justify-content:center;align-items:center;display:inline-flex}.link .link__icon:is([data-reduce-motion=true],[data-reduce-motion=true] *),.link .link__icon:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.link .link__icon:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.link .link__icon:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.link .link__icon:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.link .link__icon:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.link .link__icon svg{transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.link .link__icon[data-default-icon=true]{margin-left:var(--spacing);padding-bottom:calc(var(--spacing) * 1.5)}.link.button{gap:0;text-decoration-line:none}.pagination{justify-content:space-between;align-items:center;gap:calc(var(--spacing) * 4);flex-direction:column;width:100%;display:flex}@media(min-width:40rem){.pagination{flex-direction:row}}.pagination__summary{align-items:center;gap:calc(var(--spacing) * 2);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--muted);align-self:flex-start;display:flex}@media(min-width:40rem){.pagination__summary{align-self:center}}.pagination__content{align-items:center;gap:var(--spacing);align-self:flex-start;display:flex}@media(min-width:40rem){.pagination__content{align-self:center}}.pagination__item{display:inline-flex}.pagination__link{isolation:isolate;width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9);transform-origin:50%;border-radius:calc(var(--radius) * 3);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);white-space:nowrap;--tw-outline-style:none;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;outline-style:none;justify-content:center;align-items:center;display:inline-flex;position:relative}@media(min-width:48rem){.pagination__link{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8)}}.pagination__link{cursor:var(--cursor-interactive);transition:transform .25s var(--ease-smooth),background-color .1s var(--ease-out),box-shadow .1s var(--ease-out);transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.pagination__link:is([data-reduce-motion=true],[data-reduce-motion=true] *),.pagination__link:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.pagination__link:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.pagination__link:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.pagination__link:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.pagination__link:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.pagination__link{--pagination-link-bg:transparent;--pagination-link-bg-hover:var(--default-hover);--pagination-link-bg-pressed:var(--default-hover);--pagination-link-fg:var(--default-foreground);background-color:var(--pagination-link-bg);color:var(--pagination-link-fg)}.pagination__link:focus-visible,.pagination__link[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.pagination__link:disabled,.pagination__link[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}@media(hover:hover){.pagination__link:hover,.pagination__link[data-hovered=true]{background-color:var(--pagination-link-bg-hover)}}.pagination__link:active,.pagination__link[data-pressed=true]{background-color:var(--pagination-link-bg-pressed);transform:scale(.97)}.pagination__link[data-active=true]{--pagination-link-bg:var(--default);--pagination-link-bg-hover:var(--default-hover);--pagination-link-bg-pressed:var(--default-hover)}.pagination__ellipsis{width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--muted);-webkit-user-select:none;user-select:none;justify-content:center;align-items:center;display:inline-flex}@media(min-width:48rem){.pagination__ellipsis{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8)}}.pagination__link--nav{gap:calc(var(--spacing) * 1.5);width:auto;padding-inline:calc(var(--spacing) * 2.5)}.pagination--sm .pagination__link{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}@media(min-width:48rem){.pagination--sm .pagination__link{width:calc(var(--spacing) * 7);height:calc(var(--spacing) * 7)}}.pagination--sm .pagination__link:active,.pagination--sm .pagination__link[data-pressed=true]{transform:scale(.98)}.pagination--sm .pagination__link--nav{width:auto;padding-inline:calc(var(--spacing) * 2)}.pagination--sm .pagination__ellipsis{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}@media(min-width:48rem){.pagination--sm .pagination__ellipsis{width:calc(var(--spacing) * 7);height:calc(var(--spacing) * 7)}}.pagination--sm .pagination__summary{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.pagination--lg .pagination__link{width:calc(var(--spacing) * 10);height:calc(var(--spacing) * 10);font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}@media(min-width:48rem){.pagination--lg .pagination__link{width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9)}}.pagination--lg .pagination__link:active,.pagination--lg .pagination__link[data-pressed=true]{transform:scale(.96)}.pagination--lg .pagination__link--nav{width:auto;padding-inline:calc(var(--spacing) * 3)}.pagination--lg .pagination__ellipsis{width:calc(var(--spacing) * 10);height:calc(var(--spacing) * 10);font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}@media(min-width:48rem){.pagination--lg .pagination__ellipsis{width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9)}}.pagination--lg .pagination__summary{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.tabs{gap:calc(var(--spacing) * 2);display:flex}.tabs[data-orientation=horizontal]{flex-direction:column}.tabs[data-orientation=vertical]{flex-direction:row}.tabs__list-container{position:relative}.tabs__list{background-color:var(--default);padding:var(--spacing);border-radius:calc(var(--radius) * 2.5);display:inline-flex}.tabs__list[data-orientation=horizontal]{flex-direction:row;width:100%}.tabs__list[data-orientation=vertical]{gap:var(--spacing);flex-direction:column}.tabs__list[data-orientation=vertical] .tabs__tab{min-width:calc(var(--spacing) * 20)}.tabs__tab{z-index:1;cursor:var(--cursor-interactive);height:calc(var(--spacing) * 8);border-radius:calc(var(--radius) * 3);width:100%;padding-inline:calc(var(--spacing) * 4);text-align:center;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--muted);--tw-outline-style:none;-webkit-tap-highlight-color:transparent;transition:color .15s var(--ease-smooth),background-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out),opacity .15s var(--ease-smooth);outline-style:none;justify-content:center;align-items:center;display:flex;position:relative}.tabs__tab:is([data-reduce-motion=true],[data-reduce-motion=true] *),.tabs__tab:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.tabs__tab:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.tabs__tab:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.tabs__tab:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.tabs__tab:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.tabs__tab[data-selected=true]{color:var(--segment-foreground)}.tabs__tab[data-selected=true] .tabs__separator,.tabs__tab[data-selected=true]+.tabs__tab .tabs__separator{opacity:0}.tabs__tab:disabled,.tabs__tab[data-disabled=true],.tabs__tab[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}@media(hover:hover){.tabs__tab:not([data-selected=true]):not([data-disabled=true]):hover,.tabs__tab[data-hovered=true]:not([data-selected=true]):not([data-disabled=true]){opacity:.7}}.tabs__tab:focus-visible:not(:focus),.tabs__tab[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.tabs__separator{border-radius:calc(var(--radius) * .5);background-color:var(--muted)}@supports (color:color-mix(in lab,red,red)){.tabs__separator{background-color:color-mix(in oklab,var(--muted) 25%,transparent)}}.tabs__separator{pointer-events:none;transition:opacity .15s var(--ease-smooth);position:absolute}.tabs__separator:is([data-reduce-motion=true],[data-reduce-motion=true] *),.tabs__separator:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.tabs__separator:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.tabs__separator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.tabs__separator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.tabs__separator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.tabs__list[data-orientation=horizontal] .tabs__separator{width:1px;height:50%;top:25%;left:0}.tabs__list[data-orientation=vertical] .tabs__separator{width:90%;height:1px;top:0;left:5%}.tabs__panel{width:100%;padding:calc(var(--spacing) * 2);--tw-outline-style:none;outline-style:none}.tabs__panel[data-exiting=true]{width:100%;position:absolute;top:0;left:0}.tabs__panel[data-orientation=horizontal]{margin-top:calc(var(--spacing) * 4)}.tabs__panel[data-orientation=vertical]{margin-left:calc(var(--spacing) * 4)}.tabs__indicator{box-shadow:var(--shadow-surface);z-index:-1;border-radius:var(--radius-3xl);background-color:var(--segment);width:100%;height:100%;transition-property:translate,width,height;transition-duration:.25s;transition-timing-function:var(--ease-out-fluid);position:absolute;top:0;left:0}.tabs__indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *),.tabs__indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.tabs__indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.tabs__indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.tabs__indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.tabs__indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.tabs--secondary>.tabs__list-container>.tabs__list{background-color:#0000;border-radius:0;padding:0}.tabs--secondary>.tabs__list-container>.tabs__list[data-orientation=horizontal]{scrollbar-color:auto;scrollbar-gutter:auto;-ms-overflow-style:none;scrollbar-width:none;border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--border);max-width:100%;overflow:auto clip}.tabs--secondary>.tabs__list-container>.tabs__list[data-orientation=vertical]{border-left-style:var(--tw-border-style);border-left-width:1px;border-color:var(--border)}.tabs--secondary>.tabs__list-container .tabs__tab{border-radius:0}.tabs--secondary>.tabs__list-container .tabs__tab[data-selected=true]{color:var(--foreground)}.tabs--secondary>.tabs__list-container .tabs__separator{display:none}.tabs--secondary>.tabs__list-container .tabs__indicator{background-color:var(--accent);box-shadow:none;border-radius:0}.tabs--secondary[data-orientation=horizontal]>.tabs__list-container .tabs__indicator{height:2px;top:auto;bottom:0}.tabs--secondary[data-orientation=vertical]>.tabs__list-container .tabs__indicator{width:2px;height:100%;top:0;left:0}.button{isolation:isolate;height:calc(var(--spacing) * 10);transform-origin:50%;justify-content:center;align-items:center;gap:calc(var(--spacing) * 2);border-radius:calc(var(--radius) * 3);width:fit-content;padding-inline:calc(var(--spacing) * 4);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);white-space:nowrap;--tw-outline-style:none;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;outline-style:none;display:inline-flex;position:relative}@media(min-width:48rem){.button{height:calc(var(--spacing) * 9)}}.button{transition:transform .25s var(--ease-smooth),background-color .1s var(--ease-out),box-shadow .1s var(--ease-out);transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.button:is([data-reduce-motion=true],[data-reduce-motion=true] *),.button:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.button:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.button{cursor:var(--cursor-interactive);--button-bg:transparent;--button-bg-hover:var(--button-bg);--button-bg-pressed:var(--button-bg-hover);--button-fg:currentColor;background-color:var(--button-bg);color:var(--button-fg)}.button:focus-visible:not(:focus),.button[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.button:disabled,.button[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.button[data-pending=true]{pointer-events:none}.button:active,.button[data-pressed=true]{background-color:var(--button-bg-pressed);transform:scale(.97)}@media(hover:hover){.button:hover,.button[data-hovered=true]{background-color:var(--button-bg-hover)}}.button svg:not([data-slot=spinner] svg,[data-slot=link-icon] svg){pointer-events:none;margin-inline:calc(var(--spacing) * -.5);margin-block:calc(var(--spacing) * .5);width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5);flex-shrink:0;align-self:center}@media(min-width:40rem){.button svg:not([data-slot=spinner] svg,[data-slot=link-icon] svg){margin-block:var(--spacing);width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}}.button--sm{height:calc(var(--spacing) * 9);padding-inline:calc(var(--spacing) * 3)}@media(min-width:48rem){.button--sm{height:calc(var(--spacing) * 8)}}.button--sm svg:not([data-slot=spinner] svg,[data-slot=link-icon] svg){width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.button--sm:active,.button--sm[data-pressed=true]{transform:scale(.98)}.button--lg{height:calc(var(--spacing) * 11);font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}@media(min-width:48rem){.button--lg{height:calc(var(--spacing) * 10)}}.button--lg:active,.button--lg[data-pressed=true]{transform:scale(.96)}.button--primary{--button-bg:var(--accent);--button-bg-hover:var(--accent-hover);--button-bg-pressed:var(--accent-hover);--button-fg:var(--accent-foreground)}.button--secondary{--button-bg:var(--default);--button-bg-hover:var(--default-hover);--button-bg-pressed:var(--default-hover);--button-fg:var(--accent-soft-foreground)}.button--tertiary{--button-bg:var(--default);--button-bg-hover:var(--default-hover);--button-bg-pressed:var(--default-hover)}.button--ghost,.button--outline{--button-bg:transparent;--button-bg-hover:var(--default);--button-bg-pressed:var(--default);--button-fg:var(--default-foreground)}.button--outline{border-style:var(--tw-border-style);border-width:1px;border-color:var(--border);--button-bg-hover:var(--default)}@supports (color:color-mix(in lab,red,red)){.button--outline{--button-bg-hover:color-mix(in srgb, var(--default) 60%, transparent)}}.button--danger{--button-bg:var(--danger);--button-bg-hover:var(--danger-hover);--button-bg-pressed:var(--danger-hover);--button-fg:var(--danger-foreground)}.button--danger-soft{--button-bg:var(--danger-soft);--button-bg-hover:var(--danger-soft-hover);--button-bg-pressed:var(--danger-soft-hover);--button-fg:var(--danger-soft-foreground)}.button--icon-only{width:calc(var(--spacing) * 10);padding:0}@media(min-width:48rem){.button--icon-only{width:calc(var(--spacing) * 9)}}.button--icon-only.button--sm{width:calc(var(--spacing) * 9)}@media(min-width:48rem){.button--icon-only.button--sm{width:calc(var(--spacing) * 8)}}.button--icon-only.button--lg{width:calc(var(--spacing) * 11)}@media(min-width:48rem){.button--icon-only.button--lg{width:calc(var(--spacing) * 10)}}.button--full-width{width:100%}.button-group{justify-content:center;align-items:center;gap:0;height:auto;display:inline-flex}.button-group--horizontal{flex-direction:row}.button-group--vertical{flex-direction:column}.button-group .button{border-radius:0}.button-group--horizontal .button:first-child{border-start-start-radius:calc(var(--radius) * 3);border-end-start-radius:calc(var(--radius) * 3)}.button-group--horizontal .button:last-child{border-start-end-radius:calc(var(--radius) * 3);border-end-end-radius:calc(var(--radius) * 3)}.button-group--horizontal .button:first-child:last-child{border-radius:calc(var(--radius) * 3)}.button-group--vertical .button:first-child{border-top-left-radius:calc(var(--radius) * 3);border-top-right-radius:calc(var(--radius) * 3)}.button-group--vertical .button:last-child{border-bottom-right-radius:calc(var(--radius) * 3);border-bottom-left-radius:calc(var(--radius) * 3)}.button-group--vertical .button:first-child:last-child{border-radius:calc(var(--radius) * 3)}.button-group .button:active,.button-group .button[data-pressed=true]{transform:none}.button-group .button:focus-visible:not(:focus),.button-group .button[data-focus-visible=true]{--tw-ring-offset-width:0px;--tw-ring-inset:inset}.button-group__separator{border-radius:calc(var(--radius) * .5);opacity:.15;pointer-events:none;transition:opacity .15s var(--ease-smooth);background-color:currentColor;position:absolute}.button-group__separator:is([data-reduce-motion=true],[data-reduce-motion=true] *),.button-group__separator:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.button-group__separator:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.button-group__separator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.button-group__separator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.button-group__separator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.button-group--horizontal .button-group__separator{width:1px;height:50%;top:25%;left:-1px}.button-group--vertical .button-group__separator{width:50%;height:1px;top:-1px;left:25%}.button-group--horizontal .button--outline:first-child{border-inline-end-style:var(--tw-border-style);border-inline-end-width:0}.button-group--horizontal .button--outline:last-child{border-inline-start-style:var(--tw-border-style);border-inline-start-width:0}.button-group--horizontal .button--outline:not(:first-child):not(:last-child){border-inline-style:var(--tw-border-style);border-inline-width:0}.button-group--vertical .button--outline:first-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}.button-group--vertical .button--outline:last-child{border-top-style:var(--tw-border-style);border-top-width:0}.button-group--vertical .button--outline:not(:first-child):not(:last-child){border-block-style:var(--tw-border-style);border-block-width:0}.button-group--full-width{width:100%}.toggle-button{isolation:isolate;height:calc(var(--spacing) * 10);transform-origin:50%;justify-content:center;align-items:center;gap:calc(var(--spacing) * 2);border-radius:calc(var(--radius) * 3);width:fit-content;padding-inline:calc(var(--spacing) * 4);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);white-space:nowrap;--tw-outline-style:none;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;outline-style:none;display:inline-flex;position:relative}@media(min-width:48rem){.toggle-button{height:calc(var(--spacing) * 9)}}.toggle-button{transition:transform .25s var(--ease-smooth),background-color .1s var(--ease-out),box-shadow .1s var(--ease-out);transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.toggle-button:is([data-reduce-motion=true],[data-reduce-motion=true] *),.toggle-button:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.toggle-button:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.toggle-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.toggle-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.toggle-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.toggle-button{cursor:var(--cursor-interactive);--toggle-button-bg:var(--default);--toggle-button-bg-hover:var(--default-hover);--toggle-button-bg-pressed:var(--default-hover);--toggle-button-fg:currentColor;--toggle-button-bg-selected:var(--accent-soft);--toggle-button-bg-selected-hover:var(--accent-soft-hover);--toggle-button-bg-selected-pressed:var(--accent-soft-hover);--toggle-button-fg-selected:var(--accent-soft-foreground);background-color:var(--toggle-button-bg);color:var(--toggle-button-fg)}.toggle-button:focus-visible:not(:focus),.toggle-button[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.toggle-button:disabled,.toggle-button[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}@media(hover:hover){.toggle-button:hover,.toggle-button[data-hovered=true]{background-color:var(--toggle-button-bg-hover)}}.toggle-button:active,.toggle-button[data-pressed=true]{background-color:var(--toggle-button-bg-pressed);transform:scale(.97)}.toggle-button[data-selected=true]{background-color:var(--toggle-button-bg-selected);color:var(--toggle-button-fg-selected)}@media(hover:hover){.toggle-button[data-selected=true]:hover,.toggle-button[data-selected=true][data-hovered=true]{background-color:var(--toggle-button-bg-selected-hover)}}.toggle-button[data-selected=true]:active,.toggle-button[data-selected=true][data-pressed=true]{background-color:var(--toggle-button-bg-selected-pressed)}.toggle-button svg{pointer-events:none;margin-inline:calc(var(--spacing) * -.5);margin-block:calc(var(--spacing) * .5);width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5);flex-shrink:0;align-self:center}@media(min-width:40rem){.toggle-button svg{margin-block:var(--spacing);width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}}.toggle-button--sm{height:calc(var(--spacing) * 9);padding-inline:calc(var(--spacing) * 3)}@media(min-width:48rem){.toggle-button--sm{height:calc(var(--spacing) * 8)}}.toggle-button--sm svg{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.toggle-button--sm:active,.toggle-button--sm[data-pressed=true]{transform:scale(.98)}.toggle-button--lg{height:calc(var(--spacing) * 11);font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}@media(min-width:48rem){.toggle-button--lg{height:calc(var(--spacing) * 10)}}.toggle-button--lg:active,.toggle-button--lg[data-pressed=true]{transform:scale(.96)}.toggle-button--default{--toggle-button-bg:var(--default);--toggle-button-bg-hover:var(--default-hover);--toggle-button-bg-pressed:var(--default-hover)}.toggle-button--ghost{--toggle-button-bg:transparent;--toggle-button-bg-hover:var(--default);--toggle-button-bg-pressed:var(--default);--toggle-button-fg:var(--default-foreground)}.toggle-button--icon-only{width:calc(var(--spacing) * 10);padding:0}@media(min-width:48rem){.toggle-button--icon-only{width:calc(var(--spacing) * 9)}}.toggle-button--icon-only.toggle-button--sm{width:calc(var(--spacing) * 9)}@media(min-width:48rem){.toggle-button--icon-only.toggle-button--sm{width:calc(var(--spacing) * 8)}}.toggle-button--icon-only.toggle-button--lg{width:calc(var(--spacing) * 11)}@media(min-width:48rem){.toggle-button--icon-only.toggle-button--lg{width:calc(var(--spacing) * 10)}}.toggle-button-group{justify-content:center;align-items:center;gap:0;width:fit-content;height:auto;display:inline-flex}.toggle-button-group--horizontal{flex-direction:row}.toggle-button-group--vertical{flex-direction:column}.toggle-button-group--full-width{width:100%}.toggle-button-group .toggle-button{border-radius:0}.toggle-button-group--horizontal .toggle-button:first-child{border-start-start-radius:calc(var(--radius) * 3);border-end-start-radius:calc(var(--radius) * 3)}.toggle-button-group--horizontal .toggle-button:last-child{border-start-end-radius:calc(var(--radius) * 3);border-end-end-radius:calc(var(--radius) * 3)}.toggle-button-group--horizontal .toggle-button:first-child:last-child{border-radius:calc(var(--radius) * 3)}.toggle-button-group--vertical .toggle-button:first-child{border-top-left-radius:calc(var(--radius) * 3);border-top-right-radius:calc(var(--radius) * 3)}.toggle-button-group--vertical .toggle-button:last-child{border-bottom-right-radius:calc(var(--radius) * 3);border-bottom-left-radius:calc(var(--radius) * 3)}.toggle-button-group--vertical .toggle-button:first-child:last-child{border-radius:calc(var(--radius) * 3)}.toggle-button-group .toggle-button:active,.toggle-button-group .toggle-button[data-pressed=true]{transform:none}.toggle-button-group .toggle-button:focus-visible:not(:focus),.toggle-button-group .toggle-button[data-focus-visible=true]{--tw-ring-offset-width:0px;--tw-ring-inset:inset}.toggle-button-group--full-width .toggle-button{flex:1}.toggle-button-group__separator{border-radius:calc(var(--radius) * .5);opacity:.15;pointer-events:none;transition:opacity .15s var(--ease-smooth);background-color:currentColor;position:absolute}.toggle-button-group__separator:is([data-reduce-motion=true],[data-reduce-motion=true] *),.toggle-button-group__separator:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.toggle-button-group__separator:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.toggle-button-group__separator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.toggle-button-group__separator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.toggle-button-group__separator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.toggle-button-group--horizontal .toggle-button-group__separator{width:1px;height:50%;top:25%;left:-1px}.toggle-button-group--vertical .toggle-button-group__separator{width:50%;height:1px;top:-1px;left:25%}.toggle-button-group--detached{gap:var(--spacing)}.toggle-button-group--detached .toggle-button{border-radius:calc(var(--radius) * 3)}.toggle-button-group--detached .toggle-button-group__separator{display:none}.toolbar{align-items:center;gap:calc(var(--spacing) * 2);grid-auto-flow:column;width:fit-content;display:grid}.toolbar .separator--vertical{align-self:center;height:50%}.toolbar .separator--horizontal{justify-content:center;justify-self:center;width:50%}.toolbar--vertical{grid-auto-flow:row;justify-content:flex-start;align-items:flex-start}.toolbar--vertical .button-group{justify-content:flex-start}.toolbar--attached{border-radius:calc(var(--radius) * 3);background-color:var(--surface);padding:var(--spacing);--tw-shadow:var(--overlay-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.dropdown{gap:var(--spacing);flex-direction:column;display:flex}.dropdown__trigger{--tw-outline-style:none;transition:transform .25s var(--ease-out-quart),background-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out);transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);outline-style:none;display:inline-block}.dropdown__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *),.dropdown__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.dropdown__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.dropdown__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.dropdown__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.dropdown__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.dropdown__trigger{cursor:var(--cursor-interactive)}.dropdown__trigger:focus-visible:not(:focus),.dropdown__trigger[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.dropdown__trigger:disabled,.dropdown__trigger[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.dropdown__trigger[data-pending=true]{pointer-events:none}.dropdown__trigger:active,.dropdown__trigger[data-pressed=true]{transform:scale(.97)}.dropdown__popover{max-width:48svw;transform-origin:var(--trigger-anchor-point);scroll-padding-block:var(--spacing);scrollbar-width:var(--scrollbar-width);scrollbar-color:var(--scrollbar-color);scrollbar-gutter:var(--scrollbar-gutter);overscroll-behavior:contain;background-color:var(--overlay);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));padding:0;overflow-y:auto}@media(min-width:48rem){.dropdown__popover{min-width:calc(var(--spacing) * 55)}}.dropdown__popover{border-radius:min(32px,var(--radius-3xl));box-shadow:var(--shadow-overlay)}.dropdown__popover:focus-visible:not(:focus),.dropdown__popover[data-focus-visible=true]{--tw-outline-style:none;outline-style:none}.dropdown__popover[data-entering=true]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.15s;--tw-ease:ease;--tw-enter-opacity:0;--tw-enter-scale:.9;transition-duration:.15s;transition-timing-function:ease}.dropdown__popover[data-entering=true][data-placement=top]{--tw-enter-translate-y:calc(1*var(--spacing))}.dropdown__popover[data-entering=true][data-placement=bottom]{--tw-enter-translate-y:calc(1*var(--spacing)*-1)}.dropdown__popover[data-entering=true][data-placement=left]{--tw-enter-translate-x:calc(1*var(--spacing))}.dropdown__popover[data-entering=true][data-placement=right]{--tw-enter-translate-x:calc(1*var(--spacing)*-1)}.dropdown__popover[data-exiting=true]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.1s;--tw-ease:ease;--tw-exit-scale:.95;--tw-exit-opacity:0;transition-duration:.1s;transition-timing-function:ease}.dropdown__popover[data-exiting=true],.dropdown__popover[data-entering=true]{transition-property:opacity,transform;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));will-change:opacity,transform}.dropdown__popover [data-slot=popover-overlay-arrow]{fill:var(--overlay)}.dropdown__popover[data-placement=bottom] [data-slot=popover-overlay-arrow]{rotate:180deg}.dropdown__popover[data-placement=left] [data-slot=popover-overlay-arrow]{rotate:-90deg}.dropdown__popover[data-placement=right] [data-slot=popover-overlay-arrow]{rotate:90deg}.dropdown__popover [data-slot=dropdown-menu]{padding:calc(var(--spacing) * 1.5);--tw-outline-style:none;outline-style:none}.dropdown__popover [data-slot=menu-item]{padding-inline:calc(var(--spacing) * 2.5)}.dropdown__menu{gap:calc(var(--spacing) * .5);width:100%;padding:var(--spacing);flex-direction:column;display:flex;position:relative;overflow:clip}.dropdown__menu [data-slot=separator]{width:94%;margin-left:3%}.list-box-item{min-height:calc(var(--spacing) * 9);justify-content:flex-start;align-items:center;gap:calc(var(--spacing) * 3);border-radius:calc(var(--radius) * 2);width:100%;padding-inline:calc(var(--spacing) * 2);padding-block:calc(var(--spacing) * 1.5);--tw-outline-style:none;-webkit-tap-highlight-color:transparent;transition:transform .25s var(--ease-out-quart),box-shadow .15s var(--ease-out);outline-style:none;display:flex;position:relative}.list-box-item:is([data-reduce-motion=true],[data-reduce-motion=true] *),.list-box-item:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.list-box-item:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.list-box-item:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.list-box-item:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.list-box-item:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.list-box-item{cursor:var(--cursor-interactive)}.list-box-item [data-slot=label]{pointer-events:none;-webkit-user-select:none;user-select:none;width:fit-content}.list-box-item [data-slot=description]{pointer-events:none;text-wrap:wrap;-webkit-user-select:none;user-select:none}.list-box-item:has(.list-box-item__indicator){padding-inline-end:calc(var(--spacing) * 7)}.list-box-item:focus-visible:not(:focus),.list-box-item[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.list-box-item:active,.list-box-item[data-pressed=true]{transform:scale(.98)}@media(hover:hover){.list-box-item:hover,.list-box-item[data-hovered=true]{background-color:var(--default)}}.list-box-item[data-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.list-box-item__indicator{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4);--tw-translate-y: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y);color:var(--default-foreground);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.25s;inset-inline-end:calc(var(--spacing) * 2);flex-shrink:0;justify-content:center;align-items:center;transition-duration:.25s;display:flex;position:absolute;top:50%}.list-box-item__indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *),.list-box-item__indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.list-box-item__indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.list-box-item__indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.list-box-item__indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.list-box-item__indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.list-box-item__indicator [data-slot=list-box-item-indicator--checkmark]{width:calc(var(--spacing) * 2.5);height:calc(var(--spacing) * 2.5);transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.3s;transition-duration:.3s}.list-box-item__indicator [data-slot=list-box-item-indicator--checkmark]:is([data-reduce-motion=true],[data-reduce-motion=true] *),.list-box-item__indicator [data-slot=list-box-item-indicator--checkmark]:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.list-box-item__indicator [data-slot=list-box-item-indicator--checkmark]:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.list-box-item__indicator [data-slot=list-box-item-indicator--checkmark]:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.list-box-item__indicator [data-slot=list-box-item-indicator--checkmark]:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.list-box-item__indicator [data-slot=list-box-item-indicator--checkmark]:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.list-box-item__indicator .list-box-item[aria-selected=true] [data-slot=list-box-item-indicator--checkmark],.list-box-item__indicator .list-box-item[data-selected=true] [data-slot=list-box-item-indicator--checkmark]{transition:stroke-dashoffset .25s linear}:is(.list-box-item__indicator .list-box-item[aria-selected=true] [data-slot=list-box-item-indicator--checkmark],.list-box-item__indicator .list-box-item[data-selected=true] [data-slot=list-box-item-indicator--checkmark]):is([data-reduce-motion=true],[data-reduce-motion=true] *),:is(.list-box-item__indicator .list-box-item[aria-selected=true] [data-slot=list-box-item-indicator--checkmark],.list-box-item__indicator .list-box-item[data-selected=true] [data-slot=list-box-item-indicator--checkmark]):is([data-reduce-motion=true],[data-reduce-motion=true] *):before,:is(.list-box-item__indicator .list-box-item[aria-selected=true] [data-slot=list-box-item-indicator--checkmark],.list-box-item__indicator .list-box-item[data-selected=true] [data-slot=list-box-item-indicator--checkmark]):is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){:is(.list-box-item__indicator .list-box-item[aria-selected=true] [data-slot=list-box-item-indicator--checkmark],.list-box-item__indicator .list-box-item[data-selected=true] [data-slot=list-box-item-indicator--checkmark]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),:is(.list-box-item__indicator .list-box-item[aria-selected=true] [data-slot=list-box-item-indicator--checkmark],.list-box-item__indicator .list-box-item[data-selected=true] [data-slot=list-box-item-indicator--checkmark]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,:is(.list-box-item__indicator .list-box-item[aria-selected=true] [data-slot=list-box-item-indicator--checkmark],.list-box-item__indicator .list-box-item[data-selected=true] [data-slot=list-box-item-indicator--checkmark]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.list-box-item--danger .list-box-item__indicator,.list-box-item--danger [data-slot=label]{color:var(--danger)}.list-box-section{flex-direction:column;align-items:flex-start;gap:0;display:flex}.list-box{width:100%;padding:var(--spacing);position:relative;overflow:clip}.list-box>*+*{margin-top:var(--spacing)}.list-box [data-slot=separator][data-orientation=horizontal]{width:94%;margin-left:3%}.menu-item{min-height:calc(var(--spacing) * 9);justify-content:flex-start;align-items:center;gap:calc(var(--spacing) * 3);border-radius:calc(var(--radius) * 2);width:100%;padding-inline:calc(var(--spacing) * 2);padding-block:calc(var(--spacing) * 1.5);--tw-outline-style:none;-webkit-tap-highlight-color:transparent;transition:transform .25s var(--ease-out-quart),box-shadow .15s var(--ease-out);outline-style:none;display:flex;position:relative}.menu-item:is([data-reduce-motion=true],[data-reduce-motion=true] *),.menu-item:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.menu-item:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.menu-item:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.menu-item:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.menu-item:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.menu-item{cursor:var(--cursor-interactive)}.menu-item [data-slot=label]{pointer-events:none;-webkit-user-select:none;user-select:none;width:fit-content}.menu-item [data-slot=description]{pointer-events:none;text-wrap:wrap;-webkit-user-select:none;user-select:none}.menu-item [data-slot=submenu-indicator] svg{width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5)}.menu-item:has(.menu-item__indicator){padding-inline-start:calc(var(--spacing) * 7)}.menu-item[data-has-submenu=true]:has(.menu-item__indicator){padding-inline-start:calc(var(--spacing) * 2);padding-inline-end:calc(var(--spacing) * 7)}.menu-item:focus-visible:not(:focus),.menu-item[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.menu-item:active,.menu-item[data-pressed=true]{transform:scale(.98)}@media(hover:hover){.menu-item:hover,.menu-item[data-hovered=true]{background-color:var(--default)}}:is(.menu-item[aria-checked=true],.menu-item[aria-selected=true],.menu-item[data-selected=true]) [data-slot=menu-item-indicator--checkmark]{transition:stroke-dashoffset .1s linear}:is(.menu-item[aria-checked=true],.menu-item[aria-selected=true],.menu-item[data-selected=true]) [data-slot=menu-item-indicator--checkmark]:is([data-reduce-motion=true],[data-reduce-motion=true] *),:is(.menu-item[aria-checked=true],.menu-item[aria-selected=true],.menu-item[data-selected=true]) [data-slot=menu-item-indicator--checkmark]:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,:is(.menu-item[aria-checked=true],.menu-item[aria-selected=true],.menu-item[data-selected=true]) [data-slot=menu-item-indicator--checkmark]:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){:is(.menu-item[aria-checked=true],.menu-item[aria-selected=true],.menu-item[data-selected=true]) [data-slot=menu-item-indicator--checkmark]:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),:is(.menu-item[aria-checked=true],.menu-item[aria-selected=true],.menu-item[data-selected=true]) [data-slot=menu-item-indicator--checkmark]:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,:is(.menu-item[aria-checked=true],.menu-item[aria-selected=true],.menu-item[data-selected=true]) [data-slot=menu-item-indicator--checkmark]:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}:is(.menu-item[aria-checked=true],.menu-item[aria-selected=true],.menu-item[data-selected=true]) [data-slot=menu-item-indicator--dot]{--tw-scale-x:100%;--tw-scale-y:100%;--tw-scale-z:100%;scale:var(--tw-scale-x) var(--tw-scale-y);opacity:1}.menu-item[data-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.menu-item__indicator{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4);--tw-translate-y: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y);color:var(--muted);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.25s;inset-inline-start:calc(var(--spacing) * 2);flex-shrink:0;justify-content:center;align-items:center;transition-duration:.25s;display:flex;position:absolute;top:50%}.menu-item__indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *),.menu-item__indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.menu-item__indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.menu-item__indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.menu-item__indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.menu-item__indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.menu-item[data-has-submenu=true] .menu-item__indicator{inset-inline-start:auto;inset-inline-end:calc(var(--spacing) * 2)}.menu-item__indicator [data-slot=menu-item-indicator--checkmark]{width:calc(var(--spacing) * 2.5);height:calc(var(--spacing) * 2.5)}.menu-item[data-selection-mode=multiple] :is(.menu-item__indicator [data-slot=menu-item-indicator--checkmark]){transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.3s;transition-duration:.3s}.menu-item[data-selection-mode=multiple] :is(.menu-item__indicator [data-slot=menu-item-indicator--checkmark]):is([data-reduce-motion=true],[data-reduce-motion=true] *),.menu-item[data-selection-mode=multiple] :is(.menu-item__indicator [data-slot=menu-item-indicator--checkmark]):is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.menu-item[data-selection-mode=multiple] :is(.menu-item__indicator [data-slot=menu-item-indicator--checkmark]):is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.menu-item[data-selection-mode=multiple] :is(.menu-item__indicator [data-slot=menu-item-indicator--checkmark]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.menu-item[data-selection-mode=multiple] :is(.menu-item__indicator [data-slot=menu-item-indicator--checkmark]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.menu-item[data-selection-mode=multiple] :is(.menu-item__indicator [data-slot=menu-item-indicator--checkmark]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.menu-item__indicator [data-slot=menu-item-indicator--dot]{width:calc(var(--spacing) * 2);height:calc(var(--spacing) * 2)}.menu-item[data-selection-mode=multiple] :is(.menu-item__indicator [data-slot=menu-item-indicator--dot]){transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.25s;transition-duration:.25s}.menu-item[data-selection-mode=multiple] :is(.menu-item__indicator [data-slot=menu-item-indicator--dot]):is([data-reduce-motion=true],[data-reduce-motion=true] *),.menu-item[data-selection-mode=multiple] :is(.menu-item__indicator [data-slot=menu-item-indicator--dot]):is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.menu-item[data-selection-mode=multiple] :is(.menu-item__indicator [data-slot=menu-item-indicator--dot]):is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.menu-item[data-selection-mode=multiple] :is(.menu-item__indicator [data-slot=menu-item-indicator--dot]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.menu-item[data-selection-mode=multiple] :is(.menu-item__indicator [data-slot=menu-item-indicator--dot]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.menu-item[data-selection-mode=multiple] :is(.menu-item__indicator [data-slot=menu-item-indicator--dot]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.menu-item__indicator [data-slot=menu-item-indicator--dot]{--tw-scale-x:70%;--tw-scale-y:70%;--tw-scale-z:70%;scale:var(--tw-scale-x) var(--tw-scale-y);opacity:0}.menu-item__indicator--submenu{color:var(--muted)}.menu-item__indicator--submenu svg{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.menu-item--danger .menu-item__indicator,.menu-item--danger [data-slot=label]{color:var(--danger)}.menu-section{flex-direction:column;align-items:flex-start;gap:0;display:flex}.menu{gap:var(--spacing);width:100%;padding:var(--spacing);flex-direction:column;display:flex;position:relative;overflow:clip}.menu [data-slot=separator]{width:94%;margin-left:3%}.tag-group{gap:var(--spacing);flex-direction:column;display:flex;position:relative}.tag-group__list{gap:calc(var(--spacing) * 1.5);flex-wrap:wrap;display:flex;position:relative}.tag-group [slot=description],.tag-group [data-slot=description],.tag-group [slot=errorMessage],.tag-group [data-slot=error-message]{padding:var(--spacing)}.tag{--optical-offset:.031em;align-items:center;gap:var(--spacing);border-radius:calc(var(--radius) * 1.5);--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;transition:color .1s var(--ease-smooth),scale .1s var(--ease-smooth),opacity .1s var(--ease-smooth),background-color .1s var(--ease-smooth),box-shadow .1s var(--ease-out);transform-origin:50%;transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);display:inline-flex;position:relative}.tag:is([data-reduce-motion=true],[data-reduce-motion=true] *),.tag:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.tag:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.tag:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.tag:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.tag:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.tag{cursor:var(--cursor-interactive)}.tag svg{pointer-events:none;width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3);color:currentColor;flex-shrink:0;align-self:center}.tag:is([data-disabled=true],[aria-disabled=true]){opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.tag:is(:focus-visible,[data-focus-visible]){--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.tag:is([data-selected=true],[aria-selected=true]){background-color:var(--accent-soft);color:var(--accent-soft-foreground)}@media(hover:hover){.tag:is([data-selected=true],[aria-selected=true]):is(:hover,[data-hovered=true]){background-color:var(--accent-soft-hover)}}.tag--sm{padding-inline:calc(var(--spacing) * 2);padding-block:calc(var(--spacing) * .5);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.tag--md{padding-inline:calc(var(--spacing) * 2);padding-block:var(--spacing);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.tag--lg{border-radius:calc(var(--radius) * 2);padding-inline:calc(var(--spacing) * 2.5);padding-block:calc(var(--spacing) * 1.5);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.tag--default{background-color:var(--default);color:var(--default-foreground)}@media(hover:hover){.tag--default:is(:hover,[data-hovered=true]):not([data-selected=true]):not([data-disabled=true]){background-color:var(--default-hover)}}.tag--surface{background-color:var(--surface);color:var(--surface-foreground)}@media(hover:hover){.tag--surface:is(:hover,[data-hovered=true]):not([data-selected=true]):not([data-disabled=true]){background-color:var(--surface-hover)}}.tag__remove-button{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3);color:inherit}.tag__remove-button svg{width:inherit;height:inherit;color:currentColor;flex-shrink:0;align-self:center}.color-area{width:100%;max-width:calc(var(--spacing) * 56);border-radius:calc(var(--radius) * 2);-webkit-tap-highlight-color:transparent;aspect-ratio:1;background:var(--color-area-background);flex-shrink:0;position:relative;box-shadow:inset 0 0 0 1px #0000001a}.color-area[data-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.color-area--show-dots:after{content:"";pointer-events:none;border-radius:inherit;background-image:radial-gradient(circle,#fff3 1px,#0000 1px);background-size:8px 8px;position:absolute;top:0;right:0;bottom:0;left:0}.color-area__thumb{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4);border-radius:calc(var(--radius) * 1.5);will-change:width,height;background-color:var(--color-area-thumb-color);transition:width .15s var(--ease-out),height .15s var(--ease-out);border:3px solid #fff;box-shadow:0 0 0 1px #0000001a,inset 0 0 0 1px #0000001a}.color-area__thumb:is([data-reduce-motion=true],[data-reduce-motion=true] *),.color-area__thumb:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.color-area__thumb:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.color-area__thumb:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.color-area__thumb:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.color-area__thumb:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.color-area__thumb[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.color-area__thumb[data-dragging=true]{width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5)}.color-area__thumb[data-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.color-picker{display:inline-flex}.color-picker__trigger{align-items:center;gap:calc(var(--spacing) * 3);border-radius:calc(var(--radius) * .5);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));-webkit-tap-highlight-color:transparent;cursor:var(--cursor-interactive);transition:background-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out);display:inline-flex}.color-picker__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *),.color-picker__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.color-picker__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.color-picker__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.color-picker__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.color-picker__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.color-picker__trigger [data-slot=label]{cursor:var(--cursor-interactive)}.color-picker__trigger:focus-visible:not(:focus),.color-picker__trigger[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.color-picker__trigger:disabled,.color-picker__trigger[data-disabled=true],.color-picker__trigger[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.color-picker__popover{min-width:calc(var(--spacing) * 62);transform-origin:var(--trigger-anchor-point);scrollbar-color:auto;scrollbar-gutter:auto;-ms-overflow-style:none;scrollbar-width:none;overscroll-behavior:contain;background-color:var(--overlay);padding-inline:calc(var(--spacing) * 2);padding-top:calc(var(--spacing) * 2);padding-bottom:calc(var(--spacing) * 3);box-shadow:var(--shadow-overlay);border-radius:min(32px,calc(var(--radius) * 2.5));gap:calc(var(--spacing) * 3);flex-direction:column;display:flex;overflow:hidden auto}.color-picker__popover:focus-visible:not(:focus),.color-picker__popover[data-focus-visible=true]{--tw-outline-style:none;outline-style:none}.color-picker__popover[data-entering=true]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.15s;--tw-ease:ease;--tw-enter-opacity:0;--tw-enter-scale:.95;transition-duration:.15s;transition-timing-function:ease}.color-picker__popover[data-entering=true][data-placement^=top]{--tw-enter-translate-y:calc(1*var(--spacing))}.color-picker__popover[data-entering=true][data-placement^=bottom]{--tw-enter-translate-y:calc(1*var(--spacing)*-1)}.color-picker__popover[data-entering=true][data-placement^=left]{--tw-enter-translate-x:calc(1*var(--spacing))}.color-picker__popover[data-entering=true][data-placement^=right]{--tw-enter-translate-x:calc(1*var(--spacing)*-1)}.color-picker__popover[data-exiting=true]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.1s;--tw-ease:ease;--tw-exit-scale:.95;--tw-exit-opacity:0;transition-duration:.1s;transition-timing-function:ease}.color-picker__popover[data-exiting=true],.color-picker__popover[data-entering=true]{transition-property:opacity,transform;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));will-change:opacity,transform}.color-slider{gap:var(--spacing);grid-template:"label output""track track"/1fr auto;width:100%;display:grid}.color-slider:not(:has([data-slot=label])):not(:has(.color-slider__output)){grid-template:"track"/1fr;gap:0}.color-slider:has([data-slot=label]):not(:has(.color-slider__output)){grid-template-columns:1fr;grid-template-areas:"label""track"}.color-slider:not(:has([data-slot=label])):has(.color-slider__output){grid-template-columns:1fr;grid-template-areas:"output""track"}.color-slider:not(:has([data-slot=label])):has(.color-slider__output) .color-slider__output{justify-self:end}.color-slider [data-slot=label]{width:fit-content;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);grid-area:label}.color-slider .color-slider__output{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,);grid-area:output}.color-slider .color-slider__track{border-radius:calc(var(--radius) * 2);grid-area:track;position:relative}.color-slider .color-slider__track:before,.color-slider .color-slider__track:after{content:"";z-index:0;pointer-events:none;position:absolute}.color-slider .color-slider__thumb{cursor:grab;border-radius:calc(var(--radius) * 2);-webkit-tap-highlight-color:transparent;border-style:var(--tw-border-style);border-width:3px;border-color:var(--color-white);--tw-shadow:var(--overlay-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);z-index:1;transition:transform .25s var(--ease-out),box-shadow .15s var(--ease-out);justify-content:center;align-items:center;display:flex;position:absolute}.color-slider .color-slider__thumb:is([data-reduce-motion=true],[data-reduce-motion=true] *),.color-slider .color-slider__thumb:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.color-slider .color-slider__thumb:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.color-slider .color-slider__thumb:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.color-slider .color-slider__thumb:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.color-slider .color-slider__thumb:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.color-slider .color-slider__thumb[data-dragging=true]{cursor:grabbing}.color-slider .color-slider__thumb[data-focus-visible=true]{z-index:10;--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.color-slider .color-slider__thumb[data-disabled=true]{cursor:default;background-color:var(--default)}.color-slider:disabled,.color-slider[data-disabled=true],.color-slider[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}:is(.color-slider:disabled,.color-slider[data-disabled=true],.color-slider[aria-disabled=true]) [data-slot=label]{opacity:1}.color-slider[data-orientation=horizontal]{flex-direction:column}.color-slider[data-orientation=horizontal] .color-slider__track{height:calc(var(--spacing) * 5);border-radius:0;justify-self:center;width:calc(100% - 1.25rem);box-shadow:inset 0 1px #0000001a,inset 0 -1px #0000001a}.color-slider[data-orientation=horizontal] .color-slider__track:before,.color-slider[data-orientation=horizontal] .color-slider__track:after{width:.625rem;height:100%;top:0}.color-slider[data-orientation=horizontal] .color-slider__track:before{border-top-left-radius:calc(var(--radius) * 2);border-bottom-left-radius:calc(var(--radius) * 2);background:linear-gradient(var(--track-start-color,transparent)),repeating-conic-gradient(#efefef,#efefef 25%,#f7f7f7 0%,#f7f7f7 50%) 50% / 16px 16px;left:-.625rem;box-shadow:inset 1px 0 #0000001a,inset 0 1px #0000001a,inset 0 -1px #0000001a}.color-slider[data-orientation=horizontal] .color-slider__track:after{border-top-right-radius:calc(var(--radius) * 2);border-bottom-right-radius:calc(var(--radius) * 2);background-color:var(--track-end-color,transparent);right:-.625rem;box-shadow:inset -1px 0 #0000001a,inset 0 1px #0000001a,inset 0 -1px #0000001a}.color-slider[data-orientation=horizontal] .color-slider__thumb{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4);top:50%}.color-slider[data-orientation=vertical]{gap:calc(var(--spacing) * 2);flex-direction:row;grid-template:"output""track"1fr"label"/1fr;place-items:center;height:100%}.color-slider[data-orientation=vertical]:not(:has([data-slot=label])):not(:has(.color-slider__output)){grid-template-rows:1fr;grid-template-areas:"track";gap:0}.color-slider[data-orientation=vertical]:has([data-slot=label]):not(:has(.color-slider__output)){grid-template-rows:1fr auto;grid-template-areas:"track""label"}.color-slider[data-orientation=vertical]:not(:has([data-slot=label])):has(.color-slider__output){grid-template-rows:auto 1fr;grid-template-areas:"output""track"}.color-slider[data-orientation=vertical] .color-slider__output,.color-slider[data-orientation=vertical] [data-slot=label]{text-align:center}.color-slider[data-orientation=vertical] .color-slider__track{width:calc(var(--spacing) * 5);border-radius:0;justify-self:center;height:calc(100% - 1.25rem);box-shadow:inset 1px 0 #0000001a,inset -1px 0 #0000001a}.color-slider[data-orientation=vertical] .color-slider__track:before,.color-slider[data-orientation=vertical] .color-slider__track:after{width:100%;height:.625rem;left:0}.color-slider[data-orientation=vertical] .color-slider__track:before{background:linear-gradient(var(--track-start-color,transparent)),repeating-conic-gradient(#efefef,#efefef 25%,#f7f7f7 0%,#f7f7f7 50%) 50% / 16px 16px;border-bottom-right-radius:999px;border-bottom-left-radius:999px;bottom:-.625rem;box-shadow:inset 1px 0 #0000001a,inset -1px 0 #0000001a,inset 0 -1px #0000001a}.color-slider[data-orientation=vertical] .color-slider__track:after{background-color:var(--track-end-color,transparent);border-top-left-radius:999px;border-top-right-radius:999px;top:-.625rem;box-shadow:inset 1px 0 #0000001a,inset -1px 0 #0000001a,inset 0 1px #0000001a}.color-slider[data-orientation=vertical] .color-slider__thumb{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4);left:50%}.color-swatch{box-sizing:border-box;width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8);background:linear-gradient(var(--color-swatch-current),var(--color-swatch-current)),repeating-conic-gradient(#efefef,#efefef 25%,#f7f7f7 0%,#f7f7f7 50%) 50% / 16px 16px;flex-shrink:0;position:relative;box-shadow:inset 0 0 0 1px #0000001a}.color-swatch--circle{border-radius:calc(var(--radius) * 2)}.color-swatch--square{border-radius:calc(var(--radius) * .75)}.color-swatch--xs{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.color-swatch--xs.color-swatch--circle{border-radius:calc(var(--radius) * 1)}.color-swatch--sm{width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6)}.color-swatch--sm.color-swatch--circle{border-radius:calc(var(--radius) * 1.5)}.color-swatch--lg{width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9)}.color-swatch--lg.color-swatch--circle{border-radius:calc(var(--radius) * 3)}.color-swatch--xl{width:calc(var(--spacing) * 10);height:calc(var(--spacing) * 10)}.color-swatch--xl.color-swatch--circle{border-radius:calc(var(--radius) * 3)}.color-swatch-picker{align-items:center;gap:calc(var(--spacing) * 2);flex-wrap:wrap;display:flex}.color-swatch-picker__item{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8);border-radius:calc(var(--radius) * 2);border-style:var(--tw-border-style);--tw-outline-style:none;-webkit-tap-highlight-color:transparent;cursor:var(--cursor-interactive);transition:border-color .1s var(--ease-out),box-shadow .1s var(--ease-out);transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);border-width:2px;border-color:#0000;outline-style:none;justify-content:center;align-items:center;display:flex;position:relative}.color-swatch-picker__item:is([data-reduce-motion=true],[data-reduce-motion=true] *),.color-swatch-picker__item:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.color-swatch-picker__item:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.color-swatch-picker__item:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.color-swatch-picker__item:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.color-swatch-picker__item:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.color-swatch-picker__item:focus-visible,.color-swatch-picker__item[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.color-swatch-picker__item[data-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.color-swatch-picker__item[data-selected=true]{border-color:var(--color-swatch-current);box-shadow:var(--field-shadow)}.color-swatch-picker__item[data-selected=true] .color-swatch-picker__swatch{transform:scale(.77)}.color-swatch-picker__swatch{border-radius:inherit;width:100%;height:100%;transition:transform .1s var(--ease-out);transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);display:block}.color-swatch-picker__swatch:is([data-reduce-motion=true],[data-reduce-motion=true] *),.color-swatch-picker__swatch:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.color-swatch-picker__swatch:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.color-swatch-picker__swatch:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.color-swatch-picker__swatch:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.color-swatch-picker__swatch:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}@media(hover:hover){.color-swatch-picker__swatch:hover{transform:scale(1.1)}}.color-swatch-picker__indicator{pointer-events:none;z-index:10;justify-content:center;align-items:center;display:flex;position:absolute;top:0;right:0;bottom:0;left:0}.color-swatch-picker__indicator>*{width:33.3333%;height:33.3333%;color:var(--color-white);transition:transform .15s var(--ease-out);transform:scale(0)translateZ(0)}.color-swatch-picker__indicator>:is([data-reduce-motion=true],[data-reduce-motion=true] *),.color-swatch-picker__indicator>:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.color-swatch-picker__indicator>:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.color-swatch-picker__indicator>:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.color-swatch-picker__indicator>:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.color-swatch-picker__indicator>:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.color-swatch-picker__indicator[data-light-color=true] .color-swatch-picker__indicator>*{color:var(--color-black)}.color-swatch-picker__item[data-selected=true] .color-swatch-picker__indicator>*{transform:scale(1)translateZ(0)}.color-swatch-picker--stack{flex-direction:column}.color-swatch-picker--xs .color-swatch-picker__item{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4);border-radius:calc(var(--radius) * 1);border-style:var(--tw-border-style);border-width:1px}.color-swatch-picker--sm .color-swatch-picker__item{width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6);border-radius:calc(var(--radius) * 1.5);border-style:var(--tw-border-style);border-width:2px}.color-swatch-picker--lg .color-swatch-picker__item{width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9);border-radius:calc(var(--radius) * 3);border-style:var(--tw-border-style);border-width:3px}.color-swatch-picker--xl .color-swatch-picker__item{width:calc(var(--spacing) * 10);height:calc(var(--spacing) * 10);border-radius:calc(var(--radius) * 3);border-style:var(--tw-border-style);border-width:3px}.color-swatch-picker--square .color-swatch-picker__item{border-radius:calc(var(--radius) * 1.5)}.color-swatch-picker--square .color-swatch-picker__item .color-swatch-picker__swatch,.color-swatch-picker--square .color-swatch-picker__item[data-selected=true] .color-swatch-picker__swatch{border-radius:calc(var(--radius) * 1)}.color-swatch-picker--square.color-swatch-picker--xs .color-swatch-picker__item,.color-swatch-picker--square.color-swatch-picker--xs .color-swatch-picker__item .color-swatch-picker__swatch,.color-swatch-picker--square.color-swatch-picker--xs .color-swatch-picker__item[data-selected=true] .color-swatch-picker__swatch{border-radius:calc(var(--radius) * .75)}.color-swatch-picker--square.color-swatch-picker--sm .color-swatch-picker__item,.color-swatch-picker--square.color-swatch-picker--sm .color-swatch-picker__item .color-swatch-picker__swatch{border-radius:calc(var(--radius) * 1)}.color-swatch-picker--square.color-swatch-picker--sm .color-swatch-picker__item[data-selected=true] .color-swatch-picker__swatch{border-radius:calc(var(--radius) * .75)}.color-swatch-picker--square.color-swatch-picker--lg .color-swatch-picker__item{border-radius:calc(var(--radius) * 1.5)}.color-swatch-picker--square.color-swatch-picker--lg .color-swatch-picker__item .color-swatch-picker__swatch,.color-swatch-picker--square.color-swatch-picker--lg .color-swatch-picker__item[data-selected=true] .color-swatch-picker__swatch{border-radius:calc(var(--radius) * 1)}.color-swatch-picker--square.color-swatch-picker--xl .color-swatch-picker__item{border-radius:calc(var(--radius) * 1.5)}.color-swatch-picker--square.color-swatch-picker--xl .color-swatch-picker__item .color-swatch-picker__swatch,.color-swatch-picker--square.color-swatch-picker--xl .color-swatch-picker__item[data-selected=true] .color-swatch-picker__swatch{border-radius:calc(var(--radius) * 1)}.color-input-group{height:calc(var(--spacing) * 9);border-radius:var(--field-radius,calc(var(--radius) * 1.5));border-style:var(--tw-border-style);background-color:var(--field-background,var(--default));font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--field-foreground,var(--foreground));--tw-shadow:var(--field-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;border-width:1px;border-width:var(--border-width-field);border-color:var(--field-border);transition:background-color .15s var(--ease-smooth),border-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out);outline-style:none;align-items:center;display:inline-flex;overflow:hidden}.color-input-group:is([data-reduce-motion=true],[data-reduce-motion=true] *),.color-input-group:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.color-input-group:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.color-input-group:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.color-input-group:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.color-input-group:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}@media(hover:hover){.color-input-group:hover:not(:focus-within),.color-input-group[data-hovered=true]:not([data-focus-within=true]){background-color:var(--field-hover);border-color:var(--field-border-hover)}}.color-input-group[data-focus-within=true],.color-input-group:focus-within{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-outline-style:none;--tw-ring-offset-width:0px;outline-style:none}.color-input-group[data-invalid=true]{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}.color-input-group[data-invalid=true]:focus,.color-input-group[data-invalid=true]:focus-visible,.color-input-group[data-invalid=true][data-focused=true],.color-input-group[data-invalid=true][data-focus-visible=true],.color-input-group[data-invalid=true]:focus-within,.color-input-group[data-invalid=true][data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.color-input-group[data-invalid=true]{background-color:var(--field-focus);border-color:var(--color-field-border-invalid)}.color-input-group[data-disabled=true],.color-input-group[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.color-input-group__input{cursor:text;border-style:var(--tw-border-style);height:100%;padding-inline:calc(var(--spacing) * 3);padding-block:calc(var(--spacing) * 2);font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;background-color:#0000;border-width:0;border-radius:0;outline-style:none;flex:1;align-items:center;display:flex}@media(min-width:40rem){.color-input-group__input{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}.color-input-group__input::placeholder{color:var(--field-placeholder,var(--muted))}.color-input-group:has([data-slot=color-input-group-prefix]) .color-input-group__input{padding-left:calc(var(--spacing) * 2);border-top-left-radius:0;border-bottom-left-radius:0}.color-input-group:has([data-slot=color-input-group-suffix]) .color-input-group__input{padding-right:calc(var(--spacing) * 2);border-top-right-radius:0;border-bottom-right-radius:0}.color-input-group__input:focus,.color-input-group__input:focus-visible{--tw-outline-style:none;outline-style:none}.color-input-group__prefix{color:var(--field-placeholder,var(--muted));margin-right:0;margin-left:calc(var(--spacing) * 3);flex-shrink:0;align-items:center;display:flex}.color-input-group__suffix{color:var(--field-placeholder,var(--muted));margin-right:calc(var(--spacing) * 3);flex-shrink:0;align-items:center;display:flex}.color-input-group--secondary{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);background-color:var(--color-input-group-bg);--color-input-group-bg:var(--default);--color-input-group-bg-hover:var(--default-hover);--color-input-group-bg-focus:var(--default)}@media(hover:hover){.color-input-group--secondary:hover:not(:focus-within),.color-input-group--secondary[data-hovered=true]:not([data-focus-within=true]){background-color:var(--color-input-group-bg-hover)}}.color-input-group--secondary:focus-within,.color-input-group--secondary[data-focus-within=true]{background-color:var(--color-input-group-bg-focus)}.color-input-group--secondary[data-invalid=true]{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}.color-input-group--secondary[data-invalid=true]:focus,.color-input-group--secondary[data-invalid=true]:focus-visible,.color-input-group--secondary[data-invalid=true][data-focused=true],.color-input-group--secondary[data-invalid=true][data-focus-visible=true],.color-input-group--secondary[data-invalid=true]:focus-within,.color-input-group--secondary[data-invalid=true][data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.color-input-group--secondary[data-invalid=true]{border-color:var(--color-field-border-invalid);background-color:var(--color-input-group-bg-focus)}.color-input-group--secondary [data-slot=color-input-group-input]{background-color:#0000}.color-input-group--full-width{width:100%}.color-field{gap:var(--spacing);flex-direction:column;display:flex}:is(.color-field[data-invalid=true],.color-field[aria-invalid=true]) [data-slot=description]{display:none}.color-field [data-slot=label]{width:fit-content}.color-field--full-width{width:100%}.slider{gap:var(--spacing);grid-template-columns:1fr auto;grid-template-areas:"label output""track track";width:100%;display:grid}.slider [data-slot=label]{width:fit-content;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);grid-area:label}.slider .slider__output{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,);grid-area:output}.slider .slider__track{border-radius:calc(var(--radius) * 1.5);background-color:var(--default);grid-area:track;position:relative}.slider .slider__fill{pointer-events:none;background-color:var(--accent);position:absolute}.slider .slider__thumb{cursor:grab;border-radius:calc(var(--radius) * 1.5);background-color:var(--accent);-webkit-tap-highlight-color:transparent;transition:background-color .25s var(--ease-smooth),transform .25s var(--ease-out),box-shadow .15s var(--ease-out);justify-content:center;align-items:center;display:flex;position:absolute}.slider .slider__thumb:is([data-reduce-motion=true],[data-reduce-motion=true] *),.slider .slider__thumb:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.slider .slider__thumb:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.slider .slider__thumb:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.slider .slider__thumb:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.slider .slider__thumb:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.slider .slider__thumb:after{z-index:10;border-radius:calc(var(--radius) * 1);background-color:var(--accent-foreground);color:var(--color-black);--tw-shadow:var(--field-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);content:"";transform-origin:50%;transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));position:relative}@media(prefers-reduced-motion:reduce){.slider .slider__thumb:after:not(:is()){transition-property:none}}.slider .slider__thumb[data-dragging=true]{cursor:grabbing}.slider .slider__thumb[data-dragging=true]:after{scale:.9}@media(prefers-reduced-motion:reduce){.slider .slider__thumb[data-dragging=true]:after:not(:is()){--tw-scale-x:100%;--tw-scale-y:100%;--tw-scale-z:100%;scale:var(--tw-scale-x) var(--tw-scale-y)}}.slider .slider__thumb[data-focus-visible=true]{z-index:10;--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.slider .slider__thumb[data-disabled=true]{cursor:default}.slider:disabled,.slider[data-disabled=true],.slider[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}:is(.slider:disabled,.slider[data-disabled=true],.slider[aria-disabled=true]) [data-slot=label]{opacity:1}.slider[data-orientation=horizontal]{flex-direction:column}.slider[data-orientation=horizontal] .slider__track{height:calc(var(--spacing) * 5);border-inline-style:var(--tw-border-style);border-inline-width:.75rem;border-inline-color:#0000;width:100%}.slider[data-orientation=horizontal] .slider__track[data-fill-start=true]{border-inline-start-color:var(--accent)}.slider[data-orientation=horizontal] .slider__track[data-fill-end=true]{border-inline-end-color:var(--accent)}.slider[data-orientation=horizontal] .slider__fill,.slider[data-orientation=horizontal] .slider__thumb{height:100%}.slider[data-orientation=horizontal] .slider__thumb{width:1.75rem;top:50%}.slider[data-orientation=horizontal] .slider__thumb:after{width:1.5rem;height:1rem}.slider[data-orientation=vertical]{gap:calc(var(--spacing) * 2);flex-direction:row;grid-template:"output""track"1fr"label"/1fr;height:100%}.slider[data-orientation=vertical] .slider__output,.slider[data-orientation=vertical] [data-slot=label]{text-align:center}.slider[data-orientation=vertical] .slider__track{height:100%;width:calc(var(--spacing) * 5);border-block-style:var(--tw-border-style);border-block-width:.75rem;border-block-color:#0000;justify-self:center}.slider[data-orientation=vertical] .slider__track[data-fill-start=true]{border-bottom-color:var(--accent)}.slider[data-orientation=vertical] .slider__track[data-fill-end=true]{border-top-color:var(--accent)}.slider[data-orientation=vertical] .slider__fill,.slider[data-orientation=vertical] .slider__thumb{width:100%}.slider[data-orientation=vertical] .slider__thumb{height:1.75rem;left:50%}.slider[data-orientation=vertical] .slider__thumb:after{width:1rem;height:1.5rem}.switch{align-items:flex-start;gap:var(--spacing);-webkit-tap-highlight-color:transparent;cursor:var(--cursor-interactive);--switch-control-bg:var(--default);--switch-control-bg-hover:var(--switch-control-bg);flex-direction:column;display:flex}@supports (color:color-mix(in lab,red,red)){.switch{--switch-control-bg-hover:color-mix(in oklab, var(--switch-control-bg), transparent 20%)}}.switch{--switch-control-bg-pressed:var(--switch-control-bg-hover);--switch-control-bg-checked:var(--accent);--switch-control-bg-checked-hover:var(--accent-hover)}.switch[data-disabled=true],.switch[data-disabled=true] [data-slot=description],.switch[data-disabled=true] [data-slot=field-error]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.switch[data-disabled=true] .switch__thumb{background-color:var(--default-foreground)}@supports (color:color-mix(in lab,red,red)){.switch[data-disabled=true] .switch__thumb{background-color:color-mix(in oklab,var(--default-foreground) 20%,transparent)}}.switch>[data-slot=description]{width:100%;min-width:0;padding-inline-start:3.25rem}.switch>[data-slot=field-error]{width:100%;min-width:0;font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));color:var(--muted);padding-inline-start:3.25rem}.switch.switch--sm>[data-slot=description],.switch.switch--sm>[data-slot=field-error]{padding-inline-start:2.75rem}.switch.switch--lg>[data-slot=description],.switch.switch--lg>[data-slot=field-error]{padding-inline-start:3.75rem}:is(.switch:disabled[aria-checked=true],.switch:disabled[data-selected=true],.switch[data-disabled=true][aria-checked=true],.switch[data-disabled=true][data-selected=true],.switch[aria-disabled=true][aria-checked=true],.switch[aria-disabled=true][data-selected=true]) .switch__thumb{opacity:.4}.switch__control{border-radius:calc(var(--radius) * 1.5);background-color:var(--switch-control-bg);width:2.5rem;height:1.25rem;transition:background-color .25s var(--ease-smooth),box-shadow .15s var(--ease-out);flex-shrink:0;align-items:center;display:flex;position:relative;overflow:hidden}.switch__control:is([data-reduce-motion=true],[data-reduce-motion=true] *),.switch__control:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.switch__control:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.switch__control:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.switch__control:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.switch__control:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.switch:focus-visible .switch__control,.switch:has([data-slot=switch-content][data-focus-visible=true]) .switch__control,.switch [data-slot=switch-content][data-focus-visible=true] .switch__control{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.switch:hover .switch__control,.switch:has([data-slot=switch-content][data-hovered=true]) .switch__control,.switch [data-slot=switch-content][data-hovered=true] .switch__control{background-color:var(--switch-control-bg-hover)}.switch:active .switch__control,.switch:has([data-slot=switch-content][data-pressed=true]) .switch__control,.switch [data-slot=switch-content][data-pressed=true] .switch__control{background-color:var(--switch-control-bg-pressed)}:is(.switch:active .switch__control,.switch:has([data-slot=switch-content][data-pressed=true]) .switch__control,.switch [data-slot=switch-content][data-pressed=true] .switch__control):is([data-reduce-motion=true],[data-reduce-motion=true] *),:is(.switch:active .switch__control,.switch:has([data-slot=switch-content][data-pressed=true]) .switch__control,.switch [data-slot=switch-content][data-pressed=true] .switch__control):is([data-reduce-motion=true],[data-reduce-motion=true] *):before,:is(.switch:active .switch__control,.switch:has([data-slot=switch-content][data-pressed=true]) .switch__control,.switch [data-slot=switch-content][data-pressed=true] .switch__control):is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transform:none}@media(prefers-reduced-motion:reduce){:is(.switch:active .switch__control,.switch:has([data-slot=switch-content][data-pressed=true]) .switch__control,.switch [data-slot=switch-content][data-pressed=true] .switch__control):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),:is(.switch:active .switch__control,.switch:has([data-slot=switch-content][data-pressed=true]) .switch__control,.switch [data-slot=switch-content][data-pressed=true] .switch__control):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,:is(.switch:active .switch__control,.switch:has([data-slot=switch-content][data-pressed=true]) .switch__control,.switch [data-slot=switch-content][data-pressed=true] .switch__control):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transform:none}}.switch[aria-checked=true] .switch__control,.switch[data-selected=true] .switch__control{background-color:var(--switch-control-bg-checked)}.switch[aria-checked=true]:hover .switch__control,.switch[data-selected=true]:hover .switch__control,.switch[aria-checked=true][data-hovered=true] .switch__control,.switch[data-selected=true][data-hovered=true] .switch__control,.switch:has([data-slot=switch-content][data-hovered=true])[data-selected=true] .switch__control,.switch[aria-checked=true]:active .switch__control,.switch[data-selected=true]:active .switch__control,.switch[aria-checked=true][data-pressed=true] .switch__control,.switch[data-selected=true][data-pressed=true] .switch__control,.switch:has([data-slot=switch-content][data-pressed=true])[data-selected=true] .switch__control{background-color:var(--switch-control-bg-checked-hover)}.switch__content{cursor:inherit;align-items:center;gap:calc(var(--spacing) * 3);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--foreground);--tw-outline-style:none;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;outline-style:none;display:inline-flex}.switch--sm .switch__control{border-radius:calc(var(--radius) * 1);width:2rem;height:1rem}.switch--lg .switch__control{width:3rem;height:1.5rem}.switch__thumb{transform-origin:50%;border-radius:calc(var(--radius) * 1);background-color:var(--color-white);color:var(--color-black);--tw-shadow:var(--field-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);width:1.375rem;height:1rem;transition:margin .3s var(--ease-out-fluid),background-color .2s var(--ease-out);margin-inline-start:calc(var(--spacing) * .5);display:flex}.switch__thumb:is([data-reduce-motion=true],[data-reduce-motion=true] *),.switch__thumb:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.switch__thumb:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.switch__thumb:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.switch__thumb:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.switch__thumb:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.switch[aria-checked=true] .switch__thumb,.switch[data-selected=true] .switch__thumb{background-color:var(--accent-foreground);color:var(--accent);margin-inline-start:calc(100% - 1.5rem);box-shadow:0 0 5px #00000005,0 2px 10px #0000000f,0 0 1px #0000004d}.switch--sm .switch__thumb{border-radius:calc(var(--radius) * .75);width:1.03125rem;height:.75rem}.switch[aria-checked=true] :is(.switch--sm .switch__thumb),.switch[data-selected=true] :is(.switch--sm .switch__thumb){margin-inline-start:calc(100% - 1.15625rem)}.switch--lg .switch__thumb{border-radius:calc(var(--radius) * 1.5);width:1.71875rem;height:1.25rem}.switch[aria-checked=true] :is(.switch--lg .switch__thumb),.switch[data-selected=true] :is(.switch--lg .switch__thumb){margin-inline-start:calc(100% - 1.84375rem)}.switch__thumb>*{justify-content:center;align-items:center;width:100%;height:100%;display:flex}.switch__label{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--foreground)}.switch [data-slot=label]{-webkit-user-select:none;user-select:none}.switch__content [data-slot=label]{cursor:var(--cursor-interactive)}.switch [data-slot=description]{cursor:default;-webkit-user-select:none;user-select:none}.switch-group{gap:calc(var(--spacing) * 6);flex-direction:column;display:flex}.switch-group__items{gap:calc(var(--spacing) * 4);display:flex}.switch-group--horizontal .switch-group__items{flex-direction:row}.switch-group--vertical .switch-group__items{flex-direction:column}.badge{justify-content:center;align-items:center;gap:calc(var(--spacing) * .5);--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);min-height:calc(var(--spacing) * 7);min-width:calc(var(--spacing) * 7);border-radius:calc(var(--radius) * 3);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));--tw-leading:1.34;--badge-bg:var(--default);--badge-fg:var(--default-foreground);--badge-border:var(--background);background-color:var(--badge-bg);color:var(--badge-fg);border:1px solid var(--badge-border);flex-shrink:0;line-height:1.34;display:inline-flex}.badge__label{padding-inline:calc(var(--spacing) * .5)}.badge-anchor{flex-shrink:0;display:inline-flex;position:relative}.badge--lg{min-height:calc(var(--spacing) * 8);min-width:calc(var(--spacing) * 8);border-radius:calc(var(--radius) * 2);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-leading:1.43;line-height:1.43}.badge--sm{min-height:calc(var(--spacing) * 4);min-width:calc(var(--spacing) * 4);border-radius:calc(var(--radius) * 1.5);--tw-leading:1.34;font-size:10px;line-height:1.34}.badge--accent{--badge-fg:var(--accent-soft-foreground)}.badge--default{--badge-fg:var(--default-foreground)}.badge--success{--badge-fg:var(--success-soft-foreground)}.badge--warning{--badge-fg:var(--warning-soft-foreground)}.badge--danger{--badge-fg:var(--danger-soft-foreground)}.badge--top-right{position:absolute;top:0;right:0;transform:translate(25%,-25%)}.badge--top-left{position:absolute;top:0;left:0;transform:translate(-25%,-25%)}.badge--bottom-right{position:absolute;bottom:0;right:0;transform:translate(25%,25%)}.badge--bottom-left{position:absolute;bottom:0;left:0;transform:translate(-25%,25%)}.badge--primary.badge--accent{--badge-bg:var(--accent);--badge-fg:var(--accent-foreground)}.badge--primary.badge--default{--badge-bg:var(--default);--badge-fg:var(--default-foreground)}.badge--primary.badge--success{--badge-bg:var(--success);--badge-fg:var(--success-foreground)}.badge--primary.badge--warning{--badge-bg:var(--warning);--badge-fg:var(--warning-foreground)}.badge--primary.badge--danger{--badge-bg:var(--danger);--badge-fg:var(--danger-foreground)}.badge--soft.badge--accent{--badge-bg:var(--accent-soft);--badge-fg:var(--accent-soft-foreground)}.badge--soft.badge--default{--badge-bg:var(--default-soft);--badge-fg:var(--default-soft-foreground)}.badge--soft.badge--success{--badge-bg:var(--success-soft);--badge-fg:var(--success-soft-foreground)}.badge--soft.badge--warning{--badge-bg:var(--warning-soft);--badge-fg:var(--warning-soft-foreground)}.badge--soft.badge--danger{--badge-bg:var(--danger-soft);--badge-fg:var(--danger-soft-foreground)}.chip{align-items:center;gap:calc(var(--spacing) * .5);border-radius:calc(var(--radius) * 2);padding-inline:calc(var(--spacing) * 2);padding-block:calc(var(--spacing) * .5);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));--tw-leading:calc(var(--spacing) * 5);line-height:calc(var(--spacing) * 5);--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);--chip-bg:var(--default);--chip-fg:currentColor;background-color:var(--chip-bg);color:var(--chip-fg);flex-shrink:0;display:inline-flex}.chip__label{padding-inline:calc(var(--spacing) * .5)}.chip--accent{--chip-fg:var(--accent-soft-foreground)}.chip--danger{--chip-fg:var(--danger-soft-foreground)}.chip--default{--chip-fg:var(--default-foreground)}.chip--success{--chip-fg:var(--success-soft-foreground)}.chip--warning{--chip-fg:var(--warning-soft-foreground)}.chip--tertiary{--chip-bg:transparent}.chip--sm{padding-inline:var(--spacing);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));padding-block:0}.chip--md{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.chip--lg{padding-inline:calc(var(--spacing) * 3);padding-block:var(--spacing);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.chip--primary.chip--accent{--chip-bg:var(--accent);--chip-fg:var(--accent-foreground)}.chip--primary.chip--success{--chip-bg:var(--success);--chip-fg:var(--success-foreground)}.chip--primary.chip--warning{--chip-bg:var(--warning);--chip-fg:var(--warning-foreground)}.chip--primary.chip--danger{--chip-bg:var(--danger);--chip-fg:var(--danger-foreground)}.chip--accent.chip--soft{--chip-bg:var(--accent-soft);--chip-fg:var(--accent-soft-foreground)}.chip--success.chip--soft{--chip-bg:var(--success-soft);--chip-fg:var(--success-soft-foreground)}.chip--warning.chip--soft{--chip-bg:var(--warning-soft);--chip-fg:var(--warning-soft-foreground)}.chip--danger.chip--soft{--chip-bg:var(--danger-soft);--chip-fg:var(--danger-soft-foreground)}.chip--default.chip--soft{--chip-bg:var(--default-soft);--chip-fg:var(--default-soft-foreground)}.table-root{grid-template-columns:minmax(0,1fr);width:100%;display:grid;position:relative;overflow:clip}.table__scroll-container{scrollbar-width:var(--scrollbar-width);scrollbar-color:var(--scrollbar-color);scrollbar-gutter:var(--scrollbar-gutter);scrollbar-gutter:auto;overflow-x:auto}.table-root--primary{background-color:var(--surface-secondary);padding-inline:var(--spacing);padding-bottom:var(--spacing);border-radius:min(32px,calc(var(--radius) * 2.5))}.table-root--secondary .table__header{border-bottom-style:var(--tw-border-style);background-color:#0000;border-bottom-width:0}.table-root--secondary .table__column{background-color:var(--surface-secondary)}.table-root--secondary :is(th.table__column:first-child,[role=row]>[role=presentation]:first-of-type>.table__column){border-start-start-radius:min(32px,var(--radius-2xl));border-end-start-radius:min(32px,var(--radius-2xl))}.table-root--secondary :is(th.table__column:last-child,[role=row]>[role=presentation]:last-of-type>.table__column){border-start-end-radius:min(32px,var(--radius-2xl));border-end-end-radius:min(32px,var(--radius-2xl))}.table-root--secondary .table__body{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.table-root--secondary .table__body tr:first-child td:first-child,.table-root--secondary .table__body tr:first-child td:last-child,.table-root--secondary .table__body tr:last-child td:first-child,.table-root--secondary .table__body tr:last-child td:last-child{border-radius:0}.table-root--secondary .table__body:not(tbody){border-radius:0;overflow:visible}.table-root--secondary .table__row .table__cell{border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--separator-tertiary)}@supports (color:color-mix(in lab,red,red)){.table-root--secondary .table__row .table__cell{border-color:color-mix(in oklab,var(--separator-tertiary) 50%,transparent)}}.table-root--secondary .table__row .table__cell{background-color:#0000}@media(hover:hover){.table-root--secondary .table__row:hover .table__cell,.table-root--secondary .table__row[data-hovered=true] .table__cell{background-color:var(--default)}@supports (color:color-mix(in lab,red,red)){.table-root--secondary .table__row:hover .table__cell,.table-root--secondary .table__row[data-hovered=true] .table__cell{background-color:color-mix(in oklab,var(--default) 50%,transparent)}}}.table__content{border-collapse:separate;--tw-border-spacing-x:0;--tw-border-spacing-y:0;width:100%;border-spacing:var(--tw-border-spacing-x) var(--tw-border-spacing-y);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.table-root--primary .table__content{overflow:clip}.table__header{border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--separator)}@supports (color:color-mix(in lab,red,red)){.table__header{border-color:color-mix(in oklab,var(--separator) 50%,transparent)}}.table__header{background-color:var(--surface-secondary)}.table__column{padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 2.5);text-align:left;font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--muted);position:relative}.table__column:after{content:"";pointer-events:none;height:calc(var(--spacing) * 4);--tw-translate-y: -50% ;width:1px;translate:var(--tw-translate-x) var(--tw-translate-y);border-radius:calc(var(--radius) * .5);background-color:var(--separator);inset-inline-end:calc(var(--spacing) * 0);position:absolute;top:50%}.table__column:last-child:not(:only-child):after{content:none}.table__column[data-allows-sorting=true]{cursor:var(--cursor-interactive)}@media(hover:hover){.table__column[data-allows-sorting=true]:hover,.table__column[data-allows-sorting=true][data-hovered=true]{color:var(--foreground)}}.table__column:focus-visible,.table__column[data-focus-visible=true]{border-radius:calc(var(--radius) * 1);--tw-outline-style:none;box-shadow:inset 0 0 0 2px var(--focus);outline-style:none}[role=row]>[role=presentation]:last-of-type:not(:only-of-type)>.table__column:after{content:none}.table__sortable-column-header{justify-content:space-between;align-items:center;display:flex}.table__sortable-column-indicator{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3);transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.1s;--tw-ease:var(--ease-out);transition-duration:.1s;transition-timing-function:var(--ease-out)}.table__sortable-column-indicator[data-direction=descending]{rotate:180deg}.table__body tr:first-child td:first-child{border-start-start-radius:min(32px,var(--radius-2xl))}.table__body tr:first-child td:last-child{border-start-end-radius:min(32px,var(--radius-2xl))}.table__body tr:last-child td:first-child{border-end-start-radius:min(32px,var(--radius-2xl))}.table__body tr:last-child td:last-child{border-end-end-radius:min(32px,var(--radius-2xl))}.table__body:not(tbody){border-radius:min(32px,var(--radius-2xl));height:100%;position:relative;overflow:clip}.table__row{border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--separator);height:100%;position:relative}@supports (color:color-mix(in lab,red,red)){.table__row{border-color:color-mix(in oklab,var(--separator) 50%,transparent)}}.table__row:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}@media(hover:hover){.table__row:hover .table__cell,.table__row[data-hovered=true] .table__cell{background-color:var(--surface)}@supports (color:color-mix(in lab,red,red)){.table__row:hover .table__cell,.table__row[data-hovered=true] .table__cell{background-color:color-mix(in oklab,var(--surface) 40%,transparent)}}}.table__row[data-selected=true] .table__cell{background-color:var(--surface)}@supports (color:color-mix(in lab,red,red)){.table__row[data-selected=true] .table__cell{background-color:color-mix(in oklab,var(--surface) 10%,transparent)}}.table__row[aria-disabled=true],.table__row[data-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.table__row:focus-visible,.table__row[data-focus-visible=true]{--tw-outline-style:none;outline-style:none}.table__row[data-dragging=true]{opacity:.5}.table__row[data-drop-target=true] .table__cell{background-color:var(--accent-soft)}.table__cell{background-color:var(--surface);height:100%;padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 3);vertical-align:middle;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--foreground);border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--separator-tertiary)}@supports (color:color-mix(in lab,red,red)){.table__cell{border-color:color-mix(in oklab,var(--separator-tertiary) 50%,transparent)}}.table__cell:focus-visible,.table__cell[data-focus-visible=true]{border-radius:calc(var(--radius) * 1);--tw-outline-style:none;box-shadow:inset 0 0 0 2px var(--focus);outline-style:none}.table__row:is(:focus-visible,[data-focus-visible=true]) :is(.table__cell,.table__column){--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.table__row:is(:focus-visible,[data-focus-visible=true])>:is(.table__cell,.table__column):only-child,.table__row:is(:focus-visible,[data-focus-visible=true])>:only-child :is(.table__cell,.table__column){border-radius:calc(var(--radius) * 1);--tw-shadow:inset 0 0 0 2px var(--tw-shadow-color,var(--focus));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;outline-style:none}.table__row:is(:focus-visible,[data-focus-visible=true])>:is(.table__cell,.table__column):first-child:not(:only-child),.table__row:is(:focus-visible,[data-focus-visible=true])>:first-child:not(:only-child) :is(.table__cell,.table__column){border-top-left-radius:calc(var(--radius) * 1);border-bottom-left-radius:calc(var(--radius) * 1);--tw-shadow:inset 2px 0 0 0 var(--tw-shadow-color,var(--focus)), inset 0 2px 0 0 var(--tw-shadow-color,var(--focus)), inset 0 -2px 0 0 var(--tw-shadow-color,var(--focus));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;outline-style:none}.table__row:is(:focus-visible,[data-focus-visible=true])>:is(.table__cell,.table__column):last-child:not(:only-child),.table__row:is(:focus-visible,[data-focus-visible=true])>:last-child:not(:only-child) :is(.table__cell,.table__column){border-top-right-radius:calc(var(--radius) * 1);border-bottom-right-radius:calc(var(--radius) * 1);--tw-shadow:inset -2px 0 0 0 var(--tw-shadow-color,var(--focus)), inset 0 2px 0 0 var(--tw-shadow-color,var(--focus)), inset 0 -2px 0 0 var(--tw-shadow-color,var(--focus));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;outline-style:none}.table__row:is(:focus-visible,[data-focus-visible=true])>:is(.table__cell,.table__column):not(:first-child):not(:last-child):not(:only-child),.table__row:is(:focus-visible,[data-focus-visible=true])>:not(:first-child):not(:last-child):not(:only-child) :is(.table__cell,.table__column){--tw-shadow:inset 0 2px 0 0 var(--tw-shadow-color,var(--focus)), inset 0 -2px 0 0 var(--tw-shadow-color,var(--focus));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;outline-style:none}.table__cell[data-tree-column]{padding-inline-start:calc(1rem * var(--table-row-level,1))}.table__footer{padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 2.5);align-items:center;display:flex}.table__resizable-container{scrollbar-width:var(--scrollbar-width);scrollbar-color:var(--scrollbar-color);scrollbar-gutter:var(--scrollbar-gutter);scrollbar-gutter:auto;position:relative;overflow:auto}.table__column-resizer{height:calc(var(--spacing) * 4);--tw-translate-y: -50% ;border-radius:calc(var(--radius) * .5);background-color:var(--separator);box-sizing:content-box;--tw-translate-x: 50% ;width:1px;translate:var(--tw-translate-x) var(--tw-translate-y);cursor:col-resize;touch-action:none;padding-inline:calc(var(--spacing) * 2);--tw-border-style:none;--tw-outline-style:none;inset-inline-end:calc(var(--spacing) * 0);background-clip:content-box;border-style:none;outline-style:none;position:absolute;top:50%}.table__column-resizer[data-hovered=true],.table__column-resizer:hover,.table__column-resizer[data-resizing=true]{height:100%;width:calc(var(--spacing) * .5);background-color:var(--accent)}.table__column-resizer[data-focus-visible=true],.table__column-resizer:focus-visible{height:100%;width:calc(var(--spacing) * .5);background-color:var(--focus)}.table__column:has(.table__column-resizer):after{content:none}.table__load-more td,.table__load-more [role=rowheader]{padding-block:calc(var(--spacing) * 3);text-align:center}:is(.table__load-more td,.table__load-more [role=rowheader])>*{margin-inline:auto}.table__load-more-content{justify-content:center;align-items:center;gap:calc(var(--spacing) * 2);padding-block:calc(var(--spacing) * 2);display:flex}.alert{justify-content:flex-start;align-items:flex-start;gap:calc(var(--spacing) * 4);background-color:var(--surface);width:100%;padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 3);--tw-shadow:var(--surface-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);border-radius:min(32px,var(--radius-3xl));flex-direction:row;display:flex}.alert__content{flex-direction:column;flex-grow:1;align-items:flex-start;height:100%;display:flex}.alert__indicator{padding:var(--spacing);-webkit-user-select:none;user-select:none;justify-content:center;align-items:center;display:flex}.alert__indicator [data-slot=alert-default-icon]{box-sizing:content-box;width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.alert__title{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-leading:calc(var(--spacing) * 6);line-height:calc(var(--spacing) * 6);--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.alert__description{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--muted)}.alert--default .alert__indicator,.alert--default .alert__title{color:var(--foreground)}.alert--accent .alert__indicator,.alert--accent .alert__title{color:var(--accent-soft-foreground)}.alert--success .alert__indicator,.alert--success .alert__title{color:var(--success-soft-foreground)}.alert--warning .alert__indicator,.alert--warning .alert__title{color:var(--warning-soft-foreground)}.alert--danger .alert__indicator,.alert--danger .alert__title{color:var(--danger-soft-foreground)}.empty-state{padding:calc(var(--spacing) * 2);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--muted)}.skeleton{pointer-events:none;border-radius:calc(var(--radius) * .5);background-color:var(--surface-tertiary);position:relative;overflow:hidden}@supports (color:color-mix(in lab,red,red)){.skeleton{background-color:color-mix(in oklab,var(--surface-tertiary) 70%,transparent)}}.skeleton--shimmer:after{--tw-translate-x:-100%;translate:var(--tw-translate-x) var(--tw-translate-y);--tw-gradient-position:to right;animation:2s linear infinite skeleton;position:absolute;top:0;right:0;bottom:0;left:0}@supports (background-image:linear-gradient(in lab,red,red)){.skeleton--shimmer:after{--tw-gradient-position:to right in oklab}}.skeleton--shimmer:after{background-image:linear-gradient(var(--tw-gradient-stops));--tw-gradient-from:transparent;--tw-gradient-via:var(--surface-tertiary);--tw-gradient-via-stops:var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));--tw-gradient-to:transparent;--tw-content:"";content:var(--tw-content)}.skeleton--shimmer:has(.skeleton):after{content:none}.skeleton--shimmer:has(.skeleton):before{--tw-translate-x:-100%;translate:var(--tw-translate-x) var(--tw-translate-y);--tw-content:"";content:var(--tw-content);z-index:10;pointer-events:none;mix-blend-mode:overlay;background:linear-gradient(90deg,#0000,#ffffff80,#0000);animation:2s linear infinite skeleton;position:absolute;top:0;right:0;bottom:0;left:0}.skeleton--shimmer:has(.skeleton) .skeleton:after{content:none}.skeleton--pulse{animation:var(--animate-pulse)}.meter{gap:var(--spacing);--meter-fill:var(--accent);grid-template-columns:1fr auto;grid-template-areas:"label output""track track";width:100%;display:grid}.meter [data-slot=label]{width:fit-content;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);grid-area:label}.meter .meter__output{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,);grid-area:output}.meter .meter__track{border-radius:calc(var(--radius) * .5);background-color:var(--default);height:calc(var(--spacing) * 2);grid-area:track;position:relative;overflow:hidden}.meter .meter__fill{border-radius:calc(var(--radius) * .5);background-color:var(--meter-fill);height:100%;transition:width .3s var(--ease-out);position:absolute;top:0;left:0}.meter .meter__fill:is([data-reduce-motion=true],[data-reduce-motion=true] *),.meter .meter__fill:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.meter .meter__fill:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.meter .meter__fill:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.meter .meter__fill:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.meter .meter__fill:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.meter:disabled,.meter[data-disabled=true],.meter[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}:is(.meter:disabled,.meter[data-disabled=true],.meter[aria-disabled=true]) [data-slot=label]{opacity:1}.meter--sm .meter__track{height:var(--spacing);border-radius:calc(var(--radius) * .25)}.meter--sm .meter__fill{border-radius:calc(var(--radius) * .25)}.meter--lg .meter__track{height:calc(var(--spacing) * 3);border-radius:calc(var(--radius) * .75)}.meter--lg .meter__fill{border-radius:calc(var(--radius) * .75)}.meter--default{--meter-fill:var(--default-foreground)}.meter--accent{--meter-fill:var(--accent)}.meter--success{--meter-fill:var(--success)}.meter--warning{--meter-fill:var(--warning)}.meter--danger{--meter-fill:var(--danger)}.progress-bar{gap:var(--spacing);--progress-bar-fill:var(--accent);grid-template-columns:1fr auto;grid-template-areas:"label output""track track";width:100%;display:grid}.progress-bar [data-slot=label]{width:fit-content;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);grid-area:label}.progress-bar .progress-bar__output{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,);grid-area:output}.progress-bar .progress-bar__track{border-radius:calc(var(--radius) * .5);background-color:var(--default);height:calc(var(--spacing) * 2);grid-area:track;position:relative;overflow:hidden}.progress-bar .progress-bar__fill{border-radius:calc(var(--radius) * .5);background-color:var(--progress-bar-fill);height:100%;transition:width .3s var(--ease-out);position:absolute;top:0;left:0}.progress-bar .progress-bar__fill:is([data-reduce-motion=true],[data-reduce-motion=true] *),.progress-bar .progress-bar__fill:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.progress-bar .progress-bar__fill:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.progress-bar .progress-bar__fill:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.progress-bar .progress-bar__fill:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.progress-bar .progress-bar__fill:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.progress-bar:not([aria-valuenow]) .progress-bar__fill{width:40%;animation:1.5s cubic-bezier(.65,0,.35,1) infinite progress-bar-indeterminate}.progress-bar:not([aria-valuenow]) .progress-bar__fill:is([data-reduce-motion=true],[data-reduce-motion=true] *),.progress-bar:not([aria-valuenow]) .progress-bar__fill:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.progress-bar:not([aria-valuenow]) .progress-bar__fill:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{animation:none}@media(prefers-reduced-motion:reduce){.progress-bar:not([aria-valuenow]) .progress-bar__fill:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.progress-bar:not([aria-valuenow]) .progress-bar__fill:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.progress-bar:not([aria-valuenow]) .progress-bar__fill:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{animation:none}}.progress-bar:disabled,.progress-bar[data-disabled=true],.progress-bar[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}:is(.progress-bar:disabled,.progress-bar[data-disabled=true],.progress-bar[aria-disabled=true]) [data-slot=label]{opacity:1}@keyframes progress-bar-indeterminate{0%{transform:translate(-100%)}to{transform:translate(350%)}}.progress-bar--sm .progress-bar__track{height:var(--spacing);border-radius:calc(var(--radius) * .25)}.progress-bar--sm .progress-bar__fill{border-radius:calc(var(--radius) * .25)}.progress-bar--lg .progress-bar__track{height:calc(var(--spacing) * 3);border-radius:calc(var(--radius) * .75)}.progress-bar--lg .progress-bar__fill{border-radius:calc(var(--radius) * .75)}.progress-bar--default{--progress-bar-fill:var(--default-foreground)}.progress-bar--accent{--progress-bar-fill:var(--accent)}.progress-bar--success{--progress-bar-fill:var(--success)}.progress-bar--warning{--progress-bar-fill:var(--warning)}.progress-bar--danger{--progress-bar-fill:var(--danger)}.progress-circle{--progress-circle-stroke:var(--accent);--progress-circle-track-stroke:var(--default);justify-content:center;align-items:center;display:inline-flex}.progress-circle .progress-circle__track{width:calc(var(--spacing) * 7);height:calc(var(--spacing) * 7)}.progress-circle .progress-circle__track-circle{stroke:var(--progress-circle-track-stroke)}.progress-circle .progress-circle__fill-circle{stroke:var(--progress-circle-stroke);transition:stroke-dashoffset .3s var(--ease-out)}.progress-circle .progress-circle__fill-circle:is([data-reduce-motion=true],[data-reduce-motion=true] *),.progress-circle .progress-circle__fill-circle:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.progress-circle .progress-circle__fill-circle:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.progress-circle .progress-circle__fill-circle:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.progress-circle .progress-circle__fill-circle:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.progress-circle .progress-circle__fill-circle:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.progress-circle:not([aria-valuenow]) .progress-circle__track{animation:1s linear infinite progress-circle-spin}.progress-circle:not([aria-valuenow]) .progress-circle__track:is([data-reduce-motion=true],[data-reduce-motion=true] *),.progress-circle:not([aria-valuenow]) .progress-circle__track:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.progress-circle:not([aria-valuenow]) .progress-circle__track:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{animation:none}@media(prefers-reduced-motion:reduce){.progress-circle:not([aria-valuenow]) .progress-circle__track:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.progress-circle:not([aria-valuenow]) .progress-circle__track:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.progress-circle:not([aria-valuenow]) .progress-circle__track:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{animation:none}}.progress-circle:disabled,.progress-circle[data-disabled=true],.progress-circle[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}@keyframes progress-circle-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.progress-circle--sm .progress-circle__track{width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5)}.progress-circle--lg .progress-circle__track{width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9)}.progress-circle--default{--progress-circle-stroke:var(--default-foreground)}.progress-circle--accent{--progress-circle-stroke:var(--accent)}.progress-circle--success{--progress-circle-stroke:var(--success)}.progress-circle--warning{--progress-circle-stroke:var(--warning)}.progress-circle--danger{--progress-circle-stroke:var(--danger)}.spinner{pointer-events:none;width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6);flex-shrink:0;animation:.75s linear infinite spin;display:inline-flex}.spinner:is([data-reduce-motion=true],[data-reduce-motion=true] *),.spinner:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.spinner:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{animation:none}@media(prefers-reduced-motion:reduce){.spinner:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.spinner:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.spinner:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{animation:none}}.spinner--sm{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.spinner--lg{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8)}.spinner--xl{width:calc(var(--spacing) * 10);height:calc(var(--spacing) * 10)}.spinner--current{color:inherit}.spinner--accent{color:var(--accent)}.spinner--danger{color:var(--danger)}.spinner--success{color:var(--success)}.spinner--warning{color:var(--warning)}.toast-region{pointer-events:none;z-index:50;--tw-outline-style:none;outline-style:none;width:calc(100vw - 2rem);position:fixed}@media(min-width:40rem){.toast-region{width:auto;min-width:var(--toast-width)}}.toast-region{display:block}.toast-region--bottom{bottom:calc(var(--spacing) * 4);--tw-translate-x: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y);left:50%}.toast-region--bottom-start{bottom:calc(var(--spacing) * 4);left:calc(var(--spacing) * 4)}.toast-region--bottom-end{right:calc(var(--spacing) * 4);bottom:calc(var(--spacing) * 4)}.toast-region--top{top:calc(var(--spacing) * 4);--tw-translate-x: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y);left:50%}.toast-region--top-start{top:calc(var(--spacing) * 4);left:calc(var(--spacing) * 4)}.toast-region--top-end{top:calc(var(--spacing) * 4);right:calc(var(--spacing) * 4)}.toast-region:focus-visible{outline-style:var(--tw-outline-style);outline-offset:2px;outline-width:2px;outline-color:var(--focus)}.toast{pointer-events:auto;justify-content:flex-start;align-items:flex-start;gap:calc(var(--spacing) * 1.5);background-color:var(--surface);padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 3);--tw-shadow:var(--overlay-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);border-radius:min(32px,var(--radius-3xl));flex-direction:row;display:flex;position:absolute;left:0;right:0}.toast--bottom,.toast--bottom-start,.toast--bottom-end{bottom:0}.toast--top,.toast--top-start,.toast--top-end{top:0}.toast:not([data-frontmost=true]){pointer-events:none;height:var(--front-height);overflow:hidden}.toast:not([data-frontmost=true]) .toast__close-button{pointer-events:none;opacity:0;outline:none}.toast[data-hidden=true]{pointer-events:none;opacity:0;display:flex}.toast:focus-visible{outline-style:var(--tw-outline-style);outline-offset:2px;outline-width:2px;outline-color:var(--focus)}.toast--bottom,.toast--bottom-start,.toast--bottom-end{view-transition-class:toast-bottom}.toast--top,.toast--top-start,.toast--top-end{view-transition-class:toast-top}.toast__content{flex-direction:column;flex-grow:1;align-self:center;align-items:flex-start;height:100%;display:flex}.toast__indicator{padding:var(--spacing);color:var(--overlay-foreground);-webkit-user-select:none;user-select:none;flex-shrink:0;justify-content:center;align-items:center;display:flex}.toast__indicator [data-slot=toast-default-icon]{box-sizing:content-box;width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.toast__indicator [data-slot=spinner],.toast__indicator [data-slot=spinner-icon]{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.toast__title{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-leading:calc(var(--spacing) * 5);line-height:calc(var(--spacing) * 5);--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--overlay-foreground)}.toast__description{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--muted)}.toast__close-button{pointer-events:none;top:calc(var(--spacing) * -1);right:calc(var(--spacing) * -1);width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5);border-color:var(--border);background-color:var(--default);opacity:0;position:absolute}@media(min-width:40rem){.toast__close-button{border-style:var(--tw-border-style);background-color:var(--overlay);border-width:1px}}.toast__close-button{transition:opacity .15s var(--ease-smooth)}.toast__close-button:is([data-reduce-motion=true],[data-reduce-motion=true] *),.toast__close-button:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.toast__close-button:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.toast__close-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.toast__close-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.toast__close-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.toast__close-button [data-slot=close-button-icon]{width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5)}@media(min-width:40rem){.toast__close-button [data-slot=close-button-icon]{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}}@media(hover:hover){.toast__close-button:hover,.toast__close-button[data-hovered=true]{background-color:var(--default)}}.toast[data-frontmost=true]:hover .toast__close-button{pointer-events:auto;opacity:1}.toast__action{margin-top:calc(var(--spacing) * 2)}@media(min-width:40rem){.toast__action{margin-top:0}}.toast--accent .toast__title{color:var(--accent-soft-foreground)}.toast--success .toast__title,.toast--success .toast__indicator{color:var(--success-soft-foreground)}.toast--warning .toast__title,.toast--warning .toast__indicator{color:var(--warning-soft-foreground)}.toast--danger .toast__title,.toast--danger .toast__indicator{color:var(--danger-soft-foreground)}::view-transition-old(*){will-change:translate,opacity}::view-transition-new(*){will-change:translate,opacity}::view-transition-new(.toast-bottom):only-child{animation:.35s toast-slide-bottom-in}::view-transition-old(.toast-bottom):only-child{animation:.35s forwards toast-slide-bottom-out}::view-transition-new(.toast-top):only-child{animation:.35s toast-slide-top-in}::view-transition-old(.toast-top):only-child{animation:.35s forwards toast-slide-top-out}@keyframes toast-slide-bottom-in{0%{opacity:0;translate:0 100%}}@keyframes toast-slide-bottom-out{to{opacity:0;translate:0 100%}}@keyframes toast-slide-top-in{0%{opacity:0;translate:0 -100%}}@keyframes toast-slide-top-out{to{opacity:0;translate:0 -100%}}.checkbox-group{flex-direction:column;display:flex}.checkbox-group [data-slot=checkbox]{margin-top:calc(var(--spacing) * 4)}.checkbox{align-items:flex-start;gap:var(--spacing);--tw-outline-style:none;-webkit-tap-highlight-color:transparent;cursor:var(--cursor-interactive);outline-style:none;flex-direction:column;display:flex}.checkbox>[data-slot=description],.checkbox>[data-slot=field-error]{cursor:default;width:100%;min-width:0;font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));text-wrap:wrap;overflow-wrap:break-word;color:var(--muted);-webkit-user-select:none;user-select:none;padding-inline-start:calc(var(--spacing) * 7)}.checkbox [data-slot=label]{-webkit-user-select:none;user-select:none}.checkbox .checkbox__content [data-slot=label]{cursor:var(--cursor-interactive)}.checkbox[data-disabled=true],.checkbox[data-disabled=true] [data-slot=description],.checkbox[data-disabled=true] [data-slot=field-error]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}:is(.checkbox[data-selected=true],.checkbox[data-indeterminate=true]) .checkbox__indicator{border-color:var(--accent-foreground)}.checkbox [data-slot=checkbox-default-indicator--checkmark]{width:calc(var(--spacing) * 2.5);height:calc(var(--spacing) * 2.5);stroke-width:2.5px;color:var(--accent-foreground);transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.2s;transition-duration:.2s}.checkbox [data-slot=checkbox-default-indicator--checkmark]:is([data-reduce-motion=true],[data-reduce-motion=true] *),.checkbox [data-slot=checkbox-default-indicator--checkmark]:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.checkbox [data-slot=checkbox-default-indicator--checkmark]:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.checkbox [data-slot=checkbox-default-indicator--checkmark]:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.checkbox [data-slot=checkbox-default-indicator--checkmark]:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.checkbox [data-slot=checkbox-default-indicator--checkmark]:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.checkbox[data-selected=true] [data-slot=checkbox-default-indicator--checkmark]{transition:stroke-dashoffset .15s linear 15ms}.checkbox[data-invalid=true][data-selected=true] [data-slot=checkbox-default-indicator--checkmark],.checkbox[data-invalid=true][aria-checked=true] [data-slot=checkbox-default-indicator--checkmark],.checkbox[aria-invalid=true][data-selected=true] [data-slot=checkbox-default-indicator--checkmark],.checkbox[aria-invalid=true][aria-checked=true] [data-slot=checkbox-default-indicator--checkmark]{color:var(--danger-foreground)}.checkbox[data-indeterminate=true] [data-slot=checkbox-default-indicator--indeterminate]{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.checkbox[data-indeterminate=true][data-invalid=true] [data-slot=checkbox-default-indicator--indeterminate],.checkbox[data-indeterminate=true][aria-invalid=true] [data-slot=checkbox-default-indicator--indeterminate]{color:var(--danger-foreground)}.checkbox__control{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4);border-radius:calc(var(--radius) * .75);border-style:var(--tw-border-style);border-width:1px;border-width:var(--border-width-field);border-color:var(--field-border,var(--border));background-color:var(--field-background,var(--default));--tw-shadow:var(--field-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;-webkit-tap-highlight-color:transparent;transition:background-color .2s var(--ease-out),border-color .2s var(--ease-out),transform .1s var(--ease-out);outline-style:none;flex-shrink:0;justify-content:center;align-items:center;display:inline-flex;position:relative;overflow:hidden}.checkbox__control:is([data-reduce-motion=true],[data-reduce-motion=true] *),.checkbox__control:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.checkbox__control:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.checkbox__control:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.checkbox__control:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.checkbox__control:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.checkbox__control{cursor:var(--cursor-interactive)}.checkbox__control:before{pointer-events:none;z-index:0;transform-origin:50%;--tw-scale-x:70%;--tw-scale-y:70%;--tw-scale-z:70%;scale:var(--tw-scale-x) var(--tw-scale-y);border-radius:calc(var(--radius) * .75);background-color:var(--accent);opacity:0;--tw-content:"";content:var(--tw-content);transition:scale .1s var(--ease-linear),opacity .2s var(--ease-linear),background-color .2s var(--ease-out);position:absolute;top:0;right:0;bottom:0;left:0}@media(prefers-reduced-motion:reduce){.checkbox__control:before:not(:is()){transition-property:none}}.checkbox:focus-visible .checkbox__control,.checkbox:has([data-slot=checkbox-content][data-focus-visible=true]) .checkbox__control,.checkbox [data-slot=checkbox-content][data-focus-visible=true] .checkbox__control{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.checkbox:hover .checkbox__control,.checkbox:has([data-slot=checkbox-content][data-hovered=true]) .checkbox__control,.checkbox [data-slot=checkbox-content][data-hovered=true] .checkbox__control{border-color:var(--field-border-hover)}:is(.checkbox:hover .checkbox__control,.checkbox:has([data-slot=checkbox-content][data-hovered=true]) .checkbox__control,.checkbox [data-slot=checkbox-content][data-hovered=true] .checkbox__control):before{background-color:var(--accent-hover)}.checkbox[aria-checked=true] .checkbox__control,.checkbox[data-selected=true] .checkbox__control{color:var(--accent-foreground);border-color:#0000}:is(.checkbox[aria-checked=true] .checkbox__control,.checkbox[data-selected=true] .checkbox__control):before{--tw-scale-x:100%;--tw-scale-y:100%;--tw-scale-z:100%;scale:var(--tw-scale-x) var(--tw-scale-y);opacity:1}.checkbox[data-indeterminate=true] .checkbox__control{background-color:var(--accent);color:var(--accent-foreground)}.checkbox:active[data-indeterminate=true] .checkbox__control,.checkbox[data-pressed=true][data-indeterminate=true] .checkbox__control,.checkbox:has([data-slot=checkbox-content][data-pressed=true])[data-indeterminate=true] .checkbox__control{background-color:var(--accent-hover)}.checkbox[data-invalid=true]:not([aria-checked=true]):not([data-selected=true]):not([data-indeterminate=true]) .checkbox__control,.checkbox[aria-invalid=true]:not([aria-checked=true]):not([data-selected=true]):not([data-indeterminate=true]) .checkbox__control{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}:is(.checkbox[data-invalid=true]:not([aria-checked=true]):not([data-selected=true]):not([data-indeterminate=true]) .checkbox__control,.checkbox[aria-invalid=true]:not([aria-checked=true]):not([data-selected=true]):not([data-indeterminate=true]) .checkbox__control):focus,:is(.checkbox[data-invalid=true]:not([aria-checked=true]):not([data-selected=true]):not([data-indeterminate=true]) .checkbox__control,.checkbox[aria-invalid=true]:not([aria-checked=true]):not([data-selected=true]):not([data-indeterminate=true]) .checkbox__control):focus-visible,:is(.checkbox[data-invalid=true]:not([aria-checked=true]):not([data-selected=true]):not([data-indeterminate=true]) .checkbox__control,.checkbox[aria-invalid=true]:not([aria-checked=true]):not([data-selected=true]):not([data-indeterminate=true]) .checkbox__control)[data-focused=true],:is(.checkbox[data-invalid=true]:not([aria-checked=true]):not([data-selected=true]):not([data-indeterminate=true]) .checkbox__control,.checkbox[aria-invalid=true]:not([aria-checked=true]):not([data-selected=true]):not([data-indeterminate=true]) .checkbox__control)[data-focus-visible=true],:is(.checkbox[data-invalid=true]:not([aria-checked=true]):not([data-selected=true]):not([data-indeterminate=true]) .checkbox__control,.checkbox[aria-invalid=true]:not([aria-checked=true]):not([data-selected=true]):not([data-indeterminate=true]) .checkbox__control):focus-within,:is(.checkbox[data-invalid=true]:not([aria-checked=true]):not([data-selected=true]):not([data-indeterminate=true]) .checkbox__control,.checkbox[aria-invalid=true]:not([aria-checked=true]):not([data-selected=true]):not([data-indeterminate=true]) .checkbox__control)[data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.checkbox[data-invalid=true][aria-checked=true] .checkbox__control,.checkbox[data-invalid=true][data-selected=true] .checkbox__control,.checkbox[aria-invalid=true][aria-checked=true] .checkbox__control,.checkbox[aria-invalid=true][data-selected=true] .checkbox__control{background-color:var(--danger);color:var(--danger-foreground);border-color:#0000}:is(.checkbox[data-invalid=true][aria-checked=true] .checkbox__control,.checkbox[data-invalid=true][data-selected=true] .checkbox__control,.checkbox[aria-invalid=true][aria-checked=true] .checkbox__control,.checkbox[aria-invalid=true][data-selected=true] .checkbox__control):before{--tw-scale-x:100%;--tw-scale-y:100%;--tw-scale-z:100%;scale:var(--tw-scale-x) var(--tw-scale-y);background-color:var(--danger);opacity:1}.checkbox[data-indeterminate=true][aria-invalid=true] .checkbox__control,.checkbox[data-indeterminate=true][data-invalid=true] .checkbox__control{background-color:var(--danger);color:var(--danger-foreground)}.checkbox__indicator{z-index:10;width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3);justify-content:center;align-items:center;display:flex;position:relative}.checkbox__indicator svg{width:100%;height:100%;transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.checkbox--disabled{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.checkbox--secondary .checkbox__control{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);background-color:var(--checkbox-control-bg);--checkbox-control-bg:var(--default)}.checkbox:hover :is(.checkbox--secondary .checkbox__control),.checkbox:has([data-slot=checkbox-content][data-hovered=true]) :is(.checkbox--secondary .checkbox__control),.checkbox [data-slot=checkbox-content][data-hovered=true] :is(.checkbox--secondary .checkbox__control){border-color:var(--field-border-hover)}.checkbox__content{cursor:inherit;align-items:center;gap:calc(var(--spacing) * 3);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--foreground);--tw-outline-style:none;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;outline-style:none;display:inline-flex}.checkbox--secondary:not([aria-checked=true]):not([data-selected=true]):not([data-indeterminate=true]) .checkbox__control{background-color:var(--checkbox-control-bg)}:is(.checkbox--secondary[aria-checked=true] .checkbox__control,.checkbox--secondary[data-selected=true] .checkbox__control):before,.checkbox--secondary[data-indeterminate=true] .checkbox__control,.checkbox--secondary[data-indeterminate=true] .checkbox__control:before{background-color:var(--accent)}.fieldset{gap:calc(var(--spacing) * 6);flex-direction:column;flex:1 1 0;display:flex}.fieldset__legend{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--foreground)}.fieldset__field_group{width:100%}:where(.fieldset__field_group>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}.fieldset__actions{align-items:center;gap:calc(var(--spacing) * 2);padding-top:var(--spacing);display:flex}.input-otp{align-items:center;gap:calc(var(--spacing) * 2);display:flex;position:relative}.input-otp[data-disabled=true]{cursor:not-allowed;opacity:.5}.input-otp__group{align-items:center;gap:calc(var(--spacing) * 2);display:flex}.input-otp__slot{height:calc(var(--spacing) * 10);width:calc(var(--spacing) * 9.5);border-style:var(--tw-border-style);background-color:var(--field-background,var(--default));color:var(--field-foreground,var(--foreground));--tw-shadow:var(--field-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);border-radius:var(--field-radius,calc(var(--radius) * 1.5));font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);--tw-outline-style:none;border-width:1px;border-width:var(--border-width-field);border-color:var(--field-border);transition:background-color .15s var(--ease-smooth),border-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out);outline-style:none;flex:1;justify-content:center;align-items:center;display:flex;position:relative}.input-otp__slot:is([data-reduce-motion=true],[data-reduce-motion=true] *),.input-otp__slot:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.input-otp__slot:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.input-otp__slot:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.input-otp__slot:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.input-otp__slot:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}@media(hover:hover){.input-otp__slot:hover,.input-otp__slot[data-hovered=true]{background-color:var(--field-hover);border-color:var(--field-border-hover)}}.input-otp__slot[data-active=true]{z-index:10;background-color:var(--field-focus);--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-outline-style:none;--tw-ring-offset-width:0px;outline-style:none}.input-otp__slot[data-filled=true]{background-color:var(--field-focus)}.input-otp__slot[data-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.input-otp__slot[data-invalid=true]{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}.input-otp__slot[data-invalid=true]:focus,.input-otp__slot[data-invalid=true]:focus-visible,.input-otp__slot[data-invalid=true][data-focused=true],.input-otp__slot[data-invalid=true][data-focus-visible=true],.input-otp__slot[data-invalid=true]:focus-within,.input-otp__slot[data-invalid=true][data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.input-otp__slot[data-invalid=true]{background-color:var(--field-focus)}.input-otp__slot-value{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height));--tw-leading:calc(var(--spacing) * 6);line-height:calc(var(--spacing) * 6);--tw-tracking:-.27px;letter-spacing:-.27px;animation:slot-value-in .25s var(--ease-smooth) both;transform-origin:bottom}.input-otp__slot-value:is([data-reduce-motion=true],[data-reduce-motion=true] *),.input-otp__slot-value:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.input-otp__slot-value:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{animation:none}@media(prefers-reduced-motion:reduce){.input-otp__slot-value:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.input-otp__slot-value:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.input-otp__slot-value:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{animation:none}}.input-otp__caret{height:calc(var(--spacing) * 4);border-radius:calc(var(--radius) * .5);background-color:var(--field-placeholder,var(--muted));width:2px;animation:1.2s ease-out infinite caret-blink;position:absolute}.input-otp__separator{border-radius:calc(var(--radius) * .5);background-color:var(--separator);flex-shrink:0;width:6px;height:2px}.input-otp--secondary .input-otp__slot{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);background-color:var(--input-otp-slot-bg);--input-otp-slot-bg:var(--default);--input-otp-slot-bg-hover:var(--default-hover);--input-otp-slot-bg-focus:var(--default)}@media(hover:hover){.input-otp--secondary .input-otp__slot:hover,.input-otp--secondary .input-otp__slot[data-hovered=true]{background-color:var(--input-otp-slot-bg-hover)}}.input-otp--secondary .input-otp__slot[data-active=true],.input-otp--secondary .input-otp__slot[data-filled=true]{background-color:var(--input-otp-slot-bg-focus)}@keyframes slot-value-in{0%{opacity:0;transform:translateY(8px)scale(.8)}to{opacity:1;transform:translateY(0)scale(1)}}.input{border-radius:var(--field-radius,calc(var(--radius) * 1.5));border-style:var(--tw-border-style);background-color:var(--field-background,var(--default));padding-inline:calc(var(--spacing) * 3);padding-block:calc(var(--spacing) * 2);font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));color:var(--field-foreground,var(--foreground));--tw-shadow:var(--field-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;border-width:1px;outline-style:none}.input::placeholder{color:var(--field-placeholder,var(--muted))}@media(min-width:40rem){.input{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}.input{border-width:var(--border-width-field);border-color:var(--field-border);transition:background-color .15s var(--ease-smooth),border-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out)}.input:is([data-reduce-motion=true],[data-reduce-motion=true] *),.input:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.input:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.input:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.input:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.input:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}@media(hover:hover){.input:hover:not(:focus):not(:focus-visible),.input[data-hovered=true]:not([data-focused=true]):not([data-focus-visible=true]){background-color:var(--field-hover);border-color:var(--field-border-hover)}}.input:focus,.input[data-focused=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-outline-style:none;--tw-ring-offset-width:0px;border-color:var(--field-border-focus);background-color:var(--field-focus);outline-style:none}.input[data-invalid=true]{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}.input[data-invalid=true]:focus,.input[data-invalid=true]:focus-visible,.input[data-invalid=true][data-focused=true],.input[data-invalid=true][data-focus-visible=true],.input[data-invalid=true]:focus-within,.input[data-invalid=true][data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.input[data-invalid=true]{background-color:var(--field-focus)}.input:disabled,.input[data-disabled=true],.input[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.input--secondary{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);background-color:var(--input-bg);--input-bg:var(--default);--input-bg-hover:var(--default-hover);--input-bg-focus:var(--default)}@media(hover:hover){.input--secondary:hover:not(:focus):not(:focus-visible),.input--secondary[data-hovered=true]:not([data-focus-visible=true]):not([data-focused=true]){background-color:var(--input-bg-hover)}}.input--secondary:focus,.input--secondary[data-focused=true]{background-color:var(--input-bg-focus)}.input--secondary[data-invalid=true]{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}.input--secondary[data-invalid=true]:focus,.input--secondary[data-invalid=true]:focus-visible,.input--secondary[data-invalid=true][data-focused=true],.input--secondary[data-invalid=true][data-focus-visible=true],.input--secondary[data-invalid=true]:focus-within,.input--secondary[data-invalid=true][data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.input--secondary[data-invalid=true]{background-color:var(--input-bg-focus)}.input--full-width{width:100%}.input-group{min-height:calc(var(--spacing) * 9);border-radius:var(--field-radius,calc(var(--radius) * 1.5));border-style:var(--tw-border-style);background-color:var(--field-background,var(--default));font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--field-foreground,var(--foreground));--tw-shadow:var(--field-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;border-width:1px;border-width:var(--border-width-field);border-color:var(--field-border);outline-style:none;align-items:center;display:inline-flex}.input-group:has([data-slot=input-group-textarea]){align-items:flex-start;height:auto}.input-group{transition:background-color .15s var(--ease-smooth),border-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out)}.input-group:is([data-reduce-motion=true],[data-reduce-motion=true] *),.input-group:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.input-group:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.input-group:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.input-group:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.input-group:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}@media(hover:hover){.input-group:hover:not(:focus-within),.input-group[data-hovered=true]:not([data-focus-within=true]){background-color:var(--field-hover);border-color:var(--field-border-hover)}}.input-group:has([data-slot=input-group-input]:focus),.input-group:has([data-slot=input-group-textarea]:focus){--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-outline-style:none;--tw-ring-offset-width:0px;border-color:var(--field-border-focus);background-color:var(--field-focus);outline-style:none}.input-group[data-invalid=true]{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}.input-group[data-invalid=true]:focus,.input-group[data-invalid=true]:focus-visible,.input-group[data-invalid=true][data-focused=true],.input-group[data-invalid=true][data-focus-visible=true],.input-group[data-invalid=true]:focus-within,.input-group[data-invalid=true][data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.input-group[data-invalid=true]{background-color:var(--field-focus);border-color:var(--color-field-border-invalid)}.input-group[data-disabled=true],.input-group[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}:-webkit-any(.input-group:has([data-slot=input-group-input]:-webkit-autofill),.input-group:has([data-slot=input-group-input]:autofill)){background-color:var(--field-focus);border-color:var(--field-border-focus)}:is(.input-group:has([data-slot=input-group-input]:autofill)){background-color:var(--field-focus);border-color:var(--field-border-focus)}.input-group__input{border-style:var(--tw-border-style);padding-inline:calc(var(--spacing) * 3);padding-block:calc(var(--spacing) * 2);font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;background-color:#0000;border-width:0;border-radius:0;outline-style:none;flex:1}.input-group__input::placeholder{color:var(--field-placeholder,var(--muted))}@media(min-width:40rem){.input-group__input{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}.input-group:has([data-slot=input-group-prefix]) .input-group__input{border-top-left-radius:0;border-bottom-left-radius:0;padding-left:0}.input-group:has([data-slot=input-group-suffix]) .input-group__input{border-top-right-radius:0;border-bottom-right-radius:0;padding-right:0}.input-group__input:focus,.input-group__input:focus-visible{--tw-outline-style:none;outline-style:none}.input-group__input:-webkit-autofill{-webkit-text-fill-color:var(--field-foreground);caret-color:var(--field-foreground);transition:background-color 9999s ease-in-out;box-shadow:inset 0 0 0 1000px #0000}.input-group__input:-webkit-autofill:hover{-webkit-text-fill-color:var(--field-foreground);caret-color:var(--field-foreground);transition:background-color 9999s ease-in-out;box-shadow:inset 0 0 0 1000px #0000}.input-group__input:-webkit-autofill:focus{-webkit-text-fill-color:var(--field-foreground);caret-color:var(--field-foreground);transition:background-color 9999s ease-in-out;box-shadow:inset 0 0 0 1000px #0000}.input-group__input:-webkit-autofill:active{-webkit-text-fill-color:var(--field-foreground);caret-color:var(--field-foreground);transition:background-color 9999s ease-in-out;box-shadow:inset 0 0 0 1000px #0000}.input-group__input:autofill{-webkit-text-fill-color:var(--field-foreground);caret-color:var(--field-foreground);transition:background-color 9999s ease-in-out;box-shadow:inset 0 0 0 1000px #0000}.input-group__input[data-slot=input-group-textarea]{resize:vertical;min-height:38px}.input-group__prefix{border-top-left-radius:var(--field-radius,calc(var(--radius) * 1.5));border-bottom-left-radius:var(--field-radius,calc(var(--radius) * 1.5));height:100%;padding-inline:calc(var(--spacing) * 3);color:var(--field-placeholder,var(--muted));border-width:var(--border-width-field);border-color:var(--field-border);border-style:solid;border-right-color:var(--field-border);background-color:#0000;border-top:none;border-bottom:none;border-left:none;border-top-right-radius:0;border-bottom-right-radius:0;justify-content:center;align-items:center;display:flex}.input-group:has([data-slot=input-group-textarea]) .input-group__prefix{align-items:flex-start;padding-top:.5rem}.input-group__prefix{transition:background-color .15s var(--ease-smooth),border-color .15s var(--ease-smooth)}.input-group__prefix:is([data-reduce-motion=true],[data-reduce-motion=true] *),.input-group__prefix:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.input-group__prefix:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.input-group__prefix:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.input-group__prefix:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.input-group__prefix:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.input-group__suffix{border-top-left-radius:0;border-bottom-left-radius:0;border-top-right-radius:var(--field-radius,calc(var(--radius) * 1.5));border-bottom-right-radius:var(--field-radius,calc(var(--radius) * 1.5));height:100%;padding-inline:calc(var(--spacing) * 3);color:var(--field-placeholder,var(--muted));border-width:var(--border-width-field);border-color:var(--field-border);border-style:solid;border-left-color:var(--field-border);background-color:#0000;border-top:none;border-bottom:none;border-right:none;justify-content:center;align-items:center;display:flex}.input-group:has([data-slot=input-group-textarea]) .input-group__suffix{align-items:flex-start;padding-top:.5rem}.input-group__suffix{transition:background-color .15s var(--ease-smooth),border-color .15s var(--ease-smooth)}.input-group__suffix:is([data-reduce-motion=true],[data-reduce-motion=true] *),.input-group__suffix:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.input-group__suffix:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.input-group__suffix:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.input-group__suffix:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.input-group__suffix:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.input-group--secondary{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);background-color:var(--input-group-bg);--input-group-bg:var(--default);--input-group-bg-hover:var(--default-hover);--input-group-bg-focus:var(--default)}@media(hover:hover){.input-group--secondary:hover:not(:focus-within),.input-group--secondary[data-hovered=true]:not([data-focus-within=true]){background-color:var(--input-group-bg-hover)}}.input-group--secondary:has([data-slot=input-group-input]:focus),.input-group--secondary:has([data-slot=input-group-textarea]:focus){background-color:var(--input-group-bg-focus)}.input-group--secondary[data-invalid=true]{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}.input-group--secondary[data-invalid=true]:focus,.input-group--secondary[data-invalid=true]:focus-visible,.input-group--secondary[data-invalid=true][data-focused=true],.input-group--secondary[data-invalid=true][data-focus-visible=true],.input-group--secondary[data-invalid=true]:focus-within,.input-group--secondary[data-invalid=true][data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.input-group--secondary[data-invalid=true]{border-color:var(--color-field-border-invalid);background-color:var(--input-group-bg-focus)}.input-group--secondary [data-slot=input-group-input],.input-group--secondary [data-slot=input-group-textarea]{background-color:#0000}.input-group--full-width{width:100%}.number-field{gap:var(--spacing);flex-direction:column;display:flex}:is(.number-field[data-invalid=true],.number-field[aria-invalid=true]) [data-slot=description]{display:none}.number-field [data-slot=label]{width:fit-content}.number-field__group{height:calc(var(--spacing) * 9);border-radius:var(--field-radius,calc(var(--radius) * 1.5));border-style:var(--tw-border-style);background-color:var(--field-background,var(--default));font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--field-foreground,var(--foreground));--tw-shadow:var(--field-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;border-width:1px;border-width:var(--border-width-field);border-color:var(--field-border);transition:background-color .15s var(--ease-smooth),border-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out);outline-style:none;grid-template-columns:40px 1fr 40px;align-items:center;display:grid;overflow:hidden}.number-field__group:is([data-reduce-motion=true],[data-reduce-motion=true] *),.number-field__group:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.number-field__group:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.number-field__group:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.number-field__group:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.number-field__group:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}@media(hover:hover){.number-field__group:hover:not(:focus-within),.number-field__group[data-hovered=true]:not([data-focus-within=true]){background-color:var(--field-hover);border-color:var(--field-border-hover)}}.number-field__group[data-focus-within=true],.number-field__group:focus-within{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-outline-style:none;--tw-ring-offset-width:0px;border-color:var(--field-border-focus);background-color:var(--field-focus);outline-style:none}.number-field__group[data-invalid=true]{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}.number-field__group[data-invalid=true]:focus,.number-field__group[data-invalid=true]:focus-visible,.number-field__group[data-invalid=true][data-focused=true],.number-field__group[data-invalid=true][data-focus-visible=true],.number-field__group[data-invalid=true]:focus-within,.number-field__group[data-invalid=true][data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.number-field__group[data-invalid=true]{background-color:var(--field-focus);border-color:var(--color-field-border-invalid)}.number-field__group[data-disabled=true],.number-field__group[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}:-webkit-any(.number-field__group:has([data-slot=number-field-input]:-webkit-autofill),.number-field__group:has([data-slot=number-field-input]:autofill)){background-color:var(--field-focus);border-color:var(--field-border-focus)}:is(.number-field__group:has([data-slot=number-field-input]:autofill)){background-color:var(--field-focus);border-color:var(--field-border-focus)}.number-field__input{border-style:var(--tw-border-style);min-width:0;padding-inline:calc(var(--spacing) * 3);padding-block:calc(var(--spacing) * 2);font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,);--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;background-color:#0000;border-width:0;border-radius:0;outline-style:none}@media(min-width:40rem){.number-field__input{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}.number-field__group:has([slot=decrement]) .number-field__input{border-top-left-radius:0;border-bottom-left-radius:0}.number-field__group:has([slot=increment]) .number-field__input{border-top-right-radius:0;border-bottom-right-radius:0}.number-field__input:focus,.number-field__input:focus-visible{--tw-outline-style:none;outline-style:none}.number-field__input:-webkit-autofill{-webkit-text-fill-color:var(--field-foreground);caret-color:var(--field-foreground);transition:background-color 9999s ease-in-out;box-shadow:inset 0 0 0 1000px #0000}.number-field__input:-webkit-autofill:hover{-webkit-text-fill-color:var(--field-foreground);caret-color:var(--field-foreground);transition:background-color 9999s ease-in-out;box-shadow:inset 0 0 0 1000px #0000}.number-field__input:-webkit-autofill:focus{-webkit-text-fill-color:var(--field-foreground);caret-color:var(--field-foreground);transition:background-color 9999s ease-in-out;box-shadow:inset 0 0 0 1000px #0000}.number-field__input:-webkit-autofill:active{-webkit-text-fill-color:var(--field-foreground);caret-color:var(--field-foreground);transition:background-color 9999s ease-in-out;box-shadow:inset 0 0 0 1000px #0000}.number-field__input:autofill{-webkit-text-fill-color:var(--field-foreground);caret-color:var(--field-foreground);transition:background-color 9999s ease-in-out;box-shadow:inset 0 0 0 1000px #0000}.number-field__increment-button,.number-field__decrement-button{height:100%;width:calc(var(--spacing) * 10);color:var(--field-foreground,var(--foreground));--tw-outline-style:none;border-width:var(--border-width-field);border-color:var(--field-border);transition:background-color .15s var(--ease-smooth),border-color .15s var(--ease-smooth);background-color:#0000;border-style:solid;border-radius:0;outline-style:none;justify-content:center;align-items:center;display:flex}:is(.number-field__increment-button,.number-field__decrement-button):is([data-reduce-motion=true],[data-reduce-motion=true] *),:is(.number-field__increment-button,.number-field__decrement-button):is([data-reduce-motion=true],[data-reduce-motion=true] *):before,:is(.number-field__increment-button,.number-field__decrement-button):is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){:is(.number-field__increment-button,.number-field__decrement-button):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),:is(.number-field__increment-button,.number-field__decrement-button):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,:is(.number-field__increment-button,.number-field__decrement-button):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.number-field__increment-button,.number-field__decrement-button{cursor:var(--cursor-interactive)}:is(.number-field__increment-button,.number-field__decrement-button):active,:is(.number-field__increment-button,.number-field__decrement-button)[data-pressed=true]{background-color:var(--field-foreground,var(--foreground))}@supports (color:color-mix(in lab,red,red)){:is(.number-field__increment-button,.number-field__decrement-button):active,:is(.number-field__increment-button,.number-field__decrement-button)[data-pressed=true]{background-color:color-mix(in oklab,var(--field-foreground,var(--foreground)) 10%,transparent)}}:is(.number-field__increment-button,.number-field__decrement-button):active,:is(.number-field__increment-button,.number-field__decrement-button)[data-pressed=true]{transform:scale(.97)}:is(.number-field__increment-button,.number-field__decrement-button):disabled,:is(.number-field__increment-button,.number-field__decrement-button)[data-disabled=true],:is(.number-field__increment-button,.number-field__decrement-button)[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}:is(.number-field__increment-button,.number-field__decrement-button) [data-slot=number-field-increment-button-icon],:is(.number-field__increment-button,.number-field__decrement-button) [data-slot=number-field-decrement-button-icon]{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.number-field__increment-button{border-top-left-radius:0;border-bottom-left-radius:0;border-top-right-radius:var(--field-radius,calc(var(--radius) * 1.5));border-bottom-right-radius:var(--field-radius,calc(var(--radius) * 1.5));border-left-style:var(--tw-border-style);border-left-width:1px;border-color:var(--field-placeholder,var(--muted))}@supports (color:color-mix(in lab,red,red)){.number-field__increment-button{border-color:color-mix(in oklab,var(--field-placeholder,var(--muted)) 15%,transparent)}}.number-field__decrement-button{border-top-left-radius:var(--field-radius,calc(var(--radius) * 1.5));border-bottom-left-radius:var(--field-radius,calc(var(--radius) * 1.5));border-right-style:var(--tw-border-style);border-right-width:1px;border-color:var(--field-placeholder,var(--muted));border-top-right-radius:0;border-bottom-right-radius:0}@supports (color:color-mix(in lab,red,red)){.number-field__decrement-button{border-color:color-mix(in oklab,var(--field-placeholder,var(--muted)) 15%,transparent)}}.number-field--secondary .number-field__group{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);background-color:var(--number-field-group-bg);--number-field-group-bg:var(--default);--number-field-group-bg-hover:var(--default-hover);--number-field-group-bg-focus:var(--default)}@media(hover:hover){.number-field--secondary .number-field__group:hover:not(:focus-within),.number-field--secondary .number-field__group[data-hovered=true]:not([data-focus-within=true]){background-color:var(--number-field-group-bg-hover)}}.number-field--secondary .number-field__group:focus-within,.number-field--secondary .number-field__group[data-focus-within=true]{background-color:var(--number-field-group-bg-focus)}.number-field--secondary .number-field__group[data-invalid=true]{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}.number-field--secondary .number-field__group[data-invalid=true]:focus,.number-field--secondary .number-field__group[data-invalid=true]:focus-visible,.number-field--secondary .number-field__group[data-invalid=true][data-focused=true],.number-field--secondary .number-field__group[data-invalid=true][data-focus-visible=true],.number-field--secondary .number-field__group[data-invalid=true]:focus-within,.number-field--secondary .number-field__group[data-invalid=true][data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.number-field--secondary .number-field__group[data-invalid=true]{border-color:var(--color-field-border-invalid);background-color:var(--number-field-group-bg-focus)}.number-field--secondary .number-field__group [data-slot=number-field-input]{background-color:#0000}.number-field--full-width,.number-field__group--full-width{width:100%}.radio-group{flex-direction:column;display:flex}.radio-group[data-orientation=vertical] [data-slot=radio]{margin-top:calc(var(--spacing) * 4)}.radio-group[data-orientation=horizontal]{gap:calc(var(--spacing) * 4);flex-flow:wrap}.radio-group--secondary .radio__control{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);background-color:var(--radio-control-bg);--radio-control-bg:var(--default);--radio-control-bg-hover:var(--default-hover)}.radio:has([data-slot=radio-content][data-hovered=true]) :is(.radio-group--secondary .radio__control),.radio [data-slot=radio-content][data-hovered=true] :is(.radio-group--secondary .radio__control){border-color:var(--field-border-hover)}.radio:not([data-selected]):not(:has(input:checked)) :is(.radio-group--secondary .radio__control) .radio__indicator:empty:before{background-color:var(--radio-control-bg)}.radio:has([data-slot=radio-content][data-hovered=true]):not([data-selected]):not(:has(input:checked)) :is(.radio-group--secondary .radio__control) .radio__indicator:empty:before{background-color:var(--radio-control-bg-hover)}.radio{align-items:flex-start;gap:var(--spacing);--tw-outline-style:none;-webkit-tap-highlight-color:transparent;cursor:var(--cursor-interactive);outline-style:none;flex-direction:column;display:flex}.radio [data-slot=label]{-webkit-user-select:none;user-select:none}.radio .radio__content [data-slot=label]{cursor:var(--cursor-interactive)}.radio>[data-slot=description],.radio>[data-slot=field-error]{cursor:default;width:100%;min-width:0;font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));text-wrap:wrap;overflow-wrap:break-word;color:var(--muted);-webkit-user-select:none;user-select:none;padding-inline-start:calc(var(--spacing) * 7)}.radio:disabled,.radio[data-disabled=true],.radio[aria-disabled=true],:is(.radio:disabled,.radio[data-disabled=true],.radio[aria-disabled=true]) [data-slot=description],:is(.radio:disabled,.radio[data-disabled=true],.radio[aria-disabled=true]) [data-slot=field-error]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.radio__content{cursor:inherit;align-items:center;gap:calc(var(--spacing) * 3);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--foreground);--tw-outline-style:none;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;outline-style:none;display:inline-flex}.radio__control{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4);border-radius:calc(var(--radius) * 1);border-style:var(--tw-border-style);border-width:1px;border-width:var(--border-width-field);border-color:var(--field-border,var(--border));background-color:var(--field-background,var(--default));--tw-shadow:var(--field-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;-webkit-tap-highlight-color:transparent;transition:background-color .2s var(--ease-out),border-color .2s var(--ease-out),transform .1s var(--ease-out);outline-style:none;flex-shrink:0;justify-content:center;align-items:center;display:inline-flex;position:relative}.radio__control:is([data-reduce-motion=true],[data-reduce-motion=true] *),.radio__control:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.radio__control:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.radio__control:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.radio__control:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.radio__control:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.radio__control{cursor:var(--cursor-interactive)}.radio:has([data-slot=radio-content][data-focus-visible=true]) .radio__control,.radio [data-slot=radio-content][data-focus-visible=true] .radio__control{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.radio:has([data-slot=radio-content][data-hovered=true]) .radio__control,.radio [data-slot=radio-content][data-hovered=true] .radio__control{border-color:var(--field-border-hover)}.radio:has([data-slot=radio-content][data-hovered=true]):not([data-selected]):not(:has(input:checked)) .radio__control .radio__indicator:empty:before{background-color:var(--field-hover)}.radio:has([data-slot=radio-content][data-pressed=true]) .radio__control,.radio [data-slot=radio-content][data-pressed=true] .radio__control{--tw-scale-x:95%;--tw-scale-y:95%;--tw-scale-z:95%;scale:var(--tw-scale-x) var(--tw-scale-y)}.radio[data-selected] .radio__control,.radio:has([data-slot=radio-content][aria-checked=true]) .radio__control,.radio:has(input:checked) .radio__control{background-color:var(--accent);border-color:#0000}.radio[data-selected]:has([data-slot=radio-content][data-pressed=true]) .radio__control,.radio:has([data-slot=radio-content][data-pressed=true][aria-checked=true]) .radio__control,.radio:has(input:checked):has([data-slot=radio-content][data-pressed=true]) .radio__control{background-color:var(--accent-hover)}.radio[data-invalid=true] .radio__control,.radio[aria-invalid=true] .radio__control{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}:is(.radio[data-invalid=true] .radio__control,.radio[aria-invalid=true] .radio__control):focus,:is(.radio[data-invalid=true] .radio__control,.radio[aria-invalid=true] .radio__control):focus-visible,:is(.radio[data-invalid=true] .radio__control,.radio[aria-invalid=true] .radio__control)[data-focused=true],:is(.radio[data-invalid=true] .radio__control,.radio[aria-invalid=true] .radio__control)[data-focus-visible=true],:is(.radio[data-invalid=true] .radio__control,.radio[aria-invalid=true] .radio__control):focus-within,:is(.radio[data-invalid=true] .radio__control,.radio[aria-invalid=true] .radio__control)[data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.radio[data-invalid=true][data-selected] .radio__control,.radio[aria-invalid=true][data-selected] .radio__control,.radio[data-invalid=true]:has(input:checked) .radio__control,.radio[aria-invalid=true]:has(input:checked) .radio__control{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}:is(.radio[data-invalid=true][data-selected] .radio__control,.radio[aria-invalid=true][data-selected] .radio__control,.radio[data-invalid=true]:has(input:checked) .radio__control,.radio[aria-invalid=true]:has(input:checked) .radio__control):focus,:is(.radio[data-invalid=true][data-selected] .radio__control,.radio[aria-invalid=true][data-selected] .radio__control,.radio[data-invalid=true]:has(input:checked) .radio__control,.radio[aria-invalid=true]:has(input:checked) .radio__control):focus-visible,:is(.radio[data-invalid=true][data-selected] .radio__control,.radio[aria-invalid=true][data-selected] .radio__control,.radio[data-invalid=true]:has(input:checked) .radio__control,.radio[aria-invalid=true]:has(input:checked) .radio__control)[data-focused=true],:is(.radio[data-invalid=true][data-selected] .radio__control,.radio[aria-invalid=true][data-selected] .radio__control,.radio[data-invalid=true]:has(input:checked) .radio__control,.radio[aria-invalid=true]:has(input:checked) .radio__control)[data-focus-visible=true],:is(.radio[data-invalid=true][data-selected] .radio__control,.radio[aria-invalid=true][data-selected] .radio__control,.radio[data-invalid=true]:has(input:checked) .radio__control,.radio[aria-invalid=true]:has(input:checked) .radio__control):focus-within,:is(.radio[data-invalid=true][data-selected] .radio__control,.radio[aria-invalid=true][data-selected] .radio__control,.radio[data-invalid=true]:has(input:checked) .radio__control,.radio[aria-invalid=true]:has(input:checked) .radio__control)[data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.radio__indicator{pointer-events:none;justify-content:center;align-items:center;display:flex;position:absolute;top:0;right:0;bottom:0;left:0}.radio__indicator:empty:before{content:"";border-radius:calc(var(--radius) * 1);background-color:var(--field-background,var(--default));width:100%;height:100%;transition:scale .2s var(--ease-out),background-color .2s var(--ease-out);scale:1}@media(prefers-reduced-motion:reduce){.radio__indicator:empty:before:not(:is()){transition-property:none}}.radio[data-selected] .radio__indicator:empty:before,.radio:has([data-slot=radio-content][aria-checked=true]) .radio__indicator:empty:before,.radio:has(input:checked) .radio__indicator:empty:before{background-color:var(--accent-foreground);scale:.4286}.radio[data-selected]:has([data-slot=radio-content][data-pressed=true]) .radio__indicator:empty:before,.radio:has([data-slot=radio-content][data-pressed=true][aria-checked=true]) .radio__indicator:empty:before,.radio:has(input:checked):has([data-slot=radio-content][data-pressed=true]) .radio__indicator:empty:before{scale:.5714}.radio--disabled{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.textfield{gap:var(--spacing);flex-direction:column;display:flex}:is(.textfield[data-invalid=true],.textfield[aria-invalid=true]) [data-slot=description]{display:none}.textfield--full-width,.textfield--full-width [data-slot=input],.textfield--full-width [data-slot=textarea]{width:100%}.search-field{gap:var(--spacing);flex-direction:column;display:flex}:is(.search-field[data-invalid=true],.search-field[aria-invalid=true]) [data-slot=description]{display:none}.search-field [data-slot=label]{width:fit-content}.search-field[data-empty=true] [data-slot=search-field-clear-button]{pointer-events:none;opacity:0}.search-field__group{height:calc(var(--spacing) * 9);border-radius:var(--field-radius,calc(var(--radius) * 1.5));border-style:var(--tw-border-style);background-color:var(--field-background,var(--default));font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--field-foreground,var(--foreground));--tw-shadow:var(--field-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;border-width:1px;border-width:var(--border-width-field);border-color:var(--field-border);transition:background-color .15s var(--ease-smooth),border-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out);outline-style:none;align-items:center;display:inline-flex;position:relative;overflow:hidden}.search-field__group:is([data-reduce-motion=true],[data-reduce-motion=true] *),.search-field__group:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.search-field__group:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.search-field__group:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.search-field__group:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.search-field__group:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}@media(hover:hover){.search-field__group:hover:not(:focus-within),.search-field__group[data-hovered=true]:not([data-focus-within=true]){background-color:var(--field-hover);border-color:var(--field-border-hover)}}.search-field__group[data-focus-within=true],.search-field__group:focus-within{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-outline-style:none;--tw-ring-offset-width:0px;outline-style:none}.search-field__group[data-invalid=true]{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}.search-field__group[data-invalid=true]:focus,.search-field__group[data-invalid=true]:focus-visible,.search-field__group[data-invalid=true][data-focused=true],.search-field__group[data-invalid=true][data-focus-visible=true],.search-field__group[data-invalid=true]:focus-within,.search-field__group[data-invalid=true][data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.search-field__group[data-invalid=true]{background-color:var(--field-focus);border-color:var(--color-field-border-invalid)}.search-field__group[data-disabled=true],.search-field__group[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}:-webkit-any(.search-field__group:has([data-slot=search-field-input]:-webkit-autofill),.search-field__group:has([data-slot=search-field-input]:autofill)){background-color:var(--field-focus);border-color:var(--field-border-focus)}:is(.search-field__group:has([data-slot=search-field-input]:autofill)){background-color:var(--field-focus);border-color:var(--field-border-focus)}.search-field__input{border-style:var(--tw-border-style);padding-inline:calc(var(--spacing) * 3);padding-block:calc(var(--spacing) * 2);font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;background-color:#0000;border-width:0;border-radius:0;outline-style:none;flex:1}@media(min-width:40rem){.search-field__input{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}.search-field__input::-webkit-search-cancel-button{-webkit-appearance:none;-moz-appearance:none;appearance:none}.search-field__input::-webkit-search-decoration{-webkit-appearance:none;-moz-appearance:none;appearance:none}.search-field__group:has([data-slot=search-field-search-icon]) .search-field__input{padding-left:calc(var(--spacing) * 2);border-top-left-radius:0;border-bottom-left-radius:0}.search-field__group:has([slot=clear]) .search-field__input{padding-right:calc(var(--spacing) * 2);border-top-right-radius:0;border-bottom-right-radius:0}.search-field__input:focus,.search-field__input:focus-visible{--tw-outline-style:none;outline-style:none}.search-field__input:-webkit-autofill{-webkit-text-fill-color:var(--field-foreground);caret-color:var(--field-foreground);transition:background-color 9999s ease-in-out;box-shadow:inset 0 0 0 1000px #0000}.search-field__input:-webkit-autofill:hover{-webkit-text-fill-color:var(--field-foreground);caret-color:var(--field-foreground);transition:background-color 9999s ease-in-out;box-shadow:inset 0 0 0 1000px #0000}.search-field__input:-webkit-autofill:focus{-webkit-text-fill-color:var(--field-foreground);caret-color:var(--field-foreground);transition:background-color 9999s ease-in-out;box-shadow:inset 0 0 0 1000px #0000}.search-field__input:-webkit-autofill:active{-webkit-text-fill-color:var(--field-foreground);caret-color:var(--field-foreground);transition:background-color 9999s ease-in-out;box-shadow:inset 0 0 0 1000px #0000}.search-field__input:autofill{-webkit-text-fill-color:var(--field-foreground);caret-color:var(--field-foreground);transition:background-color 9999s ease-in-out;box-shadow:inset 0 0 0 1000px #0000}.search-field__search-icon{pointer-events:none;color:var(--field-placeholder,var(--muted));margin-right:0;margin-left:calc(var(--spacing) * 3);width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4);flex-shrink:0}.search-field__clear-button{margin-right:calc(var(--spacing) * 2);width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5);flex-shrink:0}.search-field__clear-button [data-slot=close-button-icon]{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.search-field--secondary .search-field__group{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);background-color:var(--search-field-group-bg);--search-field-group-bg:var(--default);--search-field-group-bg-hover:var(--default-hover);--search-field-group-bg-focus:var(--default)}@media(hover:hover){.search-field--secondary .search-field__group:hover:not(:focus-within),.search-field--secondary .search-field__group[data-hovered=true]:not([data-focus-within=true]){background-color:var(--search-field-group-bg-hover)}}.search-field--secondary .search-field__group:focus-within,.search-field--secondary .search-field__group[data-focus-within=true]{background-color:var(--search-field-group-bg-focus)}.search-field--secondary .search-field__group[data-invalid=true]{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}.search-field--secondary .search-field__group[data-invalid=true]:focus,.search-field--secondary .search-field__group[data-invalid=true]:focus-visible,.search-field--secondary .search-field__group[data-invalid=true][data-focused=true],.search-field--secondary .search-field__group[data-invalid=true][data-focus-visible=true],.search-field--secondary .search-field__group[data-invalid=true]:focus-within,.search-field--secondary .search-field__group[data-invalid=true][data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.search-field--secondary .search-field__group[data-invalid=true]{border-color:var(--color-field-border-invalid);background-color:var(--search-field-group-bg-focus)}.search-field--secondary .search-field__group [data-slot=search-field-input]{background-color:#0000}.search-field--full-width,.search-field__group--full-width{width:100%}.textarea{border-radius:var(--field-radius,calc(var(--radius) * 1.5));border-style:var(--tw-border-style);background-color:var(--field-background,var(--default));padding-inline:calc(var(--spacing) * 3);padding-block:calc(var(--spacing) * 2);font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));color:var(--field-foreground,var(--foreground));--tw-shadow:var(--field-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;border-width:1px;outline-style:none}.textarea::placeholder{color:var(--field-placeholder,var(--muted))}@media(min-width:40rem){.textarea{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}.textarea{border-width:var(--border-width-field);border-color:var(--field-border);min-height:38px;transition:background-color .15s var(--ease-smooth),border-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out)}.textarea:is([data-reduce-motion=true],[data-reduce-motion=true] *),.textarea:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.textarea:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.textarea:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.textarea:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.textarea:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}@media(hover:hover){.textarea:hover:not(:focus):not(:focus-visible),.textarea[data-hovered=true]:not([data-focused=true]):not([data-focus-visible=true]){background-color:var(--field-hover);border-color:var(--field-border-hover)}}.textarea:focus,.textarea[data-focused=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-outline-style:none;--tw-ring-offset-width:0px;border-color:var(--field-border-focus);background-color:var(--field-focus);outline-style:none}.textarea[data-invalid=true]{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}.textarea[data-invalid=true]:focus,.textarea[data-invalid=true]:focus-visible,.textarea[data-invalid=true][data-focused=true],.textarea[data-invalid=true][data-focus-visible=true],.textarea[data-invalid=true]:focus-within,.textarea[data-invalid=true][data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.textarea[data-invalid=true]{background-color:var(--field-focus)}.textarea:disabled,.textarea[data-disabled=true],.textarea[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.textarea--secondary{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);background-color:var(--textarea-bg);--textarea-bg:var(--default);--textarea-bg-hover:var(--default-hover);--textarea-bg-focus:var(--default)}@media(hover:hover){.textarea--secondary:hover:not(:focus):not(:focus-visible),.textarea--secondary[data-hovered=true]:not([data-focused=true]):not([data-focus-visible=true]){background-color:var(--textarea-bg-hover)}}.textarea--secondary:focus,.textarea--secondary[data-focused=true]{background-color:var(--textarea-bg-focus)}.textarea--secondary[data-invalid=true]{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}.textarea--secondary[data-invalid=true]:focus,.textarea--secondary[data-invalid=true]:focus-visible,.textarea--secondary[data-invalid=true][data-focused=true],.textarea--secondary[data-invalid=true][data-focus-visible=true],.textarea--secondary[data-invalid=true]:focus-within,.textarea--secondary[data-invalid=true][data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.textarea--secondary[data-invalid=true]{background-color:var(--textarea-bg-focus)}.textarea--full-width{width:100%}.calendar{width:calc(var(--spacing) * 63);max-width:calc(var(--spacing) * 63);container-type:inline-size}.calendar--week-view .calendar__cell,.calendar--day-view .calendar__cell{aspect-ratio:1;place-self:center;width:100%;height:auto}.calendar--day-view .calendar__grid{flex-direction:column;display:flex}.calendar--day-view .calendar__grid-header{grid-template-columns:repeat(7,1fr);width:100%;display:grid}.calendar--day-view .calendar__grid-header>tr{display:contents}.calendar--day-view .calendar__grid-body{margin-top:var(--spacing);grid-template-columns:repeat(7,1fr);width:100%;display:grid}.calendar--day-view .calendar__grid-body>tr{display:contents}.calendar--day-view .calendar__grid-body>tr:first-child>td{margin-top:0}.calendar__header{padding-inline:calc(var(--spacing) * .5);padding-bottom:calc(var(--spacing) * 4);justify-content:space-between;align-items:center;display:flex}.calendar__header:has(.calendar-year-picker__trigger[data-open=true]) .calendar__nav-button{pointer-events:none;opacity:0}.calendar__heading{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);flex:1}.calendar__nav-button{width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6);border-radius:calc(var(--radius) * 2);color:var(--accent-soft-foreground);will-change:scale;transition:transform .25s var(--ease-out),background-color .1s var(--ease-out),box-shadow .1s var(--ease-out),opacity .15s var(--ease-out);transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);justify-content:center;align-items:center;display:flex}.calendar__nav-button:is([data-reduce-motion=true],[data-reduce-motion=true] *),.calendar__nav-button:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.calendar__nav-button:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.calendar__nav-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.calendar__nav-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.calendar__nav-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.calendar__nav-button{cursor:var(--cursor-interactive)}@media(hover:hover){.calendar__nav-button:hover,.calendar__nav-button[data-hovered=true]{background-color:var(--default);color:var(--accent-soft-foreground)}}.calendar__nav-button:active,.calendar__nav-button[data-pressed=true]{transform:scale(.95)}.calendar__nav-button:focus-visible,.calendar__nav-button[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.calendar__nav-button:disabled,.calendar__nav-button[data-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.calendar__nav-button-icon{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.calendar__grid{grid-template-columns:repeat(7,1fr);width:100%;display:grid}.calendar__grid[aria-readonly=true] .calendar__cell{pointer-events:none}.calendar__grid-header,.calendar__grid-header>tr,.calendar__grid-body,.calendar__grid-body>tr{display:contents}.calendar__grid-body>tr:first-child>td{margin-top:var(--spacing)}.calendar__grid-row{display:contents}.calendar__header-cell{padding-bottom:calc(var(--spacing) * 2);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--muted);justify-content:center;align-items:center;display:flex}.calendar__cell{aspect-ratio:1;border-radius:calc(var(--radius) * 3);text-align:center;width:100%;height:100%;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);--tw-outline-style:none;-webkit-tap-highlight-color:transparent;will-change:scale;transition:transform .25s var(--ease-out),box-shadow .1s var(--ease-out);transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);outline-style:none;justify-content:center;align-items:center;display:flex;position:relative}.calendar__cell:is([data-reduce-motion=true],[data-reduce-motion=true] *),.calendar__cell:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.calendar__cell:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.calendar__cell:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.calendar__cell:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.calendar__cell:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.calendar__cell{cursor:var(--cursor-interactive)}.calendar__cell:focus-visible:not(:focus),.calendar__cell[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.calendar__cell[data-today=true]{background-color:var(--accent-soft);color:var(--accent-soft-foreground)}@media(hover:hover){.calendar__cell[data-today=true]:hover:not([data-selected=true]),.calendar__cell[data-today=true][data-hovered=true]:not([data-selected=true]){background-color:var(--accent-soft-hover)}}.calendar__cell[data-selected=true]{background-color:var(--accent);color:var(--accent-foreground)}.calendar__cell:active,.calendar__cell[data-pressed=true]{background-color:var(--default);transform:scale(.95)}:is(.calendar__cell:active,.calendar__cell[data-pressed=true])[data-selected=true]{background-color:var(--accent-hover)}@media(hover:hover){.calendar__cell:hover:not([data-selected=true]),.calendar__cell[data-hovered=true]:not([data-selected=true]){background-color:var(--default)}}.calendar__cell[data-outside-month=true]{color:var(--muted);opacity:.5}.calendar__cell[data-selected=true][data-outside-month=true]{background-color:var(--default)}.calendar__cell[data-unavailable=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.calendar__cell:disabled:not([data-outside-month=true]),.calendar__cell[data-disabled=true]:not([data-outside-month=true]){opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none;text-decoration:line-through}.calendar__cell-indicator{bottom:var(--spacing);--tw-translate-x: -50% ;width:3px;height:3px;translate:var(--tw-translate-x) var(--tw-translate-y);border-radius:calc(var(--radius) * .25);background-color:var(--muted);position:absolute;left:50%}[data-selected=true]>.calendar__cell-indicator{background-color:var(--accent-foreground)}.range-calendar{width:calc(var(--spacing) * 63);max-width:calc(var(--spacing) * 63);container-type:inline-size}.range-calendar--week-view .range-calendar__cell,.range-calendar--day-view .range-calendar__cell{aspect-ratio:1;place-self:center;width:100%;height:auto}.range-calendar--day-view .range-calendar__grid{flex-direction:column;display:flex}.range-calendar--day-view .range-calendar__grid-header{grid-template-columns:repeat(7,1fr);width:100%;display:grid}.range-calendar--day-view .range-calendar__grid-header>tr{display:contents}.range-calendar--day-view .range-calendar__grid-body{margin-top:var(--spacing);grid-template-columns:repeat(7,1fr);width:100%;display:grid}.range-calendar--day-view .range-calendar__grid-body>tr{display:contents}.range-calendar--day-view .range-calendar__grid-body>tr:first-child>td{margin-top:0}.range-calendar__header{padding-inline:calc(var(--spacing) * .5);padding-bottom:calc(var(--spacing) * 4);justify-content:space-between;align-items:center;display:flex}.range-calendar__header:has(.calendar-year-picker__trigger[data-open=true]) .range-calendar__nav-button{pointer-events:none;opacity:0}.range-calendar__heading{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);flex:1}.range-calendar__nav-button{width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6);border-radius:calc(var(--radius) * 1.5);color:var(--accent-soft-foreground);will-change:scale;transition:transform .25s var(--ease-out),background-color .1s var(--ease-out),box-shadow .1s var(--ease-out),opacity .15s var(--ease-out);transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);justify-content:center;align-items:center;display:flex}.range-calendar__nav-button:is([data-reduce-motion=true],[data-reduce-motion=true] *),.range-calendar__nav-button:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.range-calendar__nav-button:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.range-calendar__nav-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.range-calendar__nav-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.range-calendar__nav-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.range-calendar__nav-button{cursor:var(--cursor-interactive)}@media(hover:hover){.range-calendar__nav-button:hover,.range-calendar__nav-button[data-hovered=true]{background-color:var(--default);color:var(--accent-soft-foreground)}}.range-calendar__nav-button:active,.range-calendar__nav-button[data-pressed=true]{transform:scale(.95)}.range-calendar__nav-button:focus-visible,.range-calendar__nav-button[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.range-calendar__nav-button:disabled,.range-calendar__nav-button[data-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.range-calendar__nav-button-icon{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.range-calendar__grid{grid-template-columns:repeat(7,1fr);width:100%;display:grid}.range-calendar__grid[aria-readonly=true] .range-calendar__cell{pointer-events:none}.range-calendar__grid-header,.range-calendar__grid-header>tr,.range-calendar__grid-body,.range-calendar__grid-body>tr{display:contents}.range-calendar__grid-body>tr:first-child>td{margin-top:var(--spacing)}.range-calendar__grid-row{display:contents}.range-calendar__header-cell{padding-bottom:calc(var(--spacing) * 2);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--muted);justify-content:center;align-items:center;display:flex}.range-calendar__cell{z-index:1;border-radius:calc(var(--radius) * 3);--tw-outline-style:none;cursor:var(--cursor-interactive);will-change:background-color,border-color;transition:box-shadow .1s var(--ease-out),border-color .1s var(--ease-out);transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);outline-style:none;margin-block:2px;margin-inline:0;padding:0;position:relative}.range-calendar__cell:is([data-reduce-motion=true],[data-reduce-motion=true] *),.range-calendar__cell:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.range-calendar__cell:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.range-calendar__cell:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.range-calendar__cell:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.range-calendar__cell:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.range-calendar__cell .range-calendar__cell-button{aspect-ratio:1;border-radius:calc(var(--radius) * 3);width:100%;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--foreground);-webkit-tap-highlight-color:transparent;will-change:scale;transition:scale .2s var(--ease-out);transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);justify-content:center;align-items:center;display:flex}.range-calendar__cell .range-calendar__cell-button:is([data-reduce-motion=true],[data-reduce-motion=true] *),.range-calendar__cell .range-calendar__cell-button:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.range-calendar__cell .range-calendar__cell-button:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.range-calendar__cell .range-calendar__cell-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.range-calendar__cell .range-calendar__cell-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.range-calendar__cell .range-calendar__cell-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.range-calendar__cell:focus-visible:not(:focus),.range-calendar__cell[data-focus-visible=true]{z-index:2}:is(.range-calendar__cell:focus-visible:not(:focus),.range-calendar__cell[data-focus-visible=true]) .range-calendar__cell-button{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.range-calendar__cell[data-today=true] .range-calendar__cell-button{background-color:var(--accent-soft);color:var(--accent-soft-foreground)}@media(hover:hover){:is(.range-calendar__cell[data-today=true]:hover:not([data-selected=true]),.range-calendar__cell[data-today=true][data-hovered=true]:not([data-selected=true])) .range-calendar__cell-button{background-color:var(--accent-soft-hover)}}.range-calendar__cell[data-selected=true]:not([data-outside-month=true]){background-color:var(--accent-soft);border-radius:0}.range-calendar__cell[data-selected=true]:is(td:first-child>*,[aria-disabled]+td>*){border-start-start-radius:calc(var(--radius) * 1);border-end-start-radius:calc(var(--radius) * 1)}.range-calendar__cell[data-selected=true]:is(td:first-child>*,[aria-disabled]+td>*)[data-selection-start=true]{border-start-start-radius:calc(var(--radius) * 3);border-end-start-radius:calc(var(--radius) * 3)}.range-calendar__cell[data-selected=true]:is(td:last-child>*,td:has(+[aria-disabled])>*){border-start-end-radius:calc(var(--radius) * 1);border-end-end-radius:calc(var(--radius) * 1)}.range-calendar__cell[data-selected=true]:is(td:last-child>*,td:has(+[aria-disabled])>*)[data-selection-end=true]{border-start-end-radius:calc(var(--radius) * 3);border-end-end-radius:calc(var(--radius) * 3)}.range-calendar__cell[data-selection-start=true]:not([data-outside-month=true]),.range-calendar__cell[data-selection-end=true]:not([data-outside-month=true]){z-index:2}:is(.range-calendar__cell[data-selection-start=true]:not([data-outside-month=true]),.range-calendar__cell[data-selection-end=true]:not([data-outside-month=true])) .range-calendar__cell-button{background-color:var(--accent);color:var(--accent-foreground)}.range-calendar__cell[data-selection-start=true]:not([data-outside-month=true]){border-top-left-radius:calc(var(--radius) * 3);border-bottom-left-radius:calc(var(--radius) * 3)}.range-calendar__cell[data-selection-end=true]:not([data-outside-month=true]){border-top-right-radius:calc(var(--radius) * 3);border-bottom-right-radius:calc(var(--radius) * 3)}:is(.range-calendar__cell:active,.range-calendar__cell[data-pressed=true]) .range-calendar__cell-button{scale:.9}:is(:is(.range-calendar__cell:active,.range-calendar__cell[data-pressed=true])[data-selection-start=true],:is(.range-calendar__cell:active,.range-calendar__cell[data-pressed=true])[data-selection-end=true]) .range-calendar__cell-button{background-color:var(--accent-hover)}@media(hover:hover){:is(.range-calendar__cell:hover:not([data-selected=true]),.range-calendar__cell[data-hovered=true]:not([data-selected=true])) .range-calendar__cell-button{background-color:var(--default)}}.range-calendar__cell[data-outside-month=true]{color:var(--muted);opacity:.5}.range-calendar__cell[data-selected=true][data-outside-month=true]:not([data-selection-start=true],[data-selection-end=true]){background-color:var(--default)}@supports (color:color-mix(in lab,red,red)){.range-calendar__cell[data-selected=true][data-outside-month=true]:not([data-selection-start=true],[data-selection-end=true]){background-color:color-mix(in oklab,var(--default) 20%,transparent)}}.range-calendar__cell[data-unavailable=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.range-calendar__cell:disabled:not([data-outside-month=true]),.range-calendar__cell[data-disabled=true]:not([data-outside-month=true]){opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none;text-decoration:line-through}.range-calendar__grid-body td:has(>.range-calendar__cell[data-outside-month=true])+td>.range-calendar__cell[data-selected=true]{border-start-start-radius:calc(var(--radius) * 1);border-end-start-radius:calc(var(--radius) * 1)}.range-calendar__grid-body td:has(>.range-calendar__cell[data-outside-month=true])+td>.range-calendar__cell[data-selected=true][data-outside-month=true],.range-calendar__grid-body td:has(>.range-calendar__cell[data-outside-month=true])+td>.range-calendar__cell[data-selected=true][data-selection-start=true]{border-start-start-radius:calc(var(--radius) * 3);border-end-start-radius:calc(var(--radius) * 3)}.range-calendar__grid-body td:has(>.range-calendar__cell[data-selected=true]):has(+td>.range-calendar__cell[data-outside-month=true])>.range-calendar__cell[data-selected=true]{border-start-end-radius:calc(var(--radius) * 1);border-end-end-radius:calc(var(--radius) * 1)}.range-calendar__grid-body td:has(>.range-calendar__cell[data-selected=true]):has(+td>.range-calendar__cell[data-outside-month=true])>.range-calendar__cell[data-selected=true][data-outside-month=true],.range-calendar__grid-body td:has(>.range-calendar__cell[data-selected=true]):has(+td>.range-calendar__cell[data-outside-month=true])>.range-calendar__cell[data-selected=true][data-selection-end=true]{border-start-end-radius:calc(var(--radius) * 3);border-end-end-radius:calc(var(--radius) * 3)}.range-calendar__cell-indicator{bottom:var(--spacing);--tw-translate-x: -50% ;width:3px;height:3px;translate:var(--tw-translate-x) var(--tw-translate-y);border-radius:calc(var(--radius) * .25);background-color:var(--muted);position:absolute;left:50%}[data-selected=true]>.range-calendar__cell-indicator{background-color:var(--accent-foreground)}.calendar:has(.calendar-year-picker__year-grid),.range-calendar:has(.calendar-year-picker__year-grid){position:relative}.calendar:has(.calendar-year-picker__year-grid)>[data-slot=calendar-grid],.range-calendar:has(.calendar-year-picker__year-grid)>[data-slot=range-calendar-grid]{will-change:opacity;transition:opacity .15s var(--ease-out),visibility 0s linear}:is(.calendar:has(.calendar-year-picker__year-grid)>[data-slot=calendar-grid],.range-calendar:has(.calendar-year-picker__year-grid)>[data-slot=range-calendar-grid]):is([data-reduce-motion=true],[data-reduce-motion=true] *),:is(.calendar:has(.calendar-year-picker__year-grid)>[data-slot=calendar-grid],.range-calendar:has(.calendar-year-picker__year-grid)>[data-slot=range-calendar-grid]):is([data-reduce-motion=true],[data-reduce-motion=true] *):before,:is(.calendar:has(.calendar-year-picker__year-grid)>[data-slot=calendar-grid],.range-calendar:has(.calendar-year-picker__year-grid)>[data-slot=range-calendar-grid]):is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){:is(.calendar:has(.calendar-year-picker__year-grid)>[data-slot=calendar-grid],.range-calendar:has(.calendar-year-picker__year-grid)>[data-slot=range-calendar-grid]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),:is(.calendar:has(.calendar-year-picker__year-grid)>[data-slot=calendar-grid],.range-calendar:has(.calendar-year-picker__year-grid)>[data-slot=range-calendar-grid]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,:is(.calendar:has(.calendar-year-picker__year-grid)>[data-slot=calendar-grid],.range-calendar:has(.calendar-year-picker__year-grid)>[data-slot=range-calendar-grid]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.calendar:has(.calendar-year-picker__year-grid[data-open=true])>[data-slot=calendar-grid],.range-calendar:has(.calendar-year-picker__year-grid[data-open=true])>[data-slot=range-calendar-grid]{pointer-events:none;opacity:0;visibility:hidden;transition:opacity .15s var(--ease-out),visibility 0s linear .15s}:is(.calendar:has(.calendar-year-picker__year-grid[data-open=true])>[data-slot=calendar-grid],.range-calendar:has(.calendar-year-picker__year-grid[data-open=true])>[data-slot=range-calendar-grid]):is([data-reduce-motion=true],[data-reduce-motion=true] *),:is(.calendar:has(.calendar-year-picker__year-grid[data-open=true])>[data-slot=calendar-grid],.range-calendar:has(.calendar-year-picker__year-grid[data-open=true])>[data-slot=range-calendar-grid]):is([data-reduce-motion=true],[data-reduce-motion=true] *):before,:is(.calendar:has(.calendar-year-picker__year-grid[data-open=true])>[data-slot=calendar-grid],.range-calendar:has(.calendar-year-picker__year-grid[data-open=true])>[data-slot=range-calendar-grid]):is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){:is(.calendar:has(.calendar-year-picker__year-grid[data-open=true])>[data-slot=calendar-grid],.range-calendar:has(.calendar-year-picker__year-grid[data-open=true])>[data-slot=range-calendar-grid]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),:is(.calendar:has(.calendar-year-picker__year-grid[data-open=true])>[data-slot=calendar-grid],.range-calendar:has(.calendar-year-picker__year-grid[data-open=true])>[data-slot=range-calendar-grid]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,:is(.calendar:has(.calendar-year-picker__year-grid[data-open=true])>[data-slot=calendar-grid],.range-calendar:has(.calendar-year-picker__year-grid[data-open=true])>[data-slot=range-calendar-grid]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.calendar-year-picker__trigger{justify-content:flex-start;align-items:center;gap:var(--spacing);border-radius:calc(var(--radius) * 1);--tw-outline-style:none;cursor:var(--cursor-interactive);touch-action:manipulation;outline-style:none;flex:1;display:flex}.calendar-year-picker__trigger:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.calendar-year-picker__trigger-heading{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);transition:color .15s var(--ease-out)}.calendar-year-picker__trigger-heading:is([data-reduce-motion=true],[data-reduce-motion=true] *),.calendar-year-picker__trigger-heading:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.calendar-year-picker__trigger-heading:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.calendar-year-picker__trigger-heading:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.calendar-year-picker__trigger-heading:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.calendar-year-picker__trigger-heading:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.calendar-year-picker__trigger-indicator{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));color:var(--accent-soft-foreground);transition:transform .15s var(--ease-out)}.calendar-year-picker__trigger-indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *),.calendar-year-picker__trigger-indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.calendar-year-picker__trigger-indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.calendar-year-picker__trigger-indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.calendar-year-picker__trigger-indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.calendar-year-picker__trigger-indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.calendar-year-picker__trigger[data-open=true] .calendar-year-picker__trigger-indicator{transform:rotate(90deg)}.calendar-year-picker__trigger[data-open=true] .calendar-year-picker__trigger-heading{color:var(--accent-soft-foreground)}.calendar-year-picker__year-grid{pointer-events:none;scrollbar-width:var(--scrollbar-width);scrollbar-color:var(--scrollbar-color);scrollbar-gutter:var(--scrollbar-gutter);align-content:flex-start;gap:var(--spacing);padding:var(--spacing);opacity:0;will-change:opacity;grid-template-columns:repeat(3,1fr);display:grid;position:absolute;left:0;right:0;overflow-y:auto}.calendar-year-picker__year-grid[data-open=true]{pointer-events:auto;opacity:1;transition:opacity .2s var(--ease-out) 50ms}.calendar-year-picker__year-grid[data-open=true]:is([data-reduce-motion=true],[data-reduce-motion=true] *),.calendar-year-picker__year-grid[data-open=true]:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.calendar-year-picker__year-grid[data-open=true]:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.calendar-year-picker__year-grid[data-open=true]:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.calendar-year-picker__year-grid[data-open=true]:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.calendar-year-picker__year-grid[data-open=true]:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.calendar-year-picker__year-cell{height:calc(var(--spacing) * 8);border-radius:calc(var(--radius) * 3);padding-inline:calc(var(--spacing) * 2.5);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);--tw-outline-style:none;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;touch-action:manipulation;transition:color .1s var(--ease-smooth),scale .1s var(--ease-smooth),opacity .1s var(--ease-smooth),background-color .1s var(--ease-smooth),box-shadow .1s var(--ease-out);transform-origin:50%;transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);outline-style:none;justify-content:center;align-items:center;display:inline-flex;position:relative}.calendar-year-picker__year-cell:is([data-reduce-motion=true],[data-reduce-motion=true] *),.calendar-year-picker__year-cell:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.calendar-year-picker__year-cell:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.calendar-year-picker__year-cell:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.calendar-year-picker__year-cell:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.calendar-year-picker__year-cell:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.calendar-year-picker__year-cell{cursor:var(--cursor-interactive)}@media(hover:hover)and (pointer:fine){.calendar-year-picker__year-cell:is(:hover,[data-hovered=true]):not([data-selected=true]){background-color:var(--default);color:var(--default-foreground)}}.calendar-year-picker__year-cell[data-selected=true],.calendar-year-picker__year-cell[aria-selected=true]{background-color:var(--accent);color:var(--accent-foreground)}@media(hover:hover)and (pointer:fine){:is(.calendar-year-picker__year-cell[data-selected=true],.calendar-year-picker__year-cell[aria-selected=true]):is(:hover,[data-hovered=true]){background-color:var(--accent-hover)}}.calendar-year-picker__year-cell:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.date-field{gap:var(--spacing);flex-direction:column;display:flex}:is(.date-field[data-invalid=true],.date-field[aria-invalid=true]) [data-slot=description]{display:none}.date-field [data-slot=label]{width:fit-content}.date-field--full-width{width:100%}.time-field{gap:var(--spacing);flex-direction:column;display:flex}:is(.time-field[data-invalid=true],.time-field[aria-invalid=true]) [data-slot=description]{display:none}.time-field [data-slot=label]{width:fit-content}.time-field--full-width{width:100%}.date-input-group{height:calc(var(--spacing) * 9);border-radius:var(--field-radius,calc(var(--radius) * 1.5));border-style:var(--tw-border-style);background-color:var(--field-background,var(--default));font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--field-foreground,var(--foreground));--tw-shadow:var(--field-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;border-width:1px;border-width:var(--border-width-field);border-color:var(--field-border);transition:background-color .15s var(--ease-smooth),border-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out);outline-style:none;align-items:center;display:inline-flex;overflow:hidden}.date-input-group:is([data-reduce-motion=true],[data-reduce-motion=true] *),.date-input-group:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.date-input-group:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.date-input-group:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.date-input-group:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.date-input-group:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}@media(hover:hover){.date-input-group:hover:not(:focus-within),.date-input-group[data-hovered=true]:not([data-focus-within=true]){background-color:var(--field-hover);border-color:var(--field-border-hover)}}.date-input-group[data-focus-within=true]:not(:has([data-slot=date-picker-trigger]:focus,[data-slot=date-picker-trigger][data-focused=true],[data-slot=date-range-picker-trigger]:focus,[data-slot=date-range-picker-trigger][data-focused=true])),.date-input-group:focus-within:not(:has([data-slot=date-picker-trigger]:focus,[data-slot=date-picker-trigger][data-focused=true],[data-slot=date-range-picker-trigger]:focus,[data-slot=date-range-picker-trigger][data-focused=true])){--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-outline-style:none;--tw-ring-offset-width:0px;outline-style:none}.date-input-group[data-invalid=true]{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}.date-input-group[data-invalid=true]:focus,.date-input-group[data-invalid=true]:focus-visible,.date-input-group[data-invalid=true][data-focused=true],.date-input-group[data-invalid=true][data-focus-visible=true],.date-input-group[data-invalid=true]:focus-within,.date-input-group[data-invalid=true][data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.date-input-group[data-invalid=true]{background-color:var(--field-focus);border-color:var(--color-field-border-invalid)}.date-input-group[data-disabled=true],.date-input-group[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.date-input-group__input{cursor:text;border-style:var(--tw-border-style);padding-inline:calc(var(--spacing) * 3);padding-block:calc(var(--spacing) * 2);font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;background-color:#0000;border-width:0;border-radius:0;outline-style:none;flex:1;align-items:center;gap:1px;display:flex}@media(min-width:40rem){.date-input-group__input{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}.date-input-group:has([data-slot=date-input-group-prefix]) .date-input-group__input{padding-left:calc(var(--spacing) * 2);border-top-left-radius:0;border-bottom-left-radius:0}.date-input-group:has([data-slot=date-input-group-suffix]) .date-input-group__input{padding-right:calc(var(--spacing) * 2);border-top-right-radius:0;border-bottom-right-radius:0}.date-input-group:has(.date-range-picker__range-separator) .date-input-group__input[slot=start]{flex:none;padding-right:0}.date-input-group:has(.date-range-picker__range-separator) .date-input-group__input[slot=end]{padding-left:0}.date-input-group__input:focus,.date-input-group__input:focus-visible{--tw-outline-style:none;outline-style:none}.date-input-group__input-container{scrollbar-color:auto;scrollbar-gutter:auto;-ms-overflow-style:none;scrollbar-width:none;flex:1;align-items:center;width:fit-content;display:flex;overflow:auto clip}.date-input-group__segment{border-radius:calc(var(--radius) * .75);padding-inline:calc(var(--spacing) * .5);text-align:end;text-wrap:nowrap;--tw-outline-style:none;outline-style:none;display:inline-block}.date-input-group__segment[data-type=literal]{color:var(--muted);padding:0}.date-input-group__segment[data-placeholder=true]{color:var(--field-placeholder,var(--muted))}.date-input-group__segment:focus,.date-input-group__segment[data-focused=true]{background-color:var(--accent-soft);color:var(--accent-soft-foreground)}.date-input-group__segment[data-disabled=true]{opacity:.5}.date-input-group__segment[data-invalid=true]{color:var(--danger)}.date-input-group__segment[data-invalid=true]:focus,.date-input-group__segment[data-invalid=true][data-focused=true]{background-color:var(--danger-soft);color:var(--danger-soft-foreground)}.date-input-group__prefix{pointer-events:none;color:var(--field-placeholder,var(--muted));margin-right:0;margin-left:calc(var(--spacing) * 3);flex-shrink:0;align-items:center;display:flex}.date-input-group__suffix{pointer-events:none;color:var(--field-placeholder,var(--muted));margin-right:calc(var(--spacing) * 3);flex-shrink:0;align-items:center;display:flex}.date-input-group--secondary{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);background-color:var(--date-input-group-bg);--date-input-group-bg:var(--default);--date-input-group-bg-hover:var(--default-hover);--date-input-group-bg-focus:var(--default)}@media(hover:hover){.date-input-group--secondary:hover:not(:focus-within),.date-input-group--secondary[data-hovered=true]:not([data-focus-within=true]){background-color:var(--date-input-group-bg-hover)}}.date-input-group--secondary:focus-within,.date-input-group--secondary[data-focus-within=true]{background-color:var(--date-input-group-bg-focus)}.date-input-group--secondary[data-invalid=true]{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}.date-input-group--secondary[data-invalid=true]:focus,.date-input-group--secondary[data-invalid=true]:focus-visible,.date-input-group--secondary[data-invalid=true][data-focused=true],.date-input-group--secondary[data-invalid=true][data-focus-visible=true],.date-input-group--secondary[data-invalid=true]:focus-within,.date-input-group--secondary[data-invalid=true][data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.date-input-group--secondary[data-invalid=true]{border-color:var(--color-field-border-invalid);background-color:var(--date-input-group-bg-focus)}.date-input-group--secondary [data-slot=date-input-group-input]{background-color:#0000}.date-input-group--full-width{width:100%}.date-picker{gap:var(--spacing);flex-direction:column;display:inline-flex}.date-picker .date-input-group__suffix,.date-picker .date-input-group__prefix{pointer-events:auto}.date-picker__trigger{border-radius:var(--field-radius,calc(var(--radius) * 1.5));width:100%;padding:var(--spacing);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));-webkit-tap-highlight-color:transparent;cursor:var(--cursor-interactive);transition:box-shadow .15s var(--ease-out);align-items:center;display:inline-flex}.date-picker__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *),.date-picker__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.date-picker__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.date-picker__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.date-picker__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.date-picker__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.date-picker__trigger:focus-visible:not(:focus),.date-picker__trigger[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.date-picker__trigger:disabled,.date-picker__trigger[data-disabled=true],.date-picker__trigger[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.date-picker__trigger-indicator{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4);color:var(--field-placeholder,var(--muted));justify-content:center;align-items:center;display:inline-flex}.date-picker__popover{min-width:var(--trigger-width);transform-origin:var(--trigger-anchor-point);scrollbar-color:auto;scrollbar-gutter:auto;-ms-overflow-style:none;scrollbar-width:none;overscroll-behavior:contain;background-color:var(--overlay);padding:calc(var(--spacing) * 3);overflow-y:auto}.date-picker__popover:is([data-reduce-motion=true],[data-reduce-motion=true] *),.date-picker__popover:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.date-picker__popover:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.date-picker__popover:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.date-picker__popover:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.date-picker__popover:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.date-picker__popover{box-shadow:var(--shadow-overlay);border-radius:min(32px,calc(var(--radius) * 2.5))}.date-picker__popover:focus-visible:not(:focus),.date-picker__popover[data-focus-visible=true]{--tw-outline-style:none;outline-style:none}.date-picker__popover[data-entering=true]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.15s;--tw-ease:ease;--tw-enter-opacity:0;--tw-enter-scale:.95;transition-duration:.15s;transition-timing-function:ease}.date-picker__popover[data-entering=true][data-placement^=top]{--tw-enter-translate-y:calc(1*var(--spacing))}.date-picker__popover[data-entering=true][data-placement^=bottom]{--tw-enter-translate-y:calc(1*var(--spacing)*-1)}.date-picker__popover[data-entering=true][data-placement^=left]{--tw-enter-translate-x:calc(1*var(--spacing))}.date-picker__popover[data-entering=true][data-placement^=right]{--tw-enter-translate-x:calc(1*var(--spacing)*-1)}.date-picker__popover[data-exiting=true]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.1s;--tw-ease:ease;--tw-exit-scale:.95;--tw-exit-opacity:0;transition-duration:.1s;transition-timing-function:ease}.date-picker__popover[data-exiting=true],.date-picker__popover[data-entering=true]{transition-property:opacity,transform;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));will-change:opacity,transform}.date-range-picker{gap:var(--spacing);flex-direction:column;display:inline-flex}.date-range-picker .date-input-group__suffix,.date-range-picker .date-input-group__prefix{pointer-events:auto}.date-range-picker__trigger{border-radius:var(--field-radius,calc(var(--radius) * 1.5));width:100%;padding:var(--spacing);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));-webkit-tap-highlight-color:transparent;cursor:var(--cursor-interactive);transition:box-shadow .15s var(--ease-out);align-items:center;display:inline-flex}.date-range-picker__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *),.date-range-picker__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.date-range-picker__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.date-range-picker__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.date-range-picker__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.date-range-picker__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.date-range-picker__trigger:focus-visible:not(:focus),.date-range-picker__trigger[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.date-range-picker__trigger:disabled,.date-range-picker__trigger[data-disabled=true],.date-range-picker__trigger[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.date-range-picker__trigger-indicator{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4);color:var(--field-placeholder,var(--muted));justify-content:center;align-items:center;display:inline-flex}.date-range-picker__range-separator{padding-inline:var(--spacing);color:var(--field-placeholder,var(--muted));-webkit-user-select:none;user-select:none}.date-range-picker__popover{min-width:var(--trigger-width);transform-origin:var(--trigger-anchor-point);scrollbar-color:auto;scrollbar-gutter:auto;-ms-overflow-style:none;scrollbar-width:none;overscroll-behavior:contain;background-color:var(--overlay);padding:calc(var(--spacing) * 3);overflow-y:auto}.date-range-picker__popover:is([data-reduce-motion=true],[data-reduce-motion=true] *),.date-range-picker__popover:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.date-range-picker__popover:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.date-range-picker__popover:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.date-range-picker__popover:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.date-range-picker__popover:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.date-range-picker__popover{box-shadow:var(--shadow-overlay);border-radius:min(32px,calc(var(--radius) * 2.5))}.date-range-picker__popover:focus-visible:not(:focus),.date-range-picker__popover[data-focus-visible=true]{--tw-outline-style:none;outline-style:none}.date-range-picker__popover[data-entering=true]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.15s;--tw-ease:ease;--tw-enter-opacity:0;--tw-enter-scale:.95;transition-duration:.15s;transition-timing-function:ease}.date-range-picker__popover[data-entering=true][data-placement^=top]{--tw-enter-translate-y:calc(1*var(--spacing))}.date-range-picker__popover[data-entering=true][data-placement^=bottom]{--tw-enter-translate-y:calc(1*var(--spacing)*-1)}.date-range-picker__popover[data-entering=true][data-placement^=left]{--tw-enter-translate-x:calc(1*var(--spacing))}.date-range-picker__popover[data-entering=true][data-placement^=right]{--tw-enter-translate-x:calc(1*var(--spacing)*-1)}.date-range-picker__popover[data-exiting=true]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.1s;--tw-ease:ease;--tw-exit-scale:.95;--tw-exit-opacity:0;transition-duration:.1s;transition-timing-function:ease}.date-range-picker__popover[data-exiting=true],.date-range-picker__popover[data-entering=true]{transition-property:opacity,transform;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));will-change:opacity,transform}.card{gap:calc(var(--spacing) * 3);padding:calc(var(--spacing) * 4);--tw-shadow:var(--surface-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);border-radius:min(32px,var(--radius-3xl));flex-direction:column;display:flex;position:relative;overflow:visible}.card__header{flex-direction:column;display:flex}.card__title{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-leading:calc(var(--spacing) * 6);line-height:calc(var(--spacing) * 6);--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--foreground)}.card__description{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-leading:calc(var(--spacing) * 5);line-height:calc(var(--spacing) * 5);color:var(--muted)}.card__content{gap:var(--spacing);flex-direction:column;flex:1;display:flex}.card__footer{flex-direction:row;align-items:center;display:flex}.card--transparent{--tw-border-style:none;--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);background-color:#0000;border-style:none}.card--default{background-color:var(--surface)}.card--secondary{background-color:var(--surface-secondary)}.card--tertiary{background-color:var(--surface-tertiary)}.header{width:100%;padding-inline:calc(var(--spacing) * 2);padding-top:calc(var(--spacing) * 1.5);padding-bottom:var(--spacing);text-align:left;font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--muted)}.separator{border-radius:calc(var(--radius) * .5);border-top-style:var(--tw-border-style);border-top-width:0;border-bottom-style:var(--tw-border-style);background-color:var(--separator);border-bottom-width:0;flex-shrink:0;width:100%;height:1px}.separator--horizontal{width:100%;height:1px}.separator--vertical{height:auto;min-height:calc(var(--spacing) * 2);align-self:stretch;width:1px}.separator--default{background-color:var(--separator)}.separator--secondary{background-color:var(--separator-secondary)}.separator--tertiary{background-color:var(--separator-tertiary)}.separator__container{align-items:center;gap:calc(var(--spacing) * 3);display:flex}.separator__container--horizontal{flex-direction:row;width:100%}.separator__container--vertical{flex-direction:column;justify-content:center;height:100%}.separator__line{flex-grow:1;flex-shrink:0}.separator__content{text-align:center;white-space:nowrap;color:var(--muted);justify-content:center;align-items:center;display:inline-flex}.separator__content--horizontal,.separator__content--vertical{text-align:center}.surface{color:var(--foreground);position:relative}.surface--transparent{background-color:#0000}.surface--default{background-color:var(--surface);color:var(--surface-foreground)}.surface--secondary{background-color:var(--surface-secondary);color:var(--surface-secondary-foreground)}.surface--tertiary{background-color:var(--surface-tertiary);color:var(--surface-tertiary-foreground)}.avatar{width:calc(var(--spacing) * 10);height:calc(var(--spacing) * 10);border-radius:calc(var(--radius) * 3);background-color:var(--default);flex-shrink:0;justify-content:center;align-items:center;display:flex;position:relative;overflow:hidden}.avatar__fallback{background-color:var(--default);width:100%;height:100%;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);justify-content:center;align-items:center;display:flex}.avatar__image{aspect-ratio:1;width:100%;height:100%;transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.25s;transition-duration:.25s;position:absolute;top:0;right:0;bottom:0;left:0}.avatar__image:is([data-reduce-motion=true],[data-reduce-motion=true] *),.avatar__image:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.avatar__image:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.avatar__image:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.avatar__image:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.avatar__image:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.avatar--sm{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8);border-radius:calc(var(--radius) * 2)}.avatar--lg{width:calc(var(--spacing) * 12);height:calc(var(--spacing) * 12);border-radius:calc(var(--radius) * 3)}.avatar--lg .avatar__fallback{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.avatar__fallback--accent{color:var(--accent-soft-foreground)}.avatar__fallback--default{color:var(--default-soft-foreground)}.avatar__fallback--success{color:var(--success-soft-foreground)}.avatar__fallback--warning{color:var(--warning-soft-foreground)}.avatar__fallback--danger{color:var(--danger-soft-foreground)}.avatar--soft{background-color:#0000}.avatar--soft .avatar__fallback--accent{background-color:var(--accent-soft);color:var(--accent-soft-foreground)}.avatar--soft .avatar__fallback--success{background-color:var(--success-soft);color:var(--success-soft-foreground)}.avatar--soft .avatar__fallback--warning{background-color:var(--warning-soft);color:var(--warning-soft-foreground)}.avatar--soft .avatar__fallback--default{background-color:var(--default-soft);color:var(--default-soft-foreground)}.avatar--soft .avatar__fallback--danger{background-color:var(--danger-soft);color:var(--danger-soft-foreground)}.alert-dialog__trigger{cursor:var(--cursor-interactive);transition:transform .25s var(--ease-out-quart),background-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out);display:inline-block}.alert-dialog__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *),.alert-dialog__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.alert-dialog__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.alert-dialog__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.alert-dialog__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.alert-dialog__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.alert-dialog__trigger:focus-visible:not(:focus),.alert-dialog__trigger[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.alert-dialog__trigger:disabled,.alert-dialog__trigger[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.alert-dialog__trigger:active,.alert-dialog__trigger[data-pressed=true]{transform:scale(.97)}.alert-dialog__backdrop{z-index:50;height:var(--visual-viewport-height);flex-direction:row;justify-content:center;align-items:center;width:100%;display:flex;position:fixed;top:0;right:0;bottom:0;left:0}.alert-dialog__backdrop[data-entering=true]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.15s;--tw-ease:var(--ease-out);transition-duration:.15s;transition-timing-function:var(--ease-out);--tw-enter-opacity:0}.alert-dialog__backdrop[data-exiting=true]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.1s;--tw-ease:var(--ease-out);transition-duration:.1s;transition-timing-function:var(--ease-out);--tw-exit-opacity:0}.alert-dialog__backdrop[data-exiting=true],.alert-dialog__backdrop[data-entering=true]{will-change:opacity}:is(.alert-dialog__backdrop[data-exiting=true],.alert-dialog__backdrop[data-entering=true]):is([data-reduce-motion=true],[data-reduce-motion=true] *),:is(.alert-dialog__backdrop[data-exiting=true],.alert-dialog__backdrop[data-entering=true]):is([data-reduce-motion=true],[data-reduce-motion=true] *):before,:is(.alert-dialog__backdrop[data-exiting=true],.alert-dialog__backdrop[data-entering=true]):is([data-reduce-motion=true],[data-reduce-motion=true] *):after{animation:none}@media(prefers-reduced-motion:reduce){:is(.alert-dialog__backdrop[data-exiting=true],.alert-dialog__backdrop[data-entering=true]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),:is(.alert-dialog__backdrop[data-exiting=true],.alert-dialog__backdrop[data-entering=true]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,:is(.alert-dialog__backdrop[data-exiting=true],.alert-dialog__backdrop[data-entering=true]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{animation:none}}.alert-dialog__backdrop--transparent{background-color:#0000}.alert-dialog__backdrop--opaque{background-color:var(--backdrop)}.alert-dialog__backdrop--blur{background-color:var(--backdrop);--tw-backdrop-blur:blur(var(--blur-md));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.alert-dialog__container{height:var(--visual-viewport-height);width:100%;min-width:0;padding:calc(var(--spacing) * 4);flex-direction:column;flex:1;align-items:center;display:flex}@media(min-width:40rem){.alert-dialog__container{width:fit-content;padding:calc(var(--spacing) * 10)}}.alert-dialog__container{pointer-events:none}.alert-dialog__container[data-entering=true]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.25s;--tw-ease:cubic-bezier(.25, .46, .45, .94);--tw-enter-opacity:0;--tw-enter-scale: 105% ;transition-duration:.25s;transition-timing-function:cubic-bezier(.25,.46,.45,.94)}.alert-dialog__container[data-entering=true][data-placement=auto]{--tw-enter-translate-y:calc(1*var(--spacing))}@media(min-width:40rem){.alert-dialog__container[data-entering=true][data-placement=auto]{--tw-enter-translate-y: 0% }}.alert-dialog__container[data-entering=true][data-placement=top]{--tw-enter-translate-y:calc(1*var(--spacing)*-1)}.alert-dialog__container[data-entering=true][data-placement=center]{--tw-enter-translate-y: -0% }.alert-dialog__container[data-entering=true][data-placement=bottom]{--tw-enter-translate-y:calc(1*var(--spacing))}.alert-dialog__container[data-exiting=true]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.1s;--tw-ease:cubic-bezier(.25, .46, .45, .94);--tw-exit-opacity:0;--tw-exit-scale:.95;transition-duration:.1s;transition-timing-function:cubic-bezier(.25,.46,.45,.94)}.alert-dialog__container[data-exiting=true],.alert-dialog__container[data-entering=true]{will-change:opacity,transform}:is(.alert-dialog__container[data-exiting=true],.alert-dialog__container[data-entering=true]):is([data-reduce-motion=true],[data-reduce-motion=true] *),:is(.alert-dialog__container[data-exiting=true],.alert-dialog__container[data-entering=true]):is([data-reduce-motion=true],[data-reduce-motion=true] *):before,:is(.alert-dialog__container[data-exiting=true],.alert-dialog__container[data-entering=true]):is([data-reduce-motion=true],[data-reduce-motion=true] *):after{animation:none}@media(prefers-reduced-motion:reduce){:is(.alert-dialog__container[data-exiting=true],.alert-dialog__container[data-entering=true]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),:is(.alert-dialog__container[data-exiting=true],.alert-dialog__container[data-entering=true]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,:is(.alert-dialog__container[data-exiting=true],.alert-dialog__container[data-entering=true]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{animation:none}}.alert-dialog__dialog{background-color:var(--overlay);--tw-shadow:var(--overlay-shadow);width:100%;min-height:0;max-height:100%;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;border-radius:min(32px,var(--radius-3xl));padding:calc(var(--spacing) * 6);pointer-events:auto;outline-style:none;flex-direction:column;display:flex;position:relative;overflow:clip}.alert-dialog__dialog[data-placement=auto]{margin-top:auto}@media(min-width:40rem){.alert-dialog__dialog[data-placement=auto]{margin-block:auto}}.alert-dialog__dialog[data-placement=center]{margin-block:auto}.alert-dialog__dialog[data-placement=bottom]{margin-top:auto}.alert-dialog__dialog[data-placement=top]{margin-top:0}.alert-dialog__dialog--xs{max-width:var(--container-xs)}.alert-dialog__dialog--sm{max-width:var(--container-sm)}.alert-dialog__dialog--md{max-width:var(--container-md)}.alert-dialog__dialog--lg{max-width:var(--container-lg)}.alert-dialog__dialog--cover{width:100%;height:100%;min-height:100%}.alert-dialog__header{gap:calc(var(--spacing) * 3);flex-direction:column;margin-bottom:0;display:flex}.alert-dialog__header>.modal__icon{margin-bottom:0}.alert-dialog__heading{vertical-align:middle;font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--foreground)}.alert-dialog__icon{width:calc(var(--spacing) * 10);height:calc(var(--spacing) * 10);border-radius:calc(var(--radius) * 3);-webkit-user-select:none;user-select:none;flex-shrink:0;justify-content:center;align-items:center;display:flex}.alert-dialog__icon [data-slot=alert-dialog-default-icon]{box-sizing:content-box;width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5)}.alert-dialog__icon--default{background-color:var(--default);color:var(--foreground)}.alert-dialog__icon--accent{background-color:var(--accent-soft);color:var(--accent-soft-foreground)}.alert-dialog__icon--success{background-color:var(--success-soft);color:var(--success-soft-foreground)}.alert-dialog__icon--warning{background-color:var(--warning-soft);color:var(--warning-soft-foreground)}.alert-dialog__icon--danger{background-color:var(--danger-soft);color:var(--danger-soft-foreground)}.alert-dialog__body{scrollbar-width:var(--scrollbar-width);scrollbar-color:var(--scrollbar-color);scrollbar-gutter:var(--scrollbar-gutter);min-height:0;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-leading:1.43;color:var(--muted);overscroll-behavior:contain;-webkit-overflow-scrolling:touch;margin:-3px;flex:1;margin-block:0;padding:3px;line-height:1.43;overflow-y:auto}.alert-dialog__footer{justify-content:flex-end;align-items:center;gap:calc(var(--spacing) * 2);flex-direction:row;margin-top:0;display:flex}.alert-dialog__close-trigger{top:calc(var(--spacing) * 4);right:calc(var(--spacing) * 4);position:absolute}.alert-dialog__header+.alert-dialog__body{margin-top:calc(var(--spacing) * 2)}.alert-dialog__header+.alert-dialog__footer,.alert-dialog__body+.alert-dialog__footer{margin-top:calc(var(--spacing) * 5)}.drawer__trigger{cursor:var(--cursor-interactive);transition:transform .25s var(--ease-out-quart),background-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out);display:inline-block}.drawer__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *),.drawer__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.drawer__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.drawer__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.drawer__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.drawer__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.drawer__trigger:focus-visible:not(:focus),.drawer__trigger[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.drawer__trigger:disabled,.drawer__trigger[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.drawer__trigger:active,.drawer__trigger[data-pressed=true]{transform:scale(.97)}.drawer__backdrop{z-index:50;height:var(--visual-viewport-height);opacity:1;width:100%;transition:opacity .25s cubic-bezier(.32,.72,0,1);position:fixed;top:0;right:0;bottom:0;left:0}.drawer__backdrop[data-entering=true]{opacity:0}.drawer__backdrop[data-exiting=true]{opacity:0;transition-duration:.2s;transition-timing-function:cubic-bezier(.32,.72,0,1)}.drawer__backdrop[data-exiting=true],.drawer__backdrop[data-entering=true]{will-change:opacity}@media(prefers-reduced-motion:reduce){.drawer__backdrop{transition:none}}.drawer__backdrop--transparent{background-color:#0000}.drawer__backdrop--opaque{background-color:var(--backdrop)}.drawer__backdrop--blur{background-color:var(--backdrop);--tw-backdrop-blur:blur(var(--blur-md));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.drawer__content{pointer-events:none;z-index:50;height:var(--visual-viewport-height);width:100%;min-width:0;display:flex;position:fixed;top:0;right:0;bottom:0;left:0}.drawer__content--bottom{align-items:flex-end}.drawer__content--top{align-items:flex-start}.drawer__content--left{justify-content:flex-start}.drawer__content--right{justify-content:flex-end}.drawer__dialog{background-color:var(--overlay);--tw-shadow:var(--overlay-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;padding:calc(var(--spacing) * 6);pointer-events:auto;--drawer-enter-duration:.25s;--drawer-exit-duration:.2s;--drawer-enter-ease:cubic-bezier(.32, .72, 0, 1);--drawer-exit-ease:cubic-bezier(.32, .72, 0, 1);will-change:translate;transition:translate var(--drawer-enter-duration) var(--drawer-enter-ease);outline-style:none;flex-direction:column;display:flex;position:relative}@media(prefers-reduced-motion:reduce){.drawer__dialog{transition:none}}.drawer__dialog[data-placement=bottom]{border-top-left-radius:min(32px,var(--radius-2xl));border-top-right-radius:min(32px,var(--radius-2xl));width:100%;max-height:85vh}.drawer__dialog[data-placement=top]{border-bottom-left-radius:min(32px,var(--radius-2xl));border-bottom-right-radius:min(32px,var(--radius-2xl));width:100%;max-height:85vh}.drawer__dialog[data-placement=left]{height:100%;width:calc(var(--spacing) * 80);border-radius:0;max-width:85vw}@media(min-width:40rem){.drawer__dialog[data-placement=left]{width:calc(var(--spacing) * 96)}}.drawer__dialog[data-placement=right]{height:100%;width:calc(var(--spacing) * 80);border-radius:0;max-width:85vw}@media(min-width:40rem){.drawer__dialog[data-placement=right]{width:calc(var(--spacing) * 96)}}[data-exiting=true] .drawer__dialog{transition-duration:var(--drawer-exit-duration);transition-timing-function:var(--drawer-exit-ease)}.drawer__content--left .drawer__dialog,.drawer__content--right .drawer__dialog,.drawer__content--top .drawer__dialog,.drawer__content--bottom .drawer__dialog{translate:0}.drawer__content--left[data-entering=true] .drawer__dialog,.drawer__content--left[data-exiting=true] .drawer__dialog{translate:-100%}.drawer__content--right[data-entering=true] .drawer__dialog,.drawer__content--right[data-exiting=true] .drawer__dialog{translate:100%}.drawer__content--top[data-entering=true] .drawer__dialog,.drawer__content--top[data-exiting=true] .drawer__dialog{translate:0 -100%}.drawer__content--bottom[data-entering=true] .drawer__dialog,.drawer__content--bottom[data-exiting=true] .drawer__dialog{translate:0 100%}.drawer__dialog--top{padding-bottom:calc(var(--spacing) * 2)}.drawer__dialog--top .drawer__handle{padding-bottom:0}.drawer__header{gap:calc(var(--spacing) * 3);flex-direction:column;margin-bottom:0;display:flex}.drawer__heading{vertical-align:middle;font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--foreground)}.drawer__body{scrollbar-width:var(--scrollbar-width);scrollbar-color:var(--scrollbar-color);scrollbar-gutter:var(--scrollbar-gutter);min-height:0;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-leading:1.43;color:var(--muted);overscroll-behavior:contain;-webkit-overflow-scrolling:touch;margin:-3px;flex:1;margin-block:0;padding:3px;line-height:1.43;overflow-y:auto}.drawer__footer{justify-content:flex-end;align-items:center;gap:calc(var(--spacing) * 2);flex-direction:row;margin-top:0;display:flex}.drawer__handle{padding-bottom:calc(var(--spacing) * 2);justify-content:center;align-items:center;display:flex}.drawer__handle>[data-slot=drawer-handle-bar]{height:var(--spacing);width:calc(var(--spacing) * 9);border-radius:calc(var(--radius) * .25);background-color:var(--separator)}.drawer__close-trigger{top:calc(var(--spacing) * 4);right:calc(var(--spacing) * 4);position:absolute}.drawer__header+.drawer__body{margin-top:calc(var(--spacing) * 2)}.drawer__header+.drawer__footer,.drawer__body+.drawer__footer{margin-top:calc(var(--spacing) * 5)}.drawer__handle+.drawer__header,.drawer__handle+.drawer__body{margin-top:0}.modal__trigger{cursor:var(--cursor-interactive);transition:transform .25s var(--ease-out-quart),background-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out);display:inline-block}.modal__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *),.modal__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.modal__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.modal__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.modal__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.modal__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.modal__trigger:focus-visible:not(:focus),.modal__trigger[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.modal__trigger:disabled,.modal__trigger[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.modal__trigger:active,.modal__trigger[data-pressed=true]{transform:scale(.97)}.modal__backdrop{z-index:50;height:var(--visual-viewport-height);flex-direction:row;justify-content:center;align-items:center;width:100%;display:flex;position:fixed;top:0;right:0;bottom:0;left:0}.modal__backdrop[data-entering=true]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.15s;--tw-ease:var(--ease-out);transition-duration:.15s;transition-timing-function:var(--ease-out);--tw-enter-opacity:0}.modal__backdrop[data-exiting=true]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.1s;--tw-ease:var(--ease-out);transition-duration:.1s;transition-timing-function:var(--ease-out);--tw-exit-opacity:0}.modal__backdrop[data-exiting=true],.modal__backdrop[data-entering=true]{will-change:opacity}:is(.modal__backdrop[data-exiting=true],.modal__backdrop[data-entering=true]):is([data-reduce-motion=true],[data-reduce-motion=true] *),:is(.modal__backdrop[data-exiting=true],.modal__backdrop[data-entering=true]):is([data-reduce-motion=true],[data-reduce-motion=true] *):before,:is(.modal__backdrop[data-exiting=true],.modal__backdrop[data-entering=true]):is([data-reduce-motion=true],[data-reduce-motion=true] *):after{animation:none}@media(prefers-reduced-motion:reduce){:is(.modal__backdrop[data-exiting=true],.modal__backdrop[data-entering=true]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),:is(.modal__backdrop[data-exiting=true],.modal__backdrop[data-entering=true]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,:is(.modal__backdrop[data-exiting=true],.modal__backdrop[data-entering=true]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{animation:none}}.modal__backdrop--transparent{background-color:#0000}.modal__backdrop--opaque{background-color:var(--backdrop)}.modal__backdrop--blur{background-color:var(--backdrop);--tw-backdrop-blur:blur(var(--blur-md));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.modal__container{height:var(--visual-viewport-height);width:100%;min-width:0;padding:calc(var(--spacing) * 4);flex-direction:column;flex:1;align-items:center;display:flex}@media(min-width:40rem){.modal__container{width:fit-content;padding:calc(var(--spacing) * 10)}}.modal__container{pointer-events:none}.modal__container[data-entering=true]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.25s;--tw-ease:cubic-bezier(.25, .46, .45, .94);--tw-enter-opacity:0;--tw-enter-scale: 105% ;transition-duration:.25s;transition-timing-function:cubic-bezier(.25,.46,.45,.94)}.modal__container[data-entering=true][data-placement=auto]{--tw-enter-translate-y:calc(1*var(--spacing))}@media(min-width:40rem){.modal__container[data-entering=true][data-placement=auto]{--tw-enter-translate-y: 0% }}.modal__container[data-entering=true][data-placement=top]{--tw-enter-translate-y:calc(1*var(--spacing)*-1)}.modal__container[data-entering=true][data-placement=center]{--tw-enter-translate-y: -0% }.modal__container[data-entering=true][data-placement=bottom]{--tw-enter-translate-y:calc(1*var(--spacing))}.modal__container[data-exiting=true]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.1s;--tw-ease:cubic-bezier(.25, .46, .45, .94);--tw-exit-opacity:0;--tw-exit-scale:.95;transition-duration:.1s;transition-timing-function:cubic-bezier(.25,.46,.45,.94)}.modal__container[data-exiting=true],.modal__container[data-entering=true]{will-change:opacity,transform}:is(.modal__container[data-exiting=true],.modal__container[data-entering=true]):is([data-reduce-motion=true],[data-reduce-motion=true] *),:is(.modal__container[data-exiting=true],.modal__container[data-entering=true]):is([data-reduce-motion=true],[data-reduce-motion=true] *):before,:is(.modal__container[data-exiting=true],.modal__container[data-entering=true]):is([data-reduce-motion=true],[data-reduce-motion=true] *):after{animation:none}@media(prefers-reduced-motion:reduce){:is(.modal__container[data-exiting=true],.modal__container[data-entering=true]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),:is(.modal__container[data-exiting=true],.modal__container[data-entering=true]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,:is(.modal__container[data-exiting=true],.modal__container[data-entering=true]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{animation:none}}.modal__container--scroll-outside{scrollbar-width:var(--scrollbar-width);scrollbar-color:var(--scrollbar-color);scrollbar-gutter:var(--scrollbar-gutter);pointer-events:auto;-webkit-overflow-scrolling:touch;overflow-y:auto}.modal__container--full{padding:0}@media(min-width:40rem){.modal__container--full{padding:0}}.modal__container--full[data-entering=true]{--tw-enter-translate-y: 0% ;--tw-enter-scale:1}@media(min-width:40rem){.modal__container--full[data-entering=true]{--tw-enter-translate-y: 0% }}.modal__container--full[data-exiting=true]{--tw-exit-scale:1}.modal__dialog{background-color:var(--overlay);--tw-shadow:var(--overlay-shadow);width:100%;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;border-radius:min(32px,var(--radius-3xl));padding:calc(var(--spacing) * 6);pointer-events:auto;outline-style:none;flex-direction:column;display:flex;position:relative}.modal__dialog[data-placement=auto]{margin-top:auto}@media(min-width:40rem){.modal__dialog[data-placement=auto]{margin-block:auto}}.modal__dialog[data-placement=center]{margin-block:auto}.modal__dialog[data-placement=bottom]{margin-top:auto}.modal__dialog[data-placement=top]{margin-top:0}.modal__dialog--scroll-inside{min-height:0;max-height:100%;overflow:clip}.modal__dialog--scroll-outside{flex-shrink:0;height:auto;min-height:0}.modal__dialog--xs{max-width:var(--container-xs)}.modal__dialog--sm{max-width:var(--container-sm)}.modal__dialog--md{max-width:var(--container-md)}.modal__dialog--lg{max-width:var(--container-lg)}.modal__dialog--cover{width:100%;height:100%;min-height:100%}.modal__dialog--full{--tw-shadow:0 0 #0000;width:100%;height:100%;min-height:100%;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);border-radius:0}.modal__header{gap:calc(var(--spacing) * 3);flex-direction:column;margin-bottom:0;display:flex}.modal__header>.modal__icon{margin-bottom:0}.modal__heading{vertical-align:middle;font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--foreground)}.modal__icon{width:calc(var(--spacing) * 10);height:calc(var(--spacing) * 10);border-radius:calc(var(--radius) * 3);-webkit-user-select:none;user-select:none;flex-shrink:0;justify-content:center;align-items:center;display:flex}.modal__body{min-height:0;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-leading:1.43;color:var(--muted);margin:-3px;flex:1;margin-block:0;padding:3px;line-height:1.43;overflow:visible}.modal__body--scroll-inside{scrollbar-width:var(--scrollbar-width);scrollbar-color:var(--scrollbar-color);scrollbar-gutter:var(--scrollbar-gutter);overscroll-behavior:contain;-webkit-overflow-scrolling:touch;overflow-y:auto}.modal__body--scroll-outside{overflow-y:visible}.modal__footer{justify-content:flex-end;align-items:center;gap:calc(var(--spacing) * 2);flex-direction:row;margin-top:0;display:flex}.modal__close-trigger{top:calc(var(--spacing) * 4);right:calc(var(--spacing) * 4);position:absolute}.modal__header+.modal__body{margin-top:calc(var(--spacing) * 2)}.modal__header+.modal__footer,.modal__body+.modal__footer{margin-top:calc(var(--spacing) * 5)}.popover{transform-origin:var(--trigger-anchor-point);background-color:var(--overlay);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));border-radius:min(32px,var(--radius-3xl));box-shadow:var(--shadow-overlay);padding:0}.popover[data-entering=true]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.15s;--tw-ease:ease;--tw-enter-opacity:0;--tw-enter-scale:.9;transition-duration:.15s;transition-timing-function:ease}.popover[data-entering=true][data-placement=top]{--tw-enter-translate-y:calc(1*var(--spacing))}.popover[data-entering=true][data-placement=bottom]{--tw-enter-translate-y:calc(1*var(--spacing)*-1)}.popover[data-entering=true][data-placement=left]{--tw-enter-translate-x:calc(1*var(--spacing))}.popover[data-entering=true][data-placement=right]{--tw-enter-translate-x:calc(1*var(--spacing)*-1)}.popover[data-exiting=true]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.1s;--tw-ease:ease;--tw-exit-scale:.95;--tw-exit-opacity:0;transition-duration:.1s;transition-timing-function:ease}.popover[data-exiting=true],.popover[data-entering=true]{transition-property:opacity,transform;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));will-change:opacity,transform}.popover [data-slot=popover-overlay-arrow]{fill:var(--overlay)}.popover[data-placement=bottom] [data-slot=popover-overlay-arrow]{rotate:180deg}.popover[data-placement=left] [data-slot=popover-overlay-arrow]{rotate:-90deg}.popover[data-placement=right] [data-slot=popover-overlay-arrow]{rotate:90deg}.popover__dialog{padding:calc(var(--spacing) * 4);--tw-outline-style:none;outline-style:none}.popover__heading{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.popover__trigger{transition:color .15s var(--ease-smooth),background-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out);display:inline-block}.popover__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *),.popover__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.popover__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.popover__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.popover__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.popover__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.popover__trigger{cursor:var(--cursor-interactive)}.popover__trigger:focus-visible:not(:focus),.popover__trigger[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.popover__trigger:disabled,.popover__trigger[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.tooltip{max-width:var(--container-xs);transform-origin:var(--trigger-anchor-point);background-color:var(--overlay);padding:calc(var(--spacing) * 2);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));word-break:break-all;border-radius:min(32px,var(--radius-xl));box-shadow:var(--shadow-overlay)}.tooltip[data-entering=true]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.15s;--tw-ease:ease;--tw-enter-opacity:0;--tw-enter-scale:.9;transition-duration:.15s;transition-timing-function:ease}.tooltip[data-entering=true][data-placement=top]{--tw-enter-translate-y:calc(1*var(--spacing))}.tooltip[data-entering=true][data-placement=bottom]{--tw-enter-translate-y:calc(1*var(--spacing)*-1)}.tooltip[data-entering=true][data-placement=left]{--tw-enter-translate-x:calc(1*var(--spacing))}.tooltip[data-entering=true][data-placement=right]{--tw-enter-translate-x:calc(1*var(--spacing)*-1)}.tooltip[data-exiting=true]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.1s;--tw-ease:ease;--tw-exit-scale:.95;--tw-exit-opacity:0;transition-duration:.1s;transition-timing-function:ease}.tooltip[data-exiting=true],.tooltip[data-entering=true]{transition-property:opacity,transform;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));will-change:opacity,transform}.tooltip [data-slot=overlay-arrow]{stroke:var(--border)}@supports (color:color-mix(in lab,red,red)){.tooltip [data-slot=overlay-arrow]{stroke:color-mix(in oklab,var(--border) 40%,transparent)}}.tooltip [data-slot=overlay-arrow]{fill:var(--overlay)}.tooltip[data-placement=bottom] [data-slot=overlay-arrow]{rotate:180deg}.tooltip[data-placement=left] [data-slot=overlay-arrow]{rotate:-90deg}.tooltip[data-placement=right] [data-slot=overlay-arrow]{rotate:90deg}.tooltip__trigger{transition:color .15s var(--ease-smooth),background-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out);display:inline-block}.tooltip__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *),.tooltip__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.tooltip__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.tooltip__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.tooltip__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.tooltip__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.tooltip__trigger:focus-visible:not(:focus),.tooltip__trigger[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.combo-box{gap:var(--spacing);flex-direction:column;display:flex}:is(.combo-box[data-invalid=true],.combo-box[aria-invalid=true]) [data-slot=description]{display:none}.combo-box [data-slot=label]{width:fit-content}.combo-box [data-slot=input]{flex:1;min-width:0}.combo-box [data-slot=input]:has(+.combo-box__trigger){padding-inline-end:calc(var(--spacing) * 7)}.combo-box [data-slot=input]:focus,.combo-box [data-slot=input][data-focus]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-outline-style:none;--tw-ring-offset-width:0px;border-color:var(--field-border-focus);background-color:var(--field-focus);outline-style:none}.combo-box [data-slot=input]:disabled,.combo-box [data-slot=input][data-disabled],.combo-box [data-slot=input][aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.combo-box__input-group{isolation:isolate;align-items:center;display:inline-flex;position:relative}.combo-box__trigger{--tw-translate-y: -50% ;height:100%;translate:var(--tw-translate-x) var(--tw-translate-y);cursor:pointer;color:var(--field-placeholder,var(--muted));transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.15s;-webkit-tap-highlight-color:transparent;--tw-border-style:none;--tw-outline-style:none;inset-inline-end:calc(var(--spacing) * 0);background-color:#0000;border-style:none;outline-style:none;flex-shrink:0;justify-content:center;align-items:center;padding-inline-end:calc(var(--spacing) * 2);transition-duration:.15s;display:flex;position:absolute;top:50%}@media(hover:hover){.combo-box__trigger:hover,.combo-box__trigger[data-hovered=true]{color:var(--field-foreground,var(--foreground))}}.combo-box__trigger:focus-visible:not(:focus),.combo-box__trigger[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;border-radius:.25rem;outline-style:none}.combo-box__trigger[data-pressed=true]{opacity:.7}.combo-box__trigger:disabled,.combo-box__trigger[data-disabled],.combo-box__trigger[aria-disabled=true]{cursor:not-allowed;opacity:.5}.combo-box__trigger [data-slot=combo-box-trigger-default-icon]{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4);transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.15s;transition-duration:.15s}.combo-box__trigger [data-slot=combo-box-trigger-default-icon]:is([data-reduce-motion=true],[data-reduce-motion=true] *),.combo-box__trigger [data-slot=combo-box-trigger-default-icon]:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.combo-box__trigger [data-slot=combo-box-trigger-default-icon]:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.combo-box__trigger [data-slot=combo-box-trigger-default-icon]:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.combo-box__trigger [data-slot=combo-box-trigger-default-icon]:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.combo-box__trigger [data-slot=combo-box-trigger-default-icon]:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.combo-box__trigger[data-open=true] [data-slot=combo-box-trigger-default-icon]{rotate:180deg}.combo-box__popover{min-width:var(--trigger-width);transform-origin:var(--trigger-anchor-point);scroll-padding-block:var(--spacing);scrollbar-width:var(--scrollbar-width);scrollbar-color:var(--scrollbar-color);scrollbar-gutter:var(--scrollbar-gutter);overscroll-behavior:contain;background-color:var(--overlay);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));border-radius:min(32px,var(--radius-3xl));box-shadow:var(--shadow-overlay);padding:0;overflow-y:auto}.combo-box__popover:focus-visible:not(:focus),.combo-box__popover[data-focus-visible=true]{--tw-outline-style:none;outline-style:none}.combo-box__popover[data-entering=true]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.15s;--tw-ease:ease;--tw-enter-opacity:0;--tw-enter-scale:.95;transition-duration:.15s;transition-timing-function:ease}.combo-box__popover[data-entering=true][data-placement=top]{--tw-enter-translate-y:calc(1*var(--spacing))}.combo-box__popover[data-entering=true][data-placement=bottom]{--tw-enter-translate-y:calc(1*var(--spacing)*-1)}.combo-box__popover[data-entering=true][data-placement=left]{--tw-enter-translate-x:calc(1*var(--spacing))}.combo-box__popover[data-entering=true][data-placement=right]{--tw-enter-translate-x:calc(1*var(--spacing)*-1)}.combo-box__popover[data-exiting=true]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.1s;--tw-ease:ease;--tw-exit-scale:.95;--tw-exit-opacity:0;transition-duration:.1s;transition-timing-function:ease}.combo-box__popover[data-exiting=true],.combo-box__popover[data-entering=true]{transition-property:opacity,transform;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));will-change:opacity,transform}.combo-box__popover [data-slot=popover-overlay-arrow]{fill:var(--overlay)}.combo-box__popover[data-placement=bottom] [data-slot=popover-overlay-arrow]{rotate:180deg}.combo-box__popover[data-placement=left] [data-slot=popover-overlay-arrow]{rotate:-90deg}.combo-box__popover[data-placement=right] [data-slot=popover-overlay-arrow]{rotate:90deg}.combo-box__popover [data-slot=list-box]{padding:calc(var(--spacing) * 1.5);--tw-outline-style:none;outline-style:none}.combo-box__popover [data-slot=list-box-item]{padding-inline:calc(var(--spacing) * 2.5)}.combo-box__popover [data-slot=list-box-item] [data-slot=list-box-item-indicator--checkmark]{transition-property:none}.combo-box--full-width,.combo-box__input-group--full-width{width:100%}.select{gap:var(--spacing);flex-direction:column;display:flex}:is(.select[data-invalid=true],.select[aria-invalid=true]) [data-slot=description]{display:none}.select [data-slot=label]{width:fit-content}.select__trigger{isolation:isolate;min-height:calc(var(--spacing) * 9);border-radius:var(--field-radius,calc(var(--radius) * 1.5));border-style:var(--tw-border-style);background-color:var(--field-background,var(--default));padding-inline:calc(var(--spacing) * 3);padding-block:calc(var(--spacing) * 2);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--field-foreground,var(--foreground));--tw-shadow:var(--field-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;transition:background-color .15s var(--ease-smooth),border-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out);border-width:1px;outline-style:none;display:inline-flex;position:relative}.select__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *),.select__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.select__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.select__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.select__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.select__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.select__trigger{cursor:var(--cursor-interactive);border-width:var(--border-width-field);border-color:var(--field-border)}.select__trigger:has(.select__indicator){padding-inline-end:calc(var(--spacing) * 7)}@media(hover:hover){.select__trigger:hover,.select__trigger[data-hovered=true]{background-color:var(--field-hover);border-color:var(--field-border-hover)}}.select__trigger:focus-visible:not(:focus),.select__trigger[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;border-color:var(--field-border-focus);background-color:var(--field-focus);outline-style:none}.select[data-invalid=true] .select__trigger,.select[aria-invalid=true] .select__trigger{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}:is(.select[data-invalid=true] .select__trigger,.select[aria-invalid=true] .select__trigger):focus,:is(.select[data-invalid=true] .select__trigger,.select[aria-invalid=true] .select__trigger):focus-visible,:is(.select[data-invalid=true] .select__trigger,.select[aria-invalid=true] .select__trigger)[data-focused=true],:is(.select[data-invalid=true] .select__trigger,.select[aria-invalid=true] .select__trigger)[data-focus-visible=true],:is(.select[data-invalid=true] .select__trigger,.select[aria-invalid=true] .select__trigger):focus-within,:is(.select[data-invalid=true] .select__trigger,.select[aria-invalid=true] .select__trigger)[data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.select[data-invalid=true] .select__trigger,.select[aria-invalid=true] .select__trigger{background-color:var(--field-focus)}.select__trigger:disabled,.select__trigger[data-disabled=true],.select__trigger[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.select--secondary .select__trigger{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);background-color:var(--select-trigger-bg);--select-trigger-bg:var(--default);--select-trigger-bg-hover:var(--default-hover);--select-trigger-bg-focus:var(--default)}@media(hover:hover){.select--secondary .select__trigger:hover,.select--secondary .select__trigger[data-hovered=true]{background-color:var(--select-trigger-bg-hover)}}.select--secondary .select__trigger:focus-visible:not(:focus),.select--secondary .select__trigger[data-focus-visible=true],.select[data-invalid=true] :is(.select--secondary .select__trigger),.select[aria-invalid=true] :is(.select--secondary .select__trigger){background-color:var(--select-trigger-bg-focus)}.select__value{text-align:start;font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));overflow-wrap:break-word;color:currentColor;flex:1}@media(min-width:40rem){.select__value{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}.select__value[data-placeholder=true]{color:var(--field-placeholder,var(--muted))}.select__value [data-slot=list-box-item-indicator]{display:none}.select__indicator{color:var(--field-placeholder,var(--muted));transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.15s;flex-shrink:0;justify-content:center;align-items:center;margin-block:auto;transition-duration:.15s;display:flex;position:absolute;inset-block:0;inset-inline-end:calc(var(--spacing) * 2)}.select__indicator[data-open=true]{rotate:180deg}.select__indicator[data-slot=select-default-indicator]{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.select__popover{min-width:var(--trigger-width);transform-origin:var(--trigger-anchor-point);scroll-padding-block:var(--spacing);scrollbar-width:var(--scrollbar-width);scrollbar-color:var(--scrollbar-color);scrollbar-gutter:var(--scrollbar-gutter);overscroll-behavior:contain;background-color:var(--overlay);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));border-radius:min(32px,var(--radius-3xl));box-shadow:var(--shadow-overlay);padding:0;overflow-y:auto}.select__popover:focus-visible:not(:focus),.select__popover[data-focus-visible=true]{--tw-outline-style:none;outline-style:none}.select__popover[data-entering=true]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.15s;--tw-ease:ease;--tw-enter-opacity:0;--tw-enter-scale:.95;transition-duration:.15s;transition-timing-function:ease}.select__popover[data-entering=true][data-placement=top]{--tw-enter-translate-y:calc(1*var(--spacing))}.select__popover[data-entering=true][data-placement=bottom]{--tw-enter-translate-y:calc(1*var(--spacing)*-1)}.select__popover[data-entering=true][data-placement=left]{--tw-enter-translate-x:calc(1*var(--spacing))}.select__popover[data-entering=true][data-placement=right]{--tw-enter-translate-x:calc(1*var(--spacing)*-1)}.select__popover[data-exiting=true]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.1s;--tw-ease:ease;--tw-exit-scale:.95;--tw-exit-opacity:0;transition-duration:.1s;transition-timing-function:ease}.select__popover[data-exiting=true],.select__popover[data-entering=true]{transition-property:opacity,transform;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));will-change:opacity,transform}.select__popover [data-slot=popover-overlay-arrow]{fill:var(--overlay)}.select__popover[data-placement=bottom] [data-slot=popover-overlay-arrow]{rotate:180deg}.select__popover[data-placement=left] [data-slot=popover-overlay-arrow]{rotate:-90deg}.select__popover[data-placement=right] [data-slot=popover-overlay-arrow]{rotate:90deg}.select__popover [data-slot=list-box]{padding:calc(var(--spacing) * 1.5);--tw-outline-style:none;outline-style:none}.select__popover [data-slot=list-box-item]{padding-inline:calc(var(--spacing) * 2.5)}.select__popover [data-slot=list-box]:not([aria-multiselectable=true]) [data-slot=list-box-item-indicator],.select__popover [data-slot=list-box]:not([aria-multiselectable=true]) [data-slot=list-box-item-indicator] [data-slot=list-box-item-indicator--checkmark]{transition-property:none}.select--full-width,.select__trigger--full-width{width:100%}.autocomplete{gap:var(--spacing);flex-direction:column;display:flex}.autocomplete__trigger{isolation:isolate;min-height:calc(var(--spacing) * 9);border-radius:var(--field-radius,calc(var(--radius) * 1.5));border-style:var(--tw-border-style);background-color:var(--field-background,var(--default));padding-inline:calc(var(--spacing) * 3);padding-block:calc(var(--spacing) * 2);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--field-foreground,var(--foreground));--tw-shadow:var(--field-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;transition:background-color .15s var(--ease-smooth),border-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out);border-width:1px;outline-style:none;display:inline-flex;position:relative}.autocomplete__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *),.autocomplete__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.autocomplete__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.autocomplete__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.autocomplete__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.autocomplete__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.autocomplete__trigger{cursor:var(--cursor-interactive);border-width:var(--border-width-field);border-color:var(--field-border)}.autocomplete__trigger:has(.autocomplete__indicator){padding-inline-end:calc(var(--spacing) * 7)}@media(hover:hover){.autocomplete__trigger:hover:not(:has(.autocomplete__clear-button:hover)),.autocomplete__trigger[data-hovered=true]:not(:has(.autocomplete__clear-button:hover)){background-color:var(--field-hover);border-color:var(--field-border-hover)}}.autocomplete__trigger:focus-visible:not(:focus),.autocomplete__trigger[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;border-color:var(--field-border-focus);background-color:var(--field-focus);outline-style:none}.autocomplete[data-invalid=true] .autocomplete__trigger,.autocomplete[aria-invalid=true] .autocomplete__trigger{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}:is(.autocomplete[data-invalid=true] .autocomplete__trigger,.autocomplete[aria-invalid=true] .autocomplete__trigger):focus,:is(.autocomplete[data-invalid=true] .autocomplete__trigger,.autocomplete[aria-invalid=true] .autocomplete__trigger):focus-visible,:is(.autocomplete[data-invalid=true] .autocomplete__trigger,.autocomplete[aria-invalid=true] .autocomplete__trigger)[data-focused=true],:is(.autocomplete[data-invalid=true] .autocomplete__trigger,.autocomplete[aria-invalid=true] .autocomplete__trigger)[data-focus-visible=true],:is(.autocomplete[data-invalid=true] .autocomplete__trigger,.autocomplete[aria-invalid=true] .autocomplete__trigger):focus-within,:is(.autocomplete[data-invalid=true] .autocomplete__trigger,.autocomplete[aria-invalid=true] .autocomplete__trigger)[data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.autocomplete[data-invalid=true] .autocomplete__trigger,.autocomplete[aria-invalid=true] .autocomplete__trigger{background-color:var(--field-focus)}.autocomplete__trigger:disabled,.autocomplete__trigger[data-disabled=true],.autocomplete__trigger[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.autocomplete--secondary .autocomplete__trigger{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);background-color:var(--autocomplete-trigger-bg);--autocomplete-trigger-bg:var(--default);--autocomplete-trigger-bg-hover:var(--default-hover);--autocomplete-trigger-bg-focus:var(--default)}@media(hover:hover){.autocomplete--secondary .autocomplete__trigger:hover:not(:has(.autocomplete__clear-button:hover)),.autocomplete--secondary .autocomplete__trigger[data-hovered=true]:not(:has(.autocomplete__clear-button:hover)){background-color:var(--autocomplete-trigger-bg-hover)}}.autocomplete--secondary .autocomplete__trigger:focus-visible:not(:focus),.autocomplete--secondary .autocomplete__trigger[data-focus-visible=true],.autocomplete[data-invalid=true] :is(.autocomplete--secondary .autocomplete__trigger),.autocomplete[aria-invalid=true] :is(.autocomplete--secondary .autocomplete__trigger){background-color:var(--autocomplete-trigger-bg-focus)}.autocomplete__value{text-align:start;font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));overflow-wrap:break-word;color:currentColor;flex:1}@media(min-width:40rem){.autocomplete__value{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}.autocomplete__value[data-placeholder=true]{color:var(--field-placeholder,var(--muted))}.autocomplete__value [data-slot=list-box-item-indicator]{display:none}.autocomplete__indicator{color:var(--field-placeholder,var(--muted));transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.15s;cursor:var(--cursor-interactive);flex-shrink:0;justify-content:center;align-items:center;margin-block:auto;transition-duration:.15s;display:flex;position:absolute;inset-block:0;inset-inline-end:calc(var(--spacing) * 2)}.autocomplete__indicator[data-open=true]{rotate:180deg}.autocomplete__indicator[data-slot=autocomplete-default-indicator]{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.autocomplete__popover{width:var(--trigger-width);max-width:var(--trigger-width);transform-origin:var(--trigger-anchor-point);scroll-padding-block:var(--spacing);overscroll-behavior:contain;background-color:var(--overlay);padding:0;padding-top:calc(var(--spacing) * 2);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));border-radius:min(32px,var(--radius-3xl));box-shadow:var(--shadow-overlay);overflow:hidden}.autocomplete__popover:focus-visible:not(:focus),.autocomplete__popover[data-focus-visible=true]{--tw-outline-style:none;outline-style:none}.autocomplete__popover[data-entering=true]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.25s;--tw-ease:cubic-bezier(.32, .72, 0, 1);--tw-enter-opacity:0;--tw-enter-scale:.95;transition-duration:.25s;transition-timing-function:cubic-bezier(.32,.72,0,1)}.autocomplete__popover[data-entering=true][data-placement=top]{--tw-enter-translate-y:calc(1*var(--spacing))}.autocomplete__popover[data-entering=true][data-placement=bottom]{--tw-enter-translate-y:calc(1*var(--spacing)*-1)}.autocomplete__popover[data-entering=true][data-placement=left]{--tw-enter-translate-x:calc(1*var(--spacing))}.autocomplete__popover[data-entering=true][data-placement=right]{--tw-enter-translate-x:calc(1*var(--spacing)*-1)}.autocomplete__popover[data-exiting=true]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.1s;--tw-ease:cubic-bezier(.25, .46, .45, .94);--tw-exit-scale:.95;--tw-exit-opacity:0;transition-duration:.1s;transition-timing-function:cubic-bezier(.25,.46,.45,.94)}.autocomplete__popover[data-exiting=true],.autocomplete__popover[data-entering=true]{transition-property:opacity,transform;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));will-change:opacity,transform}.autocomplete__popover [data-slot=popover-overlay-arrow]{fill:var(--overlay)}.autocomplete__popover[data-placement=bottom] [data-slot=popover-overlay-arrow]{rotate:180deg}.autocomplete__popover[data-placement=left] [data-slot=popover-overlay-arrow]{rotate:-90deg}.autocomplete__popover[data-placement=right] [data-slot=popover-overlay-arrow]{rotate:90deg}.autocomplete__popover [data-slot=list-box]{scrollbar-width:var(--scrollbar-width);scrollbar-color:var(--scrollbar-color);scrollbar-gutter:var(--scrollbar-gutter);max-height:320px;padding:calc(var(--spacing) * 1.5);--tw-outline-style:none;outline-style:none;overflow-y:auto}.autocomplete__popover [data-slot=list-box-item]{padding-inline:calc(var(--spacing) * 2.5)}.autocomplete__popover [data-slot=list-box]:not([aria-multiselectable=true]) [data-slot=list-box-item-indicator],.autocomplete__popover [data-slot=list-box]:not([aria-multiselectable=true]) [data-slot=list-box-item-indicator] [data-slot=list-box-item-indicator--checkmark]{transition-property:none}.autocomplete__popover [data-slot=search-field]{padding-inline:calc(var(--spacing) * 3);padding-block:var(--spacing);--tw-outline-style:none;outline-style:none}.autocomplete__popover [data-slot=empty-state]{text-align:center;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--overlay-foreground)}@supports (color:color-mix(in lab,red,red)){.autocomplete__popover [data-slot=empty-state]{color:color-mix(in oklab,var(--overlay-foreground) 60%,transparent)}}.autocomplete__popover-dialog,.autocomplete__popover-dialog:focus,.autocomplete__popover-dialog:focus-visible,.autocomplete__popover-dialog[data-focus-visible=true]{--tw-outline-style:none;outline-style:none}.autocomplete--full-width,.autocomplete__trigger--full-width{width:100%}.autocomplete__clear-button{isolation:isolate;height:calc(var(--spacing) * 6);width:calc(var(--spacing) * 6);transform-origin:50%;border-radius:calc(var(--radius) * 1.5);padding:var(--spacing);color:var(--muted);-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5);cursor:var(--cursor-interactive);transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);background-color:#0000;flex-shrink:0;justify-content:center;align-self:center;align-items:center;margin-inline-end:0;display:inline-flex;position:relative}.autocomplete__clear-button:not([data-empty=true]){transition:opacity .15s var(--ease-smooth)}.autocomplete__clear-button:not([data-empty=true]):is([data-reduce-motion=true],[data-reduce-motion=true] *),.autocomplete__clear-button:not([data-empty=true]):is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.autocomplete__clear-button:not([data-empty=true]):is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.autocomplete__clear-button:not([data-empty=true]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.autocomplete__clear-button:not([data-empty=true]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.autocomplete__clear-button:not([data-empty=true]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.autocomplete__clear-button[data-empty=true]{pointer-events:none;opacity:0}.autocomplete__clear-button [data-slot=autocomplete-clear-button-icon]{width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5)}@media(hover:hover){.autocomplete__clear-button:hover,.autocomplete__clear-button[data-hovered=true]{background-color:var(--default-hover)}}.autocomplete__clear-button:active,.autocomplete__clear-button[data-pressed=true]{transform:scale(.93)}.kbd{height:calc(var(--spacing) * 6);align-items:center;display:inline-flex}:where(.kbd>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing) * .5) * var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing) * .5) * calc(1 - var(--tw-space-x-reverse)))}.kbd{border-radius:calc(var(--radius) * 1);background-color:var(--default);padding-inline:calc(var(--spacing) * 2);text-align:center;font-family:var(--font-sans);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);white-space:nowrap;color:var(--muted)}:where(.kbd:where(:dir(rtl),[dir=rtl],[dir=rtl] *)>:not(:last-child)){--tw-space-x-reverse:1}.kbd{word-spacing:-.25rem}.kbd__abbr{justify-content:center;align-items:center;width:100%;height:100%;text-decoration:none;display:flex}.kbd__content{justify-content:center;align-items:center;display:flex}.kbd--light{background-color:#0000}.typography,.typography-prose{color:var(--foreground)}.typography-prose h1{font-size:var(--text-4xl);line-height:var(--tw-leading,var(--text-4xl--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.typography-prose h2{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.typography-prose h3{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.typography-prose h4{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.typography-prose h5{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.typography-prose h6{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.typography-prose p{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-leading:calc(var(--spacing) * 7);line-height:calc(var(--spacing) * 7)}.typography-prose code{border-radius:calc(var(--radius) * .75);background-color:var(--default);padding-inline:calc(var(--spacing) * 1.5);padding-block:calc(var(--spacing) * .5);font-family:var(--font-mono);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--foreground)}.typography-prose a{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--link);text-underline-offset:4px;text-decoration-line:underline}.typography-prose blockquote{margin-top:calc(var(--spacing) * 4);border-left-style:var(--tw-border-style);border-left-width:4px;border-color:var(--border);padding-left:calc(var(--spacing) * 4);color:var(--muted);font-style:italic}.typography-prose ul{margin-block:calc(var(--spacing) * 4);list-style-type:disc}:where(.typography-prose ul>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}.typography-prose ul{padding-left:calc(var(--spacing) * 6)}.typography-prose ol{margin-block:calc(var(--spacing) * 4);list-style-type:decimal}:where(.typography-prose ol>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}.typography-prose ol{padding-left:calc(var(--spacing) * 6)}.typography-prose li{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-leading:calc(var(--spacing) * 7);line-height:calc(var(--spacing) * 7)}.typography-prose hr{margin-block:calc(var(--spacing) * 8);border-color:var(--separator)}.typography-prose pre{margin-block:calc(var(--spacing) * 4);border-radius:calc(var(--radius) * 1.5);background-color:var(--default);padding:calc(var(--spacing) * 4);font-family:var(--font-mono);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed);overflow-x:auto}.typography-prose strong{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);color:var(--foreground)}.typography-prose em{font-style:italic}.typography-prose img{margin-block:calc(var(--spacing) * 4);border-radius:calc(var(--radius) * 1.5)}.typography--h1{font-size:var(--text-4xl);line-height:var(--tw-leading,var(--text-4xl--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.typography--h2{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.typography--h3{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.typography--h4{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.typography--h5{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.typography--h6{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.typography--body{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-leading:calc(var(--spacing) * 7);line-height:calc(var(--spacing) * 7)}.typography--body-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-leading:calc(var(--spacing) * 6);line-height:calc(var(--spacing) * 6)}.typography--body-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));--tw-leading:calc(var(--spacing) * 5);line-height:calc(var(--spacing) * 5)}.typography--code{border-radius:calc(var(--radius) * .75);background-color:var(--default);padding-inline:calc(var(--spacing) * 1.5);padding-block:calc(var(--spacing) * .5);font-family:var(--font-mono);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--foreground)}.typography--align-start{text-align:left}.typography--align-start:where(:dir(rtl),[dir=rtl],[dir=rtl] *){text-align:right}.typography--align-center{text-align:center}.typography--align-end{text-align:right}.typography--align-end:where(:dir(rtl),[dir=rtl],[dir=rtl] *){text-align:left}.typography--align-justify{text-align:justify}.typography--color-default{color:var(--foreground)}.typography--color-muted{color:var(--muted)}.typography--truncate{text-overflow:ellipsis;white-space:nowrap;display:block;overflow:hidden}.typography--weight-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.typography--weight-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.typography--weight-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.typography--weight-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.scroll-shadow{--scroll-shadow-size:40px;--scroll-shadow-scrollbar-size:10px;position:relative}.scroll-shadow--vertical{scrollbar-width:var(--scrollbar-width);scrollbar-color:var(--scrollbar-color);scrollbar-gutter:var(--scrollbar-gutter);overflow-y:auto}.scroll-shadow--horizontal{scrollbar-width:var(--scrollbar-width);scrollbar-color:var(--scrollbar-color);scrollbar-gutter:var(--scrollbar-gutter);overflow-x:auto}.scroll-shadow--fade.scroll-shadow--vertical:where([data-top-scroll=true],[data-bottom-scroll=true],[data-top-bottom-scroll=true]){mask-image:linear-gradient(var(--scroll-linear-gradient)),linear-gradient(#000,#000);mask-position:0 0,100% 0;mask-repeat:no-repeat;mask-size:calc(100% - var(--scroll-shadow-scrollbar-size)) 100%,var(--scroll-shadow-scrollbar-size) 100%;-webkit-mask-image:linear-gradient(var(--scroll-linear-gradient)),linear-gradient(#000,#000);-webkit-mask-position:0 0,100% 0;-webkit-mask-repeat:no-repeat;-webkit-mask-size:calc(100% - var(--scroll-shadow-scrollbar-size)) 100%,var(--scroll-shadow-scrollbar-size) 100%}.scroll-shadow--fade.scroll-shadow--vertical[data-top-scroll=true]{--scroll-linear-gradient:0deg, #000 calc(100% - var(--scroll-shadow-size)), transparent}.scroll-shadow--fade.scroll-shadow--vertical[data-bottom-scroll=true]{--scroll-linear-gradient:180deg, #000 calc(100% - var(--scroll-shadow-size)), transparent}.scroll-shadow--fade.scroll-shadow--vertical[data-top-bottom-scroll=true]{--scroll-linear-gradient:#000, #000, transparent 0, #000 var(--scroll-shadow-size), #000 calc(100% - var(--scroll-shadow-size)), transparent}.scroll-shadow--fade.scroll-shadow--horizontal:where([data-left-scroll=true],[data-right-scroll=true],[data-left-right-scroll=true]){mask-image:linear-gradient(var(--scroll-linear-gradient)),linear-gradient(#000,#000);mask-position:0 0,0 100%;mask-repeat:no-repeat;mask-size:100% calc(100% - var(--scroll-shadow-scrollbar-size)),100% var(--scroll-shadow-scrollbar-size);-webkit-mask-image:linear-gradient(var(--scroll-linear-gradient)),linear-gradient(#000,#000);-webkit-mask-position:0 0,0 100%;-webkit-mask-repeat:no-repeat;-webkit-mask-size:100% calc(100% - var(--scroll-shadow-scrollbar-size)),100% var(--scroll-shadow-scrollbar-size)}.scroll-shadow--fade.scroll-shadow--horizontal[data-left-scroll=true]{--scroll-linear-gradient:270deg, #000 calc(100% - var(--scroll-shadow-size)), transparent}.scroll-shadow--fade.scroll-shadow--horizontal[data-right-scroll=true]{--scroll-linear-gradient:90deg, #000 calc(100% - var(--scroll-shadow-size)), transparent}.scroll-shadow--fade.scroll-shadow--horizontal[data-left-right-scroll=true]{--scroll-linear-gradient:to right, #000, #000, transparent 0, #000 var(--scroll-shadow-size), #000 calc(100% - var(--scroll-shadow-size)), transparent}.scroll-shadow--hide-scrollbar{scrollbar-color:auto;scrollbar-gutter:auto;-ms-overflow-style:none;scrollbar-width:none;--scroll-shadow-scrollbar-size:0px}}@layer utilities{.pointer-events-auto{pointer-events:auto}.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.inset-0{top:0;right:0;bottom:0;left:0}.inset-x-0{inset-inline:0}.top-0{top:0}.top-4{top:calc(var(--spacing) * 4)}.top-full{top:100%}.-right-3{right:calc(var(--spacing) * -3)}.right-0{right:0}.right-4{right:calc(var(--spacing) * 4)}.bottom-4{bottom:calc(var(--spacing) * 4)}.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:30}.z-50{z-index:50}.container{width:100%}@media(min-width:40rem){.container{max-width:40rem}}@media(min-width:48rem){.container{max-width:48rem}}@media(min-width:64rem){.container{max-width:64rem}}@media(min-width:80rem){.container{max-width:80rem}}@media(min-width:96rem){.container{max-width:96rem}}.mx-1{margin-inline:var(--spacing)}.mx-2{margin-inline:calc(var(--spacing) * 2)}.mx-3{margin-inline:calc(var(--spacing) * 3)}.mx-auto{margin-inline:auto}.-mt-1{margin-top:calc(var(--spacing) * -1)}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:var(--spacing)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-auto{margin-top:auto}.-mr-1{margin-right:calc(var(--spacing) * -1)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.ml-auto{margin-left:auto}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.h-1{height:var(--spacing)}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-2{height:calc(var(--spacing) * 2)}.h-3\.5{height:calc(var(--spacing) * 3.5)}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-7{height:calc(var(--spacing) * 7)}.h-12{height:calc(var(--spacing) * 12)}.h-48{height:calc(var(--spacing) * 48)}.h-full{height:100%}.max-h-48{max-height:calc(var(--spacing) * 48)}.max-h-60{max-height:calc(var(--spacing) * 60)}.max-h-72{max-height:calc(var(--spacing) * 72)}.max-h-\[90vh\]{max-height:90vh}.min-h-0{min-height:0}.min-h-full{min-height:100%}.w-1\.5{width:calc(var(--spacing) * 1.5)}.w-2{width:calc(var(--spacing) * 2)}.w-3\.5{width:calc(var(--spacing) * 3.5)}.w-4{width:calc(var(--spacing) * 4)}.w-5{width:calc(var(--spacing) * 5)}.w-6{width:calc(var(--spacing) * 6)}.w-7{width:calc(var(--spacing) * 7)}.w-11{width:calc(var(--spacing) * 11)}.w-12{width:calc(var(--spacing) * 12)}.w-28{width:calc(var(--spacing) * 28)}.w-56{width:calc(var(--spacing) * 56)}.w-64{width:calc(var(--spacing) * 64)}.w-72{width:calc(var(--spacing) * 72)}.w-fit{width:fit-content}.w-full{width:100%}.w-px{width:1px}.max-w-2xl{max-width:var(--container-2xl)}.max-w-3xl{max-width:var(--container-3xl)}.max-w-40{max-width:calc(var(--spacing) * 40)}.max-w-44{max-width:calc(var(--spacing) * 44)}.max-w-\[1800px\]{max-width:1800px}.max-w-md{max-width:var(--container-md)}.max-w-sm{max-width:var(--container-sm)}.max-w-xs{max-width:var(--container-xs)}.min-w-0{min-width:0}.min-w-\[140px\]{min-width:140px}.min-w-\[180px\]{min-width:180px}.flex-1{flex:1}.shrink-0{flex-shrink:0}.table-fixed{table-layout:fixed}.border-collapse{border-collapse:collapse}.translate-x-0\.5{--tw-translate-x:calc(var(--spacing) * .5);translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-x-5{--tw-translate-x:calc(var(--spacing) * 5);translate:var(--tw-translate-x) var(--tw-translate-y)}.rotate-180{rotate:180deg}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.cursor-col-resize{cursor:col-resize}.cursor-pointer{cursor:pointer}.touch-none{touch-action:none}.resize{resize:both}.resize-none{resize:none}.list-disc{list-style-type:disc}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-row-reverse{flex-direction:row-reverse}.flex-wrap{flex-wrap:wrap}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-0\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:var(--spacing)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-5{gap:calc(var(--spacing) * 5)}.gap-6{gap:calc(var(--spacing) * 6)}.gap-x-4{column-gap:calc(var(--spacing) * 4)}.gap-y-1\.5{row-gap:calc(var(--spacing) * 1.5)}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-\[var\(--otari-line\)\]>:not(:last-child)){border-color:var(--otari-line)}.self-start{align-self:flex-start}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-\[inherit\]{border-radius:inherit}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:calc(var(--radius) * 1)}.rounded-md{border-radius:calc(var(--radius) * .75)}.rounded-xl{border-radius:calc(var(--radius) * 1.5)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l-4{border-left-style:var(--tw-border-style);border-left-width:4px}.border-\[\#c2843a\]{border-color:#c2843a}.border-\[var\(--otari-brand\)\]{border-color:var(--otari-brand)}.border-\[var\(--otari-line\)\]{border-color:var(--otari-line)}.border-amber-200{border-color:var(--color-amber-200)}.border-emerald-200{border-color:var(--color-emerald-200)}.border-green-200{border-color:var(--color-green-200)}.border-red-200{border-color:var(--color-red-200)}.border-l-amber-500{border-left-color:var(--color-amber-500)}.border-l-emerald-500{border-left-color:var(--color-emerald-500)}.border-l-red-500{border-left-color:var(--color-red-500)}.bg-\[var\(--otari-bg\)\]{background-color:var(--otari-bg)}.bg-\[var\(--otari-brand\)\]{background-color:var(--otari-brand)}.bg-\[var\(--otari-brand-tint\)\]{background-color:var(--otari-brand-tint)}.bg-\[var\(--otari-line\)\]{background-color:var(--otari-line)}.bg-\[var\(--otari-surface\)\]{background-color:var(--otari-surface)}.bg-amber-50{background-color:var(--color-amber-50)}.bg-black\/40{background-color:#0006}@supports (color:color-mix(in lab,red,red)){.bg-black\/40{background-color:color-mix(in oklab,var(--color-black) 40%,transparent)}}.bg-emerald-50{background-color:var(--color-emerald-50)}.bg-green-50{background-color:var(--color-green-50)}.bg-green-500{background-color:var(--color-green-500)}.bg-red-50{background-color:var(--color-red-50)}.bg-red-500{background-color:var(--color-red-500)}.bg-transparent{background-color:#0000}.bg-white{background-color:var(--color-white)}.p-1{padding:var(--spacing)}.p-2{padding:calc(var(--spacing) * 2)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.p-6{padding:calc(var(--spacing) * 6)}.p-7{padding:calc(var(--spacing) * 7)}.px-0{padding-inline:0}.px-1{padding-inline:var(--spacing)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.px-6{padding-inline:calc(var(--spacing) * 6)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:var(--spacing)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-6{padding-block:calc(var(--spacing) * 6)}.py-10{padding-block:calc(var(--spacing) * 10)}.pt-0\.5{padding-top:calc(var(--spacing) * .5)}.pt-1{padding-top:var(--spacing)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-3{padding-top:calc(var(--spacing) * 3)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pr-1\.5{padding-right:calc(var(--spacing) * 1.5)}.pr-4{padding-right:calc(var(--spacing) * 4)}.pb-1{padding-bottom:var(--spacing)}.pl-4{padding-left:calc(var(--spacing) * 4)}.pl-5{padding-left:calc(var(--spacing) * 5)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.align-middle{vertical-align:middle}.font-mono{font-family:var(--font-mono)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.leading-5{--tw-leading:calc(var(--spacing) * 5);line-height:calc(var(--spacing) * 5)}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.whitespace-normal{white-space:normal}.whitespace-nowrap{white-space:nowrap}.whitespace-pre{white-space:pre}.whitespace-pre-wrap{white-space:pre-wrap}.text-\[\#b45309\]{color:#b45309}.text-\[var\(--otari-brand-dark\)\]{color:var(--otari-brand-dark)}.text-\[var\(--otari-ink\)\]{color:var(--otari-ink)}.text-\[var\(--otari-muted\)\]{color:var(--otari-muted)}.text-amber-400{color:var(--color-amber-400)}.text-amber-700{color:var(--color-amber-700)}.text-amber-800{color:var(--color-amber-800)}.text-amber-900{color:var(--color-amber-900)}.text-emerald-700{color:var(--color-emerald-700)}.text-green-700{color:var(--color-green-700)}.text-red-700{color:var(--color-red-700)}.normal-case{text-transform:none}.uppercase{text-transform:uppercase}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.underline{text-decoration-line:underline}.underline-offset-2{text-underline-offset:2px}.accent-\[var\(--otari-brand\)\]{accent-color:var(--otari-brand)}.opacity-0{opacity:0}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a), 0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a), 0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.transition-\[width\]{transition-property:width;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-150{--tw-duration:.15s;transition-duration:.15s}.select-none{-webkit-user-select:none;user-select:none}.running{animation-play-state:running}.group-focus-within\:opacity-100:is(:where(.group):focus-within *){opacity:1}@media(hover:hover){.group-hover\:w-0\.5:is(:where(.group):hover *){width:calc(var(--spacing) * .5)}.group-hover\:bg-\[var\(--otari-brand\)\]:is(:where(.group):hover *){background-color:var(--otari-brand)}.group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}}.last\:border-b-0:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}@media(hover:hover){.hover\:border-\[var\(--otari-brand\)\]:hover{border-color:var(--otari-brand)}.hover\:bg-\[var\(--otari-bg\)\]:hover{background-color:var(--otari-bg)}.hover\:bg-\[var\(--otari-brand\)\]:hover{background-color:var(--otari-brand)}.hover\:text-\[var\(--otari-brand\)\]:hover{color:var(--otari-brand)}.hover\:text-\[var\(--otari-brand-dark\)\]:hover{color:var(--otari-brand-dark)}.hover\:text-\[var\(--otari-ink\)\]:hover{color:var(--otari-ink)}.hover\:text-amber-950:hover{color:var(--color-amber-950)}.hover\:text-red-700:hover{color:var(--color-red-700)}.hover\:underline:hover{text-decoration-line:underline}}.focus\:border-\[var\(--otari-brand\)\]:focus{border-color:var(--otari-brand)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.focus-visible\:bg-\[var\(--otari-brand\)\]:focus-visible{background-color:var(--otari-brand)}.focus-visible\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-visible\:ring-\[var\(--otari-brand\)\]:focus-visible{--tw-ring-color:var(--otari-brand)}.focus-visible\:outline-2:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px}.focus-visible\:-outline-offset-2:focus-visible{outline-offset:-2px}.focus-visible\:outline-\[var\(--otari-brand\)\]:focus-visible{outline-color:var(--otari-brand)}.disabled\:opacity-50:disabled{opacity:.5}@media(min-width:40rem){.sm\:col-span-2{grid-column:span 2/span 2}.sm\:col-start-1{grid-column-start:1}.sm\:col-start-2{grid-column-start:2}.sm\:col-start-3{grid-column-start:3}.sm\:w-28{width:calc(var(--spacing) * 28)}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.sm\:grid-cols-\[minmax\(0\,1fr\)_16rem_10rem\]{grid-template-columns:minmax(0,1fr) 16rem 10rem}.sm\:flex-row{flex-direction:row}.sm\:flex-wrap{flex-wrap:wrap}.sm\:items-center{align-items:center}.sm\:items-start{align-items:flex-start}.sm\:justify-self-end{justify-self:flex-end}.sm\:justify-self-start{justify-self:flex-start}}@media(min-width:64rem){.lg\:sticky{position:sticky}.lg\:top-4{top:calc(var(--spacing) * 4)}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lg\:grid-cols-\[minmax\(0\,1fr\)_360px\]{grid-template-columns:minmax(0,1fr) 360px}.lg\:items-start{align-items:flex-start}}@media(min-width:80rem){.xl\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}}@property --tw-animation-delay{syntax:"*";inherits:false;initial-value:0s}@property --tw-animation-direction{syntax:"*";inherits:false;initial-value:normal}@property --tw-animation-duration{syntax:"*";inherits:false}@property --tw-animation-fill-mode{syntax:"*";inherits:false;initial-value:none}@property --tw-animation-iteration-count{syntax:"*";inherits:false;initial-value:1}@property --tw-enter-blur{syntax:"*";inherits:false;initial-value:0}@property --tw-enter-opacity{syntax:"*";inherits:false;initial-value:1}@property --tw-enter-rotate{syntax:"*";inherits:false;initial-value:0}@property --tw-enter-scale{syntax:"*";inherits:false;initial-value:1}@property --tw-enter-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-enter-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-blur{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-opacity{syntax:"*";inherits:false;initial-value:1}@property --tw-exit-rotate{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-scale{syntax:"*";inherits:false;initial-value:1}@property --tw-exit-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-translate-y{syntax:"*";inherits:false;initial-value:0}:root{--otari-brand:#4e8295;--otari-brand-dark:#3c6678;--otari-brand-tint:#eaf1f3;--otari-ink:#14242c;--otari-muted:#5b6b73;--otari-line:#dbe5e8;--otari-surface:#fff;--otari-bg:#f6f9fa}html,body,#root{height:100%}body{background-color:var(--otari-bg);color:var(--otari-ink);margin:0;font-family:ui-sans-serif,system-ui,-apple-system,Segoe UI,Roboto,sans-serif}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-content{syntax:"*";inherits:false;initial-value:""}@property --tw-ease{syntax:"*";inherits:false}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@property --tw-border-spacing-x{syntax:"";inherits:false;initial-value:0}@property --tw-border-spacing-y{syntax:"";inherits:false;initial-value:0}@property --tw-gradient-position{syntax:"*";inherits:false}@property --tw-gradient-from{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:"*";inherits:false}@property --tw-gradient-via-stops{syntax:"*";inherits:false}@property --tw-gradient-from-position{syntax:"";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:"";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:"";inherits:false;initial-value:100%}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-space-x-reverse{syntax:"*";inherits:false;initial-value:0}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{50%{opacity:.5}}@keyframes enter{0%{opacity:var(--tw-enter-opacity,1);transform:translate3d(var(--tw-enter-translate-x,0),var(--tw-enter-translate-y,0),0)scale3d(var(--tw-enter-scale,1),var(--tw-enter-scale,1),var(--tw-enter-scale,1))rotate(var(--tw-enter-rotate,0));filter:blur(var(--tw-enter-blur,0))}}@keyframes exit{to{opacity:var(--tw-exit-opacity,1);transform:translate3d(var(--tw-exit-translate-x,0),var(--tw-exit-translate-y,0),0)scale3d(var(--tw-exit-scale,1),var(--tw-exit-scale,1),var(--tw-exit-scale,1))rotate(var(--tw-exit-rotate,0));filter:blur(var(--tw-exit-blur,0))}}@keyframes caret-blink{0%,70%,to{opacity:1}20%,50%{opacity:0}}@keyframes skeleton{to{transform:translate(200%)}} diff --git a/src/gateway/static/dashboard/assets/index-DHQmS-9o.js b/src/gateway/static/dashboard/assets/index-DAVt9uB3.js similarity index 96% rename from src/gateway/static/dashboard/assets/index-DHQmS-9o.js rename to src/gateway/static/dashboard/assets/index-DAVt9uB3.js index 5b1ad25c..26126668 100644 --- a/src/gateway/static/dashboard/assets/index-DHQmS-9o.js +++ b/src/gateway/static/dashboard/assets/index-DAVt9uB3.js @@ -1,2 +1,2 @@ -const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/ActivityPage-BJQNqIHi.js","assets/tanstack-query-1t81HyiD.js","assets/react-dgEcD0HR.js","assets/Table-CLdjdyTx.js","assets/heroui-BX6JwHY-.js","assets/AliasesPage-C2JIWSiZ.js","assets/Field-HzRk1KDP.js","assets/BudgetsPage-inMAr92N.js","assets/KeysPage-0Svam5tu.js","assets/ModelScopeControl-DTCXvnvU.js","assets/ModelsPage-CN4L8fzW.js","assets/OverviewPage-D4ZtkmU0.js","assets/charts-Cr3Dij9t.js","assets/recharts-CR3TAEof.js","assets/ProvidersPage-CmlcXh68.js","assets/SettingsPage-UC2EHTIR.js","assets/ToolsGuardrailsPage-rcsPeR9V.js","assets/UsagePage-XCUoRhxb.js","assets/UsersPage-EoUcpZFH.js"])))=>i.map(i=>d[i]); -var be=Object.defineProperty;var je=(e,r,s)=>r in e?be(e,r,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[r]=s;var ee=(e,r,s)=>je(e,typeof r!="symbol"?r+"":r,s);import{u as x,j as t,a as v,b as f,k as Q,Q as we,c as Se}from"./tanstack-query-1t81HyiD.js";import{d as ke,r as o,N as ie,O as Pe,H as Ee,e as Ne,f as b,h as Ce}from"./react-dgEcD0HR.js";import{C as I,L as oe,I as le,a as Te,b as _e,B as P,d as L,c as C,T as Ae,e as Le}from"./heroui-BX6JwHY-.js";(function(){const r=document.createElement("link").relList;if(r&&r.supports&&r.supports("modulepreload"))return;for(const n of document.querySelectorAll('link[rel="modulepreload"]'))a(n);new MutationObserver(n=>{for(const l of n)if(l.type==="childList")for(const d of l.addedNodes)d.tagName==="LINK"&&d.rel==="modulepreload"&&a(d)}).observe(document,{childList:!0,subtree:!0});function s(n){const l={};return n.integrity&&(l.integrity=n.integrity),n.referrerPolicy&&(l.referrerPolicy=n.referrerPolicy),n.crossOrigin==="use-credentials"?l.credentials="include":n.crossOrigin==="anonymous"?l.credentials="omit":l.credentials="same-origin",l}function a(n){if(n.ep)return;n.ep=!0;const l=s(n);fetch(n.href,l)}})();var Ie=ke();const qe="modulepreload",Re=function(e){return"/"+e},te={},S=function(r,s,a){let n=Promise.resolve();if(s&&s.length>0){let d=function(h){return Promise.all(h.map(p=>Promise.resolve(p).then(g=>({status:"fulfilled",value:g}),g=>({status:"rejected",reason:g}))))};document.getElementsByTagName("link");const u=document.querySelector("meta[property=csp-nonce]"),y=(u==null?void 0:u.nonce)||(u==null?void 0:u.getAttribute("nonce"));n=d(s.map(h=>{if(h=Re(h),h in te)return;te[h]=!0;const p=h.endsWith(".css"),g=p?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${h}"]${g}`))return;const m=document.createElement("link");if(m.rel=p?"stylesheet":qe,p||(m.as="script"),m.crossOrigin="",m.href=h,y&&m.setAttribute("nonce",y),document.head.appendChild(m),p)return new Promise((c,j)=>{m.addEventListener("load",c),m.addEventListener("error",()=>j(new Error(`Unable to preload CSS for ${h}`)))})}))}function l(d){const u=new Event("vite:preloadError",{cancelable:!0});if(u.payload=d,window.dispatchEvent(u),!u.defaultPrevented)throw d}return n.then(d=>{for(const u of d||[])u.status==="rejected"&&l(u.reason);return r().catch(l)})};class E extends Error{constructor(s,a){super(a);ee(this,"status");this.name="ApiError",this.status=s}}let q=null;function re(e){q=e}async function $(e){try{const r=await e.json();if(typeof r.detail=="string")return r.detail;if(r.detail!=null)return JSON.stringify(r.detail)}catch{}return e.statusText||`Request failed (${e.status})`}async function Oe(e){let r;try{r=await fetch("/v1/auth/session",{method:"POST",headers:{Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify({master_key:e})})}catch{throw new E(0,"Network error: could not reach the gateway.")}if(r.status===401||r.status===403)return!1;if(!r.ok)throw new E(r.status,await $(r));return!0}async function De(){try{await fetch("/v1/auth/session",{method:"DELETE"})}catch{}}async function i(e,r={}){const s=new Headers(r.headers);s.set("Accept","application/json"),r.body!=null&&!s.has("Content-Type")&&s.set("Content-Type","application/json");let a;try{a=await fetch(e,{...r,headers:s})}catch{throw new E(0,"Network error: could not reach the gateway.")}if(a.status===401||a.status===403)throw q==null||q(),new E(a.status,await $(a));if(!a.ok)throw new E(a.status,await $(a));if(a.status!==204)return await a.json()}const z="otari.dashboard.hasSession",ce=o.createContext(null);function Fe(){try{return window.localStorage.getItem(z)==="1"}catch{return!1}}function Me({children:e}){const r=x(),[s,a]=o.useState(Fe),n=o.useCallback(()=>{De(),a(!1),r.clear();try{window.localStorage.removeItem(z)}catch{}},[r]),l=o.useCallback(()=>{r.clear(),a(!0);try{window.localStorage.setItem(z,"1")}catch{}},[r]);o.useEffect(()=>(re(n),()=>re(null)),[n]);const d=o.useMemo(()=>({isAuthenticated:s,login:l,logout:n}),[s,l,n]);return t.jsx(ce.Provider,{value:d,children:e})}function V(){const e=o.useContext(ce);if(!e)throw new Error("useAuth must be used within an AuthProvider");return e}function Ke(e){return e instanceof E&&e.status===0}function Ue(){const e=x(),[r,s]=o.useState(!1);return o.useEffect(()=>{const a=e.getQueryCache(),n=()=>a.getAll().some(l=>l.state.status==="error"&&Ke(l.state.error));return s(n()),a.subscribe(()=>s(n()))},[e]),r}function Be(){return Ue()?t.jsxs("div",{role:"alert","aria-live":"assertive",className:"fixed right-4 bottom-4 z-50 flex max-w-sm items-start gap-2.5 rounded-lg border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700 shadow-lg",children:[t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2","aria-hidden":!0,className:"mt-0.5 h-5 w-5 shrink-0",children:[t.jsx("path",{d:"M12 9v4M12 17h.01",strokeLinecap:"round",strokeLinejoin:"round"}),t.jsx("path",{d:"M10.3 3.9 1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0z",strokeLinejoin:"round"})]}),t.jsxs("span",{children:[t.jsx("strong",{className:"font-semibold",children:"Can’t reach the gateway."})," The backend isn’t responding; data won’t load or save until the connection is restored."]})]}):null}const N="models",O="pricing",ue="settings",de="tool-settings",H="aliases",W="discoverable",G="providers",J="provider-health",me="stored-providers",$e="model-metadata",ze="build",T="keys",_="budgets",fe="users",Y="usage",Qe=6e4,se=60*6e4;function Dt(){return v({queryKey:[N],queryFn:()=>i("/v1/models"),staleTime:6e4})}function Ve(){return v({queryKey:[ze],queryFn:()=>i("/dashboard-build.json"),refetchInterval:Qe,refetchOnWindowFocus:!0,staleTime:0,retry:!1})}function Ft(){return v({queryKey:[W],queryFn:()=>i("/v1/models/discoverable"),staleTime:5*6e4})}function Mt(){return v({queryKey:[G],queryFn:()=>i("/v1/providers"),staleTime:5*6e4})}function Kt(){return v({queryKey:["provider-catalog"],queryFn:()=>i("/v1/providers/catalog"),staleTime:1/0})}function Ut(e){return v({queryKey:["provider-catalog",e],queryFn:()=>i(`/v1/providers/catalog/${encodeURIComponent(e)}`),enabled:e!=="",staleTime:1/0})}function Bt(){return v({queryKey:[J],queryFn:()=>i("/v1/providers/health"),staleTime:se,refetchInterval:se})}function $t(){const e=x();return f({mutationFn:()=>i("/v1/providers/health?refresh=true"),onSuccess:r=>e.setQueryData([J],r)})}function zt(){return v({queryKey:[me],queryFn:()=>i("/v1/provider-credentials"),staleTime:6e4})}function D(e){e.invalidateQueries({queryKey:[me]}),e.invalidateQueries({queryKey:[G]}),e.invalidateQueries({queryKey:[N]}),e.invalidateQueries({queryKey:[W]}),e.invalidateQueries({queryKey:[J]})}function Qt(){const e=x();return f({mutationFn:r=>i("/v1/provider-credentials",{method:"POST",body:JSON.stringify(r)}),onSuccess:()=>D(e)})}function Vt(){const e=x();return f({mutationFn:({instance:r,body:s})=>i(`/v1/provider-credentials/${encodeURIComponent(r)}`,{method:"PATCH",body:JSON.stringify(s)}),onSuccess:()=>D(e)})}function Ht(){const e=x();return f({mutationFn:r=>i(`/v1/provider-credentials/${encodeURIComponent(r)}`,{method:"DELETE"}),onSuccess:()=>D(e)})}function Wt(){const e=x();return f({mutationFn:()=>i("/v1/provider-credentials/reencrypt",{method:"POST"}),onSuccess:()=>D(e)})}function Gt(){return f({mutationFn:e=>i(`/v1/provider-credentials/${encodeURIComponent(e)}/test`,{method:"POST"})})}function Jt(){return f({mutationFn:e=>i("/v1/provider-credentials/test",{method:"POST",body:JSON.stringify(e)})})}function Yt(){return v({queryKey:[$e],queryFn:()=>i("/v1/models/metadata"),staleTime:10*6e4})}function Xt(){return v({queryKey:[H],queryFn:()=>i("/v1/aliases"),staleTime:6e4})}function Zt(){const e=x();return f({mutationFn:r=>i("/v1/aliases",{method:"POST",body:JSON.stringify(r)}),onSuccess:()=>{e.invalidateQueries({queryKey:[H]}),e.invalidateQueries({queryKey:[N]})}})}function er(){const e=x();return f({mutationFn:r=>i(`/v1/aliases/${encodeURIComponent(r)}`,{method:"DELETE"}),onSuccess:()=>{e.invalidateQueries({queryKey:[H]}),e.invalidateQueries({queryKey:[N]})}})}function He(){return v({queryKey:[ue],queryFn:()=>i("/v1/settings"),staleTime:6e4})}function We(){const e=x();return f({mutationFn:r=>i("/v1/settings",{method:"PATCH",body:JSON.stringify(r)}),onSuccess:r=>{e.setQueryData([ue],r),e.invalidateQueries({queryKey:[N]}),e.invalidateQueries({queryKey:[W]})}})}function tr(){return f({mutationFn:()=>i("/v1/settings/master-key/rotate",{method:"POST"})})}function rr(){return v({queryKey:[de],queryFn:()=>i("/v1/tool-settings"),staleTime:6e4})}function sr(){const e=x();return f({mutationFn:r=>i("/v1/tool-settings",{method:"PATCH",body:JSON.stringify(r)}),onSuccess:r=>{e.setQueryData([de],r)}})}function nr(){return f({mutationFn:({service:e,url:r})=>i(`/v1/tool-settings/${encodeURIComponent(e)}/test`,{method:"POST",body:JSON.stringify({url:r})})})}const F=1e3,Ge=100;async function Je(){const e=[];for(let r=0;ri("/v1/pricing",{method:"POST",body:JSON.stringify(r)}),onSuccess:()=>{e.invalidateQueries({queryKey:[O]}),e.invalidateQueries({queryKey:[N]})}})}function or(){const e=x();return f({mutationFn:r=>i(`/v1/pricing/${encodeURIComponent(r)}`,{method:"DELETE"}),onSuccess:()=>{e.invalidateQueries({queryKey:[O]}),e.invalidateQueries({queryKey:[N]})}})}function lr(){return f({mutationFn:()=>i("/v1/pricing/refresh",{method:"POST"})})}function cr(){const e=x();return f({mutationFn:()=>i("/v1/pricing/refresh/confirm",{method:"POST"}),onSuccess:()=>{e.invalidateQueries({queryKey:[O]}),e.invalidateQueries({queryKey:[N]}),e.invalidateQueries({queryKey:[G]})}})}function ur(){return f({mutationFn:()=>i("/v1/pricing/refresh/reject",{method:"POST"})})}const M=1e3,Ye=100;async function Xe(){const e=[];for(let r=0;ri("/v1/keys",{method:"POST",body:JSON.stringify(r)}),onSuccess:()=>void e.invalidateQueries({queryKey:[T]})})}function fr(){const e=x();return f({mutationFn:({id:r,body:s})=>i(`/v1/keys/${encodeURIComponent(r)}`,{method:"PATCH",body:JSON.stringify(s)}),onSuccess:()=>void e.invalidateQueries({queryKey:[T]})})}function hr(){const e=x();return f({mutationFn:r=>i(`/v1/keys/${encodeURIComponent(r)}/rotate`,{method:"POST"}),onSuccess:()=>void e.invalidateQueries({queryKey:[T]})})}function xr(){const e=x();return f({mutationFn:r=>i(`/v1/keys/${encodeURIComponent(r)}`,{method:"DELETE"}),onSuccess:()=>void e.invalidateQueries({queryKey:[T]})})}const K=1e3,Ze=100;async function et(){const e=[];for(let r=0;ri(`/v1/budgets/${encodeURIComponent(e)}/reset-logs`),enabled:e!==null,staleTime:6e4})}function gr(){const e=x();return f({mutationFn:r=>i("/v1/budgets",{method:"POST",body:JSON.stringify(r)}),onSuccess:()=>void e.invalidateQueries({queryKey:[_]})})}function pr(){const e=x();return f({mutationFn:({id:r,body:s})=>i(`/v1/budgets/${encodeURIComponent(r)}`,{method:"PATCH",body:JSON.stringify(s)}),onSuccess:()=>void e.invalidateQueries({queryKey:[_]})})}function br(){const e=x();return f({mutationFn:r=>i(`/v1/budgets/${encodeURIComponent(r)}`,{method:"DELETE"}),onSuccess:()=>void e.invalidateQueries({queryKey:[_]})})}const U=1e3,tt=100;async function rt(){const e=[];for(let r=0;ri("/v1/users",{method:"POST",body:JSON.stringify(r)}),onSuccess:()=>X(e)})}function Sr(){const e=x();return f({mutationFn:({id:r,body:s})=>i(`/v1/users/${encodeURIComponent(r)}`,{method:"PATCH",body:JSON.stringify(s)}),onSuccess:()=>X(e)})}function kr(){const e=x();return f({mutationFn:r=>i(`/v1/users/${encodeURIComponent(r)}`,{method:"DELETE"}),onSuccess:()=>{X(e),e.invalidateQueries({queryKey:[T]})}})}function Z(e){const r=new URLSearchParams;return e.start_date&&r.set("start_date",e.start_date),e.end_date&&r.set("end_date",e.end_date),e.status&&r.set("status",e.status),e.model&&r.set("model",e.model),e.endpoint&&r.set("endpoint",e.endpoint),e.user_id&&r.set("user_id",e.user_id),r}function Pr(e,r,s){return v({queryKey:[Y,"list",e,r,s],queryFn:()=>{const a=Z(e);return a.set("skip",String(r*s)),a.set("limit",String(s)),i(`/v1/usage?${a.toString()}`)},placeholderData:Q,staleTime:1e4})}function Er(e){return v({queryKey:[Y,"count",e],queryFn:()=>i(`/v1/usage/count?${Z(e).toString()}`),placeholderData:Q,staleTime:1e4})}function Nr(e,r,s=!0){return v({queryKey:[Y,"summary",e,r],queryFn:()=>{const a=Z(e);return a.set("bucket",r),i(`/v1/usage/summary?${a.toString()}`)},enabled:s,placeholderData:Q,staleTime:3e4})}function Cr(e){return e==null?"0":new Intl.NumberFormat("en-US").format(e)}function Tr(e){if(e==null)return"$0.00";const r=e!==0&&Math.abs(e)<.01?4:2;return new Intl.NumberFormat("en-US",{style:"currency",currency:"USD",minimumFractionDigits:2,maximumFractionDigits:r}).format(e)}function _r(e){if(e==null)return"—";if(e>=1e6){const r=e/1e6;return`${Number.isInteger(r)?r:r.toFixed(1)}M`}if(e>=1e3){const r=Math.round(e/1e3);return r>=1e3?"1M":`${r}K`}return String(e)}const st=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];function Ar(e){if(!e)return"—";const r=/^(\d{4})-(\d{2})/.exec(e);if(!r)return e;const s=Number(r[2])-1;return s<0||s>11?r[1]:`${st[s]} ${r[1]}`}const nt=new Intl.NumberFormat("en-US",{style:"currency",currency:"USD",maximumFractionDigits:2});function Lr(e){return nt.format(e)}function Ir(e){return e>=1e6?`${(e/1e6).toFixed(1)}M`:e>=1e3?`${(e/1e3).toFixed(1)}k`:String(e)}function at(e){return`${(e*100).toFixed(1)}%`}function qr(e,r){return r===void 0||r===0?null:(e-r)/r}function Rr(e,r=Date.now()){if(!e)return"never";const s=new Date(e);if(Number.isNaN(s.getTime()))return e;const a=Math.round((r-s.getTime())/1e3),n=a<0,l=Math.abs(a),d=[["second",60],["minute",60],["hour",24],["day",30],["month",12],["year",Number.POSITIVE_INFINITY]];let u=l,y="second";for(const[p,g]of d){if(y=p,u0?"▲":e<0?"▼":"•";return t.jsxs("span",{className:"text-[var(--otari-muted)]",children:[r," ",at(Math.abs(e))," vs prev"]})}function it(e){return e instanceof E||e instanceof Error?e.message:"Something went wrong."}function ot({error:e}){return e?t.jsx("div",{role:"alert",className:"rounded-lg border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700",children:it(e)}):null}function lt({tone:e="info",children:r}){const s=e==="warning"?"border-amber-200 bg-amber-50 text-amber-800":"border-[var(--otari-brand)] bg-[var(--otari-brand-tint)] text-[var(--otari-brand-dark)]";return t.jsx("div",{className:`rounded-lg border px-4 py-3 text-sm ${s}`,children:r})}function Fr({title:e,description:r,action:s}){return t.jsxs("div",{className:"flex flex-col gap-3",children:[t.jsxs("div",{children:[t.jsx("h1",{className:"text-xl font-semibold text-[var(--otari-ink)]",children:e}),r?t.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:r}):null]}),s?t.jsx("div",{className:"flex flex-wrap gap-2",children:s}):null]})}function Mr({children:e,confirmLabel:r,onConfirm:s,isPending:a}){const[n,l]=o.useState(!1);return n?t.jsxs("span",{className:"inline-flex items-center gap-1",children:[t.jsx(P,{size:"sm",variant:"danger",isDisabled:a,onPress:s,children:r}),t.jsx(P,{size:"sm",variant:"ghost",isDisabled:a,onPress:()=>l(!1),children:"Cancel"})]}):t.jsx(P,{size:"sm",variant:"danger-soft",onPress:()=>l(!0),children:e})}const ct="rounded-lg border border-[var(--otari-line)] bg-[var(--otari-bg)] px-3 py-2 text-sm text-[var(--otari-ink)] focus:border-[var(--otari-brand)] focus:outline-none";function Kr({id:e,label:r,ariaLabel:s,value:a,onChange:n,options:l,children:d,disabled:u}){const y=o.useId(),h=e??(r?y:void 0),p=t.jsx("select",{id:h,"aria-label":r?void 0:s,value:a,disabled:u,onChange:g=>n(g.target.value),className:ct,children:l?l.map(g=>t.jsx("option",{value:g.value,children:g.label},g.value)):d});return r?t.jsxs("div",{className:"flex flex-col gap-1",children:[t.jsx("label",{htmlFor:h,className:"text-xs font-medium text-[var(--otari-muted)]",children:r}),p]}):p}function Ur({label:e,value:r,onChange:s,options:a,placeholder:n,maxVisible:l=50,allowsCustom:d=!1}){const u=m=>{var c;return((c=a.find(j=>j.value===m))==null?void 0:c.label)??m},[y,h]=o.useState(()=>u(r));o.useEffect(()=>{h(u(r))},[r]);const p=y.trim().toLowerCase(),g=a.filter(m=>!p||m.value.toLowerCase().includes(p)||m.label.toLowerCase().includes(p)).slice(0,l);return t.jsxs(I.Root,{allowsEmptyCollection:!0,allowsCustomValue:d,menuTrigger:"focus",inputValue:y,onInputChange:m=>{h(m),d?s(m.trim()):m.trim()===""&&s("")},onSelectionChange:m=>{m!=null&&s(String(m))},className:"flex flex-col gap-1",children:[t.jsx(oe,{className:"text-xs font-medium text-[var(--otari-muted)]",children:e}),t.jsxs(I.InputGroup,{children:[t.jsx(le,{placeholder:n,autoComplete:"off",onFocus:m=>m.currentTarget.select()}),t.jsx(I.Trigger,{})]}),t.jsx(I.Popover,{children:t.jsx(Te,{items:g,className:"max-h-72 overflow-auto",children:m=>t.jsx(_e,{id:m.value,textValue:m.label,children:m.label})})})]})}function ut(){var l;const e=He(),r=We(),[s,a]=o.useState(!1);return!(((l=e.data)==null?void 0:l.require_pricing)===!0&&e.data.default_pricing===!1)||s?null:t.jsx("div",{className:"shrink-0 px-6 pt-3",children:t.jsx(lt,{tone:"warning",children:t.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[t.jsxs("span",{children:["Requests are rejected until pricing is set (",t.jsx("code",{children:"require_pricing"})," is on). Enable default pricing to meter new models with public rates right away."]}),t.jsxs("span",{className:"flex items-center gap-2",children:[t.jsx(P,{size:"sm",variant:"primary",isDisabled:r.isPending,onPress:()=>r.mutate({default_pricing:!0}),children:r.isPending?"Enabling…":"Enable default pricing"}),t.jsx(P,{size:"sm",variant:"ghost",onPress:()=>a(!0),children:"Dismiss"})]})]})})})}function dt(){const{data:e}=Ve(),r=o.useRef(null);return e&&r.current===null&&(r.current=e.build),e!=null&&r.current!=null&&e.build!==r.current}function mt(){const e=dt(),[r,s]=o.useState(!1);return!e||r?null:t.jsx("div",{className:"pointer-events-none absolute inset-x-0 top-0 z-50 flex justify-center",children:t.jsxs("div",{role:"status",className:"pointer-events-auto mt-1.5 flex items-center gap-3 rounded-full border border-[var(--otari-brand)] bg-[var(--otari-brand-tint)] py-1.5 pr-1.5 pl-4 text-sm text-[var(--otari-brand-dark)] shadow-md",children:[t.jsxs("span",{children:[t.jsx("strong",{className:"font-semibold",children:"An update is available."})," Reloading keeps you signed in."]}),t.jsx(P,{size:"sm",variant:"primary",onPress:()=>window.location.reload(),children:"Update now"}),t.jsx(P,{size:"sm",variant:"ghost",onPress:()=>s(!0),children:"Later"})]})})}const he=200,xe=480,B=240,ft=60,ye="otari.dashboard.sidebarWidth",ve="otari.dashboard.sidebarCollapsed",ae=16,R=e=>Math.min(xe,Math.max(he,e));function ht(){if(typeof window>"u")return B;try{const e=window.localStorage.getItem(ye),r=e?Number.parseInt(e,10):Number.NaN;return Number.isNaN(r)?B:R(r)}catch{return B}}function xt(){if(typeof window>"u")return!1;try{return window.localStorage.getItem(ve)==="1"}catch{return!1}}const yt=[{key:"home"},{key:"observability",label:"Observability"},{key:"catalog",label:"Catalog"},{key:"access",label:"Access"},{key:"system"}],vt=[{to:"/",section:"home",label:"Overview",end:!0,icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("rect",{x:"3.5",y:"3.5",width:"7",height:"7",rx:"1.5",strokeLinejoin:"round"}),t.jsx("rect",{x:"13.5",y:"3.5",width:"7",height:"7",rx:"1.5",strokeLinejoin:"round"}),t.jsx("rect",{x:"3.5",y:"13.5",width:"7",height:"7",rx:"1.5",strokeLinejoin:"round"}),t.jsx("rect",{x:"13.5",y:"13.5",width:"7",height:"7",rx:"1.5",strokeLinejoin:"round"})]})},{to:"/activity",section:"observability",label:"Activity",icon:t.jsx("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:t.jsx("path",{d:"M3 12h4l2.5-6 4 12 2.5-6H21",strokeLinecap:"round",strokeLinejoin:"round"})})},{to:"/usage",section:"observability",label:"Usage",icon:t.jsx("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:t.jsx("path",{d:"M4 20V10M10 20V4M16 20v-7M22 20H2",strokeLinecap:"round",strokeLinejoin:"round"})})},{to:"/providers",section:"catalog",label:"Providers",icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("rect",{x:"3.5",y:"4.5",width:"17",height:"6",rx:"1.5",strokeLinejoin:"round"}),t.jsx("rect",{x:"3.5",y:"13.5",width:"17",height:"6",rx:"1.5",strokeLinejoin:"round"}),t.jsx("path",{d:"M7 7.5h.01M7 16.5h.01",strokeLinecap:"round",strokeLinejoin:"round"})]})},{to:"/users",section:"access",label:"Users",icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("circle",{cx:"9",cy:"8",r:"3.2",strokeLinejoin:"round"}),t.jsx("path",{d:"M3.5 19a5.5 5.5 0 0 1 11 0",strokeLinecap:"round",strokeLinejoin:"round"}),t.jsx("path",{d:"M16 5.2a3.2 3.2 0 0 1 0 5.6M17.5 19a5.5 5.5 0 0 0-3-4.9",strokeLinecap:"round",strokeLinejoin:"round"})]})},{to:"/keys",section:"access",label:"API keys",icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("circle",{cx:"7.5",cy:"15.5",r:"3.5"}),t.jsx("path",{d:"M10 13l7-7M14 5l3 3M16.5 7.5l2-2",strokeLinecap:"round",strokeLinejoin:"round"})]})},{to:"/budgets",section:"access",label:"Budgets",icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("path",{d:"M3 7.5A1.5 1.5 0 0 1 4.5 6H18a1.5 1.5 0 0 1 1.5 1.5V9",strokeLinejoin:"round"}),t.jsx("rect",{x:"3",y:"7.5",width:"18",height:"12",rx:"1.5",strokeLinejoin:"round"}),t.jsx("path",{d:"M16 13.5h.01",strokeLinecap:"round",strokeLinejoin:"round"}),t.jsx("path",{d:"M21 12v3h-3.5a1.5 1.5 0 0 1 0-3H21z",strokeLinejoin:"round"})]})},{to:"/models",section:"catalog",label:"Models",icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("path",{d:"M12 3l8 4.5v9L12 21l-8-4.5v-9L12 3z",strokeLinejoin:"round"}),t.jsx("path",{d:"M12 12l8-4.5M12 12v9M12 12L4 7.5",strokeLinejoin:"round"})]})},{to:"/aliases",section:"catalog",label:"Aliases",icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("path",{d:"M20.6 13.4L13.4 20.6a2 2 0 0 1-2.8 0l-7-7A2 2 0 0 1 3 12.2V5a2 2 0 0 1 2-2h7.2a2 2 0 0 1 1.4.6l7 7a2 2 0 0 1 0 2.8z",strokeLinejoin:"round"}),t.jsx("circle",{cx:"7.5",cy:"7.5",r:"1.5"})]})},{to:"/tools",section:"system",label:"Tools & Guardrails",icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("path",{d:"M14.7 6.3a4 4 0 0 1 5 5l-8.4 8.4a2 2 0 0 1-2.8 0l-2.2-2.2a2 2 0 0 1 0-2.8z",strokeLinejoin:"round"}),t.jsx("path",{d:"M12 9 5 16",strokeLinecap:"round"})]})},{to:"/settings",section:"system",label:"Settings",icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("circle",{cx:"12",cy:"12",r:"3"}),t.jsx("path",{d:"M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z",strokeLinejoin:"round"})]})}];function gt(){const{logout:e}=V(),r=o.useRef(null),[s,a]=o.useState(ht),[n,l]=o.useState(xt),[d,u]=o.useState(!1);o.useEffect(()=>{const c=window.setTimeout(()=>{try{window.localStorage.setItem(ye,String(Math.round(s)))}catch{}},200);return()=>window.clearTimeout(c)},[s]),o.useEffect(()=>{try{window.localStorage.setItem(ve,n?"1":"0")}catch{}},[n]);const y=o.useCallback(c=>{c.preventDefault(),c.currentTarget.setPointerCapture(c.pointerId),u(!0)},[]),h=o.useCallback(c=>{var A;if(!c.currentTarget.hasPointerCapture(c.pointerId))return;const j=((A=r.current)==null?void 0:A.getBoundingClientRect().left)??0;a(R(c.clientX-j))},[]),p=o.useCallback(c=>{c.currentTarget.hasPointerCapture(c.pointerId)&&c.currentTarget.releasePointerCapture(c.pointerId),u(!1)},[]),g=o.useCallback(c=>{c.key==="ArrowLeft"?(c.preventDefault(),a(j=>R(j-ae))):c.key==="ArrowRight"&&(c.preventDefault(),a(j=>R(j+ae)))},[]),m=n?ft:s;return t.jsxs("div",{className:C("relative flex h-full flex-col overflow-hidden",d&&"cursor-col-resize select-none"),children:[t.jsxs("header",{className:"flex shrink-0 items-center justify-between border-b border-[var(--otari-line)] bg-[var(--otari-surface)] px-5 py-3",children:[t.jsxs("div",{className:"flex items-center gap-2.5",children:[t.jsx("img",{src:"/favicon.svg",alt:"",className:"h-7 w-7 shrink-0"}),t.jsx("span",{className:"text-base font-semibold text-[var(--otari-ink)]",children:"Otari"})]}),t.jsx(P,{size:"sm",variant:"outline",onPress:e,"aria-label":"Sign out",children:"Sign out"})]}),t.jsx(mt,{}),t.jsx(Be,{}),t.jsx(ut,{}),t.jsxs("div",{className:"flex min-h-0 flex-1",children:[t.jsxs("aside",{ref:r,style:{width:m},className:C("relative flex shrink-0 flex-col border-r border-[var(--otari-line)] bg-[var(--otari-surface)]",!d&&"transition-[width] duration-150"),children:[t.jsx("button",{type:"button",onClick:()=>l(c=>!c),"aria-label":n?"Expand sidebar":"Collapse sidebar","aria-pressed":n,title:n?"Expand sidebar":"Collapse sidebar",className:"absolute -right-3 top-4 z-30 flex h-6 w-6 items-center justify-center rounded-full border border-[var(--otari-line)] bg-[var(--otari-surface)] text-[var(--otari-muted)] shadow-sm transition-colors hover:border-[var(--otari-brand)] hover:text-[var(--otari-brand-dark)]",children:t.jsx("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",className:C("h-3.5 w-3.5 transition-transform",n&&"rotate-180"),children:t.jsx("path",{d:"M15 6l-6 6 6 6",strokeLinecap:"round",strokeLinejoin:"round"})})}),t.jsx("nav",{className:C("flex flex-col py-4",n?"px-2":"px-3"),children:yt.map((c,j)=>{const A=vt.filter(k=>k.section===c.key);return A.length===0?null:t.jsxs("div",{className:j>0?"mt-4":void 0,children:[!n&&c.label?t.jsx("div",{className:"px-3 pb-1 text-[11px] font-semibold tracking-wider text-[var(--otari-muted)] uppercase",children:c.label}):null,j>0&&(n||!c.label)?t.jsx("div",{className:"mx-1 mb-2 border-t border-[var(--otari-line)]"}):null,t.jsx("div",{className:"flex flex-col gap-1",children:A.map(k=>t.jsxs(ie,{to:k.to,end:k.end,"aria-label":n?k.label:void 0,title:n?k.label:void 0,className:({isActive:pe})=>C("flex items-center rounded-lg py-2 text-sm font-medium transition-colors",n?"justify-center px-0":"gap-3 px-3",pe?"bg-[var(--otari-brand-tint)] text-[var(--otari-brand-dark)]":"text-[var(--otari-muted)] hover:bg-[var(--otari-bg)] hover:text-[var(--otari-ink)]"),children:[k.icon,n?null:k.label]},k.to))})]},c.key)})}),t.jsxs("a",{href:"https://otari.ai",target:"_blank",rel:"noreferrer",title:"otari.ai — the hosted Otari gateway",className:C("mt-auto mb-3 flex items-center rounded-lg py-2 text-xs font-medium text-[var(--otari-muted)] transition-colors hover:bg-[var(--otari-bg)] hover:text-[var(--otari-brand-dark)]",n?"mx-2 justify-center px-0":"mx-3 gap-2 px-3"),children:[t.jsx("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-4 w-4 shrink-0",children:t.jsx("path",{d:"M18 10h-1.26A8 8 0 1 0 9 20h9a5 5 0 0 0 0-10z",strokeLinejoin:"round"})}),n?null:t.jsxs("span",{className:"flex-1",children:["otari.ai ",t.jsx("span",{"aria-hidden":!0,children:"↗"})]})]}),n?null:t.jsx("div",{role:"separator","aria-orientation":"vertical","aria-label":"Resize sidebar","aria-valuenow":Math.round(s),"aria-valuemin":he,"aria-valuemax":xe,tabIndex:0,onPointerDown:y,onPointerMove:h,onPointerUp:p,onKeyDown:g,className:C("absolute top-0 right-0 z-10 h-full w-1.5 cursor-col-resize touch-none transition-colors","hover:bg-[var(--otari-brand)] focus-visible:bg-[var(--otari-brand)] focus:outline-none",d?"bg-[var(--otari-brand)]":"bg-transparent")})]}),t.jsx("main",{className:"flex-1 overflow-y-auto",children:t.jsx("div",{className:"mx-auto flex max-w-[1800px] flex-col gap-6 px-6 py-6",children:t.jsx(Pe,{})})})]})]})}function pt(){const{login:e}=V(),[r,s]=o.useState(""),[a,n]=o.useState(null),[l,d]=o.useState(!1),u=async()=>{const y=r.trim();if(!(!y||l)){d(!0),n(null);try{await Oe(y)?e():n(new Error("Invalid master key."))}catch(h){n(h)}finally{d(!1)}}};return t.jsx("div",{className:"flex min-h-full items-center justify-center p-6",children:t.jsx(L,{className:"w-full max-w-md",children:t.jsxs(L.Content,{className:"flex flex-col gap-5 p-7",children:[t.jsxs("div",{className:"flex flex-col items-center gap-3 text-center",children:[t.jsx("img",{src:"/favicon.svg",alt:"Otari",className:"h-12 w-12"}),t.jsxs("div",{children:[t.jsx("h1",{className:"text-lg font-semibold text-[var(--otari-ink)]",children:"Otari Dashboard"}),t.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:"Sign in with your master key to browse models, set pricing, and manage settings."})]})]}),t.jsxs("form",{className:"flex flex-col gap-4",onSubmit:y=>{y.preventDefault(),u()},children:[t.jsxs(Ae,{value:r,onChange:y=>{s(y),a&&n(null)},type:"password",isRequired:!0,className:"flex flex-col gap-1",children:[t.jsx(oe,{className:"text-sm font-medium text-[var(--otari-ink)]",children:"Master key"}),t.jsx(le,{placeholder:"otari-mk-… or your master key",autoFocus:!0,autoComplete:"off"})]}),t.jsxs("details",{className:"text-xs text-[var(--otari-muted)]",children:[t.jsx("summary",{className:"cursor-pointer font-medium text-[var(--otari-brand-dark)]",children:"First run? Where to find your key"}),t.jsxs("p",{className:"mt-2 leading-relaxed",children:["If you did not set ",t.jsx("code",{children:"OTARI_MASTER_KEY"}),", Otari generated one and printed it to the server logs on startup. Look for the line ",t.jsx("code",{children:"Your master key:"})," (for example, run"," ",t.jsx("code",{children:"docker logs "}),") and paste it above."]})]}),t.jsx(ot,{error:a}),t.jsx(P,{type:"submit",variant:"primary",fullWidth:!0,isDisabled:!r.trim()||l,children:l?"Signing in…":"Sign in"})]}),t.jsx("p",{className:"text-center text-xs text-[var(--otari-muted)]",children:"The key is sent once to this gateway and exchanged for a session cookie; it is never stored in the browser."}),t.jsx("div",{className:"border-t border-[var(--otari-line)] pt-4 text-center",children:t.jsx(Le,{href:"/welcome",className:"text-sm font-medium text-[var(--otari-brand-dark)]",children:"New to Otari? Open the welcome guide"})})]})})})}const bt=o.lazy(async()=>({default:(await S(async()=>{const{ActivityPage:e}=await import("./ActivityPage-BJQNqIHi.js");return{ActivityPage:e}},__vite__mapDeps([0,1,2,3,4]))).ActivityPage})),jt=o.lazy(async()=>({default:(await S(async()=>{const{AliasesPage:e}=await import("./AliasesPage-C2JIWSiZ.js");return{AliasesPage:e}},__vite__mapDeps([5,1,2,6,4,3]))).AliasesPage})),wt=o.lazy(async()=>({default:(await S(async()=>{const{BudgetsPage:e}=await import("./BudgetsPage-inMAr92N.js");return{BudgetsPage:e}},__vite__mapDeps([7,1,2,6,4,3]))).BudgetsPage})),St=o.lazy(async()=>({default:(await S(async()=>{const{KeysPage:e}=await import("./KeysPage-0Svam5tu.js");return{KeysPage:e}},__vite__mapDeps([8,1,2,6,4,9,3]))).KeysPage})),kt=o.lazy(async()=>({default:(await S(async()=>{const{ModelsPage:e}=await import("./ModelsPage-CN4L8fzW.js");return{ModelsPage:e}},__vite__mapDeps([10,1,2,3,4]))).ModelsPage})),Pt=o.lazy(async()=>({default:(await S(async()=>{const{OverviewIndex:e}=await import("./OverviewPage-D4ZtkmU0.js");return{OverviewIndex:e}},__vite__mapDeps([11,1,2,12,13,4,3]))).OverviewIndex})),Et=o.lazy(async()=>({default:(await S(async()=>{const{ProvidersPage:e}=await import("./ProvidersPage-CmlcXh68.js");return{ProvidersPage:e}},__vite__mapDeps([14,1,2,6,4,3]))).ProvidersPage})),Nt=o.lazy(async()=>({default:(await S(async()=>{const{SettingsPage:e}=await import("./SettingsPage-UC2EHTIR.js");return{SettingsPage:e}},__vite__mapDeps([15,1,2,4]))).SettingsPage})),Ct=o.lazy(async()=>({default:(await S(async()=>{const{ToolsGuardrailsPage:e}=await import("./ToolsGuardrailsPage-rcsPeR9V.js");return{ToolsGuardrailsPage:e}},__vite__mapDeps([16,1,2,4]))).ToolsGuardrailsPage})),Tt=o.lazy(async()=>({default:(await S(async()=>{const{UsagePage:e}=await import("./UsagePage-XCUoRhxb.js");return{UsagePage:e}},__vite__mapDeps([17,1,2,12,13,4,3]))).UsagePage})),_t=o.lazy(async()=>({default:(await S(async()=>{const{UsersPage:e}=await import("./UsersPage-EoUcpZFH.js");return{UsersPage:e}},__vite__mapDeps([18,1,2,6,4,9,3]))).UsersPage}));function w(e){return t.jsx(o.Suspense,{fallback:t.jsx("div",{role:"status",children:"Loading page…"}),children:e})}function At(){const{isAuthenticated:e}=V();return e?t.jsx(Ee,{children:t.jsx(Ne,{children:t.jsxs(b,{element:t.jsx(gt,{}),children:[t.jsx(b,{index:!0,element:w(t.jsx(Pt,{}))}),t.jsx(b,{path:"providers",element:w(t.jsx(Et,{}))}),t.jsx(b,{path:"keys",element:w(t.jsx(St,{}))}),t.jsx(b,{path:"users",element:w(t.jsx(_t,{}))}),t.jsx(b,{path:"budgets",element:w(t.jsx(wt,{}))}),t.jsx(b,{path:"activity",element:w(t.jsx(bt,{}))}),t.jsx(b,{path:"usage",element:w(t.jsx(Tt,{}))}),t.jsx(b,{path:"models",element:w(t.jsx(kt,{}))}),t.jsx(b,{path:"aliases",element:w(t.jsx(jt,{}))}),t.jsx(b,{path:"tools",element:w(t.jsx(Ct,{}))}),t.jsx(b,{path:"settings",element:w(t.jsx(Nt,{}))}),t.jsx(b,{path:"*",element:t.jsx(Ce,{to:"/",replace:!0})})]})})}):t.jsx(pt,{})}function Lt({children:e}){const[r]=o.useState(()=>new we({defaultOptions:{queries:{refetchOnWindowFocus:!1,retry:(s,a)=>a instanceof E&&(a.status===401||a.status===403)?!1:s<2}}}));return t.jsx(Se,{client:r,children:t.jsx(Me,{children:e})})}const ge=document.getElementById("root");if(!ge)throw new Error("Root element #root not found");Ie.createRoot(ge).render(t.jsx(o.StrictMode,{children:t.jsx(Lt,{children:t.jsx(At,{})})}));export{Jt as $,Ar as A,He as B,Mr as C,Tr as D,ot as E,Kr as F,ir as G,or as H,lt as I,Mt as J,Bt as K,qr as L,Lr as M,Dr as N,at as O,Fr as P,Rr as Q,zt as R,Or as S,Ht as T,Gt as U,We as V,Vt as W,$t as X,Qt as Y,Ut as Z,Kt as _,Pr as a,lr as a0,cr as a1,ur as a2,tr as a3,Wt as a4,rr as a5,sr as a6,nr as a7,Ir as a8,kr as a9,wr as aa,Er as b,Nr as c,Ur as d,Ft as e,Xt as f,er as g,it as h,Zt as i,yr as j,gr as k,pr as l,br as m,Sr as n,vr as o,dr as p,fr as q,hr as r,xr as s,mr as t,jr as u,Dt as v,ar as w,Yt as x,_r as y,Cr as z}; +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/ActivityPage-Cw34Jlno.js","assets/tanstack-query-1t81HyiD.js","assets/react-dgEcD0HR.js","assets/Table-CLdjdyTx.js","assets/heroui-BX6JwHY-.js","assets/AliasesPage-CCRTl9Co.js","assets/Field-HzRk1KDP.js","assets/BudgetsPage-iAjnK5BF.js","assets/KeysPage-C6eaoTUP.js","assets/ModelScopeControl-CkKcIwGe.js","assets/ModelsPage-DwBDAaxV.js","assets/OverviewPage-B_g2blUc.js","assets/charts-Cr3Dij9t.js","assets/recharts-CR3TAEof.js","assets/ProvidersPage-DhHL_fxe.js","assets/SettingsPage-BPWZBXQE.js","assets/ToolsGuardrailsPage-Zh-JPOxJ.js","assets/UsagePage-Dk-t74Uz.js","assets/UsersPage-D6v_0kF6.js"])))=>i.map(i=>d[i]); +var be=Object.defineProperty;var je=(e,r,s)=>r in e?be(e,r,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[r]=s;var ee=(e,r,s)=>je(e,typeof r!="symbol"?r+"":r,s);import{u as x,j as t,a as v,b as f,k as Q,Q as we,c as Se}from"./tanstack-query-1t81HyiD.js";import{d as ke,r as o,N as ie,O as Pe,H as Ee,e as Ne,f as b,h as Ce}from"./react-dgEcD0HR.js";import{C as I,L as oe,I as le,a as Te,b as _e,B as P,d as L,c as C,T as Ae,e as Le}from"./heroui-BX6JwHY-.js";(function(){const r=document.createElement("link").relList;if(r&&r.supports&&r.supports("modulepreload"))return;for(const n of document.querySelectorAll('link[rel="modulepreload"]'))a(n);new MutationObserver(n=>{for(const l of n)if(l.type==="childList")for(const d of l.addedNodes)d.tagName==="LINK"&&d.rel==="modulepreload"&&a(d)}).observe(document,{childList:!0,subtree:!0});function s(n){const l={};return n.integrity&&(l.integrity=n.integrity),n.referrerPolicy&&(l.referrerPolicy=n.referrerPolicy),n.crossOrigin==="use-credentials"?l.credentials="include":n.crossOrigin==="anonymous"?l.credentials="omit":l.credentials="same-origin",l}function a(n){if(n.ep)return;n.ep=!0;const l=s(n);fetch(n.href,l)}})();var Ie=ke();const qe="modulepreload",Re=function(e){return"/"+e},te={},S=function(r,s,a){let n=Promise.resolve();if(s&&s.length>0){let d=function(h){return Promise.all(h.map(p=>Promise.resolve(p).then(g=>({status:"fulfilled",value:g}),g=>({status:"rejected",reason:g}))))};document.getElementsByTagName("link");const u=document.querySelector("meta[property=csp-nonce]"),y=(u==null?void 0:u.nonce)||(u==null?void 0:u.getAttribute("nonce"));n=d(s.map(h=>{if(h=Re(h),h in te)return;te[h]=!0;const p=h.endsWith(".css"),g=p?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${h}"]${g}`))return;const m=document.createElement("link");if(m.rel=p?"stylesheet":qe,p||(m.as="script"),m.crossOrigin="",m.href=h,y&&m.setAttribute("nonce",y),document.head.appendChild(m),p)return new Promise((c,j)=>{m.addEventListener("load",c),m.addEventListener("error",()=>j(new Error(`Unable to preload CSS for ${h}`)))})}))}function l(d){const u=new Event("vite:preloadError",{cancelable:!0});if(u.payload=d,window.dispatchEvent(u),!u.defaultPrevented)throw d}return n.then(d=>{for(const u of d||[])u.status==="rejected"&&l(u.reason);return r().catch(l)})};class E extends Error{constructor(s,a){super(a);ee(this,"status");this.name="ApiError",this.status=s}}let q=null;function re(e){q=e}async function $(e){try{const r=await e.json();if(typeof r.detail=="string")return r.detail;if(r.detail!=null)return JSON.stringify(r.detail)}catch{}return e.statusText||`Request failed (${e.status})`}async function Oe(e){let r;try{r=await fetch("/v1/auth/session",{method:"POST",headers:{Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify({master_key:e})})}catch{throw new E(0,"Network error: could not reach the gateway.")}if(r.status===401||r.status===403)return!1;if(!r.ok)throw new E(r.status,await $(r));return!0}async function De(){try{await fetch("/v1/auth/session",{method:"DELETE"})}catch{}}async function i(e,r={}){const s=new Headers(r.headers);s.set("Accept","application/json"),r.body!=null&&!s.has("Content-Type")&&s.set("Content-Type","application/json");let a;try{a=await fetch(e,{...r,headers:s})}catch{throw new E(0,"Network error: could not reach the gateway.")}if(a.status===401||a.status===403)throw q==null||q(),new E(a.status,await $(a));if(!a.ok)throw new E(a.status,await $(a));if(a.status!==204)return await a.json()}const z="otari.dashboard.hasSession",ce=o.createContext(null);function Fe(){try{return window.localStorage.getItem(z)==="1"}catch{return!1}}function Me({children:e}){const r=x(),[s,a]=o.useState(Fe),n=o.useCallback(()=>{De(),a(!1),r.clear();try{window.localStorage.removeItem(z)}catch{}},[r]),l=o.useCallback(()=>{r.clear(),a(!0);try{window.localStorage.setItem(z,"1")}catch{}},[r]);o.useEffect(()=>(re(n),()=>re(null)),[n]);const d=o.useMemo(()=>({isAuthenticated:s,login:l,logout:n}),[s,l,n]);return t.jsx(ce.Provider,{value:d,children:e})}function V(){const e=o.useContext(ce);if(!e)throw new Error("useAuth must be used within an AuthProvider");return e}function Ke(e){return e instanceof E&&e.status===0}function Ue(){const e=x(),[r,s]=o.useState(!1);return o.useEffect(()=>{const a=e.getQueryCache(),n=()=>a.getAll().some(l=>l.state.status==="error"&&Ke(l.state.error));return s(n()),a.subscribe(()=>s(n()))},[e]),r}function Be(){return Ue()?t.jsxs("div",{role:"alert","aria-live":"assertive",className:"fixed right-4 bottom-4 z-50 flex max-w-sm items-start gap-2.5 rounded-lg border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700 shadow-lg",children:[t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2","aria-hidden":!0,className:"mt-0.5 h-5 w-5 shrink-0",children:[t.jsx("path",{d:"M12 9v4M12 17h.01",strokeLinecap:"round",strokeLinejoin:"round"}),t.jsx("path",{d:"M10.3 3.9 1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0z",strokeLinejoin:"round"})]}),t.jsxs("span",{children:[t.jsx("strong",{className:"font-semibold",children:"Can’t reach the gateway."})," The backend isn’t responding; data won’t load or save until the connection is restored."]})]}):null}const N="models",O="pricing",ue="settings",de="tool-settings",H="aliases",W="discoverable",G="providers",J="provider-health",me="stored-providers",$e="model-metadata",ze="build",T="keys",_="budgets",fe="users",Y="usage",Qe=6e4,se=60*6e4;function Dt(){return v({queryKey:[N],queryFn:()=>i("/v1/models"),staleTime:6e4})}function Ve(){return v({queryKey:[ze],queryFn:()=>i("/dashboard-build.json"),refetchInterval:Qe,refetchOnWindowFocus:!0,staleTime:0,retry:!1})}function Ft(){return v({queryKey:[W],queryFn:()=>i("/v1/models/discoverable"),staleTime:5*6e4})}function Mt(){return v({queryKey:[G],queryFn:()=>i("/v1/providers"),staleTime:5*6e4})}function Kt(){return v({queryKey:["provider-catalog"],queryFn:()=>i("/v1/providers/catalog"),staleTime:1/0})}function Ut(e){return v({queryKey:["provider-catalog",e],queryFn:()=>i(`/v1/providers/catalog/${encodeURIComponent(e)}`),enabled:e!=="",staleTime:1/0})}function Bt(){return v({queryKey:[J],queryFn:()=>i("/v1/providers/health"),staleTime:se,refetchInterval:se})}function $t(){const e=x();return f({mutationFn:()=>i("/v1/providers/health?refresh=true"),onSuccess:r=>e.setQueryData([J],r)})}function zt(){return v({queryKey:[me],queryFn:()=>i("/v1/provider-credentials"),staleTime:6e4})}function D(e){e.invalidateQueries({queryKey:[me]}),e.invalidateQueries({queryKey:[G]}),e.invalidateQueries({queryKey:[N]}),e.invalidateQueries({queryKey:[W]}),e.invalidateQueries({queryKey:[J]})}function Qt(){const e=x();return f({mutationFn:r=>i("/v1/provider-credentials",{method:"POST",body:JSON.stringify(r)}),onSuccess:()=>D(e)})}function Vt(){const e=x();return f({mutationFn:({instance:r,body:s})=>i(`/v1/provider-credentials/${encodeURIComponent(r)}`,{method:"PATCH",body:JSON.stringify(s)}),onSuccess:()=>D(e)})}function Ht(){const e=x();return f({mutationFn:r=>i(`/v1/provider-credentials/${encodeURIComponent(r)}`,{method:"DELETE"}),onSuccess:()=>D(e)})}function Wt(){const e=x();return f({mutationFn:()=>i("/v1/provider-credentials/reencrypt",{method:"POST"}),onSuccess:()=>D(e)})}function Gt(){return f({mutationFn:e=>i(`/v1/provider-credentials/${encodeURIComponent(e)}/test`,{method:"POST"})})}function Jt(){return f({mutationFn:e=>i("/v1/provider-credentials/test",{method:"POST",body:JSON.stringify(e)})})}function Yt(){return v({queryKey:[$e],queryFn:()=>i("/v1/models/metadata"),staleTime:10*6e4})}function Xt(){return v({queryKey:[H],queryFn:()=>i("/v1/aliases"),staleTime:6e4})}function Zt(){const e=x();return f({mutationFn:r=>i("/v1/aliases",{method:"POST",body:JSON.stringify(r)}),onSuccess:()=>{e.invalidateQueries({queryKey:[H]}),e.invalidateQueries({queryKey:[N]})}})}function er(){const e=x();return f({mutationFn:r=>i(`/v1/aliases/${encodeURIComponent(r)}`,{method:"DELETE"}),onSuccess:()=>{e.invalidateQueries({queryKey:[H]}),e.invalidateQueries({queryKey:[N]})}})}function He(){return v({queryKey:[ue],queryFn:()=>i("/v1/settings"),staleTime:6e4})}function We(){const e=x();return f({mutationFn:r=>i("/v1/settings",{method:"PATCH",body:JSON.stringify(r)}),onSuccess:r=>{e.setQueryData([ue],r),e.invalidateQueries({queryKey:[N]}),e.invalidateQueries({queryKey:[W]})}})}function tr(){return f({mutationFn:()=>i("/v1/settings/master-key/rotate",{method:"POST"})})}function rr(){return v({queryKey:[de],queryFn:()=>i("/v1/tool-settings"),staleTime:6e4})}function sr(){const e=x();return f({mutationFn:r=>i("/v1/tool-settings",{method:"PATCH",body:JSON.stringify(r)}),onSuccess:r=>{e.setQueryData([de],r)}})}function nr(){return f({mutationFn:({service:e,url:r})=>i(`/v1/tool-settings/${encodeURIComponent(e)}/test`,{method:"POST",body:JSON.stringify({url:r})})})}const F=1e3,Ge=100;async function Je(){const e=[];for(let r=0;ri("/v1/pricing",{method:"POST",body:JSON.stringify(r)}),onSuccess:()=>{e.invalidateQueries({queryKey:[O]}),e.invalidateQueries({queryKey:[N]})}})}function or(){const e=x();return f({mutationFn:r=>i(`/v1/pricing/${encodeURIComponent(r)}`,{method:"DELETE"}),onSuccess:()=>{e.invalidateQueries({queryKey:[O]}),e.invalidateQueries({queryKey:[N]})}})}function lr(){return f({mutationFn:()=>i("/v1/pricing/refresh",{method:"POST"})})}function cr(){const e=x();return f({mutationFn:()=>i("/v1/pricing/refresh/confirm",{method:"POST"}),onSuccess:()=>{e.invalidateQueries({queryKey:[O]}),e.invalidateQueries({queryKey:[N]}),e.invalidateQueries({queryKey:[G]})}})}function ur(){return f({mutationFn:()=>i("/v1/pricing/refresh/reject",{method:"POST"})})}const M=1e3,Ye=100;async function Xe(){const e=[];for(let r=0;ri("/v1/keys",{method:"POST",body:JSON.stringify(r)}),onSuccess:()=>void e.invalidateQueries({queryKey:[T]})})}function fr(){const e=x();return f({mutationFn:({id:r,body:s})=>i(`/v1/keys/${encodeURIComponent(r)}`,{method:"PATCH",body:JSON.stringify(s)}),onSuccess:()=>void e.invalidateQueries({queryKey:[T]})})}function hr(){const e=x();return f({mutationFn:r=>i(`/v1/keys/${encodeURIComponent(r)}/rotate`,{method:"POST"}),onSuccess:()=>void e.invalidateQueries({queryKey:[T]})})}function xr(){const e=x();return f({mutationFn:r=>i(`/v1/keys/${encodeURIComponent(r)}`,{method:"DELETE"}),onSuccess:()=>void e.invalidateQueries({queryKey:[T]})})}const K=1e3,Ze=100;async function et(){const e=[];for(let r=0;ri(`/v1/budgets/${encodeURIComponent(e)}/reset-logs`),enabled:e!==null,staleTime:6e4})}function gr(){const e=x();return f({mutationFn:r=>i("/v1/budgets",{method:"POST",body:JSON.stringify(r)}),onSuccess:()=>void e.invalidateQueries({queryKey:[_]})})}function pr(){const e=x();return f({mutationFn:({id:r,body:s})=>i(`/v1/budgets/${encodeURIComponent(r)}`,{method:"PATCH",body:JSON.stringify(s)}),onSuccess:()=>void e.invalidateQueries({queryKey:[_]})})}function br(){const e=x();return f({mutationFn:r=>i(`/v1/budgets/${encodeURIComponent(r)}`,{method:"DELETE"}),onSuccess:()=>void e.invalidateQueries({queryKey:[_]})})}const U=1e3,tt=100;async function rt(){const e=[];for(let r=0;ri("/v1/users",{method:"POST",body:JSON.stringify(r)}),onSuccess:()=>X(e)})}function Sr(){const e=x();return f({mutationFn:({id:r,body:s})=>i(`/v1/users/${encodeURIComponent(r)}`,{method:"PATCH",body:JSON.stringify(s)}),onSuccess:()=>X(e)})}function kr(){const e=x();return f({mutationFn:r=>i(`/v1/users/${encodeURIComponent(r)}`,{method:"DELETE"}),onSuccess:()=>{X(e),e.invalidateQueries({queryKey:[T]})}})}function Z(e){const r=new URLSearchParams;return e.start_date&&r.set("start_date",e.start_date),e.end_date&&r.set("end_date",e.end_date),e.status&&r.set("status",e.status),e.model&&r.set("model",e.model),e.endpoint&&r.set("endpoint",e.endpoint),e.user_id&&r.set("user_id",e.user_id),r}function Pr(e,r,s){return v({queryKey:[Y,"list",e,r,s],queryFn:()=>{const a=Z(e);return a.set("skip",String(r*s)),a.set("limit",String(s)),i(`/v1/usage?${a.toString()}`)},placeholderData:Q,staleTime:1e4})}function Er(e){return v({queryKey:[Y,"count",e],queryFn:()=>i(`/v1/usage/count?${Z(e).toString()}`),placeholderData:Q,staleTime:1e4})}function Nr(e,r,s=!0){return v({queryKey:[Y,"summary",e,r],queryFn:()=>{const a=Z(e);return a.set("bucket",r),i(`/v1/usage/summary?${a.toString()}`)},enabled:s,placeholderData:Q,staleTime:3e4})}function Cr(e){return e==null?"0":new Intl.NumberFormat("en-US").format(e)}function Tr(e){if(e==null)return"$0.00";const r=e!==0&&Math.abs(e)<.01?4:2;return new Intl.NumberFormat("en-US",{style:"currency",currency:"USD",minimumFractionDigits:2,maximumFractionDigits:r}).format(e)}function _r(e){if(e==null)return"—";if(e>=1e6){const r=e/1e6;return`${Number.isInteger(r)?r:r.toFixed(1)}M`}if(e>=1e3){const r=Math.round(e/1e3);return r>=1e3?"1M":`${r}K`}return String(e)}const st=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];function Ar(e){if(!e)return"—";const r=/^(\d{4})-(\d{2})/.exec(e);if(!r)return e;const s=Number(r[2])-1;return s<0||s>11?r[1]:`${st[s]} ${r[1]}`}const nt=new Intl.NumberFormat("en-US",{style:"currency",currency:"USD",maximumFractionDigits:2});function Lr(e){return nt.format(e)}function Ir(e){return e>=1e6?`${(e/1e6).toFixed(1)}M`:e>=1e3?`${(e/1e3).toFixed(1)}k`:String(e)}function at(e){return`${(e*100).toFixed(1)}%`}function qr(e,r){return r===void 0||r===0?null:(e-r)/r}function Rr(e,r=Date.now()){if(!e)return"never";const s=new Date(e);if(Number.isNaN(s.getTime()))return e;const a=Math.round((r-s.getTime())/1e3),n=a<0,l=Math.abs(a),d=[["second",60],["minute",60],["hour",24],["day",30],["month",12],["year",Number.POSITIVE_INFINITY]];let u=l,y="second";for(const[p,g]of d){if(y=p,u0?"▲":e<0?"▼":"•";return t.jsxs("span",{className:"text-[var(--otari-muted)]",children:[r," ",at(Math.abs(e))," vs prev"]})}function it(e){return e instanceof E||e instanceof Error?e.message:"Something went wrong."}function ot({error:e}){return e?t.jsx("div",{role:"alert",className:"rounded-lg border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700",children:it(e)}):null}function lt({tone:e="info",children:r}){const s=e==="warning"?"border-amber-200 bg-amber-50 text-amber-800":"border-[var(--otari-brand)] bg-[var(--otari-brand-tint)] text-[var(--otari-brand-dark)]";return t.jsx("div",{className:`rounded-lg border px-4 py-3 text-sm ${s}`,children:r})}function Fr({title:e,description:r,action:s}){return t.jsxs("div",{className:"flex flex-col gap-3",children:[t.jsxs("div",{children:[t.jsx("h1",{className:"text-xl font-semibold text-[var(--otari-ink)]",children:e}),r?t.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:r}):null]}),s?t.jsx("div",{className:"flex flex-wrap gap-2",children:s}):null]})}function Mr({children:e,confirmLabel:r,onConfirm:s,isPending:a}){const[n,l]=o.useState(!1);return n?t.jsxs("span",{className:"inline-flex items-center gap-1",children:[t.jsx(P,{size:"sm",variant:"danger",isDisabled:a,onPress:s,children:r}),t.jsx(P,{size:"sm",variant:"ghost",isDisabled:a,onPress:()=>l(!1),children:"Cancel"})]}):t.jsx(P,{size:"sm",variant:"danger-soft",onPress:()=>l(!0),children:e})}const ct="rounded-lg border border-[var(--otari-line)] bg-[var(--otari-bg)] px-3 py-2 text-sm text-[var(--otari-ink)] focus:border-[var(--otari-brand)] focus:outline-none";function Kr({id:e,label:r,ariaLabel:s,value:a,onChange:n,options:l,children:d,disabled:u}){const y=o.useId(),h=e??(r?y:void 0),p=t.jsx("select",{id:h,"aria-label":r?void 0:s,value:a,disabled:u,onChange:g=>n(g.target.value),className:ct,children:l?l.map(g=>t.jsx("option",{value:g.value,children:g.label},g.value)):d});return r?t.jsxs("div",{className:"flex flex-col gap-1",children:[t.jsx("label",{htmlFor:h,className:"text-xs font-medium text-[var(--otari-muted)]",children:r}),p]}):p}function Ur({label:e,value:r,onChange:s,options:a,placeholder:n,maxVisible:l=50,allowsCustom:d=!1}){const u=m=>{var c;return((c=a.find(j=>j.value===m))==null?void 0:c.label)??m},[y,h]=o.useState(()=>u(r));o.useEffect(()=>{h(u(r))},[r]);const p=y.trim().toLowerCase(),g=a.filter(m=>!p||m.value.toLowerCase().includes(p)||m.label.toLowerCase().includes(p)).slice(0,l);return t.jsxs(I.Root,{allowsEmptyCollection:!0,allowsCustomValue:d,menuTrigger:"focus",inputValue:y,onInputChange:m=>{h(m),d?s(m.trim()):m.trim()===""&&s("")},onSelectionChange:m=>{m!=null&&s(String(m))},className:"flex flex-col gap-1",children:[t.jsx(oe,{className:"text-xs font-medium text-[var(--otari-muted)]",children:e}),t.jsxs(I.InputGroup,{children:[t.jsx(le,{placeholder:n,autoComplete:"off",onFocus:m=>m.currentTarget.select()}),t.jsx(I.Trigger,{})]}),t.jsx(I.Popover,{children:t.jsx(Te,{items:g,className:"max-h-72 overflow-auto",children:m=>t.jsx(_e,{id:m.value,textValue:m.label,children:m.label})})})]})}function ut(){var l;const e=He(),r=We(),[s,a]=o.useState(!1);return!(((l=e.data)==null?void 0:l.require_pricing)===!0&&e.data.default_pricing===!1)||s?null:t.jsx("div",{className:"shrink-0 px-6 pt-3",children:t.jsx(lt,{tone:"warning",children:t.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[t.jsxs("span",{children:["Requests are rejected until pricing is set (",t.jsx("code",{children:"require_pricing"})," is on). Enable default pricing to meter new models with public rates right away."]}),t.jsxs("span",{className:"flex items-center gap-2",children:[t.jsx(P,{size:"sm",variant:"primary",isDisabled:r.isPending,onPress:()=>r.mutate({default_pricing:!0}),children:r.isPending?"Enabling…":"Enable default pricing"}),t.jsx(P,{size:"sm",variant:"ghost",onPress:()=>a(!0),children:"Dismiss"})]})]})})})}function dt(){const{data:e}=Ve(),r=o.useRef(null);return e&&r.current===null&&(r.current=e.build),e!=null&&r.current!=null&&e.build!==r.current}function mt(){const e=dt(),[r,s]=o.useState(!1);return!e||r?null:t.jsx("div",{className:"pointer-events-none absolute inset-x-0 top-0 z-50 flex justify-center",children:t.jsxs("div",{role:"status",className:"pointer-events-auto mt-1.5 flex items-center gap-3 rounded-full border border-[var(--otari-brand)] bg-[var(--otari-brand-tint)] py-1.5 pr-1.5 pl-4 text-sm text-[var(--otari-brand-dark)] shadow-md",children:[t.jsxs("span",{children:[t.jsx("strong",{className:"font-semibold",children:"An update is available."})," Reloading keeps you signed in."]}),t.jsx(P,{size:"sm",variant:"primary",onPress:()=>window.location.reload(),children:"Update now"}),t.jsx(P,{size:"sm",variant:"ghost",onPress:()=>s(!0),children:"Later"})]})})}const he=200,xe=480,B=240,ft=60,ye="otari.dashboard.sidebarWidth",ve="otari.dashboard.sidebarCollapsed",ae=16,R=e=>Math.min(xe,Math.max(he,e));function ht(){if(typeof window>"u")return B;try{const e=window.localStorage.getItem(ye),r=e?Number.parseInt(e,10):Number.NaN;return Number.isNaN(r)?B:R(r)}catch{return B}}function xt(){if(typeof window>"u")return!1;try{return window.localStorage.getItem(ve)==="1"}catch{return!1}}const yt=[{key:"home"},{key:"observability",label:"Observability"},{key:"catalog",label:"Catalog"},{key:"access",label:"Access"},{key:"system"}],vt=[{to:"/",section:"home",label:"Overview",end:!0,icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("rect",{x:"3.5",y:"3.5",width:"7",height:"7",rx:"1.5",strokeLinejoin:"round"}),t.jsx("rect",{x:"13.5",y:"3.5",width:"7",height:"7",rx:"1.5",strokeLinejoin:"round"}),t.jsx("rect",{x:"3.5",y:"13.5",width:"7",height:"7",rx:"1.5",strokeLinejoin:"round"}),t.jsx("rect",{x:"13.5",y:"13.5",width:"7",height:"7",rx:"1.5",strokeLinejoin:"round"})]})},{to:"/activity",section:"observability",label:"Activity",icon:t.jsx("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:t.jsx("path",{d:"M3 12h4l2.5-6 4 12 2.5-6H21",strokeLinecap:"round",strokeLinejoin:"round"})})},{to:"/usage",section:"observability",label:"Usage",icon:t.jsx("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:t.jsx("path",{d:"M4 20V10M10 20V4M16 20v-7M22 20H2",strokeLinecap:"round",strokeLinejoin:"round"})})},{to:"/providers",section:"catalog",label:"Providers",icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("rect",{x:"3.5",y:"4.5",width:"17",height:"6",rx:"1.5",strokeLinejoin:"round"}),t.jsx("rect",{x:"3.5",y:"13.5",width:"17",height:"6",rx:"1.5",strokeLinejoin:"round"}),t.jsx("path",{d:"M7 7.5h.01M7 16.5h.01",strokeLinecap:"round",strokeLinejoin:"round"})]})},{to:"/users",section:"access",label:"Users",icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("circle",{cx:"9",cy:"8",r:"3.2",strokeLinejoin:"round"}),t.jsx("path",{d:"M3.5 19a5.5 5.5 0 0 1 11 0",strokeLinecap:"round",strokeLinejoin:"round"}),t.jsx("path",{d:"M16 5.2a3.2 3.2 0 0 1 0 5.6M17.5 19a5.5 5.5 0 0 0-3-4.9",strokeLinecap:"round",strokeLinejoin:"round"})]})},{to:"/keys",section:"access",label:"API keys",icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("circle",{cx:"7.5",cy:"15.5",r:"3.5"}),t.jsx("path",{d:"M10 13l7-7M14 5l3 3M16.5 7.5l2-2",strokeLinecap:"round",strokeLinejoin:"round"})]})},{to:"/budgets",section:"access",label:"Budgets",icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("path",{d:"M3 7.5A1.5 1.5 0 0 1 4.5 6H18a1.5 1.5 0 0 1 1.5 1.5V9",strokeLinejoin:"round"}),t.jsx("rect",{x:"3",y:"7.5",width:"18",height:"12",rx:"1.5",strokeLinejoin:"round"}),t.jsx("path",{d:"M16 13.5h.01",strokeLinecap:"round",strokeLinejoin:"round"}),t.jsx("path",{d:"M21 12v3h-3.5a1.5 1.5 0 0 1 0-3H21z",strokeLinejoin:"round"})]})},{to:"/models",section:"catalog",label:"Models",icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("path",{d:"M12 3l8 4.5v9L12 21l-8-4.5v-9L12 3z",strokeLinejoin:"round"}),t.jsx("path",{d:"M12 12l8-4.5M12 12v9M12 12L4 7.5",strokeLinejoin:"round"})]})},{to:"/aliases",section:"catalog",label:"Aliases",icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("path",{d:"M20.6 13.4L13.4 20.6a2 2 0 0 1-2.8 0l-7-7A2 2 0 0 1 3 12.2V5a2 2 0 0 1 2-2h7.2a2 2 0 0 1 1.4.6l7 7a2 2 0 0 1 0 2.8z",strokeLinejoin:"round"}),t.jsx("circle",{cx:"7.5",cy:"7.5",r:"1.5"})]})},{to:"/tools",section:"system",label:"Tools & Guardrails",icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("path",{d:"M14.7 6.3a4 4 0 0 1 5 5l-8.4 8.4a2 2 0 0 1-2.8 0l-2.2-2.2a2 2 0 0 1 0-2.8z",strokeLinejoin:"round"}),t.jsx("path",{d:"M12 9 5 16",strokeLinecap:"round"})]})},{to:"/settings",section:"system",label:"Settings",icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("circle",{cx:"12",cy:"12",r:"3"}),t.jsx("path",{d:"M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z",strokeLinejoin:"round"})]})}];function gt(){const{logout:e}=V(),r=o.useRef(null),[s,a]=o.useState(ht),[n,l]=o.useState(xt),[d,u]=o.useState(!1);o.useEffect(()=>{const c=window.setTimeout(()=>{try{window.localStorage.setItem(ye,String(Math.round(s)))}catch{}},200);return()=>window.clearTimeout(c)},[s]),o.useEffect(()=>{try{window.localStorage.setItem(ve,n?"1":"0")}catch{}},[n]);const y=o.useCallback(c=>{c.preventDefault(),c.currentTarget.setPointerCapture(c.pointerId),u(!0)},[]),h=o.useCallback(c=>{var A;if(!c.currentTarget.hasPointerCapture(c.pointerId))return;const j=((A=r.current)==null?void 0:A.getBoundingClientRect().left)??0;a(R(c.clientX-j))},[]),p=o.useCallback(c=>{c.currentTarget.hasPointerCapture(c.pointerId)&&c.currentTarget.releasePointerCapture(c.pointerId),u(!1)},[]),g=o.useCallback(c=>{c.key==="ArrowLeft"?(c.preventDefault(),a(j=>R(j-ae))):c.key==="ArrowRight"&&(c.preventDefault(),a(j=>R(j+ae)))},[]),m=n?ft:s;return t.jsxs("div",{className:C("relative flex h-full flex-col overflow-hidden",d&&"cursor-col-resize select-none"),children:[t.jsxs("header",{className:"flex shrink-0 items-center justify-between border-b border-[var(--otari-line)] bg-[var(--otari-surface)] px-5 py-3",children:[t.jsxs("div",{className:"flex items-center gap-2.5",children:[t.jsx("img",{src:"/favicon.svg",alt:"",className:"h-7 w-7 shrink-0"}),t.jsx("span",{className:"text-base font-semibold text-[var(--otari-ink)]",children:"Otari"})]}),t.jsx(P,{size:"sm",variant:"outline",onPress:e,"aria-label":"Sign out",children:"Sign out"})]}),t.jsx(mt,{}),t.jsx(Be,{}),t.jsx(ut,{}),t.jsxs("div",{className:"flex min-h-0 flex-1",children:[t.jsxs("aside",{ref:r,style:{width:m},className:C("relative flex shrink-0 flex-col border-r border-[var(--otari-line)] bg-[var(--otari-surface)]",!d&&"transition-[width] duration-150"),children:[t.jsx("button",{type:"button",onClick:()=>l(c=>!c),"aria-label":n?"Expand sidebar":"Collapse sidebar","aria-pressed":n,title:n?"Expand sidebar":"Collapse sidebar",className:"absolute -right-3 top-4 z-30 flex h-6 w-6 items-center justify-center rounded-full border border-[var(--otari-line)] bg-[var(--otari-surface)] text-[var(--otari-muted)] shadow-sm transition-colors hover:border-[var(--otari-brand)] hover:text-[var(--otari-brand-dark)]",children:t.jsx("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",className:C("h-3.5 w-3.5 transition-transform",n&&"rotate-180"),children:t.jsx("path",{d:"M15 6l-6 6 6 6",strokeLinecap:"round",strokeLinejoin:"round"})})}),t.jsx("nav",{className:C("flex flex-col py-4",n?"px-2":"px-3"),children:yt.map((c,j)=>{const A=vt.filter(k=>k.section===c.key);return A.length===0?null:t.jsxs("div",{className:j>0?"mt-4":void 0,children:[!n&&c.label?t.jsx("div",{className:"px-3 pb-1 text-[11px] font-semibold tracking-wider text-[var(--otari-muted)] uppercase",children:c.label}):null,j>0&&(n||!c.label)?t.jsx("div",{className:"mx-1 mb-2 border-t border-[var(--otari-line)]"}):null,t.jsx("div",{className:"flex flex-col gap-1",children:A.map(k=>t.jsxs(ie,{to:k.to,end:k.end,"aria-label":n?k.label:void 0,title:n?k.label:void 0,className:({isActive:pe})=>C("flex items-center rounded-lg py-2 text-sm font-medium transition-colors",n?"justify-center px-0":"gap-3 px-3",pe?"bg-[var(--otari-brand-tint)] text-[var(--otari-brand-dark)]":"text-[var(--otari-muted)] hover:bg-[var(--otari-bg)] hover:text-[var(--otari-ink)]"),children:[k.icon,n?null:k.label]},k.to))})]},c.key)})}),t.jsxs("a",{href:"https://otari.ai",target:"_blank",rel:"noreferrer",title:"otari.ai — the hosted Otari gateway",className:C("mt-auto mb-3 flex items-center rounded-lg py-2 text-xs font-medium text-[var(--otari-muted)] transition-colors hover:bg-[var(--otari-bg)] hover:text-[var(--otari-brand-dark)]",n?"mx-2 justify-center px-0":"mx-3 gap-2 px-3"),children:[t.jsx("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-4 w-4 shrink-0",children:t.jsx("path",{d:"M18 10h-1.26A8 8 0 1 0 9 20h9a5 5 0 0 0 0-10z",strokeLinejoin:"round"})}),n?null:t.jsxs("span",{className:"flex-1",children:["otari.ai ",t.jsx("span",{"aria-hidden":!0,children:"↗"})]})]}),n?null:t.jsx("div",{role:"separator","aria-orientation":"vertical","aria-label":"Resize sidebar","aria-valuenow":Math.round(s),"aria-valuemin":he,"aria-valuemax":xe,tabIndex:0,onPointerDown:y,onPointerMove:h,onPointerUp:p,onKeyDown:g,className:C("absolute top-0 right-0 z-10 h-full w-1.5 cursor-col-resize touch-none transition-colors","hover:bg-[var(--otari-brand)] focus-visible:bg-[var(--otari-brand)] focus:outline-none",d?"bg-[var(--otari-brand)]":"bg-transparent")})]}),t.jsx("main",{className:"flex-1 overflow-y-auto",children:t.jsx("div",{className:"mx-auto flex max-w-[1800px] flex-col gap-6 px-6 py-6",children:t.jsx(Pe,{})})})]})]})}function pt(){const{login:e}=V(),[r,s]=o.useState(""),[a,n]=o.useState(null),[l,d]=o.useState(!1),u=async()=>{const y=r.trim();if(!(!y||l)){d(!0),n(null);try{await Oe(y)?e():n(new Error("Invalid master key."))}catch(h){n(h)}finally{d(!1)}}};return t.jsx("div",{className:"flex min-h-full items-center justify-center p-6",children:t.jsx(L,{className:"w-full max-w-md",children:t.jsxs(L.Content,{className:"flex flex-col gap-5 p-7",children:[t.jsxs("div",{className:"flex flex-col items-center gap-3 text-center",children:[t.jsx("img",{src:"/favicon.svg",alt:"Otari",className:"h-12 w-12"}),t.jsxs("div",{children:[t.jsx("h1",{className:"text-lg font-semibold text-[var(--otari-ink)]",children:"Otari Dashboard"}),t.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:"Sign in with your master key to browse models, set pricing, and manage settings."})]})]}),t.jsxs("form",{className:"flex flex-col gap-4",onSubmit:y=>{y.preventDefault(),u()},children:[t.jsxs(Ae,{value:r,onChange:y=>{s(y),a&&n(null)},type:"password",isRequired:!0,className:"flex flex-col gap-1",children:[t.jsx(oe,{className:"text-sm font-medium text-[var(--otari-ink)]",children:"Master key"}),t.jsx(le,{placeholder:"otari-mk-… or your master key",autoFocus:!0,autoComplete:"off"})]}),t.jsxs("details",{className:"text-xs text-[var(--otari-muted)]",children:[t.jsx("summary",{className:"cursor-pointer font-medium text-[var(--otari-brand-dark)]",children:"First run? Where to find your key"}),t.jsxs("p",{className:"mt-2 leading-relaxed",children:["If you did not set ",t.jsx("code",{children:"OTARI_MASTER_KEY"}),", Otari generated one and printed it to the server logs on startup. Look for the line ",t.jsx("code",{children:"Your master key:"})," (for example, run"," ",t.jsx("code",{children:"docker logs "}),") and paste it above."]})]}),t.jsx(ot,{error:a}),t.jsx(P,{type:"submit",variant:"primary",fullWidth:!0,isDisabled:!r.trim()||l,children:l?"Signing in…":"Sign in"})]}),t.jsx("p",{className:"text-center text-xs text-[var(--otari-muted)]",children:"The key is sent once to this gateway and exchanged for a session cookie; it is never stored in the browser."}),t.jsx("div",{className:"border-t border-[var(--otari-line)] pt-4 text-center",children:t.jsx(Le,{href:"/welcome",className:"text-sm font-medium text-[var(--otari-brand-dark)]",children:"New to Otari? Open the welcome guide"})})]})})})}const bt=o.lazy(async()=>({default:(await S(async()=>{const{ActivityPage:e}=await import("./ActivityPage-Cw34Jlno.js");return{ActivityPage:e}},__vite__mapDeps([0,1,2,3,4]))).ActivityPage})),jt=o.lazy(async()=>({default:(await S(async()=>{const{AliasesPage:e}=await import("./AliasesPage-CCRTl9Co.js");return{AliasesPage:e}},__vite__mapDeps([5,1,2,6,4,3]))).AliasesPage})),wt=o.lazy(async()=>({default:(await S(async()=>{const{BudgetsPage:e}=await import("./BudgetsPage-iAjnK5BF.js");return{BudgetsPage:e}},__vite__mapDeps([7,1,2,6,4,3]))).BudgetsPage})),St=o.lazy(async()=>({default:(await S(async()=>{const{KeysPage:e}=await import("./KeysPage-C6eaoTUP.js");return{KeysPage:e}},__vite__mapDeps([8,1,2,6,4,9,3]))).KeysPage})),kt=o.lazy(async()=>({default:(await S(async()=>{const{ModelsPage:e}=await import("./ModelsPage-DwBDAaxV.js");return{ModelsPage:e}},__vite__mapDeps([10,1,2,3,4]))).ModelsPage})),Pt=o.lazy(async()=>({default:(await S(async()=>{const{OverviewIndex:e}=await import("./OverviewPage-B_g2blUc.js");return{OverviewIndex:e}},__vite__mapDeps([11,1,2,12,13,4,3]))).OverviewIndex})),Et=o.lazy(async()=>({default:(await S(async()=>{const{ProvidersPage:e}=await import("./ProvidersPage-DhHL_fxe.js");return{ProvidersPage:e}},__vite__mapDeps([14,1,2,6,4,3]))).ProvidersPage})),Nt=o.lazy(async()=>({default:(await S(async()=>{const{SettingsPage:e}=await import("./SettingsPage-BPWZBXQE.js");return{SettingsPage:e}},__vite__mapDeps([15,1,2,4]))).SettingsPage})),Ct=o.lazy(async()=>({default:(await S(async()=>{const{ToolsGuardrailsPage:e}=await import("./ToolsGuardrailsPage-Zh-JPOxJ.js");return{ToolsGuardrailsPage:e}},__vite__mapDeps([16,1,2,4]))).ToolsGuardrailsPage})),Tt=o.lazy(async()=>({default:(await S(async()=>{const{UsagePage:e}=await import("./UsagePage-Dk-t74Uz.js");return{UsagePage:e}},__vite__mapDeps([17,1,2,12,13,4,3]))).UsagePage})),_t=o.lazy(async()=>({default:(await S(async()=>{const{UsersPage:e}=await import("./UsersPage-D6v_0kF6.js");return{UsersPage:e}},__vite__mapDeps([18,1,2,6,4,9,3]))).UsersPage}));function w(e){return t.jsx(o.Suspense,{fallback:t.jsx("div",{role:"status",children:"Loading page…"}),children:e})}function At(){const{isAuthenticated:e}=V();return e?t.jsx(Ee,{children:t.jsx(Ne,{children:t.jsxs(b,{element:t.jsx(gt,{}),children:[t.jsx(b,{index:!0,element:w(t.jsx(Pt,{}))}),t.jsx(b,{path:"providers",element:w(t.jsx(Et,{}))}),t.jsx(b,{path:"keys",element:w(t.jsx(St,{}))}),t.jsx(b,{path:"users",element:w(t.jsx(_t,{}))}),t.jsx(b,{path:"budgets",element:w(t.jsx(wt,{}))}),t.jsx(b,{path:"activity",element:w(t.jsx(bt,{}))}),t.jsx(b,{path:"usage",element:w(t.jsx(Tt,{}))}),t.jsx(b,{path:"models",element:w(t.jsx(kt,{}))}),t.jsx(b,{path:"aliases",element:w(t.jsx(jt,{}))}),t.jsx(b,{path:"tools",element:w(t.jsx(Ct,{}))}),t.jsx(b,{path:"settings",element:w(t.jsx(Nt,{}))}),t.jsx(b,{path:"*",element:t.jsx(Ce,{to:"/",replace:!0})})]})})}):t.jsx(pt,{})}function Lt({children:e}){const[r]=o.useState(()=>new we({defaultOptions:{queries:{refetchOnWindowFocus:!1,retry:(s,a)=>a instanceof E&&(a.status===401||a.status===403)?!1:s<2}}}));return t.jsx(Se,{client:r,children:t.jsx(Me,{children:e})})}const ge=document.getElementById("root");if(!ge)throw new Error("Root element #root not found");Ie.createRoot(ge).render(t.jsx(o.StrictMode,{children:t.jsx(Lt,{children:t.jsx(At,{})})}));export{Jt as $,Ar as A,He as B,Mr as C,Tr as D,ot as E,Kr as F,ir as G,or as H,lt as I,Mt as J,Bt as K,qr as L,Lr as M,Dr as N,at as O,Fr as P,Rr as Q,zt as R,Or as S,Ht as T,Gt as U,We as V,Vt as W,$t as X,Qt as Y,Ut as Z,Kt as _,Pr as a,lr as a0,cr as a1,ur as a2,tr as a3,Wt as a4,rr as a5,sr as a6,nr as a7,Ir as a8,kr as a9,wr as aa,Er as b,Nr as c,Ur as d,Ft as e,Xt as f,er as g,it as h,Zt as i,yr as j,gr as k,pr as l,br as m,Sr as n,vr as o,dr as p,fr as q,hr as r,xr as s,mr as t,jr as u,Dt as v,ar as w,Yt as x,_r as y,Cr as z}; diff --git a/src/gateway/static/dashboard/index.html b/src/gateway/static/dashboard/index.html index f3c178ed..5010b87d 100644 --- a/src/gateway/static/dashboard/index.html +++ b/src/gateway/static/dashboard/index.html @@ -6,11 +6,11 @@ Otari Dashboard - + - +
diff --git a/web/src/pages/BudgetsPage.test.tsx b/web/src/pages/BudgetsPage.test.tsx index e388d75e..a2ea516f 100644 --- a/web/src/pages/BudgetsPage.test.tsx +++ b/web/src/pages/BudgetsPage.test.tsx @@ -292,6 +292,30 @@ describe("BudgetsPage", () => { expect(JSON.parse(String(post[1]?.body))).toMatchObject({ budget_duration_sec: null }); }); + it("rejects a fractional custom period instead of rounding it up", async () => { + const fetchMock = mockApi({ budgets: [] }); + const user = userEvent.setup(); + renderPage(); + + await user.click(await screen.findByRole("button", { name: "Create your first budget" })); + await user.click(screen.getByRole("button", { name: "Custom" })); + await user.click(screen.getByLabelText("Every N days")); + await user.paste("1.5"); + + // 1.5 is flagged and held unsaved, never silently rounded to 2 days. + expect(await screen.findByText("Enter a whole number of days.")).toBeInTheDocument(); + await user.click(screen.getByRole("button", { name: "Create budget" })); + + const post = await vi.waitFor(() => { + const call = fetchMock.mock.calls.find( + ([url, init]) => String(url).includes("/v1/budgets") && (init?.method ?? "") === "POST", + ); + if (!call) throw new Error("no budget POST"); + return call; + }); + expect(JSON.parse(String(post[1]?.body))).toMatchObject({ budget_duration_sec: null }); + }); + it("creates an unlimited budget when the limit is left blank", async () => { const fetchMock = mockApi({ budgets: [] }); const user = userEvent.setup(); diff --git a/web/src/pages/BudgetsPage.tsx b/web/src/pages/BudgetsPage.tsx index 8e3de79a..8c969c0e 100644 --- a/web/src/pages/BudgetsPage.tsx +++ b/web/src/pages/BudgetsPage.tsx @@ -1,5 +1,5 @@ import { Button, Card, Spinner } from "@heroui/react"; -import { Fragment, useState } from "react"; +import { Fragment, useEffect, useState } from "react"; import { useBudgetResetLogs, @@ -68,7 +68,21 @@ function parseLimit(raw: string): { value: number | null; valid: boolean } { function PeriodPicker({ value, onChange }: { value: number | null; onChange: (seconds: number | null) => void }) { const isPreset = PERIOD_PRESETS.some((p) => p.seconds === value); const [custom, setCustom] = useState(!isPreset); - const customDays = value !== null && value % DAY === 0 ? String(value / DAY) : ""; + const committedDays = value !== null && value % DAY === 0 ? String(value / DAY) : ""; + // A local draft so an in-progress, not-yet-valid entry (e.g. "1.5") stays on + // screen to be flagged, rather than being coerced. Reseed it when the committed + // value changes from outside (a preset click, or editing a different budget). + const [draft, setDraft] = useState(committedDays); + useEffect(() => { + setDraft(committedDays); + }, [committedDays]); + + const trimmedDays = draft.trim(); + const daysValue = Number(trimmedDays); + // Whole days only: a fractional or non-positive entry is rejected outright + // (surfaced below and left unsaved) rather than silently rounded, so 1.5 never + // becomes 2. + const invalidDays = trimmedDays !== "" && (!Number.isInteger(daysValue) || daysValue <= 0); return (
@@ -95,18 +109,22 @@ function PeriodPicker({ value, onChange }: { value: number | null; onChange: (se
{ + setDraft(raw); const n = Number(raw.trim()); - const seconds = Math.round(n) * DAY; - onChange( - raw.trim() === "" || !Number.isFinite(n) || n <= 0 || !Number.isFinite(seconds) || seconds <= 0 - ? null - : seconds, - ); + // Reject a non-integer or non-positive value instead of rounding it; + // it is held as null (unsaved) until the operator types whole days. + onChange(raw.trim() === "" || !Number.isInteger(n) || n <= 0 ? null : n * DAY); }} placeholder="14" - description="Whole days between resets." + description={ + invalidDays ? ( + Enter a whole number of days. + ) : ( + "Whole days between resets." + ) + } />
) : null} diff --git a/web/src/pages/ToolsGuardrailsPage.test.tsx b/web/src/pages/ToolsGuardrailsPage.test.tsx index f0cf2d67..5992b8f9 100644 --- a/web/src/pages/ToolsGuardrailsPage.test.tsx +++ b/web/src/pages/ToolsGuardrailsPage.test.tsx @@ -1,5 +1,5 @@ import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; -import { render, screen } from "@testing-library/react"; +import { render, screen, waitFor } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import type { ReactElement } from "react"; import { afterEach, describe, expect, it, vi } from "vitest"; @@ -115,6 +115,45 @@ describe("ToolsGuardrailsPage", () => { expect(await screen.findByText("reachable (HTTP 200)")).toBeInTheDocument(); }); + it("does not keep a test result against a URL that changed underneath it", async () => { + // Editing the field already drops a stale result (the onChange reset). This + // covers the path that reset does not: the committed URL changing from a + // refetch (e.g. a background refresh, or saving a sibling field) re-seeds the + // input with no keystroke, so a result must be gated on the URL it tested. + const user = userEvent.setup(); + let searxngUrl = "http://searxng:8080"; + vi.spyOn(globalThis, "fetch").mockImplementation(async (input, init) => { + const url = String(input); + const method = (init?.method ?? "GET").toUpperCase(); + if (url.includes("/tool-settings/") && url.endsWith("/test")) { + return jsonResponse({ ok: true, reason: "reachable (HTTP 200)" }); + } + if (url.includes("/v1/tool-settings")) { + // Saving the engines field surfaces a server-changed web_search_url, so + // the next GET re-seeds the URL field without an operator keystroke. + if (method === "PATCH") searxngUrl = "http://searxng:9999"; + return jsonResponse({ + fields: FIELDS.map((f) => (f.key === "web_search_url" ? { ...f, value: searxngUrl } : f)), + }); + } + return jsonResponse([]); + }); + renderWithClient(); + await screen.findByText("Web search"); + + // Test the URL; its result shows while the field still holds the tested URL. + await user.click(screen.getByRole("button", { name: "Test web_search" })); + expect(await screen.findByText("reachable (HTTP 200)")).toBeInTheDocument(); + + // Save a sibling field; the refetch re-seeds web_search_url to a new value. + await user.type(screen.getByLabelText("web_search_engines"), "google"); + await user.click(screen.getByRole("button", { name: "Save web_search_engines" })); + + await waitFor(() => expect(screen.getByLabelText("web_search_url")).toHaveValue("http://searxng:9999")); + // The result belonged to the old URL, so it must no longer be shown. + expect(screen.queryByText("reachable (HTTP 200)")).not.toBeInTheDocument(); + }); + it("shows an inline error under the field when a save is rejected", async () => { mockApi({ patchStatus: 422, patchDetail: "URL must use http or https, got no scheme." }); const user = userEvent.setup(); diff --git a/web/src/pages/ToolsGuardrailsPage.tsx b/web/src/pages/ToolsGuardrailsPage.tsx index c0e95747..665d2baf 100644 --- a/web/src/pages/ToolsGuardrailsPage.tsx +++ b/web/src/pages/ToolsGuardrailsPage.tsx @@ -120,6 +120,10 @@ function UrlRow({ }) { const committed = typeof field.value === "string" ? field.value : ""; const [draft, setDraft] = useState(committed); + // The URL a still-relevant test result belongs to. A pending request for the old + // URL can resolve after the field is edited; only render a result whose URL still + // matches the field, so an outcome is never shown against a different URL. + const [testedUrl, setTestedUrl] = useState(null); const test = useTestService(); useEffect(() => { @@ -128,6 +132,7 @@ function UrlRow({ const changed = draft.trim() !== committed; const trimmed = draft.trim(); + const resultMatches = testedUrl !== null && testedUrl === trimmed; return (
@@ -142,7 +147,8 @@ function UrlRow({ onChange={(event) => { setDraft(event.target.value); // Drop any prior reachability result so a result for the old URL - // never sits beside a newly-typed, untested one. + // never sits beside a newly-typed, untested one. The result render is + // also gated on `resultMatches`, which covers a late-resolving request. test.reset(); }} className={INPUT_CELL} @@ -162,7 +168,10 @@ function UrlRow({ variant="outline" aria-label={`Test ${field.service}`} isDisabled={trimmed === "" || test.isPending} - onPress={() => test.mutate({ service: field.service, url: trimmed })} + onPress={() => { + setTestedUrl(trimmed); + test.mutate({ service: field.service, url: trimmed }); + }} > {test.isPending ? "Testing…" : "Test"} @@ -170,7 +179,7 @@ function UrlRow({
{/* aria-live so the reachability outcome is announced, not just shown. */} - {test.isPending ? null : test.error ? ( + {test.isPending || !resultMatches ? null : test.error ? ( {errorMessage(test.error)} ) : test.data ? ( {test.data.reason} diff --git a/web/src/pages/UsagePage.test.tsx b/web/src/pages/UsagePage.test.tsx index 38112316..ab4e628f 100644 --- a/web/src/pages/UsagePage.test.tsx +++ b/web/src/pages/UsagePage.test.tsx @@ -153,6 +153,50 @@ describe("UsagePage", () => { expect(loc).toContain("model=gpt-5.6"); }); + it("keeps an active user filter when drilling into a model", async () => { + const user = userEvent.setup(); + mockApi(summary()); + renderPage(); + await screen.findByText("gpt-5.6"); + + // Filter by a user, then drill into a model row. The user constraint must + // survive the navigation, not be dropped in favor of only the clicked model. + const userInput = screen.getByRole("combobox", { name: "User" }); + await user.click(userInput); + await user.type(userInput, "alice"); + await user.click(await screen.findByRole("option", { name: /alice/ })); + + const row = (await screen.findByText("gpt-5.6")).closest("tr")!; + await user.click(row); + + const loc = screen.getByTestId("loc").textContent ?? ""; + expect(loc.startsWith("/activity")).toBe(true); + expect(loc).toContain("model=gpt-5.6"); + expect(loc).toContain("user_id=alice"); + }); + + it("keeps an active model filter when drilling into a user", async () => { + const user = userEvent.setup(); + mockApi(summary()); + renderPage(); + await screen.findByText("alice"); + + // Filter by a model, then drill into a user row. The model constraint must + // survive the navigation, not be dropped in favor of only the clicked user. + const modelInput = screen.getByRole("combobox", { name: "Model" }); + await user.click(modelInput); + await user.type(modelInput, "gpt"); + await user.click(await screen.findByRole("option", { name: /gpt-5.6/ })); + + const row = (await screen.findByText("alice")).closest("tr")!; + await user.click(row); + + const loc = screen.getByTestId("loc").textContent ?? ""; + expect(loc.startsWith("/activity")).toBe(true); + expect(loc).toContain("user_id=alice"); + expect(loc).toContain("model=gpt-5.6"); + }); + it("filters models by typeahead and commits the exact picked model", async () => { const fetchMock = mockApi(summary()); const user = userEvent.setup(); diff --git a/web/src/pages/UsagePage.tsx b/web/src/pages/UsagePage.tsx index 1568eaf9..c56a61ae 100644 --- a/web/src/pages/UsagePage.tsx +++ b/web/src/pages/UsagePage.tsx @@ -415,7 +415,9 @@ export function UsagePage() { rows={data?.by_model ?? []} totalCost={totals?.cost ?? 0} emptyLabel={anyFilter ? "No usage matches these filters." : "No usage recorded yet."} - onDrill={(key) => drillTo({ model: key })} + // Drilling into a model keeps any active user filter, so the log stays + // scoped to that user instead of showing every user's spend on the model. + onDrill={(key) => drillTo({ model: key, user_id: userFilter || undefined })} loading={summary.isLoading} /> drillTo({ user_id: key })} + // Likewise, drilling into a user keeps any active model filter. + onDrill={(key) => drillTo({ user_id: key, model: modelFilter.trim() || undefined })} loading={summary.isLoading} />
From bc9a2e82b2f5afdc0c53044ff9591c1803dcdee9 Mon Sep 17 00:00:00 2001 From: Nathan Brake Date: Thu, 23 Jul 2026 21:10:30 +0000 Subject: [PATCH 2/3] fix(dashboard): review follow-ups on budgets validation and usage test Self-review: the budgets custom-period validity check used Number.isInteger, which admits a finite-but-overflowing day count (1e308 is an integer, yet 1e308 * DAY overflows to Infinity). Switch both the inline validity check and onChange to Number.isSafeInteger, restoring the finiteness guard the original Math.round path had and rejecting overflowing input outright. CodeRabbit nitpick: the UsagePage test location probe was queried by test id. Expose it via a status role with an accessible name and query getByRole, per the frontend testing guideline; migrate the pre-existing usage too for consistency. Rebuild the committed dashboard bundle for the budgets change. Co-Authored-By: Claude Opus 4.8 (1M context) --- ...vityPage-Cw34Jlno.js => ActivityPage-BrL4O-hT.js} | 2 +- ...iasesPage-CCRTl9Co.js => AliasesPage-RDVKM-by.js} | 2 +- .../static/dashboard/assets/BudgetsPage-Ctwj8twD.js | 1 + .../static/dashboard/assets/BudgetsPage-iAjnK5BF.js | 1 - .../{KeysPage-C6eaoTUP.js => KeysPage-DCo4FFYU.js} | 2 +- ...rol-CkKcIwGe.js => ModelScopeControl-DiX2Etqz.js} | 2 +- ...ModelsPage-DwBDAaxV.js => ModelsPage-C028BOtV.js} | 2 +- ...viewPage-B_g2blUc.js => OverviewPage-KThfhw1Z.js} | 2 +- ...ersPage-DhHL_fxe.js => ProvidersPage-BEN5bHZD.js} | 2 +- ...ingsPage-BPWZBXQE.js => SettingsPage-hENBFRMI.js} | 2 +- ...e-Zh-JPOxJ.js => ToolsGuardrailsPage-DWSik0Ga.js} | 2 +- .../{UsagePage-Dk-t74Uz.js => UsagePage-B95PT-hq.js} | 2 +- .../{UsersPage-D6v_0kF6.js => UsersPage-D5CmT8Bq.js} | 2 +- .../assets/{index-DAVt9uB3.js => index-BJySXQ_a.js} | 4 ++-- src/gateway/static/dashboard/index.html | 2 +- web/src/pages/BudgetsPage.tsx | 10 +++++----- web/src/pages/UsagePage.test.tsx | 12 ++++++++---- 17 files changed, 28 insertions(+), 24 deletions(-) rename src/gateway/static/dashboard/assets/{ActivityPage-Cw34Jlno.js => ActivityPage-BrL4O-hT.js} (99%) rename src/gateway/static/dashboard/assets/{AliasesPage-CCRTl9Co.js => AliasesPage-RDVKM-by.js} (98%) create mode 100644 src/gateway/static/dashboard/assets/BudgetsPage-Ctwj8twD.js delete mode 100644 src/gateway/static/dashboard/assets/BudgetsPage-iAjnK5BF.js rename src/gateway/static/dashboard/assets/{KeysPage-C6eaoTUP.js => KeysPage-DCo4FFYU.js} (99%) rename src/gateway/static/dashboard/assets/{ModelScopeControl-CkKcIwGe.js => ModelScopeControl-DiX2Etqz.js} (98%) rename src/gateway/static/dashboard/assets/{ModelsPage-DwBDAaxV.js => ModelsPage-C028BOtV.js} (99%) rename src/gateway/static/dashboard/assets/{OverviewPage-B_g2blUc.js => OverviewPage-KThfhw1Z.js} (99%) rename src/gateway/static/dashboard/assets/{ProvidersPage-DhHL_fxe.js => ProvidersPage-BEN5bHZD.js} (99%) rename src/gateway/static/dashboard/assets/{SettingsPage-BPWZBXQE.js => SettingsPage-hENBFRMI.js} (99%) rename src/gateway/static/dashboard/assets/{ToolsGuardrailsPage-Zh-JPOxJ.js => ToolsGuardrailsPage-DWSik0Ga.js} (99%) rename src/gateway/static/dashboard/assets/{UsagePage-Dk-t74Uz.js => UsagePage-B95PT-hq.js} (99%) rename src/gateway/static/dashboard/assets/{UsersPage-D6v_0kF6.js => UsersPage-D5CmT8Bq.js} (98%) rename src/gateway/static/dashboard/assets/{index-DAVt9uB3.js => index-BJySXQ_a.js} (96%) diff --git a/src/gateway/static/dashboard/assets/ActivityPage-Cw34Jlno.js b/src/gateway/static/dashboard/assets/ActivityPage-BrL4O-hT.js similarity index 99% rename from src/gateway/static/dashboard/assets/ActivityPage-Cw34Jlno.js rename to src/gateway/static/dashboard/assets/ActivityPage-BrL4O-hT.js index 209539cb..2e52850e 100644 --- a/src/gateway/static/dashboard/assets/ActivityPage-Cw34Jlno.js +++ b/src/gateway/static/dashboard/assets/ActivityPage-BrL4O-hT.js @@ -1 +1 @@ -import{j as e}from"./tanstack-query-1t81HyiD.js";import{u as le,r as n}from"./react-dgEcD0HR.js";import{u as re,a as ne,b as ie,c as oe,P as ce,E as de,F as G,d as Y}from"./index-DAVt9uB3.js";import{T as ue,a as me,b as d,L as xe,c as he,d as pe,e as u}from"./Table-CLdjdyTx.js";import{B as f,S as ge}from"./heroui-BX6JwHY-.js";const je=new Intl.NumberFormat(void 0,{style:"currency",currency:"USD",maximumFractionDigits:4});function _(t){return t===null?"—":je.format(t)}function o(t){return t===null?"—":t.toLocaleString()}function Z(t){return t===null?"—":t<1e3?`${t} ms`:`${(t/1e3).toFixed(t<1e4?2:1)} s`}function ve(t){const a=new Date(t);return Number.isNaN(a.getTime())?t:a.toLocaleString()}function be(t){const a=new Date(t).getTime();if(Number.isNaN(a))return t;const r=Math.max(0,Math.round((Date.now()-a)/1e3));if(r<60)return`${r}s ago`;const i=Math.round(r/60);if(i<60)return`${i}m ago`;const m=Math.round(i/60);return m<24?`${m}h ago`:`${Math.round(m/24)}d ago`}const fe=3600,k=86400,Ne=[{label:"Last hour",seconds:fe},{label:"24h",seconds:k},{label:"7d",seconds:7*k},{label:"All",seconds:null}],Se=[{label:"All",value:""},{label:"Success",value:"success"},{label:"Error",value:"error"}],_e=["/v1/chat/completions","/v1/messages","/v1/responses","/v1/embeddings","/v1/moderations","/v1/audio/transcriptions","/v1/audio/speech","/v1/images/generations","/v1/rerank","/v1/batches","/v1/batches/results"],N=50;function D(t){return new Date(Date.now()-t*1e3).toISOString()}function ke({status:t}){const a=t==="error"?"border-red-200 bg-red-50 text-red-700":"border-[var(--otari-line)] bg-[var(--otari-brand-tint)] text-[var(--otari-brand-dark)]";return e.jsx("span",{className:`inline-flex items-center rounded-full border px-2 py-0.5 text-xs font-medium ${a}`,children:t})}function l({label:t,children:a}){return e.jsxs("div",{className:"flex flex-col gap-0.5",children:[e.jsx("span",{className:"text-[11px] font-medium uppercase tracking-wide text-[var(--otari-muted)]",children:t}),e.jsx("span",{className:"text-sm text-[var(--otari-ink)] break-all",children:a})]})}function we({entry:t}){var a;return e.jsxs("div",{className:"flex flex-col gap-4 px-4 py-4",children:[t.error_message?e.jsxs("div",{className:"flex flex-col gap-1.5",children:[e.jsx("div",{className:"flex items-center justify-between",children:e.jsx("span",{className:"text-[11px] font-medium uppercase tracking-wide text-[var(--otari-muted)]",children:"Error"})}),e.jsx("pre",{className:"max-h-48 overflow-auto rounded-lg border border-red-200 bg-red-50 p-3 text-xs whitespace-pre-wrap break-all text-red-700",children:"The provider returned an error. Inspect gateway logs for details."})]}):null,e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2 lg:grid-cols-4",children:[e.jsx(l,{label:"Provider",children:t.provider??"—"}),e.jsx(l,{label:"Endpoint",children:t.endpoint}),e.jsx(l,{label:"User",children:t.user_id??"—"}),e.jsx(l,{label:"API key",children:t.api_key_id??"—"}),e.jsx(l,{label:"Prompt tokens",children:o(t.prompt_tokens)}),e.jsx(l,{label:"Completion tokens",children:o(t.completion_tokens)}),e.jsx(l,{label:"Total tokens",children:o(t.total_tokens)}),e.jsx(l,{label:"Cost",children:_(t.cost)}),e.jsx(l,{label:"Cache read tokens",children:o(t.cache_read_tokens)}),e.jsx(l,{label:"Cache write tokens",children:o(t.cache_write_tokens)}),e.jsx(l,{label:"1h cache writes",children:o(t.cache_write_1h_tokens??null)}),e.jsx(l,{label:"Total time",children:Z(t.latency_ms)}),e.jsx(l,{label:"Request ID",children:t.id})]}),(a=t.pricing_breakdown)!=null&&a.length?e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsx("span",{className:"text-[11px] font-medium uppercase tracking-wide text-[var(--otari-muted)]",children:"Billed meters"}),e.jsx("div",{className:"grid gap-2 sm:grid-cols-2 lg:grid-cols-3",children:t.pricing_breakdown.map(r=>e.jsxs(l,{label:r.meter.replaceAll("_"," "),children:[o(r.units)," at ",_(r.rate_per_million)," / 1M, ",_(r.cost)]},r.meter))})]}):null]})}const A=7;function Ce(){var B,z,H;const t=re(),[a]=le(),r=a.get("start_date")??void 0,[i,m]=n.useState(r?null:k),[S,w]=n.useState(()=>r??D(k)),[x,C]=n.useState(()=>a.get("status")??""),[c,M]=n.useState(()=>a.get("model")??""),[h,$]=n.useState(""),[p,U]=n.useState(()=>a.get("user_id")??""),[j,T]=n.useState(0),[J,K]=n.useState(null),P=n.useMemo(()=>({start_date:S,status:x||void 0,model:c.trim()||void 0,endpoint:h||void 0,user_id:p||void 0}),[S,x,c,h,p]);n.useEffect(()=>{T(0)},[P]);const g=ne(P,j,N),v=ie(P),Q=n.useMemo(()=>({start_date:S,status:x||void 0,endpoint:h||void 0,user_id:p||void 0}),[S,x,h,p]),F=((z=(B=oe(Q,"day").data)==null?void 0:B.by_model)==null?void 0:z.filter(s=>!s.is_other&&s.key!==null).map(s=>s.key))??[],b=g.data??[],E=((H=v.data)==null?void 0:H.total)??0,I=!!(x||c.trim()||h||p||i!==null),V=s=>{m(s),w(s===null?void 0:D(s))},W=()=>{m(null),w(void 0),C(""),M(""),$(""),U("")},X=()=>{i!==null&&w(D(i)),g.refetch(),v.refetch()},L=b.length>0,O=L?j*N+1:0,R=j*N+b.length,q=v.isSuccess&&!v.isPlaceholderData,ee=q?E===0?"0 of 0":`${O}–${R} of ${E.toLocaleString()}`:L?`${O}–${R}`:"0",se=q?(j+1)*Ne.jsx(f,{size:"sm",variant:i===s.seconds?"primary":"outline",onPress:()=>V(s.seconds),children:s.label},s.label))}),e.jsxs("div",{className:"flex flex-wrap items-end gap-3",children:[e.jsx(G,{id:"filter-status",label:"Status",value:x,onChange:C,children:Se.map(s=>e.jsx("option",{value:s.value,children:s.label},s.value))}),e.jsxs(G,{id:"filter-endpoint",label:"Endpoint",value:h,onChange:$,children:[e.jsx("option",{value:"",children:"All endpoints"}),_e.map(s=>e.jsx("option",{value:s,children:s},s))]}),e.jsx(Y,{label:"User",value:p,onChange:U,placeholder:"All users",options:(t.data??[]).map(s=>({value:s.user_id,label:s.alias?`${s.alias} (${s.user_id})`:s.user_id}))}),e.jsx(Y,{label:"Model",value:c,onChange:M,allowsCustom:!0,placeholder:"Any model",options:(c&&!F.includes(c)?[c,...F]:F).map(s=>({value:s,label:s}))}),I?e.jsx(f,{size:"sm",variant:"ghost",onPress:W,children:"Clear filters"}):null]})]}),e.jsxs(ue,{children:[e.jsx(me,{children:e.jsxs("tr",{children:[e.jsx(d,{children:"Time"}),e.jsx(d,{children:"User"}),e.jsx(d,{children:"Model"}),e.jsx(d,{className:"text-right",children:"Tokens"}),e.jsx(d,{className:"text-right",children:"Cost"}),e.jsx(d,{className:"text-right",children:"Total time"}),e.jsx(d,{children:"Status"})]})}),e.jsx("tbody",{children:g.isLoading?e.jsx(xe,{colSpan:A}):b.length===0?e.jsx(he,{colSpan:A,children:I?"No requests match these filters.":"No requests recorded yet."}):b.map(s=>{const te=s.status==="error",y=J===s.id;return e.jsxs(n.Fragment,{children:[e.jsxs(pe,{selected:y,className:te?"bg-red-50":"",onClick:()=>K(ae=>ae===s.id?null:s.id),children:[e.jsx(u,{className:"text-[var(--otari-muted)]",children:e.jsx("span",{title:ve(s.timestamp),children:be(s.timestamp)})}),e.jsx(u,{className:"text-[var(--otari-ink)]",children:s.user_id??"—"}),e.jsx(u,{className:"text-[var(--otari-ink)]",children:s.model}),e.jsx(u,{className:"text-right tabular-nums",children:o(s.total_tokens)}),e.jsx(u,{className:"text-right tabular-nums",children:_(s.cost)}),e.jsx(u,{className:"text-right tabular-nums",children:Z(s.latency_ms)}),e.jsx(u,{children:e.jsx(ke,{status:s.status})})]}),y?e.jsx("tr",{className:"border-b border-[var(--otari-line)] bg-[var(--otari-bg)]",children:e.jsx("td",{colSpan:A,children:e.jsx(we,{entry:s})})}):null]},s.id)})})]}),e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsxs("span",{className:"inline-flex items-center gap-2 text-sm text-[var(--otari-muted)]",children:[ee,g.isFetching?e.jsx(ge,{size:"sm"}):null]}),e.jsxs("span",{className:"inline-flex gap-1.5",children:[e.jsx(f,{size:"sm",variant:"outline",isDisabled:j===0,onPress:()=>T(s=>Math.max(0,s-1)),children:"Previous"}),e.jsx(f,{size:"sm",variant:"outline",isDisabled:!se,onPress:()=>T(s=>s+1),children:"Next"})]})]})]})}export{Ce as ActivityPage}; +import{j as e}from"./tanstack-query-1t81HyiD.js";import{u as le,r as n}from"./react-dgEcD0HR.js";import{u as re,a as ne,b as ie,c as oe,P as ce,E as de,F as G,d as Y}from"./index-BJySXQ_a.js";import{T as ue,a as me,b as d,L as xe,c as he,d as pe,e as u}from"./Table-CLdjdyTx.js";import{B as f,S as ge}from"./heroui-BX6JwHY-.js";const je=new Intl.NumberFormat(void 0,{style:"currency",currency:"USD",maximumFractionDigits:4});function _(t){return t===null?"—":je.format(t)}function o(t){return t===null?"—":t.toLocaleString()}function Z(t){return t===null?"—":t<1e3?`${t} ms`:`${(t/1e3).toFixed(t<1e4?2:1)} s`}function ve(t){const a=new Date(t);return Number.isNaN(a.getTime())?t:a.toLocaleString()}function be(t){const a=new Date(t).getTime();if(Number.isNaN(a))return t;const r=Math.max(0,Math.round((Date.now()-a)/1e3));if(r<60)return`${r}s ago`;const i=Math.round(r/60);if(i<60)return`${i}m ago`;const m=Math.round(i/60);return m<24?`${m}h ago`:`${Math.round(m/24)}d ago`}const fe=3600,k=86400,Ne=[{label:"Last hour",seconds:fe},{label:"24h",seconds:k},{label:"7d",seconds:7*k},{label:"All",seconds:null}],Se=[{label:"All",value:""},{label:"Success",value:"success"},{label:"Error",value:"error"}],_e=["/v1/chat/completions","/v1/messages","/v1/responses","/v1/embeddings","/v1/moderations","/v1/audio/transcriptions","/v1/audio/speech","/v1/images/generations","/v1/rerank","/v1/batches","/v1/batches/results"],N=50;function D(t){return new Date(Date.now()-t*1e3).toISOString()}function ke({status:t}){const a=t==="error"?"border-red-200 bg-red-50 text-red-700":"border-[var(--otari-line)] bg-[var(--otari-brand-tint)] text-[var(--otari-brand-dark)]";return e.jsx("span",{className:`inline-flex items-center rounded-full border px-2 py-0.5 text-xs font-medium ${a}`,children:t})}function l({label:t,children:a}){return e.jsxs("div",{className:"flex flex-col gap-0.5",children:[e.jsx("span",{className:"text-[11px] font-medium uppercase tracking-wide text-[var(--otari-muted)]",children:t}),e.jsx("span",{className:"text-sm text-[var(--otari-ink)] break-all",children:a})]})}function we({entry:t}){var a;return e.jsxs("div",{className:"flex flex-col gap-4 px-4 py-4",children:[t.error_message?e.jsxs("div",{className:"flex flex-col gap-1.5",children:[e.jsx("div",{className:"flex items-center justify-between",children:e.jsx("span",{className:"text-[11px] font-medium uppercase tracking-wide text-[var(--otari-muted)]",children:"Error"})}),e.jsx("pre",{className:"max-h-48 overflow-auto rounded-lg border border-red-200 bg-red-50 p-3 text-xs whitespace-pre-wrap break-all text-red-700",children:"The provider returned an error. Inspect gateway logs for details."})]}):null,e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2 lg:grid-cols-4",children:[e.jsx(l,{label:"Provider",children:t.provider??"—"}),e.jsx(l,{label:"Endpoint",children:t.endpoint}),e.jsx(l,{label:"User",children:t.user_id??"—"}),e.jsx(l,{label:"API key",children:t.api_key_id??"—"}),e.jsx(l,{label:"Prompt tokens",children:o(t.prompt_tokens)}),e.jsx(l,{label:"Completion tokens",children:o(t.completion_tokens)}),e.jsx(l,{label:"Total tokens",children:o(t.total_tokens)}),e.jsx(l,{label:"Cost",children:_(t.cost)}),e.jsx(l,{label:"Cache read tokens",children:o(t.cache_read_tokens)}),e.jsx(l,{label:"Cache write tokens",children:o(t.cache_write_tokens)}),e.jsx(l,{label:"1h cache writes",children:o(t.cache_write_1h_tokens??null)}),e.jsx(l,{label:"Total time",children:Z(t.latency_ms)}),e.jsx(l,{label:"Request ID",children:t.id})]}),(a=t.pricing_breakdown)!=null&&a.length?e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsx("span",{className:"text-[11px] font-medium uppercase tracking-wide text-[var(--otari-muted)]",children:"Billed meters"}),e.jsx("div",{className:"grid gap-2 sm:grid-cols-2 lg:grid-cols-3",children:t.pricing_breakdown.map(r=>e.jsxs(l,{label:r.meter.replaceAll("_"," "),children:[o(r.units)," at ",_(r.rate_per_million)," / 1M, ",_(r.cost)]},r.meter))})]}):null]})}const A=7;function Ce(){var B,z,H;const t=re(),[a]=le(),r=a.get("start_date")??void 0,[i,m]=n.useState(r?null:k),[S,w]=n.useState(()=>r??D(k)),[x,C]=n.useState(()=>a.get("status")??""),[c,M]=n.useState(()=>a.get("model")??""),[h,$]=n.useState(""),[p,U]=n.useState(()=>a.get("user_id")??""),[j,T]=n.useState(0),[J,K]=n.useState(null),P=n.useMemo(()=>({start_date:S,status:x||void 0,model:c.trim()||void 0,endpoint:h||void 0,user_id:p||void 0}),[S,x,c,h,p]);n.useEffect(()=>{T(0)},[P]);const g=ne(P,j,N),v=ie(P),Q=n.useMemo(()=>({start_date:S,status:x||void 0,endpoint:h||void 0,user_id:p||void 0}),[S,x,h,p]),F=((z=(B=oe(Q,"day").data)==null?void 0:B.by_model)==null?void 0:z.filter(s=>!s.is_other&&s.key!==null).map(s=>s.key))??[],b=g.data??[],E=((H=v.data)==null?void 0:H.total)??0,I=!!(x||c.trim()||h||p||i!==null),V=s=>{m(s),w(s===null?void 0:D(s))},W=()=>{m(null),w(void 0),C(""),M(""),$(""),U("")},X=()=>{i!==null&&w(D(i)),g.refetch(),v.refetch()},L=b.length>0,O=L?j*N+1:0,R=j*N+b.length,q=v.isSuccess&&!v.isPlaceholderData,ee=q?E===0?"0 of 0":`${O}–${R} of ${E.toLocaleString()}`:L?`${O}–${R}`:"0",se=q?(j+1)*Ne.jsx(f,{size:"sm",variant:i===s.seconds?"primary":"outline",onPress:()=>V(s.seconds),children:s.label},s.label))}),e.jsxs("div",{className:"flex flex-wrap items-end gap-3",children:[e.jsx(G,{id:"filter-status",label:"Status",value:x,onChange:C,children:Se.map(s=>e.jsx("option",{value:s.value,children:s.label},s.value))}),e.jsxs(G,{id:"filter-endpoint",label:"Endpoint",value:h,onChange:$,children:[e.jsx("option",{value:"",children:"All endpoints"}),_e.map(s=>e.jsx("option",{value:s,children:s},s))]}),e.jsx(Y,{label:"User",value:p,onChange:U,placeholder:"All users",options:(t.data??[]).map(s=>({value:s.user_id,label:s.alias?`${s.alias} (${s.user_id})`:s.user_id}))}),e.jsx(Y,{label:"Model",value:c,onChange:M,allowsCustom:!0,placeholder:"Any model",options:(c&&!F.includes(c)?[c,...F]:F).map(s=>({value:s,label:s}))}),I?e.jsx(f,{size:"sm",variant:"ghost",onPress:W,children:"Clear filters"}):null]})]}),e.jsxs(ue,{children:[e.jsx(me,{children:e.jsxs("tr",{children:[e.jsx(d,{children:"Time"}),e.jsx(d,{children:"User"}),e.jsx(d,{children:"Model"}),e.jsx(d,{className:"text-right",children:"Tokens"}),e.jsx(d,{className:"text-right",children:"Cost"}),e.jsx(d,{className:"text-right",children:"Total time"}),e.jsx(d,{children:"Status"})]})}),e.jsx("tbody",{children:g.isLoading?e.jsx(xe,{colSpan:A}):b.length===0?e.jsx(he,{colSpan:A,children:I?"No requests match these filters.":"No requests recorded yet."}):b.map(s=>{const te=s.status==="error",y=J===s.id;return e.jsxs(n.Fragment,{children:[e.jsxs(pe,{selected:y,className:te?"bg-red-50":"",onClick:()=>K(ae=>ae===s.id?null:s.id),children:[e.jsx(u,{className:"text-[var(--otari-muted)]",children:e.jsx("span",{title:ve(s.timestamp),children:be(s.timestamp)})}),e.jsx(u,{className:"text-[var(--otari-ink)]",children:s.user_id??"—"}),e.jsx(u,{className:"text-[var(--otari-ink)]",children:s.model}),e.jsx(u,{className:"text-right tabular-nums",children:o(s.total_tokens)}),e.jsx(u,{className:"text-right tabular-nums",children:_(s.cost)}),e.jsx(u,{className:"text-right tabular-nums",children:Z(s.latency_ms)}),e.jsx(u,{children:e.jsx(ke,{status:s.status})})]}),y?e.jsx("tr",{className:"border-b border-[var(--otari-line)] bg-[var(--otari-bg)]",children:e.jsx("td",{colSpan:A,children:e.jsx(we,{entry:s})})}):null]},s.id)})})]}),e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsxs("span",{className:"inline-flex items-center gap-2 text-sm text-[var(--otari-muted)]",children:[ee,g.isFetching?e.jsx(ge,{size:"sm"}):null]}),e.jsxs("span",{className:"inline-flex gap-1.5",children:[e.jsx(f,{size:"sm",variant:"outline",isDisabled:j===0,onPress:()=>T(s=>Math.max(0,s-1)),children:"Previous"}),e.jsx(f,{size:"sm",variant:"outline",isDisabled:!se,onPress:()=>T(s=>s+1),children:"Next"})]})]})]})}export{Ce as ActivityPage}; diff --git a/src/gateway/static/dashboard/assets/AliasesPage-CCRTl9Co.js b/src/gateway/static/dashboard/assets/AliasesPage-RDVKM-by.js similarity index 98% rename from src/gateway/static/dashboard/assets/AliasesPage-CCRTl9Co.js rename to src/gateway/static/dashboard/assets/AliasesPage-RDVKM-by.js index 362a4dfb..0082b241 100644 --- a/src/gateway/static/dashboard/assets/AliasesPage-CCRTl9Co.js +++ b/src/gateway/static/dashboard/assets/AliasesPage-RDVKM-by.js @@ -1 +1 @@ -import{j as e}from"./tanstack-query-1t81HyiD.js";import{r as x,u as w}from"./react-dgEcD0HR.js";import{e as L,f as E,g as B,P as D,E as N,C as I,h as M,i as A}from"./index-DAVt9uB3.js";import{F}from"./Field-HzRk1KDP.js";import{C as j,L as R,I as q,a as V,b as H,B as h,f as $,d as C}from"./heroui-BX6JwHY-.js";import{T as z,a as G,d as T,b as f,L as K,c as W,e as v}from"./Table-CLdjdyTx.js";const X=50;function k({label:t,value:n,onChange:a,description:r,placeholder:m="provider:model",autoFocus:i,isRequired:c}){const l=L(),{visible:d,total:s,failed:g}=x.useMemo(()=>{var S;const o=n.trim().toLowerCase(),p=((S=l.data)==null?void 0:S.providers)??[],y=p.flatMap(u=>u.models),P=o?y.filter(u=>u.key.toLowerCase().includes(o)):y;return{visible:P.slice(0,X),total:P.length,failed:p.filter(u=>!u.ok)}},[l.data,n]),b=l.isLoading?"Loading models from your providers…":g.length>0?`Could not list models for ${g.map(p=>p.provider).join(", ")}. Check that provider's credentials, or type the model key directly.`:s>d.length?`Showing ${d.length} of ${s} matches. Keep typing to narrow them.`:r;return e.jsxs(j.Root,{allowsCustomValue:!0,allowsEmptyCollection:!0,menuTrigger:"input",inputValue:n,onInputChange:a,onSelectionChange:o=>{o!=null&&a(String(o))},isRequired:c,className:"flex max-w-md flex-col gap-1",children:[e.jsx(R,{className:"text-sm font-medium text-[var(--otari-ink)]",children:t}),e.jsxs(j.InputGroup,{children:[e.jsx(q,{placeholder:m,autoFocus:i}),e.jsx(j.Trigger,{})]}),e.jsx(j.Popover,{children:e.jsx(V,{items:d,className:"max-h-72 overflow-auto",children:o=>e.jsx(H,{id:o.key,textValue:o.key,children:o.key})})}),b?e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:b}):null]})}function _({alias:t,onClose:n}){const a=A(),[r,m]=x.useState(t.target),i=r.trim()!==""&&r.trim()!==t.target,c=()=>{i&&a.mutate({name:t.name,target:r.trim()},{onSuccess:n})};return e.jsx(C,{children:e.jsxs(C.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsxs("div",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:["Edit alias ",e.jsx("code",{children:t.name})]}),e.jsx(N,{error:a.error}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx("span",{className:"text-sm font-medium text-[var(--otari-ink)]",children:"Alias name"}),e.jsx("code",{className:"text-sm text-[var(--otari-muted)]",children:t.name}),e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"The alias name is the key and cannot be changed here. Delete and recreate to rename."})]}),e.jsx(k,{label:"Target",value:r,onChange:m,isRequired:!0,description:"The real model this resolves to. Callers never see it."})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(h,{variant:"primary",isDisabled:!i||a.isPending,onPress:c,children:a.isPending?"Saving…":"Save changes"}),e.jsx(h,{variant:"ghost",onPress:n,children:"Cancel"})]})]})})}function J({onClose:t,initialTarget:n=""}){const a=A(),[r,m]=x.useState(""),[i,c]=x.useState(n),l=/[:/]/.test(r),d=r.trim()!==""&&i.trim()!==""&&!l,s=()=>{d&&a.mutate({name:r.trim(),target:i.trim()},{onSuccess:t})};return e.jsx(C,{children:e.jsxs(C.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsx("div",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:"New alias"}),e.jsx(N,{error:a.error}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsx(F,{label:"Alias name",value:r,onChange:m,placeholder:"fast-model",isRequired:!0,autoFocus:!0,description:l?e.jsx("span",{className:"text-red-700",children:"An alias name cannot contain “:” or “/”."}):"What callers send as `model`."}),e.jsx(k,{label:"Target",value:i,onChange:c,isRequired:!0,description:"The real model this resolves to. Callers never see it."})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(h,{variant:"primary",isDisabled:!d||a.isPending,onPress:s,children:a.isPending?"Creating…":"Create alias"}),e.jsx(h,{variant:"ghost",onPress:t,children:"Cancel"})]})]})})}function se(){const t=E(),n=B(),[a]=w(),r=a.get("target")??"",[m,i]=x.useState(r!==""),[c,l]=x.useState(null),d=[...t.data??[]].sort((s,g)=>s.name.localeCompare(g.name));return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(D,{title:"Aliases",description:"Friendly names that map to a real provider:model. Callers send the alias as the model; pricing, budgets, and usage key on the target.",action:m||c?null:e.jsx(h,{variant:"primary",onPress:()=>{l(null),i(!0)},children:"New alias"})}),e.jsx(N,{error:t.error}),m?e.jsx(J,{initialTarget:r,onClose:()=>i(!1)}):null,c?e.jsx(_,{alias:c,onClose:()=>l(null)}):null,e.jsxs(z,{children:[e.jsx(G,{children:e.jsxs(T,{children:[e.jsx(f,{children:"Alias"}),e.jsx(f,{children:"Target"}),e.jsx(f,{children:"Source"}),e.jsx(f,{className:"text-right",children:"Actions"})]})}),e.jsx("tbody",{children:t.isLoading?e.jsx(K,{colSpan:4}):d.length===0?e.jsx(W,{colSpan:4,children:"No aliases yet. Create one to give a model a friendly name."}):d.map(s=>e.jsxs(T,{children:[e.jsx(v,{className:"font-medium break-all text-[var(--otari-ink)]",children:s.name}),e.jsx(v,{className:"break-all text-[var(--otari-muted)]",children:s.target}),e.jsx(v,{children:e.jsx($,{size:"sm",color:s.source==="stored"?"accent":"default",children:s.source})}),e.jsx(v,{className:"text-right whitespace-nowrap",children:s.source==="stored"?e.jsxs("span",{className:"inline-flex items-center gap-2",children:[e.jsx(h,{size:"sm",variant:"ghost",onPress:()=>{i(!1),l(s)},children:"Edit"}),e.jsx(I,{confirmLabel:"Delete",isPending:n.isPending,onConfirm:()=>n.mutate(s.name),children:"Delete"}),n.error?e.jsx("span",{className:"text-xs text-red-700",children:M(n.error)}):null]}):e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"set in config.yml"})})]},s.name))})]})]})}export{se as AliasesPage}; +import{j as e}from"./tanstack-query-1t81HyiD.js";import{r as x,u as w}from"./react-dgEcD0HR.js";import{e as L,f as E,g as B,P as D,E as N,C as I,h as M,i as A}from"./index-BJySXQ_a.js";import{F}from"./Field-HzRk1KDP.js";import{C as j,L as R,I as q,a as V,b as H,B as h,f as $,d as C}from"./heroui-BX6JwHY-.js";import{T as z,a as G,d as T,b as f,L as K,c as W,e as v}from"./Table-CLdjdyTx.js";const X=50;function k({label:t,value:n,onChange:a,description:r,placeholder:m="provider:model",autoFocus:i,isRequired:c}){const l=L(),{visible:d,total:s,failed:g}=x.useMemo(()=>{var S;const o=n.trim().toLowerCase(),p=((S=l.data)==null?void 0:S.providers)??[],y=p.flatMap(u=>u.models),P=o?y.filter(u=>u.key.toLowerCase().includes(o)):y;return{visible:P.slice(0,X),total:P.length,failed:p.filter(u=>!u.ok)}},[l.data,n]),b=l.isLoading?"Loading models from your providers…":g.length>0?`Could not list models for ${g.map(p=>p.provider).join(", ")}. Check that provider's credentials, or type the model key directly.`:s>d.length?`Showing ${d.length} of ${s} matches. Keep typing to narrow them.`:r;return e.jsxs(j.Root,{allowsCustomValue:!0,allowsEmptyCollection:!0,menuTrigger:"input",inputValue:n,onInputChange:a,onSelectionChange:o=>{o!=null&&a(String(o))},isRequired:c,className:"flex max-w-md flex-col gap-1",children:[e.jsx(R,{className:"text-sm font-medium text-[var(--otari-ink)]",children:t}),e.jsxs(j.InputGroup,{children:[e.jsx(q,{placeholder:m,autoFocus:i}),e.jsx(j.Trigger,{})]}),e.jsx(j.Popover,{children:e.jsx(V,{items:d,className:"max-h-72 overflow-auto",children:o=>e.jsx(H,{id:o.key,textValue:o.key,children:o.key})})}),b?e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:b}):null]})}function _({alias:t,onClose:n}){const a=A(),[r,m]=x.useState(t.target),i=r.trim()!==""&&r.trim()!==t.target,c=()=>{i&&a.mutate({name:t.name,target:r.trim()},{onSuccess:n})};return e.jsx(C,{children:e.jsxs(C.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsxs("div",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:["Edit alias ",e.jsx("code",{children:t.name})]}),e.jsx(N,{error:a.error}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx("span",{className:"text-sm font-medium text-[var(--otari-ink)]",children:"Alias name"}),e.jsx("code",{className:"text-sm text-[var(--otari-muted)]",children:t.name}),e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"The alias name is the key and cannot be changed here. Delete and recreate to rename."})]}),e.jsx(k,{label:"Target",value:r,onChange:m,isRequired:!0,description:"The real model this resolves to. Callers never see it."})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(h,{variant:"primary",isDisabled:!i||a.isPending,onPress:c,children:a.isPending?"Saving…":"Save changes"}),e.jsx(h,{variant:"ghost",onPress:n,children:"Cancel"})]})]})})}function J({onClose:t,initialTarget:n=""}){const a=A(),[r,m]=x.useState(""),[i,c]=x.useState(n),l=/[:/]/.test(r),d=r.trim()!==""&&i.trim()!==""&&!l,s=()=>{d&&a.mutate({name:r.trim(),target:i.trim()},{onSuccess:t})};return e.jsx(C,{children:e.jsxs(C.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsx("div",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:"New alias"}),e.jsx(N,{error:a.error}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsx(F,{label:"Alias name",value:r,onChange:m,placeholder:"fast-model",isRequired:!0,autoFocus:!0,description:l?e.jsx("span",{className:"text-red-700",children:"An alias name cannot contain “:” or “/”."}):"What callers send as `model`."}),e.jsx(k,{label:"Target",value:i,onChange:c,isRequired:!0,description:"The real model this resolves to. Callers never see it."})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(h,{variant:"primary",isDisabled:!d||a.isPending,onPress:s,children:a.isPending?"Creating…":"Create alias"}),e.jsx(h,{variant:"ghost",onPress:t,children:"Cancel"})]})]})})}function se(){const t=E(),n=B(),[a]=w(),r=a.get("target")??"",[m,i]=x.useState(r!==""),[c,l]=x.useState(null),d=[...t.data??[]].sort((s,g)=>s.name.localeCompare(g.name));return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(D,{title:"Aliases",description:"Friendly names that map to a real provider:model. Callers send the alias as the model; pricing, budgets, and usage key on the target.",action:m||c?null:e.jsx(h,{variant:"primary",onPress:()=>{l(null),i(!0)},children:"New alias"})}),e.jsx(N,{error:t.error}),m?e.jsx(J,{initialTarget:r,onClose:()=>i(!1)}):null,c?e.jsx(_,{alias:c,onClose:()=>l(null)}):null,e.jsxs(z,{children:[e.jsx(G,{children:e.jsxs(T,{children:[e.jsx(f,{children:"Alias"}),e.jsx(f,{children:"Target"}),e.jsx(f,{children:"Source"}),e.jsx(f,{className:"text-right",children:"Actions"})]})}),e.jsx("tbody",{children:t.isLoading?e.jsx(K,{colSpan:4}):d.length===0?e.jsx(W,{colSpan:4,children:"No aliases yet. Create one to give a model a friendly name."}):d.map(s=>e.jsxs(T,{children:[e.jsx(v,{className:"font-medium break-all text-[var(--otari-ink)]",children:s.name}),e.jsx(v,{className:"break-all text-[var(--otari-muted)]",children:s.target}),e.jsx(v,{children:e.jsx($,{size:"sm",color:s.source==="stored"?"accent":"default",children:s.source})}),e.jsx(v,{className:"text-right whitespace-nowrap",children:s.source==="stored"?e.jsxs("span",{className:"inline-flex items-center gap-2",children:[e.jsx(h,{size:"sm",variant:"ghost",onPress:()=>{i(!1),l(s)},children:"Edit"}),e.jsx(I,{confirmLabel:"Delete",isPending:n.isPending,onConfirm:()=>n.mutate(s.name),children:"Delete"}),n.error?e.jsx("span",{className:"text-xs text-red-700",children:M(n.error)}):null]}):e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"set in config.yml"})})]},s.name))})]})]})}export{se as AliasesPage}; diff --git a/src/gateway/static/dashboard/assets/BudgetsPage-Ctwj8twD.js b/src/gateway/static/dashboard/assets/BudgetsPage-Ctwj8twD.js new file mode 100644 index 00000000..6ac704db --- /dev/null +++ b/src/gateway/static/dashboard/assets/BudgetsPage-Ctwj8twD.js @@ -0,0 +1 @@ +import{j as e}from"./tanstack-query-1t81HyiD.js";import{r as d}from"./react-dgEcD0HR.js";import{j as Y,u as G,k as K,l as Q,m as X,n as J,P as Z,E as R,I as ee,o as se}from"./index-BJySXQ_a.js";import{F as L}from"./Field-HzRk1KDP.js";import{T as te,a as re,b as S,L as ae,c as ne,d as ie,e as C}from"./Table-CLdjdyTx.js";import{C as U,I as le,a as de,b as oe,B as g,d as E,S as ue}from"./heroui-BX6JwHY-.js";const ce=50;function me({value:s,onChange:r,users:a,label:i,description:l}){const[m,x]=d.useState(""),o=d.useMemo(()=>a.filter(t=>!t.user_id.startsWith("apikey-")).map(t=>({id:t.user_id,label:t.alias?`${t.user_id} (${t.alias})`:t.user_id})),[a]),h=d.useMemo(()=>{const t=m.trim().toLowerCase();return o.filter(u=>!s.includes(u.id)).filter(u=>!t||u.id.toLowerCase().includes(t)||u.label.toLowerCase().includes(t)).slice(0,ce)},[o,s,m]),c=t=>{s.includes(t)||r([...s,t]),x("")},p=t=>r(s.filter(u=>u!==t));return e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsxs("div",{children:[e.jsx("span",{className:"text-sm font-medium text-[var(--otari-ink)]",children:i}),l?e.jsx("p",{className:"text-xs text-[var(--otari-muted)]",children:l}):null]}),s.length>0?e.jsx("div",{className:"flex flex-wrap gap-1.5",children:s.map(t=>e.jsxs("span",{className:"inline-flex items-center gap-1 rounded-full bg-[var(--otari-brand-tint)] px-2.5 py-1 font-mono text-xs text-[var(--otari-brand-dark)]",children:[t,e.jsx("button",{type:"button","aria-label":`Remove ${t}`,onClick:()=>p(t),className:"text-[var(--otari-brand-dark)] hover:text-red-700",children:"×"})]},t))}):null,o.length===0?e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"No users yet. Create users first, then assign them here or from the Users page."}):e.jsxs(U.Root,{allowsEmptyCollection:!0,menuTrigger:"input",inputValue:m,onInputChange:x,selectedKey:null,onSelectionChange:t=>{t!=null&&c(String(t))},className:"flex flex-col gap-1",children:[e.jsxs(U.InputGroup,{children:[e.jsx(le,{"aria-label":"Add a user",placeholder:"Search users…",autoComplete:"off"}),e.jsx(U.Trigger,{})]}),e.jsx(U.Popover,{children:e.jsx(de,{items:h,className:"max-h-72 overflow-auto",children:t=>e.jsx(oe,{id:t.id,textValue:t.label,children:t.label})})})]})]})}const xe=new Intl.NumberFormat(void 0,{style:"currency",currency:"USD",maximumFractionDigits:2});function w(s){return xe.format(s)}const b=86400,$=3600,I=[{label:"No reset",seconds:null},{label:"Daily",seconds:b},{label:"Weekly",seconds:7*b},{label:"Monthly",seconds:30*b}];function ge(s){if(s===null)return"No reset";const r=I.find(a=>a.seconds===s);return r?r.label:s%b===0?`Every ${s/b} days`:s%$===0?`Every ${s/$} hours`:`Every ${s}s`}function F(s){if(!s)return"—";const r=new Date(s);return Number.isNaN(r.getTime())?"—":r.toLocaleString()}function he(s){const r=s.trim();if(r==="")return{value:null,valid:!0};const a=Number(r);return!Number.isFinite(a)||a<0?{value:null,valid:!1}:{value:a,valid:!0}}function pe({value:s,onChange:r}){const a=I.some(t=>t.seconds===s),[i,l]=d.useState(!a),m=s!==null&&s%b===0?String(s/b):"",[x,o]=d.useState(m);d.useEffect(()=>{o(m)},[m]);const h=x.trim(),c=Number(h),p=h!==""&&(!Number.isSafeInteger(c)||c<=0);return e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsx("span",{className:"text-sm font-medium text-[var(--otari-ink)]",children:"Reset period"}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[I.map(t=>e.jsx(g,{size:"sm",variant:!i&&s===t.seconds?"primary":"outline",onPress:()=>{l(!1),r(t.seconds)},children:t.label},t.label)),e.jsx(g,{size:"sm",variant:i?"primary":"outline",onPress:()=>l(!0),children:"Custom"})]}),i?e.jsx("div",{className:"flex items-end gap-2",children:e.jsx(L,{label:"Every N days",value:x,onChange:t=>{o(t);const u=Number(t.trim());r(t.trim()===""||!Number.isSafeInteger(u)||u<=0?null:u*b)},placeholder:"14",description:p?e.jsx("span",{className:"text-red-700",children:"Enter a whole number of days."}):"Whole days between resets."})}):null,e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"Spend returns to zero each period. A user’s clock starts when the budget is assigned to them."})]})}function O({title:s,submitLabel:r,initial:a,error:i,isPending:l,onSubmit:m,onClose:x,assignUsers:o}){const[h,c]=d.useState(a.name??""),[p,t]=d.useState(a.max_budget===null?"":String(a.max_budget)),[u,j]=d.useState(a.budget_duration_sec),[v,N]=d.useState([]),_=he(p),P=()=>{l||!_.valid||m({name:h.trim()||null,max_budget:_.value,budget_duration_sec:u},v)};return e.jsx(E,{children:e.jsxs(E.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsx("div",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:s}),e.jsx(R,{error:i}),e.jsx(L,{label:"Name (optional)",value:h,onChange:c,autoFocus:!0,placeholder:"team-free-tier",description:"A label to recognize this budget later."}),e.jsx(L,{label:"Spending limit (USD)",value:p,onChange:t,placeholder:"100.00",description:_.valid?"The most a single user on this budget may spend per period. Leave blank for no limit.":e.jsx("span",{className:"text-red-700",children:"Enter a non-negative number, or leave blank for no limit."})}),e.jsx(pe,{value:u,onChange:j}),o?e.jsx(me,{label:"Assign to users (optional)",description:"Attach this budget to existing users now. You can also manage assignments later on the Users page.",value:v,onChange:N,users:o}):null,e.jsxs("div",{className:"flex gap-2",children:[e.jsx(g,{variant:"primary",isDisabled:l||!_.valid,onPress:P,children:l?"Saving…":r}),e.jsx(g,{variant:"ghost",isDisabled:l,onPress:x,children:"Cancel"})]})]})})}function fe({budget:s}){if(s.user_count===0)return e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"No users assigned"});const r=s.total_spend;if(s.max_budget===null)return e.jsxs("span",{className:"text-xs text-[var(--otari-ink)]",children:[w(r)," spent",e.jsx("span",{className:"text-[var(--otari-muted)]",children:" · no limit"})]});const a=s.max_budget*s.user_count,i=a>0?Math.min(100,r/a*100):0,l=r>a;return e.jsxs("div",{className:"flex min-w-[140px] flex-col gap-1",children:[e.jsxs("div",{className:"flex items-baseline justify-between gap-2 text-xs",children:[e.jsx("span",{className:"text-[var(--otari-ink)]",children:w(r)}),e.jsxs("span",{className:"text-[var(--otari-muted)]",children:["of ",w(a)]})]}),e.jsx("div",{className:"h-1.5 w-full overflow-hidden rounded-full bg-[var(--otari-line)]",role:"progressbar","aria-valuenow":Math.round(i),"aria-valuemin":0,"aria-valuemax":100,"aria-label":"Aggregate spend against total allocation",children:e.jsx("div",{className:`h-full rounded-full ${l?"bg-red-500":"bg-[var(--otari-brand)]"}`,style:{width:`${Math.max(i,l?100:2)}%`}})})]})}function je({budgetId:s}){const r=se(s);if(r.isLoading)return e.jsxs("div",{className:"flex items-center gap-2 px-4 py-4 text-sm text-[var(--otari-muted)]",children:[e.jsx(ue,{size:"sm"})," Loading reset history…"]});if(r.error)return e.jsx("div",{className:"px-4 py-4",children:e.jsx(R,{error:r.error})});const a=r.data??[];return a.length===0?e.jsx("div",{className:"px-4 py-4 text-sm text-[var(--otari-muted)]",children:"No resets recorded yet for this budget."}):e.jsx("div",{className:"overflow-x-auto px-4 py-3",children:e.jsxs("table",{className:"w-full border-collapse text-xs",children:[e.jsx("thead",{className:"text-left text-[var(--otari-muted)]",children:e.jsxs("tr",{children:[e.jsx("th",{className:"py-1.5 pr-4 font-medium",children:"User"}),e.jsx("th",{className:"py-1.5 pr-4 font-medium",children:"Spend cleared"}),e.jsx("th",{className:"py-1.5 pr-4 font-medium",children:"Reset at"}),e.jsx("th",{className:"py-1.5 font-medium",children:"Next reset"})]})}),e.jsx("tbody",{children:a.map(i=>e.jsxs("tr",{className:"border-t border-[var(--otari-line)]",children:[e.jsx("td",{className:"py-1.5 pr-4",children:e.jsx("code",{children:i.user_id??"—"})}),e.jsx("td",{className:"py-1.5 pr-4 text-[var(--otari-ink)]",children:w(i.previous_spend)}),e.jsx("td",{className:"py-1.5 pr-4 text-[var(--otari-muted)]",children:F(i.reset_at)}),e.jsx("td",{className:"py-1.5 text-[var(--otari-muted)]",children:F(i.next_reset_at)})]},i.id))})]})})}function be({onCreate:s}){return e.jsx(E,{children:e.jsxs(E.Content,{className:"flex flex-col gap-4 p-6",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-semibold text-[var(--otari-ink)]",children:"No budgets yet"}),e.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:"A budget caps how much a user may spend and, optionally, resets that spend on a schedule. Create one, then assign it to users to enforce a limit."})]}),e.jsx("div",{children:e.jsx(g,{variant:"primary",onPress:s,children:"Create your first budget"})})]})})}function ve({label:s,isPending:r,onConfirm:a}){const[i,l]=d.useState(!1);return i?e.jsxs("div",{className:"flex flex-col items-end gap-1.5 rounded-lg border border-amber-200 bg-amber-50 p-2 text-right",children:[e.jsxs("span",{className:"max-w-xs text-xs text-amber-800",children:["Delete ",e.jsx("strong",{children:s}),"? Users keep their spend but lose this limit. Cannot be undone."]}),e.jsxs("span",{className:"inline-flex gap-1",children:[e.jsx(g,{size:"sm",variant:"danger",isDisabled:r,onPress:a,children:"Delete permanently"}),e.jsx(g,{size:"sm",variant:"ghost",isDisabled:r,onPress:()=>l(!1),children:"Cancel"})]})]}):e.jsx(g,{size:"sm",variant:"danger-soft",onPress:()=>l(!0),children:"Delete"})}function V(s){return s.split("-")[0]}function H(s){return s.name??V(s.budget_id)}function Pe(){const s=Y(),r=G(),a=K(),i=Q(),l=X(),m=J(),[x,o]=d.useState(!1),[h,c]=d.useState(null),[p,t]=d.useState(null),[u,j]=d.useState(null),[v,N]=d.useState(null),[_,P]=d.useState(!1),D=s.data??[],T=s.isLoading,y=D.find(n=>n.budget_id===h)??null,z=!T&&D.length===0&&!x,M=async(n,f)=>{P(!0),j(null);const B=await Promise.allSettled(f.map(k=>m.mutateAsync({id:k,body:{budget_id:n}})));P(!1);const A=B.flatMap((k,q)=>k.status==="rejected"?[f[q]]:[]);if(A.length>0){N({budgetId:n,userIds:A}),j(new Error(`Budget created, but could not assign it to: ${A.join(", ")}. Retry to try again.`));return}N(null),o(!1)},W=(n,f)=>{if(v){M(v.budgetId,v.userIds);return}j(null),a.mutate(n,{onSuccess:async B=>{if(f.length>0){await M(B.budget_id,f);return}o(!1)}})};return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(Z,{title:"Budgets",description:"Define spending limits and reset schedules. Assign a budget to users to enforce it.",action:x||z?null:e.jsx(g,{variant:"primary",onPress:()=>{c(null),j(null),N(null),o(!0)},children:"Create budget"})}),e.jsx(R,{error:s.error??a.error??i.error??l.error??m.error}),e.jsx(ee,{children:"Assign a budget to users when you create it, or later from the Users page. Each row’s usage aggregates the spend of the users currently on that budget."}),z?e.jsx(be,{onCreate:()=>{c(null),j(null),N(null),o(!0)}}):null,x?e.jsx(O,{title:"Create budget",submitLabel:v?"Retry assignments":"Create budget",initial:{name:null,max_budget:null,budget_duration_sec:null},error:a.error??u,isPending:a.isPending||_,assignUsers:r.data??[],onSubmit:W,onClose:()=>{j(null),N(null),o(!1)}}):null,y?e.jsx(O,{title:`Edit budget ${H(y)}`,submitLabel:"Save changes",initial:{name:y.name,max_budget:y.max_budget,budget_duration_sec:y.budget_duration_sec},error:i.error,isPending:i.isPending,onSubmit:n=>i.mutate({id:y.budget_id,body:n},{onSuccess:()=>c(null)}),onClose:()=>c(null)},y.budget_id):null,e.jsxs(te,{children:[e.jsx(re,{children:e.jsxs("tr",{children:[e.jsx(S,{children:"Budget"}),e.jsx(S,{children:"Limit (per user)"}),e.jsx(S,{children:"Reset"}),e.jsx(S,{children:"Users"}),e.jsx(S,{children:"Usage"}),e.jsx(S,{className:"text-right",children:"Actions"})]})}),e.jsx("tbody",{children:T?e.jsx(ae,{colSpan:6}):D.length===0?e.jsx(ne,{colSpan:6,children:"No budgets yet. Create one to cap spending."}):D.map(n=>e.jsxs(d.Fragment,{children:[e.jsxs(ie,{selected:h===n.budget_id,onClick:()=>{o(!1),c(n.budget_id)},children:[e.jsx(C,{className:"font-medium text-[var(--otari-ink)]",children:e.jsxs("div",{className:"flex flex-col gap-0.5",children:[e.jsx("span",{children:n.name??e.jsx("span",{className:"text-[var(--otari-muted)]",children:"(unnamed)"})}),e.jsx("code",{className:"text-[11px] text-[var(--otari-muted)]",title:n.budget_id,children:V(n.budget_id)})]})}),e.jsx(C,{children:n.max_budget===null?e.jsx("span",{className:"text-[var(--otari-muted)]",children:"Unlimited"}):w(n.max_budget)}),e.jsx(C,{className:"text-[var(--otari-muted)]",children:ge(n.budget_duration_sec)}),e.jsx(C,{className:"text-[var(--otari-muted)]",children:n.user_count}),e.jsx(C,{children:e.jsx(fe,{budget:n})}),e.jsx(C,{children:e.jsxs("div",{className:"flex items-center justify-end gap-1.5",onClick:f=>f.stopPropagation(),children:[e.jsx(g,{size:"sm",variant:"ghost",onPress:()=>t(f=>f===n.budget_id?null:n.budget_id),children:p===n.budget_id?"Hide history":"History"}),e.jsx(g,{size:"sm",variant:"ghost",onPress:()=>{o(!1),c(n.budget_id)},children:"Edit"}),e.jsx(ve,{label:H(n),isPending:l.isPending,onConfirm:()=>l.mutate(n.budget_id)})]})})]}),p===n.budget_id?e.jsx("tr",{className:"border-b border-[var(--otari-line)] bg-[var(--otari-bg)]",children:e.jsx("td",{colSpan:6,children:e.jsx(je,{budgetId:n.budget_id})})}):null]},n.budget_id))})]})]})}export{Pe as BudgetsPage}; diff --git a/src/gateway/static/dashboard/assets/BudgetsPage-iAjnK5BF.js b/src/gateway/static/dashboard/assets/BudgetsPage-iAjnK5BF.js deleted file mode 100644 index 1cc6d4f7..00000000 --- a/src/gateway/static/dashboard/assets/BudgetsPage-iAjnK5BF.js +++ /dev/null @@ -1 +0,0 @@ -import{j as e}from"./tanstack-query-1t81HyiD.js";import{r as d}from"./react-dgEcD0HR.js";import{j as Y,u as G,k as K,l as Q,m as X,n as J,P as Z,E as R,I as ee,o as se}from"./index-DAVt9uB3.js";import{F as L}from"./Field-HzRk1KDP.js";import{T as te,a as re,b as S,L as ae,c as ne,d as ie,e as C}from"./Table-CLdjdyTx.js";import{C as U,I as le,a as de,b as oe,B as g,d as E,S as ue}from"./heroui-BX6JwHY-.js";const ce=50;function me({value:s,onChange:r,users:a,label:i,description:l}){const[m,x]=d.useState(""),o=d.useMemo(()=>a.filter(t=>!t.user_id.startsWith("apikey-")).map(t=>({id:t.user_id,label:t.alias?`${t.user_id} (${t.alias})`:t.user_id})),[a]),h=d.useMemo(()=>{const t=m.trim().toLowerCase();return o.filter(u=>!s.includes(u.id)).filter(u=>!t||u.id.toLowerCase().includes(t)||u.label.toLowerCase().includes(t)).slice(0,ce)},[o,s,m]),c=t=>{s.includes(t)||r([...s,t]),x("")},p=t=>r(s.filter(u=>u!==t));return e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsxs("div",{children:[e.jsx("span",{className:"text-sm font-medium text-[var(--otari-ink)]",children:i}),l?e.jsx("p",{className:"text-xs text-[var(--otari-muted)]",children:l}):null]}),s.length>0?e.jsx("div",{className:"flex flex-wrap gap-1.5",children:s.map(t=>e.jsxs("span",{className:"inline-flex items-center gap-1 rounded-full bg-[var(--otari-brand-tint)] px-2.5 py-1 font-mono text-xs text-[var(--otari-brand-dark)]",children:[t,e.jsx("button",{type:"button","aria-label":`Remove ${t}`,onClick:()=>p(t),className:"text-[var(--otari-brand-dark)] hover:text-red-700",children:"×"})]},t))}):null,o.length===0?e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"No users yet. Create users first, then assign them here or from the Users page."}):e.jsxs(U.Root,{allowsEmptyCollection:!0,menuTrigger:"input",inputValue:m,onInputChange:x,selectedKey:null,onSelectionChange:t=>{t!=null&&c(String(t))},className:"flex flex-col gap-1",children:[e.jsxs(U.InputGroup,{children:[e.jsx(le,{"aria-label":"Add a user",placeholder:"Search users…",autoComplete:"off"}),e.jsx(U.Trigger,{})]}),e.jsx(U.Popover,{children:e.jsx(de,{items:h,className:"max-h-72 overflow-auto",children:t=>e.jsx(oe,{id:t.id,textValue:t.label,children:t.label})})})]})]})}const xe=new Intl.NumberFormat(void 0,{style:"currency",currency:"USD",maximumFractionDigits:2});function w(s){return xe.format(s)}const b=86400,$=3600,I=[{label:"No reset",seconds:null},{label:"Daily",seconds:b},{label:"Weekly",seconds:7*b},{label:"Monthly",seconds:30*b}];function ge(s){if(s===null)return"No reset";const r=I.find(a=>a.seconds===s);return r?r.label:s%b===0?`Every ${s/b} days`:s%$===0?`Every ${s/$} hours`:`Every ${s}s`}function F(s){if(!s)return"—";const r=new Date(s);return Number.isNaN(r.getTime())?"—":r.toLocaleString()}function he(s){const r=s.trim();if(r==="")return{value:null,valid:!0};const a=Number(r);return!Number.isFinite(a)||a<0?{value:null,valid:!1}:{value:a,valid:!0}}function pe({value:s,onChange:r}){const a=I.some(t=>t.seconds===s),[i,l]=d.useState(!a),m=s!==null&&s%b===0?String(s/b):"",[x,o]=d.useState(m);d.useEffect(()=>{o(m)},[m]);const h=x.trim(),c=Number(h),p=h!==""&&(!Number.isInteger(c)||c<=0);return e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsx("span",{className:"text-sm font-medium text-[var(--otari-ink)]",children:"Reset period"}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[I.map(t=>e.jsx(g,{size:"sm",variant:!i&&s===t.seconds?"primary":"outline",onPress:()=>{l(!1),r(t.seconds)},children:t.label},t.label)),e.jsx(g,{size:"sm",variant:i?"primary":"outline",onPress:()=>l(!0),children:"Custom"})]}),i?e.jsx("div",{className:"flex items-end gap-2",children:e.jsx(L,{label:"Every N days",value:x,onChange:t=>{o(t);const u=Number(t.trim());r(t.trim()===""||!Number.isInteger(u)||u<=0?null:u*b)},placeholder:"14",description:p?e.jsx("span",{className:"text-red-700",children:"Enter a whole number of days."}):"Whole days between resets."})}):null,e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"Spend returns to zero each period. A user’s clock starts when the budget is assigned to them."})]})}function O({title:s,submitLabel:r,initial:a,error:i,isPending:l,onSubmit:m,onClose:x,assignUsers:o}){const[h,c]=d.useState(a.name??""),[p,t]=d.useState(a.max_budget===null?"":String(a.max_budget)),[u,j]=d.useState(a.budget_duration_sec),[v,N]=d.useState([]),_=he(p),P=()=>{l||!_.valid||m({name:h.trim()||null,max_budget:_.value,budget_duration_sec:u},v)};return e.jsx(E,{children:e.jsxs(E.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsx("div",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:s}),e.jsx(R,{error:i}),e.jsx(L,{label:"Name (optional)",value:h,onChange:c,autoFocus:!0,placeholder:"team-free-tier",description:"A label to recognize this budget later."}),e.jsx(L,{label:"Spending limit (USD)",value:p,onChange:t,placeholder:"100.00",description:_.valid?"The most a single user on this budget may spend per period. Leave blank for no limit.":e.jsx("span",{className:"text-red-700",children:"Enter a non-negative number, or leave blank for no limit."})}),e.jsx(pe,{value:u,onChange:j}),o?e.jsx(me,{label:"Assign to users (optional)",description:"Attach this budget to existing users now. You can also manage assignments later on the Users page.",value:v,onChange:N,users:o}):null,e.jsxs("div",{className:"flex gap-2",children:[e.jsx(g,{variant:"primary",isDisabled:l||!_.valid,onPress:P,children:l?"Saving…":r}),e.jsx(g,{variant:"ghost",isDisabled:l,onPress:x,children:"Cancel"})]})]})})}function fe({budget:s}){if(s.user_count===0)return e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"No users assigned"});const r=s.total_spend;if(s.max_budget===null)return e.jsxs("span",{className:"text-xs text-[var(--otari-ink)]",children:[w(r)," spent",e.jsx("span",{className:"text-[var(--otari-muted)]",children:" · no limit"})]});const a=s.max_budget*s.user_count,i=a>0?Math.min(100,r/a*100):0,l=r>a;return e.jsxs("div",{className:"flex min-w-[140px] flex-col gap-1",children:[e.jsxs("div",{className:"flex items-baseline justify-between gap-2 text-xs",children:[e.jsx("span",{className:"text-[var(--otari-ink)]",children:w(r)}),e.jsxs("span",{className:"text-[var(--otari-muted)]",children:["of ",w(a)]})]}),e.jsx("div",{className:"h-1.5 w-full overflow-hidden rounded-full bg-[var(--otari-line)]",role:"progressbar","aria-valuenow":Math.round(i),"aria-valuemin":0,"aria-valuemax":100,"aria-label":"Aggregate spend against total allocation",children:e.jsx("div",{className:`h-full rounded-full ${l?"bg-red-500":"bg-[var(--otari-brand)]"}`,style:{width:`${Math.max(i,l?100:2)}%`}})})]})}function je({budgetId:s}){const r=se(s);if(r.isLoading)return e.jsxs("div",{className:"flex items-center gap-2 px-4 py-4 text-sm text-[var(--otari-muted)]",children:[e.jsx(ue,{size:"sm"})," Loading reset history…"]});if(r.error)return e.jsx("div",{className:"px-4 py-4",children:e.jsx(R,{error:r.error})});const a=r.data??[];return a.length===0?e.jsx("div",{className:"px-4 py-4 text-sm text-[var(--otari-muted)]",children:"No resets recorded yet for this budget."}):e.jsx("div",{className:"overflow-x-auto px-4 py-3",children:e.jsxs("table",{className:"w-full border-collapse text-xs",children:[e.jsx("thead",{className:"text-left text-[var(--otari-muted)]",children:e.jsxs("tr",{children:[e.jsx("th",{className:"py-1.5 pr-4 font-medium",children:"User"}),e.jsx("th",{className:"py-1.5 pr-4 font-medium",children:"Spend cleared"}),e.jsx("th",{className:"py-1.5 pr-4 font-medium",children:"Reset at"}),e.jsx("th",{className:"py-1.5 font-medium",children:"Next reset"})]})}),e.jsx("tbody",{children:a.map(i=>e.jsxs("tr",{className:"border-t border-[var(--otari-line)]",children:[e.jsx("td",{className:"py-1.5 pr-4",children:e.jsx("code",{children:i.user_id??"—"})}),e.jsx("td",{className:"py-1.5 pr-4 text-[var(--otari-ink)]",children:w(i.previous_spend)}),e.jsx("td",{className:"py-1.5 pr-4 text-[var(--otari-muted)]",children:F(i.reset_at)}),e.jsx("td",{className:"py-1.5 text-[var(--otari-muted)]",children:F(i.next_reset_at)})]},i.id))})]})})}function be({onCreate:s}){return e.jsx(E,{children:e.jsxs(E.Content,{className:"flex flex-col gap-4 p-6",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-semibold text-[var(--otari-ink)]",children:"No budgets yet"}),e.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:"A budget caps how much a user may spend and, optionally, resets that spend on a schedule. Create one, then assign it to users to enforce a limit."})]}),e.jsx("div",{children:e.jsx(g,{variant:"primary",onPress:s,children:"Create your first budget"})})]})})}function ve({label:s,isPending:r,onConfirm:a}){const[i,l]=d.useState(!1);return i?e.jsxs("div",{className:"flex flex-col items-end gap-1.5 rounded-lg border border-amber-200 bg-amber-50 p-2 text-right",children:[e.jsxs("span",{className:"max-w-xs text-xs text-amber-800",children:["Delete ",e.jsx("strong",{children:s}),"? Users keep their spend but lose this limit. Cannot be undone."]}),e.jsxs("span",{className:"inline-flex gap-1",children:[e.jsx(g,{size:"sm",variant:"danger",isDisabled:r,onPress:a,children:"Delete permanently"}),e.jsx(g,{size:"sm",variant:"ghost",isDisabled:r,onPress:()=>l(!1),children:"Cancel"})]})]}):e.jsx(g,{size:"sm",variant:"danger-soft",onPress:()=>l(!0),children:"Delete"})}function V(s){return s.split("-")[0]}function H(s){return s.name??V(s.budget_id)}function Pe(){const s=Y(),r=G(),a=K(),i=Q(),l=X(),m=J(),[x,o]=d.useState(!1),[h,c]=d.useState(null),[p,t]=d.useState(null),[u,j]=d.useState(null),[v,N]=d.useState(null),[_,P]=d.useState(!1),D=s.data??[],T=s.isLoading,y=D.find(n=>n.budget_id===h)??null,z=!T&&D.length===0&&!x,M=async(n,f)=>{P(!0),j(null);const B=await Promise.allSettled(f.map(k=>m.mutateAsync({id:k,body:{budget_id:n}})));P(!1);const A=B.flatMap((k,q)=>k.status==="rejected"?[f[q]]:[]);if(A.length>0){N({budgetId:n,userIds:A}),j(new Error(`Budget created, but could not assign it to: ${A.join(", ")}. Retry to try again.`));return}N(null),o(!1)},W=(n,f)=>{if(v){M(v.budgetId,v.userIds);return}j(null),a.mutate(n,{onSuccess:async B=>{if(f.length>0){await M(B.budget_id,f);return}o(!1)}})};return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(Z,{title:"Budgets",description:"Define spending limits and reset schedules. Assign a budget to users to enforce it.",action:x||z?null:e.jsx(g,{variant:"primary",onPress:()=>{c(null),j(null),N(null),o(!0)},children:"Create budget"})}),e.jsx(R,{error:s.error??a.error??i.error??l.error??m.error}),e.jsx(ee,{children:"Assign a budget to users when you create it, or later from the Users page. Each row’s usage aggregates the spend of the users currently on that budget."}),z?e.jsx(be,{onCreate:()=>{c(null),j(null),N(null),o(!0)}}):null,x?e.jsx(O,{title:"Create budget",submitLabel:v?"Retry assignments":"Create budget",initial:{name:null,max_budget:null,budget_duration_sec:null},error:a.error??u,isPending:a.isPending||_,assignUsers:r.data??[],onSubmit:W,onClose:()=>{j(null),N(null),o(!1)}}):null,y?e.jsx(O,{title:`Edit budget ${H(y)}`,submitLabel:"Save changes",initial:{name:y.name,max_budget:y.max_budget,budget_duration_sec:y.budget_duration_sec},error:i.error,isPending:i.isPending,onSubmit:n=>i.mutate({id:y.budget_id,body:n},{onSuccess:()=>c(null)}),onClose:()=>c(null)},y.budget_id):null,e.jsxs(te,{children:[e.jsx(re,{children:e.jsxs("tr",{children:[e.jsx(S,{children:"Budget"}),e.jsx(S,{children:"Limit (per user)"}),e.jsx(S,{children:"Reset"}),e.jsx(S,{children:"Users"}),e.jsx(S,{children:"Usage"}),e.jsx(S,{className:"text-right",children:"Actions"})]})}),e.jsx("tbody",{children:T?e.jsx(ae,{colSpan:6}):D.length===0?e.jsx(ne,{colSpan:6,children:"No budgets yet. Create one to cap spending."}):D.map(n=>e.jsxs(d.Fragment,{children:[e.jsxs(ie,{selected:h===n.budget_id,onClick:()=>{o(!1),c(n.budget_id)},children:[e.jsx(C,{className:"font-medium text-[var(--otari-ink)]",children:e.jsxs("div",{className:"flex flex-col gap-0.5",children:[e.jsx("span",{children:n.name??e.jsx("span",{className:"text-[var(--otari-muted)]",children:"(unnamed)"})}),e.jsx("code",{className:"text-[11px] text-[var(--otari-muted)]",title:n.budget_id,children:V(n.budget_id)})]})}),e.jsx(C,{children:n.max_budget===null?e.jsx("span",{className:"text-[var(--otari-muted)]",children:"Unlimited"}):w(n.max_budget)}),e.jsx(C,{className:"text-[var(--otari-muted)]",children:ge(n.budget_duration_sec)}),e.jsx(C,{className:"text-[var(--otari-muted)]",children:n.user_count}),e.jsx(C,{children:e.jsx(fe,{budget:n})}),e.jsx(C,{children:e.jsxs("div",{className:"flex items-center justify-end gap-1.5",onClick:f=>f.stopPropagation(),children:[e.jsx(g,{size:"sm",variant:"ghost",onPress:()=>t(f=>f===n.budget_id?null:n.budget_id),children:p===n.budget_id?"Hide history":"History"}),e.jsx(g,{size:"sm",variant:"ghost",onPress:()=>{o(!1),c(n.budget_id)},children:"Edit"}),e.jsx(ve,{label:H(n),isPending:l.isPending,onConfirm:()=>l.mutate(n.budget_id)})]})})]}),p===n.budget_id?e.jsx("tr",{className:"border-b border-[var(--otari-line)] bg-[var(--otari-bg)]",children:e.jsx("td",{colSpan:6,children:e.jsx(je,{budgetId:n.budget_id})})}):null]},n.budget_id))})]})]})}export{Pe as BudgetsPage}; diff --git a/src/gateway/static/dashboard/assets/KeysPage-C6eaoTUP.js b/src/gateway/static/dashboard/assets/KeysPage-DCo4FFYU.js similarity index 99% rename from src/gateway/static/dashboard/assets/KeysPage-C6eaoTUP.js rename to src/gateway/static/dashboard/assets/KeysPage-DCo4FFYU.js index 3e4a1297..2daf1e46 100644 --- a/src/gateway/static/dashboard/assets/KeysPage-C6eaoTUP.js +++ b/src/gateway/static/dashboard/assets/KeysPage-DCo4FFYU.js @@ -1,4 +1,4 @@ -import{j as e}from"./tanstack-query-1t81HyiD.js";import{r as m}from"./react-dgEcD0HR.js";import{p as $,q as E,r as z,s as K,P as H,E as T,t as B,u as M,I as V}from"./index-DAVt9uB3.js";import{F as k}from"./Field-HzRk1KDP.js";import{M as O,a as A}from"./ModelScopeControl-CkKcIwGe.js";import{C as _,L as U,I as q,a as W,b as G,D as Y,B as g,f as P,d as C}from"./heroui-BX6JwHY-.js";import{T as J,a as Q,b as v,L as X,c as Z,d as ee,e as y}from"./Table-CLdjdyTx.js";function te({value:t,onChange:s,users:n,description:i}){const c=n.filter(a=>!a.user_id.startsWith("apikey-")).map(a=>({id:a.user_id,name:a.alias?`${a.user_id} (${a.alias})`:a.user_id})),[l,o]=m.useState(t),u=l.trim().toLowerCase(),j=c.filter(a=>!u||a.id.toLowerCase().includes(u)||a.name.toLowerCase().includes(u)).slice(0,50),p=a=>{const x=a.trim(),w=c.find(N=>N.id===x||N.name===x);return w?w.id:x},d=p(l),h=c.some(a=>a.id===d),f=d!==""&&!h?e.jsxs("span",{children:["Creates a new user ",e.jsx("code",{children:d}),"."]}):i??"Spend and budgets track against this user.";return e.jsxs(_.Root,{allowsCustomValue:!0,allowsEmptyCollection:!0,menuTrigger:"focus",inputValue:l,onInputChange:a=>{o(a),s(p(a))},onSelectionChange:a=>{if(a!=null){const x=String(a);o(x),s(x)}},className:"flex max-w-md flex-col gap-1",children:[e.jsx(U,{className:"text-sm font-medium text-[var(--otari-ink)]",children:"Owner"}),e.jsxs(_.InputGroup,{children:[e.jsx(q,{placeholder:"Pick a user, or type a new id…",autoComplete:"off","data-1p-ignore":!0,"data-lpignore":"true",onFocus:a=>a.currentTarget.select()}),e.jsx(_.Trigger,{})]}),e.jsx(_.Popover,{children:e.jsx(W,{items:j,className:"max-h-72 overflow-auto",children:a=>e.jsx(G,{id:a.id,textValue:a.name,children:a.name})})}),e.jsx(Y,{className:"text-xs text-[var(--otari-muted)]",children:f})]})}function L(t){if(!t)return"—";const s=new Date(t);return Number.isNaN(s.getTime())?"—":s.toLocaleDateString()}function se(t){if(!t)return null;const s=new Date(t).getTime();if(Number.isNaN(s))return null;const n=Math.round((s-Date.now())/1e3),i=Math.abs(n),c=[["day",86400],["hour",3600],["minute",60]],l=new Intl.RelativeTimeFormat(void 0,{numeric:"auto"});for(const[o,u]of c)if(i>=u)return l.format(Math.round(n/u),o);return l.format(n,"second")}function ne(t){if(!t.expires_at)return!1;const s=new Date(t.expires_at).getTime();return!Number.isNaN(s)&&sString(i).padStart(2,"0");return`${s.getFullYear()}-${n(s.getMonth()+1)}-${n(s.getDate())}T${n(s.getHours())}:${n(s.getMinutes())}`}const ae=t=>(t??"").startsWith("apikey-");function I({label:t,value:s,multiline:n=!1,fieldRef:i}){const c=m.useRef(null),l=i??c,[o,u]=m.useState(!1),[j,p]=m.useState(!1),d=async()=>{var f,a,x;(f=l.current)==null||f.focus(),(a=l.current)==null||a.select();try{if((x=navigator.clipboard)!=null&&x.writeText){await navigator.clipboard.writeText(s),u(!0),p(!1),window.setTimeout(()=>u(!1),2e3);return}}catch{}p(!0)},h="w-full rounded-lg border border-[var(--otari-line)] bg-[var(--otari-bg)] px-3 py-2 font-mono text-xs text-[var(--otari-ink)]";return e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-xs font-medium text-[var(--otari-muted)]",children:t}),e.jsx(g,{size:"sm",variant:"outline",onPress:d,children:o?"Copied":"Copy"})]}),n?e.jsx("textarea",{ref:l,readOnly:!0,rows:s.split(` +import{j as e}from"./tanstack-query-1t81HyiD.js";import{r as m}from"./react-dgEcD0HR.js";import{p as $,q as E,r as z,s as K,P as H,E as T,t as B,u as M,I as V}from"./index-BJySXQ_a.js";import{F as k}from"./Field-HzRk1KDP.js";import{M as O,a as A}from"./ModelScopeControl-DiX2Etqz.js";import{C as _,L as U,I as q,a as W,b as G,D as Y,B as g,f as P,d as C}from"./heroui-BX6JwHY-.js";import{T as J,a as Q,b as v,L as X,c as Z,d as ee,e as y}from"./Table-CLdjdyTx.js";function te({value:t,onChange:s,users:n,description:i}){const c=n.filter(a=>!a.user_id.startsWith("apikey-")).map(a=>({id:a.user_id,name:a.alias?`${a.user_id} (${a.alias})`:a.user_id})),[l,o]=m.useState(t),u=l.trim().toLowerCase(),j=c.filter(a=>!u||a.id.toLowerCase().includes(u)||a.name.toLowerCase().includes(u)).slice(0,50),p=a=>{const x=a.trim(),w=c.find(N=>N.id===x||N.name===x);return w?w.id:x},d=p(l),h=c.some(a=>a.id===d),f=d!==""&&!h?e.jsxs("span",{children:["Creates a new user ",e.jsx("code",{children:d}),"."]}):i??"Spend and budgets track against this user.";return e.jsxs(_.Root,{allowsCustomValue:!0,allowsEmptyCollection:!0,menuTrigger:"focus",inputValue:l,onInputChange:a=>{o(a),s(p(a))},onSelectionChange:a=>{if(a!=null){const x=String(a);o(x),s(x)}},className:"flex max-w-md flex-col gap-1",children:[e.jsx(U,{className:"text-sm font-medium text-[var(--otari-ink)]",children:"Owner"}),e.jsxs(_.InputGroup,{children:[e.jsx(q,{placeholder:"Pick a user, or type a new id…",autoComplete:"off","data-1p-ignore":!0,"data-lpignore":"true",onFocus:a=>a.currentTarget.select()}),e.jsx(_.Trigger,{})]}),e.jsx(_.Popover,{children:e.jsx(W,{items:j,className:"max-h-72 overflow-auto",children:a=>e.jsx(G,{id:a.id,textValue:a.name,children:a.name})})}),e.jsx(Y,{className:"text-xs text-[var(--otari-muted)]",children:f})]})}function L(t){if(!t)return"—";const s=new Date(t);return Number.isNaN(s.getTime())?"—":s.toLocaleDateString()}function se(t){if(!t)return null;const s=new Date(t).getTime();if(Number.isNaN(s))return null;const n=Math.round((s-Date.now())/1e3),i=Math.abs(n),c=[["day",86400],["hour",3600],["minute",60]],l=new Intl.RelativeTimeFormat(void 0,{numeric:"auto"});for(const[o,u]of c)if(i>=u)return l.format(Math.round(n/u),o);return l.format(n,"second")}function ne(t){if(!t.expires_at)return!1;const s=new Date(t.expires_at).getTime();return!Number.isNaN(s)&&sString(i).padStart(2,"0");return`${s.getFullYear()}-${n(s.getMonth()+1)}-${n(s.getDate())}T${n(s.getHours())}:${n(s.getMinutes())}`}const ae=t=>(t??"").startsWith("apikey-");function I({label:t,value:s,multiline:n=!1,fieldRef:i}){const c=m.useRef(null),l=i??c,[o,u]=m.useState(!1),[j,p]=m.useState(!1),d=async()=>{var f,a,x;(f=l.current)==null||f.focus(),(a=l.current)==null||a.select();try{if((x=navigator.clipboard)!=null&&x.writeText){await navigator.clipboard.writeText(s),u(!0),p(!1),window.setTimeout(()=>u(!1),2e3);return}}catch{}p(!0)},h="w-full rounded-lg border border-[var(--otari-line)] bg-[var(--otari-bg)] px-3 py-2 font-mono text-xs text-[var(--otari-ink)]";return e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-xs font-medium text-[var(--otari-muted)]",children:t}),e.jsx(g,{size:"sm",variant:"outline",onPress:d,children:o?"Copied":"Copy"})]}),n?e.jsx("textarea",{ref:l,readOnly:!0,rows:s.split(` `).length,value:s,onFocus:f=>f.currentTarget.select(),className:`${h} resize-none whitespace-pre`}):e.jsx("input",{ref:l,readOnly:!0,value:s,onFocus:f=>f.currentTarget.select(),className:h}),e.jsx("span",{"aria-live":"polite",className:"text-xs text-green-700",children:o?"Copied to clipboard.":""}),j?e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"Selected. Press Ctrl/Cmd-C to copy."}):null]})}function ie({title:t,result:s,onClose:n}){const i=m.useRef(null),c=m.useRef(null),l=typeof window<"u"?window.location.origin:"",o=s.key;m.useEffect(()=>{var d,h;(d=c.current)==null||d.focus(),(h=c.current)==null||h.select()},[]);const u=d=>{var x;if(d.key!=="Tab")return;const h=(x=i.current)==null?void 0:x.querySelectorAll('button, input, textarea, a[href], [tabindex]:not([tabindex="-1"])');if(!h||h.length===0)return;const f=h[0],a=h[h.length-1];d.shiftKey&&document.activeElement===f?(d.preventDefault(),a.focus()):!d.shiftKey&&document.activeElement===a&&(d.preventDefault(),f.focus())},j=[`curl ${l}/v1/chat/completions \\`,` -H "Otari-Key: ${o}" \\`,' -H "Content-Type: application/json" \\',` -d '{"model": "your-model", "messages": [{"role": "user", "content": "Hello"}]}'`].join(` `),p=["from openai import OpenAI","",`client = OpenAI(base_url="${l}/v1", api_key="${o}")`,"resp = client.chat.completions.create(",' model="your-model",',' messages=[{"role": "user", "content": "Hello"}],',")","print(resp.choices[0].message.content)"].join(` `);return e.jsx("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4",role:"presentation",children:e.jsxs("div",{ref:i,role:"dialog","aria-modal":"true","aria-labelledby":"reveal-title",onKeyDown:u,className:"flex max-h-[90vh] w-full max-w-2xl flex-col gap-4 overflow-y-auto rounded-xl bg-[var(--otari-surface)] p-6 shadow-xl",children:[e.jsx("h2",{id:"reveal-title",className:"text-lg font-semibold text-[var(--otari-ink)]",children:t}),e.jsx(V,{tone:"warning",children:"Copy this key now. For security it is shown only once and cannot be retrieved later. If you lose it, use Regenerate to issue a new secret."}),e.jsxs("p",{className:"text-xs text-[var(--otari-muted)]",children:["Model access: ",A(s.allowed_models).text,"."]}),e.jsx(I,{label:"Secret key",value:o,fieldRef:c}),e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-sm font-medium text-[var(--otari-ink)]",children:"Make your first call"}),e.jsxs("p",{className:"text-xs text-[var(--otari-muted)]",children:["Replace ",e.jsx("code",{children:"your-model"})," with a model from the Models page."]})]}),e.jsx(I,{label:"curl",value:j,multiline:!0}),e.jsx(I,{label:"Python (OpenAI SDK)",value:p,multiline:!0})]}),e.jsx("div",{className:"flex justify-end",children:e.jsx(g,{variant:"primary",onPress:n,children:"I’ve saved this key"})})]})})}function R({trigger:t,message:s,confirmLabel:n,isPending:i,onConfirm:c}){const[l,o]=m.useState(!1);return l?e.jsxs("div",{className:"flex flex-col items-end gap-1.5 rounded-lg border border-amber-200 bg-amber-50 p-2 text-right",children:[e.jsx("span",{className:"max-w-xs text-xs text-amber-800",children:s}),e.jsxs("span",{className:"inline-flex gap-1",children:[e.jsx(g,{size:"sm",variant:"danger",isDisabled:i,onPress:c,children:n}),e.jsx(g,{size:"sm",variant:"ghost",isDisabled:i,onPress:()=>o(!1),children:"Cancel"})]})]}):e.jsx(g,{size:"sm",variant:"danger-soft",onPress:()=>o(!0),children:t})}function F({userId:t,users:s}){const n=t.trim();if(n==="")return e.jsx("p",{className:"text-xs text-[var(--otari-muted)]",children:"Choose an owner above to see the models this key can inherit."});const i=s.find(o=>o.user_id===n);if(!i)return e.jsxs("p",{className:"text-xs text-[var(--otari-muted)]",children:["New user ",e.jsx("code",{children:n})," starts unrestricted, so this key may allow any model."]});const{text:c}=A(i.allowed_models),l=i.allowed_models&&i.allowed_models.length>0?i.allowed_models.join(", "):null;return e.jsxs("p",{className:"text-xs text-[var(--otari-muted)]",children:["Owner ",e.jsx("code",{children:n})," allows ",e.jsx("span",{className:"font-medium text-[var(--otari-ink)]",children:c.toLowerCase()}),l?e.jsxs(e.Fragment,{children:[" (",e.jsx("span",{className:"font-mono",children:l}),")"]}):null,". This key inherits that, or narrows within it."]})}function le({onClose:t,onCreated:s}){const n=B(),i=M(),[c,l]=m.useState(""),[o,u]=m.useState(""),[j,p]=m.useState(!1),[d,h]=m.useState(""),[f,a]=m.useState(null),[x,w]=m.useState(!0),N=o!==""&&new Date(o).getTime(){if(n.isPending||!x||r)return;const S={key_name:c.trim()||null,user_id:d.trim(),expires_at:o?new Date(o).toISOString():null,allowed_models:f};n.mutate(S,{onSuccess:D=>{s(D),t()}})};return e.jsx(C,{children:e.jsxs(C.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsx("div",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:"Create API key"}),e.jsx(T,{error:n.error}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsx(k,{label:"Name",value:c,onChange:l,placeholder:"ci-bot",autoFocus:!0,description:"A label to recognize this key later."}),e.jsx(k,{label:"Expires (optional)",value:o,onChange:u,type:"datetime-local",description:N?e.jsx("span",{className:"text-red-700",children:"That time is in the past; the key would be rejected immediately."}):"Leave blank for a key that never expires."})]}),e.jsx(te,{value:d,onChange:h,users:i.data??[]}),e.jsx("button",{type:"button",className:"self-start text-xs font-medium text-[var(--otari-brand-dark)]",onClick:()=>p(S=>!S),children:j?"Hide advanced":"Advanced (restrict models)"}),j?e.jsxs("div",{className:"flex flex-col gap-4 rounded-lg border border-[var(--otari-line)] p-4",children:[e.jsx(F,{userId:d,users:i.data??[]}),e.jsx(O,{title:"Restrict this key's models",description:"By default this key inherits its owner's access. Optionally narrow it to a subset; a key can never exceed its owner's allowed models.",anyLabel:"Inherit owner access",initial:null,onChange:(S,D)=>{a(S),w(D)}})]}):null,e.jsxs("div",{className:"flex gap-2",children:[e.jsx(g,{variant:"primary",isDisabled:n.isPending||!x||r,onPress:b,children:n.isPending?"Creating…":"Create key"}),e.jsx(g,{variant:"ghost",onPress:t,children:"Cancel"})]})]})})}function oe({apiKey:t,onClose:s}){const n=E(),i=M(),[c,l]=m.useState(t.key_name??""),[o,u]=m.useState(re(t.expires_at)),[j,p]=m.useState(t.allowed_models),[d,h]=m.useState(!0),f=()=>{n.isPending||!d||n.mutate({id:t.id,body:{key_name:c.trim()||null,expires_at:o?new Date(o).toISOString():null,allowed_models:j}},{onSuccess:s})};return e.jsx(C,{children:e.jsxs(C.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsxs("div",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:["Edit ",e.jsx("code",{children:t.key_name??t.id})]}),e.jsx(T,{error:n.error}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsx(k,{label:"Name",value:c,onChange:l,placeholder:"ci-bot"}),e.jsx(k,{label:"Expires",value:o,onChange:u,type:"datetime-local",description:"Blank clears the expiry."})]}),t.user_id?e.jsx(F,{userId:t.user_id,users:i.data??[]}):null,e.jsx(O,{title:"Restrict this key's models",description:"This key inherits its owner's access by default. Narrow it to a subset here; it can never exceed the owner's allowed models.",anyLabel:"Inherit owner access",initial:t.allowed_models,onChange:(a,x)=>{p(a),h(x)}}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(g,{variant:"primary",isDisabled:n.isPending||!d,onPress:f,children:n.isPending?"Saving…":"Save changes"}),e.jsx(g,{variant:"ghost",onPress:s,children:"Cancel"})]})]})})}function ce({apiKey:t}){return t.is_active?ne(t)?e.jsx(P,{size:"sm",color:"warning",children:"Expired"}):e.jsx(P,{size:"sm",color:"accent",children:"Active"}):e.jsx(P,{size:"sm",color:"default",children:"Disabled"})}function de({allowed:t}){const{text:s,tone:n}=A(t),i=n==="danger"?"text-red-700 font-medium":n==="muted"?"text-[var(--otari-muted)]":"text-[var(--otari-brand-dark)] font-medium",c=t&&t.length>0?t.join(", "):void 0;return e.jsx("span",{className:`text-xs ${i}`,title:c,children:s})}function ue({onCreate:t}){return e.jsx(C,{children:e.jsxs(C.Content,{className:"flex flex-col gap-4 p-6",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-semibold text-[var(--otari-ink)]",children:"No API keys yet"}),e.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:"An API key authenticates callers to this gateway. Create one to make your first request; the secret is shown once, so keep it somewhere safe."})]}),e.jsx("div",{children:e.jsx(g,{variant:"primary",onPress:t,children:"Create your first key"})})]})})}function ve(){const t=$(),s=E(),n=z(),i=K(),[c,l]=m.useState(!1),[o,u]=m.useState(null),[j,p]=m.useState(null),d=t.data??[],h=t.isLoading,f=d.find(r=>r.id===o)??null,a=!h&&d.length===0&&!c,x=r=>r.key_name??r.id,w=(r,b)=>s.mutate({id:r.id,body:{is_active:b}}),N=r=>n.mutate(r.id,{onSuccess:b=>p({title:`New secret for ${x(r)}`,result:b})});return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(H,{title:"API keys",description:"Issue and revoke the keys that authenticate callers to this gateway. Secrets are shown once at creation.",action:c?null:e.jsx(g,{variant:"primary",onPress:()=>{u(null),l(!0)},children:"Create key"})}),e.jsx(T,{error:t.error??s.error??n.error??i.error}),a?e.jsx(ue,{onCreate:()=>{u(null),l(!0)}}):null,c?e.jsx(le,{onClose:()=>l(!1),onCreated:r=>p({title:"API key created",result:r})}):null,f?e.jsx(oe,{apiKey:f,onClose:()=>u(null)},f.id):null,e.jsxs(J,{children:[e.jsx(Q,{children:e.jsxs("tr",{children:[e.jsx(v,{children:"Name"}),e.jsx(v,{children:"Status"}),e.jsx(v,{children:"Owner"}),e.jsx(v,{children:"Key"}),e.jsx(v,{children:"Created"}),e.jsx(v,{children:"Last used"}),e.jsx(v,{children:"Expires"}),e.jsx(v,{className:"text-right",children:"Actions"})]})}),e.jsx("tbody",{children:h?e.jsx(X,{colSpan:8}):d.length===0?e.jsx(Z,{colSpan:8,children:"No API keys yet. Create one to authenticate a caller."}):d.map(r=>e.jsxs(ee,{selected:o===r.id,onClick:()=>{l(!1),u(r.id)},children:[e.jsx(y,{className:"font-medium text-[var(--otari-ink)]",children:e.jsxs("div",{className:"flex flex-col gap-0.5",children:[e.jsx("span",{children:r.key_name??e.jsx("span",{className:"text-[var(--otari-muted)]",children:"(unnamed)"})}),e.jsx(de,{allowed:r.allowed_models})]})}),e.jsx(y,{children:e.jsx(ce,{apiKey:r})}),e.jsx(y,{className:"text-[var(--otari-muted)]",children:ae(r.user_id)?e.jsx("span",{className:"inline-flex items-center gap-1.5",children:e.jsx(P,{size:"sm",color:"default",children:"virtual"})}):e.jsx("code",{className:"text-xs",children:r.user_id??"—"})}),e.jsx(y,{children:e.jsx("code",{className:"text-xs text-[var(--otari-muted)]",children:r.key_prefix?`${r.key_prefix}…`:"—"})}),e.jsx(y,{className:"text-[var(--otari-muted)]",children:L(r.created_at)}),e.jsx(y,{className:"text-[var(--otari-muted)]",children:se(r.last_used_at)??"never"}),e.jsx(y,{className:"text-[var(--otari-muted)]",children:e.jsx("span",{title:r.expires_at?new Date(r.expires_at).toLocaleString():void 0,children:r.expires_at?L(r.expires_at):"never"})}),e.jsx(y,{children:e.jsxs("div",{className:"flex items-center justify-end gap-1.5",onClick:b=>b.stopPropagation(),children:[r.is_active?e.jsx(g,{size:"sm",variant:"outline",isDisabled:s.isPending,onPress:()=>w(r,!1),children:"Disable"}):e.jsx(g,{size:"sm",variant:"outline",isDisabled:s.isPending,onPress:()=>w(r,!0),children:"Enable"}),e.jsx(g,{size:"sm",variant:"ghost",onPress:()=>{l(!1),u(r.id)},children:"Edit"}),e.jsx(R,{trigger:"Regenerate",confirmLabel:"Regenerate",isPending:n.isPending,message:e.jsxs(e.Fragment,{children:["Regenerate the secret for ",e.jsx("strong",{children:x(r)}),"? The current secret stops working immediately, with no grace period."]}),onConfirm:()=>N(r)}),r.is_active?null:e.jsx(R,{trigger:"Delete",confirmLabel:"Delete permanently",isPending:i.isPending,message:e.jsxs(e.Fragment,{children:["Permanently delete ",e.jsx("strong",{children:x(r)}),"? This removes the key and unlinks its usage history. Cannot be undone."]}),onConfirm:()=>i.mutate(r.id)})]})})]},r.id))})]}),j?e.jsx(ie,{title:j.title,result:j.result,onClose:()=>{p(null),n.reset()}}):null]})}export{ve as KeysPage}; diff --git a/src/gateway/static/dashboard/assets/ModelScopeControl-CkKcIwGe.js b/src/gateway/static/dashboard/assets/ModelScopeControl-DiX2Etqz.js similarity index 98% rename from src/gateway/static/dashboard/assets/ModelScopeControl-CkKcIwGe.js rename to src/gateway/static/dashboard/assets/ModelScopeControl-DiX2Etqz.js index 9466aec5..98e12f81 100644 --- a/src/gateway/static/dashboard/assets/ModelScopeControl-CkKcIwGe.js +++ b/src/gateway/static/dashboard/assets/ModelScopeControl-DiX2Etqz.js @@ -1 +1 @@ -import{j as t}from"./tanstack-query-1t81HyiD.js";import{r as n}from"./react-dgEcD0HR.js";import{J as A,e as $,f as P}from"./index-DAVt9uB3.js";import{C as d,I as R,a as T,b as V}from"./heroui-BX6JwHY-.js";function q(r){return r===null?"any":r.length===0?"block":"only"}const O=50;function Q({initial:r,onChange:m,title:N="Model access",description:w,anyLabel:C="Any model"}){const x=A(),u=$(),v=P(),[i,S]=n.useState(q(r)),[a,g]=n.useState(r??[]),[p,y]=n.useState(""),f=n.useMemo(()=>{var j,k;const e=new Set,s=[],l=(o,c)=>{o&&!e.has(o)&&(e.add(o),s.push({id:o,label:c}))};for(const o of((j=x.data)==null?void 0:j.providers)??[])l(`${o.instance}:*`,`${o.instance}:* · all ${o.instance} models`);for(const o of((k=u.data)==null?void 0:k.providers)??[])for(const c of o.models)l(c.key,c.key);for(const o of v.data??[])l(o.target,`${o.name} · alias`);return s},[x.data,u.data,v.data]),L=n.useMemo(()=>{const e=p.trim().toLowerCase();return f.filter(s=>!a.includes(s.id)).filter(s=>!e||s.id.toLowerCase().includes(e)||s.label.toLowerCase().includes(e)).slice(0,O)},[f,a,p]),h=(e,s)=>{e==="any"?m(null,!0):e==="block"?m([],!0):m(s,s.length>0)},B=e=>{S(e),h(e,a)},M=e=>{const s=a.includes(e)?a:[...a,e];g(s),y(""),h("only",s)},E=e=>{const s=a.filter(l=>l!==e);g(s),h("only",s)},b=(e,s)=>t.jsx("button",{type:"button","aria-pressed":i===e,onClick:()=>B(e),className:i===e?"rounded-md bg-white px-3 py-1.5 text-sm font-medium text-[var(--otari-ink)] shadow-sm":"rounded-md px-3 py-1.5 text-sm text-[var(--otari-muted)] hover:text-[var(--otari-ink)]",children:s}),I=!u.isLoading&&!x.isLoading&&f.length===0;return t.jsxs("div",{className:"flex flex-col gap-3",children:[t.jsxs("div",{children:[t.jsx("span",{className:"text-sm font-medium text-[var(--otari-ink)]",children:N}),t.jsx("p",{className:"text-xs text-[var(--otari-muted)]",children:w??"Which models this key may list and call. The master key is never restricted, so blocking a key cannot lock you out of the dashboard."})]}),t.jsxs("div",{className:"flex w-fit items-center gap-1 rounded-lg bg-[var(--otari-bg)] p-1",children:[b("any",C),b("only","Only selected"),b("block","Block all")]}),i==="block"?t.jsxs("div",{className:"rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-xs text-amber-800",children:["Blocked from ",t.jsx("strong",{children:"every"})," model until you change this access."]}):null,i==="only"?t.jsxs("div",{className:"flex flex-col gap-2",children:[t.jsx("div",{className:"flex flex-wrap gap-1.5",children:a.length===0?t.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"Pick at least one model below, or choose “Block all”."}):a.map(e=>t.jsxs("span",{className:"inline-flex items-center gap-1 rounded-full bg-[var(--otari-brand-tint)] px-2.5 py-1 font-mono text-xs text-[var(--otari-brand-dark)]",children:[e,t.jsx("button",{type:"button","aria-label":`Remove ${e}`,onClick:()=>E(e),className:"text-[var(--otari-brand-dark)] hover:text-red-700",children:"×"})]},e))}),I?t.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"No providers or models discovered yet. Configure a provider first, then scope this key."}):t.jsxs(d.Root,{allowsEmptyCollection:!0,menuTrigger:"input",inputValue:p,onInputChange:y,selectedKey:null,onSelectionChange:e=>{e!=null&&M(String(e))},className:"flex max-w-md flex-col gap-1",children:[t.jsxs(d.InputGroup,{children:[t.jsx(R,{"aria-label":"Add a model",placeholder:"Search providers, models, aliases…",autoComplete:"off"}),t.jsx(d.Trigger,{})]}),t.jsx(d.Popover,{children:t.jsx(T,{items:L,className:"max-h-72 overflow-auto",children:e=>t.jsx(V,{id:e.id,textValue:e.label,children:e.label})})})]})]}):null]})}function W(r){return r===null?{text:"All models",tone:"muted"}:r.length===0?{text:"No models",tone:"danger"}:{text:"Selected models",tone:"normal"}}export{Q as M,W as a}; +import{j as t}from"./tanstack-query-1t81HyiD.js";import{r as n}from"./react-dgEcD0HR.js";import{J as A,e as $,f as P}from"./index-BJySXQ_a.js";import{C as d,I as R,a as T,b as V}from"./heroui-BX6JwHY-.js";function q(r){return r===null?"any":r.length===0?"block":"only"}const O=50;function Q({initial:r,onChange:m,title:N="Model access",description:w,anyLabel:C="Any model"}){const x=A(),u=$(),v=P(),[i,S]=n.useState(q(r)),[a,g]=n.useState(r??[]),[p,y]=n.useState(""),f=n.useMemo(()=>{var j,k;const e=new Set,s=[],l=(o,c)=>{o&&!e.has(o)&&(e.add(o),s.push({id:o,label:c}))};for(const o of((j=x.data)==null?void 0:j.providers)??[])l(`${o.instance}:*`,`${o.instance}:* · all ${o.instance} models`);for(const o of((k=u.data)==null?void 0:k.providers)??[])for(const c of o.models)l(c.key,c.key);for(const o of v.data??[])l(o.target,`${o.name} · alias`);return s},[x.data,u.data,v.data]),L=n.useMemo(()=>{const e=p.trim().toLowerCase();return f.filter(s=>!a.includes(s.id)).filter(s=>!e||s.id.toLowerCase().includes(e)||s.label.toLowerCase().includes(e)).slice(0,O)},[f,a,p]),h=(e,s)=>{e==="any"?m(null,!0):e==="block"?m([],!0):m(s,s.length>0)},B=e=>{S(e),h(e,a)},M=e=>{const s=a.includes(e)?a:[...a,e];g(s),y(""),h("only",s)},E=e=>{const s=a.filter(l=>l!==e);g(s),h("only",s)},b=(e,s)=>t.jsx("button",{type:"button","aria-pressed":i===e,onClick:()=>B(e),className:i===e?"rounded-md bg-white px-3 py-1.5 text-sm font-medium text-[var(--otari-ink)] shadow-sm":"rounded-md px-3 py-1.5 text-sm text-[var(--otari-muted)] hover:text-[var(--otari-ink)]",children:s}),I=!u.isLoading&&!x.isLoading&&f.length===0;return t.jsxs("div",{className:"flex flex-col gap-3",children:[t.jsxs("div",{children:[t.jsx("span",{className:"text-sm font-medium text-[var(--otari-ink)]",children:N}),t.jsx("p",{className:"text-xs text-[var(--otari-muted)]",children:w??"Which models this key may list and call. The master key is never restricted, so blocking a key cannot lock you out of the dashboard."})]}),t.jsxs("div",{className:"flex w-fit items-center gap-1 rounded-lg bg-[var(--otari-bg)] p-1",children:[b("any",C),b("only","Only selected"),b("block","Block all")]}),i==="block"?t.jsxs("div",{className:"rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-xs text-amber-800",children:["Blocked from ",t.jsx("strong",{children:"every"})," model until you change this access."]}):null,i==="only"?t.jsxs("div",{className:"flex flex-col gap-2",children:[t.jsx("div",{className:"flex flex-wrap gap-1.5",children:a.length===0?t.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"Pick at least one model below, or choose “Block all”."}):a.map(e=>t.jsxs("span",{className:"inline-flex items-center gap-1 rounded-full bg-[var(--otari-brand-tint)] px-2.5 py-1 font-mono text-xs text-[var(--otari-brand-dark)]",children:[e,t.jsx("button",{type:"button","aria-label":`Remove ${e}`,onClick:()=>E(e),className:"text-[var(--otari-brand-dark)] hover:text-red-700",children:"×"})]},e))}),I?t.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"No providers or models discovered yet. Configure a provider first, then scope this key."}):t.jsxs(d.Root,{allowsEmptyCollection:!0,menuTrigger:"input",inputValue:p,onInputChange:y,selectedKey:null,onSelectionChange:e=>{e!=null&&M(String(e))},className:"flex max-w-md flex-col gap-1",children:[t.jsxs(d.InputGroup,{children:[t.jsx(R,{"aria-label":"Add a model",placeholder:"Search providers, models, aliases…",autoComplete:"off"}),t.jsx(d.Trigger,{})]}),t.jsx(d.Popover,{children:t.jsx(T,{items:L,className:"max-h-72 overflow-auto",children:e=>t.jsx(V,{id:e.id,textValue:e.label,children:e.label})})})]})]}):null]})}function W(r){return r===null?{text:"All models",tone:"muted"}:r.length===0?{text:"No models",tone:"danger"}:{text:"Selected models",tone:"normal"}}export{Q as M,W as a}; diff --git a/src/gateway/static/dashboard/assets/ModelsPage-DwBDAaxV.js b/src/gateway/static/dashboard/assets/ModelsPage-C028BOtV.js similarity index 99% rename from src/gateway/static/dashboard/assets/ModelsPage-DwBDAaxV.js rename to src/gateway/static/dashboard/assets/ModelsPage-C028BOtV.js index cb5da755..bb337196 100644 --- a/src/gateway/static/dashboard/assets/ModelsPage-DwBDAaxV.js +++ b/src/gateway/static/dashboard/assets/ModelsPage-C028BOtV.js @@ -1 +1 @@ -import{j as e}from"./tanstack-query-1t81HyiD.js";import{i as rt,u as nt,r as c}from"./react-dgEcD0HR.js";import{v as at,w as st,e as lt,x as ct,P as ot,E as ut,F as E,I as dt,y as ne,z as pt,A as ht,B as xt,D as A,G as $e,H as Ee,C as Ae,h as me}from"./index-DAVt9uB3.js";import{T as mt,a as ft,d as Ce,b as re,L as vt,e as U,c as bt}from"./Table-CLdjdyTx.js";import{B as L,d as ke,f as K}from"./heroui-BX6JwHY-.js";function We(t){const i=t.indexOf(":");return i>0?t.slice(0,i):"—"}function gt(t,i=Date.now()){const r=new Map;for(const n of t){const a=r.get(n.model_key)??[];a.push(n),r.set(n.model_key,a)}const s=[];for(const n of r.values()){const a=[...n].sort((h,p)=>Date.parse(h.effective_at)-Date.parse(p.effective_at)),d=[...a].reverse().find(h=>Date.parse(h.effective_at)<=i);s.push(d??a[0])}return s.sort((n,a)=>n.model_key.localeCompare(a.model_key))}const _t="otari",Me=[{value:"vision",label:"Vision",test:t=>Array.isArray(t.input_modalities)&&t.input_modalities.includes("image")},{value:"tool_call",label:"Tool calling",test:t=>!!t.tool_call},{value:"reasoning",label:"Reasoning",test:t=>!!t.reasoning},{value:"structured_output",label:"Structured output",test:t=>!!t.structured_output},{value:"attachment",label:"Attachments",test:t=>!!t.attachment},{value:"audio",label:"Audio",test:t=>Array.isArray(t.input_modalities)&&t.input_modalities.includes("audio")},{value:"pdf",label:"PDF",test:t=>Array.isArray(t.input_modalities)&&t.input_modalities.includes("pdf")}],jt=[{key:"reasoning",label:"Reasoning"},{key:"tool_call",label:"Tool calling"},{key:"structured_output",label:"Structured output"},{key:"attachment",label:"Attachments"},{key:"temperature",label:"Temperature"}],Te={text:"Text",image:"Image",audio:"Audio",video:"Video",pdf:"PDF"},Pt=[{value:"0",label:"Any context"},{value:"8000",label:"≥ 8K"},{value:"32000",label:"≥ 32K"},{value:"128000",label:"≥ 128K"},{value:"200000",label:"≥ 200K"},{value:"1000000",label:"≥ 1M"}],yt=[{value:"",label:"Any price"},{value:"1",label:"≤ $1 / 1M in"},{value:"3",label:"≤ $3 / 1M in"},{value:"10",label:"≤ $10 / 1M in"},{value:"30",label:"≤ $30 / 1M in"}],Nt=[{value:"",label:"Base prices"},{value:"8000",label:"Compare at 8K"},{value:"128000",label:"Compare at 128K"},{value:"200000",label:"Compare at 200K"},{value:"500000",label:"Compare at 500K"},{value:"1000000",label:"Compare at 1M"}],St=[{value:"all",label:"Any release date"},{value:"365",label:"Past year"},{value:"730",label:"Past 2 years"},{value:"1095",label:"Past 3 years"}],Ct=1440*60*1e3;function Ie(t,i){const r=`${i}:`;return t.startsWith(r)?t.slice(r.length):t}function kt(t,i){const r={inputPrice:t.inputPrice,outputPrice:t.outputPrice,cacheReadPrice:t.cacheReadPrice,cacheWritePrice:t.cacheWritePrice,cacheWrite1hPrice:t.cacheWrite1hPrice};if(i==null)return r;const s=t.pricingTiers.filter(n=>n.min_input_tokens<=i).sort((n,a)=>a.min_input_tokens-n.min_input_tokens)[0];return s?{inputPrice:s.input_price_per_million??r.inputPrice,outputPrice:s.output_price_per_million??r.outputPrice,cacheReadPrice:s.cache_read_price_per_million??r.cacheReadPrice,cacheWritePrice:s.cache_write_price_per_million??r.cacheWritePrice,cacheWrite1hPrice:s.cache_write_1h_price_per_million??r.cacheWrite1hPrice}:r}function ae(t){const i=Number(t);return t.trim()!==""&&Number.isFinite(i)&&i>=0}function R(t){if(t.trim()==="")return!0;const i=Number(t);return Number.isFinite(i)&&i>=0}function V(t){return t.trim()===""?null:Number(t)}function De(t){return t.map((i,r)=>({id:r,minInputTokens:String(i.min_input_tokens),input:i.input_price_per_million==null?"":String(i.input_price_per_million),output:i.output_price_per_million==null?"":String(i.output_price_per_million),cacheRead:i.cache_read_price_per_million==null?"":String(i.cache_read_price_per_million),cacheWrite:i.cache_write_price_per_million==null?"":String(i.cache_write_price_per_million),cacheWrite1h:i.cache_write_1h_price_per_million==null?"":String(i.cache_write_1h_price_per_million)}))}function Oe(t){const i=new Set;return t.every(r=>{const s=Number(r.minInputTokens),n=[r.input,r.output,r.cacheRead,r.cacheWrite,r.cacheWrite1h].some(a=>a.trim()!=="");return!Number.isInteger(s)||s<=0||i.has(s)||!n?!1:(i.add(s),[r.input,r.output,r.cacheRead,r.cacheWrite,r.cacheWrite1h].every(R))})}function Fe(t){return t.map(i=>({min_input_tokens:Number(i.minInputTokens),...i.input.trim()===""?{}:{input_price_per_million:Number(i.input)},...i.output.trim()===""?{}:{output_price_per_million:Number(i.output)},...i.cacheRead.trim()===""?{}:{cache_read_price_per_million:Number(i.cacheRead)},...i.cacheWrite.trim()===""?{}:{cache_write_price_per_million:Number(i.cacheWrite)},...i.cacheWrite1h.trim()===""?{}:{cache_write_1h_price_per_million:Number(i.cacheWrite1h)}}))}function j({value:t,onChange:i,ariaLabel:r}){return e.jsx("input",{type:"number",step:"any",min:"0",inputMode:"decimal","aria-label":r,value:t,onChange:s=>i(s.target.value),className:"w-28 rounded-md border border-[var(--otari-line)] bg-white px-2 py-1 text-right text-sm tabular-nums focus:border-[var(--otari-brand)] focus:outline-none"})}function ze({tiers:t,onChange:i}){const r=(n,a,d)=>{i(t.map(h=>h.id===n?{...h,[a]:d}:h))},s=()=>{const n=t.reduce((a,d)=>Math.max(a,d.id),-1)+1;i([...t,{id:n,minInputTokens:"128000",input:"",output:"",cacheRead:"",cacheWrite:"",cacheWrite1h:""}])};return e.jsxs("div",{className:"flex flex-col gap-2 rounded-lg border border-[var(--otari-line)] p-3",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-xs font-medium text-[var(--otari-ink)]",children:"Long-context price tiers"}),e.jsx("p",{className:"text-xs text-[var(--otari-muted)]",children:"At a threshold, listed rates replace the base rate for the whole request."})]}),e.jsx(L,{size:"sm",variant:"outline",onPress:s,children:"Add tier"})]}),t.map(n=>e.jsxs("div",{className:"flex flex-wrap items-end gap-2 border-t border-[var(--otari-line)] pt-2",children:[e.jsxs("label",{className:"flex flex-col gap-1 text-xs text-[var(--otari-muted)]",children:["Context ≥ tokens",e.jsx("input",{type:"number",min:"1",step:"1",inputMode:"numeric","aria-label":"Tier context threshold",value:n.minInputTokens,onChange:a=>r(n.id,"minInputTokens",a.target.value),className:"w-28 rounded-md border border-[var(--otari-line)] bg-white px-2 py-1 text-right text-sm tabular-nums focus:border-[var(--otari-brand)] focus:outline-none"})]}),e.jsxs("label",{className:"flex flex-col gap-1 text-xs text-[var(--otari-muted)]",children:["Input",e.jsx(j,{value:n.input,onChange:a=>r(n.id,"input",a),ariaLabel:"Tier input price"})]}),e.jsxs("label",{className:"flex flex-col gap-1 text-xs text-[var(--otari-muted)]",children:["Output",e.jsx(j,{value:n.output,onChange:a=>r(n.id,"output",a),ariaLabel:"Tier output price"})]}),e.jsxs("label",{className:"flex flex-col gap-1 text-xs text-[var(--otari-muted)]",children:["Cache read",e.jsx(j,{value:n.cacheRead,onChange:a=>r(n.id,"cacheRead",a),ariaLabel:"Tier cache read price"})]}),e.jsxs("label",{className:"flex flex-col gap-1 text-xs text-[var(--otari-muted)]",children:["Cache write",e.jsx(j,{value:n.cacheWrite,onChange:a=>r(n.id,"cacheWrite",a),ariaLabel:"Tier cache write price"})]}),e.jsxs("label",{className:"flex flex-col gap-1 text-xs text-[var(--otari-muted)]",children:["1h write",e.jsx(j,{value:n.cacheWrite1h,onChange:a=>r(n.id,"cacheWrite1h",a),ariaLabel:"Tier 1 hour cache write price"})]}),e.jsx(L,{size:"sm",variant:"ghost",onPress:()=>i(t.filter(a=>a.id!==n.id)),children:"Remove"})]},n.id))]})}function Wt({source:t}){return t==="configured"?e.jsx(K,{size:"sm",color:"default",children:"configured"}):t==="default"||t==="alias"?e.jsx(K,{size:"sm",color:"accent",children:t}):e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"not priced"})}function se({label:t,tone:i="info",children:r}){const s=c.useId();return e.jsxs("span",{className:"group relative inline-flex items-center font-normal normal-case",children:[e.jsx("button",{type:"button","aria-label":t,"aria-describedby":s,className:`inline-flex h-4 w-4 items-center justify-center rounded-full border text-[10px] leading-none ${i==="warning"?"border-[#c2843a] text-[#b45309]":"border-[var(--otari-line)] text-[var(--otari-muted)] hover:border-[var(--otari-brand)] hover:text-[var(--otari-brand)]"}`,children:"i"}),e.jsx("span",{id:s,role:"tooltip",className:"pointer-events-none absolute top-full right-0 z-20 mt-1.5 w-72 rounded-lg border border-[var(--otari-line)] bg-[var(--otari-surface)] px-3 py-2 text-left text-xs font-normal whitespace-normal break-words text-[var(--otari-ink)] opacity-0 shadow-lg transition-opacity group-hover:opacity-100 group-focus-within:opacity-100",children:r})]})}function Mt(){const t=xt();return t.data?t.data.default_pricing?e.jsx(se,{label:"How unpriced models are metered",tone:"info",children:"Default pricing is on: models without a configured price are metered using community-maintained rates (the bundled genai-prices dataset). Set a price to override the fallback."}):e.jsxs(se,{label:"How unpriced models are metered",tone:"warning",children:["Default pricing is off: only models with a configured price are metered.",t.data.require_pricing?" Requests for any other model are rejected (HTTP 402) because require_pricing is on.":" Other models are served without cost tracking."]}):null}function T({label:t,value:i}){return e.jsxs("div",{className:"flex items-baseline justify-between gap-3",children:[e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:t}),e.jsx("span",{className:"text-right text-sm text-[var(--otari-ink)] tabular-nums",children:i})]})}function ie({title:t,children:i}){return e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsx("span",{className:"text-xs font-semibold uppercase tracking-wide text-[var(--otari-muted)]",children:t}),i]})}function Tt({row:t}){const i=$e(),r=Ee(),[s,n]=c.useState(!1),[a,d]=c.useState(""),[h,p]=c.useState(""),[v,P]=c.useState(""),[m,S]=c.useState(""),[k,W]=c.useState(""),[D,y]=c.useState([]),Y=()=>{d(t.inputPrice==null?"":String(t.inputPrice)),p(t.outputPrice==null?"":String(t.outputPrice)),P(t.cacheReadPrice==null?"":String(t.cacheReadPrice)),S(t.cacheWritePrice==null?"":String(t.cacheWritePrice)),W(t.cacheWrite1hPrice==null?"":String(t.cacheWrite1hPrice)),y(De(t.pricingTiers)),n(!0)},M=ae(a)&&ae(h)&&R(v)&&R(m)&&R(k)&&Oe(D),G=()=>{M&&i.mutate({model_key:t.key,input_price_per_million:Number(a),output_price_per_million:Number(h),cache_read_price_per_million:V(v),cache_write_price_per_million:V(m),cache_write_1h_price_per_million:V(k),pricing_tiers:Fe(D)},{onSuccess:()=>n(!1)})};return s?e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"Input $ / 1M"}),e.jsx(j,{value:a,onChange:d,ariaLabel:`Input price for ${t.key}`})]}),e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"Output $ / 1M"}),e.jsx(j,{value:h,onChange:p,ariaLabel:`Output price for ${t.key}`})]}),e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"Cache read $ / 1M"}),e.jsx(j,{value:v,onChange:P,ariaLabel:`Cache read price for ${t.key}`})]}),e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"Cache write $ / 1M"}),e.jsx(j,{value:m,onChange:S,ariaLabel:`Cache write price for ${t.key}`})]}),e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"1h cache write $ / 1M"}),e.jsx(j,{value:k,onChange:W,ariaLabel:`1 hour cache write price for ${t.key}`})]}),e.jsx(ze,{tiers:D,onChange:y}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(L,{size:"sm",variant:"primary",isDisabled:i.isPending||!M,onPress:G,children:"Save"}),e.jsx(L,{size:"sm",variant:"ghost",isDisabled:i.isPending,onPress:()=>n(!1),children:"Cancel"})]}),i.error?e.jsx("span",{className:"text-xs text-red-700",children:me(i.error)}):null]}):e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsx(T,{label:"Input",value:t.inputPrice==null?"—":`${A(t.inputPrice)} / 1M`}),e.jsx(T,{label:"Output",value:t.outputPrice==null?"—":`${A(t.outputPrice)} / 1M`}),e.jsx(T,{label:"Cache read",value:t.cacheReadPrice==null?"—":`${A(t.cacheReadPrice)} / 1M`}),e.jsx(T,{label:"Cache write",value:t.cacheWritePrice==null?"—":`${A(t.cacheWritePrice)} / 1M`}),e.jsx(T,{label:"1h cache write",value:t.cacheWrite1hPrice==null?"—":`${A(t.cacheWrite1hPrice)} / 1M`}),e.jsx(T,{label:"Context tiers",value:t.pricingTiers.length?`${t.pricingTiers.length} configured`:"—"}),e.jsxs("div",{className:"flex items-center gap-2 pt-1",children:[e.jsx(L,{size:"sm",variant:"outline",onPress:Y,children:t.source==="configured"?"Edit price":"Set price"}),t.source==="configured"?e.jsxs(e.Fragment,{children:[e.jsx(Ae,{confirmLabel:"Reset",isPending:r.isPending,onConfirm:()=>r.mutate(t.key),children:"Reset"}),e.jsx(se,{label:"What reset does",children:"Removes the custom price. The model reverts to the default rate (genai-prices) when default pricing is on, otherwise it is metered at no cost."})]}):null,r.error?e.jsx("span",{className:"text-xs text-red-700",children:me(r.error)}):null]})]})}function It({row:t,metadata:i,metadataAvailable:r,onMakeAlias:s,onClose:n}){const a=(i==null?void 0:i.input_modalities)??[],d=(i==null?void 0:i.output_modalities)??[],h=jt.filter(({key:p})=>i==null?void 0:i[p]);return e.jsx(ke,{children:e.jsxs(ke.Content,{className:"flex flex-col gap-5 p-5",children:[e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("h2",{className:"text-base font-semibold break-all text-[var(--otari-ink)]",children:t.model}),i!=null&&i.deprecated?e.jsx(K,{size:"sm",color:"danger",children:"deprecated"}):null]}),e.jsxs("p",{className:"mt-1 text-xs break-all text-[var(--otari-muted)]",children:["Selector: ",e.jsx("code",{children:t.key})]}),i!=null&&i.family?e.jsx("p",{className:"text-xs text-[var(--otari-muted)]",children:i.family}):null]}),e.jsx("button",{type:"button","aria-label":"Close model details",onClick:n,className:"-mt-1 -mr-1 shrink-0 rounded-md px-1.5 py-0.5 text-lg leading-none text-[var(--otari-muted)] hover:bg-[var(--otari-bg)] hover:text-[var(--otari-ink)]",children:"✕"})]}),i!=null&&i.description?e.jsx("p",{className:"text-sm text-[var(--otari-ink)]",children:i.description}):null,e.jsxs(ie,{title:"Pricing",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Wt,{source:t.source}),t.isDiscovered?null:e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"not discovered"})]}),e.jsx(Tt,{row:t},t.key),e.jsx(L,{size:"sm",variant:"outline",onPress:()=>s(t.key),children:"Make an alias"})]}),e.jsxs(ie,{title:"Specs",children:[e.jsx(T,{label:"Context window",value:ne(t.contextWindow)}),e.jsx(T,{label:"Max output",value:ne((i==null?void 0:i.max_output_tokens)??null)}),e.jsx(T,{label:"Knowledge cutoff",value:(i==null?void 0:i.knowledge_cutoff)??"—"}),e.jsx(T,{label:"Released",value:ht(i==null?void 0:i.release_date)}),e.jsx(T,{label:"Open weights",value:i?i.open_weights?"Yes":"No":"—"})]}),e.jsx(ie,{title:"Modalities",children:a.length===0&&d.length===0?e.jsx("span",{className:"text-sm text-[var(--otari-muted)]",children:"Unknown."}):e.jsxs("div",{className:"flex flex-col gap-1.5 text-xs text-[var(--otari-muted)]",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-1",children:[e.jsx("span",{children:"In:"}),a.map(p=>e.jsx(K,{size:"sm",color:"default",children:Te[p]??p},p))]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-1",children:[e.jsx("span",{children:"Out:"}),d.map(p=>e.jsx(K,{size:"sm",color:"default",children:Te[p]??p},p))]})]})}),e.jsx(ie,{title:"Capabilities",children:h.length>0?e.jsx("div",{className:"flex flex-wrap gap-1.5",children:h.map(({key:p,label:v})=>e.jsx(K,{size:"sm",color:"default",children:v},p))}):e.jsx("span",{className:"text-sm text-[var(--otari-muted)]",children:r?"None reported.":"Extended metadata unavailable (models.dev disabled or unreachable)."})})]})})}const Lt=15,$t=[{value:"15",label:"15 per page"},{value:"25",label:"25 per page"},{value:"50",label:"50 per page"}];function Et({value:t,onChange:i,placeholder:r}){return e.jsx("input",{type:"search",value:t,onChange:s=>i(s.target.value),placeholder:r,"aria-label":r,className:"w-full max-w-xs rounded-md border border-[var(--otari-line)] bg-white px-3 py-1.5 text-sm focus:border-[var(--otari-brand)] focus:outline-none"})}function At({page:t,pageCount:i,total:r,pageSize:s,onPage:n,onPageSize:a}){return e.jsxs("div",{className:"flex items-center justify-between px-1 pt-1 text-sm text-[var(--otari-muted)]",children:[e.jsxs("span",{children:[i>1?`Page ${t+1} of ${i} · `:"",pt(r)," model",r===1?"":"s"]}),e.jsxs("span",{className:"inline-flex gap-2",children:[e.jsx(E,{ariaLabel:"Rows per page",value:String(s),onChange:d=>a(Number(d)),options:$t}),i>1?e.jsxs(e.Fragment,{children:[e.jsx(L,{size:"sm",variant:"outline",isDisabled:t===0,onPress:()=>n(t-1),children:"Prev"}),e.jsx(L,{size:"sm",variant:"outline",isDisabled:t>=i-1,onPress:()=>n(t+1),children:"Next"})]}):null]})]})}const Be="otari.dashboard.modelsSort",xe={col:"model",dir:"asc"},Dt=["model","released","input","output"];function Ot(){if(typeof window>"u")return xe;try{const t=window.localStorage.getItem(Be);if(!t)return xe;const i=JSON.parse(t);if(Dt.includes(i.col)&&(i.dir==="asc"||i.dir==="desc"))return{col:i.col,dir:i.dir}}catch{}return xe}function Le({label:t,col:i,sort:r,onSort:s,align:n="left",info:a}){const d=r.col===i;return e.jsx(re,{className:n==="right"?"text-right":void 0,ariaSort:d?r.dir==="asc"?"ascending":"descending":"none",children:e.jsxs("span",{className:`inline-flex items-center gap-1.5 ${n==="right"?"flex-row-reverse":""}`,children:[e.jsxs("button",{type:"button",onClick:()=>s(i),className:`inline-flex items-center gap-1 ${n==="right"?"flex-row-reverse":""} hover:text-[var(--otari-ink)]`,children:[t,e.jsx("span",{className:"text-[10px] text-[var(--otari-muted)]",children:d?r.dir==="asc"?"▲":"▼":"↕"})]}),a]})})}function Ft({row:t,onClose:i}){const r=$e(),s=Ee(),[n,a]=c.useState(t.inputPrice==null?"":String(t.inputPrice)),[d,h]=c.useState(t.outputPrice==null?"":String(t.outputPrice)),[p,v]=c.useState(t.cacheReadPrice==null?"":String(t.cacheReadPrice)),[P,m]=c.useState(t.cacheWritePrice==null?"":String(t.cacheWritePrice)),[S,k]=c.useState(t.cacheWrite1hPrice==null?"":String(t.cacheWrite1hPrice)),[W,D]=c.useState(De(t.pricingTiers)),y=ae(n)&&ae(d)&&R(p)&&R(P)&&R(S)&&Oe(W),Y=()=>{y&&r.mutate({model_key:t.key,input_price_per_million:Number(n),output_price_per_million:Number(d),cache_read_price_per_million:V(p),cache_write_price_per_million:V(P),cache_write_1h_price_per_million:V(S),pricing_tiers:Fe(W)},{onSuccess:i})};return e.jsxs("div",{className:"flex flex-col gap-3 px-4 py-3",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsx("span",{className:"text-xs font-medium break-all text-[var(--otari-muted)]",children:t.key}),e.jsxs("label",{className:"flex items-center gap-1.5 text-xs text-[var(--otari-muted)]",children:["Input $ / 1M",e.jsx(j,{value:n,onChange:a,ariaLabel:`Input price for ${t.key}`})]}),e.jsxs("label",{className:"flex items-center gap-1.5 text-xs text-[var(--otari-muted)]",children:["Output $ / 1M",e.jsx(j,{value:d,onChange:h,ariaLabel:`Output price for ${t.key}`})]}),e.jsxs("label",{className:"flex items-center gap-1.5 text-xs text-[var(--otari-muted)]",children:["Cache read $ / 1M",e.jsx(j,{value:p,onChange:v,ariaLabel:`Cache read price for ${t.key}`})]}),e.jsxs("label",{className:"flex items-center gap-1.5 text-xs text-[var(--otari-muted)]",children:["Cache write $ / 1M",e.jsx(j,{value:P,onChange:m,ariaLabel:`Cache write price for ${t.key}`})]}),e.jsxs("label",{className:"flex items-center gap-1.5 text-xs text-[var(--otari-muted)]",children:["1h cache write $ / 1M",e.jsx(j,{value:S,onChange:k,ariaLabel:`1 hour cache write price for ${t.key}`})]}),e.jsx(L,{size:"sm",variant:"primary",isDisabled:r.isPending||!y,onPress:Y,children:r.isPending?"Saving…":"Save"}),e.jsx(L,{size:"sm",variant:"ghost",isDisabled:r.isPending,onPress:i,children:"Cancel"}),t.source==="configured"?e.jsxs("span",{className:"inline-flex items-center gap-1",children:[e.jsx(Ae,{confirmLabel:"Reset",isPending:s.isPending,onConfirm:()=>s.mutate(t.key,{onSuccess:i}),children:"Reset"}),e.jsx(se,{label:"What reset does",children:"Removes the custom price. The model reverts to the default rate (genai-prices) when default pricing is on, otherwise it is metered at no cost."})]}):null,r.error||s.error?e.jsx("span",{className:"text-xs text-red-700",children:me(r.error??s.error)}):null]}),e.jsx(ze,{tiers:W,onChange:D})]})}function zt({primary:t,secondary:i,rowKey:r,primaryLabel:s,secondaryLabel:n,onEdit:a}){const d=(h,p)=>e.jsx("button",{type:"button","aria-label":`Edit ${p} price for ${r}`,className:"tabular-nums hover:text-[var(--otari-brand-dark)] hover:underline",onClick:v=>{v.stopPropagation(),a()},children:h==null?"—":A(h)});return e.jsxs("span",{className:"inline-flex items-center justify-end gap-1",children:[d(t,s),e.jsx("span",{className:"text-[var(--otari-muted)]",children:"/"}),d(i,n)]})}function Bt({rates:t,rowKey:i,onEdit:r}){const s=[t.cacheReadPrice==null?null:`R ${A(t.cacheReadPrice)}`,t.cacheWritePrice==null?null:`W ${A(t.cacheWritePrice)}`,t.cacheWrite1hPrice==null?null:`1h ${A(t.cacheWrite1hPrice)}`].filter(n=>n!==null);return e.jsx("button",{type:"button","aria-label":`Edit caching price for ${i}`,className:"max-w-44 text-right text-xs leading-5 text-[var(--otari-muted)] hover:text-[var(--otari-brand-dark)] hover:underline",onClick:n=>{n.stopPropagation(),r()},children:s.length>0?s.join(" · "):"Input-rate fallback"})}function Rt({row:t,onEdit:i}){const r=[...t.pricingTiers].sort((n,a)=>n.min_input_tokens-a.min_input_tokens).map(n=>ne(n.min_input_tokens)),s=r.length===0?"Base only":`${r.length} tier${r.length===1?"":"s"} · ≥ ${r.join(", ")}`;return e.jsx("button",{type:"button","aria-label":`Edit pricing policy for ${t.key}`,className:"max-w-40 text-right text-xs leading-5 text-[var(--otari-muted)] hover:text-[var(--otari-brand-dark)] hover:underline",onClick:n=>{n.stopPropagation(),i()},children:s})}function Kt({rows:t,isLoading:i,empty:r,sort:s,onSort:n,selectedKey:a,onSelect:d,pricingKey:h,onSetPricingKey:p,comparisonContextTokens:v}){const P=v==null?"Base":`at ${ne(v)}`;return e.jsxs(mt,{children:[e.jsx(ft,{children:e.jsxs(Ce,{children:[e.jsx(Le,{label:"Model",col:"model",sort:s,onSort:n}),e.jsx(re,{children:"Provider"}),e.jsx(Le,{label:`${P} in / out $ / 1M`,col:"input",sort:s,onSort:n,align:"right",info:e.jsx(Mt,{})}),e.jsxs(re,{className:"text-right",children:["Caching ",v==null?"policy":P]}),e.jsx(re,{className:"text-right",children:"Pricing policy"})]})}),e.jsx("tbody",{children:i?e.jsx(vt,{colSpan:5}):t.length>0?t.map(m=>{const S=()=>p(h===m.key?null:m.key),k=kt(m,v);return e.jsxs(c.Fragment,{children:[e.jsxs(Ce,{onClick:()=>d(m.key),selected:m.key===a,children:[e.jsxs(U,{className:"font-medium break-all",children:[m.model,e.jsx("span",{className:"sr-only",children:m.key})]}),e.jsx(U,{className:"text-[var(--otari-muted)]",children:m.provider}),e.jsx(U,{className:"text-right",children:e.jsx(zt,{primary:k.inputPrice,secondary:k.outputPrice,rowKey:m.key,primaryLabel:"input",secondaryLabel:"output",onEdit:S})}),e.jsx(U,{className:"text-right",children:e.jsx(Bt,{rates:k,rowKey:m.key,onEdit:S})}),e.jsx(U,{className:"text-right",children:e.jsx(Rt,{row:m,onEdit:S})})]}),h===m.key?e.jsx("tr",{className:"border-b border-[var(--otari-line)] bg-[var(--otari-bg)] last:border-b-0",children:e.jsx("td",{colSpan:5,children:e.jsx(Ft,{row:m,onClose:()=>p(null)})})}):null]},m.key)}):e.jsx(bt,{colSpan:5,children:r})})]})}function Vt({providers:t}){return t.length===0?null:e.jsxs(dt,{tone:"warning",children:["Could not list ",t.map(i=>i.provider).join(", "),". Check that provider's credentials in config.yml; its models are missing from the list below."]})}function Jt(){var je,Pe,ye;const t=rt(),[i]=nt(),r=at(),s=st(),n=lt(),a=ct(),[d,h]=c.useState(""),[p,v]=c.useState(0),[P,m]=c.useState(Lt),[S,k]=c.useState(null),[W,D]=c.useState(null),[y,Y]=c.useState(Ot);c.useEffect(()=>{try{window.localStorage.setItem(Be,JSON.stringify(y))}catch{}},[y]);const[M,G]=c.useState(i.get("provider")||"all"),[F,Re]=c.useState("all"),[H,Ke]=c.useState("all"),[q,Ve]=c.useState("all"),[le,Ye]=c.useState("0"),[J,He]=c.useState(""),[Z,qe]=c.useState("all"),[ce,we]=c.useState(""),O=((je=a.data)==null?void 0:je.models)??{},Ue=((Pe=a.data)==null?void 0:Pe.available)??!1,fe=c.useMemo(()=>{var l;return new Set((((l=n.data)==null?void 0:l.providers)??[]).flatMap(f=>f.models.map(o=>o.key)))},[n.data]),Ge=l=>{h(l),v(0)},z=l=>f=>{l(f),v(0)},Je=l=>{Y(f=>f.col===l?{col:l,dir:f.dir==="asc"?"desc":"asc"}:{col:l,dir:l==="released"?"desc":"asc"}),v(0)},X=c.useMemo(()=>{var C,g,_,$,I,B,Ne;const l=new Map(gt(s.data??[]).map(u=>[u.model_key,u])),f=[],o=new Set,b=(u,he,Se,x)=>{if(o.has(u))return;o.add(u);const N=l.get(u);f.push({key:u,model:Ie(he,Se),provider:Se,isDiscovered:fe.has(u),contextWindow:(x==null?void 0:x.contextWindow)??null,inputPrice:N?N.input_price_per_million:(x==null?void 0:x.inputPrice)??null,outputPrice:N?N.output_price_per_million:(x==null?void 0:x.outputPrice)??null,cacheReadPrice:N?N.cache_read_price_per_million:(x==null?void 0:x.cacheReadPrice)??null,cacheWritePrice:N?N.cache_write_price_per_million:(x==null?void 0:x.cacheWritePrice)??null,cacheWrite1hPrice:N?N.cache_write_1h_price_per_million??null:(x==null?void 0:x.cacheWrite1hPrice)??null,pricingTiers:N?N.pricing_tiers??[]:(x==null?void 0:x.pricingTiers)??[],source:N?"configured":(x==null?void 0:x.source)??"none"})};for(const u of((C=r.data)==null?void 0:C.data)??[]){if(u.owned_by===_t)continue;const he=u.pricing_source==="default"?"default":u.pricing?"configured":"none";b(u.id,u.id,u.owned_by||We(u.id),{key:u.id,model:u.id,provider:u.owned_by,contextWindow:u.context_window,inputPrice:((g=u.pricing)==null?void 0:g.input_price_per_million)??null,outputPrice:((_=u.pricing)==null?void 0:_.output_price_per_million)??null,cacheReadPrice:(($=u.pricing)==null?void 0:$.cache_read_price_per_million)??null,cacheWritePrice:((I=u.pricing)==null?void 0:I.cache_write_price_per_million)??null,cacheWrite1hPrice:((B=u.pricing)==null?void 0:B.cache_write_1h_price_per_million)??null,pricingTiers:((Ne=u.pricing)==null?void 0:Ne.pricing_tiers)??[],source:he})}for(const u of l.keys())b(u,u,We(u));return f},[r.data,s.data,fe]),Ze=c.useMemo(()=>new Map(X.map(l=>[l.key,l])),[X]),Q=c.useMemo(()=>{var o,b,C;const l=X.map(g=>{var _,$;return{...g,contextWindow:g.contextWindow??((_=O[g.key])==null?void 0:_.context_window)??null,releaseDate:(($=O[g.key])==null?void 0:$.release_date)??null}}),f=new Set(l.map(g=>g.key));for(const g of((o=n.data)==null?void 0:o.providers)??[])for(const _ of g.models)f.has(_.key)||(f.add(_.key),l.push({key:_.key,model:Ie(_.key,g.provider),provider:g.provider,isDiscovered:!0,contextWindow:((b=O[_.key])==null?void 0:b.context_window)??null,releaseDate:((C=O[_.key])==null?void 0:C.release_date)??null,inputPrice:null,outputPrice:null,cacheReadPrice:null,cacheWritePrice:null,cacheWrite1hPrice:null,pricingTiers:[],source:"none"}));return l},[X,n.data,O]),Xe=(((ye=n.data)==null?void 0:ye.providers)??[]).filter(l=>!l.ok),ee=c.useMemo(()=>{const l=Array.from(new Set(Q.map(f=>f.provider))).sort((f,o)=>f.localeCompare(o));return[{value:"all",label:"All providers"},...l.map(f=>({value:f,label:f}))]},[Q]);c.useEffect(()=>{M==="all"||ee.length<=1||ee.some(l=>l.value===M)||G("all")},[ee,M]);const w=d.trim().toLowerCase(),oe=Number(le)||0,ue=J===""?Number.POSITIVE_INFINITY:Number(J),Qe=ce===""?null:Number(ce),de=Z==="all"?null:Date.now()-Number(Z)*Ct,pe=c.useMemo(()=>{const l=o=>{if(w&&!o.key.toLowerCase().includes(w)&&!o.provider.toLowerCase().includes(w)||M!=="all"&&o.provider!==M||F==="configured"&&o.source!=="configured"||F==="default"&&o.source!=="default"||F==="priced"&&o.inputPrice==null||F==="unpriced"&&o.inputPrice!=null||H==="discovered"&&!o.isDiscovered||H==="custom"&&o.isDiscovered)return!1;if(q!=="all"){const b=Me.find(g=>g.value===q),C=O[o.key];if(!b||!C||!b.test(C))return!1}if(oe>0&&(o.contextWindow==null||o.contextWindowue))return!1;if(de!=null){const b=o.releaseDate?Date.parse(o.releaseDate):Number.NaN;if(Number.isNaN(b)||b{const C=y.dir==="asc"?1:-1;if(y.col==="model")return o.model.localeCompare(b.model)*C;if(y.col==="released"){const I=o.releaseDate??null,B=b.releaseDate??null;return!I&&!B?o.model.localeCompare(b.model):I?B?(IB?1:0)*C||o.model.localeCompare(b.model):-1:1}const g=I=>y.col==="input"?I.inputPrice:I.outputPrice,_=g(o),$=g(b);return _==null&&$==null?o.model.localeCompare(b.model):_==null?1:$==null?-1:(_-$)*C||o.model.localeCompare(b.model)};return Q.filter(l).sort(f)},[Q,w,M,F,H,q,oe,ue,de,O,y]),ve=pe.length,be=Math.max(1,Math.ceil(ve/P)),ge=Math.min(p,be-1),_e=ge*P,et=pe.slice(_e,_e+P),tt=r.isLoading||s.isLoading||n.isLoading,it=w!==""||M!=="all"||F!=="all"||H!=="all"||q!=="all"||le!=="0"||J!==""||Z!=="all"?"No models match your filters.":"No models yet. Add a provider on the Providers page, or price a model below.",te=W?pe.find(l=>l.key===W)??Ze.get(W)??null:null;return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(ot,{title:"Models",description:"Every model your providers can serve. Set a price on any model so budgets and usage tracking work."}),e.jsx(ut,{error:r.error??s.error??n.error??a.error}),e.jsxs("div",{className:`grid gap-4 lg:items-start ${te?"lg:grid-cols-[minmax(0,1fr)_360px]":"grid-cols-1"}`,children:[e.jsxs("div",{className:"flex min-w-0 flex-col gap-3",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx(Et,{value:d,onChange:Ge,placeholder:"Search models…"}),e.jsx(E,{ariaLabel:"Filter by provider",value:M,onChange:z(G),options:ee}),e.jsx(E,{ariaLabel:"Filter by pricing",value:F,onChange:z(Re),options:[{value:"all",label:"Any pricing"},{value:"configured",label:"Custom price"},{value:"default",label:"Default price"},{value:"priced",label:"Priced"},{value:"unpriced",label:"Unpriced"}]}),e.jsx(E,{ariaLabel:"Filter by source",value:H,onChange:z(Ke),options:[{value:"all",label:"Any source"},{value:"discovered",label:"Discovered"},{value:"custom",label:"Custom (not discovered)"}]}),e.jsx(E,{ariaLabel:"Filter by capability",value:q,onChange:z(Ve),options:[{value:"all",label:"Any capability"},...Me.map(l=>({value:l.value,label:l.label}))]}),e.jsx(E,{ariaLabel:"Minimum context window",value:le,onChange:z(Ye),options:Pt}),e.jsx(E,{ariaLabel:"Maximum input price",value:J,onChange:z(He),options:yt}),e.jsx(E,{ariaLabel:"Compare prices at context",value:ce,onChange:we,options:Nt}),e.jsx(E,{ariaLabel:"Filter by release date",value:Z,onChange:z(qe),options:St})]}),e.jsx(Vt,{providers:Xe}),e.jsx(Kt,{rows:et,isLoading:tt,empty:it,sort:y,onSort:Je,selectedKey:W,onSelect:D,pricingKey:S,onSetPricingKey:k,comparisonContextTokens:Qe}),e.jsx("div",{className:"flex flex-wrap items-center justify-between gap-2",children:e.jsx(At,{page:ge,pageCount:be,total:ve,pageSize:P,onPage:v,onPageSize:l=>{m(l),v(0)}})})]}),te?e.jsx("aside",{className:"lg:sticky lg:top-4",children:e.jsx(It,{row:te,metadata:O[te.key],metadataAvailable:Ue,onMakeAlias:l=>t(`/aliases?target=${encodeURIComponent(l)}`),onClose:()=>D(null)})}):null]})]})}export{Jt as ModelsPage}; +import{j as e}from"./tanstack-query-1t81HyiD.js";import{i as rt,u as nt,r as c}from"./react-dgEcD0HR.js";import{v as at,w as st,e as lt,x as ct,P as ot,E as ut,F as E,I as dt,y as ne,z as pt,A as ht,B as xt,D as A,G as $e,H as Ee,C as Ae,h as me}from"./index-BJySXQ_a.js";import{T as mt,a as ft,d as Ce,b as re,L as vt,e as U,c as bt}from"./Table-CLdjdyTx.js";import{B as L,d as ke,f as K}from"./heroui-BX6JwHY-.js";function We(t){const i=t.indexOf(":");return i>0?t.slice(0,i):"—"}function gt(t,i=Date.now()){const r=new Map;for(const n of t){const a=r.get(n.model_key)??[];a.push(n),r.set(n.model_key,a)}const s=[];for(const n of r.values()){const a=[...n].sort((h,p)=>Date.parse(h.effective_at)-Date.parse(p.effective_at)),d=[...a].reverse().find(h=>Date.parse(h.effective_at)<=i);s.push(d??a[0])}return s.sort((n,a)=>n.model_key.localeCompare(a.model_key))}const _t="otari",Me=[{value:"vision",label:"Vision",test:t=>Array.isArray(t.input_modalities)&&t.input_modalities.includes("image")},{value:"tool_call",label:"Tool calling",test:t=>!!t.tool_call},{value:"reasoning",label:"Reasoning",test:t=>!!t.reasoning},{value:"structured_output",label:"Structured output",test:t=>!!t.structured_output},{value:"attachment",label:"Attachments",test:t=>!!t.attachment},{value:"audio",label:"Audio",test:t=>Array.isArray(t.input_modalities)&&t.input_modalities.includes("audio")},{value:"pdf",label:"PDF",test:t=>Array.isArray(t.input_modalities)&&t.input_modalities.includes("pdf")}],jt=[{key:"reasoning",label:"Reasoning"},{key:"tool_call",label:"Tool calling"},{key:"structured_output",label:"Structured output"},{key:"attachment",label:"Attachments"},{key:"temperature",label:"Temperature"}],Te={text:"Text",image:"Image",audio:"Audio",video:"Video",pdf:"PDF"},Pt=[{value:"0",label:"Any context"},{value:"8000",label:"≥ 8K"},{value:"32000",label:"≥ 32K"},{value:"128000",label:"≥ 128K"},{value:"200000",label:"≥ 200K"},{value:"1000000",label:"≥ 1M"}],yt=[{value:"",label:"Any price"},{value:"1",label:"≤ $1 / 1M in"},{value:"3",label:"≤ $3 / 1M in"},{value:"10",label:"≤ $10 / 1M in"},{value:"30",label:"≤ $30 / 1M in"}],Nt=[{value:"",label:"Base prices"},{value:"8000",label:"Compare at 8K"},{value:"128000",label:"Compare at 128K"},{value:"200000",label:"Compare at 200K"},{value:"500000",label:"Compare at 500K"},{value:"1000000",label:"Compare at 1M"}],St=[{value:"all",label:"Any release date"},{value:"365",label:"Past year"},{value:"730",label:"Past 2 years"},{value:"1095",label:"Past 3 years"}],Ct=1440*60*1e3;function Ie(t,i){const r=`${i}:`;return t.startsWith(r)?t.slice(r.length):t}function kt(t,i){const r={inputPrice:t.inputPrice,outputPrice:t.outputPrice,cacheReadPrice:t.cacheReadPrice,cacheWritePrice:t.cacheWritePrice,cacheWrite1hPrice:t.cacheWrite1hPrice};if(i==null)return r;const s=t.pricingTiers.filter(n=>n.min_input_tokens<=i).sort((n,a)=>a.min_input_tokens-n.min_input_tokens)[0];return s?{inputPrice:s.input_price_per_million??r.inputPrice,outputPrice:s.output_price_per_million??r.outputPrice,cacheReadPrice:s.cache_read_price_per_million??r.cacheReadPrice,cacheWritePrice:s.cache_write_price_per_million??r.cacheWritePrice,cacheWrite1hPrice:s.cache_write_1h_price_per_million??r.cacheWrite1hPrice}:r}function ae(t){const i=Number(t);return t.trim()!==""&&Number.isFinite(i)&&i>=0}function R(t){if(t.trim()==="")return!0;const i=Number(t);return Number.isFinite(i)&&i>=0}function V(t){return t.trim()===""?null:Number(t)}function De(t){return t.map((i,r)=>({id:r,minInputTokens:String(i.min_input_tokens),input:i.input_price_per_million==null?"":String(i.input_price_per_million),output:i.output_price_per_million==null?"":String(i.output_price_per_million),cacheRead:i.cache_read_price_per_million==null?"":String(i.cache_read_price_per_million),cacheWrite:i.cache_write_price_per_million==null?"":String(i.cache_write_price_per_million),cacheWrite1h:i.cache_write_1h_price_per_million==null?"":String(i.cache_write_1h_price_per_million)}))}function Oe(t){const i=new Set;return t.every(r=>{const s=Number(r.minInputTokens),n=[r.input,r.output,r.cacheRead,r.cacheWrite,r.cacheWrite1h].some(a=>a.trim()!=="");return!Number.isInteger(s)||s<=0||i.has(s)||!n?!1:(i.add(s),[r.input,r.output,r.cacheRead,r.cacheWrite,r.cacheWrite1h].every(R))})}function Fe(t){return t.map(i=>({min_input_tokens:Number(i.minInputTokens),...i.input.trim()===""?{}:{input_price_per_million:Number(i.input)},...i.output.trim()===""?{}:{output_price_per_million:Number(i.output)},...i.cacheRead.trim()===""?{}:{cache_read_price_per_million:Number(i.cacheRead)},...i.cacheWrite.trim()===""?{}:{cache_write_price_per_million:Number(i.cacheWrite)},...i.cacheWrite1h.trim()===""?{}:{cache_write_1h_price_per_million:Number(i.cacheWrite1h)}}))}function j({value:t,onChange:i,ariaLabel:r}){return e.jsx("input",{type:"number",step:"any",min:"0",inputMode:"decimal","aria-label":r,value:t,onChange:s=>i(s.target.value),className:"w-28 rounded-md border border-[var(--otari-line)] bg-white px-2 py-1 text-right text-sm tabular-nums focus:border-[var(--otari-brand)] focus:outline-none"})}function ze({tiers:t,onChange:i}){const r=(n,a,d)=>{i(t.map(h=>h.id===n?{...h,[a]:d}:h))},s=()=>{const n=t.reduce((a,d)=>Math.max(a,d.id),-1)+1;i([...t,{id:n,minInputTokens:"128000",input:"",output:"",cacheRead:"",cacheWrite:"",cacheWrite1h:""}])};return e.jsxs("div",{className:"flex flex-col gap-2 rounded-lg border border-[var(--otari-line)] p-3",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-xs font-medium text-[var(--otari-ink)]",children:"Long-context price tiers"}),e.jsx("p",{className:"text-xs text-[var(--otari-muted)]",children:"At a threshold, listed rates replace the base rate for the whole request."})]}),e.jsx(L,{size:"sm",variant:"outline",onPress:s,children:"Add tier"})]}),t.map(n=>e.jsxs("div",{className:"flex flex-wrap items-end gap-2 border-t border-[var(--otari-line)] pt-2",children:[e.jsxs("label",{className:"flex flex-col gap-1 text-xs text-[var(--otari-muted)]",children:["Context ≥ tokens",e.jsx("input",{type:"number",min:"1",step:"1",inputMode:"numeric","aria-label":"Tier context threshold",value:n.minInputTokens,onChange:a=>r(n.id,"minInputTokens",a.target.value),className:"w-28 rounded-md border border-[var(--otari-line)] bg-white px-2 py-1 text-right text-sm tabular-nums focus:border-[var(--otari-brand)] focus:outline-none"})]}),e.jsxs("label",{className:"flex flex-col gap-1 text-xs text-[var(--otari-muted)]",children:["Input",e.jsx(j,{value:n.input,onChange:a=>r(n.id,"input",a),ariaLabel:"Tier input price"})]}),e.jsxs("label",{className:"flex flex-col gap-1 text-xs text-[var(--otari-muted)]",children:["Output",e.jsx(j,{value:n.output,onChange:a=>r(n.id,"output",a),ariaLabel:"Tier output price"})]}),e.jsxs("label",{className:"flex flex-col gap-1 text-xs text-[var(--otari-muted)]",children:["Cache read",e.jsx(j,{value:n.cacheRead,onChange:a=>r(n.id,"cacheRead",a),ariaLabel:"Tier cache read price"})]}),e.jsxs("label",{className:"flex flex-col gap-1 text-xs text-[var(--otari-muted)]",children:["Cache write",e.jsx(j,{value:n.cacheWrite,onChange:a=>r(n.id,"cacheWrite",a),ariaLabel:"Tier cache write price"})]}),e.jsxs("label",{className:"flex flex-col gap-1 text-xs text-[var(--otari-muted)]",children:["1h write",e.jsx(j,{value:n.cacheWrite1h,onChange:a=>r(n.id,"cacheWrite1h",a),ariaLabel:"Tier 1 hour cache write price"})]}),e.jsx(L,{size:"sm",variant:"ghost",onPress:()=>i(t.filter(a=>a.id!==n.id)),children:"Remove"})]},n.id))]})}function Wt({source:t}){return t==="configured"?e.jsx(K,{size:"sm",color:"default",children:"configured"}):t==="default"||t==="alias"?e.jsx(K,{size:"sm",color:"accent",children:t}):e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"not priced"})}function se({label:t,tone:i="info",children:r}){const s=c.useId();return e.jsxs("span",{className:"group relative inline-flex items-center font-normal normal-case",children:[e.jsx("button",{type:"button","aria-label":t,"aria-describedby":s,className:`inline-flex h-4 w-4 items-center justify-center rounded-full border text-[10px] leading-none ${i==="warning"?"border-[#c2843a] text-[#b45309]":"border-[var(--otari-line)] text-[var(--otari-muted)] hover:border-[var(--otari-brand)] hover:text-[var(--otari-brand)]"}`,children:"i"}),e.jsx("span",{id:s,role:"tooltip",className:"pointer-events-none absolute top-full right-0 z-20 mt-1.5 w-72 rounded-lg border border-[var(--otari-line)] bg-[var(--otari-surface)] px-3 py-2 text-left text-xs font-normal whitespace-normal break-words text-[var(--otari-ink)] opacity-0 shadow-lg transition-opacity group-hover:opacity-100 group-focus-within:opacity-100",children:r})]})}function Mt(){const t=xt();return t.data?t.data.default_pricing?e.jsx(se,{label:"How unpriced models are metered",tone:"info",children:"Default pricing is on: models without a configured price are metered using community-maintained rates (the bundled genai-prices dataset). Set a price to override the fallback."}):e.jsxs(se,{label:"How unpriced models are metered",tone:"warning",children:["Default pricing is off: only models with a configured price are metered.",t.data.require_pricing?" Requests for any other model are rejected (HTTP 402) because require_pricing is on.":" Other models are served without cost tracking."]}):null}function T({label:t,value:i}){return e.jsxs("div",{className:"flex items-baseline justify-between gap-3",children:[e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:t}),e.jsx("span",{className:"text-right text-sm text-[var(--otari-ink)] tabular-nums",children:i})]})}function ie({title:t,children:i}){return e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsx("span",{className:"text-xs font-semibold uppercase tracking-wide text-[var(--otari-muted)]",children:t}),i]})}function Tt({row:t}){const i=$e(),r=Ee(),[s,n]=c.useState(!1),[a,d]=c.useState(""),[h,p]=c.useState(""),[v,P]=c.useState(""),[m,S]=c.useState(""),[k,W]=c.useState(""),[D,y]=c.useState([]),Y=()=>{d(t.inputPrice==null?"":String(t.inputPrice)),p(t.outputPrice==null?"":String(t.outputPrice)),P(t.cacheReadPrice==null?"":String(t.cacheReadPrice)),S(t.cacheWritePrice==null?"":String(t.cacheWritePrice)),W(t.cacheWrite1hPrice==null?"":String(t.cacheWrite1hPrice)),y(De(t.pricingTiers)),n(!0)},M=ae(a)&&ae(h)&&R(v)&&R(m)&&R(k)&&Oe(D),G=()=>{M&&i.mutate({model_key:t.key,input_price_per_million:Number(a),output_price_per_million:Number(h),cache_read_price_per_million:V(v),cache_write_price_per_million:V(m),cache_write_1h_price_per_million:V(k),pricing_tiers:Fe(D)},{onSuccess:()=>n(!1)})};return s?e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"Input $ / 1M"}),e.jsx(j,{value:a,onChange:d,ariaLabel:`Input price for ${t.key}`})]}),e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"Output $ / 1M"}),e.jsx(j,{value:h,onChange:p,ariaLabel:`Output price for ${t.key}`})]}),e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"Cache read $ / 1M"}),e.jsx(j,{value:v,onChange:P,ariaLabel:`Cache read price for ${t.key}`})]}),e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"Cache write $ / 1M"}),e.jsx(j,{value:m,onChange:S,ariaLabel:`Cache write price for ${t.key}`})]}),e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"1h cache write $ / 1M"}),e.jsx(j,{value:k,onChange:W,ariaLabel:`1 hour cache write price for ${t.key}`})]}),e.jsx(ze,{tiers:D,onChange:y}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(L,{size:"sm",variant:"primary",isDisabled:i.isPending||!M,onPress:G,children:"Save"}),e.jsx(L,{size:"sm",variant:"ghost",isDisabled:i.isPending,onPress:()=>n(!1),children:"Cancel"})]}),i.error?e.jsx("span",{className:"text-xs text-red-700",children:me(i.error)}):null]}):e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsx(T,{label:"Input",value:t.inputPrice==null?"—":`${A(t.inputPrice)} / 1M`}),e.jsx(T,{label:"Output",value:t.outputPrice==null?"—":`${A(t.outputPrice)} / 1M`}),e.jsx(T,{label:"Cache read",value:t.cacheReadPrice==null?"—":`${A(t.cacheReadPrice)} / 1M`}),e.jsx(T,{label:"Cache write",value:t.cacheWritePrice==null?"—":`${A(t.cacheWritePrice)} / 1M`}),e.jsx(T,{label:"1h cache write",value:t.cacheWrite1hPrice==null?"—":`${A(t.cacheWrite1hPrice)} / 1M`}),e.jsx(T,{label:"Context tiers",value:t.pricingTiers.length?`${t.pricingTiers.length} configured`:"—"}),e.jsxs("div",{className:"flex items-center gap-2 pt-1",children:[e.jsx(L,{size:"sm",variant:"outline",onPress:Y,children:t.source==="configured"?"Edit price":"Set price"}),t.source==="configured"?e.jsxs(e.Fragment,{children:[e.jsx(Ae,{confirmLabel:"Reset",isPending:r.isPending,onConfirm:()=>r.mutate(t.key),children:"Reset"}),e.jsx(se,{label:"What reset does",children:"Removes the custom price. The model reverts to the default rate (genai-prices) when default pricing is on, otherwise it is metered at no cost."})]}):null,r.error?e.jsx("span",{className:"text-xs text-red-700",children:me(r.error)}):null]})]})}function It({row:t,metadata:i,metadataAvailable:r,onMakeAlias:s,onClose:n}){const a=(i==null?void 0:i.input_modalities)??[],d=(i==null?void 0:i.output_modalities)??[],h=jt.filter(({key:p})=>i==null?void 0:i[p]);return e.jsx(ke,{children:e.jsxs(ke.Content,{className:"flex flex-col gap-5 p-5",children:[e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("h2",{className:"text-base font-semibold break-all text-[var(--otari-ink)]",children:t.model}),i!=null&&i.deprecated?e.jsx(K,{size:"sm",color:"danger",children:"deprecated"}):null]}),e.jsxs("p",{className:"mt-1 text-xs break-all text-[var(--otari-muted)]",children:["Selector: ",e.jsx("code",{children:t.key})]}),i!=null&&i.family?e.jsx("p",{className:"text-xs text-[var(--otari-muted)]",children:i.family}):null]}),e.jsx("button",{type:"button","aria-label":"Close model details",onClick:n,className:"-mt-1 -mr-1 shrink-0 rounded-md px-1.5 py-0.5 text-lg leading-none text-[var(--otari-muted)] hover:bg-[var(--otari-bg)] hover:text-[var(--otari-ink)]",children:"✕"})]}),i!=null&&i.description?e.jsx("p",{className:"text-sm text-[var(--otari-ink)]",children:i.description}):null,e.jsxs(ie,{title:"Pricing",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Wt,{source:t.source}),t.isDiscovered?null:e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"not discovered"})]}),e.jsx(Tt,{row:t},t.key),e.jsx(L,{size:"sm",variant:"outline",onPress:()=>s(t.key),children:"Make an alias"})]}),e.jsxs(ie,{title:"Specs",children:[e.jsx(T,{label:"Context window",value:ne(t.contextWindow)}),e.jsx(T,{label:"Max output",value:ne((i==null?void 0:i.max_output_tokens)??null)}),e.jsx(T,{label:"Knowledge cutoff",value:(i==null?void 0:i.knowledge_cutoff)??"—"}),e.jsx(T,{label:"Released",value:ht(i==null?void 0:i.release_date)}),e.jsx(T,{label:"Open weights",value:i?i.open_weights?"Yes":"No":"—"})]}),e.jsx(ie,{title:"Modalities",children:a.length===0&&d.length===0?e.jsx("span",{className:"text-sm text-[var(--otari-muted)]",children:"Unknown."}):e.jsxs("div",{className:"flex flex-col gap-1.5 text-xs text-[var(--otari-muted)]",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-1",children:[e.jsx("span",{children:"In:"}),a.map(p=>e.jsx(K,{size:"sm",color:"default",children:Te[p]??p},p))]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-1",children:[e.jsx("span",{children:"Out:"}),d.map(p=>e.jsx(K,{size:"sm",color:"default",children:Te[p]??p},p))]})]})}),e.jsx(ie,{title:"Capabilities",children:h.length>0?e.jsx("div",{className:"flex flex-wrap gap-1.5",children:h.map(({key:p,label:v})=>e.jsx(K,{size:"sm",color:"default",children:v},p))}):e.jsx("span",{className:"text-sm text-[var(--otari-muted)]",children:r?"None reported.":"Extended metadata unavailable (models.dev disabled or unreachable)."})})]})})}const Lt=15,$t=[{value:"15",label:"15 per page"},{value:"25",label:"25 per page"},{value:"50",label:"50 per page"}];function Et({value:t,onChange:i,placeholder:r}){return e.jsx("input",{type:"search",value:t,onChange:s=>i(s.target.value),placeholder:r,"aria-label":r,className:"w-full max-w-xs rounded-md border border-[var(--otari-line)] bg-white px-3 py-1.5 text-sm focus:border-[var(--otari-brand)] focus:outline-none"})}function At({page:t,pageCount:i,total:r,pageSize:s,onPage:n,onPageSize:a}){return e.jsxs("div",{className:"flex items-center justify-between px-1 pt-1 text-sm text-[var(--otari-muted)]",children:[e.jsxs("span",{children:[i>1?`Page ${t+1} of ${i} · `:"",pt(r)," model",r===1?"":"s"]}),e.jsxs("span",{className:"inline-flex gap-2",children:[e.jsx(E,{ariaLabel:"Rows per page",value:String(s),onChange:d=>a(Number(d)),options:$t}),i>1?e.jsxs(e.Fragment,{children:[e.jsx(L,{size:"sm",variant:"outline",isDisabled:t===0,onPress:()=>n(t-1),children:"Prev"}),e.jsx(L,{size:"sm",variant:"outline",isDisabled:t>=i-1,onPress:()=>n(t+1),children:"Next"})]}):null]})]})}const Be="otari.dashboard.modelsSort",xe={col:"model",dir:"asc"},Dt=["model","released","input","output"];function Ot(){if(typeof window>"u")return xe;try{const t=window.localStorage.getItem(Be);if(!t)return xe;const i=JSON.parse(t);if(Dt.includes(i.col)&&(i.dir==="asc"||i.dir==="desc"))return{col:i.col,dir:i.dir}}catch{}return xe}function Le({label:t,col:i,sort:r,onSort:s,align:n="left",info:a}){const d=r.col===i;return e.jsx(re,{className:n==="right"?"text-right":void 0,ariaSort:d?r.dir==="asc"?"ascending":"descending":"none",children:e.jsxs("span",{className:`inline-flex items-center gap-1.5 ${n==="right"?"flex-row-reverse":""}`,children:[e.jsxs("button",{type:"button",onClick:()=>s(i),className:`inline-flex items-center gap-1 ${n==="right"?"flex-row-reverse":""} hover:text-[var(--otari-ink)]`,children:[t,e.jsx("span",{className:"text-[10px] text-[var(--otari-muted)]",children:d?r.dir==="asc"?"▲":"▼":"↕"})]}),a]})})}function Ft({row:t,onClose:i}){const r=$e(),s=Ee(),[n,a]=c.useState(t.inputPrice==null?"":String(t.inputPrice)),[d,h]=c.useState(t.outputPrice==null?"":String(t.outputPrice)),[p,v]=c.useState(t.cacheReadPrice==null?"":String(t.cacheReadPrice)),[P,m]=c.useState(t.cacheWritePrice==null?"":String(t.cacheWritePrice)),[S,k]=c.useState(t.cacheWrite1hPrice==null?"":String(t.cacheWrite1hPrice)),[W,D]=c.useState(De(t.pricingTiers)),y=ae(n)&&ae(d)&&R(p)&&R(P)&&R(S)&&Oe(W),Y=()=>{y&&r.mutate({model_key:t.key,input_price_per_million:Number(n),output_price_per_million:Number(d),cache_read_price_per_million:V(p),cache_write_price_per_million:V(P),cache_write_1h_price_per_million:V(S),pricing_tiers:Fe(W)},{onSuccess:i})};return e.jsxs("div",{className:"flex flex-col gap-3 px-4 py-3",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsx("span",{className:"text-xs font-medium break-all text-[var(--otari-muted)]",children:t.key}),e.jsxs("label",{className:"flex items-center gap-1.5 text-xs text-[var(--otari-muted)]",children:["Input $ / 1M",e.jsx(j,{value:n,onChange:a,ariaLabel:`Input price for ${t.key}`})]}),e.jsxs("label",{className:"flex items-center gap-1.5 text-xs text-[var(--otari-muted)]",children:["Output $ / 1M",e.jsx(j,{value:d,onChange:h,ariaLabel:`Output price for ${t.key}`})]}),e.jsxs("label",{className:"flex items-center gap-1.5 text-xs text-[var(--otari-muted)]",children:["Cache read $ / 1M",e.jsx(j,{value:p,onChange:v,ariaLabel:`Cache read price for ${t.key}`})]}),e.jsxs("label",{className:"flex items-center gap-1.5 text-xs text-[var(--otari-muted)]",children:["Cache write $ / 1M",e.jsx(j,{value:P,onChange:m,ariaLabel:`Cache write price for ${t.key}`})]}),e.jsxs("label",{className:"flex items-center gap-1.5 text-xs text-[var(--otari-muted)]",children:["1h cache write $ / 1M",e.jsx(j,{value:S,onChange:k,ariaLabel:`1 hour cache write price for ${t.key}`})]}),e.jsx(L,{size:"sm",variant:"primary",isDisabled:r.isPending||!y,onPress:Y,children:r.isPending?"Saving…":"Save"}),e.jsx(L,{size:"sm",variant:"ghost",isDisabled:r.isPending,onPress:i,children:"Cancel"}),t.source==="configured"?e.jsxs("span",{className:"inline-flex items-center gap-1",children:[e.jsx(Ae,{confirmLabel:"Reset",isPending:s.isPending,onConfirm:()=>s.mutate(t.key,{onSuccess:i}),children:"Reset"}),e.jsx(se,{label:"What reset does",children:"Removes the custom price. The model reverts to the default rate (genai-prices) when default pricing is on, otherwise it is metered at no cost."})]}):null,r.error||s.error?e.jsx("span",{className:"text-xs text-red-700",children:me(r.error??s.error)}):null]}),e.jsx(ze,{tiers:W,onChange:D})]})}function zt({primary:t,secondary:i,rowKey:r,primaryLabel:s,secondaryLabel:n,onEdit:a}){const d=(h,p)=>e.jsx("button",{type:"button","aria-label":`Edit ${p} price for ${r}`,className:"tabular-nums hover:text-[var(--otari-brand-dark)] hover:underline",onClick:v=>{v.stopPropagation(),a()},children:h==null?"—":A(h)});return e.jsxs("span",{className:"inline-flex items-center justify-end gap-1",children:[d(t,s),e.jsx("span",{className:"text-[var(--otari-muted)]",children:"/"}),d(i,n)]})}function Bt({rates:t,rowKey:i,onEdit:r}){const s=[t.cacheReadPrice==null?null:`R ${A(t.cacheReadPrice)}`,t.cacheWritePrice==null?null:`W ${A(t.cacheWritePrice)}`,t.cacheWrite1hPrice==null?null:`1h ${A(t.cacheWrite1hPrice)}`].filter(n=>n!==null);return e.jsx("button",{type:"button","aria-label":`Edit caching price for ${i}`,className:"max-w-44 text-right text-xs leading-5 text-[var(--otari-muted)] hover:text-[var(--otari-brand-dark)] hover:underline",onClick:n=>{n.stopPropagation(),r()},children:s.length>0?s.join(" · "):"Input-rate fallback"})}function Rt({row:t,onEdit:i}){const r=[...t.pricingTiers].sort((n,a)=>n.min_input_tokens-a.min_input_tokens).map(n=>ne(n.min_input_tokens)),s=r.length===0?"Base only":`${r.length} tier${r.length===1?"":"s"} · ≥ ${r.join(", ")}`;return e.jsx("button",{type:"button","aria-label":`Edit pricing policy for ${t.key}`,className:"max-w-40 text-right text-xs leading-5 text-[var(--otari-muted)] hover:text-[var(--otari-brand-dark)] hover:underline",onClick:n=>{n.stopPropagation(),i()},children:s})}function Kt({rows:t,isLoading:i,empty:r,sort:s,onSort:n,selectedKey:a,onSelect:d,pricingKey:h,onSetPricingKey:p,comparisonContextTokens:v}){const P=v==null?"Base":`at ${ne(v)}`;return e.jsxs(mt,{children:[e.jsx(ft,{children:e.jsxs(Ce,{children:[e.jsx(Le,{label:"Model",col:"model",sort:s,onSort:n}),e.jsx(re,{children:"Provider"}),e.jsx(Le,{label:`${P} in / out $ / 1M`,col:"input",sort:s,onSort:n,align:"right",info:e.jsx(Mt,{})}),e.jsxs(re,{className:"text-right",children:["Caching ",v==null?"policy":P]}),e.jsx(re,{className:"text-right",children:"Pricing policy"})]})}),e.jsx("tbody",{children:i?e.jsx(vt,{colSpan:5}):t.length>0?t.map(m=>{const S=()=>p(h===m.key?null:m.key),k=kt(m,v);return e.jsxs(c.Fragment,{children:[e.jsxs(Ce,{onClick:()=>d(m.key),selected:m.key===a,children:[e.jsxs(U,{className:"font-medium break-all",children:[m.model,e.jsx("span",{className:"sr-only",children:m.key})]}),e.jsx(U,{className:"text-[var(--otari-muted)]",children:m.provider}),e.jsx(U,{className:"text-right",children:e.jsx(zt,{primary:k.inputPrice,secondary:k.outputPrice,rowKey:m.key,primaryLabel:"input",secondaryLabel:"output",onEdit:S})}),e.jsx(U,{className:"text-right",children:e.jsx(Bt,{rates:k,rowKey:m.key,onEdit:S})}),e.jsx(U,{className:"text-right",children:e.jsx(Rt,{row:m,onEdit:S})})]}),h===m.key?e.jsx("tr",{className:"border-b border-[var(--otari-line)] bg-[var(--otari-bg)] last:border-b-0",children:e.jsx("td",{colSpan:5,children:e.jsx(Ft,{row:m,onClose:()=>p(null)})})}):null]},m.key)}):e.jsx(bt,{colSpan:5,children:r})})]})}function Vt({providers:t}){return t.length===0?null:e.jsxs(dt,{tone:"warning",children:["Could not list ",t.map(i=>i.provider).join(", "),". Check that provider's credentials in config.yml; its models are missing from the list below."]})}function Jt(){var je,Pe,ye;const t=rt(),[i]=nt(),r=at(),s=st(),n=lt(),a=ct(),[d,h]=c.useState(""),[p,v]=c.useState(0),[P,m]=c.useState(Lt),[S,k]=c.useState(null),[W,D]=c.useState(null),[y,Y]=c.useState(Ot);c.useEffect(()=>{try{window.localStorage.setItem(Be,JSON.stringify(y))}catch{}},[y]);const[M,G]=c.useState(i.get("provider")||"all"),[F,Re]=c.useState("all"),[H,Ke]=c.useState("all"),[q,Ve]=c.useState("all"),[le,Ye]=c.useState("0"),[J,He]=c.useState(""),[Z,qe]=c.useState("all"),[ce,we]=c.useState(""),O=((je=a.data)==null?void 0:je.models)??{},Ue=((Pe=a.data)==null?void 0:Pe.available)??!1,fe=c.useMemo(()=>{var l;return new Set((((l=n.data)==null?void 0:l.providers)??[]).flatMap(f=>f.models.map(o=>o.key)))},[n.data]),Ge=l=>{h(l),v(0)},z=l=>f=>{l(f),v(0)},Je=l=>{Y(f=>f.col===l?{col:l,dir:f.dir==="asc"?"desc":"asc"}:{col:l,dir:l==="released"?"desc":"asc"}),v(0)},X=c.useMemo(()=>{var C,g,_,$,I,B,Ne;const l=new Map(gt(s.data??[]).map(u=>[u.model_key,u])),f=[],o=new Set,b=(u,he,Se,x)=>{if(o.has(u))return;o.add(u);const N=l.get(u);f.push({key:u,model:Ie(he,Se),provider:Se,isDiscovered:fe.has(u),contextWindow:(x==null?void 0:x.contextWindow)??null,inputPrice:N?N.input_price_per_million:(x==null?void 0:x.inputPrice)??null,outputPrice:N?N.output_price_per_million:(x==null?void 0:x.outputPrice)??null,cacheReadPrice:N?N.cache_read_price_per_million:(x==null?void 0:x.cacheReadPrice)??null,cacheWritePrice:N?N.cache_write_price_per_million:(x==null?void 0:x.cacheWritePrice)??null,cacheWrite1hPrice:N?N.cache_write_1h_price_per_million??null:(x==null?void 0:x.cacheWrite1hPrice)??null,pricingTiers:N?N.pricing_tiers??[]:(x==null?void 0:x.pricingTiers)??[],source:N?"configured":(x==null?void 0:x.source)??"none"})};for(const u of((C=r.data)==null?void 0:C.data)??[]){if(u.owned_by===_t)continue;const he=u.pricing_source==="default"?"default":u.pricing?"configured":"none";b(u.id,u.id,u.owned_by||We(u.id),{key:u.id,model:u.id,provider:u.owned_by,contextWindow:u.context_window,inputPrice:((g=u.pricing)==null?void 0:g.input_price_per_million)??null,outputPrice:((_=u.pricing)==null?void 0:_.output_price_per_million)??null,cacheReadPrice:(($=u.pricing)==null?void 0:$.cache_read_price_per_million)??null,cacheWritePrice:((I=u.pricing)==null?void 0:I.cache_write_price_per_million)??null,cacheWrite1hPrice:((B=u.pricing)==null?void 0:B.cache_write_1h_price_per_million)??null,pricingTiers:((Ne=u.pricing)==null?void 0:Ne.pricing_tiers)??[],source:he})}for(const u of l.keys())b(u,u,We(u));return f},[r.data,s.data,fe]),Ze=c.useMemo(()=>new Map(X.map(l=>[l.key,l])),[X]),Q=c.useMemo(()=>{var o,b,C;const l=X.map(g=>{var _,$;return{...g,contextWindow:g.contextWindow??((_=O[g.key])==null?void 0:_.context_window)??null,releaseDate:(($=O[g.key])==null?void 0:$.release_date)??null}}),f=new Set(l.map(g=>g.key));for(const g of((o=n.data)==null?void 0:o.providers)??[])for(const _ of g.models)f.has(_.key)||(f.add(_.key),l.push({key:_.key,model:Ie(_.key,g.provider),provider:g.provider,isDiscovered:!0,contextWindow:((b=O[_.key])==null?void 0:b.context_window)??null,releaseDate:((C=O[_.key])==null?void 0:C.release_date)??null,inputPrice:null,outputPrice:null,cacheReadPrice:null,cacheWritePrice:null,cacheWrite1hPrice:null,pricingTiers:[],source:"none"}));return l},[X,n.data,O]),Xe=(((ye=n.data)==null?void 0:ye.providers)??[]).filter(l=>!l.ok),ee=c.useMemo(()=>{const l=Array.from(new Set(Q.map(f=>f.provider))).sort((f,o)=>f.localeCompare(o));return[{value:"all",label:"All providers"},...l.map(f=>({value:f,label:f}))]},[Q]);c.useEffect(()=>{M==="all"||ee.length<=1||ee.some(l=>l.value===M)||G("all")},[ee,M]);const w=d.trim().toLowerCase(),oe=Number(le)||0,ue=J===""?Number.POSITIVE_INFINITY:Number(J),Qe=ce===""?null:Number(ce),de=Z==="all"?null:Date.now()-Number(Z)*Ct,pe=c.useMemo(()=>{const l=o=>{if(w&&!o.key.toLowerCase().includes(w)&&!o.provider.toLowerCase().includes(w)||M!=="all"&&o.provider!==M||F==="configured"&&o.source!=="configured"||F==="default"&&o.source!=="default"||F==="priced"&&o.inputPrice==null||F==="unpriced"&&o.inputPrice!=null||H==="discovered"&&!o.isDiscovered||H==="custom"&&o.isDiscovered)return!1;if(q!=="all"){const b=Me.find(g=>g.value===q),C=O[o.key];if(!b||!C||!b.test(C))return!1}if(oe>0&&(o.contextWindow==null||o.contextWindowue))return!1;if(de!=null){const b=o.releaseDate?Date.parse(o.releaseDate):Number.NaN;if(Number.isNaN(b)||b{const C=y.dir==="asc"?1:-1;if(y.col==="model")return o.model.localeCompare(b.model)*C;if(y.col==="released"){const I=o.releaseDate??null,B=b.releaseDate??null;return!I&&!B?o.model.localeCompare(b.model):I?B?(IB?1:0)*C||o.model.localeCompare(b.model):-1:1}const g=I=>y.col==="input"?I.inputPrice:I.outputPrice,_=g(o),$=g(b);return _==null&&$==null?o.model.localeCompare(b.model):_==null?1:$==null?-1:(_-$)*C||o.model.localeCompare(b.model)};return Q.filter(l).sort(f)},[Q,w,M,F,H,q,oe,ue,de,O,y]),ve=pe.length,be=Math.max(1,Math.ceil(ve/P)),ge=Math.min(p,be-1),_e=ge*P,et=pe.slice(_e,_e+P),tt=r.isLoading||s.isLoading||n.isLoading,it=w!==""||M!=="all"||F!=="all"||H!=="all"||q!=="all"||le!=="0"||J!==""||Z!=="all"?"No models match your filters.":"No models yet. Add a provider on the Providers page, or price a model below.",te=W?pe.find(l=>l.key===W)??Ze.get(W)??null:null;return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(ot,{title:"Models",description:"Every model your providers can serve. Set a price on any model so budgets and usage tracking work."}),e.jsx(ut,{error:r.error??s.error??n.error??a.error}),e.jsxs("div",{className:`grid gap-4 lg:items-start ${te?"lg:grid-cols-[minmax(0,1fr)_360px]":"grid-cols-1"}`,children:[e.jsxs("div",{className:"flex min-w-0 flex-col gap-3",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx(Et,{value:d,onChange:Ge,placeholder:"Search models…"}),e.jsx(E,{ariaLabel:"Filter by provider",value:M,onChange:z(G),options:ee}),e.jsx(E,{ariaLabel:"Filter by pricing",value:F,onChange:z(Re),options:[{value:"all",label:"Any pricing"},{value:"configured",label:"Custom price"},{value:"default",label:"Default price"},{value:"priced",label:"Priced"},{value:"unpriced",label:"Unpriced"}]}),e.jsx(E,{ariaLabel:"Filter by source",value:H,onChange:z(Ke),options:[{value:"all",label:"Any source"},{value:"discovered",label:"Discovered"},{value:"custom",label:"Custom (not discovered)"}]}),e.jsx(E,{ariaLabel:"Filter by capability",value:q,onChange:z(Ve),options:[{value:"all",label:"Any capability"},...Me.map(l=>({value:l.value,label:l.label}))]}),e.jsx(E,{ariaLabel:"Minimum context window",value:le,onChange:z(Ye),options:Pt}),e.jsx(E,{ariaLabel:"Maximum input price",value:J,onChange:z(He),options:yt}),e.jsx(E,{ariaLabel:"Compare prices at context",value:ce,onChange:we,options:Nt}),e.jsx(E,{ariaLabel:"Filter by release date",value:Z,onChange:z(qe),options:St})]}),e.jsx(Vt,{providers:Xe}),e.jsx(Kt,{rows:et,isLoading:tt,empty:it,sort:y,onSort:Je,selectedKey:W,onSelect:D,pricingKey:S,onSetPricingKey:k,comparisonContextTokens:Qe}),e.jsx("div",{className:"flex flex-wrap items-center justify-between gap-2",children:e.jsx(At,{page:ge,pageCount:be,total:ve,pageSize:P,onPage:v,onPageSize:l=>{m(l),v(0)}})})]}),te?e.jsx("aside",{className:"lg:sticky lg:top-4",children:e.jsx(It,{row:te,metadata:O[te.key],metadataAvailable:Ue,onMakeAlias:l=>t(`/aliases?target=${encodeURIComponent(l)}`),onClose:()=>D(null)})}):null]})]})}export{Jt as ModelsPage}; diff --git a/src/gateway/static/dashboard/assets/OverviewPage-B_g2blUc.js b/src/gateway/static/dashboard/assets/OverviewPage-KThfhw1Z.js similarity index 99% rename from src/gateway/static/dashboard/assets/OverviewPage-B_g2blUc.js rename to src/gateway/static/dashboard/assets/OverviewPage-KThfhw1Z.js index 7cd4e993..de31c991 100644 --- a/src/gateway/static/dashboard/assets/OverviewPage-B_g2blUc.js +++ b/src/gateway/static/dashboard/assets/OverviewPage-KThfhw1Z.js @@ -1 +1 @@ -import{j as t}from"./tanstack-query-1t81HyiD.js";import{r as f,i as Z,N as G}from"./react-dgEcD0HR.js";import{J as tt,c as N,K as et,j as rt,p as at,u as st,a as nt,L as _,P as ot,E as Y,S as p,M as D,N as R,z as E,O as k,Q as it}from"./index-DAVt9uB3.js";import{S as H}from"./charts-Cr3Dij9t.js";import{T as lt,a as dt,b,L as ct,c as ut,d as xt,e as j}from"./Table-CLdjdyTx.js";import{d as B,B as mt}from"./heroui-BX6JwHY-.js";import"./recharts-CR3TAEof.js";function U(e){return e==="neutral"?void 0:e}const vt=.02,ht=.1;function F(e){if(!e||e.request_count===0)return{rate:null,status:"neutral"};const n=e.error_count/e.request_count,a=n>=ht?"alert":n>=vt?"warn":"ok";return{rate:n,status:a}}function pt(e){return!e||e.total===0?"neutral":e.healthy>=e.total?"ok":e.healthy===0?"alert":"warn"}const ft=.8;function gt(e){if(e.length===0)return{status:"neutral",label:"No budgets configured",overCount:0,nearCount:0,cappedCount:0};const n=e.filter(s=>s.max_budget!==null&&s.user_count>0);if(n.length===0)return{status:"neutral",label:"No capped budgets",overCount:0,nearCount:0,cappedCount:0};let a=0,r=0,c,m=-1;for(const s of n){const o=s.max_budget*s.user_count,i=o>0?s.total_spend/o:0;i>=1?a+=1:i>=ft&&(r+=1),i>m&&(m=i,c={name:s.name??s.budget_id,spent:s.total_spend,allocated:o,pct:i})}const u=a>0?"alert":r>0?"warn":"ok",g=a>0?`${a} over limit`:r>0?`${r} near limit`:"All within budget";return{status:u,label:g,overCount:a,nearCount:r,cappedCount:n.length,worst:c}}const K=864e5,W=30;function I(){const e=new Date;return`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,"0")}-${String(e.getDate()).padStart(2,"0")}`}function bt(){const[e,n]=f.useState(I);return f.useEffect(()=>{const a=()=>{if(document.visibilityState==="visible"){const r=I();n(c=>c===r?c:r)}};return document.addEventListener("visibilitychange",a),window.addEventListener("focus",a),()=>{document.removeEventListener("visibilitychange",a),window.removeEventListener("focus",a)}},[]),f.useMemo(()=>{const a=Date.now(),r=new Date(a);return{today:new Date(r.getFullYear(),r.getMonth(),r.getDate()).toISOString(),periodStart:new Date(a-W*K).toISOString(),prevStart:new Date(a-2*W*K).toISOString()}},[e])}const jt={ok:"Healthy",warn:"Elevated",alert:"High"},St={ok:"On track",warn:"Near limit",alert:"Over budget"};function Pt(){const e=tt();return e.isLoading?null:t.jsx(yt,{needsSetup:e.isSuccess&&e.data.providers.length===0})}function yt({needsSetup:e=!1}){var $,A,P,T,M,q;const n=bt(),a=f.useMemo(()=>({start_date:n.today}),[n]),r=f.useMemo(()=>({start_date:n.periodStart}),[n]),c=f.useMemo(()=>({start_date:n.prevStart,end_date:n.periodStart}),[n]),m=N(a,"hour"),u=N(r,"day"),g=N(c,"day"),s=et(),o=rt(),i=at(),S=st(),y=nt({},0,5),C=($=m.data)==null?void 0:$.totals,x=(A=u.data)==null?void 0:A.totals,v=(P=g.data)==null?void 0:P.totals,w=((T=u.data)==null?void 0:T.series)??[],O=w.length>1,l=F(x),L=F(v),z=l.rate!==null&&L.rate!==null?_(l.rate,L.rate):null,d=gt(o.data??[]),J=pt(s.data),Q=(i.data??[]).filter(h=>h.is_active).length,V=(S.data??[]).filter(h=>!h.blocked).length,X=m.error??u.error??s.error??o.error??i.error??S.error;return t.jsxs("div",{className:"flex flex-col gap-6",children:[t.jsx(ot,{title:"Overview",description:"At-a-glance spend, traffic, and health across the gateway."}),e?t.jsx(wt,{}):null,t.jsx(Y,{error:X}),t.jsx(_t,{providerHealth:J,healthy:((M=s.data)==null?void 0:M.healthy)??0,total:((q=s.data)==null?void 0:q.total)??0,budget:d,errStatus:l.status,errRate:l.rate,ready:s.isSuccess&&o.isSuccess&&u.isSuccess,failed:s.isError||o.isError||u.isError}),t.jsxs("div",{className:"grid grid-cols-2 gap-4 sm:grid-cols-3 xl:grid-cols-4",children:[t.jsx(p,{label:"Spend today",value:C?D(C.cost):"—"}),t.jsx(p,{label:"Spend, last 30 days",value:x?D(x.cost):"—",hint:x?t.jsx(R,{fraction:_(x.cost,v==null?void 0:v.cost)}):null,chart:O?t.jsx(H,{values:w.map(h=>h.cost),ariaLabel:"Spend trend over the last 30 days"}):void 0}),t.jsx(p,{label:"Requests, last 30 days",value:x?E(x.request_count):"—",hint:x?t.jsx(R,{fraction:_(x.request_count,v==null?void 0:v.request_count)}):null,chart:O?t.jsx(H,{values:w.map(h=>h.requests),ariaLabel:"Request volume trend over the last 30 days"}):void 0}),t.jsx(p,{label:"Error rate, last 30 days",value:l.rate===null?"—":k(l.rate),status:U(l.status),statusLabel:l.status==="neutral"?void 0:jt[l.status],hint:l.rate!==null?t.jsx(R,{fraction:z}):null}),t.jsx(p,{label:"Budget health",value:o.data&&d.worst?k(d.worst.pct):"—",status:o.data?U(d.status):void 0,statusLabel:o.data&&d.status!=="neutral"?St[d.status]:void 0,hint:o.data?d.worst?`${d.label} · worst: ${d.worst.name}`:d.label:void 0,to:"/budgets"}),t.jsx(p,{label:"Active keys",value:i.data?E(Q):"—",to:"/keys"}),t.jsx(p,{label:"Active users",value:S.data?E(V):"—",to:"/users"})]}),t.jsx(Et,{entries:y.data??[],loading:y.isLoading,error:y.error})]})}function wt(){const e=Z();return t.jsx(B,{children:t.jsxs(B.Content,{className:"flex flex-col gap-3 p-6",children:[t.jsxs("div",{children:[t.jsx("h2",{className:"text-lg font-semibold text-[var(--otari-ink)]",children:"Get started with Otari"}),t.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:"Add a provider to begin serving models. Once it is configured, this page will show your gateway’s traffic, spend, and health."})]}),t.jsx("div",{children:t.jsx(mt,{variant:"primary",onPress:()=>e("/providers"),children:"Add your first provider"})})]})})}function Nt({text:e}){return t.jsx("div",{role:"status",className:"flex items-center gap-2 rounded-xl border border-[var(--otari-line)] bg-[var(--otari-bg)] px-4 py-3 text-sm text-[var(--otari-muted)]",children:e})}function _t({providerHealth:e,healthy:n,total:a,budget:r,errStatus:c,errRate:m,ready:u,failed:g}){if(g)return t.jsx(Nt,{text:"Some status data could not be loaded."});if(!u)return null;const s=[];if((e==="warn"||e==="alert")&&a>0){const o=a-n;s.push({text:`${o} provider${o===1?"":"s"} unreachable`,to:"/providers"})}return r.overCount>0?s.push({text:`${r.overCount} budget${r.overCount===1?"":"s"} over limit`,to:"/budgets"}):r.nearCount>0&&s.push({text:`${r.nearCount} budget${r.nearCount===1?"":"s"} near limit`,to:"/budgets"}),c==="alert"&&m!==null&&s.push({text:`error rate ${k(m)}`,to:"/activity?status=error"}),s.length===0?null:t.jsxs("div",{role:"alert",className:"flex flex-col gap-2 rounded-xl border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-900 sm:flex-row sm:flex-wrap sm:items-center",children:[t.jsx("span",{className:"font-medium",children:"Needs attention:"}),s.map((o,i)=>t.jsxs("span",{className:"flex items-center gap-2",children:[i>0?t.jsx("span",{"aria-hidden":!0,className:"text-amber-400",children:"·"}):null,t.jsx(G,{to:o.to,className:"underline underline-offset-2 hover:text-amber-950",children:o.text})]},o.to+o.text))]})}function Rt(e){return e==="error"?"error":"ok"}function Et({entries:e,loading:n,error:a}){return t.jsxs("div",{className:"flex flex-col gap-3",children:[t.jsxs("div",{className:"flex items-center justify-between",children:[t.jsx("h2",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:"Recent activity"}),t.jsx(G,{to:"/activity",className:"text-sm text-[var(--otari-brand-dark)] hover:underline",children:"View all →"})]}),t.jsx(Y,{error:a}),t.jsxs(lt,{children:[t.jsx(dt,{children:t.jsxs("tr",{children:[t.jsx(b,{children:"Time"}),t.jsx(b,{children:"Model"}),t.jsx(b,{className:"text-right",children:"Cost"}),t.jsx(b,{children:"Status"})]})}),t.jsx("tbody",{children:n?t.jsx(ct,{colSpan:4}):e.length===0?t.jsx(ut,{colSpan:4,children:"No requests yet. Once the gateway serves traffic, it appears here."}):e.map(r=>t.jsxs(xt,{children:[t.jsx(j,{className:"text-[var(--otari-muted)]",children:t.jsx("span",{title:new Date(r.timestamp).toLocaleString(),children:it(r.timestamp)})}),t.jsx(j,{className:"text-[var(--otari-ink)]",children:r.model}),t.jsx(j,{className:"text-right tabular-nums",children:r.cost===null?"—":D(r.cost)}),t.jsx(j,{children:t.jsx("span",{className:`inline-flex items-center rounded-full border px-2 py-0.5 text-xs font-medium ${r.status==="error"?"border-red-200 bg-red-50 text-red-700":"border-[var(--otari-line)] bg-[var(--otari-brand-tint)] text-[var(--otari-brand-dark)]"}`,children:Rt(r.status)})})]},r.id))})]})]})}export{Pt as OverviewIndex,yt as OverviewPage,I as localDayKey}; +import{j as t}from"./tanstack-query-1t81HyiD.js";import{r as f,i as Z,N as G}from"./react-dgEcD0HR.js";import{J as tt,c as N,K as et,j as rt,p as at,u as st,a as nt,L as _,P as ot,E as Y,S as p,M as D,N as R,z as E,O as k,Q as it}from"./index-BJySXQ_a.js";import{S as H}from"./charts-Cr3Dij9t.js";import{T as lt,a as dt,b,L as ct,c as ut,d as xt,e as j}from"./Table-CLdjdyTx.js";import{d as B,B as mt}from"./heroui-BX6JwHY-.js";import"./recharts-CR3TAEof.js";function U(e){return e==="neutral"?void 0:e}const vt=.02,ht=.1;function F(e){if(!e||e.request_count===0)return{rate:null,status:"neutral"};const n=e.error_count/e.request_count,a=n>=ht?"alert":n>=vt?"warn":"ok";return{rate:n,status:a}}function pt(e){return!e||e.total===0?"neutral":e.healthy>=e.total?"ok":e.healthy===0?"alert":"warn"}const ft=.8;function gt(e){if(e.length===0)return{status:"neutral",label:"No budgets configured",overCount:0,nearCount:0,cappedCount:0};const n=e.filter(s=>s.max_budget!==null&&s.user_count>0);if(n.length===0)return{status:"neutral",label:"No capped budgets",overCount:0,nearCount:0,cappedCount:0};let a=0,r=0,c,m=-1;for(const s of n){const o=s.max_budget*s.user_count,i=o>0?s.total_spend/o:0;i>=1?a+=1:i>=ft&&(r+=1),i>m&&(m=i,c={name:s.name??s.budget_id,spent:s.total_spend,allocated:o,pct:i})}const u=a>0?"alert":r>0?"warn":"ok",g=a>0?`${a} over limit`:r>0?`${r} near limit`:"All within budget";return{status:u,label:g,overCount:a,nearCount:r,cappedCount:n.length,worst:c}}const K=864e5,W=30;function I(){const e=new Date;return`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,"0")}-${String(e.getDate()).padStart(2,"0")}`}function bt(){const[e,n]=f.useState(I);return f.useEffect(()=>{const a=()=>{if(document.visibilityState==="visible"){const r=I();n(c=>c===r?c:r)}};return document.addEventListener("visibilitychange",a),window.addEventListener("focus",a),()=>{document.removeEventListener("visibilitychange",a),window.removeEventListener("focus",a)}},[]),f.useMemo(()=>{const a=Date.now(),r=new Date(a);return{today:new Date(r.getFullYear(),r.getMonth(),r.getDate()).toISOString(),periodStart:new Date(a-W*K).toISOString(),prevStart:new Date(a-2*W*K).toISOString()}},[e])}const jt={ok:"Healthy",warn:"Elevated",alert:"High"},St={ok:"On track",warn:"Near limit",alert:"Over budget"};function Pt(){const e=tt();return e.isLoading?null:t.jsx(yt,{needsSetup:e.isSuccess&&e.data.providers.length===0})}function yt({needsSetup:e=!1}){var $,A,P,T,M,q;const n=bt(),a=f.useMemo(()=>({start_date:n.today}),[n]),r=f.useMemo(()=>({start_date:n.periodStart}),[n]),c=f.useMemo(()=>({start_date:n.prevStart,end_date:n.periodStart}),[n]),m=N(a,"hour"),u=N(r,"day"),g=N(c,"day"),s=et(),o=rt(),i=at(),S=st(),y=nt({},0,5),C=($=m.data)==null?void 0:$.totals,x=(A=u.data)==null?void 0:A.totals,v=(P=g.data)==null?void 0:P.totals,w=((T=u.data)==null?void 0:T.series)??[],O=w.length>1,l=F(x),L=F(v),z=l.rate!==null&&L.rate!==null?_(l.rate,L.rate):null,d=gt(o.data??[]),J=pt(s.data),Q=(i.data??[]).filter(h=>h.is_active).length,V=(S.data??[]).filter(h=>!h.blocked).length,X=m.error??u.error??s.error??o.error??i.error??S.error;return t.jsxs("div",{className:"flex flex-col gap-6",children:[t.jsx(ot,{title:"Overview",description:"At-a-glance spend, traffic, and health across the gateway."}),e?t.jsx(wt,{}):null,t.jsx(Y,{error:X}),t.jsx(_t,{providerHealth:J,healthy:((M=s.data)==null?void 0:M.healthy)??0,total:((q=s.data)==null?void 0:q.total)??0,budget:d,errStatus:l.status,errRate:l.rate,ready:s.isSuccess&&o.isSuccess&&u.isSuccess,failed:s.isError||o.isError||u.isError}),t.jsxs("div",{className:"grid grid-cols-2 gap-4 sm:grid-cols-3 xl:grid-cols-4",children:[t.jsx(p,{label:"Spend today",value:C?D(C.cost):"—"}),t.jsx(p,{label:"Spend, last 30 days",value:x?D(x.cost):"—",hint:x?t.jsx(R,{fraction:_(x.cost,v==null?void 0:v.cost)}):null,chart:O?t.jsx(H,{values:w.map(h=>h.cost),ariaLabel:"Spend trend over the last 30 days"}):void 0}),t.jsx(p,{label:"Requests, last 30 days",value:x?E(x.request_count):"—",hint:x?t.jsx(R,{fraction:_(x.request_count,v==null?void 0:v.request_count)}):null,chart:O?t.jsx(H,{values:w.map(h=>h.requests),ariaLabel:"Request volume trend over the last 30 days"}):void 0}),t.jsx(p,{label:"Error rate, last 30 days",value:l.rate===null?"—":k(l.rate),status:U(l.status),statusLabel:l.status==="neutral"?void 0:jt[l.status],hint:l.rate!==null?t.jsx(R,{fraction:z}):null}),t.jsx(p,{label:"Budget health",value:o.data&&d.worst?k(d.worst.pct):"—",status:o.data?U(d.status):void 0,statusLabel:o.data&&d.status!=="neutral"?St[d.status]:void 0,hint:o.data?d.worst?`${d.label} · worst: ${d.worst.name}`:d.label:void 0,to:"/budgets"}),t.jsx(p,{label:"Active keys",value:i.data?E(Q):"—",to:"/keys"}),t.jsx(p,{label:"Active users",value:S.data?E(V):"—",to:"/users"})]}),t.jsx(Et,{entries:y.data??[],loading:y.isLoading,error:y.error})]})}function wt(){const e=Z();return t.jsx(B,{children:t.jsxs(B.Content,{className:"flex flex-col gap-3 p-6",children:[t.jsxs("div",{children:[t.jsx("h2",{className:"text-lg font-semibold text-[var(--otari-ink)]",children:"Get started with Otari"}),t.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:"Add a provider to begin serving models. Once it is configured, this page will show your gateway’s traffic, spend, and health."})]}),t.jsx("div",{children:t.jsx(mt,{variant:"primary",onPress:()=>e("/providers"),children:"Add your first provider"})})]})})}function Nt({text:e}){return t.jsx("div",{role:"status",className:"flex items-center gap-2 rounded-xl border border-[var(--otari-line)] bg-[var(--otari-bg)] px-4 py-3 text-sm text-[var(--otari-muted)]",children:e})}function _t({providerHealth:e,healthy:n,total:a,budget:r,errStatus:c,errRate:m,ready:u,failed:g}){if(g)return t.jsx(Nt,{text:"Some status data could not be loaded."});if(!u)return null;const s=[];if((e==="warn"||e==="alert")&&a>0){const o=a-n;s.push({text:`${o} provider${o===1?"":"s"} unreachable`,to:"/providers"})}return r.overCount>0?s.push({text:`${r.overCount} budget${r.overCount===1?"":"s"} over limit`,to:"/budgets"}):r.nearCount>0&&s.push({text:`${r.nearCount} budget${r.nearCount===1?"":"s"} near limit`,to:"/budgets"}),c==="alert"&&m!==null&&s.push({text:`error rate ${k(m)}`,to:"/activity?status=error"}),s.length===0?null:t.jsxs("div",{role:"alert",className:"flex flex-col gap-2 rounded-xl border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-900 sm:flex-row sm:flex-wrap sm:items-center",children:[t.jsx("span",{className:"font-medium",children:"Needs attention:"}),s.map((o,i)=>t.jsxs("span",{className:"flex items-center gap-2",children:[i>0?t.jsx("span",{"aria-hidden":!0,className:"text-amber-400",children:"·"}):null,t.jsx(G,{to:o.to,className:"underline underline-offset-2 hover:text-amber-950",children:o.text})]},o.to+o.text))]})}function Rt(e){return e==="error"?"error":"ok"}function Et({entries:e,loading:n,error:a}){return t.jsxs("div",{className:"flex flex-col gap-3",children:[t.jsxs("div",{className:"flex items-center justify-between",children:[t.jsx("h2",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:"Recent activity"}),t.jsx(G,{to:"/activity",className:"text-sm text-[var(--otari-brand-dark)] hover:underline",children:"View all →"})]}),t.jsx(Y,{error:a}),t.jsxs(lt,{children:[t.jsx(dt,{children:t.jsxs("tr",{children:[t.jsx(b,{children:"Time"}),t.jsx(b,{children:"Model"}),t.jsx(b,{className:"text-right",children:"Cost"}),t.jsx(b,{children:"Status"})]})}),t.jsx("tbody",{children:n?t.jsx(ct,{colSpan:4}):e.length===0?t.jsx(ut,{colSpan:4,children:"No requests yet. Once the gateway serves traffic, it appears here."}):e.map(r=>t.jsxs(xt,{children:[t.jsx(j,{className:"text-[var(--otari-muted)]",children:t.jsx("span",{title:new Date(r.timestamp).toLocaleString(),children:it(r.timestamp)})}),t.jsx(j,{className:"text-[var(--otari-ink)]",children:r.model}),t.jsx(j,{className:"text-right tabular-nums",children:r.cost===null?"—":D(r.cost)}),t.jsx(j,{children:t.jsx("span",{className:`inline-flex items-center rounded-full border px-2 py-0.5 text-xs font-medium ${r.status==="error"?"border-red-200 bg-red-50 text-red-700":"border-[var(--otari-line)] bg-[var(--otari-brand-tint)] text-[var(--otari-brand-dark)]"}`,children:Rt(r.status)})})]},r.id))})]})]})}export{Pt as OverviewIndex,yt as OverviewPage,I as localDayKey}; diff --git a/src/gateway/static/dashboard/assets/ProvidersPage-DhHL_fxe.js b/src/gateway/static/dashboard/assets/ProvidersPage-BEN5bHZD.js similarity index 99% rename from src/gateway/static/dashboard/assets/ProvidersPage-DhHL_fxe.js rename to src/gateway/static/dashboard/assets/ProvidersPage-BEN5bHZD.js index e7ade3bc..f4849c22 100644 --- a/src/gateway/static/dashboard/assets/ProvidersPage-DhHL_fxe.js +++ b/src/gateway/static/dashboard/assets/ProvidersPage-BEN5bHZD.js @@ -1 +1 @@ -import{j as e}from"./tanstack-query-1t81HyiD.js";import{r as x,L as Q}from"./react-dgEcD0HR.js";import{J as X,R as Z,B as ee,K as se,T as te,U as ae,V as ne,P as re,E as R,I as ie,C as oe,W as de,X as le,Q as U,h as M,Y,Z as ce,_ as me,$ as ue}from"./index-DAVt9uB3.js";import{F as A}from"./Field-HzRk1KDP.js";import{T as xe,a as pe,b as _,L as he,c as ve,d as ge,e as C}from"./Table-CLdjdyTx.js";import{B as g,f as z,d as T,S as fe,T as je,L as V,I as W,D as be,C as E,a as ye,b as ke}from"./heroui-BX6JwHY-.js";function B({value:t,onChange:a,label:s,placeholder:n,description:i}){return e.jsxs(je,{value:t,onChange:a,className:"flex max-w-md flex-col gap-1",children:[e.jsx(V,{className:"text-sm font-medium text-[var(--otari-ink)]",children:s}),e.jsx(W,{type:"password",placeholder:n??"sk-…",autoComplete:"off",autoCorrect:"off",autoCapitalize:"off",spellCheck:!1,"data-1p-ignore":!0,"data-lpignore":"true"}),i?e.jsx(be,{className:"text-xs text-[var(--otari-muted)]",children:i}):null]})}function G({label:t,value:a,onChange:s,description:n,placeholder:i,extra:l=[],includeCatalog:m=!0}){var y;const v=me(),u=x.useMemo(()=>m?[...l,...(v.data??[]).map(o=>({id:o.id,name:o.name}))]:l,[v.data,l,m]),[p,c]=x.useState(()=>{var o;return((o=u.find(j=>j.id===a))==null?void 0:o.name)??""}),f=((y=u.find(o=>o.id===a))==null?void 0:y.name)??"",h=p.trim()===f.trim()?"":p.trim().toLowerCase(),d=u.filter(o=>!h||o.name.toLowerCase().includes(h)||o.id.toLowerCase().includes(h)).slice(0,50);return e.jsxs(E.Root,{allowsEmptyCollection:!0,menuTrigger:"focus",inputValue:p,onInputChange:c,onSelectionChange:o=>{var j;o!=null?(s(String(o)),c(((j=u.find(P=>P.id===String(o)))==null?void 0:j.name)??"")):(s(""),c(""))},className:"flex max-w-md flex-col gap-1",children:[e.jsx(V,{className:"text-sm font-medium text-[var(--otari-ink)]",children:t}),e.jsxs(E.InputGroup,{children:[e.jsx(W,{placeholder:i??"Search providers…",autoComplete:"off","data-1p-ignore":!0,"data-lpignore":"true",onFocus:o=>o.currentTarget.select()}),e.jsx(E.Trigger,{})]}),e.jsx(E.Popover,{children:e.jsx(ye,{items:d,className:"max-h-72 overflow-auto",children:o=>e.jsx(ke,{id:o.id,textValue:o.name,children:o.name})})}),n?e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:n}):null]})}function J({getPayload:t}){const a=ue(),s=t();return e.jsxs("div",{className:"flex flex-col gap-1.5",children:[e.jsx(g,{variant:"outline",isDisabled:s===null||a.isPending,onPress:()=>{s&&a.mutate(s)},children:a.isPending?"Testing…":"Test connection"}),e.jsx("span",{role:"status","aria-live":"polite",children:a.isPending?null:a.error?e.jsx("span",{className:"text-xs text-red-700",children:M(a.error)}):a.data?a.data.ok?e.jsxs("span",{className:"text-xs font-medium text-green-700",children:["Connected. ",a.data.model_count," model",a.data.model_count===1?"":"s"," available."]}):e.jsx("span",{className:"block max-w-md break-words text-xs text-red-700",children:a.data.error??"Connection failed."}):null})]})}function Pe({onClose:t}){var I;const a=Y(),[s,n]=x.useState(""),[i,l]=x.useState(""),[m,v]=x.useState(!1),[u,p]=x.useState(""),[c,f]=x.useState(""),h=ce(s),d=((I=h.data)==null?void 0:I.id)===s?h.data:void 0;x.useEffect(()=>{d&&p(d.default_api_base??"")},[d]);const y=(d==null?void 0:d.env_key_present)??!1,o=((d==null?void 0:d.requires_api_key)??!0)&&!y,j=c.trim()!==""&&c.trim()!==s,P=/[:/]/.test(c),k=s!==""&&!P&&(!o||i.trim()!=="")&&!a.isPending,w=()=>{k&&a.mutate({instance:j?c.trim():s,provider_type:j?s:null,api_base:u.trim()||null,api_key:i.trim()||null},{onSuccess:t})};return e.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsx(R,{error:a.error}),e.jsx(G,{label:"Provider",value:s,onChange:N=>{n(N),f(""),p("")},description:"Its endpoint is built in."}),e.jsx(B,{value:i,onChange:l,label:d&&!o?"API key (optional)":"API key",description:d?o?`${d.name}'s endpoint is built in — just add your key.`:y?`${d.env_key} is set on the server, so a key is optional here. Paste one to override it.`:`${d.name} needs no API key.`:"Stored encrypted. Requires OTARI_SECRET_KEY on the server."}),e.jsx("button",{type:"button",className:"self-start text-xs font-medium text-[var(--otari-brand-dark)]",onClick:()=>v(N=>!N),children:m?"Hide advanced":"Advanced (API base, rename)"}),m?e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsx(A,{label:"API base",value:u,onChange:p,placeholder:(d==null?void 0:d.default_api_base)??"https://…/v1",description:"Only if you route through a proxy. Blank uses the built-in default."}),e.jsx(A,{label:"Name",value:c,onChange:f,placeholder:s||"instance name",description:P?e.jsx("span",{className:"text-red-700",children:"A name cannot contain “:” or “/”."}):"Rename to run two instances of the same provider."})]}):null,e.jsxs("div",{className:"flex flex-wrap items-start gap-2",children:[e.jsx(g,{variant:"primary",isDisabled:!k,onPress:w,children:a.isPending?"Adding…":"Add provider"}),e.jsx(g,{variant:"ghost",onPress:t,children:"Cancel"}),e.jsx(J,{getPayload:()=>s===""?null:{instance:j?c.trim():s,provider_type:j?s:null,api_base:u.trim()||null,api_key:i.trim()||null}})]})]})}function Ne({onClose:t}){const a=Y(),[s,n]=x.useState(""),[i,l]=x.useState("openai-compatible"),[m,v]=x.useState(""),[u,p]=x.useState(""),c=/[:/]/.test(s),f=s.trim()!==""&&!c&&m.trim()!==""&&!a.isPending,h=()=>{f&&a.mutate({instance:s.trim(),provider_type:i||"openai-compatible",api_base:m.trim(),api_key:u.trim()||null},{onSuccess:t})};return e.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsx(R,{error:a.error}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsx(A,{label:"Name",value:s,onChange:n,placeholder:"my-local-llm",isRequired:!0,autoFocus:!0,description:c?e.jsx("span",{className:"text-red-700",children:"A name cannot contain “:” or “/”."}):"Call it whatever you want."}),e.jsx(G,{label:"Compatible with",value:i,onChange:l,includeCatalog:!1,description:"The API this endpoint speaks.",extra:[{id:"openai-compatible",name:"OpenAI"},{id:"anthropic-compatible",name:"Anthropic"}]})]}),e.jsx(A,{label:"API base",value:m,onChange:v,placeholder:"http://localhost:8000/v1",isRequired:!0,description:"The endpoint URL of your server."}),e.jsx(B,{value:u,onChange:p,label:"API key (optional)",description:"Many local backends need none. Stored encrypted."}),e.jsxs("div",{className:"flex flex-wrap items-start gap-2",children:[e.jsx(g,{variant:"primary",isDisabled:!f,onPress:h,children:a.isPending?"Adding…":"Add provider"}),e.jsx(g,{variant:"ghost",onPress:t,children:"Cancel"}),e.jsx(J,{getPayload:()=>s.trim()===""||m.trim()===""?null:{instance:s.trim(),provider_type:i||"openai-compatible",api_base:m.trim(),api_key:u.trim()||null}})]})]})}function Se({onClose:t}){const[a,s]=x.useState("known");return e.jsx(T,{children:e.jsxs(T.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsx("div",{className:"flex items-center justify-between",children:e.jsx("div",{className:"flex items-center gap-1 rounded-lg bg-[var(--otari-bg)] p-1",children:[["known","Known provider"],["custom","Custom endpoint"]].map(([n,i])=>e.jsx("button",{type:"button","aria-pressed":a===n,onClick:()=>s(n),className:a===n?"rounded-md bg-white px-3 py-1.5 text-sm font-medium text-[var(--otari-ink)] shadow-sm":"rounded-md px-3 py-1.5 text-sm text-[var(--otari-muted)] hover:text-[var(--otari-ink)]",children:i},n))})}),a==="known"?e.jsx(Pe,{onClose:t}):e.jsx(Ne,{onClose:t})]})})}function _e({provider:t,onClose:a}){const s=de(),[n,i]=x.useState(t.provider_type??""),[l,m]=x.useState(t.api_base??""),[v,u]=x.useState(!1),[p,c]=x.useState(""),f=()=>{if(s.isPending)return;const h={provider_type:n.trim()||null,api_base:l.trim()||null,expected_updated_at:t.updated_at};v&&p.trim()&&(h.api_key=p.trim()),s.mutate({instance:t.instance,body:h},{onSuccess:a})};return e.jsx(T,{children:e.jsxs(T.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsxs("div",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:["Edit ",e.jsx("code",{children:t.instance})]}),e.jsx(R,{error:s.error}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsx(A,{label:"Provider type",value:n,onChange:i,placeholder:"openai"}),e.jsx(A,{label:"API base",value:l,onChange:m,placeholder:"https://api.openai.com/v1"})]}),e.jsx("div",{className:"flex flex-col gap-2",children:v?e.jsxs(e.Fragment,{children:[e.jsx(B,{value:p,onChange:c,label:"New API key",description:"Stored encrypted. The old key is replaced when you save."}),e.jsx("button",{type:"button",className:"self-start text-xs font-medium text-[var(--otari-brand-dark)]",onClick:()=>{u(!1),c("")},children:"Keep the current key"})]}):e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsxs("span",{className:"text-sm text-[var(--otari-muted)]",children:["API key: ",e.jsx("code",{children:t.last4?`••••${t.last4}`:"none set"})]}),e.jsx(g,{size:"sm",variant:"outline",onPress:()=>u(!0),children:"Replace key"})]})}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(g,{variant:"primary",isDisabled:s.isPending,onPress:f,children:s.isPending?"Saving…":"Save changes"}),e.jsx(g,{variant:"ghost",onPress:a,children:"Cancel"})]})]})})}function Ce(t,a){const s=new Map((a??[]).map(l=>[l.instance,l])),n=new Map((t??[]).map(l=>[l.instance,l]));return[...new Set([...s.keys(),...n.keys()])].sort().map(l=>{const m=s.get(l);return{instance:l,source:m?"stored":"config",stored:m,meta:n.get(l)}})}function Ae({state:t}){return t?t.status==="pending"?e.jsxs("span",{className:"inline-flex items-center gap-1.5 text-xs text-[var(--otari-muted)]",children:[e.jsx(fe,{size:"sm"})," Testing…"]}):t.ok?e.jsxs("span",{className:"text-xs font-medium text-green-700",children:["Connected. ",t.model_count," model",t.model_count===1?"":"s"," available."]}):e.jsx("span",{className:"block max-w-xs break-words text-xs text-red-700",children:t.error??"Connection failed."}):null}function Te({health:t}){if(!t)return e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"—"});const a=t.ok?"border-green-200 bg-green-50 text-green-700":"border-red-200 bg-red-50 text-red-700",s=t.checked_at?`Last checked ${U(t.checked_at)}`:"Not checked yet",n=t.ok?s:`${t.error??"Unreachable"} · ${s}`;return e.jsxs("span",{title:n,className:`inline-flex items-center gap-1.5 rounded-full border px-2.5 py-0.5 text-xs font-medium ${a}`,children:[e.jsx("span",{"aria-hidden":!0,className:`h-1.5 w-1.5 rounded-full ${t.ok?"bg-green-500":"bg-red-500"}`}),t.ok?"Reachable":"Unreachable"]})}function we({healthy:t,total:a,checkedAt:s}){const n=t===a,i=le();return e.jsxs("div",{className:"flex flex-wrap items-center gap-3 rounded-xl border border-[var(--otari-line)] bg-[var(--otari-surface)] px-4 py-2.5 text-sm",children:[e.jsx("span",{"aria-hidden":!0,className:`h-2 w-2 rounded-full ${n?"bg-green-500":"bg-red-500"}`}),e.jsxs("span",{className:"font-medium text-[var(--otari-ink)]",children:[t," of ",a," provider",a===1?"":"s"," reachable"]}),s?e.jsxs("span",{className:"text-[var(--otari-muted)]",children:["Last checked ",U(s)]}):null,e.jsx(g,{size:"sm",variant:"ghost",className:"ml-auto",isDisabled:i.isPending,onPress:()=>i.mutate(),children:i.isPending?"Re-checking…":"Re-check all"})]})}function K({n:t,title:a,children:s}){return e.jsxs("li",{className:"flex gap-3",children:[e.jsx("span",{className:"flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-[var(--otari-brand-tint)] text-xs font-semibold text-[var(--otari-brand-dark)]",children:t}),e.jsxs("div",{className:"text-sm",children:[e.jsx("div",{className:"font-medium text-[var(--otari-ink)]",children:a}),e.jsx("div",{className:"text-[var(--otari-muted)]",children:s})]})]})}function Ie({onAddProvider:t,needsPricing:a,onEnablePricing:s,enabling:n,secretKeyConfigured:i}){return e.jsx(T,{children:e.jsxs(T.Content,{className:"flex flex-col gap-4 p-6",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-semibold text-[var(--otari-ink)]",children:"Welcome to Otari"}),e.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:"You are signed in. Add a provider to start serving models: three quick steps."})]}),e.jsxs("ol",{className:"flex flex-col gap-3",children:[e.jsxs(K,{n:1,title:"Add a provider",children:["Enter a provider name (like ",e.jsx("code",{children:"openai"}),") and its API key. Keys are encrypted at rest."]}),e.jsxs(K,{n:2,title:"Test the connection",children:["Use ",e.jsx("strong",{children:"Test"})," on the provider row to confirm the key works and see how many models it serves."]}),e.jsxs(K,{n:3,title:"Send your first request",children:["Point your app at ",e.jsx("code",{children:"/v1"})," on this gateway with the API key printed in the server logs (",e.jsx("code",{children:"gw-…"}),"). See the"," ",e.jsx("a",{href:"/welcome",className:"font-medium text-[var(--otari-brand-dark)]",children:"quickstart"}),"."]})]}),a?e.jsxs("p",{className:"text-sm text-[var(--otari-muted)]",children:["Tip: ",e.jsx("code",{children:"require_pricing"})," is on, so requests are rejected until pricing is set."," ",e.jsx("button",{type:"button",className:"font-medium text-[var(--otari-brand-dark)] disabled:opacity-50",disabled:n,onClick:s,children:"Enable default pricing"})," ","to meter new models with public rates."]}):null,e.jsx("div",{children:e.jsx(g,{variant:"primary",isDisabled:!i,onPress:t,children:"Add your first provider"})})]})})}function $e(){var N,L,D,$;const t=X(),a=Z(),s=ee(),n=se(),i=te(),l=ae(),m=ne(),[v,u]=x.useState(!1),[p,c]=x.useState(null),[f,h]=x.useState({}),d=Ce((N=t.data)==null?void 0:N.providers,a.data),y=new Map((((L=n.data)==null?void 0:L.providers)??[]).map(r=>[r.instance,r])),o=t.isLoading||a.isLoading,j=((D=a.data)==null?void 0:D.find(r=>r.instance===p))??null,P=(($=s.data)==null?void 0:$.require_pricing)===!0&&s.data.default_pricing===!1,k=s.data?s.data.secret_key_configured!==!1:!s.isError,w=!o&&d.length===0&&!v,I=r=>{h(b=>({...b,[r]:{status:"pending"}})),l.mutate(r,{onSuccess:b=>h(S=>({...S,[r]:{status:"done",...b}})),onError:b=>h(S=>({...S,[r]:{status:"done",ok:!1,model_count:0,error:M(b)}}))})};return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(re,{title:"Providers",description:"Add provider API keys here to serve models without editing config.yml. Keys are encrypted at rest.",action:v||w?null:e.jsx(g,{variant:"primary",isDisabled:!k,onPress:()=>{c(null),u(!0)},children:"Add provider"})}),e.jsx(R,{error:t.error??a.error??s.error??n.error??m.error??i.error}),k?null:e.jsxs(ie,{tone:"warning",children:[e.jsx("code",{children:"OTARI_SECRET_KEY"})," is not set, so provider keys can't be encrypted at rest and adding providers from the dashboard is disabled. Set it on the server and restart to add providers here. Providers defined in"," ",e.jsx("code",{children:"config.yml"})," keep working without it."]}),w?e.jsx(Ie,{onAddProvider:()=>{c(null),u(!0)},needsPricing:P,onEnablePricing:()=>m.mutate({default_pricing:!0}),enabling:m.isPending,secretKeyConfigured:k}):null,v&&k?e.jsx(Se,{onClose:()=>u(!1)}):null,j?e.jsx(_e,{provider:j,onClose:()=>c(null)}):null,!o&&d.length>0&&n.data&&n.data.total>0?e.jsx(we,{healthy:n.data.healthy,total:n.data.total,checkedAt:n.data.checked_at}):null,e.jsxs(xe,{children:[e.jsx(pe,{children:e.jsxs("tr",{children:[e.jsx(_,{children:"Provider"}),e.jsx(_,{children:"Type"}),e.jsx(_,{children:"Source"}),e.jsx(_,{children:"API key"}),e.jsx(_,{children:"Status"}),e.jsx(_,{className:"text-right",children:"Actions"})]})}),e.jsx("tbody",{children:o?e.jsx(he,{colSpan:6}):d.length===0?e.jsx(ve,{colSpan:6,children:"No providers yet. Add your first provider to start serving models."}):d.map(r=>{var b,S,O,q,F,H;return e.jsxs(ge,{children:[e.jsx(C,{className:"font-medium",children:e.jsx(Q,{to:`/models?provider=${encodeURIComponent(r.instance)}`,className:"text-[var(--otari-ink)] hover:text-[var(--otari-brand-dark)] hover:underline",children:r.instance})}),e.jsx(C,{className:"text-[var(--otari-muted)]",children:((b=r.meta)==null?void 0:b.provider_type)??((S=r.stored)==null?void 0:S.provider_type)??r.instance}),e.jsx(C,{children:r.source==="stored"?e.jsx(z,{size:"sm",color:"accent",children:"stored"}):e.jsx(z,{size:"sm",color:"default",children:"config"})}),e.jsx(C,{className:"text-[var(--otari-muted)]",children:r.source==="stored"?r.stored&&!r.stored.decryptable?e.jsx("span",{className:"text-amber-700",title:"This key can't be decrypted with the current OTARI_SECRET_KEY. Replace the key, or restore the original OTARI_SECRET_KEY.",children:"⚠ key unreadable"}):e.jsx("code",{children:(O=r.stored)!=null&&O.last4?`••••${r.stored.last4}`:"none set"}):(q=r.meta)!=null&&q.env_key?e.jsxs("span",{children:["via ",e.jsx("code",{children:r.meta.env_key})]}):"config.yml"}),e.jsx(C,{children:e.jsx(Te,{health:y.get(r.instance)})}),e.jsx(C,{children:r.source==="stored"?e.jsxs("div",{className:"flex flex-col items-end gap-1.5",children:[e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx(g,{size:"sm",variant:"outline",isDisabled:((F=f[r.instance])==null?void 0:F.status)==="pending"||((H=r.stored)==null?void 0:H.decryptable)===!1,onPress:()=>I(r.instance),children:"Test"}),e.jsx(g,{size:"sm",variant:"ghost",onPress:()=>{u(!1),c(r.instance)},children:"Edit"}),e.jsx(oe,{confirmLabel:"Delete",isPending:i.isPending,onConfirm:()=>i.mutate(r.instance),children:"Delete"})]}),e.jsx(Ae,{state:f[r.instance]})]}):e.jsx("span",{className:"block text-right text-xs text-[var(--otari-muted)]",children:"managed in config.yml"})})]},r.instance)})})]})]})}export{$e as ProvidersPage}; +import{j as e}from"./tanstack-query-1t81HyiD.js";import{r as x,L as Q}from"./react-dgEcD0HR.js";import{J as X,R as Z,B as ee,K as se,T as te,U as ae,V as ne,P as re,E as R,I as ie,C as oe,W as de,X as le,Q as U,h as M,Y,Z as ce,_ as me,$ as ue}from"./index-BJySXQ_a.js";import{F as A}from"./Field-HzRk1KDP.js";import{T as xe,a as pe,b as _,L as he,c as ve,d as ge,e as C}from"./Table-CLdjdyTx.js";import{B as g,f as z,d as T,S as fe,T as je,L as V,I as W,D as be,C as E,a as ye,b as ke}from"./heroui-BX6JwHY-.js";function B({value:t,onChange:a,label:s,placeholder:n,description:i}){return e.jsxs(je,{value:t,onChange:a,className:"flex max-w-md flex-col gap-1",children:[e.jsx(V,{className:"text-sm font-medium text-[var(--otari-ink)]",children:s}),e.jsx(W,{type:"password",placeholder:n??"sk-…",autoComplete:"off",autoCorrect:"off",autoCapitalize:"off",spellCheck:!1,"data-1p-ignore":!0,"data-lpignore":"true"}),i?e.jsx(be,{className:"text-xs text-[var(--otari-muted)]",children:i}):null]})}function G({label:t,value:a,onChange:s,description:n,placeholder:i,extra:l=[],includeCatalog:m=!0}){var y;const v=me(),u=x.useMemo(()=>m?[...l,...(v.data??[]).map(o=>({id:o.id,name:o.name}))]:l,[v.data,l,m]),[p,c]=x.useState(()=>{var o;return((o=u.find(j=>j.id===a))==null?void 0:o.name)??""}),f=((y=u.find(o=>o.id===a))==null?void 0:y.name)??"",h=p.trim()===f.trim()?"":p.trim().toLowerCase(),d=u.filter(o=>!h||o.name.toLowerCase().includes(h)||o.id.toLowerCase().includes(h)).slice(0,50);return e.jsxs(E.Root,{allowsEmptyCollection:!0,menuTrigger:"focus",inputValue:p,onInputChange:c,onSelectionChange:o=>{var j;o!=null?(s(String(o)),c(((j=u.find(P=>P.id===String(o)))==null?void 0:j.name)??"")):(s(""),c(""))},className:"flex max-w-md flex-col gap-1",children:[e.jsx(V,{className:"text-sm font-medium text-[var(--otari-ink)]",children:t}),e.jsxs(E.InputGroup,{children:[e.jsx(W,{placeholder:i??"Search providers…",autoComplete:"off","data-1p-ignore":!0,"data-lpignore":"true",onFocus:o=>o.currentTarget.select()}),e.jsx(E.Trigger,{})]}),e.jsx(E.Popover,{children:e.jsx(ye,{items:d,className:"max-h-72 overflow-auto",children:o=>e.jsx(ke,{id:o.id,textValue:o.name,children:o.name})})}),n?e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:n}):null]})}function J({getPayload:t}){const a=ue(),s=t();return e.jsxs("div",{className:"flex flex-col gap-1.5",children:[e.jsx(g,{variant:"outline",isDisabled:s===null||a.isPending,onPress:()=>{s&&a.mutate(s)},children:a.isPending?"Testing…":"Test connection"}),e.jsx("span",{role:"status","aria-live":"polite",children:a.isPending?null:a.error?e.jsx("span",{className:"text-xs text-red-700",children:M(a.error)}):a.data?a.data.ok?e.jsxs("span",{className:"text-xs font-medium text-green-700",children:["Connected. ",a.data.model_count," model",a.data.model_count===1?"":"s"," available."]}):e.jsx("span",{className:"block max-w-md break-words text-xs text-red-700",children:a.data.error??"Connection failed."}):null})]})}function Pe({onClose:t}){var I;const a=Y(),[s,n]=x.useState(""),[i,l]=x.useState(""),[m,v]=x.useState(!1),[u,p]=x.useState(""),[c,f]=x.useState(""),h=ce(s),d=((I=h.data)==null?void 0:I.id)===s?h.data:void 0;x.useEffect(()=>{d&&p(d.default_api_base??"")},[d]);const y=(d==null?void 0:d.env_key_present)??!1,o=((d==null?void 0:d.requires_api_key)??!0)&&!y,j=c.trim()!==""&&c.trim()!==s,P=/[:/]/.test(c),k=s!==""&&!P&&(!o||i.trim()!=="")&&!a.isPending,w=()=>{k&&a.mutate({instance:j?c.trim():s,provider_type:j?s:null,api_base:u.trim()||null,api_key:i.trim()||null},{onSuccess:t})};return e.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsx(R,{error:a.error}),e.jsx(G,{label:"Provider",value:s,onChange:N=>{n(N),f(""),p("")},description:"Its endpoint is built in."}),e.jsx(B,{value:i,onChange:l,label:d&&!o?"API key (optional)":"API key",description:d?o?`${d.name}'s endpoint is built in — just add your key.`:y?`${d.env_key} is set on the server, so a key is optional here. Paste one to override it.`:`${d.name} needs no API key.`:"Stored encrypted. Requires OTARI_SECRET_KEY on the server."}),e.jsx("button",{type:"button",className:"self-start text-xs font-medium text-[var(--otari-brand-dark)]",onClick:()=>v(N=>!N),children:m?"Hide advanced":"Advanced (API base, rename)"}),m?e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsx(A,{label:"API base",value:u,onChange:p,placeholder:(d==null?void 0:d.default_api_base)??"https://…/v1",description:"Only if you route through a proxy. Blank uses the built-in default."}),e.jsx(A,{label:"Name",value:c,onChange:f,placeholder:s||"instance name",description:P?e.jsx("span",{className:"text-red-700",children:"A name cannot contain “:” or “/”."}):"Rename to run two instances of the same provider."})]}):null,e.jsxs("div",{className:"flex flex-wrap items-start gap-2",children:[e.jsx(g,{variant:"primary",isDisabled:!k,onPress:w,children:a.isPending?"Adding…":"Add provider"}),e.jsx(g,{variant:"ghost",onPress:t,children:"Cancel"}),e.jsx(J,{getPayload:()=>s===""?null:{instance:j?c.trim():s,provider_type:j?s:null,api_base:u.trim()||null,api_key:i.trim()||null}})]})]})}function Ne({onClose:t}){const a=Y(),[s,n]=x.useState(""),[i,l]=x.useState("openai-compatible"),[m,v]=x.useState(""),[u,p]=x.useState(""),c=/[:/]/.test(s),f=s.trim()!==""&&!c&&m.trim()!==""&&!a.isPending,h=()=>{f&&a.mutate({instance:s.trim(),provider_type:i||"openai-compatible",api_base:m.trim(),api_key:u.trim()||null},{onSuccess:t})};return e.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsx(R,{error:a.error}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsx(A,{label:"Name",value:s,onChange:n,placeholder:"my-local-llm",isRequired:!0,autoFocus:!0,description:c?e.jsx("span",{className:"text-red-700",children:"A name cannot contain “:” or “/”."}):"Call it whatever you want."}),e.jsx(G,{label:"Compatible with",value:i,onChange:l,includeCatalog:!1,description:"The API this endpoint speaks.",extra:[{id:"openai-compatible",name:"OpenAI"},{id:"anthropic-compatible",name:"Anthropic"}]})]}),e.jsx(A,{label:"API base",value:m,onChange:v,placeholder:"http://localhost:8000/v1",isRequired:!0,description:"The endpoint URL of your server."}),e.jsx(B,{value:u,onChange:p,label:"API key (optional)",description:"Many local backends need none. Stored encrypted."}),e.jsxs("div",{className:"flex flex-wrap items-start gap-2",children:[e.jsx(g,{variant:"primary",isDisabled:!f,onPress:h,children:a.isPending?"Adding…":"Add provider"}),e.jsx(g,{variant:"ghost",onPress:t,children:"Cancel"}),e.jsx(J,{getPayload:()=>s.trim()===""||m.trim()===""?null:{instance:s.trim(),provider_type:i||"openai-compatible",api_base:m.trim(),api_key:u.trim()||null}})]})]})}function Se({onClose:t}){const[a,s]=x.useState("known");return e.jsx(T,{children:e.jsxs(T.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsx("div",{className:"flex items-center justify-between",children:e.jsx("div",{className:"flex items-center gap-1 rounded-lg bg-[var(--otari-bg)] p-1",children:[["known","Known provider"],["custom","Custom endpoint"]].map(([n,i])=>e.jsx("button",{type:"button","aria-pressed":a===n,onClick:()=>s(n),className:a===n?"rounded-md bg-white px-3 py-1.5 text-sm font-medium text-[var(--otari-ink)] shadow-sm":"rounded-md px-3 py-1.5 text-sm text-[var(--otari-muted)] hover:text-[var(--otari-ink)]",children:i},n))})}),a==="known"?e.jsx(Pe,{onClose:t}):e.jsx(Ne,{onClose:t})]})})}function _e({provider:t,onClose:a}){const s=de(),[n,i]=x.useState(t.provider_type??""),[l,m]=x.useState(t.api_base??""),[v,u]=x.useState(!1),[p,c]=x.useState(""),f=()=>{if(s.isPending)return;const h={provider_type:n.trim()||null,api_base:l.trim()||null,expected_updated_at:t.updated_at};v&&p.trim()&&(h.api_key=p.trim()),s.mutate({instance:t.instance,body:h},{onSuccess:a})};return e.jsx(T,{children:e.jsxs(T.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsxs("div",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:["Edit ",e.jsx("code",{children:t.instance})]}),e.jsx(R,{error:s.error}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsx(A,{label:"Provider type",value:n,onChange:i,placeholder:"openai"}),e.jsx(A,{label:"API base",value:l,onChange:m,placeholder:"https://api.openai.com/v1"})]}),e.jsx("div",{className:"flex flex-col gap-2",children:v?e.jsxs(e.Fragment,{children:[e.jsx(B,{value:p,onChange:c,label:"New API key",description:"Stored encrypted. The old key is replaced when you save."}),e.jsx("button",{type:"button",className:"self-start text-xs font-medium text-[var(--otari-brand-dark)]",onClick:()=>{u(!1),c("")},children:"Keep the current key"})]}):e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsxs("span",{className:"text-sm text-[var(--otari-muted)]",children:["API key: ",e.jsx("code",{children:t.last4?`••••${t.last4}`:"none set"})]}),e.jsx(g,{size:"sm",variant:"outline",onPress:()=>u(!0),children:"Replace key"})]})}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(g,{variant:"primary",isDisabled:s.isPending,onPress:f,children:s.isPending?"Saving…":"Save changes"}),e.jsx(g,{variant:"ghost",onPress:a,children:"Cancel"})]})]})})}function Ce(t,a){const s=new Map((a??[]).map(l=>[l.instance,l])),n=new Map((t??[]).map(l=>[l.instance,l]));return[...new Set([...s.keys(),...n.keys()])].sort().map(l=>{const m=s.get(l);return{instance:l,source:m?"stored":"config",stored:m,meta:n.get(l)}})}function Ae({state:t}){return t?t.status==="pending"?e.jsxs("span",{className:"inline-flex items-center gap-1.5 text-xs text-[var(--otari-muted)]",children:[e.jsx(fe,{size:"sm"})," Testing…"]}):t.ok?e.jsxs("span",{className:"text-xs font-medium text-green-700",children:["Connected. ",t.model_count," model",t.model_count===1?"":"s"," available."]}):e.jsx("span",{className:"block max-w-xs break-words text-xs text-red-700",children:t.error??"Connection failed."}):null}function Te({health:t}){if(!t)return e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"—"});const a=t.ok?"border-green-200 bg-green-50 text-green-700":"border-red-200 bg-red-50 text-red-700",s=t.checked_at?`Last checked ${U(t.checked_at)}`:"Not checked yet",n=t.ok?s:`${t.error??"Unreachable"} · ${s}`;return e.jsxs("span",{title:n,className:`inline-flex items-center gap-1.5 rounded-full border px-2.5 py-0.5 text-xs font-medium ${a}`,children:[e.jsx("span",{"aria-hidden":!0,className:`h-1.5 w-1.5 rounded-full ${t.ok?"bg-green-500":"bg-red-500"}`}),t.ok?"Reachable":"Unreachable"]})}function we({healthy:t,total:a,checkedAt:s}){const n=t===a,i=le();return e.jsxs("div",{className:"flex flex-wrap items-center gap-3 rounded-xl border border-[var(--otari-line)] bg-[var(--otari-surface)] px-4 py-2.5 text-sm",children:[e.jsx("span",{"aria-hidden":!0,className:`h-2 w-2 rounded-full ${n?"bg-green-500":"bg-red-500"}`}),e.jsxs("span",{className:"font-medium text-[var(--otari-ink)]",children:[t," of ",a," provider",a===1?"":"s"," reachable"]}),s?e.jsxs("span",{className:"text-[var(--otari-muted)]",children:["Last checked ",U(s)]}):null,e.jsx(g,{size:"sm",variant:"ghost",className:"ml-auto",isDisabled:i.isPending,onPress:()=>i.mutate(),children:i.isPending?"Re-checking…":"Re-check all"})]})}function K({n:t,title:a,children:s}){return e.jsxs("li",{className:"flex gap-3",children:[e.jsx("span",{className:"flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-[var(--otari-brand-tint)] text-xs font-semibold text-[var(--otari-brand-dark)]",children:t}),e.jsxs("div",{className:"text-sm",children:[e.jsx("div",{className:"font-medium text-[var(--otari-ink)]",children:a}),e.jsx("div",{className:"text-[var(--otari-muted)]",children:s})]})]})}function Ie({onAddProvider:t,needsPricing:a,onEnablePricing:s,enabling:n,secretKeyConfigured:i}){return e.jsx(T,{children:e.jsxs(T.Content,{className:"flex flex-col gap-4 p-6",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-semibold text-[var(--otari-ink)]",children:"Welcome to Otari"}),e.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:"You are signed in. Add a provider to start serving models: three quick steps."})]}),e.jsxs("ol",{className:"flex flex-col gap-3",children:[e.jsxs(K,{n:1,title:"Add a provider",children:["Enter a provider name (like ",e.jsx("code",{children:"openai"}),") and its API key. Keys are encrypted at rest."]}),e.jsxs(K,{n:2,title:"Test the connection",children:["Use ",e.jsx("strong",{children:"Test"})," on the provider row to confirm the key works and see how many models it serves."]}),e.jsxs(K,{n:3,title:"Send your first request",children:["Point your app at ",e.jsx("code",{children:"/v1"})," on this gateway with the API key printed in the server logs (",e.jsx("code",{children:"gw-…"}),"). See the"," ",e.jsx("a",{href:"/welcome",className:"font-medium text-[var(--otari-brand-dark)]",children:"quickstart"}),"."]})]}),a?e.jsxs("p",{className:"text-sm text-[var(--otari-muted)]",children:["Tip: ",e.jsx("code",{children:"require_pricing"})," is on, so requests are rejected until pricing is set."," ",e.jsx("button",{type:"button",className:"font-medium text-[var(--otari-brand-dark)] disabled:opacity-50",disabled:n,onClick:s,children:"Enable default pricing"})," ","to meter new models with public rates."]}):null,e.jsx("div",{children:e.jsx(g,{variant:"primary",isDisabled:!i,onPress:t,children:"Add your first provider"})})]})})}function $e(){var N,L,D,$;const t=X(),a=Z(),s=ee(),n=se(),i=te(),l=ae(),m=ne(),[v,u]=x.useState(!1),[p,c]=x.useState(null),[f,h]=x.useState({}),d=Ce((N=t.data)==null?void 0:N.providers,a.data),y=new Map((((L=n.data)==null?void 0:L.providers)??[]).map(r=>[r.instance,r])),o=t.isLoading||a.isLoading,j=((D=a.data)==null?void 0:D.find(r=>r.instance===p))??null,P=(($=s.data)==null?void 0:$.require_pricing)===!0&&s.data.default_pricing===!1,k=s.data?s.data.secret_key_configured!==!1:!s.isError,w=!o&&d.length===0&&!v,I=r=>{h(b=>({...b,[r]:{status:"pending"}})),l.mutate(r,{onSuccess:b=>h(S=>({...S,[r]:{status:"done",...b}})),onError:b=>h(S=>({...S,[r]:{status:"done",ok:!1,model_count:0,error:M(b)}}))})};return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(re,{title:"Providers",description:"Add provider API keys here to serve models without editing config.yml. Keys are encrypted at rest.",action:v||w?null:e.jsx(g,{variant:"primary",isDisabled:!k,onPress:()=>{c(null),u(!0)},children:"Add provider"})}),e.jsx(R,{error:t.error??a.error??s.error??n.error??m.error??i.error}),k?null:e.jsxs(ie,{tone:"warning",children:[e.jsx("code",{children:"OTARI_SECRET_KEY"})," is not set, so provider keys can't be encrypted at rest and adding providers from the dashboard is disabled. Set it on the server and restart to add providers here. Providers defined in"," ",e.jsx("code",{children:"config.yml"})," keep working without it."]}),w?e.jsx(Ie,{onAddProvider:()=>{c(null),u(!0)},needsPricing:P,onEnablePricing:()=>m.mutate({default_pricing:!0}),enabling:m.isPending,secretKeyConfigured:k}):null,v&&k?e.jsx(Se,{onClose:()=>u(!1)}):null,j?e.jsx(_e,{provider:j,onClose:()=>c(null)}):null,!o&&d.length>0&&n.data&&n.data.total>0?e.jsx(we,{healthy:n.data.healthy,total:n.data.total,checkedAt:n.data.checked_at}):null,e.jsxs(xe,{children:[e.jsx(pe,{children:e.jsxs("tr",{children:[e.jsx(_,{children:"Provider"}),e.jsx(_,{children:"Type"}),e.jsx(_,{children:"Source"}),e.jsx(_,{children:"API key"}),e.jsx(_,{children:"Status"}),e.jsx(_,{className:"text-right",children:"Actions"})]})}),e.jsx("tbody",{children:o?e.jsx(he,{colSpan:6}):d.length===0?e.jsx(ve,{colSpan:6,children:"No providers yet. Add your first provider to start serving models."}):d.map(r=>{var b,S,O,q,F,H;return e.jsxs(ge,{children:[e.jsx(C,{className:"font-medium",children:e.jsx(Q,{to:`/models?provider=${encodeURIComponent(r.instance)}`,className:"text-[var(--otari-ink)] hover:text-[var(--otari-brand-dark)] hover:underline",children:r.instance})}),e.jsx(C,{className:"text-[var(--otari-muted)]",children:((b=r.meta)==null?void 0:b.provider_type)??((S=r.stored)==null?void 0:S.provider_type)??r.instance}),e.jsx(C,{children:r.source==="stored"?e.jsx(z,{size:"sm",color:"accent",children:"stored"}):e.jsx(z,{size:"sm",color:"default",children:"config"})}),e.jsx(C,{className:"text-[var(--otari-muted)]",children:r.source==="stored"?r.stored&&!r.stored.decryptable?e.jsx("span",{className:"text-amber-700",title:"This key can't be decrypted with the current OTARI_SECRET_KEY. Replace the key, or restore the original OTARI_SECRET_KEY.",children:"⚠ key unreadable"}):e.jsx("code",{children:(O=r.stored)!=null&&O.last4?`••••${r.stored.last4}`:"none set"}):(q=r.meta)!=null&&q.env_key?e.jsxs("span",{children:["via ",e.jsx("code",{children:r.meta.env_key})]}):"config.yml"}),e.jsx(C,{children:e.jsx(Te,{health:y.get(r.instance)})}),e.jsx(C,{children:r.source==="stored"?e.jsxs("div",{className:"flex flex-col items-end gap-1.5",children:[e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx(g,{size:"sm",variant:"outline",isDisabled:((F=f[r.instance])==null?void 0:F.status)==="pending"||((H=r.stored)==null?void 0:H.decryptable)===!1,onPress:()=>I(r.instance),children:"Test"}),e.jsx(g,{size:"sm",variant:"ghost",onPress:()=>{u(!1),c(r.instance)},children:"Edit"}),e.jsx(oe,{confirmLabel:"Delete",isPending:i.isPending,onConfirm:()=>i.mutate(r.instance),children:"Delete"})]}),e.jsx(Ae,{state:f[r.instance]})]}):e.jsx("span",{className:"block text-right text-xs text-[var(--otari-muted)]",children:"managed in config.yml"})})]},r.instance)})})]})]})}export{$e as ProvidersPage}; diff --git a/src/gateway/static/dashboard/assets/SettingsPage-BPWZBXQE.js b/src/gateway/static/dashboard/assets/SettingsPage-hENBFRMI.js similarity index 99% rename from src/gateway/static/dashboard/assets/SettingsPage-BPWZBXQE.js rename to src/gateway/static/dashboard/assets/SettingsPage-hENBFRMI.js index 17e45e67..6fba6cdb 100644 --- a/src/gateway/static/dashboard/assets/SettingsPage-BPWZBXQE.js +++ b/src/gateway/static/dashboard/assets/SettingsPage-hENBFRMI.js @@ -1 +1 @@ -import{j as e}from"./tanstack-query-1t81HyiD.js";import{r as u}from"./react-dgEcD0HR.js";import{B as R,V as C,P,E as y,a0 as E,a1 as T,a2 as _,F as D,a3 as A,R as O,a4 as F,I as w}from"./index-DAVt9uB3.js";import{d as v,B as h,A as d,g as I,I as K}from"./heroui-BX6JwHY-.js";function b(t,r){return{[t]:r}}function z(t,r){let s=0;for(const a of r)if(a===t[s]&&(s+=1),s===t.length)return!0;return t.length===0}function M(t,r){const s=r.trim().toLowerCase();if(s==="")return!0;const a=`${t.key} ${t.description??""} ${t.group}`.toLowerCase(),n=t.key.toLowerCase().replace(/[^a-z0-9]/g,"");return s.split(/\s+/).every(i=>a.includes(i)||z(i,n))}function B({checked:t,onChange:r,label:s,disabled:a}){return e.jsx("button",{type:"button",role:"switch","aria-checked":t,"aria-label":s,disabled:a,onClick:()=>r(!t),className:`relative inline-flex h-6 w-11 shrink-0 items-center rounded-full transition-colors disabled:opacity-50 ${t?"bg-[var(--otari-brand)]":"bg-[var(--otari-line)]"}`,children:e.jsx("span",{className:`inline-block h-5 w-5 transform rounded-full bg-white shadow transition-transform ${t?"translate-x-5":"translate-x-0.5"}`})})}function L({field:t,onSave:r,disabled:s}){const a=typeof t.value=="number"?t.value:0,[n,i]=u.useState(String(a)),o=t.type==="float";u.useEffect(()=>{i(String(a))},[a]);const c=Number(n),p=n.trim()!==""&&Number.isFinite(c)&&(o||Number.isInteger(c)),m=t.minimum??void 0,x=t.exclusive_minimum??void 0,g=x!==void 0?c>x:m!==void 0?c>=m:c>=0,l=p&&g&&c!==a;return e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(K,{type:"number",min:"0",step:o?"any":"1",inputMode:o?"decimal":"numeric","aria-label":t.key,value:n,disabled:s,onChange:f=>i(f.target.value),className:"w-28 rounded-md border border-[var(--otari-line)] bg-white px-2 py-1 text-right text-sm tabular-nums focus:border-[var(--otari-brand)] focus:outline-none disabled:opacity-50"}),e.jsx(h,{size:"sm",variant:"primary","aria-label":`Save ${t.key}`,isDisabled:s||!l,onPress:()=>r(c),children:"Save"})]})}function $({field:t,onSave:r,disabled:s}){const a=typeof t.value=="string"?t.value:"",[n,i]=u.useState(a);u.useEffect(()=>{i(a)},[a]);const o=n!==a;return e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("input",{type:"text","aria-label":t.key,value:n,disabled:s,placeholder:"unset",onChange:c=>i(c.target.value),className:"w-56 rounded-md border border-[var(--otari-line)] bg-white px-2 py-1 text-sm focus:border-[var(--otari-brand)] focus:outline-none disabled:opacity-50"}),e.jsx(h,{size:"sm",variant:"primary","aria-label":`Save ${t.key}`,isDisabled:s||!o,onPress:()=>r(n.trim()===""?null:n),children:"Save"})]})}function H(t){const{value:r}=t;return r==null?"unset":typeof r=="boolean"?r?"on":"off":Array.isArray(r)?r.length?r.join(", "):"none":String(r)}function Y({field:t,patch:r,disabled:s}){return t.settable?t.type==="bool"?e.jsx(B,{checked:t.value===!0,onChange:a=>r(b(t.key,a)),label:t.key,disabled:s}):t.options&&t.options.length>0?e.jsx(D,{ariaLabel:t.key,value:String(t.value??""),onChange:a=>r(b(t.key,a)),options:t.options.map(a=>({value:a,label:a}))}):t.type==="int"||t.type==="float"?e.jsx(L,{field:t,onSave:a=>r(b(t.key,a)),disabled:s}):e.jsx($,{field:t,onSave:a=>r(b(t.key,a)),disabled:s}):e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-sm tabular-nums text-[var(--otari-ink)]",children:H(t)}),e.jsx("span",{className:"rounded-full border border-[var(--otari-line)] px-2 py-0.5 text-xs text-[var(--otari-muted)]",children:"startup-only"})]})}function q({field:t,patch:r,disabled:s}){return e.jsxs("div",{className:"flex items-start justify-between gap-6 py-4",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("code",{className:"text-sm font-medium text-[var(--otari-ink)]",children:t.key}),t.description?e.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:t.description}):null]}),e.jsx("div",{className:"shrink-0 pt-0.5",children:e.jsx(Y,{field:t,patch:r,disabled:s})})]})}function V({value:t,fieldRef:r}){const s=u.useRef(null),a=r??s,[n,i]=u.useState(!1),[o,c]=u.useState(!1),p=async()=>{var m,x,g;(m=a.current)==null||m.focus(),(x=a.current)==null||x.select();try{if((g=navigator.clipboard)!=null&&g.writeText){await navigator.clipboard.writeText(t),i(!0),c(!1),window.setTimeout(()=>i(!1),2e3);return}}catch{}c(!0)};return e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-xs font-medium text-[var(--otari-muted)]",children:"New master key"}),e.jsx(h,{size:"sm",variant:"outline",onPress:p,children:n?"Copied":"Copy"})]}),e.jsx("input",{ref:a,readOnly:!0,value:t,onFocus:m=>m.currentTarget.select(),autoComplete:"off",autoCorrect:"off",autoCapitalize:"off",spellCheck:!1,"data-1p-ignore":!0,"data-lpignore":"true"}),e.jsx("span",{"aria-live":"polite",className:"text-xs text-[var(--otari-brand-dark)]",children:n?"Copied to clipboard.":""}),o?e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"Selected. Press Ctrl/Cmd-C to copy."}):null]})}function U({masterKey:t,error:r,isPending:s,onRegenerate:a,onClose:n}){const i=u.useRef(null);return u.useEffect(()=>{var o,c;t!==void 0&&((o=i.current)==null||o.focus(),(c=i.current)==null||c.select())},[t]),e.jsx(d.Backdrop,{children:e.jsx(d.Container,{placement:"center",size:"lg",children:e.jsxs(d.Dialog,{children:[e.jsx(d.Header,{children:e.jsx(d.Heading,{children:t!==void 0?"Master key regenerated":"Regenerate master key?"})}),e.jsx(d.Body,{className:"flex flex-col gap-4",children:t!==void 0?e.jsxs(e.Fragment,{children:[e.jsx(w,{tone:"warning",children:"Copy this key now. It is shown once and cannot be retrieved again after you close this dialog."}),e.jsx("p",{className:"text-sm text-[var(--otari-muted)]",children:"The previous master key has stopped working. This browser tab now uses the new key."}),e.jsx(V,{value:t,fieldRef:i})]}):e.jsxs(e.Fragment,{children:[e.jsx(w,{tone:"warning",children:"This immediately invalidates the current dashboard master key. Other signed-in dashboard sessions will need the new key to continue."}),e.jsx("p",{className:"text-sm text-[var(--otari-muted)]",children:"The replacement key will be shown once. Save it before closing the next screen."}),e.jsx(y,{error:r})]})}),e.jsx(d.Footer,{children:t!==void 0?e.jsx(h,{variant:"primary",onPress:n,children:"I’ve saved this key"}):e.jsxs(e.Fragment,{children:[e.jsx(h,{variant:"ghost",isDisabled:s,onPress:n,children:"Cancel"}),e.jsx(h,{variant:"danger",isPending:s,onPress:a,children:"Regenerate key"})]})})]})})})}function G({source:t}){const r=A(),[s,a]=u.useState(!1),[n,i]=u.useState(),o=t==="generated",c=()=>r.mutate(void 0,{onSuccess:x=>{i(x.master_key)}}),p=()=>{a(!1),i(void 0),r.reset()},m=x=>{x?(r.reset(),a(!0)):n===void 0&&p()};return e.jsx("div",{className:"flex flex-col gap-4 py-4",children:e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("code",{className:"text-sm font-medium text-[var(--otari-ink)]",children:"master_key"}),e.jsx("p",{className:"mt-1 max-w-3xl text-sm text-[var(--otari-muted)]",children:o?"This gateway uses its first-run generated dashboard key. Regeneration invalidates the current key immediately.":"This gateway uses a key managed through OTARI_MASTER_KEY or config.yml. Rotate it in configuration, then restart the gateway."})]}),e.jsxs(d,{isOpen:s,onOpenChange:m,children:[o?e.jsx(d.Trigger,{className:I({size:"sm",variant:"danger-soft"}),children:"Regenerate"}):e.jsx(h,{size:"sm",variant:"danger-soft",isDisabled:!0,children:"Managed in configuration"}),s?e.jsx(U,{masterKey:n,error:r.error,isPending:r.isPending,onRegenerate:c,onClose:p}):null]})]})})}function X(){var o;const t=O(),r=F(),s=r.data,a=((o=t.data)==null?void 0:o.length)??0,n=(t.data??[]).filter(c=>!c.decryptable).length,i=a>0;return e.jsxs("div",{className:"flex flex-col gap-4 py-4",children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("code",{className:"text-sm font-medium text-[var(--otari-ink)]",children:"OTARI_SECRET_KEY"}),e.jsxs("p",{className:"mt-1 max-w-3xl text-sm text-[var(--otari-muted)]",children:["Generate a new key with ",e.jsx("code",{children:"uv run otari gen-secret-key"}),", then restart with"," ",e.jsx("code",{children:"OTARI_SECRET_KEY=,"}),". Re-encrypt the stored provider keys, then restart with ",e.jsx("code",{children:"OTARI_SECRET_KEY="})," once none are unreadable."]})]}),e.jsx("div",{className:"shrink-0",children:e.jsx(h,{size:"sm",variant:"outline",isDisabled:!i||r.isPending,onPress:()=>r.mutate(),children:r.isPending?"Re-encrypting…":"Re-encrypt provider keys"})})]}),e.jsx(y,{error:t.error??r.error}),n>0?e.jsxs(w,{tone:"warning",children:[n," stored provider key",n===1?"":"s"," cannot be decrypted with the current"," ",e.jsx("code",{children:"OTARI_SECRET_KEY"}),". Restore the old secret key and re-encrypt, or edit each affected provider and replace its key."]}):null,s?e.jsxs("p",{className:"text-sm text-[var(--otari-muted)]",role:"status","aria-live":"polite",children:["Re-encrypted ",s.reencrypted," provider key",s.reencrypted===1?"":"s",".",s.unreadable>0?` ${s.unreadable} still need replacement.`:" All decryptable stored keys now use the primary secret key."]}):!t.isLoading&&!i?e.jsx("p",{className:"text-sm text-[var(--otari-muted)]",children:"No stored provider keys need re-encryption."}):null]})}function J({masterKeySource:t}){return e.jsxs("section",{className:"flex flex-col gap-2",children:[e.jsxs("h2",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:["Credential security ",e.jsx("span",{className:"font-normal text-[var(--otari-muted)]",children:"(2)"})]}),e.jsx(v,{children:e.jsxs(v.Content,{className:"flex flex-col divide-y divide-[var(--otari-line)] px-5 py-1",children:[e.jsx(G,{source:t}),e.jsx(X,{})]})})]})}function Q({preview:t,error:r,isPending:s,onAccept:a,onReject:n}){return e.jsx(d.Backdrop,{children:e.jsx(d.Container,{placement:"center",size:"lg",children:e.jsxs(d.Dialog,{children:[e.jsx(d.Header,{children:e.jsx(d.Heading,{children:"Review default price updates"})}),e.jsxs(d.Body,{className:"flex flex-col gap-4",children:[e.jsxs("p",{className:"text-sm text-[var(--otari-muted)]",children:[t.added_count," added, ",t.changed_count," changed, and ",t.removed_count," removed upstream model prices. The accepted catalog is saved in the database with source ",e.jsx("code",{children:"genai-prices"})," and reloads after a restart. Your ",t.protected_model_count," custom model price",t.protected_model_count===1?"":"s"," remain unchanged."]}),t.changes.length>0?e.jsx("ul",{className:"max-h-60 list-disc overflow-auto pl-5 text-sm text-[var(--otari-ink)]",children:t.changes.map(i=>e.jsxs("li",{children:[i.model_key,": ",i.change]},i.model_key))}):null,t.changes_truncated?e.jsx("p",{className:"text-xs text-[var(--otari-muted)]",children:"Only the first 100 changes are shown."}):null,e.jsx(y,{error:r})]}),e.jsxs(d.Footer,{children:[e.jsx(h,{variant:"ghost",isDisabled:s,onPress:n,children:"Reject changes"}),e.jsx(h,{variant:"primary",isPending:s,onPress:a,children:"Accept price updates"})]})]})})})}function W(){const t=E(),r=T(),s=_(),a=t.data,n=r.isPending||s.isPending,i=()=>{a===void 0||n||s.mutate(void 0,{onSuccess:t.reset})};return e.jsxs("section",{className:"flex flex-col gap-2",children:[e.jsx("h2",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:"Default pricing catalog"}),e.jsx(v,{children:e.jsxs(v.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"text-sm font-medium text-[var(--otari-ink)]",children:"genai-prices defaults"}),e.jsxs("p",{className:"mt-1 max-w-3xl text-sm text-[var(--otari-muted)]",children:["Fetch the latest upstream catalog, review the proposed change summary, then accept or reject it. Accepted data is stored as ",e.jsx("code",{children:"genai-prices"}),"; custom prices remain separate and always take precedence."]})]}),e.jsx(h,{size:"sm",variant:"outline",isDisabled:t.isPending||n,onPress:()=>t.mutate(),children:t.isPending?"Checking prices…":"Check for price updates"})]}),e.jsx(y,{error:t.error})]})}),e.jsxs(d,{isOpen:a!==void 0,onOpenChange:o=>o?void 0:i(),children:[e.jsx(d.Trigger,{className:"hidden",children:"Review price updates"}),a?e.jsx(Q,{preview:a,error:r.error??s.error,isPending:n,onAccept:()=>r.mutate(void 0,{onSuccess:t.reset}),onReject:i}):null]})]})}function Z(t){const r=[],s=new Map;for(const a of t){let n=s.get(a.group);n||(n={name:a.group,fields:[]},s.set(a.group,n),r.push(n)),n.fields.push(a)}return r}function ae(){const t=R(),r=C(),s=t.data,a=r.isPending,[n,i]=u.useState(""),[o,c]=u.useState(!1),p=u.useRef(null);u.useEffect(()=>{function l(f){var N;const j=f.target,S=j&&(j.tagName==="INPUT"||j.tagName==="TEXTAREA"||j.tagName==="SELECT");f.key==="/"&&!S&&(f.preventDefault(),(N=p.current)==null||N.focus())}return window.addEventListener("keydown",l),()=>window.removeEventListener("keydown",l)},[]);const m=l=>r.mutate(l),x=(s==null?void 0:s.config)??[],g=x.filter(l=>(o?l.settable:!0)&&M(l,n)),k=Z(g);return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(P,{title:"Settings",description:"Every effective gateway setting. Settable fields apply immediately and persist across restarts; startup-only fields are shown for reference and change only via config.yml or environment variables (then a restart)."}),e.jsx(y,{error:t.error??r.error}),e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsx("input",{ref:p,type:"search","aria-label":"Search settings",placeholder:"Search settings (press / to focus)…",value:n,onChange:l=>i(l.target.value),onKeyDown:l=>{l.key==="Escape"&&i("")},className:"min-w-0 flex-1 rounded-lg border border-[var(--otari-line)] bg-[var(--otari-bg)] px-3 py-2 text-sm text-[var(--otari-ink)] focus:border-[var(--otari-brand)] focus:outline-none"}),e.jsxs("label",{className:"flex items-center gap-2 text-sm text-[var(--otari-muted)]",children:[e.jsx("input",{type:"checkbox",checked:o,onChange:l=>c(l.target.checked),className:"h-4 w-4 accent-[var(--otari-brand)]"}),"Settable only"]})]}),s?e.jsxs("p",{className:"text-xs text-[var(--otari-muted)]",children:["Showing ",g.length," of ",x.length," settings"]}):null,s&&g.length===0?e.jsx("p",{className:"text-sm text-[var(--otari-muted)]",children:"No settings match your search."}):null,k.map(l=>e.jsxs("section",{className:"flex flex-col gap-2",children:[e.jsxs("h2",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:[l.name," ",e.jsxs("span",{className:"font-normal text-[var(--otari-muted)]",children:["(",l.fields.length,")"]})]}),e.jsx(v,{children:e.jsx(v.Content,{className:"flex flex-col divide-y divide-[var(--otari-line)] px-5 py-1",children:l.fields.map(f=>e.jsx(q,{field:f,patch:m,disabled:!s||a},f.key))})})]},l.name)),s?e.jsx(W,{}):null,s?e.jsx(J,{masterKeySource:s.master_key_source}):null,s?e.jsxs("p",{className:"text-xs text-[var(--otari-muted)]",children:["Mode: ",s.mode," · Version ",s.version,s.require_pricing?" · require_pricing on":""]}):null]})}export{ae as SettingsPage,M as fieldMatches}; +import{j as e}from"./tanstack-query-1t81HyiD.js";import{r as u}from"./react-dgEcD0HR.js";import{B as R,V as C,P,E as y,a0 as E,a1 as T,a2 as _,F as D,a3 as A,R as O,a4 as F,I as w}from"./index-BJySXQ_a.js";import{d as v,B as h,A as d,g as I,I as K}from"./heroui-BX6JwHY-.js";function b(t,r){return{[t]:r}}function z(t,r){let s=0;for(const a of r)if(a===t[s]&&(s+=1),s===t.length)return!0;return t.length===0}function M(t,r){const s=r.trim().toLowerCase();if(s==="")return!0;const a=`${t.key} ${t.description??""} ${t.group}`.toLowerCase(),n=t.key.toLowerCase().replace(/[^a-z0-9]/g,"");return s.split(/\s+/).every(i=>a.includes(i)||z(i,n))}function B({checked:t,onChange:r,label:s,disabled:a}){return e.jsx("button",{type:"button",role:"switch","aria-checked":t,"aria-label":s,disabled:a,onClick:()=>r(!t),className:`relative inline-flex h-6 w-11 shrink-0 items-center rounded-full transition-colors disabled:opacity-50 ${t?"bg-[var(--otari-brand)]":"bg-[var(--otari-line)]"}`,children:e.jsx("span",{className:`inline-block h-5 w-5 transform rounded-full bg-white shadow transition-transform ${t?"translate-x-5":"translate-x-0.5"}`})})}function L({field:t,onSave:r,disabled:s}){const a=typeof t.value=="number"?t.value:0,[n,i]=u.useState(String(a)),o=t.type==="float";u.useEffect(()=>{i(String(a))},[a]);const c=Number(n),p=n.trim()!==""&&Number.isFinite(c)&&(o||Number.isInteger(c)),m=t.minimum??void 0,x=t.exclusive_minimum??void 0,g=x!==void 0?c>x:m!==void 0?c>=m:c>=0,l=p&&g&&c!==a;return e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(K,{type:"number",min:"0",step:o?"any":"1",inputMode:o?"decimal":"numeric","aria-label":t.key,value:n,disabled:s,onChange:f=>i(f.target.value),className:"w-28 rounded-md border border-[var(--otari-line)] bg-white px-2 py-1 text-right text-sm tabular-nums focus:border-[var(--otari-brand)] focus:outline-none disabled:opacity-50"}),e.jsx(h,{size:"sm",variant:"primary","aria-label":`Save ${t.key}`,isDisabled:s||!l,onPress:()=>r(c),children:"Save"})]})}function $({field:t,onSave:r,disabled:s}){const a=typeof t.value=="string"?t.value:"",[n,i]=u.useState(a);u.useEffect(()=>{i(a)},[a]);const o=n!==a;return e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("input",{type:"text","aria-label":t.key,value:n,disabled:s,placeholder:"unset",onChange:c=>i(c.target.value),className:"w-56 rounded-md border border-[var(--otari-line)] bg-white px-2 py-1 text-sm focus:border-[var(--otari-brand)] focus:outline-none disabled:opacity-50"}),e.jsx(h,{size:"sm",variant:"primary","aria-label":`Save ${t.key}`,isDisabled:s||!o,onPress:()=>r(n.trim()===""?null:n),children:"Save"})]})}function H(t){const{value:r}=t;return r==null?"unset":typeof r=="boolean"?r?"on":"off":Array.isArray(r)?r.length?r.join(", "):"none":String(r)}function Y({field:t,patch:r,disabled:s}){return t.settable?t.type==="bool"?e.jsx(B,{checked:t.value===!0,onChange:a=>r(b(t.key,a)),label:t.key,disabled:s}):t.options&&t.options.length>0?e.jsx(D,{ariaLabel:t.key,value:String(t.value??""),onChange:a=>r(b(t.key,a)),options:t.options.map(a=>({value:a,label:a}))}):t.type==="int"||t.type==="float"?e.jsx(L,{field:t,onSave:a=>r(b(t.key,a)),disabled:s}):e.jsx($,{field:t,onSave:a=>r(b(t.key,a)),disabled:s}):e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-sm tabular-nums text-[var(--otari-ink)]",children:H(t)}),e.jsx("span",{className:"rounded-full border border-[var(--otari-line)] px-2 py-0.5 text-xs text-[var(--otari-muted)]",children:"startup-only"})]})}function q({field:t,patch:r,disabled:s}){return e.jsxs("div",{className:"flex items-start justify-between gap-6 py-4",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("code",{className:"text-sm font-medium text-[var(--otari-ink)]",children:t.key}),t.description?e.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:t.description}):null]}),e.jsx("div",{className:"shrink-0 pt-0.5",children:e.jsx(Y,{field:t,patch:r,disabled:s})})]})}function V({value:t,fieldRef:r}){const s=u.useRef(null),a=r??s,[n,i]=u.useState(!1),[o,c]=u.useState(!1),p=async()=>{var m,x,g;(m=a.current)==null||m.focus(),(x=a.current)==null||x.select();try{if((g=navigator.clipboard)!=null&&g.writeText){await navigator.clipboard.writeText(t),i(!0),c(!1),window.setTimeout(()=>i(!1),2e3);return}}catch{}c(!0)};return e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-xs font-medium text-[var(--otari-muted)]",children:"New master key"}),e.jsx(h,{size:"sm",variant:"outline",onPress:p,children:n?"Copied":"Copy"})]}),e.jsx("input",{ref:a,readOnly:!0,value:t,onFocus:m=>m.currentTarget.select(),autoComplete:"off",autoCorrect:"off",autoCapitalize:"off",spellCheck:!1,"data-1p-ignore":!0,"data-lpignore":"true"}),e.jsx("span",{"aria-live":"polite",className:"text-xs text-[var(--otari-brand-dark)]",children:n?"Copied to clipboard.":""}),o?e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"Selected. Press Ctrl/Cmd-C to copy."}):null]})}function U({masterKey:t,error:r,isPending:s,onRegenerate:a,onClose:n}){const i=u.useRef(null);return u.useEffect(()=>{var o,c;t!==void 0&&((o=i.current)==null||o.focus(),(c=i.current)==null||c.select())},[t]),e.jsx(d.Backdrop,{children:e.jsx(d.Container,{placement:"center",size:"lg",children:e.jsxs(d.Dialog,{children:[e.jsx(d.Header,{children:e.jsx(d.Heading,{children:t!==void 0?"Master key regenerated":"Regenerate master key?"})}),e.jsx(d.Body,{className:"flex flex-col gap-4",children:t!==void 0?e.jsxs(e.Fragment,{children:[e.jsx(w,{tone:"warning",children:"Copy this key now. It is shown once and cannot be retrieved again after you close this dialog."}),e.jsx("p",{className:"text-sm text-[var(--otari-muted)]",children:"The previous master key has stopped working. This browser tab now uses the new key."}),e.jsx(V,{value:t,fieldRef:i})]}):e.jsxs(e.Fragment,{children:[e.jsx(w,{tone:"warning",children:"This immediately invalidates the current dashboard master key. Other signed-in dashboard sessions will need the new key to continue."}),e.jsx("p",{className:"text-sm text-[var(--otari-muted)]",children:"The replacement key will be shown once. Save it before closing the next screen."}),e.jsx(y,{error:r})]})}),e.jsx(d.Footer,{children:t!==void 0?e.jsx(h,{variant:"primary",onPress:n,children:"I’ve saved this key"}):e.jsxs(e.Fragment,{children:[e.jsx(h,{variant:"ghost",isDisabled:s,onPress:n,children:"Cancel"}),e.jsx(h,{variant:"danger",isPending:s,onPress:a,children:"Regenerate key"})]})})]})})})}function G({source:t}){const r=A(),[s,a]=u.useState(!1),[n,i]=u.useState(),o=t==="generated",c=()=>r.mutate(void 0,{onSuccess:x=>{i(x.master_key)}}),p=()=>{a(!1),i(void 0),r.reset()},m=x=>{x?(r.reset(),a(!0)):n===void 0&&p()};return e.jsx("div",{className:"flex flex-col gap-4 py-4",children:e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("code",{className:"text-sm font-medium text-[var(--otari-ink)]",children:"master_key"}),e.jsx("p",{className:"mt-1 max-w-3xl text-sm text-[var(--otari-muted)]",children:o?"This gateway uses its first-run generated dashboard key. Regeneration invalidates the current key immediately.":"This gateway uses a key managed through OTARI_MASTER_KEY or config.yml. Rotate it in configuration, then restart the gateway."})]}),e.jsxs(d,{isOpen:s,onOpenChange:m,children:[o?e.jsx(d.Trigger,{className:I({size:"sm",variant:"danger-soft"}),children:"Regenerate"}):e.jsx(h,{size:"sm",variant:"danger-soft",isDisabled:!0,children:"Managed in configuration"}),s?e.jsx(U,{masterKey:n,error:r.error,isPending:r.isPending,onRegenerate:c,onClose:p}):null]})]})})}function X(){var o;const t=O(),r=F(),s=r.data,a=((o=t.data)==null?void 0:o.length)??0,n=(t.data??[]).filter(c=>!c.decryptable).length,i=a>0;return e.jsxs("div",{className:"flex flex-col gap-4 py-4",children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("code",{className:"text-sm font-medium text-[var(--otari-ink)]",children:"OTARI_SECRET_KEY"}),e.jsxs("p",{className:"mt-1 max-w-3xl text-sm text-[var(--otari-muted)]",children:["Generate a new key with ",e.jsx("code",{children:"uv run otari gen-secret-key"}),", then restart with"," ",e.jsx("code",{children:"OTARI_SECRET_KEY=,"}),". Re-encrypt the stored provider keys, then restart with ",e.jsx("code",{children:"OTARI_SECRET_KEY="})," once none are unreadable."]})]}),e.jsx("div",{className:"shrink-0",children:e.jsx(h,{size:"sm",variant:"outline",isDisabled:!i||r.isPending,onPress:()=>r.mutate(),children:r.isPending?"Re-encrypting…":"Re-encrypt provider keys"})})]}),e.jsx(y,{error:t.error??r.error}),n>0?e.jsxs(w,{tone:"warning",children:[n," stored provider key",n===1?"":"s"," cannot be decrypted with the current"," ",e.jsx("code",{children:"OTARI_SECRET_KEY"}),". Restore the old secret key and re-encrypt, or edit each affected provider and replace its key."]}):null,s?e.jsxs("p",{className:"text-sm text-[var(--otari-muted)]",role:"status","aria-live":"polite",children:["Re-encrypted ",s.reencrypted," provider key",s.reencrypted===1?"":"s",".",s.unreadable>0?` ${s.unreadable} still need replacement.`:" All decryptable stored keys now use the primary secret key."]}):!t.isLoading&&!i?e.jsx("p",{className:"text-sm text-[var(--otari-muted)]",children:"No stored provider keys need re-encryption."}):null]})}function J({masterKeySource:t}){return e.jsxs("section",{className:"flex flex-col gap-2",children:[e.jsxs("h2",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:["Credential security ",e.jsx("span",{className:"font-normal text-[var(--otari-muted)]",children:"(2)"})]}),e.jsx(v,{children:e.jsxs(v.Content,{className:"flex flex-col divide-y divide-[var(--otari-line)] px-5 py-1",children:[e.jsx(G,{source:t}),e.jsx(X,{})]})})]})}function Q({preview:t,error:r,isPending:s,onAccept:a,onReject:n}){return e.jsx(d.Backdrop,{children:e.jsx(d.Container,{placement:"center",size:"lg",children:e.jsxs(d.Dialog,{children:[e.jsx(d.Header,{children:e.jsx(d.Heading,{children:"Review default price updates"})}),e.jsxs(d.Body,{className:"flex flex-col gap-4",children:[e.jsxs("p",{className:"text-sm text-[var(--otari-muted)]",children:[t.added_count," added, ",t.changed_count," changed, and ",t.removed_count," removed upstream model prices. The accepted catalog is saved in the database with source ",e.jsx("code",{children:"genai-prices"})," and reloads after a restart. Your ",t.protected_model_count," custom model price",t.protected_model_count===1?"":"s"," remain unchanged."]}),t.changes.length>0?e.jsx("ul",{className:"max-h-60 list-disc overflow-auto pl-5 text-sm text-[var(--otari-ink)]",children:t.changes.map(i=>e.jsxs("li",{children:[i.model_key,": ",i.change]},i.model_key))}):null,t.changes_truncated?e.jsx("p",{className:"text-xs text-[var(--otari-muted)]",children:"Only the first 100 changes are shown."}):null,e.jsx(y,{error:r})]}),e.jsxs(d.Footer,{children:[e.jsx(h,{variant:"ghost",isDisabled:s,onPress:n,children:"Reject changes"}),e.jsx(h,{variant:"primary",isPending:s,onPress:a,children:"Accept price updates"})]})]})})})}function W(){const t=E(),r=T(),s=_(),a=t.data,n=r.isPending||s.isPending,i=()=>{a===void 0||n||s.mutate(void 0,{onSuccess:t.reset})};return e.jsxs("section",{className:"flex flex-col gap-2",children:[e.jsx("h2",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:"Default pricing catalog"}),e.jsx(v,{children:e.jsxs(v.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"text-sm font-medium text-[var(--otari-ink)]",children:"genai-prices defaults"}),e.jsxs("p",{className:"mt-1 max-w-3xl text-sm text-[var(--otari-muted)]",children:["Fetch the latest upstream catalog, review the proposed change summary, then accept or reject it. Accepted data is stored as ",e.jsx("code",{children:"genai-prices"}),"; custom prices remain separate and always take precedence."]})]}),e.jsx(h,{size:"sm",variant:"outline",isDisabled:t.isPending||n,onPress:()=>t.mutate(),children:t.isPending?"Checking prices…":"Check for price updates"})]}),e.jsx(y,{error:t.error})]})}),e.jsxs(d,{isOpen:a!==void 0,onOpenChange:o=>o?void 0:i(),children:[e.jsx(d.Trigger,{className:"hidden",children:"Review price updates"}),a?e.jsx(Q,{preview:a,error:r.error??s.error,isPending:n,onAccept:()=>r.mutate(void 0,{onSuccess:t.reset}),onReject:i}):null]})]})}function Z(t){const r=[],s=new Map;for(const a of t){let n=s.get(a.group);n||(n={name:a.group,fields:[]},s.set(a.group,n),r.push(n)),n.fields.push(a)}return r}function ae(){const t=R(),r=C(),s=t.data,a=r.isPending,[n,i]=u.useState(""),[o,c]=u.useState(!1),p=u.useRef(null);u.useEffect(()=>{function l(f){var N;const j=f.target,S=j&&(j.tagName==="INPUT"||j.tagName==="TEXTAREA"||j.tagName==="SELECT");f.key==="/"&&!S&&(f.preventDefault(),(N=p.current)==null||N.focus())}return window.addEventListener("keydown",l),()=>window.removeEventListener("keydown",l)},[]);const m=l=>r.mutate(l),x=(s==null?void 0:s.config)??[],g=x.filter(l=>(o?l.settable:!0)&&M(l,n)),k=Z(g);return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(P,{title:"Settings",description:"Every effective gateway setting. Settable fields apply immediately and persist across restarts; startup-only fields are shown for reference and change only via config.yml or environment variables (then a restart)."}),e.jsx(y,{error:t.error??r.error}),e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsx("input",{ref:p,type:"search","aria-label":"Search settings",placeholder:"Search settings (press / to focus)…",value:n,onChange:l=>i(l.target.value),onKeyDown:l=>{l.key==="Escape"&&i("")},className:"min-w-0 flex-1 rounded-lg border border-[var(--otari-line)] bg-[var(--otari-bg)] px-3 py-2 text-sm text-[var(--otari-ink)] focus:border-[var(--otari-brand)] focus:outline-none"}),e.jsxs("label",{className:"flex items-center gap-2 text-sm text-[var(--otari-muted)]",children:[e.jsx("input",{type:"checkbox",checked:o,onChange:l=>c(l.target.checked),className:"h-4 w-4 accent-[var(--otari-brand)]"}),"Settable only"]})]}),s?e.jsxs("p",{className:"text-xs text-[var(--otari-muted)]",children:["Showing ",g.length," of ",x.length," settings"]}):null,s&&g.length===0?e.jsx("p",{className:"text-sm text-[var(--otari-muted)]",children:"No settings match your search."}):null,k.map(l=>e.jsxs("section",{className:"flex flex-col gap-2",children:[e.jsxs("h2",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:[l.name," ",e.jsxs("span",{className:"font-normal text-[var(--otari-muted)]",children:["(",l.fields.length,")"]})]}),e.jsx(v,{children:e.jsx(v.Content,{className:"flex flex-col divide-y divide-[var(--otari-line)] px-5 py-1",children:l.fields.map(f=>e.jsx(q,{field:f,patch:m,disabled:!s||a},f.key))})})]},l.name)),s?e.jsx(W,{}):null,s?e.jsx(J,{masterKeySource:s.master_key_source}):null,s?e.jsxs("p",{className:"text-xs text-[var(--otari-muted)]",children:["Mode: ",s.mode," · Version ",s.version,s.require_pricing?" · require_pricing on":""]}):null]})}export{ae as SettingsPage,M as fieldMatches}; diff --git a/src/gateway/static/dashboard/assets/ToolsGuardrailsPage-Zh-JPOxJ.js b/src/gateway/static/dashboard/assets/ToolsGuardrailsPage-DWSik0Ga.js similarity index 99% rename from src/gateway/static/dashboard/assets/ToolsGuardrailsPage-Zh-JPOxJ.js rename to src/gateway/static/dashboard/assets/ToolsGuardrailsPage-DWSik0Ga.js index d57862df..8a8ae507 100644 --- a/src/gateway/static/dashboard/assets/ToolsGuardrailsPage-Zh-JPOxJ.js +++ b/src/gateway/static/dashboard/assets/ToolsGuardrailsPage-DWSik0Ga.js @@ -1 +1 @@ -import{j as e}from"./tanstack-query-1t81HyiD.js";import{r as x}from"./react-dgEcD0HR.js";import{a5 as C,a6 as L,P as E,E as P,h as w,a7 as R,F as D}from"./index-DAVt9uB3.js";import{d as N,B as b}from"./heroui-BX6JwHY-.js";function M(s,t){return{[s]:t}}const U=[{key:"web_search",label:"Web search",blurb:"Backend for otari_web_search tools (a SearXNG instance or a search adapter).",order:["web_search_url","web_search_engines","web_search_max_results","web_search_extract","web_search_purpose_hint"]},{key:"sandbox",label:"Code execution",blurb:"Backend for otari_code_execution tools (the sandbox that runs generated code).",order:["sandbox_url","sandbox_purpose_hint"]},{key:"guardrails",label:"Guardrails",blurb:"Default input-guardrails service used when a request does not pass its own guardrail URL.",order:["guardrails_url"]}];function B(){const[s,t]=x.useState(null),a=x.useRef(void 0),n=r=>{t(r),window.clearTimeout(a.current),a.current=window.setTimeout(()=>t(null),2500)};return x.useEffect(()=>()=>window.clearTimeout(a.current),[]),[s,n]}function $({message:s}){return s?e.jsxs("div",{role:"status","aria-live":"polite",className:"fixed right-4 bottom-4 z-50 flex items-center gap-2 rounded-lg border border-green-200 bg-green-50 px-4 py-3 text-sm font-medium text-green-700 shadow-lg",children:[e.jsx("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2","aria-hidden":!0,className:"h-5 w-5",children:e.jsx("path",{d:"M20 6 9 17l-5-5",strokeLinecap:"round",strokeLinejoin:"round"})}),s]}):null}const S="rounded-md border border-[var(--otari-line)] bg-[var(--otari-surface)] px-2 py-1 text-sm focus:border-[var(--otari-brand)] focus:outline-none disabled:opacity-50",g="grid gap-x-4 gap-y-1.5 py-4 sm:grid-cols-[minmax(0,1fr)_16rem_10rem] sm:items-start",_=`w-full sm:col-start-2 ${S}`,k="flex items-center gap-2 sm:col-start-3",f="flex flex-col gap-1 sm:col-span-2 sm:col-start-2";function j({message:s}){return s?e.jsx("span",{className:"break-words text-xs text-red-700",children:s}):null}function y({field:s,help:t}){return e.jsxs("div",{className:"min-w-0 sm:col-start-1",children:[e.jsx("code",{className:"text-sm font-medium text-[var(--otari-ink)]",children:s.key}),s.description?e.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:s.description}):null,t?e.jsx("p",{className:"mt-1 text-xs text-[var(--otari-muted)]",children:t}):null]})}function z({field:s,onSave:t,saveError:a,disabled:n}){const r=typeof s.value=="string"?s.value:"",[l,i]=x.useState(r),[m,p]=x.useState(null),c=R();x.useEffect(()=>{i(r)},[r]);const o=l.trim()!==r,d=l.trim(),h=m!==null&&m===d;return e.jsxs("div",{className:g,children:[e.jsx(y,{field:s,help:"Leave blank and Save to fall back to the configured default."}),e.jsx("input",{type:"text",inputMode:"url","aria-label":s.key,value:l,disabled:n,placeholder:"unset",onChange:v=>{i(v.target.value),c.reset()},className:_}),e.jsxs("div",{className:k,children:[e.jsx(b,{size:"sm",variant:"primary","aria-label":`Save ${s.key}`,isDisabled:n||!o,onPress:()=>t(d===""?null:d),children:"Save"}),e.jsx(b,{size:"sm",variant:"outline","aria-label":`Test ${s.service}`,isDisabled:d===""||c.isPending,onPress:()=>{p(d),c.mutate({service:s.service,url:d})},children:c.isPending?"Testing…":"Test"})]}),e.jsxs("div",{className:f,children:[e.jsx("span",{role:"status","aria-live":"polite",className:"block break-words text-xs",children:c.isPending||!h?null:c.error?e.jsx("span",{className:"text-red-700",children:w(c.error)}):c.data?e.jsx("span",{className:c.data.ok?"font-medium text-green-700":"text-red-700",children:c.data.reason}):null}),e.jsx(j,{message:a})]})]})}function G({field:s,onSave:t,saveError:a,disabled:n}){const r=typeof s.value=="string"?s.value:"",[l,i]=x.useState(r);x.useEffect(()=>{i(r)},[r]);const m=l!==r;return e.jsxs("div",{className:g,children:[e.jsx(y,{field:s}),e.jsx("input",{type:"text","aria-label":s.key,value:l,disabled:n,placeholder:"default",onChange:p=>i(p.target.value),className:_}),e.jsx("div",{className:k,children:e.jsx(b,{size:"sm",variant:"primary","aria-label":`Save ${s.key}`,isDisabled:n||!m,onPress:()=>t(l.trim()===""?null:l.trim()),children:"Save"})}),a?e.jsx("div",{className:f,children:e.jsx(j,{message:a})}):null]})}function I({field:s,onSave:t,saveError:a,disabled:n}){const r=typeof s.value=="number"?String(s.value):"",[l,i]=x.useState(r);x.useEffect(()=>{i(r)},[r]);const m=l.trim(),p=Number(m),o=(m===""||Number.isInteger(p)&&p>=1)&&m!==r;return e.jsxs("div",{className:g,children:[e.jsx(y,{field:s,help:"Leave blank to use the backend default."}),e.jsx("input",{type:"number",min:"1",step:"1",inputMode:"numeric","aria-label":s.key,value:l,disabled:n,placeholder:"default",onChange:d=>i(d.target.value),className:`w-full text-right tabular-nums sm:col-start-2 sm:w-28 sm:justify-self-end ${S}`}),e.jsx("div",{className:k,children:e.jsx(b,{size:"sm",variant:"primary","aria-label":`Save ${s.key}`,isDisabled:n||!o,onPress:()=>t(m===""?null:p),children:"Save"})}),a?e.jsx("div",{className:f,children:e.jsx(j,{message:a})}):null]})}function A({field:s,onSave:t,saveError:a,disabled:n}){const r=s.value===!0?"on":s.value===!1?"off":"default";return e.jsxs("div",{className:g,children:[e.jsx(y,{field:s}),e.jsx("div",{className:"sm:col-start-2 sm:justify-self-start",children:e.jsx(D,{ariaLabel:s.key,value:r,onChange:l=>t(l==="default"?null:l==="on"),options:[{value:"default",label:"Default"},{value:"on",label:"On"},{value:"off",label:"Off"}],disabled:n})}),a?e.jsx("div",{className:f,children:e.jsx(j,{message:a})}):null]})}function F({field:s,onSave:t,saveError:a,disabled:n}){return s.type==="url"?e.jsx(z,{field:s,onSave:t,saveError:a,disabled:n}):s.type==="int"?e.jsx(I,{field:s,onSave:t,saveError:a,disabled:n}):s.type==="bool"?e.jsx(A,{field:s,onSave:t,saveError:a,disabled:n}):e.jsx(G,{field:s,onSave:t,saveError:a,disabled:n})}function K(){const s=C(),t=L(),[a,n]=B(),[r,l]=x.useState({}),i=s.data,m=!i||t.isPending,p=new Map(((i==null?void 0:i.fields)??[]).map(o=>[o.key,o])),c=(o,d)=>{l(h=>{const{[o.key]:v,...u}=h;return u}),t.mutate(M(o.key,d),{onSuccess:()=>n(`${o.key} saved`),onError:h=>l(v=>({...v,[o.key]:w(h)}))})};return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(E,{title:"Tools & Guardrails",description:"Configure the built-in tool and guardrail service endpoints without a restart. Changes apply immediately and persist. URLs are validated for shape (http/https) and can be tested for reachability before saving; the network-safety gates for these services live on the Settings page."}),e.jsx(P,{error:s.error}),U.map(o=>{const d=o.order.map(u=>p.get(u)).filter(u=>u!==void 0),h=((i==null?void 0:i.fields)??[]).filter(u=>u.service===o.key&&!o.order.includes(u.key)),v=[...d,...h];return v.length===0?null:e.jsxs("section",{className:"flex flex-col gap-2",children:[e.jsx("h2",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:o.label}),e.jsx("p",{className:"text-sm text-[var(--otari-muted)]",children:o.blurb}),e.jsx(N,{children:e.jsx(N.Content,{className:"flex flex-col divide-y divide-[var(--otari-line)] px-5 py-1",children:v.map(u=>e.jsx(F,{field:u,onSave:T=>c(u,T),saveError:r[u.key],disabled:m},u.key))})})]},o.key)}),e.jsx($,{message:a})]})}export{K as ToolsGuardrailsPage}; +import{j as e}from"./tanstack-query-1t81HyiD.js";import{r as x}from"./react-dgEcD0HR.js";import{a5 as C,a6 as L,P as E,E as P,h as w,a7 as R,F as D}from"./index-BJySXQ_a.js";import{d as N,B as b}from"./heroui-BX6JwHY-.js";function M(s,t){return{[s]:t}}const U=[{key:"web_search",label:"Web search",blurb:"Backend for otari_web_search tools (a SearXNG instance or a search adapter).",order:["web_search_url","web_search_engines","web_search_max_results","web_search_extract","web_search_purpose_hint"]},{key:"sandbox",label:"Code execution",blurb:"Backend for otari_code_execution tools (the sandbox that runs generated code).",order:["sandbox_url","sandbox_purpose_hint"]},{key:"guardrails",label:"Guardrails",blurb:"Default input-guardrails service used when a request does not pass its own guardrail URL.",order:["guardrails_url"]}];function B(){const[s,t]=x.useState(null),a=x.useRef(void 0),n=r=>{t(r),window.clearTimeout(a.current),a.current=window.setTimeout(()=>t(null),2500)};return x.useEffect(()=>()=>window.clearTimeout(a.current),[]),[s,n]}function $({message:s}){return s?e.jsxs("div",{role:"status","aria-live":"polite",className:"fixed right-4 bottom-4 z-50 flex items-center gap-2 rounded-lg border border-green-200 bg-green-50 px-4 py-3 text-sm font-medium text-green-700 shadow-lg",children:[e.jsx("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2","aria-hidden":!0,className:"h-5 w-5",children:e.jsx("path",{d:"M20 6 9 17l-5-5",strokeLinecap:"round",strokeLinejoin:"round"})}),s]}):null}const S="rounded-md border border-[var(--otari-line)] bg-[var(--otari-surface)] px-2 py-1 text-sm focus:border-[var(--otari-brand)] focus:outline-none disabled:opacity-50",g="grid gap-x-4 gap-y-1.5 py-4 sm:grid-cols-[minmax(0,1fr)_16rem_10rem] sm:items-start",_=`w-full sm:col-start-2 ${S}`,k="flex items-center gap-2 sm:col-start-3",f="flex flex-col gap-1 sm:col-span-2 sm:col-start-2";function j({message:s}){return s?e.jsx("span",{className:"break-words text-xs text-red-700",children:s}):null}function y({field:s,help:t}){return e.jsxs("div",{className:"min-w-0 sm:col-start-1",children:[e.jsx("code",{className:"text-sm font-medium text-[var(--otari-ink)]",children:s.key}),s.description?e.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:s.description}):null,t?e.jsx("p",{className:"mt-1 text-xs text-[var(--otari-muted)]",children:t}):null]})}function z({field:s,onSave:t,saveError:a,disabled:n}){const r=typeof s.value=="string"?s.value:"",[l,i]=x.useState(r),[m,p]=x.useState(null),c=R();x.useEffect(()=>{i(r)},[r]);const o=l.trim()!==r,d=l.trim(),h=m!==null&&m===d;return e.jsxs("div",{className:g,children:[e.jsx(y,{field:s,help:"Leave blank and Save to fall back to the configured default."}),e.jsx("input",{type:"text",inputMode:"url","aria-label":s.key,value:l,disabled:n,placeholder:"unset",onChange:v=>{i(v.target.value),c.reset()},className:_}),e.jsxs("div",{className:k,children:[e.jsx(b,{size:"sm",variant:"primary","aria-label":`Save ${s.key}`,isDisabled:n||!o,onPress:()=>t(d===""?null:d),children:"Save"}),e.jsx(b,{size:"sm",variant:"outline","aria-label":`Test ${s.service}`,isDisabled:d===""||c.isPending,onPress:()=>{p(d),c.mutate({service:s.service,url:d})},children:c.isPending?"Testing…":"Test"})]}),e.jsxs("div",{className:f,children:[e.jsx("span",{role:"status","aria-live":"polite",className:"block break-words text-xs",children:c.isPending||!h?null:c.error?e.jsx("span",{className:"text-red-700",children:w(c.error)}):c.data?e.jsx("span",{className:c.data.ok?"font-medium text-green-700":"text-red-700",children:c.data.reason}):null}),e.jsx(j,{message:a})]})]})}function G({field:s,onSave:t,saveError:a,disabled:n}){const r=typeof s.value=="string"?s.value:"",[l,i]=x.useState(r);x.useEffect(()=>{i(r)},[r]);const m=l!==r;return e.jsxs("div",{className:g,children:[e.jsx(y,{field:s}),e.jsx("input",{type:"text","aria-label":s.key,value:l,disabled:n,placeholder:"default",onChange:p=>i(p.target.value),className:_}),e.jsx("div",{className:k,children:e.jsx(b,{size:"sm",variant:"primary","aria-label":`Save ${s.key}`,isDisabled:n||!m,onPress:()=>t(l.trim()===""?null:l.trim()),children:"Save"})}),a?e.jsx("div",{className:f,children:e.jsx(j,{message:a})}):null]})}function I({field:s,onSave:t,saveError:a,disabled:n}){const r=typeof s.value=="number"?String(s.value):"",[l,i]=x.useState(r);x.useEffect(()=>{i(r)},[r]);const m=l.trim(),p=Number(m),o=(m===""||Number.isInteger(p)&&p>=1)&&m!==r;return e.jsxs("div",{className:g,children:[e.jsx(y,{field:s,help:"Leave blank to use the backend default."}),e.jsx("input",{type:"number",min:"1",step:"1",inputMode:"numeric","aria-label":s.key,value:l,disabled:n,placeholder:"default",onChange:d=>i(d.target.value),className:`w-full text-right tabular-nums sm:col-start-2 sm:w-28 sm:justify-self-end ${S}`}),e.jsx("div",{className:k,children:e.jsx(b,{size:"sm",variant:"primary","aria-label":`Save ${s.key}`,isDisabled:n||!o,onPress:()=>t(m===""?null:p),children:"Save"})}),a?e.jsx("div",{className:f,children:e.jsx(j,{message:a})}):null]})}function A({field:s,onSave:t,saveError:a,disabled:n}){const r=s.value===!0?"on":s.value===!1?"off":"default";return e.jsxs("div",{className:g,children:[e.jsx(y,{field:s}),e.jsx("div",{className:"sm:col-start-2 sm:justify-self-start",children:e.jsx(D,{ariaLabel:s.key,value:r,onChange:l=>t(l==="default"?null:l==="on"),options:[{value:"default",label:"Default"},{value:"on",label:"On"},{value:"off",label:"Off"}],disabled:n})}),a?e.jsx("div",{className:f,children:e.jsx(j,{message:a})}):null]})}function F({field:s,onSave:t,saveError:a,disabled:n}){return s.type==="url"?e.jsx(z,{field:s,onSave:t,saveError:a,disabled:n}):s.type==="int"?e.jsx(I,{field:s,onSave:t,saveError:a,disabled:n}):s.type==="bool"?e.jsx(A,{field:s,onSave:t,saveError:a,disabled:n}):e.jsx(G,{field:s,onSave:t,saveError:a,disabled:n})}function K(){const s=C(),t=L(),[a,n]=B(),[r,l]=x.useState({}),i=s.data,m=!i||t.isPending,p=new Map(((i==null?void 0:i.fields)??[]).map(o=>[o.key,o])),c=(o,d)=>{l(h=>{const{[o.key]:v,...u}=h;return u}),t.mutate(M(o.key,d),{onSuccess:()=>n(`${o.key} saved`),onError:h=>l(v=>({...v,[o.key]:w(h)}))})};return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(E,{title:"Tools & Guardrails",description:"Configure the built-in tool and guardrail service endpoints without a restart. Changes apply immediately and persist. URLs are validated for shape (http/https) and can be tested for reachability before saving; the network-safety gates for these services live on the Settings page."}),e.jsx(P,{error:s.error}),U.map(o=>{const d=o.order.map(u=>p.get(u)).filter(u=>u!==void 0),h=((i==null?void 0:i.fields)??[]).filter(u=>u.service===o.key&&!o.order.includes(u.key)),v=[...d,...h];return v.length===0?null:e.jsxs("section",{className:"flex flex-col gap-2",children:[e.jsx("h2",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:o.label}),e.jsx("p",{className:"text-sm text-[var(--otari-muted)]",children:o.blurb}),e.jsx(N,{children:e.jsx(N.Content,{className:"flex flex-col divide-y divide-[var(--otari-line)] px-5 py-1",children:v.map(u=>e.jsx(F,{field:u,onSave:T=>c(u,T),saveError:r[u.key],disabled:m},u.key))})})]},o.key)}),e.jsx($,{message:a})]})}export{K as ToolsGuardrailsPage}; diff --git a/src/gateway/static/dashboard/assets/UsagePage-Dk-t74Uz.js b/src/gateway/static/dashboard/assets/UsagePage-B95PT-hq.js similarity index 99% rename from src/gateway/static/dashboard/assets/UsagePage-Dk-t74Uz.js rename to src/gateway/static/dashboard/assets/UsagePage-B95PT-hq.js index 93b25f17..55dc67f5 100644 --- a/src/gateway/static/dashboard/assets/UsagePage-Dk-t74Uz.js +++ b/src/gateway/static/dashboard/assets/UsagePage-B95PT-hq.js @@ -1 +1 @@ -import{j as e}from"./tanstack-query-1t81HyiD.js";import{i as ie,r as x}from"./react-dgEcD0HR.js";import{u as ce,c as D,P as de,E as ue,d as J,S as v,N as b,L as p,M as $,O as he,a8 as S}from"./index-DAVt9uB3.js";import{S as E,B as me}from"./charts-Cr3Dij9t.js";import{T as xe,a as ge,b as M,L as fe,c as ve,d as je,e as O}from"./Table-CLdjdyTx.js";import{B as k,S as K}from"./heroui-BX6JwHY-.js";import"./recharts-CR3TAEof.js";function z(a){return a.toLocaleString()}function be(a){return a===null?"—":a<1e3?`${Math.round(a)} ms`:`${(a/1e3).toFixed(2)} s`}const pe=3600,R=86400,L=[{label:"Last hour",seconds:pe,bucket:"hour"},{label:"24h",seconds:R,bucket:"hour"},{label:"7d",seconds:7*R,bucket:"day"},{label:"30d",seconds:30*R,bucket:"day"},{label:"All",seconds:null,bucket:"day"}],U=L[3],A=15;function B(a){return new Date(Date.now()-a*1e3).toISOString()}function Q({title:a,rows:r,totalCost:n,emptyLabel:f,onDrill:c,loading:d}){const[u,_]=x.useState(!1),g=u?r:r.slice(0,A),N=r.length-g.length;return e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsx("h2",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:a}),e.jsxs(xe,{children:[e.jsx(ge,{children:e.jsxs("tr",{children:[e.jsx(M,{children:a.replace("Spend by ","")}),e.jsx(M,{className:"text-right",children:"Requests"}),e.jsx(M,{className:"text-right",children:"Spend"})]})}),e.jsx("tbody",{children:d?e.jsx(fe,{colSpan:3}):r.length===0?e.jsx(ve,{colSpan:3,children:f}):g.map((o,T)=>{const m=o.is_other,y=!m&&o.key!==null,h=n>0?o.cost/n:0;return e.jsxs(je,{onClick:y?()=>c(o.key):void 0,children:[e.jsx(O,{className:"text-[var(--otari-ink)]",children:e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx("span",{className:"truncate",children:m?`Other (${o.requests.toLocaleString()} req)`:o.key??"(unknown)"}),e.jsx("span",{className:"h-1 w-full overflow-hidden rounded-full bg-[var(--otari-line)]",children:e.jsx("span",{className:"block h-full rounded-full bg-[var(--otari-brand)]",style:{width:`${Math.min(100,h*100)}%`}})})]})}),e.jsx(O,{className:"text-right tabular-nums text-[var(--otari-muted)]",children:z(o.requests)}),e.jsx(O,{className:"text-right tabular-nums text-[var(--otari-ink)]",children:$(o.cost)})]},o.key??`__null_${T}`)})})]}),!d&&N>0?e.jsxs(k,{size:"sm",variant:"ghost",onPress:()=>_(!0),children:["Show all ",r.length]}):null,!d&&u&&r.length>A?e.jsxs(k,{size:"sm",variant:"ghost",onPress:()=>_(!1),children:["Show top ",A]}):null]})}const ke=[{key:"cost",label:"Cost"},{key:"tokens",label:"Tokens"},{key:"requests",label:"Requests"}];function _e(a,r){return r==="cost"?a.cost:r==="tokens"?a.tokens:a.requests}function W(a,r){return r==="cost"?$(a):r==="tokens"?S(a):z(a)}function ye(a,r){const n=new Date(a);return Number.isNaN(n.getTime())?a:r==="hour"?n.toLocaleTimeString(void 0,{hour:"2-digit",minute:"2-digit",timeZone:"UTC"}):n.toLocaleDateString(void 0,{month:"short",day:"numeric",timeZone:"UTC"})}function Se(a,r,n){const f=a.map(d=>({label:ye(d.bucket_start,n),value:_e(d,r)})),c=f.length?Math.max(...f.map(d=>d.value)):0;return{points:f,peak:c,count:a.length}}function De(){var V,Z,Y;const a=ie(),r=ce(),[n,f]=x.useState(U),[c,d]=x.useState(()=>U.seconds===null?void 0:B(U.seconds)),[u,_]=x.useState(""),[g,N]=x.useState(""),[o,T]=x.useState("cost"),m=x.useMemo(()=>({start_date:c,model:u.trim()||void 0,user_id:g||void 0}),[c,u,g]),y=x.useMemo(()=>n.seconds===null||!c?null:{...m,start_date:new Date(new Date(c).getTime()-n.seconds*1e3).toISOString(),end_date:c},[m,n.seconds,c]),h=D(m,n.bucket),X=D(y??m,n.bucket,y!==null),i=h.data,t=i==null?void 0:i.totals,l=y!==null?(V=X.data)==null?void 0:V.totals:void 0,ee=x.useMemo(()=>({...m,model:void 0}),[m]),q=((Y=(Z=D(ee,n.bucket).data)==null?void 0:Z.by_model)==null?void 0:Y.filter(s=>!s.is_other&&s.key!==null).map(s=>s.key))??[],se=(r.data??[]).map(s=>({value:s.user_id,label:s.alias?`${s.alias} (${s.user_id})`:s.user_id})),te=(u&&!q.includes(u)?[u,...q]:q).map(s=>({value:s,label:s})),w=!!(u.trim()||g||n.seconds!==null),ae=!!(i&&t&&t.request_count===0&&!w),H=s=>{f(s),d(s.seconds===null?void 0:B(s.seconds))},ne=()=>{H(L[L.length-1]),_(""),N("")},re=()=>{n.seconds!==null&&d(B(n.seconds)),h.refetch()},I=s=>{const P=new URLSearchParams;c&&P.set("start_date",c);for(const[oe,G]of Object.entries(s))G&&P.set(oe,G);a(`/activity?${P.toString()}`)},le=t&&t.request_count>0?t.error_count/t.request_count:0,j=(i==null?void 0:i.series)??[],C=j.length>1,F=Se(j,o,n.bucket);return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(de,{title:"Usage & analytics",description:"Aggregate spend, tokens, and request volume over time. Click a model or user to drill into the request log.",action:e.jsx(k,{variant:"outline",onPress:re,isDisabled:h.isFetching,children:"Refresh"})}),e.jsx(ue,{error:h.error}),e.jsxs("div",{className:"flex flex-wrap items-end gap-3",children:[e.jsx("div",{className:"flex flex-wrap gap-2",children:L.map(s=>e.jsx(k,{size:"sm",variant:n.label===s.label?"primary":"outline",onPress:()=>H(s),children:s.label},s.label))}),e.jsxs("div",{className:"flex flex-wrap items-end gap-3",children:[e.jsx(J,{label:"User",value:g,onChange:N,options:se,placeholder:"All users"}),e.jsx(J,{label:"Model",value:u,onChange:_,options:te,placeholder:"All models"}),w?e.jsx(k,{size:"sm",variant:"ghost",onPress:ne,children:"Clear filters"}):null]})]}),ae?e.jsx("div",{className:"rounded-xl border border-[var(--otari-line)] bg-[var(--otari-surface)] px-4 py-10 text-center text-sm text-[var(--otari-muted)]",children:"No usage yet. Once the gateway serves requests, spend and volume appear here."}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex flex-wrap gap-4",children:[e.jsx(v,{label:"Spend",value:t?$(t.cost):"—",hint:t?e.jsx(b,{fraction:p(t.cost,l==null?void 0:l.cost)}):null,chart:C?e.jsx(E,{values:j.map(s=>s.cost),ariaLabel:"Spend trend over the selected window"}):void 0}),e.jsx(v,{label:"Requests",value:t?z(t.request_count):"—",hint:t?e.jsxs("span",{className:"text-[var(--otari-muted)]",children:[he(le)," errors",l?e.jsxs(e.Fragment,{children:[" · ",e.jsx(b,{fraction:p(t.request_count,l.request_count)})]}):null]}):null,chart:C?e.jsx(E,{values:j.map(s=>s.requests),ariaLabel:"Request volume trend over the selected window"}):void 0}),e.jsx(v,{label:"Tokens",value:t?S(t.total_tokens):"—",hint:t?e.jsx(b,{fraction:p(t.total_tokens,l==null?void 0:l.total_tokens)}):null,chart:C?e.jsx(E,{values:j.map(s=>s.tokens),ariaLabel:"Token usage trend over the selected window"}):void 0}),e.jsx(v,{label:"Cache read",value:t?S(t.cache_read_tokens):"—",hint:t?e.jsx(b,{fraction:p(t.cache_read_tokens,l==null?void 0:l.cache_read_tokens)}):null}),e.jsx(v,{label:"Cache write",value:t?S(t.cache_write_tokens):"—",hint:t?e.jsx(b,{fraction:p(t.cache_write_tokens,l==null?void 0:l.cache_write_tokens)}):null}),e.jsx(v,{label:"1h cache write",value:t?S(t.cache_write_1h_tokens??0):"—",hint:t?e.jsx(b,{fraction:p(t.cache_write_1h_tokens??0,(l==null?void 0:l.cache_write_1h_tokens)??0)}):null}),e.jsx(v,{label:"Avg latency",value:t?be(t.avg_latency_ms):"—"})]}),e.jsxs("div",{className:"grid gap-6 lg:grid-cols-2",children:[e.jsx(Q,{title:"Spend by model",rows:(i==null?void 0:i.by_model)??[],totalCost:(t==null?void 0:t.cost)??0,emptyLabel:w?"No usage matches these filters.":"No usage recorded yet.",onDrill:s=>I({model:s,user_id:g||void 0}),loading:h.isLoading}),e.jsx(Q,{title:"Spend by user",rows:(i==null?void 0:i.by_user)??[],totalCost:(t==null?void 0:t.cost)??0,emptyLabel:w?"No usage matches these filters.":"No usage recorded yet.",onDrill:s=>I({user_id:s,model:u.trim()||void 0}),loading:h.isLoading})]}),e.jsxs("div",{className:"flex flex-col gap-3 rounded-xl border border-[var(--otari-line)] bg-[var(--otari-surface)] p-4",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsx("h2",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:"Over time"}),e.jsxs("div",{className:"inline-flex gap-1.5",children:[ke.map(s=>e.jsx(k,{size:"sm",variant:o===s.key?"primary":"outline",onPress:()=>T(s.key),children:s.label},s.key)),h.isFetching?e.jsx(K,{size:"sm"}):null]})]}),h.isLoading?e.jsx("div",{className:"flex h-48 items-center justify-center",children:e.jsx(K,{size:"sm"})}):j.length===0?e.jsx("div",{className:"flex h-48 items-center justify-center text-sm text-[var(--otari-muted)]",children:"No data in this range."}):e.jsxs("figure",{className:"flex flex-col gap-2",children:[e.jsx(me,{data:F.points,formatValue:s=>W(s,o),ariaLabel:`${o} per ${n.bucket}`}),e.jsxs("figcaption",{className:"text-xs text-[var(--otari-muted)]",children:[W(F.peak,o)," peak · ",F.count," ",n.bucket==="hour"?"hours":"days"," (times in UTC)"]})]})]})]})]})}export{De as UsagePage}; +import{j as e}from"./tanstack-query-1t81HyiD.js";import{i as ie,r as x}from"./react-dgEcD0HR.js";import{u as ce,c as D,P as de,E as ue,d as J,S as v,N as b,L as p,M as $,O as he,a8 as S}from"./index-BJySXQ_a.js";import{S as E,B as me}from"./charts-Cr3Dij9t.js";import{T as xe,a as ge,b as M,L as fe,c as ve,d as je,e as O}from"./Table-CLdjdyTx.js";import{B as k,S as K}from"./heroui-BX6JwHY-.js";import"./recharts-CR3TAEof.js";function z(a){return a.toLocaleString()}function be(a){return a===null?"—":a<1e3?`${Math.round(a)} ms`:`${(a/1e3).toFixed(2)} s`}const pe=3600,R=86400,L=[{label:"Last hour",seconds:pe,bucket:"hour"},{label:"24h",seconds:R,bucket:"hour"},{label:"7d",seconds:7*R,bucket:"day"},{label:"30d",seconds:30*R,bucket:"day"},{label:"All",seconds:null,bucket:"day"}],U=L[3],A=15;function B(a){return new Date(Date.now()-a*1e3).toISOString()}function Q({title:a,rows:r,totalCost:n,emptyLabel:f,onDrill:c,loading:d}){const[u,_]=x.useState(!1),g=u?r:r.slice(0,A),N=r.length-g.length;return e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsx("h2",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:a}),e.jsxs(xe,{children:[e.jsx(ge,{children:e.jsxs("tr",{children:[e.jsx(M,{children:a.replace("Spend by ","")}),e.jsx(M,{className:"text-right",children:"Requests"}),e.jsx(M,{className:"text-right",children:"Spend"})]})}),e.jsx("tbody",{children:d?e.jsx(fe,{colSpan:3}):r.length===0?e.jsx(ve,{colSpan:3,children:f}):g.map((o,T)=>{const m=o.is_other,y=!m&&o.key!==null,h=n>0?o.cost/n:0;return e.jsxs(je,{onClick:y?()=>c(o.key):void 0,children:[e.jsx(O,{className:"text-[var(--otari-ink)]",children:e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx("span",{className:"truncate",children:m?`Other (${o.requests.toLocaleString()} req)`:o.key??"(unknown)"}),e.jsx("span",{className:"h-1 w-full overflow-hidden rounded-full bg-[var(--otari-line)]",children:e.jsx("span",{className:"block h-full rounded-full bg-[var(--otari-brand)]",style:{width:`${Math.min(100,h*100)}%`}})})]})}),e.jsx(O,{className:"text-right tabular-nums text-[var(--otari-muted)]",children:z(o.requests)}),e.jsx(O,{className:"text-right tabular-nums text-[var(--otari-ink)]",children:$(o.cost)})]},o.key??`__null_${T}`)})})]}),!d&&N>0?e.jsxs(k,{size:"sm",variant:"ghost",onPress:()=>_(!0),children:["Show all ",r.length]}):null,!d&&u&&r.length>A?e.jsxs(k,{size:"sm",variant:"ghost",onPress:()=>_(!1),children:["Show top ",A]}):null]})}const ke=[{key:"cost",label:"Cost"},{key:"tokens",label:"Tokens"},{key:"requests",label:"Requests"}];function _e(a,r){return r==="cost"?a.cost:r==="tokens"?a.tokens:a.requests}function W(a,r){return r==="cost"?$(a):r==="tokens"?S(a):z(a)}function ye(a,r){const n=new Date(a);return Number.isNaN(n.getTime())?a:r==="hour"?n.toLocaleTimeString(void 0,{hour:"2-digit",minute:"2-digit",timeZone:"UTC"}):n.toLocaleDateString(void 0,{month:"short",day:"numeric",timeZone:"UTC"})}function Se(a,r,n){const f=a.map(d=>({label:ye(d.bucket_start,n),value:_e(d,r)})),c=f.length?Math.max(...f.map(d=>d.value)):0;return{points:f,peak:c,count:a.length}}function De(){var V,Z,Y;const a=ie(),r=ce(),[n,f]=x.useState(U),[c,d]=x.useState(()=>U.seconds===null?void 0:B(U.seconds)),[u,_]=x.useState(""),[g,N]=x.useState(""),[o,T]=x.useState("cost"),m=x.useMemo(()=>({start_date:c,model:u.trim()||void 0,user_id:g||void 0}),[c,u,g]),y=x.useMemo(()=>n.seconds===null||!c?null:{...m,start_date:new Date(new Date(c).getTime()-n.seconds*1e3).toISOString(),end_date:c},[m,n.seconds,c]),h=D(m,n.bucket),X=D(y??m,n.bucket,y!==null),i=h.data,t=i==null?void 0:i.totals,l=y!==null?(V=X.data)==null?void 0:V.totals:void 0,ee=x.useMemo(()=>({...m,model:void 0}),[m]),q=((Y=(Z=D(ee,n.bucket).data)==null?void 0:Z.by_model)==null?void 0:Y.filter(s=>!s.is_other&&s.key!==null).map(s=>s.key))??[],se=(r.data??[]).map(s=>({value:s.user_id,label:s.alias?`${s.alias} (${s.user_id})`:s.user_id})),te=(u&&!q.includes(u)?[u,...q]:q).map(s=>({value:s,label:s})),w=!!(u.trim()||g||n.seconds!==null),ae=!!(i&&t&&t.request_count===0&&!w),H=s=>{f(s),d(s.seconds===null?void 0:B(s.seconds))},ne=()=>{H(L[L.length-1]),_(""),N("")},re=()=>{n.seconds!==null&&d(B(n.seconds)),h.refetch()},I=s=>{const P=new URLSearchParams;c&&P.set("start_date",c);for(const[oe,G]of Object.entries(s))G&&P.set(oe,G);a(`/activity?${P.toString()}`)},le=t&&t.request_count>0?t.error_count/t.request_count:0,j=(i==null?void 0:i.series)??[],C=j.length>1,F=Se(j,o,n.bucket);return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(de,{title:"Usage & analytics",description:"Aggregate spend, tokens, and request volume over time. Click a model or user to drill into the request log.",action:e.jsx(k,{variant:"outline",onPress:re,isDisabled:h.isFetching,children:"Refresh"})}),e.jsx(ue,{error:h.error}),e.jsxs("div",{className:"flex flex-wrap items-end gap-3",children:[e.jsx("div",{className:"flex flex-wrap gap-2",children:L.map(s=>e.jsx(k,{size:"sm",variant:n.label===s.label?"primary":"outline",onPress:()=>H(s),children:s.label},s.label))}),e.jsxs("div",{className:"flex flex-wrap items-end gap-3",children:[e.jsx(J,{label:"User",value:g,onChange:N,options:se,placeholder:"All users"}),e.jsx(J,{label:"Model",value:u,onChange:_,options:te,placeholder:"All models"}),w?e.jsx(k,{size:"sm",variant:"ghost",onPress:ne,children:"Clear filters"}):null]})]}),ae?e.jsx("div",{className:"rounded-xl border border-[var(--otari-line)] bg-[var(--otari-surface)] px-4 py-10 text-center text-sm text-[var(--otari-muted)]",children:"No usage yet. Once the gateway serves requests, spend and volume appear here."}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex flex-wrap gap-4",children:[e.jsx(v,{label:"Spend",value:t?$(t.cost):"—",hint:t?e.jsx(b,{fraction:p(t.cost,l==null?void 0:l.cost)}):null,chart:C?e.jsx(E,{values:j.map(s=>s.cost),ariaLabel:"Spend trend over the selected window"}):void 0}),e.jsx(v,{label:"Requests",value:t?z(t.request_count):"—",hint:t?e.jsxs("span",{className:"text-[var(--otari-muted)]",children:[he(le)," errors",l?e.jsxs(e.Fragment,{children:[" · ",e.jsx(b,{fraction:p(t.request_count,l.request_count)})]}):null]}):null,chart:C?e.jsx(E,{values:j.map(s=>s.requests),ariaLabel:"Request volume trend over the selected window"}):void 0}),e.jsx(v,{label:"Tokens",value:t?S(t.total_tokens):"—",hint:t?e.jsx(b,{fraction:p(t.total_tokens,l==null?void 0:l.total_tokens)}):null,chart:C?e.jsx(E,{values:j.map(s=>s.tokens),ariaLabel:"Token usage trend over the selected window"}):void 0}),e.jsx(v,{label:"Cache read",value:t?S(t.cache_read_tokens):"—",hint:t?e.jsx(b,{fraction:p(t.cache_read_tokens,l==null?void 0:l.cache_read_tokens)}):null}),e.jsx(v,{label:"Cache write",value:t?S(t.cache_write_tokens):"—",hint:t?e.jsx(b,{fraction:p(t.cache_write_tokens,l==null?void 0:l.cache_write_tokens)}):null}),e.jsx(v,{label:"1h cache write",value:t?S(t.cache_write_1h_tokens??0):"—",hint:t?e.jsx(b,{fraction:p(t.cache_write_1h_tokens??0,(l==null?void 0:l.cache_write_1h_tokens)??0)}):null}),e.jsx(v,{label:"Avg latency",value:t?be(t.avg_latency_ms):"—"})]}),e.jsxs("div",{className:"grid gap-6 lg:grid-cols-2",children:[e.jsx(Q,{title:"Spend by model",rows:(i==null?void 0:i.by_model)??[],totalCost:(t==null?void 0:t.cost)??0,emptyLabel:w?"No usage matches these filters.":"No usage recorded yet.",onDrill:s=>I({model:s,user_id:g||void 0}),loading:h.isLoading}),e.jsx(Q,{title:"Spend by user",rows:(i==null?void 0:i.by_user)??[],totalCost:(t==null?void 0:t.cost)??0,emptyLabel:w?"No usage matches these filters.":"No usage recorded yet.",onDrill:s=>I({user_id:s,model:u.trim()||void 0}),loading:h.isLoading})]}),e.jsxs("div",{className:"flex flex-col gap-3 rounded-xl border border-[var(--otari-line)] bg-[var(--otari-surface)] p-4",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsx("h2",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:"Over time"}),e.jsxs("div",{className:"inline-flex gap-1.5",children:[ke.map(s=>e.jsx(k,{size:"sm",variant:o===s.key?"primary":"outline",onPress:()=>T(s.key),children:s.label},s.key)),h.isFetching?e.jsx(K,{size:"sm"}):null]})]}),h.isLoading?e.jsx("div",{className:"flex h-48 items-center justify-center",children:e.jsx(K,{size:"sm"})}):j.length===0?e.jsx("div",{className:"flex h-48 items-center justify-center text-sm text-[var(--otari-muted)]",children:"No data in this range."}):e.jsxs("figure",{className:"flex flex-col gap-2",children:[e.jsx(me,{data:F.points,formatValue:s=>W(s,o),ariaLabel:`${o} per ${n.bucket}`}),e.jsxs("figcaption",{className:"text-xs text-[var(--otari-muted)]",children:[W(F.peak,o)," peak · ",F.count," ",n.bucket==="hour"?"hours":"days"," (times in UTC)"]})]})]})]})]})}export{De as UsagePage}; diff --git a/src/gateway/static/dashboard/assets/UsersPage-D6v_0kF6.js b/src/gateway/static/dashboard/assets/UsersPage-D5CmT8Bq.js similarity index 98% rename from src/gateway/static/dashboard/assets/UsersPage-D6v_0kF6.js rename to src/gateway/static/dashboard/assets/UsersPage-D5CmT8Bq.js index 8d417142..1a1bfa43 100644 --- a/src/gateway/static/dashboard/assets/UsersPage-D6v_0kF6.js +++ b/src/gateway/static/dashboard/assets/UsersPage-D5CmT8Bq.js @@ -1 +1 @@ -import{j as e}from"./tanstack-query-1t81HyiD.js";import{r as n}from"./react-dgEcD0HR.js";import{u as E,j as w,n as I,a9 as V,P as L,E as A,aa as O}from"./index-DAVt9uB3.js";import{F as N}from"./Field-HzRk1KDP.js";import{M as B,a as R}from"./ModelScopeControl-CkKcIwGe.js";import{T as H,a as $,b as f,L as q,c as W,d as G,e as b}from"./Table-CLdjdyTx.js";import{B as o,f as P,d as v}from"./heroui-BX6JwHY-.js";const J=new Intl.NumberFormat(void 0,{style:"currency",currency:"USD",maximumFractionDigits:4});function S(t){return J.format(t)}const _=t=>t.startsWith("apikey-");function D(t){return t.split("-")[0]}function M(t){return t.name??D(t.budget_id)}function T({value:t,onChange:i,budgets:r}){return e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx("label",{htmlFor:"user-budget",className:"text-sm font-medium text-[var(--otari-ink)]",children:"Budget"}),e.jsxs("select",{id:"user-budget",value:t??"",onChange:a=>i(a.target.value||null),className:"w-full rounded-lg border border-[var(--otari-line)] bg-[var(--otari-bg)] px-3 py-2 text-sm text-[var(--otari-ink)]",children:[e.jsx("option",{value:"",children:"No budget (unlimited)"}),r.map(a=>e.jsxs("option",{value:a.budget_id,children:[M(a),a.max_budget===null?" · no limit":` · ${S(a.max_budget)}`]},a.budget_id))]}),e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"The spending limit this user is held to. Manage budgets on the Budgets page."})]})}function K({onClose:t}){const i=O(),r=w(),[a,l]=n.useState(""),[d,c]=n.useState(""),[u,j]=n.useState(null),[y,x]=n.useState(null),[g,p]=n.useState(!0),m=()=>{if(i.isPending||!g||a.trim()==="")return;const h={user_id:a.trim(),alias:d.trim()||null,budget_id:u,allowed_models:y};i.mutate(h,{onSuccess:t})};return e.jsx(v,{children:e.jsxs(v.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsx("div",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:"Create user"}),e.jsx(A,{error:i.error}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsx(N,{label:"User ID",value:a,onChange:l,placeholder:"alice@example.com",isRequired:!0,autoFocus:!0,description:"The identifier callers send as the `user` field; spend and budgets track against it."}),e.jsx(N,{label:"Alias (optional)",value:d,onChange:c,placeholder:"Alice"})]}),e.jsx(T,{value:u,onChange:j,budgets:r.data??[]}),e.jsx(B,{title:"Model access (default for this user's keys)",description:"The models this user's keys may list and call by default. A key can narrow this, but never exceed it.",initial:null,onChange:(h,C)=>{x(h),p(C)}}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(o,{variant:"primary",isDisabled:i.isPending||!g||a.trim()==="",onPress:m,children:i.isPending?"Creating…":"Create user"}),e.jsx(o,{variant:"ghost",onPress:t,children:"Cancel"})]})]})})}function Q({user:t,onClose:i}){const r=I(),a=w(),[l,d]=n.useState(t.alias??""),[c,u]=n.useState(t.budget_id),[j,y]=n.useState(t.allowed_models),[x,g]=n.useState(!0),p=()=>{if(r.isPending||!x)return;const m={alias:l.trim()||null,budget_id:c,allowed_models:j};r.mutate({id:t.user_id,body:m},{onSuccess:i})};return e.jsx(v,{children:e.jsxs(v.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsxs("div",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:["Edit ",e.jsx("code",{children:t.user_id})]}),e.jsx(A,{error:r.error}),e.jsx(N,{label:"Alias",value:l,onChange:d,placeholder:"Alice"}),e.jsx(T,{value:c,onChange:u,budgets:a.data??[]}),e.jsx(B,{title:"Model access (default for this user's keys)",description:"The models this user's keys may list and call by default. A key can narrow this, but never exceed it.",initial:t.allowed_models,onChange:(m,h)=>{y(m),g(h)}}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(o,{variant:"primary",isDisabled:r.isPending||!x,onPress:p,children:r.isPending?"Saving…":"Save changes"}),e.jsx(o,{variant:"ghost",onPress:i,children:"Cancel"})]})]})})}function X({trigger:t,message:i,confirmLabel:r,isPending:a,onConfirm:l}){const[d,c]=n.useState(!1);return d?e.jsxs("div",{className:"flex flex-col items-end gap-1.5 rounded-lg border border-amber-200 bg-amber-50 p-2 text-right",children:[e.jsx("span",{className:"max-w-xs text-xs text-amber-800",children:i}),e.jsxs("span",{className:"inline-flex gap-1",children:[e.jsx(o,{size:"sm",variant:"danger",isDisabled:a,onPress:l,children:r}),e.jsx(o,{size:"sm",variant:"ghost",isDisabled:a,onPress:()=>c(!1),children:"Cancel"})]})]}):e.jsx(o,{size:"sm",variant:"danger-soft",onPress:()=>c(!0),children:t})}function Y({user:t}){return t.blocked?e.jsx(P,{size:"sm",color:"warning",children:"Blocked"}):e.jsx(P,{size:"sm",color:"accent",children:"Active"})}function Z({allowed:t}){const{text:i,tone:r}=R(t),a=r==="danger"?"text-red-700 font-medium":r==="muted"?"text-[var(--otari-muted)]":"text-[var(--otari-brand-dark)] font-medium",l=t&&t.length>0?t.join(", "):void 0;return e.jsx("span",{className:`text-xs ${a}`,title:l,children:i})}function ee({onCreate:t}){return e.jsx(v,{children:e.jsxs(v.Content,{className:"flex flex-col gap-4 p-6",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-semibold text-[var(--otari-ink)]",children:"No users yet"}),e.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:"A user owns API keys and carries the budget and default model access those keys inherit. Create a user here, then issue its keys on the API keys page."})]}),e.jsx("div",{children:e.jsx(o,{variant:"primary",onPress:t,children:"Create your first user"})})]})})}function de(){const t=E(),i=w(),r=I(),a=V(),[l,d]=n.useState(!1),[c,u]=n.useState(null),[j,y]=n.useState(!1),x=t.data??[],g=t.isLoading,p=x.filter(s=>_(s.user_id)).length,m=j?x:x.filter(s=>!_(s.user_id)),h=x.find(s=>s.user_id===c)??null,C=!g&&m.length===0&&!l,z=new Map((i.data??[]).map(s=>[s.budget_id,s])),U=(s,k)=>r.mutate({id:s.user_id,body:{blocked:k}});return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(L,{title:"Users",description:"People and teams that own API keys. Set each one's budget and default model access here; issue their keys on the API keys page.",action:l?null:e.jsx(o,{variant:"primary",onPress:()=>{u(null),d(!0)},children:"Create user"})}),e.jsx(A,{error:t.error??r.error??a.error}),C?e.jsx(ee,{onCreate:()=>{u(null),d(!0)}}):null,p>0?e.jsxs("label",{className:"flex w-fit items-center gap-2 text-xs text-[var(--otari-muted)]",children:[e.jsx("input",{type:"checkbox",checked:j,onChange:s=>y(s.target.checked)}),"Show auto-created (virtual) users (",p,")"]}):null,l?e.jsx(K,{onClose:()=>d(!1)}):null,h?e.jsx(Q,{user:h,onClose:()=>u(null)},h.user_id):null,e.jsxs(H,{children:[e.jsx($,{children:e.jsxs("tr",{children:[e.jsx(f,{children:"User"}),e.jsx(f,{children:"Status"}),e.jsx(f,{children:"Budget"}),e.jsx(f,{children:"Spend"}),e.jsx(f,{children:"Model access"}),e.jsx(f,{className:"text-right",children:"Actions"})]})}),e.jsx("tbody",{children:g?e.jsx(q,{colSpan:6}):m.length===0?e.jsx(W,{colSpan:6,children:"No users yet. Create one, or create an API key to auto-create one."}):m.map(s=>{const k=s.budget_id?z.get(s.budget_id):void 0;return e.jsxs(G,{selected:c===s.user_id,onClick:()=>{d(!1),u(s.user_id)},children:[e.jsx(b,{className:"font-medium text-[var(--otari-ink)]",children:e.jsxs("div",{className:"flex flex-col gap-0.5",children:[e.jsxs("span",{className:"inline-flex items-center gap-1.5",children:[e.jsx("code",{className:"text-xs",children:s.user_id}),_(s.user_id)?e.jsx(P,{size:"sm",color:"default",children:"virtual"}):null]}),s.alias?e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:s.alias}):null]})}),e.jsx(b,{children:e.jsx(Y,{user:s})}),e.jsx(b,{className:"text-[var(--otari-muted)]",children:s.budget_id?e.jsx("span",{title:s.budget_id,children:k?M(k):D(s.budget_id)}):"—"}),e.jsxs(b,{className:"text-[var(--otari-muted)]",children:[S(s.spend),s.reserved>0?e.jsxs("span",{className:"text-[var(--otari-muted)]",children:[" (+",S(s.reserved)," held)"]}):null]}),e.jsx(b,{children:e.jsx(Z,{allowed:s.allowed_models})}),e.jsx(b,{children:e.jsxs("div",{className:"flex items-center justify-end gap-1.5",onClick:F=>F.stopPropagation(),children:[s.blocked?e.jsx(o,{size:"sm",variant:"outline",isDisabled:r.isPending,onPress:()=>U(s,!1),children:"Unblock"}):e.jsx(o,{size:"sm",variant:"outline",isDisabled:r.isPending,onPress:()=>U(s,!0),children:"Block"}),e.jsx(o,{size:"sm",variant:"ghost",onPress:()=>{d(!1),u(s.user_id)},children:"Edit"}),e.jsx(X,{trigger:"Delete",confirmLabel:"Delete user",isPending:a.isPending,message:e.jsxs(e.Fragment,{children:["Delete ",e.jsx("strong",{children:s.user_id}),"? This deactivates its API keys and hides the user; usage history is preserved."]}),onConfirm:()=>a.mutate(s.user_id)})]})})]},s.user_id)})})]})]})}export{de as UsersPage}; +import{j as e}from"./tanstack-query-1t81HyiD.js";import{r as n}from"./react-dgEcD0HR.js";import{u as E,j as w,n as I,a9 as V,P as L,E as A,aa as O}from"./index-BJySXQ_a.js";import{F as N}from"./Field-HzRk1KDP.js";import{M as B,a as R}from"./ModelScopeControl-DiX2Etqz.js";import{T as H,a as $,b as f,L as q,c as W,d as G,e as b}from"./Table-CLdjdyTx.js";import{B as o,f as P,d as v}from"./heroui-BX6JwHY-.js";const J=new Intl.NumberFormat(void 0,{style:"currency",currency:"USD",maximumFractionDigits:4});function S(t){return J.format(t)}const _=t=>t.startsWith("apikey-");function D(t){return t.split("-")[0]}function M(t){return t.name??D(t.budget_id)}function T({value:t,onChange:i,budgets:r}){return e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx("label",{htmlFor:"user-budget",className:"text-sm font-medium text-[var(--otari-ink)]",children:"Budget"}),e.jsxs("select",{id:"user-budget",value:t??"",onChange:a=>i(a.target.value||null),className:"w-full rounded-lg border border-[var(--otari-line)] bg-[var(--otari-bg)] px-3 py-2 text-sm text-[var(--otari-ink)]",children:[e.jsx("option",{value:"",children:"No budget (unlimited)"}),r.map(a=>e.jsxs("option",{value:a.budget_id,children:[M(a),a.max_budget===null?" · no limit":` · ${S(a.max_budget)}`]},a.budget_id))]}),e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"The spending limit this user is held to. Manage budgets on the Budgets page."})]})}function K({onClose:t}){const i=O(),r=w(),[a,l]=n.useState(""),[d,c]=n.useState(""),[u,j]=n.useState(null),[y,x]=n.useState(null),[g,p]=n.useState(!0),m=()=>{if(i.isPending||!g||a.trim()==="")return;const h={user_id:a.trim(),alias:d.trim()||null,budget_id:u,allowed_models:y};i.mutate(h,{onSuccess:t})};return e.jsx(v,{children:e.jsxs(v.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsx("div",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:"Create user"}),e.jsx(A,{error:i.error}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsx(N,{label:"User ID",value:a,onChange:l,placeholder:"alice@example.com",isRequired:!0,autoFocus:!0,description:"The identifier callers send as the `user` field; spend and budgets track against it."}),e.jsx(N,{label:"Alias (optional)",value:d,onChange:c,placeholder:"Alice"})]}),e.jsx(T,{value:u,onChange:j,budgets:r.data??[]}),e.jsx(B,{title:"Model access (default for this user's keys)",description:"The models this user's keys may list and call by default. A key can narrow this, but never exceed it.",initial:null,onChange:(h,C)=>{x(h),p(C)}}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(o,{variant:"primary",isDisabled:i.isPending||!g||a.trim()==="",onPress:m,children:i.isPending?"Creating…":"Create user"}),e.jsx(o,{variant:"ghost",onPress:t,children:"Cancel"})]})]})})}function Q({user:t,onClose:i}){const r=I(),a=w(),[l,d]=n.useState(t.alias??""),[c,u]=n.useState(t.budget_id),[j,y]=n.useState(t.allowed_models),[x,g]=n.useState(!0),p=()=>{if(r.isPending||!x)return;const m={alias:l.trim()||null,budget_id:c,allowed_models:j};r.mutate({id:t.user_id,body:m},{onSuccess:i})};return e.jsx(v,{children:e.jsxs(v.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsxs("div",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:["Edit ",e.jsx("code",{children:t.user_id})]}),e.jsx(A,{error:r.error}),e.jsx(N,{label:"Alias",value:l,onChange:d,placeholder:"Alice"}),e.jsx(T,{value:c,onChange:u,budgets:a.data??[]}),e.jsx(B,{title:"Model access (default for this user's keys)",description:"The models this user's keys may list and call by default. A key can narrow this, but never exceed it.",initial:t.allowed_models,onChange:(m,h)=>{y(m),g(h)}}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(o,{variant:"primary",isDisabled:r.isPending||!x,onPress:p,children:r.isPending?"Saving…":"Save changes"}),e.jsx(o,{variant:"ghost",onPress:i,children:"Cancel"})]})]})})}function X({trigger:t,message:i,confirmLabel:r,isPending:a,onConfirm:l}){const[d,c]=n.useState(!1);return d?e.jsxs("div",{className:"flex flex-col items-end gap-1.5 rounded-lg border border-amber-200 bg-amber-50 p-2 text-right",children:[e.jsx("span",{className:"max-w-xs text-xs text-amber-800",children:i}),e.jsxs("span",{className:"inline-flex gap-1",children:[e.jsx(o,{size:"sm",variant:"danger",isDisabled:a,onPress:l,children:r}),e.jsx(o,{size:"sm",variant:"ghost",isDisabled:a,onPress:()=>c(!1),children:"Cancel"})]})]}):e.jsx(o,{size:"sm",variant:"danger-soft",onPress:()=>c(!0),children:t})}function Y({user:t}){return t.blocked?e.jsx(P,{size:"sm",color:"warning",children:"Blocked"}):e.jsx(P,{size:"sm",color:"accent",children:"Active"})}function Z({allowed:t}){const{text:i,tone:r}=R(t),a=r==="danger"?"text-red-700 font-medium":r==="muted"?"text-[var(--otari-muted)]":"text-[var(--otari-brand-dark)] font-medium",l=t&&t.length>0?t.join(", "):void 0;return e.jsx("span",{className:`text-xs ${a}`,title:l,children:i})}function ee({onCreate:t}){return e.jsx(v,{children:e.jsxs(v.Content,{className:"flex flex-col gap-4 p-6",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-semibold text-[var(--otari-ink)]",children:"No users yet"}),e.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:"A user owns API keys and carries the budget and default model access those keys inherit. Create a user here, then issue its keys on the API keys page."})]}),e.jsx("div",{children:e.jsx(o,{variant:"primary",onPress:t,children:"Create your first user"})})]})})}function de(){const t=E(),i=w(),r=I(),a=V(),[l,d]=n.useState(!1),[c,u]=n.useState(null),[j,y]=n.useState(!1),x=t.data??[],g=t.isLoading,p=x.filter(s=>_(s.user_id)).length,m=j?x:x.filter(s=>!_(s.user_id)),h=x.find(s=>s.user_id===c)??null,C=!g&&m.length===0&&!l,z=new Map((i.data??[]).map(s=>[s.budget_id,s])),U=(s,k)=>r.mutate({id:s.user_id,body:{blocked:k}});return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(L,{title:"Users",description:"People and teams that own API keys. Set each one's budget and default model access here; issue their keys on the API keys page.",action:l?null:e.jsx(o,{variant:"primary",onPress:()=>{u(null),d(!0)},children:"Create user"})}),e.jsx(A,{error:t.error??r.error??a.error}),C?e.jsx(ee,{onCreate:()=>{u(null),d(!0)}}):null,p>0?e.jsxs("label",{className:"flex w-fit items-center gap-2 text-xs text-[var(--otari-muted)]",children:[e.jsx("input",{type:"checkbox",checked:j,onChange:s=>y(s.target.checked)}),"Show auto-created (virtual) users (",p,")"]}):null,l?e.jsx(K,{onClose:()=>d(!1)}):null,h?e.jsx(Q,{user:h,onClose:()=>u(null)},h.user_id):null,e.jsxs(H,{children:[e.jsx($,{children:e.jsxs("tr",{children:[e.jsx(f,{children:"User"}),e.jsx(f,{children:"Status"}),e.jsx(f,{children:"Budget"}),e.jsx(f,{children:"Spend"}),e.jsx(f,{children:"Model access"}),e.jsx(f,{className:"text-right",children:"Actions"})]})}),e.jsx("tbody",{children:g?e.jsx(q,{colSpan:6}):m.length===0?e.jsx(W,{colSpan:6,children:"No users yet. Create one, or create an API key to auto-create one."}):m.map(s=>{const k=s.budget_id?z.get(s.budget_id):void 0;return e.jsxs(G,{selected:c===s.user_id,onClick:()=>{d(!1),u(s.user_id)},children:[e.jsx(b,{className:"font-medium text-[var(--otari-ink)]",children:e.jsxs("div",{className:"flex flex-col gap-0.5",children:[e.jsxs("span",{className:"inline-flex items-center gap-1.5",children:[e.jsx("code",{className:"text-xs",children:s.user_id}),_(s.user_id)?e.jsx(P,{size:"sm",color:"default",children:"virtual"}):null]}),s.alias?e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:s.alias}):null]})}),e.jsx(b,{children:e.jsx(Y,{user:s})}),e.jsx(b,{className:"text-[var(--otari-muted)]",children:s.budget_id?e.jsx("span",{title:s.budget_id,children:k?M(k):D(s.budget_id)}):"—"}),e.jsxs(b,{className:"text-[var(--otari-muted)]",children:[S(s.spend),s.reserved>0?e.jsxs("span",{className:"text-[var(--otari-muted)]",children:[" (+",S(s.reserved)," held)"]}):null]}),e.jsx(b,{children:e.jsx(Z,{allowed:s.allowed_models})}),e.jsx(b,{children:e.jsxs("div",{className:"flex items-center justify-end gap-1.5",onClick:F=>F.stopPropagation(),children:[s.blocked?e.jsx(o,{size:"sm",variant:"outline",isDisabled:r.isPending,onPress:()=>U(s,!1),children:"Unblock"}):e.jsx(o,{size:"sm",variant:"outline",isDisabled:r.isPending,onPress:()=>U(s,!0),children:"Block"}),e.jsx(o,{size:"sm",variant:"ghost",onPress:()=>{d(!1),u(s.user_id)},children:"Edit"}),e.jsx(X,{trigger:"Delete",confirmLabel:"Delete user",isPending:a.isPending,message:e.jsxs(e.Fragment,{children:["Delete ",e.jsx("strong",{children:s.user_id}),"? This deactivates its API keys and hides the user; usage history is preserved."]}),onConfirm:()=>a.mutate(s.user_id)})]})})]},s.user_id)})})]})]})}export{de as UsersPage}; diff --git a/src/gateway/static/dashboard/assets/index-DAVt9uB3.js b/src/gateway/static/dashboard/assets/index-BJySXQ_a.js similarity index 96% rename from src/gateway/static/dashboard/assets/index-DAVt9uB3.js rename to src/gateway/static/dashboard/assets/index-BJySXQ_a.js index 26126668..87984804 100644 --- a/src/gateway/static/dashboard/assets/index-DAVt9uB3.js +++ b/src/gateway/static/dashboard/assets/index-BJySXQ_a.js @@ -1,2 +1,2 @@ -const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/ActivityPage-Cw34Jlno.js","assets/tanstack-query-1t81HyiD.js","assets/react-dgEcD0HR.js","assets/Table-CLdjdyTx.js","assets/heroui-BX6JwHY-.js","assets/AliasesPage-CCRTl9Co.js","assets/Field-HzRk1KDP.js","assets/BudgetsPage-iAjnK5BF.js","assets/KeysPage-C6eaoTUP.js","assets/ModelScopeControl-CkKcIwGe.js","assets/ModelsPage-DwBDAaxV.js","assets/OverviewPage-B_g2blUc.js","assets/charts-Cr3Dij9t.js","assets/recharts-CR3TAEof.js","assets/ProvidersPage-DhHL_fxe.js","assets/SettingsPage-BPWZBXQE.js","assets/ToolsGuardrailsPage-Zh-JPOxJ.js","assets/UsagePage-Dk-t74Uz.js","assets/UsersPage-D6v_0kF6.js"])))=>i.map(i=>d[i]); -var be=Object.defineProperty;var je=(e,r,s)=>r in e?be(e,r,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[r]=s;var ee=(e,r,s)=>je(e,typeof r!="symbol"?r+"":r,s);import{u as x,j as t,a as v,b as f,k as Q,Q as we,c as Se}from"./tanstack-query-1t81HyiD.js";import{d as ke,r as o,N as ie,O as Pe,H as Ee,e as Ne,f as b,h as Ce}from"./react-dgEcD0HR.js";import{C as I,L as oe,I as le,a as Te,b as _e,B as P,d as L,c as C,T as Ae,e as Le}from"./heroui-BX6JwHY-.js";(function(){const r=document.createElement("link").relList;if(r&&r.supports&&r.supports("modulepreload"))return;for(const n of document.querySelectorAll('link[rel="modulepreload"]'))a(n);new MutationObserver(n=>{for(const l of n)if(l.type==="childList")for(const d of l.addedNodes)d.tagName==="LINK"&&d.rel==="modulepreload"&&a(d)}).observe(document,{childList:!0,subtree:!0});function s(n){const l={};return n.integrity&&(l.integrity=n.integrity),n.referrerPolicy&&(l.referrerPolicy=n.referrerPolicy),n.crossOrigin==="use-credentials"?l.credentials="include":n.crossOrigin==="anonymous"?l.credentials="omit":l.credentials="same-origin",l}function a(n){if(n.ep)return;n.ep=!0;const l=s(n);fetch(n.href,l)}})();var Ie=ke();const qe="modulepreload",Re=function(e){return"/"+e},te={},S=function(r,s,a){let n=Promise.resolve();if(s&&s.length>0){let d=function(h){return Promise.all(h.map(p=>Promise.resolve(p).then(g=>({status:"fulfilled",value:g}),g=>({status:"rejected",reason:g}))))};document.getElementsByTagName("link");const u=document.querySelector("meta[property=csp-nonce]"),y=(u==null?void 0:u.nonce)||(u==null?void 0:u.getAttribute("nonce"));n=d(s.map(h=>{if(h=Re(h),h in te)return;te[h]=!0;const p=h.endsWith(".css"),g=p?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${h}"]${g}`))return;const m=document.createElement("link");if(m.rel=p?"stylesheet":qe,p||(m.as="script"),m.crossOrigin="",m.href=h,y&&m.setAttribute("nonce",y),document.head.appendChild(m),p)return new Promise((c,j)=>{m.addEventListener("load",c),m.addEventListener("error",()=>j(new Error(`Unable to preload CSS for ${h}`)))})}))}function l(d){const u=new Event("vite:preloadError",{cancelable:!0});if(u.payload=d,window.dispatchEvent(u),!u.defaultPrevented)throw d}return n.then(d=>{for(const u of d||[])u.status==="rejected"&&l(u.reason);return r().catch(l)})};class E extends Error{constructor(s,a){super(a);ee(this,"status");this.name="ApiError",this.status=s}}let q=null;function re(e){q=e}async function $(e){try{const r=await e.json();if(typeof r.detail=="string")return r.detail;if(r.detail!=null)return JSON.stringify(r.detail)}catch{}return e.statusText||`Request failed (${e.status})`}async function Oe(e){let r;try{r=await fetch("/v1/auth/session",{method:"POST",headers:{Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify({master_key:e})})}catch{throw new E(0,"Network error: could not reach the gateway.")}if(r.status===401||r.status===403)return!1;if(!r.ok)throw new E(r.status,await $(r));return!0}async function De(){try{await fetch("/v1/auth/session",{method:"DELETE"})}catch{}}async function i(e,r={}){const s=new Headers(r.headers);s.set("Accept","application/json"),r.body!=null&&!s.has("Content-Type")&&s.set("Content-Type","application/json");let a;try{a=await fetch(e,{...r,headers:s})}catch{throw new E(0,"Network error: could not reach the gateway.")}if(a.status===401||a.status===403)throw q==null||q(),new E(a.status,await $(a));if(!a.ok)throw new E(a.status,await $(a));if(a.status!==204)return await a.json()}const z="otari.dashboard.hasSession",ce=o.createContext(null);function Fe(){try{return window.localStorage.getItem(z)==="1"}catch{return!1}}function Me({children:e}){const r=x(),[s,a]=o.useState(Fe),n=o.useCallback(()=>{De(),a(!1),r.clear();try{window.localStorage.removeItem(z)}catch{}},[r]),l=o.useCallback(()=>{r.clear(),a(!0);try{window.localStorage.setItem(z,"1")}catch{}},[r]);o.useEffect(()=>(re(n),()=>re(null)),[n]);const d=o.useMemo(()=>({isAuthenticated:s,login:l,logout:n}),[s,l,n]);return t.jsx(ce.Provider,{value:d,children:e})}function V(){const e=o.useContext(ce);if(!e)throw new Error("useAuth must be used within an AuthProvider");return e}function Ke(e){return e instanceof E&&e.status===0}function Ue(){const e=x(),[r,s]=o.useState(!1);return o.useEffect(()=>{const a=e.getQueryCache(),n=()=>a.getAll().some(l=>l.state.status==="error"&&Ke(l.state.error));return s(n()),a.subscribe(()=>s(n()))},[e]),r}function Be(){return Ue()?t.jsxs("div",{role:"alert","aria-live":"assertive",className:"fixed right-4 bottom-4 z-50 flex max-w-sm items-start gap-2.5 rounded-lg border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700 shadow-lg",children:[t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2","aria-hidden":!0,className:"mt-0.5 h-5 w-5 shrink-0",children:[t.jsx("path",{d:"M12 9v4M12 17h.01",strokeLinecap:"round",strokeLinejoin:"round"}),t.jsx("path",{d:"M10.3 3.9 1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0z",strokeLinejoin:"round"})]}),t.jsxs("span",{children:[t.jsx("strong",{className:"font-semibold",children:"Can’t reach the gateway."})," The backend isn’t responding; data won’t load or save until the connection is restored."]})]}):null}const N="models",O="pricing",ue="settings",de="tool-settings",H="aliases",W="discoverable",G="providers",J="provider-health",me="stored-providers",$e="model-metadata",ze="build",T="keys",_="budgets",fe="users",Y="usage",Qe=6e4,se=60*6e4;function Dt(){return v({queryKey:[N],queryFn:()=>i("/v1/models"),staleTime:6e4})}function Ve(){return v({queryKey:[ze],queryFn:()=>i("/dashboard-build.json"),refetchInterval:Qe,refetchOnWindowFocus:!0,staleTime:0,retry:!1})}function Ft(){return v({queryKey:[W],queryFn:()=>i("/v1/models/discoverable"),staleTime:5*6e4})}function Mt(){return v({queryKey:[G],queryFn:()=>i("/v1/providers"),staleTime:5*6e4})}function Kt(){return v({queryKey:["provider-catalog"],queryFn:()=>i("/v1/providers/catalog"),staleTime:1/0})}function Ut(e){return v({queryKey:["provider-catalog",e],queryFn:()=>i(`/v1/providers/catalog/${encodeURIComponent(e)}`),enabled:e!=="",staleTime:1/0})}function Bt(){return v({queryKey:[J],queryFn:()=>i("/v1/providers/health"),staleTime:se,refetchInterval:se})}function $t(){const e=x();return f({mutationFn:()=>i("/v1/providers/health?refresh=true"),onSuccess:r=>e.setQueryData([J],r)})}function zt(){return v({queryKey:[me],queryFn:()=>i("/v1/provider-credentials"),staleTime:6e4})}function D(e){e.invalidateQueries({queryKey:[me]}),e.invalidateQueries({queryKey:[G]}),e.invalidateQueries({queryKey:[N]}),e.invalidateQueries({queryKey:[W]}),e.invalidateQueries({queryKey:[J]})}function Qt(){const e=x();return f({mutationFn:r=>i("/v1/provider-credentials",{method:"POST",body:JSON.stringify(r)}),onSuccess:()=>D(e)})}function Vt(){const e=x();return f({mutationFn:({instance:r,body:s})=>i(`/v1/provider-credentials/${encodeURIComponent(r)}`,{method:"PATCH",body:JSON.stringify(s)}),onSuccess:()=>D(e)})}function Ht(){const e=x();return f({mutationFn:r=>i(`/v1/provider-credentials/${encodeURIComponent(r)}`,{method:"DELETE"}),onSuccess:()=>D(e)})}function Wt(){const e=x();return f({mutationFn:()=>i("/v1/provider-credentials/reencrypt",{method:"POST"}),onSuccess:()=>D(e)})}function Gt(){return f({mutationFn:e=>i(`/v1/provider-credentials/${encodeURIComponent(e)}/test`,{method:"POST"})})}function Jt(){return f({mutationFn:e=>i("/v1/provider-credentials/test",{method:"POST",body:JSON.stringify(e)})})}function Yt(){return v({queryKey:[$e],queryFn:()=>i("/v1/models/metadata"),staleTime:10*6e4})}function Xt(){return v({queryKey:[H],queryFn:()=>i("/v1/aliases"),staleTime:6e4})}function Zt(){const e=x();return f({mutationFn:r=>i("/v1/aliases",{method:"POST",body:JSON.stringify(r)}),onSuccess:()=>{e.invalidateQueries({queryKey:[H]}),e.invalidateQueries({queryKey:[N]})}})}function er(){const e=x();return f({mutationFn:r=>i(`/v1/aliases/${encodeURIComponent(r)}`,{method:"DELETE"}),onSuccess:()=>{e.invalidateQueries({queryKey:[H]}),e.invalidateQueries({queryKey:[N]})}})}function He(){return v({queryKey:[ue],queryFn:()=>i("/v1/settings"),staleTime:6e4})}function We(){const e=x();return f({mutationFn:r=>i("/v1/settings",{method:"PATCH",body:JSON.stringify(r)}),onSuccess:r=>{e.setQueryData([ue],r),e.invalidateQueries({queryKey:[N]}),e.invalidateQueries({queryKey:[W]})}})}function tr(){return f({mutationFn:()=>i("/v1/settings/master-key/rotate",{method:"POST"})})}function rr(){return v({queryKey:[de],queryFn:()=>i("/v1/tool-settings"),staleTime:6e4})}function sr(){const e=x();return f({mutationFn:r=>i("/v1/tool-settings",{method:"PATCH",body:JSON.stringify(r)}),onSuccess:r=>{e.setQueryData([de],r)}})}function nr(){return f({mutationFn:({service:e,url:r})=>i(`/v1/tool-settings/${encodeURIComponent(e)}/test`,{method:"POST",body:JSON.stringify({url:r})})})}const F=1e3,Ge=100;async function Je(){const e=[];for(let r=0;ri("/v1/pricing",{method:"POST",body:JSON.stringify(r)}),onSuccess:()=>{e.invalidateQueries({queryKey:[O]}),e.invalidateQueries({queryKey:[N]})}})}function or(){const e=x();return f({mutationFn:r=>i(`/v1/pricing/${encodeURIComponent(r)}`,{method:"DELETE"}),onSuccess:()=>{e.invalidateQueries({queryKey:[O]}),e.invalidateQueries({queryKey:[N]})}})}function lr(){return f({mutationFn:()=>i("/v1/pricing/refresh",{method:"POST"})})}function cr(){const e=x();return f({mutationFn:()=>i("/v1/pricing/refresh/confirm",{method:"POST"}),onSuccess:()=>{e.invalidateQueries({queryKey:[O]}),e.invalidateQueries({queryKey:[N]}),e.invalidateQueries({queryKey:[G]})}})}function ur(){return f({mutationFn:()=>i("/v1/pricing/refresh/reject",{method:"POST"})})}const M=1e3,Ye=100;async function Xe(){const e=[];for(let r=0;ri("/v1/keys",{method:"POST",body:JSON.stringify(r)}),onSuccess:()=>void e.invalidateQueries({queryKey:[T]})})}function fr(){const e=x();return f({mutationFn:({id:r,body:s})=>i(`/v1/keys/${encodeURIComponent(r)}`,{method:"PATCH",body:JSON.stringify(s)}),onSuccess:()=>void e.invalidateQueries({queryKey:[T]})})}function hr(){const e=x();return f({mutationFn:r=>i(`/v1/keys/${encodeURIComponent(r)}/rotate`,{method:"POST"}),onSuccess:()=>void e.invalidateQueries({queryKey:[T]})})}function xr(){const e=x();return f({mutationFn:r=>i(`/v1/keys/${encodeURIComponent(r)}`,{method:"DELETE"}),onSuccess:()=>void e.invalidateQueries({queryKey:[T]})})}const K=1e3,Ze=100;async function et(){const e=[];for(let r=0;ri(`/v1/budgets/${encodeURIComponent(e)}/reset-logs`),enabled:e!==null,staleTime:6e4})}function gr(){const e=x();return f({mutationFn:r=>i("/v1/budgets",{method:"POST",body:JSON.stringify(r)}),onSuccess:()=>void e.invalidateQueries({queryKey:[_]})})}function pr(){const e=x();return f({mutationFn:({id:r,body:s})=>i(`/v1/budgets/${encodeURIComponent(r)}`,{method:"PATCH",body:JSON.stringify(s)}),onSuccess:()=>void e.invalidateQueries({queryKey:[_]})})}function br(){const e=x();return f({mutationFn:r=>i(`/v1/budgets/${encodeURIComponent(r)}`,{method:"DELETE"}),onSuccess:()=>void e.invalidateQueries({queryKey:[_]})})}const U=1e3,tt=100;async function rt(){const e=[];for(let r=0;ri("/v1/users",{method:"POST",body:JSON.stringify(r)}),onSuccess:()=>X(e)})}function Sr(){const e=x();return f({mutationFn:({id:r,body:s})=>i(`/v1/users/${encodeURIComponent(r)}`,{method:"PATCH",body:JSON.stringify(s)}),onSuccess:()=>X(e)})}function kr(){const e=x();return f({mutationFn:r=>i(`/v1/users/${encodeURIComponent(r)}`,{method:"DELETE"}),onSuccess:()=>{X(e),e.invalidateQueries({queryKey:[T]})}})}function Z(e){const r=new URLSearchParams;return e.start_date&&r.set("start_date",e.start_date),e.end_date&&r.set("end_date",e.end_date),e.status&&r.set("status",e.status),e.model&&r.set("model",e.model),e.endpoint&&r.set("endpoint",e.endpoint),e.user_id&&r.set("user_id",e.user_id),r}function Pr(e,r,s){return v({queryKey:[Y,"list",e,r,s],queryFn:()=>{const a=Z(e);return a.set("skip",String(r*s)),a.set("limit",String(s)),i(`/v1/usage?${a.toString()}`)},placeholderData:Q,staleTime:1e4})}function Er(e){return v({queryKey:[Y,"count",e],queryFn:()=>i(`/v1/usage/count?${Z(e).toString()}`),placeholderData:Q,staleTime:1e4})}function Nr(e,r,s=!0){return v({queryKey:[Y,"summary",e,r],queryFn:()=>{const a=Z(e);return a.set("bucket",r),i(`/v1/usage/summary?${a.toString()}`)},enabled:s,placeholderData:Q,staleTime:3e4})}function Cr(e){return e==null?"0":new Intl.NumberFormat("en-US").format(e)}function Tr(e){if(e==null)return"$0.00";const r=e!==0&&Math.abs(e)<.01?4:2;return new Intl.NumberFormat("en-US",{style:"currency",currency:"USD",minimumFractionDigits:2,maximumFractionDigits:r}).format(e)}function _r(e){if(e==null)return"—";if(e>=1e6){const r=e/1e6;return`${Number.isInteger(r)?r:r.toFixed(1)}M`}if(e>=1e3){const r=Math.round(e/1e3);return r>=1e3?"1M":`${r}K`}return String(e)}const st=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];function Ar(e){if(!e)return"—";const r=/^(\d{4})-(\d{2})/.exec(e);if(!r)return e;const s=Number(r[2])-1;return s<0||s>11?r[1]:`${st[s]} ${r[1]}`}const nt=new Intl.NumberFormat("en-US",{style:"currency",currency:"USD",maximumFractionDigits:2});function Lr(e){return nt.format(e)}function Ir(e){return e>=1e6?`${(e/1e6).toFixed(1)}M`:e>=1e3?`${(e/1e3).toFixed(1)}k`:String(e)}function at(e){return`${(e*100).toFixed(1)}%`}function qr(e,r){return r===void 0||r===0?null:(e-r)/r}function Rr(e,r=Date.now()){if(!e)return"never";const s=new Date(e);if(Number.isNaN(s.getTime()))return e;const a=Math.round((r-s.getTime())/1e3),n=a<0,l=Math.abs(a),d=[["second",60],["minute",60],["hour",24],["day",30],["month",12],["year",Number.POSITIVE_INFINITY]];let u=l,y="second";for(const[p,g]of d){if(y=p,u0?"▲":e<0?"▼":"•";return t.jsxs("span",{className:"text-[var(--otari-muted)]",children:[r," ",at(Math.abs(e))," vs prev"]})}function it(e){return e instanceof E||e instanceof Error?e.message:"Something went wrong."}function ot({error:e}){return e?t.jsx("div",{role:"alert",className:"rounded-lg border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700",children:it(e)}):null}function lt({tone:e="info",children:r}){const s=e==="warning"?"border-amber-200 bg-amber-50 text-amber-800":"border-[var(--otari-brand)] bg-[var(--otari-brand-tint)] text-[var(--otari-brand-dark)]";return t.jsx("div",{className:`rounded-lg border px-4 py-3 text-sm ${s}`,children:r})}function Fr({title:e,description:r,action:s}){return t.jsxs("div",{className:"flex flex-col gap-3",children:[t.jsxs("div",{children:[t.jsx("h1",{className:"text-xl font-semibold text-[var(--otari-ink)]",children:e}),r?t.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:r}):null]}),s?t.jsx("div",{className:"flex flex-wrap gap-2",children:s}):null]})}function Mr({children:e,confirmLabel:r,onConfirm:s,isPending:a}){const[n,l]=o.useState(!1);return n?t.jsxs("span",{className:"inline-flex items-center gap-1",children:[t.jsx(P,{size:"sm",variant:"danger",isDisabled:a,onPress:s,children:r}),t.jsx(P,{size:"sm",variant:"ghost",isDisabled:a,onPress:()=>l(!1),children:"Cancel"})]}):t.jsx(P,{size:"sm",variant:"danger-soft",onPress:()=>l(!0),children:e})}const ct="rounded-lg border border-[var(--otari-line)] bg-[var(--otari-bg)] px-3 py-2 text-sm text-[var(--otari-ink)] focus:border-[var(--otari-brand)] focus:outline-none";function Kr({id:e,label:r,ariaLabel:s,value:a,onChange:n,options:l,children:d,disabled:u}){const y=o.useId(),h=e??(r?y:void 0),p=t.jsx("select",{id:h,"aria-label":r?void 0:s,value:a,disabled:u,onChange:g=>n(g.target.value),className:ct,children:l?l.map(g=>t.jsx("option",{value:g.value,children:g.label},g.value)):d});return r?t.jsxs("div",{className:"flex flex-col gap-1",children:[t.jsx("label",{htmlFor:h,className:"text-xs font-medium text-[var(--otari-muted)]",children:r}),p]}):p}function Ur({label:e,value:r,onChange:s,options:a,placeholder:n,maxVisible:l=50,allowsCustom:d=!1}){const u=m=>{var c;return((c=a.find(j=>j.value===m))==null?void 0:c.label)??m},[y,h]=o.useState(()=>u(r));o.useEffect(()=>{h(u(r))},[r]);const p=y.trim().toLowerCase(),g=a.filter(m=>!p||m.value.toLowerCase().includes(p)||m.label.toLowerCase().includes(p)).slice(0,l);return t.jsxs(I.Root,{allowsEmptyCollection:!0,allowsCustomValue:d,menuTrigger:"focus",inputValue:y,onInputChange:m=>{h(m),d?s(m.trim()):m.trim()===""&&s("")},onSelectionChange:m=>{m!=null&&s(String(m))},className:"flex flex-col gap-1",children:[t.jsx(oe,{className:"text-xs font-medium text-[var(--otari-muted)]",children:e}),t.jsxs(I.InputGroup,{children:[t.jsx(le,{placeholder:n,autoComplete:"off",onFocus:m=>m.currentTarget.select()}),t.jsx(I.Trigger,{})]}),t.jsx(I.Popover,{children:t.jsx(Te,{items:g,className:"max-h-72 overflow-auto",children:m=>t.jsx(_e,{id:m.value,textValue:m.label,children:m.label})})})]})}function ut(){var l;const e=He(),r=We(),[s,a]=o.useState(!1);return!(((l=e.data)==null?void 0:l.require_pricing)===!0&&e.data.default_pricing===!1)||s?null:t.jsx("div",{className:"shrink-0 px-6 pt-3",children:t.jsx(lt,{tone:"warning",children:t.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[t.jsxs("span",{children:["Requests are rejected until pricing is set (",t.jsx("code",{children:"require_pricing"})," is on). Enable default pricing to meter new models with public rates right away."]}),t.jsxs("span",{className:"flex items-center gap-2",children:[t.jsx(P,{size:"sm",variant:"primary",isDisabled:r.isPending,onPress:()=>r.mutate({default_pricing:!0}),children:r.isPending?"Enabling…":"Enable default pricing"}),t.jsx(P,{size:"sm",variant:"ghost",onPress:()=>a(!0),children:"Dismiss"})]})]})})})}function dt(){const{data:e}=Ve(),r=o.useRef(null);return e&&r.current===null&&(r.current=e.build),e!=null&&r.current!=null&&e.build!==r.current}function mt(){const e=dt(),[r,s]=o.useState(!1);return!e||r?null:t.jsx("div",{className:"pointer-events-none absolute inset-x-0 top-0 z-50 flex justify-center",children:t.jsxs("div",{role:"status",className:"pointer-events-auto mt-1.5 flex items-center gap-3 rounded-full border border-[var(--otari-brand)] bg-[var(--otari-brand-tint)] py-1.5 pr-1.5 pl-4 text-sm text-[var(--otari-brand-dark)] shadow-md",children:[t.jsxs("span",{children:[t.jsx("strong",{className:"font-semibold",children:"An update is available."})," Reloading keeps you signed in."]}),t.jsx(P,{size:"sm",variant:"primary",onPress:()=>window.location.reload(),children:"Update now"}),t.jsx(P,{size:"sm",variant:"ghost",onPress:()=>s(!0),children:"Later"})]})})}const he=200,xe=480,B=240,ft=60,ye="otari.dashboard.sidebarWidth",ve="otari.dashboard.sidebarCollapsed",ae=16,R=e=>Math.min(xe,Math.max(he,e));function ht(){if(typeof window>"u")return B;try{const e=window.localStorage.getItem(ye),r=e?Number.parseInt(e,10):Number.NaN;return Number.isNaN(r)?B:R(r)}catch{return B}}function xt(){if(typeof window>"u")return!1;try{return window.localStorage.getItem(ve)==="1"}catch{return!1}}const yt=[{key:"home"},{key:"observability",label:"Observability"},{key:"catalog",label:"Catalog"},{key:"access",label:"Access"},{key:"system"}],vt=[{to:"/",section:"home",label:"Overview",end:!0,icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("rect",{x:"3.5",y:"3.5",width:"7",height:"7",rx:"1.5",strokeLinejoin:"round"}),t.jsx("rect",{x:"13.5",y:"3.5",width:"7",height:"7",rx:"1.5",strokeLinejoin:"round"}),t.jsx("rect",{x:"3.5",y:"13.5",width:"7",height:"7",rx:"1.5",strokeLinejoin:"round"}),t.jsx("rect",{x:"13.5",y:"13.5",width:"7",height:"7",rx:"1.5",strokeLinejoin:"round"})]})},{to:"/activity",section:"observability",label:"Activity",icon:t.jsx("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:t.jsx("path",{d:"M3 12h4l2.5-6 4 12 2.5-6H21",strokeLinecap:"round",strokeLinejoin:"round"})})},{to:"/usage",section:"observability",label:"Usage",icon:t.jsx("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:t.jsx("path",{d:"M4 20V10M10 20V4M16 20v-7M22 20H2",strokeLinecap:"round",strokeLinejoin:"round"})})},{to:"/providers",section:"catalog",label:"Providers",icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("rect",{x:"3.5",y:"4.5",width:"17",height:"6",rx:"1.5",strokeLinejoin:"round"}),t.jsx("rect",{x:"3.5",y:"13.5",width:"17",height:"6",rx:"1.5",strokeLinejoin:"round"}),t.jsx("path",{d:"M7 7.5h.01M7 16.5h.01",strokeLinecap:"round",strokeLinejoin:"round"})]})},{to:"/users",section:"access",label:"Users",icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("circle",{cx:"9",cy:"8",r:"3.2",strokeLinejoin:"round"}),t.jsx("path",{d:"M3.5 19a5.5 5.5 0 0 1 11 0",strokeLinecap:"round",strokeLinejoin:"round"}),t.jsx("path",{d:"M16 5.2a3.2 3.2 0 0 1 0 5.6M17.5 19a5.5 5.5 0 0 0-3-4.9",strokeLinecap:"round",strokeLinejoin:"round"})]})},{to:"/keys",section:"access",label:"API keys",icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("circle",{cx:"7.5",cy:"15.5",r:"3.5"}),t.jsx("path",{d:"M10 13l7-7M14 5l3 3M16.5 7.5l2-2",strokeLinecap:"round",strokeLinejoin:"round"})]})},{to:"/budgets",section:"access",label:"Budgets",icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("path",{d:"M3 7.5A1.5 1.5 0 0 1 4.5 6H18a1.5 1.5 0 0 1 1.5 1.5V9",strokeLinejoin:"round"}),t.jsx("rect",{x:"3",y:"7.5",width:"18",height:"12",rx:"1.5",strokeLinejoin:"round"}),t.jsx("path",{d:"M16 13.5h.01",strokeLinecap:"round",strokeLinejoin:"round"}),t.jsx("path",{d:"M21 12v3h-3.5a1.5 1.5 0 0 1 0-3H21z",strokeLinejoin:"round"})]})},{to:"/models",section:"catalog",label:"Models",icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("path",{d:"M12 3l8 4.5v9L12 21l-8-4.5v-9L12 3z",strokeLinejoin:"round"}),t.jsx("path",{d:"M12 12l8-4.5M12 12v9M12 12L4 7.5",strokeLinejoin:"round"})]})},{to:"/aliases",section:"catalog",label:"Aliases",icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("path",{d:"M20.6 13.4L13.4 20.6a2 2 0 0 1-2.8 0l-7-7A2 2 0 0 1 3 12.2V5a2 2 0 0 1 2-2h7.2a2 2 0 0 1 1.4.6l7 7a2 2 0 0 1 0 2.8z",strokeLinejoin:"round"}),t.jsx("circle",{cx:"7.5",cy:"7.5",r:"1.5"})]})},{to:"/tools",section:"system",label:"Tools & Guardrails",icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("path",{d:"M14.7 6.3a4 4 0 0 1 5 5l-8.4 8.4a2 2 0 0 1-2.8 0l-2.2-2.2a2 2 0 0 1 0-2.8z",strokeLinejoin:"round"}),t.jsx("path",{d:"M12 9 5 16",strokeLinecap:"round"})]})},{to:"/settings",section:"system",label:"Settings",icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("circle",{cx:"12",cy:"12",r:"3"}),t.jsx("path",{d:"M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z",strokeLinejoin:"round"})]})}];function gt(){const{logout:e}=V(),r=o.useRef(null),[s,a]=o.useState(ht),[n,l]=o.useState(xt),[d,u]=o.useState(!1);o.useEffect(()=>{const c=window.setTimeout(()=>{try{window.localStorage.setItem(ye,String(Math.round(s)))}catch{}},200);return()=>window.clearTimeout(c)},[s]),o.useEffect(()=>{try{window.localStorage.setItem(ve,n?"1":"0")}catch{}},[n]);const y=o.useCallback(c=>{c.preventDefault(),c.currentTarget.setPointerCapture(c.pointerId),u(!0)},[]),h=o.useCallback(c=>{var A;if(!c.currentTarget.hasPointerCapture(c.pointerId))return;const j=((A=r.current)==null?void 0:A.getBoundingClientRect().left)??0;a(R(c.clientX-j))},[]),p=o.useCallback(c=>{c.currentTarget.hasPointerCapture(c.pointerId)&&c.currentTarget.releasePointerCapture(c.pointerId),u(!1)},[]),g=o.useCallback(c=>{c.key==="ArrowLeft"?(c.preventDefault(),a(j=>R(j-ae))):c.key==="ArrowRight"&&(c.preventDefault(),a(j=>R(j+ae)))},[]),m=n?ft:s;return t.jsxs("div",{className:C("relative flex h-full flex-col overflow-hidden",d&&"cursor-col-resize select-none"),children:[t.jsxs("header",{className:"flex shrink-0 items-center justify-between border-b border-[var(--otari-line)] bg-[var(--otari-surface)] px-5 py-3",children:[t.jsxs("div",{className:"flex items-center gap-2.5",children:[t.jsx("img",{src:"/favicon.svg",alt:"",className:"h-7 w-7 shrink-0"}),t.jsx("span",{className:"text-base font-semibold text-[var(--otari-ink)]",children:"Otari"})]}),t.jsx(P,{size:"sm",variant:"outline",onPress:e,"aria-label":"Sign out",children:"Sign out"})]}),t.jsx(mt,{}),t.jsx(Be,{}),t.jsx(ut,{}),t.jsxs("div",{className:"flex min-h-0 flex-1",children:[t.jsxs("aside",{ref:r,style:{width:m},className:C("relative flex shrink-0 flex-col border-r border-[var(--otari-line)] bg-[var(--otari-surface)]",!d&&"transition-[width] duration-150"),children:[t.jsx("button",{type:"button",onClick:()=>l(c=>!c),"aria-label":n?"Expand sidebar":"Collapse sidebar","aria-pressed":n,title:n?"Expand sidebar":"Collapse sidebar",className:"absolute -right-3 top-4 z-30 flex h-6 w-6 items-center justify-center rounded-full border border-[var(--otari-line)] bg-[var(--otari-surface)] text-[var(--otari-muted)] shadow-sm transition-colors hover:border-[var(--otari-brand)] hover:text-[var(--otari-brand-dark)]",children:t.jsx("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",className:C("h-3.5 w-3.5 transition-transform",n&&"rotate-180"),children:t.jsx("path",{d:"M15 6l-6 6 6 6",strokeLinecap:"round",strokeLinejoin:"round"})})}),t.jsx("nav",{className:C("flex flex-col py-4",n?"px-2":"px-3"),children:yt.map((c,j)=>{const A=vt.filter(k=>k.section===c.key);return A.length===0?null:t.jsxs("div",{className:j>0?"mt-4":void 0,children:[!n&&c.label?t.jsx("div",{className:"px-3 pb-1 text-[11px] font-semibold tracking-wider text-[var(--otari-muted)] uppercase",children:c.label}):null,j>0&&(n||!c.label)?t.jsx("div",{className:"mx-1 mb-2 border-t border-[var(--otari-line)]"}):null,t.jsx("div",{className:"flex flex-col gap-1",children:A.map(k=>t.jsxs(ie,{to:k.to,end:k.end,"aria-label":n?k.label:void 0,title:n?k.label:void 0,className:({isActive:pe})=>C("flex items-center rounded-lg py-2 text-sm font-medium transition-colors",n?"justify-center px-0":"gap-3 px-3",pe?"bg-[var(--otari-brand-tint)] text-[var(--otari-brand-dark)]":"text-[var(--otari-muted)] hover:bg-[var(--otari-bg)] hover:text-[var(--otari-ink)]"),children:[k.icon,n?null:k.label]},k.to))})]},c.key)})}),t.jsxs("a",{href:"https://otari.ai",target:"_blank",rel:"noreferrer",title:"otari.ai — the hosted Otari gateway",className:C("mt-auto mb-3 flex items-center rounded-lg py-2 text-xs font-medium text-[var(--otari-muted)] transition-colors hover:bg-[var(--otari-bg)] hover:text-[var(--otari-brand-dark)]",n?"mx-2 justify-center px-0":"mx-3 gap-2 px-3"),children:[t.jsx("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-4 w-4 shrink-0",children:t.jsx("path",{d:"M18 10h-1.26A8 8 0 1 0 9 20h9a5 5 0 0 0 0-10z",strokeLinejoin:"round"})}),n?null:t.jsxs("span",{className:"flex-1",children:["otari.ai ",t.jsx("span",{"aria-hidden":!0,children:"↗"})]})]}),n?null:t.jsx("div",{role:"separator","aria-orientation":"vertical","aria-label":"Resize sidebar","aria-valuenow":Math.round(s),"aria-valuemin":he,"aria-valuemax":xe,tabIndex:0,onPointerDown:y,onPointerMove:h,onPointerUp:p,onKeyDown:g,className:C("absolute top-0 right-0 z-10 h-full w-1.5 cursor-col-resize touch-none transition-colors","hover:bg-[var(--otari-brand)] focus-visible:bg-[var(--otari-brand)] focus:outline-none",d?"bg-[var(--otari-brand)]":"bg-transparent")})]}),t.jsx("main",{className:"flex-1 overflow-y-auto",children:t.jsx("div",{className:"mx-auto flex max-w-[1800px] flex-col gap-6 px-6 py-6",children:t.jsx(Pe,{})})})]})]})}function pt(){const{login:e}=V(),[r,s]=o.useState(""),[a,n]=o.useState(null),[l,d]=o.useState(!1),u=async()=>{const y=r.trim();if(!(!y||l)){d(!0),n(null);try{await Oe(y)?e():n(new Error("Invalid master key."))}catch(h){n(h)}finally{d(!1)}}};return t.jsx("div",{className:"flex min-h-full items-center justify-center p-6",children:t.jsx(L,{className:"w-full max-w-md",children:t.jsxs(L.Content,{className:"flex flex-col gap-5 p-7",children:[t.jsxs("div",{className:"flex flex-col items-center gap-3 text-center",children:[t.jsx("img",{src:"/favicon.svg",alt:"Otari",className:"h-12 w-12"}),t.jsxs("div",{children:[t.jsx("h1",{className:"text-lg font-semibold text-[var(--otari-ink)]",children:"Otari Dashboard"}),t.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:"Sign in with your master key to browse models, set pricing, and manage settings."})]})]}),t.jsxs("form",{className:"flex flex-col gap-4",onSubmit:y=>{y.preventDefault(),u()},children:[t.jsxs(Ae,{value:r,onChange:y=>{s(y),a&&n(null)},type:"password",isRequired:!0,className:"flex flex-col gap-1",children:[t.jsx(oe,{className:"text-sm font-medium text-[var(--otari-ink)]",children:"Master key"}),t.jsx(le,{placeholder:"otari-mk-… or your master key",autoFocus:!0,autoComplete:"off"})]}),t.jsxs("details",{className:"text-xs text-[var(--otari-muted)]",children:[t.jsx("summary",{className:"cursor-pointer font-medium text-[var(--otari-brand-dark)]",children:"First run? Where to find your key"}),t.jsxs("p",{className:"mt-2 leading-relaxed",children:["If you did not set ",t.jsx("code",{children:"OTARI_MASTER_KEY"}),", Otari generated one and printed it to the server logs on startup. Look for the line ",t.jsx("code",{children:"Your master key:"})," (for example, run"," ",t.jsx("code",{children:"docker logs "}),") and paste it above."]})]}),t.jsx(ot,{error:a}),t.jsx(P,{type:"submit",variant:"primary",fullWidth:!0,isDisabled:!r.trim()||l,children:l?"Signing in…":"Sign in"})]}),t.jsx("p",{className:"text-center text-xs text-[var(--otari-muted)]",children:"The key is sent once to this gateway and exchanged for a session cookie; it is never stored in the browser."}),t.jsx("div",{className:"border-t border-[var(--otari-line)] pt-4 text-center",children:t.jsx(Le,{href:"/welcome",className:"text-sm font-medium text-[var(--otari-brand-dark)]",children:"New to Otari? Open the welcome guide"})})]})})})}const bt=o.lazy(async()=>({default:(await S(async()=>{const{ActivityPage:e}=await import("./ActivityPage-Cw34Jlno.js");return{ActivityPage:e}},__vite__mapDeps([0,1,2,3,4]))).ActivityPage})),jt=o.lazy(async()=>({default:(await S(async()=>{const{AliasesPage:e}=await import("./AliasesPage-CCRTl9Co.js");return{AliasesPage:e}},__vite__mapDeps([5,1,2,6,4,3]))).AliasesPage})),wt=o.lazy(async()=>({default:(await S(async()=>{const{BudgetsPage:e}=await import("./BudgetsPage-iAjnK5BF.js");return{BudgetsPage:e}},__vite__mapDeps([7,1,2,6,4,3]))).BudgetsPage})),St=o.lazy(async()=>({default:(await S(async()=>{const{KeysPage:e}=await import("./KeysPage-C6eaoTUP.js");return{KeysPage:e}},__vite__mapDeps([8,1,2,6,4,9,3]))).KeysPage})),kt=o.lazy(async()=>({default:(await S(async()=>{const{ModelsPage:e}=await import("./ModelsPage-DwBDAaxV.js");return{ModelsPage:e}},__vite__mapDeps([10,1,2,3,4]))).ModelsPage})),Pt=o.lazy(async()=>({default:(await S(async()=>{const{OverviewIndex:e}=await import("./OverviewPage-B_g2blUc.js");return{OverviewIndex:e}},__vite__mapDeps([11,1,2,12,13,4,3]))).OverviewIndex})),Et=o.lazy(async()=>({default:(await S(async()=>{const{ProvidersPage:e}=await import("./ProvidersPage-DhHL_fxe.js");return{ProvidersPage:e}},__vite__mapDeps([14,1,2,6,4,3]))).ProvidersPage})),Nt=o.lazy(async()=>({default:(await S(async()=>{const{SettingsPage:e}=await import("./SettingsPage-BPWZBXQE.js");return{SettingsPage:e}},__vite__mapDeps([15,1,2,4]))).SettingsPage})),Ct=o.lazy(async()=>({default:(await S(async()=>{const{ToolsGuardrailsPage:e}=await import("./ToolsGuardrailsPage-Zh-JPOxJ.js");return{ToolsGuardrailsPage:e}},__vite__mapDeps([16,1,2,4]))).ToolsGuardrailsPage})),Tt=o.lazy(async()=>({default:(await S(async()=>{const{UsagePage:e}=await import("./UsagePage-Dk-t74Uz.js");return{UsagePage:e}},__vite__mapDeps([17,1,2,12,13,4,3]))).UsagePage})),_t=o.lazy(async()=>({default:(await S(async()=>{const{UsersPage:e}=await import("./UsersPage-D6v_0kF6.js");return{UsersPage:e}},__vite__mapDeps([18,1,2,6,4,9,3]))).UsersPage}));function w(e){return t.jsx(o.Suspense,{fallback:t.jsx("div",{role:"status",children:"Loading page…"}),children:e})}function At(){const{isAuthenticated:e}=V();return e?t.jsx(Ee,{children:t.jsx(Ne,{children:t.jsxs(b,{element:t.jsx(gt,{}),children:[t.jsx(b,{index:!0,element:w(t.jsx(Pt,{}))}),t.jsx(b,{path:"providers",element:w(t.jsx(Et,{}))}),t.jsx(b,{path:"keys",element:w(t.jsx(St,{}))}),t.jsx(b,{path:"users",element:w(t.jsx(_t,{}))}),t.jsx(b,{path:"budgets",element:w(t.jsx(wt,{}))}),t.jsx(b,{path:"activity",element:w(t.jsx(bt,{}))}),t.jsx(b,{path:"usage",element:w(t.jsx(Tt,{}))}),t.jsx(b,{path:"models",element:w(t.jsx(kt,{}))}),t.jsx(b,{path:"aliases",element:w(t.jsx(jt,{}))}),t.jsx(b,{path:"tools",element:w(t.jsx(Ct,{}))}),t.jsx(b,{path:"settings",element:w(t.jsx(Nt,{}))}),t.jsx(b,{path:"*",element:t.jsx(Ce,{to:"/",replace:!0})})]})})}):t.jsx(pt,{})}function Lt({children:e}){const[r]=o.useState(()=>new we({defaultOptions:{queries:{refetchOnWindowFocus:!1,retry:(s,a)=>a instanceof E&&(a.status===401||a.status===403)?!1:s<2}}}));return t.jsx(Se,{client:r,children:t.jsx(Me,{children:e})})}const ge=document.getElementById("root");if(!ge)throw new Error("Root element #root not found");Ie.createRoot(ge).render(t.jsx(o.StrictMode,{children:t.jsx(Lt,{children:t.jsx(At,{})})}));export{Jt as $,Ar as A,He as B,Mr as C,Tr as D,ot as E,Kr as F,ir as G,or as H,lt as I,Mt as J,Bt as K,qr as L,Lr as M,Dr as N,at as O,Fr as P,Rr as Q,zt as R,Or as S,Ht as T,Gt as U,We as V,Vt as W,$t as X,Qt as Y,Ut as Z,Kt as _,Pr as a,lr as a0,cr as a1,ur as a2,tr as a3,Wt as a4,rr as a5,sr as a6,nr as a7,Ir as a8,kr as a9,wr as aa,Er as b,Nr as c,Ur as d,Ft as e,Xt as f,er as g,it as h,Zt as i,yr as j,gr as k,pr as l,br as m,Sr as n,vr as o,dr as p,fr as q,hr as r,xr as s,mr as t,jr as u,Dt as v,ar as w,Yt as x,_r as y,Cr as z}; +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/ActivityPage-BrL4O-hT.js","assets/tanstack-query-1t81HyiD.js","assets/react-dgEcD0HR.js","assets/Table-CLdjdyTx.js","assets/heroui-BX6JwHY-.js","assets/AliasesPage-RDVKM-by.js","assets/Field-HzRk1KDP.js","assets/BudgetsPage-Ctwj8twD.js","assets/KeysPage-DCo4FFYU.js","assets/ModelScopeControl-DiX2Etqz.js","assets/ModelsPage-C028BOtV.js","assets/OverviewPage-KThfhw1Z.js","assets/charts-Cr3Dij9t.js","assets/recharts-CR3TAEof.js","assets/ProvidersPage-BEN5bHZD.js","assets/SettingsPage-hENBFRMI.js","assets/ToolsGuardrailsPage-DWSik0Ga.js","assets/UsagePage-B95PT-hq.js","assets/UsersPage-D5CmT8Bq.js"])))=>i.map(i=>d[i]); +var be=Object.defineProperty;var je=(e,r,s)=>r in e?be(e,r,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[r]=s;var ee=(e,r,s)=>je(e,typeof r!="symbol"?r+"":r,s);import{u as x,j as t,a as v,b as f,k as Q,Q as we,c as Se}from"./tanstack-query-1t81HyiD.js";import{d as ke,r as o,N as ie,O as Pe,H as Ee,e as Ne,f as b,h as Ce}from"./react-dgEcD0HR.js";import{C as I,L as oe,I as le,a as Te,b as _e,B as P,d as L,c as C,T as Ae,e as Le}from"./heroui-BX6JwHY-.js";(function(){const r=document.createElement("link").relList;if(r&&r.supports&&r.supports("modulepreload"))return;for(const n of document.querySelectorAll('link[rel="modulepreload"]'))a(n);new MutationObserver(n=>{for(const l of n)if(l.type==="childList")for(const d of l.addedNodes)d.tagName==="LINK"&&d.rel==="modulepreload"&&a(d)}).observe(document,{childList:!0,subtree:!0});function s(n){const l={};return n.integrity&&(l.integrity=n.integrity),n.referrerPolicy&&(l.referrerPolicy=n.referrerPolicy),n.crossOrigin==="use-credentials"?l.credentials="include":n.crossOrigin==="anonymous"?l.credentials="omit":l.credentials="same-origin",l}function a(n){if(n.ep)return;n.ep=!0;const l=s(n);fetch(n.href,l)}})();var Ie=ke();const qe="modulepreload",Re=function(e){return"/"+e},te={},S=function(r,s,a){let n=Promise.resolve();if(s&&s.length>0){let d=function(h){return Promise.all(h.map(p=>Promise.resolve(p).then(g=>({status:"fulfilled",value:g}),g=>({status:"rejected",reason:g}))))};document.getElementsByTagName("link");const u=document.querySelector("meta[property=csp-nonce]"),y=(u==null?void 0:u.nonce)||(u==null?void 0:u.getAttribute("nonce"));n=d(s.map(h=>{if(h=Re(h),h in te)return;te[h]=!0;const p=h.endsWith(".css"),g=p?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${h}"]${g}`))return;const m=document.createElement("link");if(m.rel=p?"stylesheet":qe,p||(m.as="script"),m.crossOrigin="",m.href=h,y&&m.setAttribute("nonce",y),document.head.appendChild(m),p)return new Promise((c,j)=>{m.addEventListener("load",c),m.addEventListener("error",()=>j(new Error(`Unable to preload CSS for ${h}`)))})}))}function l(d){const u=new Event("vite:preloadError",{cancelable:!0});if(u.payload=d,window.dispatchEvent(u),!u.defaultPrevented)throw d}return n.then(d=>{for(const u of d||[])u.status==="rejected"&&l(u.reason);return r().catch(l)})};class E extends Error{constructor(s,a){super(a);ee(this,"status");this.name="ApiError",this.status=s}}let q=null;function re(e){q=e}async function $(e){try{const r=await e.json();if(typeof r.detail=="string")return r.detail;if(r.detail!=null)return JSON.stringify(r.detail)}catch{}return e.statusText||`Request failed (${e.status})`}async function Oe(e){let r;try{r=await fetch("/v1/auth/session",{method:"POST",headers:{Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify({master_key:e})})}catch{throw new E(0,"Network error: could not reach the gateway.")}if(r.status===401||r.status===403)return!1;if(!r.ok)throw new E(r.status,await $(r));return!0}async function De(){try{await fetch("/v1/auth/session",{method:"DELETE"})}catch{}}async function i(e,r={}){const s=new Headers(r.headers);s.set("Accept","application/json"),r.body!=null&&!s.has("Content-Type")&&s.set("Content-Type","application/json");let a;try{a=await fetch(e,{...r,headers:s})}catch{throw new E(0,"Network error: could not reach the gateway.")}if(a.status===401||a.status===403)throw q==null||q(),new E(a.status,await $(a));if(!a.ok)throw new E(a.status,await $(a));if(a.status!==204)return await a.json()}const z="otari.dashboard.hasSession",ce=o.createContext(null);function Fe(){try{return window.localStorage.getItem(z)==="1"}catch{return!1}}function Me({children:e}){const r=x(),[s,a]=o.useState(Fe),n=o.useCallback(()=>{De(),a(!1),r.clear();try{window.localStorage.removeItem(z)}catch{}},[r]),l=o.useCallback(()=>{r.clear(),a(!0);try{window.localStorage.setItem(z,"1")}catch{}},[r]);o.useEffect(()=>(re(n),()=>re(null)),[n]);const d=o.useMemo(()=>({isAuthenticated:s,login:l,logout:n}),[s,l,n]);return t.jsx(ce.Provider,{value:d,children:e})}function V(){const e=o.useContext(ce);if(!e)throw new Error("useAuth must be used within an AuthProvider");return e}function Ke(e){return e instanceof E&&e.status===0}function Ue(){const e=x(),[r,s]=o.useState(!1);return o.useEffect(()=>{const a=e.getQueryCache(),n=()=>a.getAll().some(l=>l.state.status==="error"&&Ke(l.state.error));return s(n()),a.subscribe(()=>s(n()))},[e]),r}function Be(){return Ue()?t.jsxs("div",{role:"alert","aria-live":"assertive",className:"fixed right-4 bottom-4 z-50 flex max-w-sm items-start gap-2.5 rounded-lg border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700 shadow-lg",children:[t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2","aria-hidden":!0,className:"mt-0.5 h-5 w-5 shrink-0",children:[t.jsx("path",{d:"M12 9v4M12 17h.01",strokeLinecap:"round",strokeLinejoin:"round"}),t.jsx("path",{d:"M10.3 3.9 1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0z",strokeLinejoin:"round"})]}),t.jsxs("span",{children:[t.jsx("strong",{className:"font-semibold",children:"Can’t reach the gateway."})," The backend isn’t responding; data won’t load or save until the connection is restored."]})]}):null}const N="models",O="pricing",ue="settings",de="tool-settings",H="aliases",W="discoverable",G="providers",J="provider-health",me="stored-providers",$e="model-metadata",ze="build",T="keys",_="budgets",fe="users",Y="usage",Qe=6e4,se=60*6e4;function Dt(){return v({queryKey:[N],queryFn:()=>i("/v1/models"),staleTime:6e4})}function Ve(){return v({queryKey:[ze],queryFn:()=>i("/dashboard-build.json"),refetchInterval:Qe,refetchOnWindowFocus:!0,staleTime:0,retry:!1})}function Ft(){return v({queryKey:[W],queryFn:()=>i("/v1/models/discoverable"),staleTime:5*6e4})}function Mt(){return v({queryKey:[G],queryFn:()=>i("/v1/providers"),staleTime:5*6e4})}function Kt(){return v({queryKey:["provider-catalog"],queryFn:()=>i("/v1/providers/catalog"),staleTime:1/0})}function Ut(e){return v({queryKey:["provider-catalog",e],queryFn:()=>i(`/v1/providers/catalog/${encodeURIComponent(e)}`),enabled:e!=="",staleTime:1/0})}function Bt(){return v({queryKey:[J],queryFn:()=>i("/v1/providers/health"),staleTime:se,refetchInterval:se})}function $t(){const e=x();return f({mutationFn:()=>i("/v1/providers/health?refresh=true"),onSuccess:r=>e.setQueryData([J],r)})}function zt(){return v({queryKey:[me],queryFn:()=>i("/v1/provider-credentials"),staleTime:6e4})}function D(e){e.invalidateQueries({queryKey:[me]}),e.invalidateQueries({queryKey:[G]}),e.invalidateQueries({queryKey:[N]}),e.invalidateQueries({queryKey:[W]}),e.invalidateQueries({queryKey:[J]})}function Qt(){const e=x();return f({mutationFn:r=>i("/v1/provider-credentials",{method:"POST",body:JSON.stringify(r)}),onSuccess:()=>D(e)})}function Vt(){const e=x();return f({mutationFn:({instance:r,body:s})=>i(`/v1/provider-credentials/${encodeURIComponent(r)}`,{method:"PATCH",body:JSON.stringify(s)}),onSuccess:()=>D(e)})}function Ht(){const e=x();return f({mutationFn:r=>i(`/v1/provider-credentials/${encodeURIComponent(r)}`,{method:"DELETE"}),onSuccess:()=>D(e)})}function Wt(){const e=x();return f({mutationFn:()=>i("/v1/provider-credentials/reencrypt",{method:"POST"}),onSuccess:()=>D(e)})}function Gt(){return f({mutationFn:e=>i(`/v1/provider-credentials/${encodeURIComponent(e)}/test`,{method:"POST"})})}function Jt(){return f({mutationFn:e=>i("/v1/provider-credentials/test",{method:"POST",body:JSON.stringify(e)})})}function Yt(){return v({queryKey:[$e],queryFn:()=>i("/v1/models/metadata"),staleTime:10*6e4})}function Xt(){return v({queryKey:[H],queryFn:()=>i("/v1/aliases"),staleTime:6e4})}function Zt(){const e=x();return f({mutationFn:r=>i("/v1/aliases",{method:"POST",body:JSON.stringify(r)}),onSuccess:()=>{e.invalidateQueries({queryKey:[H]}),e.invalidateQueries({queryKey:[N]})}})}function er(){const e=x();return f({mutationFn:r=>i(`/v1/aliases/${encodeURIComponent(r)}`,{method:"DELETE"}),onSuccess:()=>{e.invalidateQueries({queryKey:[H]}),e.invalidateQueries({queryKey:[N]})}})}function He(){return v({queryKey:[ue],queryFn:()=>i("/v1/settings"),staleTime:6e4})}function We(){const e=x();return f({mutationFn:r=>i("/v1/settings",{method:"PATCH",body:JSON.stringify(r)}),onSuccess:r=>{e.setQueryData([ue],r),e.invalidateQueries({queryKey:[N]}),e.invalidateQueries({queryKey:[W]})}})}function tr(){return f({mutationFn:()=>i("/v1/settings/master-key/rotate",{method:"POST"})})}function rr(){return v({queryKey:[de],queryFn:()=>i("/v1/tool-settings"),staleTime:6e4})}function sr(){const e=x();return f({mutationFn:r=>i("/v1/tool-settings",{method:"PATCH",body:JSON.stringify(r)}),onSuccess:r=>{e.setQueryData([de],r)}})}function nr(){return f({mutationFn:({service:e,url:r})=>i(`/v1/tool-settings/${encodeURIComponent(e)}/test`,{method:"POST",body:JSON.stringify({url:r})})})}const F=1e3,Ge=100;async function Je(){const e=[];for(let r=0;ri("/v1/pricing",{method:"POST",body:JSON.stringify(r)}),onSuccess:()=>{e.invalidateQueries({queryKey:[O]}),e.invalidateQueries({queryKey:[N]})}})}function or(){const e=x();return f({mutationFn:r=>i(`/v1/pricing/${encodeURIComponent(r)}`,{method:"DELETE"}),onSuccess:()=>{e.invalidateQueries({queryKey:[O]}),e.invalidateQueries({queryKey:[N]})}})}function lr(){return f({mutationFn:()=>i("/v1/pricing/refresh",{method:"POST"})})}function cr(){const e=x();return f({mutationFn:()=>i("/v1/pricing/refresh/confirm",{method:"POST"}),onSuccess:()=>{e.invalidateQueries({queryKey:[O]}),e.invalidateQueries({queryKey:[N]}),e.invalidateQueries({queryKey:[G]})}})}function ur(){return f({mutationFn:()=>i("/v1/pricing/refresh/reject",{method:"POST"})})}const M=1e3,Ye=100;async function Xe(){const e=[];for(let r=0;ri("/v1/keys",{method:"POST",body:JSON.stringify(r)}),onSuccess:()=>void e.invalidateQueries({queryKey:[T]})})}function fr(){const e=x();return f({mutationFn:({id:r,body:s})=>i(`/v1/keys/${encodeURIComponent(r)}`,{method:"PATCH",body:JSON.stringify(s)}),onSuccess:()=>void e.invalidateQueries({queryKey:[T]})})}function hr(){const e=x();return f({mutationFn:r=>i(`/v1/keys/${encodeURIComponent(r)}/rotate`,{method:"POST"}),onSuccess:()=>void e.invalidateQueries({queryKey:[T]})})}function xr(){const e=x();return f({mutationFn:r=>i(`/v1/keys/${encodeURIComponent(r)}`,{method:"DELETE"}),onSuccess:()=>void e.invalidateQueries({queryKey:[T]})})}const K=1e3,Ze=100;async function et(){const e=[];for(let r=0;ri(`/v1/budgets/${encodeURIComponent(e)}/reset-logs`),enabled:e!==null,staleTime:6e4})}function gr(){const e=x();return f({mutationFn:r=>i("/v1/budgets",{method:"POST",body:JSON.stringify(r)}),onSuccess:()=>void e.invalidateQueries({queryKey:[_]})})}function pr(){const e=x();return f({mutationFn:({id:r,body:s})=>i(`/v1/budgets/${encodeURIComponent(r)}`,{method:"PATCH",body:JSON.stringify(s)}),onSuccess:()=>void e.invalidateQueries({queryKey:[_]})})}function br(){const e=x();return f({mutationFn:r=>i(`/v1/budgets/${encodeURIComponent(r)}`,{method:"DELETE"}),onSuccess:()=>void e.invalidateQueries({queryKey:[_]})})}const U=1e3,tt=100;async function rt(){const e=[];for(let r=0;ri("/v1/users",{method:"POST",body:JSON.stringify(r)}),onSuccess:()=>X(e)})}function Sr(){const e=x();return f({mutationFn:({id:r,body:s})=>i(`/v1/users/${encodeURIComponent(r)}`,{method:"PATCH",body:JSON.stringify(s)}),onSuccess:()=>X(e)})}function kr(){const e=x();return f({mutationFn:r=>i(`/v1/users/${encodeURIComponent(r)}`,{method:"DELETE"}),onSuccess:()=>{X(e),e.invalidateQueries({queryKey:[T]})}})}function Z(e){const r=new URLSearchParams;return e.start_date&&r.set("start_date",e.start_date),e.end_date&&r.set("end_date",e.end_date),e.status&&r.set("status",e.status),e.model&&r.set("model",e.model),e.endpoint&&r.set("endpoint",e.endpoint),e.user_id&&r.set("user_id",e.user_id),r}function Pr(e,r,s){return v({queryKey:[Y,"list",e,r,s],queryFn:()=>{const a=Z(e);return a.set("skip",String(r*s)),a.set("limit",String(s)),i(`/v1/usage?${a.toString()}`)},placeholderData:Q,staleTime:1e4})}function Er(e){return v({queryKey:[Y,"count",e],queryFn:()=>i(`/v1/usage/count?${Z(e).toString()}`),placeholderData:Q,staleTime:1e4})}function Nr(e,r,s=!0){return v({queryKey:[Y,"summary",e,r],queryFn:()=>{const a=Z(e);return a.set("bucket",r),i(`/v1/usage/summary?${a.toString()}`)},enabled:s,placeholderData:Q,staleTime:3e4})}function Cr(e){return e==null?"0":new Intl.NumberFormat("en-US").format(e)}function Tr(e){if(e==null)return"$0.00";const r=e!==0&&Math.abs(e)<.01?4:2;return new Intl.NumberFormat("en-US",{style:"currency",currency:"USD",minimumFractionDigits:2,maximumFractionDigits:r}).format(e)}function _r(e){if(e==null)return"—";if(e>=1e6){const r=e/1e6;return`${Number.isInteger(r)?r:r.toFixed(1)}M`}if(e>=1e3){const r=Math.round(e/1e3);return r>=1e3?"1M":`${r}K`}return String(e)}const st=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];function Ar(e){if(!e)return"—";const r=/^(\d{4})-(\d{2})/.exec(e);if(!r)return e;const s=Number(r[2])-1;return s<0||s>11?r[1]:`${st[s]} ${r[1]}`}const nt=new Intl.NumberFormat("en-US",{style:"currency",currency:"USD",maximumFractionDigits:2});function Lr(e){return nt.format(e)}function Ir(e){return e>=1e6?`${(e/1e6).toFixed(1)}M`:e>=1e3?`${(e/1e3).toFixed(1)}k`:String(e)}function at(e){return`${(e*100).toFixed(1)}%`}function qr(e,r){return r===void 0||r===0?null:(e-r)/r}function Rr(e,r=Date.now()){if(!e)return"never";const s=new Date(e);if(Number.isNaN(s.getTime()))return e;const a=Math.round((r-s.getTime())/1e3),n=a<0,l=Math.abs(a),d=[["second",60],["minute",60],["hour",24],["day",30],["month",12],["year",Number.POSITIVE_INFINITY]];let u=l,y="second";for(const[p,g]of d){if(y=p,u0?"▲":e<0?"▼":"•";return t.jsxs("span",{className:"text-[var(--otari-muted)]",children:[r," ",at(Math.abs(e))," vs prev"]})}function it(e){return e instanceof E||e instanceof Error?e.message:"Something went wrong."}function ot({error:e}){return e?t.jsx("div",{role:"alert",className:"rounded-lg border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700",children:it(e)}):null}function lt({tone:e="info",children:r}){const s=e==="warning"?"border-amber-200 bg-amber-50 text-amber-800":"border-[var(--otari-brand)] bg-[var(--otari-brand-tint)] text-[var(--otari-brand-dark)]";return t.jsx("div",{className:`rounded-lg border px-4 py-3 text-sm ${s}`,children:r})}function Fr({title:e,description:r,action:s}){return t.jsxs("div",{className:"flex flex-col gap-3",children:[t.jsxs("div",{children:[t.jsx("h1",{className:"text-xl font-semibold text-[var(--otari-ink)]",children:e}),r?t.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:r}):null]}),s?t.jsx("div",{className:"flex flex-wrap gap-2",children:s}):null]})}function Mr({children:e,confirmLabel:r,onConfirm:s,isPending:a}){const[n,l]=o.useState(!1);return n?t.jsxs("span",{className:"inline-flex items-center gap-1",children:[t.jsx(P,{size:"sm",variant:"danger",isDisabled:a,onPress:s,children:r}),t.jsx(P,{size:"sm",variant:"ghost",isDisabled:a,onPress:()=>l(!1),children:"Cancel"})]}):t.jsx(P,{size:"sm",variant:"danger-soft",onPress:()=>l(!0),children:e})}const ct="rounded-lg border border-[var(--otari-line)] bg-[var(--otari-bg)] px-3 py-2 text-sm text-[var(--otari-ink)] focus:border-[var(--otari-brand)] focus:outline-none";function Kr({id:e,label:r,ariaLabel:s,value:a,onChange:n,options:l,children:d,disabled:u}){const y=o.useId(),h=e??(r?y:void 0),p=t.jsx("select",{id:h,"aria-label":r?void 0:s,value:a,disabled:u,onChange:g=>n(g.target.value),className:ct,children:l?l.map(g=>t.jsx("option",{value:g.value,children:g.label},g.value)):d});return r?t.jsxs("div",{className:"flex flex-col gap-1",children:[t.jsx("label",{htmlFor:h,className:"text-xs font-medium text-[var(--otari-muted)]",children:r}),p]}):p}function Ur({label:e,value:r,onChange:s,options:a,placeholder:n,maxVisible:l=50,allowsCustom:d=!1}){const u=m=>{var c;return((c=a.find(j=>j.value===m))==null?void 0:c.label)??m},[y,h]=o.useState(()=>u(r));o.useEffect(()=>{h(u(r))},[r]);const p=y.trim().toLowerCase(),g=a.filter(m=>!p||m.value.toLowerCase().includes(p)||m.label.toLowerCase().includes(p)).slice(0,l);return t.jsxs(I.Root,{allowsEmptyCollection:!0,allowsCustomValue:d,menuTrigger:"focus",inputValue:y,onInputChange:m=>{h(m),d?s(m.trim()):m.trim()===""&&s("")},onSelectionChange:m=>{m!=null&&s(String(m))},className:"flex flex-col gap-1",children:[t.jsx(oe,{className:"text-xs font-medium text-[var(--otari-muted)]",children:e}),t.jsxs(I.InputGroup,{children:[t.jsx(le,{placeholder:n,autoComplete:"off",onFocus:m=>m.currentTarget.select()}),t.jsx(I.Trigger,{})]}),t.jsx(I.Popover,{children:t.jsx(Te,{items:g,className:"max-h-72 overflow-auto",children:m=>t.jsx(_e,{id:m.value,textValue:m.label,children:m.label})})})]})}function ut(){var l;const e=He(),r=We(),[s,a]=o.useState(!1);return!(((l=e.data)==null?void 0:l.require_pricing)===!0&&e.data.default_pricing===!1)||s?null:t.jsx("div",{className:"shrink-0 px-6 pt-3",children:t.jsx(lt,{tone:"warning",children:t.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[t.jsxs("span",{children:["Requests are rejected until pricing is set (",t.jsx("code",{children:"require_pricing"})," is on). Enable default pricing to meter new models with public rates right away."]}),t.jsxs("span",{className:"flex items-center gap-2",children:[t.jsx(P,{size:"sm",variant:"primary",isDisabled:r.isPending,onPress:()=>r.mutate({default_pricing:!0}),children:r.isPending?"Enabling…":"Enable default pricing"}),t.jsx(P,{size:"sm",variant:"ghost",onPress:()=>a(!0),children:"Dismiss"})]})]})})})}function dt(){const{data:e}=Ve(),r=o.useRef(null);return e&&r.current===null&&(r.current=e.build),e!=null&&r.current!=null&&e.build!==r.current}function mt(){const e=dt(),[r,s]=o.useState(!1);return!e||r?null:t.jsx("div",{className:"pointer-events-none absolute inset-x-0 top-0 z-50 flex justify-center",children:t.jsxs("div",{role:"status",className:"pointer-events-auto mt-1.5 flex items-center gap-3 rounded-full border border-[var(--otari-brand)] bg-[var(--otari-brand-tint)] py-1.5 pr-1.5 pl-4 text-sm text-[var(--otari-brand-dark)] shadow-md",children:[t.jsxs("span",{children:[t.jsx("strong",{className:"font-semibold",children:"An update is available."})," Reloading keeps you signed in."]}),t.jsx(P,{size:"sm",variant:"primary",onPress:()=>window.location.reload(),children:"Update now"}),t.jsx(P,{size:"sm",variant:"ghost",onPress:()=>s(!0),children:"Later"})]})})}const he=200,xe=480,B=240,ft=60,ye="otari.dashboard.sidebarWidth",ve="otari.dashboard.sidebarCollapsed",ae=16,R=e=>Math.min(xe,Math.max(he,e));function ht(){if(typeof window>"u")return B;try{const e=window.localStorage.getItem(ye),r=e?Number.parseInt(e,10):Number.NaN;return Number.isNaN(r)?B:R(r)}catch{return B}}function xt(){if(typeof window>"u")return!1;try{return window.localStorage.getItem(ve)==="1"}catch{return!1}}const yt=[{key:"home"},{key:"observability",label:"Observability"},{key:"catalog",label:"Catalog"},{key:"access",label:"Access"},{key:"system"}],vt=[{to:"/",section:"home",label:"Overview",end:!0,icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("rect",{x:"3.5",y:"3.5",width:"7",height:"7",rx:"1.5",strokeLinejoin:"round"}),t.jsx("rect",{x:"13.5",y:"3.5",width:"7",height:"7",rx:"1.5",strokeLinejoin:"round"}),t.jsx("rect",{x:"3.5",y:"13.5",width:"7",height:"7",rx:"1.5",strokeLinejoin:"round"}),t.jsx("rect",{x:"13.5",y:"13.5",width:"7",height:"7",rx:"1.5",strokeLinejoin:"round"})]})},{to:"/activity",section:"observability",label:"Activity",icon:t.jsx("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:t.jsx("path",{d:"M3 12h4l2.5-6 4 12 2.5-6H21",strokeLinecap:"round",strokeLinejoin:"round"})})},{to:"/usage",section:"observability",label:"Usage",icon:t.jsx("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:t.jsx("path",{d:"M4 20V10M10 20V4M16 20v-7M22 20H2",strokeLinecap:"round",strokeLinejoin:"round"})})},{to:"/providers",section:"catalog",label:"Providers",icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("rect",{x:"3.5",y:"4.5",width:"17",height:"6",rx:"1.5",strokeLinejoin:"round"}),t.jsx("rect",{x:"3.5",y:"13.5",width:"17",height:"6",rx:"1.5",strokeLinejoin:"round"}),t.jsx("path",{d:"M7 7.5h.01M7 16.5h.01",strokeLinecap:"round",strokeLinejoin:"round"})]})},{to:"/users",section:"access",label:"Users",icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("circle",{cx:"9",cy:"8",r:"3.2",strokeLinejoin:"round"}),t.jsx("path",{d:"M3.5 19a5.5 5.5 0 0 1 11 0",strokeLinecap:"round",strokeLinejoin:"round"}),t.jsx("path",{d:"M16 5.2a3.2 3.2 0 0 1 0 5.6M17.5 19a5.5 5.5 0 0 0-3-4.9",strokeLinecap:"round",strokeLinejoin:"round"})]})},{to:"/keys",section:"access",label:"API keys",icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("circle",{cx:"7.5",cy:"15.5",r:"3.5"}),t.jsx("path",{d:"M10 13l7-7M14 5l3 3M16.5 7.5l2-2",strokeLinecap:"round",strokeLinejoin:"round"})]})},{to:"/budgets",section:"access",label:"Budgets",icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("path",{d:"M3 7.5A1.5 1.5 0 0 1 4.5 6H18a1.5 1.5 0 0 1 1.5 1.5V9",strokeLinejoin:"round"}),t.jsx("rect",{x:"3",y:"7.5",width:"18",height:"12",rx:"1.5",strokeLinejoin:"round"}),t.jsx("path",{d:"M16 13.5h.01",strokeLinecap:"round",strokeLinejoin:"round"}),t.jsx("path",{d:"M21 12v3h-3.5a1.5 1.5 0 0 1 0-3H21z",strokeLinejoin:"round"})]})},{to:"/models",section:"catalog",label:"Models",icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("path",{d:"M12 3l8 4.5v9L12 21l-8-4.5v-9L12 3z",strokeLinejoin:"round"}),t.jsx("path",{d:"M12 12l8-4.5M12 12v9M12 12L4 7.5",strokeLinejoin:"round"})]})},{to:"/aliases",section:"catalog",label:"Aliases",icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("path",{d:"M20.6 13.4L13.4 20.6a2 2 0 0 1-2.8 0l-7-7A2 2 0 0 1 3 12.2V5a2 2 0 0 1 2-2h7.2a2 2 0 0 1 1.4.6l7 7a2 2 0 0 1 0 2.8z",strokeLinejoin:"round"}),t.jsx("circle",{cx:"7.5",cy:"7.5",r:"1.5"})]})},{to:"/tools",section:"system",label:"Tools & Guardrails",icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("path",{d:"M14.7 6.3a4 4 0 0 1 5 5l-8.4 8.4a2 2 0 0 1-2.8 0l-2.2-2.2a2 2 0 0 1 0-2.8z",strokeLinejoin:"round"}),t.jsx("path",{d:"M12 9 5 16",strokeLinecap:"round"})]})},{to:"/settings",section:"system",label:"Settings",icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("circle",{cx:"12",cy:"12",r:"3"}),t.jsx("path",{d:"M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z",strokeLinejoin:"round"})]})}];function gt(){const{logout:e}=V(),r=o.useRef(null),[s,a]=o.useState(ht),[n,l]=o.useState(xt),[d,u]=o.useState(!1);o.useEffect(()=>{const c=window.setTimeout(()=>{try{window.localStorage.setItem(ye,String(Math.round(s)))}catch{}},200);return()=>window.clearTimeout(c)},[s]),o.useEffect(()=>{try{window.localStorage.setItem(ve,n?"1":"0")}catch{}},[n]);const y=o.useCallback(c=>{c.preventDefault(),c.currentTarget.setPointerCapture(c.pointerId),u(!0)},[]),h=o.useCallback(c=>{var A;if(!c.currentTarget.hasPointerCapture(c.pointerId))return;const j=((A=r.current)==null?void 0:A.getBoundingClientRect().left)??0;a(R(c.clientX-j))},[]),p=o.useCallback(c=>{c.currentTarget.hasPointerCapture(c.pointerId)&&c.currentTarget.releasePointerCapture(c.pointerId),u(!1)},[]),g=o.useCallback(c=>{c.key==="ArrowLeft"?(c.preventDefault(),a(j=>R(j-ae))):c.key==="ArrowRight"&&(c.preventDefault(),a(j=>R(j+ae)))},[]),m=n?ft:s;return t.jsxs("div",{className:C("relative flex h-full flex-col overflow-hidden",d&&"cursor-col-resize select-none"),children:[t.jsxs("header",{className:"flex shrink-0 items-center justify-between border-b border-[var(--otari-line)] bg-[var(--otari-surface)] px-5 py-3",children:[t.jsxs("div",{className:"flex items-center gap-2.5",children:[t.jsx("img",{src:"/favicon.svg",alt:"",className:"h-7 w-7 shrink-0"}),t.jsx("span",{className:"text-base font-semibold text-[var(--otari-ink)]",children:"Otari"})]}),t.jsx(P,{size:"sm",variant:"outline",onPress:e,"aria-label":"Sign out",children:"Sign out"})]}),t.jsx(mt,{}),t.jsx(Be,{}),t.jsx(ut,{}),t.jsxs("div",{className:"flex min-h-0 flex-1",children:[t.jsxs("aside",{ref:r,style:{width:m},className:C("relative flex shrink-0 flex-col border-r border-[var(--otari-line)] bg-[var(--otari-surface)]",!d&&"transition-[width] duration-150"),children:[t.jsx("button",{type:"button",onClick:()=>l(c=>!c),"aria-label":n?"Expand sidebar":"Collapse sidebar","aria-pressed":n,title:n?"Expand sidebar":"Collapse sidebar",className:"absolute -right-3 top-4 z-30 flex h-6 w-6 items-center justify-center rounded-full border border-[var(--otari-line)] bg-[var(--otari-surface)] text-[var(--otari-muted)] shadow-sm transition-colors hover:border-[var(--otari-brand)] hover:text-[var(--otari-brand-dark)]",children:t.jsx("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",className:C("h-3.5 w-3.5 transition-transform",n&&"rotate-180"),children:t.jsx("path",{d:"M15 6l-6 6 6 6",strokeLinecap:"round",strokeLinejoin:"round"})})}),t.jsx("nav",{className:C("flex flex-col py-4",n?"px-2":"px-3"),children:yt.map((c,j)=>{const A=vt.filter(k=>k.section===c.key);return A.length===0?null:t.jsxs("div",{className:j>0?"mt-4":void 0,children:[!n&&c.label?t.jsx("div",{className:"px-3 pb-1 text-[11px] font-semibold tracking-wider text-[var(--otari-muted)] uppercase",children:c.label}):null,j>0&&(n||!c.label)?t.jsx("div",{className:"mx-1 mb-2 border-t border-[var(--otari-line)]"}):null,t.jsx("div",{className:"flex flex-col gap-1",children:A.map(k=>t.jsxs(ie,{to:k.to,end:k.end,"aria-label":n?k.label:void 0,title:n?k.label:void 0,className:({isActive:pe})=>C("flex items-center rounded-lg py-2 text-sm font-medium transition-colors",n?"justify-center px-0":"gap-3 px-3",pe?"bg-[var(--otari-brand-tint)] text-[var(--otari-brand-dark)]":"text-[var(--otari-muted)] hover:bg-[var(--otari-bg)] hover:text-[var(--otari-ink)]"),children:[k.icon,n?null:k.label]},k.to))})]},c.key)})}),t.jsxs("a",{href:"https://otari.ai",target:"_blank",rel:"noreferrer",title:"otari.ai — the hosted Otari gateway",className:C("mt-auto mb-3 flex items-center rounded-lg py-2 text-xs font-medium text-[var(--otari-muted)] transition-colors hover:bg-[var(--otari-bg)] hover:text-[var(--otari-brand-dark)]",n?"mx-2 justify-center px-0":"mx-3 gap-2 px-3"),children:[t.jsx("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-4 w-4 shrink-0",children:t.jsx("path",{d:"M18 10h-1.26A8 8 0 1 0 9 20h9a5 5 0 0 0 0-10z",strokeLinejoin:"round"})}),n?null:t.jsxs("span",{className:"flex-1",children:["otari.ai ",t.jsx("span",{"aria-hidden":!0,children:"↗"})]})]}),n?null:t.jsx("div",{role:"separator","aria-orientation":"vertical","aria-label":"Resize sidebar","aria-valuenow":Math.round(s),"aria-valuemin":he,"aria-valuemax":xe,tabIndex:0,onPointerDown:y,onPointerMove:h,onPointerUp:p,onKeyDown:g,className:C("absolute top-0 right-0 z-10 h-full w-1.5 cursor-col-resize touch-none transition-colors","hover:bg-[var(--otari-brand)] focus-visible:bg-[var(--otari-brand)] focus:outline-none",d?"bg-[var(--otari-brand)]":"bg-transparent")})]}),t.jsx("main",{className:"flex-1 overflow-y-auto",children:t.jsx("div",{className:"mx-auto flex max-w-[1800px] flex-col gap-6 px-6 py-6",children:t.jsx(Pe,{})})})]})]})}function pt(){const{login:e}=V(),[r,s]=o.useState(""),[a,n]=o.useState(null),[l,d]=o.useState(!1),u=async()=>{const y=r.trim();if(!(!y||l)){d(!0),n(null);try{await Oe(y)?e():n(new Error("Invalid master key."))}catch(h){n(h)}finally{d(!1)}}};return t.jsx("div",{className:"flex min-h-full items-center justify-center p-6",children:t.jsx(L,{className:"w-full max-w-md",children:t.jsxs(L.Content,{className:"flex flex-col gap-5 p-7",children:[t.jsxs("div",{className:"flex flex-col items-center gap-3 text-center",children:[t.jsx("img",{src:"/favicon.svg",alt:"Otari",className:"h-12 w-12"}),t.jsxs("div",{children:[t.jsx("h1",{className:"text-lg font-semibold text-[var(--otari-ink)]",children:"Otari Dashboard"}),t.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:"Sign in with your master key to browse models, set pricing, and manage settings."})]})]}),t.jsxs("form",{className:"flex flex-col gap-4",onSubmit:y=>{y.preventDefault(),u()},children:[t.jsxs(Ae,{value:r,onChange:y=>{s(y),a&&n(null)},type:"password",isRequired:!0,className:"flex flex-col gap-1",children:[t.jsx(oe,{className:"text-sm font-medium text-[var(--otari-ink)]",children:"Master key"}),t.jsx(le,{placeholder:"otari-mk-… or your master key",autoFocus:!0,autoComplete:"off"})]}),t.jsxs("details",{className:"text-xs text-[var(--otari-muted)]",children:[t.jsx("summary",{className:"cursor-pointer font-medium text-[var(--otari-brand-dark)]",children:"First run? Where to find your key"}),t.jsxs("p",{className:"mt-2 leading-relaxed",children:["If you did not set ",t.jsx("code",{children:"OTARI_MASTER_KEY"}),", Otari generated one and printed it to the server logs on startup. Look for the line ",t.jsx("code",{children:"Your master key:"})," (for example, run"," ",t.jsx("code",{children:"docker logs "}),") and paste it above."]})]}),t.jsx(ot,{error:a}),t.jsx(P,{type:"submit",variant:"primary",fullWidth:!0,isDisabled:!r.trim()||l,children:l?"Signing in…":"Sign in"})]}),t.jsx("p",{className:"text-center text-xs text-[var(--otari-muted)]",children:"The key is sent once to this gateway and exchanged for a session cookie; it is never stored in the browser."}),t.jsx("div",{className:"border-t border-[var(--otari-line)] pt-4 text-center",children:t.jsx(Le,{href:"/welcome",className:"text-sm font-medium text-[var(--otari-brand-dark)]",children:"New to Otari? Open the welcome guide"})})]})})})}const bt=o.lazy(async()=>({default:(await S(async()=>{const{ActivityPage:e}=await import("./ActivityPage-BrL4O-hT.js");return{ActivityPage:e}},__vite__mapDeps([0,1,2,3,4]))).ActivityPage})),jt=o.lazy(async()=>({default:(await S(async()=>{const{AliasesPage:e}=await import("./AliasesPage-RDVKM-by.js");return{AliasesPage:e}},__vite__mapDeps([5,1,2,6,4,3]))).AliasesPage})),wt=o.lazy(async()=>({default:(await S(async()=>{const{BudgetsPage:e}=await import("./BudgetsPage-Ctwj8twD.js");return{BudgetsPage:e}},__vite__mapDeps([7,1,2,6,4,3]))).BudgetsPage})),St=o.lazy(async()=>({default:(await S(async()=>{const{KeysPage:e}=await import("./KeysPage-DCo4FFYU.js");return{KeysPage:e}},__vite__mapDeps([8,1,2,6,4,9,3]))).KeysPage})),kt=o.lazy(async()=>({default:(await S(async()=>{const{ModelsPage:e}=await import("./ModelsPage-C028BOtV.js");return{ModelsPage:e}},__vite__mapDeps([10,1,2,3,4]))).ModelsPage})),Pt=o.lazy(async()=>({default:(await S(async()=>{const{OverviewIndex:e}=await import("./OverviewPage-KThfhw1Z.js");return{OverviewIndex:e}},__vite__mapDeps([11,1,2,12,13,4,3]))).OverviewIndex})),Et=o.lazy(async()=>({default:(await S(async()=>{const{ProvidersPage:e}=await import("./ProvidersPage-BEN5bHZD.js");return{ProvidersPage:e}},__vite__mapDeps([14,1,2,6,4,3]))).ProvidersPage})),Nt=o.lazy(async()=>({default:(await S(async()=>{const{SettingsPage:e}=await import("./SettingsPage-hENBFRMI.js");return{SettingsPage:e}},__vite__mapDeps([15,1,2,4]))).SettingsPage})),Ct=o.lazy(async()=>({default:(await S(async()=>{const{ToolsGuardrailsPage:e}=await import("./ToolsGuardrailsPage-DWSik0Ga.js");return{ToolsGuardrailsPage:e}},__vite__mapDeps([16,1,2,4]))).ToolsGuardrailsPage})),Tt=o.lazy(async()=>({default:(await S(async()=>{const{UsagePage:e}=await import("./UsagePage-B95PT-hq.js");return{UsagePage:e}},__vite__mapDeps([17,1,2,12,13,4,3]))).UsagePage})),_t=o.lazy(async()=>({default:(await S(async()=>{const{UsersPage:e}=await import("./UsersPage-D5CmT8Bq.js");return{UsersPage:e}},__vite__mapDeps([18,1,2,6,4,9,3]))).UsersPage}));function w(e){return t.jsx(o.Suspense,{fallback:t.jsx("div",{role:"status",children:"Loading page…"}),children:e})}function At(){const{isAuthenticated:e}=V();return e?t.jsx(Ee,{children:t.jsx(Ne,{children:t.jsxs(b,{element:t.jsx(gt,{}),children:[t.jsx(b,{index:!0,element:w(t.jsx(Pt,{}))}),t.jsx(b,{path:"providers",element:w(t.jsx(Et,{}))}),t.jsx(b,{path:"keys",element:w(t.jsx(St,{}))}),t.jsx(b,{path:"users",element:w(t.jsx(_t,{}))}),t.jsx(b,{path:"budgets",element:w(t.jsx(wt,{}))}),t.jsx(b,{path:"activity",element:w(t.jsx(bt,{}))}),t.jsx(b,{path:"usage",element:w(t.jsx(Tt,{}))}),t.jsx(b,{path:"models",element:w(t.jsx(kt,{}))}),t.jsx(b,{path:"aliases",element:w(t.jsx(jt,{}))}),t.jsx(b,{path:"tools",element:w(t.jsx(Ct,{}))}),t.jsx(b,{path:"settings",element:w(t.jsx(Nt,{}))}),t.jsx(b,{path:"*",element:t.jsx(Ce,{to:"/",replace:!0})})]})})}):t.jsx(pt,{})}function Lt({children:e}){const[r]=o.useState(()=>new we({defaultOptions:{queries:{refetchOnWindowFocus:!1,retry:(s,a)=>a instanceof E&&(a.status===401||a.status===403)?!1:s<2}}}));return t.jsx(Se,{client:r,children:t.jsx(Me,{children:e})})}const ge=document.getElementById("root");if(!ge)throw new Error("Root element #root not found");Ie.createRoot(ge).render(t.jsx(o.StrictMode,{children:t.jsx(Lt,{children:t.jsx(At,{})})}));export{Jt as $,Ar as A,He as B,Mr as C,Tr as D,ot as E,Kr as F,ir as G,or as H,lt as I,Mt as J,Bt as K,qr as L,Lr as M,Dr as N,at as O,Fr as P,Rr as Q,zt as R,Or as S,Ht as T,Gt as U,We as V,Vt as W,$t as X,Qt as Y,Ut as Z,Kt as _,Pr as a,lr as a0,cr as a1,ur as a2,tr as a3,Wt as a4,rr as a5,sr as a6,nr as a7,Ir as a8,kr as a9,wr as aa,Er as b,Nr as c,Ur as d,Ft as e,Xt as f,er as g,it as h,Zt as i,yr as j,gr as k,pr as l,br as m,Sr as n,vr as o,dr as p,fr as q,hr as r,xr as s,mr as t,jr as u,Dt as v,ar as w,Yt as x,_r as y,Cr as z}; diff --git a/src/gateway/static/dashboard/index.html b/src/gateway/static/dashboard/index.html index 5010b87d..630b0c06 100644 --- a/src/gateway/static/dashboard/index.html +++ b/src/gateway/static/dashboard/index.html @@ -6,7 +6,7 @@ Otari Dashboard - + diff --git a/web/src/pages/BudgetsPage.tsx b/web/src/pages/BudgetsPage.tsx index 8c969c0e..bb925ade 100644 --- a/web/src/pages/BudgetsPage.tsx +++ b/web/src/pages/BudgetsPage.tsx @@ -79,10 +79,10 @@ function PeriodPicker({ value, onChange }: { value: number | null; onChange: (se const trimmedDays = draft.trim(); const daysValue = Number(trimmedDays); - // Whole days only: a fractional or non-positive entry is rejected outright - // (surfaced below and left unsaved) rather than silently rounded, so 1.5 never - // becomes 2. - const invalidDays = trimmedDays !== "" && (!Number.isInteger(daysValue) || daysValue <= 0); + // Whole days only: a fractional, non-positive, or non-finite entry is rejected + // outright (surfaced below and left unsaved) rather than silently rounded, so + // 1.5 never becomes 2. isSafeInteger also rules out an overflowing day count. + const invalidDays = trimmedDays !== "" && (!Number.isSafeInteger(daysValue) || daysValue <= 0); return (
@@ -115,7 +115,7 @@ function PeriodPicker({ value, onChange }: { value: number | null; onChange: (se const n = Number(raw.trim()); // Reject a non-integer or non-positive value instead of rounding it; // it is held as null (unsaved) until the operator types whole days. - onChange(raw.trim() === "" || !Number.isInteger(n) || n <= 0 ? null : n * DAY); + onChange(raw.trim() === "" || !Number.isSafeInteger(n) || n <= 0 ? null : n * DAY); }} placeholder="14" description={ diff --git a/web/src/pages/UsagePage.test.tsx b/web/src/pages/UsagePage.test.tsx index ab4e628f..b9cc0ccb 100644 --- a/web/src/pages/UsagePage.test.tsx +++ b/web/src/pages/UsagePage.test.tsx @@ -62,7 +62,11 @@ function mockApi(body: UsageSummary | null) { // Surfaces the current location so a drill-down navigation can be asserted. function LocationProbe() { const loc = useLocation(); - return
{`${loc.pathname}${loc.search}`}
; + // A status role with an accessible name so tests query the probe by role + // rather than a test id. + return ( +
{`${loc.pathname}${loc.search}`}
+ ); } function renderPage(ui: ReactElement) { @@ -148,7 +152,7 @@ describe("UsagePage", () => { const row = (await screen.findByText("gpt-5.6")).closest("tr")!; await user.click(row); - const loc = screen.getByTestId("loc").textContent ?? ""; + const loc = screen.getByRole("status", { name: "Current location" }).textContent ?? ""; expect(loc.startsWith("/activity")).toBe(true); expect(loc).toContain("model=gpt-5.6"); }); @@ -169,7 +173,7 @@ describe("UsagePage", () => { const row = (await screen.findByText("gpt-5.6")).closest("tr")!; await user.click(row); - const loc = screen.getByTestId("loc").textContent ?? ""; + const loc = screen.getByRole("status", { name: "Current location" }).textContent ?? ""; expect(loc.startsWith("/activity")).toBe(true); expect(loc).toContain("model=gpt-5.6"); expect(loc).toContain("user_id=alice"); @@ -191,7 +195,7 @@ describe("UsagePage", () => { const row = (await screen.findByText("alice")).closest("tr")!; await user.click(row); - const loc = screen.getByTestId("loc").textContent ?? ""; + const loc = screen.getByRole("status", { name: "Current location" }).textContent ?? ""; expect(loc.startsWith("/activity")).toBe(true); expect(loc).toContain("user_id=alice"); expect(loc).toContain("model=gpt-5.6"); From 1022d85659d3d9b80efc80b5bbda24b60f6f08ed Mon Sep 17 00:00:00 2001 From: Nathan Brake Date: Fri, 24 Jul 2026 09:18:24 +0000 Subject: [PATCH 3/3] fix(dashboard): don't wipe or silently clear an invalid budget period Addresses review feedback from @khaledosman and Copilot on the budgets fix. khaledosman: the draft-reseed effect defeated the validation on the interactive and edit paths. Making a committed value fractional (e.g. 14 -> 14.5) emits onChange(null), which recomputed committedDays to "" and the effect then wiped the draft, so the error never showed. durationSec is only ever changed by PeriodPicker itself, so reseeding the draft from it always reacted to this component's own emission. Drop the effect; seed the draft on mount and reset it only on an explicit preset click (switching budgets already remounts the keyed form). Copilot: an invalid entry emitting null let Save clear an existing period to "no reset". Lift the period's validity to the form (like the limit field) and disable Save while the custom entry is invalid, so an invalid value can neither be rounded nor silently saved. Update the two paste-into-empty tests to assert Save is blocked, and add an edit test that makes a committed 14-day period fractional and asserts the field keeps "14.5", shows the error, and disables Save (the path the paste tests missed). Rebuild the committed dashboard bundle. Co-Authored-By: Claude Opus 4.8 (1M context) --- ...e-BrL4O-hT.js => ActivityPage-dbjTjmS5.js} | 2 +- ...ge-RDVKM-by.js => AliasesPage-DqjEr6cA.js} | 2 +- .../dashboard/assets/BudgetsPage-Ctwj8twD.js | 1 - .../dashboard/assets/BudgetsPage-DK4vAOyb.js | 1 + ...sPage-DCo4FFYU.js => KeysPage-DkXRnk8b.js} | 2 +- ...2Etqz.js => ModelScopeControl-CV1Wulbr.js} | 2 +- ...age-C028BOtV.js => ModelsPage-C-ZlmFwf.js} | 2 +- ...e-KThfhw1Z.js => OverviewPage-Cb1DW9ZC.js} | 2 +- ...-BEN5bHZD.js => ProvidersPage-CLe2cN4-.js} | 2 +- ...e-hENBFRMI.js => SettingsPage-BdorKXf4.js} | 2 +- ...0Ga.js => ToolsGuardrailsPage-D8Qsr-tI.js} | 2 +- ...Page-B95PT-hq.js => UsagePage-CRzEneXv.js} | 2 +- ...Page-D5CmT8Bq.js => UsersPage-zP5EVG6k.js} | 2 +- .../{index-BJySXQ_a.js => index-C94BH4OZ.js} | 4 +- src/gateway/static/dashboard/index.html | 2 +- web/src/pages/BudgetsPage.test.tsx | 51 +++++++++++------- web/src/pages/BudgetsPage.tsx | 53 ++++++++++++++----- 17 files changed, 85 insertions(+), 49 deletions(-) rename src/gateway/static/dashboard/assets/{ActivityPage-BrL4O-hT.js => ActivityPage-dbjTjmS5.js} (99%) rename src/gateway/static/dashboard/assets/{AliasesPage-RDVKM-by.js => AliasesPage-DqjEr6cA.js} (98%) delete mode 100644 src/gateway/static/dashboard/assets/BudgetsPage-Ctwj8twD.js create mode 100644 src/gateway/static/dashboard/assets/BudgetsPage-DK4vAOyb.js rename src/gateway/static/dashboard/assets/{KeysPage-DCo4FFYU.js => KeysPage-DkXRnk8b.js} (99%) rename src/gateway/static/dashboard/assets/{ModelScopeControl-DiX2Etqz.js => ModelScopeControl-CV1Wulbr.js} (98%) rename src/gateway/static/dashboard/assets/{ModelsPage-C028BOtV.js => ModelsPage-C-ZlmFwf.js} (99%) rename src/gateway/static/dashboard/assets/{OverviewPage-KThfhw1Z.js => OverviewPage-Cb1DW9ZC.js} (99%) rename src/gateway/static/dashboard/assets/{ProvidersPage-BEN5bHZD.js => ProvidersPage-CLe2cN4-.js} (99%) rename src/gateway/static/dashboard/assets/{SettingsPage-hENBFRMI.js => SettingsPage-BdorKXf4.js} (99%) rename src/gateway/static/dashboard/assets/{ToolsGuardrailsPage-DWSik0Ga.js => ToolsGuardrailsPage-D8Qsr-tI.js} (99%) rename src/gateway/static/dashboard/assets/{UsagePage-B95PT-hq.js => UsagePage-CRzEneXv.js} (99%) rename src/gateway/static/dashboard/assets/{UsersPage-D5CmT8Bq.js => UsersPage-zP5EVG6k.js} (98%) rename src/gateway/static/dashboard/assets/{index-BJySXQ_a.js => index-C94BH4OZ.js} (96%) diff --git a/src/gateway/static/dashboard/assets/ActivityPage-BrL4O-hT.js b/src/gateway/static/dashboard/assets/ActivityPage-dbjTjmS5.js similarity index 99% rename from src/gateway/static/dashboard/assets/ActivityPage-BrL4O-hT.js rename to src/gateway/static/dashboard/assets/ActivityPage-dbjTjmS5.js index 2e52850e..98e0cfa1 100644 --- a/src/gateway/static/dashboard/assets/ActivityPage-BrL4O-hT.js +++ b/src/gateway/static/dashboard/assets/ActivityPage-dbjTjmS5.js @@ -1 +1 @@ -import{j as e}from"./tanstack-query-1t81HyiD.js";import{u as le,r as n}from"./react-dgEcD0HR.js";import{u as re,a as ne,b as ie,c as oe,P as ce,E as de,F as G,d as Y}from"./index-BJySXQ_a.js";import{T as ue,a as me,b as d,L as xe,c as he,d as pe,e as u}from"./Table-CLdjdyTx.js";import{B as f,S as ge}from"./heroui-BX6JwHY-.js";const je=new Intl.NumberFormat(void 0,{style:"currency",currency:"USD",maximumFractionDigits:4});function _(t){return t===null?"—":je.format(t)}function o(t){return t===null?"—":t.toLocaleString()}function Z(t){return t===null?"—":t<1e3?`${t} ms`:`${(t/1e3).toFixed(t<1e4?2:1)} s`}function ve(t){const a=new Date(t);return Number.isNaN(a.getTime())?t:a.toLocaleString()}function be(t){const a=new Date(t).getTime();if(Number.isNaN(a))return t;const r=Math.max(0,Math.round((Date.now()-a)/1e3));if(r<60)return`${r}s ago`;const i=Math.round(r/60);if(i<60)return`${i}m ago`;const m=Math.round(i/60);return m<24?`${m}h ago`:`${Math.round(m/24)}d ago`}const fe=3600,k=86400,Ne=[{label:"Last hour",seconds:fe},{label:"24h",seconds:k},{label:"7d",seconds:7*k},{label:"All",seconds:null}],Se=[{label:"All",value:""},{label:"Success",value:"success"},{label:"Error",value:"error"}],_e=["/v1/chat/completions","/v1/messages","/v1/responses","/v1/embeddings","/v1/moderations","/v1/audio/transcriptions","/v1/audio/speech","/v1/images/generations","/v1/rerank","/v1/batches","/v1/batches/results"],N=50;function D(t){return new Date(Date.now()-t*1e3).toISOString()}function ke({status:t}){const a=t==="error"?"border-red-200 bg-red-50 text-red-700":"border-[var(--otari-line)] bg-[var(--otari-brand-tint)] text-[var(--otari-brand-dark)]";return e.jsx("span",{className:`inline-flex items-center rounded-full border px-2 py-0.5 text-xs font-medium ${a}`,children:t})}function l({label:t,children:a}){return e.jsxs("div",{className:"flex flex-col gap-0.5",children:[e.jsx("span",{className:"text-[11px] font-medium uppercase tracking-wide text-[var(--otari-muted)]",children:t}),e.jsx("span",{className:"text-sm text-[var(--otari-ink)] break-all",children:a})]})}function we({entry:t}){var a;return e.jsxs("div",{className:"flex flex-col gap-4 px-4 py-4",children:[t.error_message?e.jsxs("div",{className:"flex flex-col gap-1.5",children:[e.jsx("div",{className:"flex items-center justify-between",children:e.jsx("span",{className:"text-[11px] font-medium uppercase tracking-wide text-[var(--otari-muted)]",children:"Error"})}),e.jsx("pre",{className:"max-h-48 overflow-auto rounded-lg border border-red-200 bg-red-50 p-3 text-xs whitespace-pre-wrap break-all text-red-700",children:"The provider returned an error. Inspect gateway logs for details."})]}):null,e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2 lg:grid-cols-4",children:[e.jsx(l,{label:"Provider",children:t.provider??"—"}),e.jsx(l,{label:"Endpoint",children:t.endpoint}),e.jsx(l,{label:"User",children:t.user_id??"—"}),e.jsx(l,{label:"API key",children:t.api_key_id??"—"}),e.jsx(l,{label:"Prompt tokens",children:o(t.prompt_tokens)}),e.jsx(l,{label:"Completion tokens",children:o(t.completion_tokens)}),e.jsx(l,{label:"Total tokens",children:o(t.total_tokens)}),e.jsx(l,{label:"Cost",children:_(t.cost)}),e.jsx(l,{label:"Cache read tokens",children:o(t.cache_read_tokens)}),e.jsx(l,{label:"Cache write tokens",children:o(t.cache_write_tokens)}),e.jsx(l,{label:"1h cache writes",children:o(t.cache_write_1h_tokens??null)}),e.jsx(l,{label:"Total time",children:Z(t.latency_ms)}),e.jsx(l,{label:"Request ID",children:t.id})]}),(a=t.pricing_breakdown)!=null&&a.length?e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsx("span",{className:"text-[11px] font-medium uppercase tracking-wide text-[var(--otari-muted)]",children:"Billed meters"}),e.jsx("div",{className:"grid gap-2 sm:grid-cols-2 lg:grid-cols-3",children:t.pricing_breakdown.map(r=>e.jsxs(l,{label:r.meter.replaceAll("_"," "),children:[o(r.units)," at ",_(r.rate_per_million)," / 1M, ",_(r.cost)]},r.meter))})]}):null]})}const A=7;function Ce(){var B,z,H;const t=re(),[a]=le(),r=a.get("start_date")??void 0,[i,m]=n.useState(r?null:k),[S,w]=n.useState(()=>r??D(k)),[x,C]=n.useState(()=>a.get("status")??""),[c,M]=n.useState(()=>a.get("model")??""),[h,$]=n.useState(""),[p,U]=n.useState(()=>a.get("user_id")??""),[j,T]=n.useState(0),[J,K]=n.useState(null),P=n.useMemo(()=>({start_date:S,status:x||void 0,model:c.trim()||void 0,endpoint:h||void 0,user_id:p||void 0}),[S,x,c,h,p]);n.useEffect(()=>{T(0)},[P]);const g=ne(P,j,N),v=ie(P),Q=n.useMemo(()=>({start_date:S,status:x||void 0,endpoint:h||void 0,user_id:p||void 0}),[S,x,h,p]),F=((z=(B=oe(Q,"day").data)==null?void 0:B.by_model)==null?void 0:z.filter(s=>!s.is_other&&s.key!==null).map(s=>s.key))??[],b=g.data??[],E=((H=v.data)==null?void 0:H.total)??0,I=!!(x||c.trim()||h||p||i!==null),V=s=>{m(s),w(s===null?void 0:D(s))},W=()=>{m(null),w(void 0),C(""),M(""),$(""),U("")},X=()=>{i!==null&&w(D(i)),g.refetch(),v.refetch()},L=b.length>0,O=L?j*N+1:0,R=j*N+b.length,q=v.isSuccess&&!v.isPlaceholderData,ee=q?E===0?"0 of 0":`${O}–${R} of ${E.toLocaleString()}`:L?`${O}–${R}`:"0",se=q?(j+1)*Ne.jsx(f,{size:"sm",variant:i===s.seconds?"primary":"outline",onPress:()=>V(s.seconds),children:s.label},s.label))}),e.jsxs("div",{className:"flex flex-wrap items-end gap-3",children:[e.jsx(G,{id:"filter-status",label:"Status",value:x,onChange:C,children:Se.map(s=>e.jsx("option",{value:s.value,children:s.label},s.value))}),e.jsxs(G,{id:"filter-endpoint",label:"Endpoint",value:h,onChange:$,children:[e.jsx("option",{value:"",children:"All endpoints"}),_e.map(s=>e.jsx("option",{value:s,children:s},s))]}),e.jsx(Y,{label:"User",value:p,onChange:U,placeholder:"All users",options:(t.data??[]).map(s=>({value:s.user_id,label:s.alias?`${s.alias} (${s.user_id})`:s.user_id}))}),e.jsx(Y,{label:"Model",value:c,onChange:M,allowsCustom:!0,placeholder:"Any model",options:(c&&!F.includes(c)?[c,...F]:F).map(s=>({value:s,label:s}))}),I?e.jsx(f,{size:"sm",variant:"ghost",onPress:W,children:"Clear filters"}):null]})]}),e.jsxs(ue,{children:[e.jsx(me,{children:e.jsxs("tr",{children:[e.jsx(d,{children:"Time"}),e.jsx(d,{children:"User"}),e.jsx(d,{children:"Model"}),e.jsx(d,{className:"text-right",children:"Tokens"}),e.jsx(d,{className:"text-right",children:"Cost"}),e.jsx(d,{className:"text-right",children:"Total time"}),e.jsx(d,{children:"Status"})]})}),e.jsx("tbody",{children:g.isLoading?e.jsx(xe,{colSpan:A}):b.length===0?e.jsx(he,{colSpan:A,children:I?"No requests match these filters.":"No requests recorded yet."}):b.map(s=>{const te=s.status==="error",y=J===s.id;return e.jsxs(n.Fragment,{children:[e.jsxs(pe,{selected:y,className:te?"bg-red-50":"",onClick:()=>K(ae=>ae===s.id?null:s.id),children:[e.jsx(u,{className:"text-[var(--otari-muted)]",children:e.jsx("span",{title:ve(s.timestamp),children:be(s.timestamp)})}),e.jsx(u,{className:"text-[var(--otari-ink)]",children:s.user_id??"—"}),e.jsx(u,{className:"text-[var(--otari-ink)]",children:s.model}),e.jsx(u,{className:"text-right tabular-nums",children:o(s.total_tokens)}),e.jsx(u,{className:"text-right tabular-nums",children:_(s.cost)}),e.jsx(u,{className:"text-right tabular-nums",children:Z(s.latency_ms)}),e.jsx(u,{children:e.jsx(ke,{status:s.status})})]}),y?e.jsx("tr",{className:"border-b border-[var(--otari-line)] bg-[var(--otari-bg)]",children:e.jsx("td",{colSpan:A,children:e.jsx(we,{entry:s})})}):null]},s.id)})})]}),e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsxs("span",{className:"inline-flex items-center gap-2 text-sm text-[var(--otari-muted)]",children:[ee,g.isFetching?e.jsx(ge,{size:"sm"}):null]}),e.jsxs("span",{className:"inline-flex gap-1.5",children:[e.jsx(f,{size:"sm",variant:"outline",isDisabled:j===0,onPress:()=>T(s=>Math.max(0,s-1)),children:"Previous"}),e.jsx(f,{size:"sm",variant:"outline",isDisabled:!se,onPress:()=>T(s=>s+1),children:"Next"})]})]})]})}export{Ce as ActivityPage}; +import{j as e}from"./tanstack-query-1t81HyiD.js";import{u as le,r as n}from"./react-dgEcD0HR.js";import{u as re,a as ne,b as ie,c as oe,P as ce,E as de,F as G,d as Y}from"./index-C94BH4OZ.js";import{T as ue,a as me,b as d,L as xe,c as he,d as pe,e as u}from"./Table-CLdjdyTx.js";import{B as f,S as ge}from"./heroui-BX6JwHY-.js";const je=new Intl.NumberFormat(void 0,{style:"currency",currency:"USD",maximumFractionDigits:4});function _(t){return t===null?"—":je.format(t)}function o(t){return t===null?"—":t.toLocaleString()}function Z(t){return t===null?"—":t<1e3?`${t} ms`:`${(t/1e3).toFixed(t<1e4?2:1)} s`}function ve(t){const a=new Date(t);return Number.isNaN(a.getTime())?t:a.toLocaleString()}function be(t){const a=new Date(t).getTime();if(Number.isNaN(a))return t;const r=Math.max(0,Math.round((Date.now()-a)/1e3));if(r<60)return`${r}s ago`;const i=Math.round(r/60);if(i<60)return`${i}m ago`;const m=Math.round(i/60);return m<24?`${m}h ago`:`${Math.round(m/24)}d ago`}const fe=3600,k=86400,Ne=[{label:"Last hour",seconds:fe},{label:"24h",seconds:k},{label:"7d",seconds:7*k},{label:"All",seconds:null}],Se=[{label:"All",value:""},{label:"Success",value:"success"},{label:"Error",value:"error"}],_e=["/v1/chat/completions","/v1/messages","/v1/responses","/v1/embeddings","/v1/moderations","/v1/audio/transcriptions","/v1/audio/speech","/v1/images/generations","/v1/rerank","/v1/batches","/v1/batches/results"],N=50;function D(t){return new Date(Date.now()-t*1e3).toISOString()}function ke({status:t}){const a=t==="error"?"border-red-200 bg-red-50 text-red-700":"border-[var(--otari-line)] bg-[var(--otari-brand-tint)] text-[var(--otari-brand-dark)]";return e.jsx("span",{className:`inline-flex items-center rounded-full border px-2 py-0.5 text-xs font-medium ${a}`,children:t})}function l({label:t,children:a}){return e.jsxs("div",{className:"flex flex-col gap-0.5",children:[e.jsx("span",{className:"text-[11px] font-medium uppercase tracking-wide text-[var(--otari-muted)]",children:t}),e.jsx("span",{className:"text-sm text-[var(--otari-ink)] break-all",children:a})]})}function we({entry:t}){var a;return e.jsxs("div",{className:"flex flex-col gap-4 px-4 py-4",children:[t.error_message?e.jsxs("div",{className:"flex flex-col gap-1.5",children:[e.jsx("div",{className:"flex items-center justify-between",children:e.jsx("span",{className:"text-[11px] font-medium uppercase tracking-wide text-[var(--otari-muted)]",children:"Error"})}),e.jsx("pre",{className:"max-h-48 overflow-auto rounded-lg border border-red-200 bg-red-50 p-3 text-xs whitespace-pre-wrap break-all text-red-700",children:"The provider returned an error. Inspect gateway logs for details."})]}):null,e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2 lg:grid-cols-4",children:[e.jsx(l,{label:"Provider",children:t.provider??"—"}),e.jsx(l,{label:"Endpoint",children:t.endpoint}),e.jsx(l,{label:"User",children:t.user_id??"—"}),e.jsx(l,{label:"API key",children:t.api_key_id??"—"}),e.jsx(l,{label:"Prompt tokens",children:o(t.prompt_tokens)}),e.jsx(l,{label:"Completion tokens",children:o(t.completion_tokens)}),e.jsx(l,{label:"Total tokens",children:o(t.total_tokens)}),e.jsx(l,{label:"Cost",children:_(t.cost)}),e.jsx(l,{label:"Cache read tokens",children:o(t.cache_read_tokens)}),e.jsx(l,{label:"Cache write tokens",children:o(t.cache_write_tokens)}),e.jsx(l,{label:"1h cache writes",children:o(t.cache_write_1h_tokens??null)}),e.jsx(l,{label:"Total time",children:Z(t.latency_ms)}),e.jsx(l,{label:"Request ID",children:t.id})]}),(a=t.pricing_breakdown)!=null&&a.length?e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsx("span",{className:"text-[11px] font-medium uppercase tracking-wide text-[var(--otari-muted)]",children:"Billed meters"}),e.jsx("div",{className:"grid gap-2 sm:grid-cols-2 lg:grid-cols-3",children:t.pricing_breakdown.map(r=>e.jsxs(l,{label:r.meter.replaceAll("_"," "),children:[o(r.units)," at ",_(r.rate_per_million)," / 1M, ",_(r.cost)]},r.meter))})]}):null]})}const A=7;function Ce(){var B,z,H;const t=re(),[a]=le(),r=a.get("start_date")??void 0,[i,m]=n.useState(r?null:k),[S,w]=n.useState(()=>r??D(k)),[x,C]=n.useState(()=>a.get("status")??""),[c,M]=n.useState(()=>a.get("model")??""),[h,$]=n.useState(""),[p,U]=n.useState(()=>a.get("user_id")??""),[j,T]=n.useState(0),[J,K]=n.useState(null),P=n.useMemo(()=>({start_date:S,status:x||void 0,model:c.trim()||void 0,endpoint:h||void 0,user_id:p||void 0}),[S,x,c,h,p]);n.useEffect(()=>{T(0)},[P]);const g=ne(P,j,N),v=ie(P),Q=n.useMemo(()=>({start_date:S,status:x||void 0,endpoint:h||void 0,user_id:p||void 0}),[S,x,h,p]),F=((z=(B=oe(Q,"day").data)==null?void 0:B.by_model)==null?void 0:z.filter(s=>!s.is_other&&s.key!==null).map(s=>s.key))??[],b=g.data??[],E=((H=v.data)==null?void 0:H.total)??0,I=!!(x||c.trim()||h||p||i!==null),V=s=>{m(s),w(s===null?void 0:D(s))},W=()=>{m(null),w(void 0),C(""),M(""),$(""),U("")},X=()=>{i!==null&&w(D(i)),g.refetch(),v.refetch()},L=b.length>0,O=L?j*N+1:0,R=j*N+b.length,q=v.isSuccess&&!v.isPlaceholderData,ee=q?E===0?"0 of 0":`${O}–${R} of ${E.toLocaleString()}`:L?`${O}–${R}`:"0",se=q?(j+1)*Ne.jsx(f,{size:"sm",variant:i===s.seconds?"primary":"outline",onPress:()=>V(s.seconds),children:s.label},s.label))}),e.jsxs("div",{className:"flex flex-wrap items-end gap-3",children:[e.jsx(G,{id:"filter-status",label:"Status",value:x,onChange:C,children:Se.map(s=>e.jsx("option",{value:s.value,children:s.label},s.value))}),e.jsxs(G,{id:"filter-endpoint",label:"Endpoint",value:h,onChange:$,children:[e.jsx("option",{value:"",children:"All endpoints"}),_e.map(s=>e.jsx("option",{value:s,children:s},s))]}),e.jsx(Y,{label:"User",value:p,onChange:U,placeholder:"All users",options:(t.data??[]).map(s=>({value:s.user_id,label:s.alias?`${s.alias} (${s.user_id})`:s.user_id}))}),e.jsx(Y,{label:"Model",value:c,onChange:M,allowsCustom:!0,placeholder:"Any model",options:(c&&!F.includes(c)?[c,...F]:F).map(s=>({value:s,label:s}))}),I?e.jsx(f,{size:"sm",variant:"ghost",onPress:W,children:"Clear filters"}):null]})]}),e.jsxs(ue,{children:[e.jsx(me,{children:e.jsxs("tr",{children:[e.jsx(d,{children:"Time"}),e.jsx(d,{children:"User"}),e.jsx(d,{children:"Model"}),e.jsx(d,{className:"text-right",children:"Tokens"}),e.jsx(d,{className:"text-right",children:"Cost"}),e.jsx(d,{className:"text-right",children:"Total time"}),e.jsx(d,{children:"Status"})]})}),e.jsx("tbody",{children:g.isLoading?e.jsx(xe,{colSpan:A}):b.length===0?e.jsx(he,{colSpan:A,children:I?"No requests match these filters.":"No requests recorded yet."}):b.map(s=>{const te=s.status==="error",y=J===s.id;return e.jsxs(n.Fragment,{children:[e.jsxs(pe,{selected:y,className:te?"bg-red-50":"",onClick:()=>K(ae=>ae===s.id?null:s.id),children:[e.jsx(u,{className:"text-[var(--otari-muted)]",children:e.jsx("span",{title:ve(s.timestamp),children:be(s.timestamp)})}),e.jsx(u,{className:"text-[var(--otari-ink)]",children:s.user_id??"—"}),e.jsx(u,{className:"text-[var(--otari-ink)]",children:s.model}),e.jsx(u,{className:"text-right tabular-nums",children:o(s.total_tokens)}),e.jsx(u,{className:"text-right tabular-nums",children:_(s.cost)}),e.jsx(u,{className:"text-right tabular-nums",children:Z(s.latency_ms)}),e.jsx(u,{children:e.jsx(ke,{status:s.status})})]}),y?e.jsx("tr",{className:"border-b border-[var(--otari-line)] bg-[var(--otari-bg)]",children:e.jsx("td",{colSpan:A,children:e.jsx(we,{entry:s})})}):null]},s.id)})})]}),e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsxs("span",{className:"inline-flex items-center gap-2 text-sm text-[var(--otari-muted)]",children:[ee,g.isFetching?e.jsx(ge,{size:"sm"}):null]}),e.jsxs("span",{className:"inline-flex gap-1.5",children:[e.jsx(f,{size:"sm",variant:"outline",isDisabled:j===0,onPress:()=>T(s=>Math.max(0,s-1)),children:"Previous"}),e.jsx(f,{size:"sm",variant:"outline",isDisabled:!se,onPress:()=>T(s=>s+1),children:"Next"})]})]})]})}export{Ce as ActivityPage}; diff --git a/src/gateway/static/dashboard/assets/AliasesPage-RDVKM-by.js b/src/gateway/static/dashboard/assets/AliasesPage-DqjEr6cA.js similarity index 98% rename from src/gateway/static/dashboard/assets/AliasesPage-RDVKM-by.js rename to src/gateway/static/dashboard/assets/AliasesPage-DqjEr6cA.js index 0082b241..776eee30 100644 --- a/src/gateway/static/dashboard/assets/AliasesPage-RDVKM-by.js +++ b/src/gateway/static/dashboard/assets/AliasesPage-DqjEr6cA.js @@ -1 +1 @@ -import{j as e}from"./tanstack-query-1t81HyiD.js";import{r as x,u as w}from"./react-dgEcD0HR.js";import{e as L,f as E,g as B,P as D,E as N,C as I,h as M,i as A}from"./index-BJySXQ_a.js";import{F}from"./Field-HzRk1KDP.js";import{C as j,L as R,I as q,a as V,b as H,B as h,f as $,d as C}from"./heroui-BX6JwHY-.js";import{T as z,a as G,d as T,b as f,L as K,c as W,e as v}from"./Table-CLdjdyTx.js";const X=50;function k({label:t,value:n,onChange:a,description:r,placeholder:m="provider:model",autoFocus:i,isRequired:c}){const l=L(),{visible:d,total:s,failed:g}=x.useMemo(()=>{var S;const o=n.trim().toLowerCase(),p=((S=l.data)==null?void 0:S.providers)??[],y=p.flatMap(u=>u.models),P=o?y.filter(u=>u.key.toLowerCase().includes(o)):y;return{visible:P.slice(0,X),total:P.length,failed:p.filter(u=>!u.ok)}},[l.data,n]),b=l.isLoading?"Loading models from your providers…":g.length>0?`Could not list models for ${g.map(p=>p.provider).join(", ")}. Check that provider's credentials, or type the model key directly.`:s>d.length?`Showing ${d.length} of ${s} matches. Keep typing to narrow them.`:r;return e.jsxs(j.Root,{allowsCustomValue:!0,allowsEmptyCollection:!0,menuTrigger:"input",inputValue:n,onInputChange:a,onSelectionChange:o=>{o!=null&&a(String(o))},isRequired:c,className:"flex max-w-md flex-col gap-1",children:[e.jsx(R,{className:"text-sm font-medium text-[var(--otari-ink)]",children:t}),e.jsxs(j.InputGroup,{children:[e.jsx(q,{placeholder:m,autoFocus:i}),e.jsx(j.Trigger,{})]}),e.jsx(j.Popover,{children:e.jsx(V,{items:d,className:"max-h-72 overflow-auto",children:o=>e.jsx(H,{id:o.key,textValue:o.key,children:o.key})})}),b?e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:b}):null]})}function _({alias:t,onClose:n}){const a=A(),[r,m]=x.useState(t.target),i=r.trim()!==""&&r.trim()!==t.target,c=()=>{i&&a.mutate({name:t.name,target:r.trim()},{onSuccess:n})};return e.jsx(C,{children:e.jsxs(C.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsxs("div",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:["Edit alias ",e.jsx("code",{children:t.name})]}),e.jsx(N,{error:a.error}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx("span",{className:"text-sm font-medium text-[var(--otari-ink)]",children:"Alias name"}),e.jsx("code",{className:"text-sm text-[var(--otari-muted)]",children:t.name}),e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"The alias name is the key and cannot be changed here. Delete and recreate to rename."})]}),e.jsx(k,{label:"Target",value:r,onChange:m,isRequired:!0,description:"The real model this resolves to. Callers never see it."})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(h,{variant:"primary",isDisabled:!i||a.isPending,onPress:c,children:a.isPending?"Saving…":"Save changes"}),e.jsx(h,{variant:"ghost",onPress:n,children:"Cancel"})]})]})})}function J({onClose:t,initialTarget:n=""}){const a=A(),[r,m]=x.useState(""),[i,c]=x.useState(n),l=/[:/]/.test(r),d=r.trim()!==""&&i.trim()!==""&&!l,s=()=>{d&&a.mutate({name:r.trim(),target:i.trim()},{onSuccess:t})};return e.jsx(C,{children:e.jsxs(C.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsx("div",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:"New alias"}),e.jsx(N,{error:a.error}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsx(F,{label:"Alias name",value:r,onChange:m,placeholder:"fast-model",isRequired:!0,autoFocus:!0,description:l?e.jsx("span",{className:"text-red-700",children:"An alias name cannot contain “:” or “/”."}):"What callers send as `model`."}),e.jsx(k,{label:"Target",value:i,onChange:c,isRequired:!0,description:"The real model this resolves to. Callers never see it."})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(h,{variant:"primary",isDisabled:!d||a.isPending,onPress:s,children:a.isPending?"Creating…":"Create alias"}),e.jsx(h,{variant:"ghost",onPress:t,children:"Cancel"})]})]})})}function se(){const t=E(),n=B(),[a]=w(),r=a.get("target")??"",[m,i]=x.useState(r!==""),[c,l]=x.useState(null),d=[...t.data??[]].sort((s,g)=>s.name.localeCompare(g.name));return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(D,{title:"Aliases",description:"Friendly names that map to a real provider:model. Callers send the alias as the model; pricing, budgets, and usage key on the target.",action:m||c?null:e.jsx(h,{variant:"primary",onPress:()=>{l(null),i(!0)},children:"New alias"})}),e.jsx(N,{error:t.error}),m?e.jsx(J,{initialTarget:r,onClose:()=>i(!1)}):null,c?e.jsx(_,{alias:c,onClose:()=>l(null)}):null,e.jsxs(z,{children:[e.jsx(G,{children:e.jsxs(T,{children:[e.jsx(f,{children:"Alias"}),e.jsx(f,{children:"Target"}),e.jsx(f,{children:"Source"}),e.jsx(f,{className:"text-right",children:"Actions"})]})}),e.jsx("tbody",{children:t.isLoading?e.jsx(K,{colSpan:4}):d.length===0?e.jsx(W,{colSpan:4,children:"No aliases yet. Create one to give a model a friendly name."}):d.map(s=>e.jsxs(T,{children:[e.jsx(v,{className:"font-medium break-all text-[var(--otari-ink)]",children:s.name}),e.jsx(v,{className:"break-all text-[var(--otari-muted)]",children:s.target}),e.jsx(v,{children:e.jsx($,{size:"sm",color:s.source==="stored"?"accent":"default",children:s.source})}),e.jsx(v,{className:"text-right whitespace-nowrap",children:s.source==="stored"?e.jsxs("span",{className:"inline-flex items-center gap-2",children:[e.jsx(h,{size:"sm",variant:"ghost",onPress:()=>{i(!1),l(s)},children:"Edit"}),e.jsx(I,{confirmLabel:"Delete",isPending:n.isPending,onConfirm:()=>n.mutate(s.name),children:"Delete"}),n.error?e.jsx("span",{className:"text-xs text-red-700",children:M(n.error)}):null]}):e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"set in config.yml"})})]},s.name))})]})]})}export{se as AliasesPage}; +import{j as e}from"./tanstack-query-1t81HyiD.js";import{r as x,u as w}from"./react-dgEcD0HR.js";import{e as L,f as E,g as B,P as D,E as N,C as I,h as M,i as A}from"./index-C94BH4OZ.js";import{F}from"./Field-HzRk1KDP.js";import{C as j,L as R,I as q,a as V,b as H,B as h,f as $,d as C}from"./heroui-BX6JwHY-.js";import{T as z,a as G,d as T,b as f,L as K,c as W,e as v}from"./Table-CLdjdyTx.js";const X=50;function k({label:t,value:n,onChange:a,description:r,placeholder:m="provider:model",autoFocus:i,isRequired:c}){const l=L(),{visible:d,total:s,failed:g}=x.useMemo(()=>{var S;const o=n.trim().toLowerCase(),p=((S=l.data)==null?void 0:S.providers)??[],y=p.flatMap(u=>u.models),P=o?y.filter(u=>u.key.toLowerCase().includes(o)):y;return{visible:P.slice(0,X),total:P.length,failed:p.filter(u=>!u.ok)}},[l.data,n]),b=l.isLoading?"Loading models from your providers…":g.length>0?`Could not list models for ${g.map(p=>p.provider).join(", ")}. Check that provider's credentials, or type the model key directly.`:s>d.length?`Showing ${d.length} of ${s} matches. Keep typing to narrow them.`:r;return e.jsxs(j.Root,{allowsCustomValue:!0,allowsEmptyCollection:!0,menuTrigger:"input",inputValue:n,onInputChange:a,onSelectionChange:o=>{o!=null&&a(String(o))},isRequired:c,className:"flex max-w-md flex-col gap-1",children:[e.jsx(R,{className:"text-sm font-medium text-[var(--otari-ink)]",children:t}),e.jsxs(j.InputGroup,{children:[e.jsx(q,{placeholder:m,autoFocus:i}),e.jsx(j.Trigger,{})]}),e.jsx(j.Popover,{children:e.jsx(V,{items:d,className:"max-h-72 overflow-auto",children:o=>e.jsx(H,{id:o.key,textValue:o.key,children:o.key})})}),b?e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:b}):null]})}function _({alias:t,onClose:n}){const a=A(),[r,m]=x.useState(t.target),i=r.trim()!==""&&r.trim()!==t.target,c=()=>{i&&a.mutate({name:t.name,target:r.trim()},{onSuccess:n})};return e.jsx(C,{children:e.jsxs(C.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsxs("div",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:["Edit alias ",e.jsx("code",{children:t.name})]}),e.jsx(N,{error:a.error}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx("span",{className:"text-sm font-medium text-[var(--otari-ink)]",children:"Alias name"}),e.jsx("code",{className:"text-sm text-[var(--otari-muted)]",children:t.name}),e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"The alias name is the key and cannot be changed here. Delete and recreate to rename."})]}),e.jsx(k,{label:"Target",value:r,onChange:m,isRequired:!0,description:"The real model this resolves to. Callers never see it."})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(h,{variant:"primary",isDisabled:!i||a.isPending,onPress:c,children:a.isPending?"Saving…":"Save changes"}),e.jsx(h,{variant:"ghost",onPress:n,children:"Cancel"})]})]})})}function J({onClose:t,initialTarget:n=""}){const a=A(),[r,m]=x.useState(""),[i,c]=x.useState(n),l=/[:/]/.test(r),d=r.trim()!==""&&i.trim()!==""&&!l,s=()=>{d&&a.mutate({name:r.trim(),target:i.trim()},{onSuccess:t})};return e.jsx(C,{children:e.jsxs(C.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsx("div",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:"New alias"}),e.jsx(N,{error:a.error}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsx(F,{label:"Alias name",value:r,onChange:m,placeholder:"fast-model",isRequired:!0,autoFocus:!0,description:l?e.jsx("span",{className:"text-red-700",children:"An alias name cannot contain “:” or “/”."}):"What callers send as `model`."}),e.jsx(k,{label:"Target",value:i,onChange:c,isRequired:!0,description:"The real model this resolves to. Callers never see it."})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(h,{variant:"primary",isDisabled:!d||a.isPending,onPress:s,children:a.isPending?"Creating…":"Create alias"}),e.jsx(h,{variant:"ghost",onPress:t,children:"Cancel"})]})]})})}function se(){const t=E(),n=B(),[a]=w(),r=a.get("target")??"",[m,i]=x.useState(r!==""),[c,l]=x.useState(null),d=[...t.data??[]].sort((s,g)=>s.name.localeCompare(g.name));return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(D,{title:"Aliases",description:"Friendly names that map to a real provider:model. Callers send the alias as the model; pricing, budgets, and usage key on the target.",action:m||c?null:e.jsx(h,{variant:"primary",onPress:()=>{l(null),i(!0)},children:"New alias"})}),e.jsx(N,{error:t.error}),m?e.jsx(J,{initialTarget:r,onClose:()=>i(!1)}):null,c?e.jsx(_,{alias:c,onClose:()=>l(null)}):null,e.jsxs(z,{children:[e.jsx(G,{children:e.jsxs(T,{children:[e.jsx(f,{children:"Alias"}),e.jsx(f,{children:"Target"}),e.jsx(f,{children:"Source"}),e.jsx(f,{className:"text-right",children:"Actions"})]})}),e.jsx("tbody",{children:t.isLoading?e.jsx(K,{colSpan:4}):d.length===0?e.jsx(W,{colSpan:4,children:"No aliases yet. Create one to give a model a friendly name."}):d.map(s=>e.jsxs(T,{children:[e.jsx(v,{className:"font-medium break-all text-[var(--otari-ink)]",children:s.name}),e.jsx(v,{className:"break-all text-[var(--otari-muted)]",children:s.target}),e.jsx(v,{children:e.jsx($,{size:"sm",color:s.source==="stored"?"accent":"default",children:s.source})}),e.jsx(v,{className:"text-right whitespace-nowrap",children:s.source==="stored"?e.jsxs("span",{className:"inline-flex items-center gap-2",children:[e.jsx(h,{size:"sm",variant:"ghost",onPress:()=>{i(!1),l(s)},children:"Edit"}),e.jsx(I,{confirmLabel:"Delete",isPending:n.isPending,onConfirm:()=>n.mutate(s.name),children:"Delete"}),n.error?e.jsx("span",{className:"text-xs text-red-700",children:M(n.error)}):null]}):e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"set in config.yml"})})]},s.name))})]})]})}export{se as AliasesPage}; diff --git a/src/gateway/static/dashboard/assets/BudgetsPage-Ctwj8twD.js b/src/gateway/static/dashboard/assets/BudgetsPage-Ctwj8twD.js deleted file mode 100644 index 6ac704db..00000000 --- a/src/gateway/static/dashboard/assets/BudgetsPage-Ctwj8twD.js +++ /dev/null @@ -1 +0,0 @@ -import{j as e}from"./tanstack-query-1t81HyiD.js";import{r as d}from"./react-dgEcD0HR.js";import{j as Y,u as G,k as K,l as Q,m as X,n as J,P as Z,E as R,I as ee,o as se}from"./index-BJySXQ_a.js";import{F as L}from"./Field-HzRk1KDP.js";import{T as te,a as re,b as S,L as ae,c as ne,d as ie,e as C}from"./Table-CLdjdyTx.js";import{C as U,I as le,a as de,b as oe,B as g,d as E,S as ue}from"./heroui-BX6JwHY-.js";const ce=50;function me({value:s,onChange:r,users:a,label:i,description:l}){const[m,x]=d.useState(""),o=d.useMemo(()=>a.filter(t=>!t.user_id.startsWith("apikey-")).map(t=>({id:t.user_id,label:t.alias?`${t.user_id} (${t.alias})`:t.user_id})),[a]),h=d.useMemo(()=>{const t=m.trim().toLowerCase();return o.filter(u=>!s.includes(u.id)).filter(u=>!t||u.id.toLowerCase().includes(t)||u.label.toLowerCase().includes(t)).slice(0,ce)},[o,s,m]),c=t=>{s.includes(t)||r([...s,t]),x("")},p=t=>r(s.filter(u=>u!==t));return e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsxs("div",{children:[e.jsx("span",{className:"text-sm font-medium text-[var(--otari-ink)]",children:i}),l?e.jsx("p",{className:"text-xs text-[var(--otari-muted)]",children:l}):null]}),s.length>0?e.jsx("div",{className:"flex flex-wrap gap-1.5",children:s.map(t=>e.jsxs("span",{className:"inline-flex items-center gap-1 rounded-full bg-[var(--otari-brand-tint)] px-2.5 py-1 font-mono text-xs text-[var(--otari-brand-dark)]",children:[t,e.jsx("button",{type:"button","aria-label":`Remove ${t}`,onClick:()=>p(t),className:"text-[var(--otari-brand-dark)] hover:text-red-700",children:"×"})]},t))}):null,o.length===0?e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"No users yet. Create users first, then assign them here or from the Users page."}):e.jsxs(U.Root,{allowsEmptyCollection:!0,menuTrigger:"input",inputValue:m,onInputChange:x,selectedKey:null,onSelectionChange:t=>{t!=null&&c(String(t))},className:"flex flex-col gap-1",children:[e.jsxs(U.InputGroup,{children:[e.jsx(le,{"aria-label":"Add a user",placeholder:"Search users…",autoComplete:"off"}),e.jsx(U.Trigger,{})]}),e.jsx(U.Popover,{children:e.jsx(de,{items:h,className:"max-h-72 overflow-auto",children:t=>e.jsx(oe,{id:t.id,textValue:t.label,children:t.label})})})]})]})}const xe=new Intl.NumberFormat(void 0,{style:"currency",currency:"USD",maximumFractionDigits:2});function w(s){return xe.format(s)}const b=86400,$=3600,I=[{label:"No reset",seconds:null},{label:"Daily",seconds:b},{label:"Weekly",seconds:7*b},{label:"Monthly",seconds:30*b}];function ge(s){if(s===null)return"No reset";const r=I.find(a=>a.seconds===s);return r?r.label:s%b===0?`Every ${s/b} days`:s%$===0?`Every ${s/$} hours`:`Every ${s}s`}function F(s){if(!s)return"—";const r=new Date(s);return Number.isNaN(r.getTime())?"—":r.toLocaleString()}function he(s){const r=s.trim();if(r==="")return{value:null,valid:!0};const a=Number(r);return!Number.isFinite(a)||a<0?{value:null,valid:!1}:{value:a,valid:!0}}function pe({value:s,onChange:r}){const a=I.some(t=>t.seconds===s),[i,l]=d.useState(!a),m=s!==null&&s%b===0?String(s/b):"",[x,o]=d.useState(m);d.useEffect(()=>{o(m)},[m]);const h=x.trim(),c=Number(h),p=h!==""&&(!Number.isSafeInteger(c)||c<=0);return e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsx("span",{className:"text-sm font-medium text-[var(--otari-ink)]",children:"Reset period"}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[I.map(t=>e.jsx(g,{size:"sm",variant:!i&&s===t.seconds?"primary":"outline",onPress:()=>{l(!1),r(t.seconds)},children:t.label},t.label)),e.jsx(g,{size:"sm",variant:i?"primary":"outline",onPress:()=>l(!0),children:"Custom"})]}),i?e.jsx("div",{className:"flex items-end gap-2",children:e.jsx(L,{label:"Every N days",value:x,onChange:t=>{o(t);const u=Number(t.trim());r(t.trim()===""||!Number.isSafeInteger(u)||u<=0?null:u*b)},placeholder:"14",description:p?e.jsx("span",{className:"text-red-700",children:"Enter a whole number of days."}):"Whole days between resets."})}):null,e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"Spend returns to zero each period. A user’s clock starts when the budget is assigned to them."})]})}function O({title:s,submitLabel:r,initial:a,error:i,isPending:l,onSubmit:m,onClose:x,assignUsers:o}){const[h,c]=d.useState(a.name??""),[p,t]=d.useState(a.max_budget===null?"":String(a.max_budget)),[u,j]=d.useState(a.budget_duration_sec),[v,N]=d.useState([]),_=he(p),P=()=>{l||!_.valid||m({name:h.trim()||null,max_budget:_.value,budget_duration_sec:u},v)};return e.jsx(E,{children:e.jsxs(E.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsx("div",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:s}),e.jsx(R,{error:i}),e.jsx(L,{label:"Name (optional)",value:h,onChange:c,autoFocus:!0,placeholder:"team-free-tier",description:"A label to recognize this budget later."}),e.jsx(L,{label:"Spending limit (USD)",value:p,onChange:t,placeholder:"100.00",description:_.valid?"The most a single user on this budget may spend per period. Leave blank for no limit.":e.jsx("span",{className:"text-red-700",children:"Enter a non-negative number, or leave blank for no limit."})}),e.jsx(pe,{value:u,onChange:j}),o?e.jsx(me,{label:"Assign to users (optional)",description:"Attach this budget to existing users now. You can also manage assignments later on the Users page.",value:v,onChange:N,users:o}):null,e.jsxs("div",{className:"flex gap-2",children:[e.jsx(g,{variant:"primary",isDisabled:l||!_.valid,onPress:P,children:l?"Saving…":r}),e.jsx(g,{variant:"ghost",isDisabled:l,onPress:x,children:"Cancel"})]})]})})}function fe({budget:s}){if(s.user_count===0)return e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"No users assigned"});const r=s.total_spend;if(s.max_budget===null)return e.jsxs("span",{className:"text-xs text-[var(--otari-ink)]",children:[w(r)," spent",e.jsx("span",{className:"text-[var(--otari-muted)]",children:" · no limit"})]});const a=s.max_budget*s.user_count,i=a>0?Math.min(100,r/a*100):0,l=r>a;return e.jsxs("div",{className:"flex min-w-[140px] flex-col gap-1",children:[e.jsxs("div",{className:"flex items-baseline justify-between gap-2 text-xs",children:[e.jsx("span",{className:"text-[var(--otari-ink)]",children:w(r)}),e.jsxs("span",{className:"text-[var(--otari-muted)]",children:["of ",w(a)]})]}),e.jsx("div",{className:"h-1.5 w-full overflow-hidden rounded-full bg-[var(--otari-line)]",role:"progressbar","aria-valuenow":Math.round(i),"aria-valuemin":0,"aria-valuemax":100,"aria-label":"Aggregate spend against total allocation",children:e.jsx("div",{className:`h-full rounded-full ${l?"bg-red-500":"bg-[var(--otari-brand)]"}`,style:{width:`${Math.max(i,l?100:2)}%`}})})]})}function je({budgetId:s}){const r=se(s);if(r.isLoading)return e.jsxs("div",{className:"flex items-center gap-2 px-4 py-4 text-sm text-[var(--otari-muted)]",children:[e.jsx(ue,{size:"sm"})," Loading reset history…"]});if(r.error)return e.jsx("div",{className:"px-4 py-4",children:e.jsx(R,{error:r.error})});const a=r.data??[];return a.length===0?e.jsx("div",{className:"px-4 py-4 text-sm text-[var(--otari-muted)]",children:"No resets recorded yet for this budget."}):e.jsx("div",{className:"overflow-x-auto px-4 py-3",children:e.jsxs("table",{className:"w-full border-collapse text-xs",children:[e.jsx("thead",{className:"text-left text-[var(--otari-muted)]",children:e.jsxs("tr",{children:[e.jsx("th",{className:"py-1.5 pr-4 font-medium",children:"User"}),e.jsx("th",{className:"py-1.5 pr-4 font-medium",children:"Spend cleared"}),e.jsx("th",{className:"py-1.5 pr-4 font-medium",children:"Reset at"}),e.jsx("th",{className:"py-1.5 font-medium",children:"Next reset"})]})}),e.jsx("tbody",{children:a.map(i=>e.jsxs("tr",{className:"border-t border-[var(--otari-line)]",children:[e.jsx("td",{className:"py-1.5 pr-4",children:e.jsx("code",{children:i.user_id??"—"})}),e.jsx("td",{className:"py-1.5 pr-4 text-[var(--otari-ink)]",children:w(i.previous_spend)}),e.jsx("td",{className:"py-1.5 pr-4 text-[var(--otari-muted)]",children:F(i.reset_at)}),e.jsx("td",{className:"py-1.5 text-[var(--otari-muted)]",children:F(i.next_reset_at)})]},i.id))})]})})}function be({onCreate:s}){return e.jsx(E,{children:e.jsxs(E.Content,{className:"flex flex-col gap-4 p-6",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-semibold text-[var(--otari-ink)]",children:"No budgets yet"}),e.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:"A budget caps how much a user may spend and, optionally, resets that spend on a schedule. Create one, then assign it to users to enforce a limit."})]}),e.jsx("div",{children:e.jsx(g,{variant:"primary",onPress:s,children:"Create your first budget"})})]})})}function ve({label:s,isPending:r,onConfirm:a}){const[i,l]=d.useState(!1);return i?e.jsxs("div",{className:"flex flex-col items-end gap-1.5 rounded-lg border border-amber-200 bg-amber-50 p-2 text-right",children:[e.jsxs("span",{className:"max-w-xs text-xs text-amber-800",children:["Delete ",e.jsx("strong",{children:s}),"? Users keep their spend but lose this limit. Cannot be undone."]}),e.jsxs("span",{className:"inline-flex gap-1",children:[e.jsx(g,{size:"sm",variant:"danger",isDisabled:r,onPress:a,children:"Delete permanently"}),e.jsx(g,{size:"sm",variant:"ghost",isDisabled:r,onPress:()=>l(!1),children:"Cancel"})]})]}):e.jsx(g,{size:"sm",variant:"danger-soft",onPress:()=>l(!0),children:"Delete"})}function V(s){return s.split("-")[0]}function H(s){return s.name??V(s.budget_id)}function Pe(){const s=Y(),r=G(),a=K(),i=Q(),l=X(),m=J(),[x,o]=d.useState(!1),[h,c]=d.useState(null),[p,t]=d.useState(null),[u,j]=d.useState(null),[v,N]=d.useState(null),[_,P]=d.useState(!1),D=s.data??[],T=s.isLoading,y=D.find(n=>n.budget_id===h)??null,z=!T&&D.length===0&&!x,M=async(n,f)=>{P(!0),j(null);const B=await Promise.allSettled(f.map(k=>m.mutateAsync({id:k,body:{budget_id:n}})));P(!1);const A=B.flatMap((k,q)=>k.status==="rejected"?[f[q]]:[]);if(A.length>0){N({budgetId:n,userIds:A}),j(new Error(`Budget created, but could not assign it to: ${A.join(", ")}. Retry to try again.`));return}N(null),o(!1)},W=(n,f)=>{if(v){M(v.budgetId,v.userIds);return}j(null),a.mutate(n,{onSuccess:async B=>{if(f.length>0){await M(B.budget_id,f);return}o(!1)}})};return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(Z,{title:"Budgets",description:"Define spending limits and reset schedules. Assign a budget to users to enforce it.",action:x||z?null:e.jsx(g,{variant:"primary",onPress:()=>{c(null),j(null),N(null),o(!0)},children:"Create budget"})}),e.jsx(R,{error:s.error??a.error??i.error??l.error??m.error}),e.jsx(ee,{children:"Assign a budget to users when you create it, or later from the Users page. Each row’s usage aggregates the spend of the users currently on that budget."}),z?e.jsx(be,{onCreate:()=>{c(null),j(null),N(null),o(!0)}}):null,x?e.jsx(O,{title:"Create budget",submitLabel:v?"Retry assignments":"Create budget",initial:{name:null,max_budget:null,budget_duration_sec:null},error:a.error??u,isPending:a.isPending||_,assignUsers:r.data??[],onSubmit:W,onClose:()=>{j(null),N(null),o(!1)}}):null,y?e.jsx(O,{title:`Edit budget ${H(y)}`,submitLabel:"Save changes",initial:{name:y.name,max_budget:y.max_budget,budget_duration_sec:y.budget_duration_sec},error:i.error,isPending:i.isPending,onSubmit:n=>i.mutate({id:y.budget_id,body:n},{onSuccess:()=>c(null)}),onClose:()=>c(null)},y.budget_id):null,e.jsxs(te,{children:[e.jsx(re,{children:e.jsxs("tr",{children:[e.jsx(S,{children:"Budget"}),e.jsx(S,{children:"Limit (per user)"}),e.jsx(S,{children:"Reset"}),e.jsx(S,{children:"Users"}),e.jsx(S,{children:"Usage"}),e.jsx(S,{className:"text-right",children:"Actions"})]})}),e.jsx("tbody",{children:T?e.jsx(ae,{colSpan:6}):D.length===0?e.jsx(ne,{colSpan:6,children:"No budgets yet. Create one to cap spending."}):D.map(n=>e.jsxs(d.Fragment,{children:[e.jsxs(ie,{selected:h===n.budget_id,onClick:()=>{o(!1),c(n.budget_id)},children:[e.jsx(C,{className:"font-medium text-[var(--otari-ink)]",children:e.jsxs("div",{className:"flex flex-col gap-0.5",children:[e.jsx("span",{children:n.name??e.jsx("span",{className:"text-[var(--otari-muted)]",children:"(unnamed)"})}),e.jsx("code",{className:"text-[11px] text-[var(--otari-muted)]",title:n.budget_id,children:V(n.budget_id)})]})}),e.jsx(C,{children:n.max_budget===null?e.jsx("span",{className:"text-[var(--otari-muted)]",children:"Unlimited"}):w(n.max_budget)}),e.jsx(C,{className:"text-[var(--otari-muted)]",children:ge(n.budget_duration_sec)}),e.jsx(C,{className:"text-[var(--otari-muted)]",children:n.user_count}),e.jsx(C,{children:e.jsx(fe,{budget:n})}),e.jsx(C,{children:e.jsxs("div",{className:"flex items-center justify-end gap-1.5",onClick:f=>f.stopPropagation(),children:[e.jsx(g,{size:"sm",variant:"ghost",onPress:()=>t(f=>f===n.budget_id?null:n.budget_id),children:p===n.budget_id?"Hide history":"History"}),e.jsx(g,{size:"sm",variant:"ghost",onPress:()=>{o(!1),c(n.budget_id)},children:"Edit"}),e.jsx(ve,{label:H(n),isPending:l.isPending,onConfirm:()=>l.mutate(n.budget_id)})]})})]}),p===n.budget_id?e.jsx("tr",{className:"border-b border-[var(--otari-line)] bg-[var(--otari-bg)]",children:e.jsx("td",{colSpan:6,children:e.jsx(je,{budgetId:n.budget_id})})}):null]},n.budget_id))})]})]})}export{Pe as BudgetsPage}; diff --git a/src/gateway/static/dashboard/assets/BudgetsPage-DK4vAOyb.js b/src/gateway/static/dashboard/assets/BudgetsPage-DK4vAOyb.js new file mode 100644 index 00000000..f1076965 --- /dev/null +++ b/src/gateway/static/dashboard/assets/BudgetsPage-DK4vAOyb.js @@ -0,0 +1 @@ +import{j as e}from"./tanstack-query-1t81HyiD.js";import{r as d}from"./react-dgEcD0HR.js";import{j as G,u as K,k as Q,l as X,m as J,n as Z,P as ee,E as T,I as se,o as te}from"./index-C94BH4OZ.js";import{F as I}from"./Field-HzRk1KDP.js";import{T as re,a as ae,b as S,L as ne,c as ie,d as le,e as C}from"./Table-CLdjdyTx.js";import{C as E,I as de,a as oe,b as ue,B as h,d as B,S as ce}from"./heroui-BX6JwHY-.js";const me=50;function xe({value:s,onChange:a,users:r,label:i,description:l}){const[m,x]=d.useState(""),o=d.useMemo(()=>r.filter(t=>!t.user_id.startsWith("apikey-")).map(t=>({id:t.user_id,label:t.alias?`${t.user_id} (${t.alias})`:t.user_id})),[r]),p=d.useMemo(()=>{const t=m.trim().toLowerCase();return o.filter(u=>!s.includes(u.id)).filter(u=>!t||u.id.toLowerCase().includes(t)||u.label.toLowerCase().includes(t)).slice(0,me)},[o,s,m]),c=t=>{s.includes(t)||a([...s,t]),x("")},g=t=>a(s.filter(u=>u!==t));return e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsxs("div",{children:[e.jsx("span",{className:"text-sm font-medium text-[var(--otari-ink)]",children:i}),l?e.jsx("p",{className:"text-xs text-[var(--otari-muted)]",children:l}):null]}),s.length>0?e.jsx("div",{className:"flex flex-wrap gap-1.5",children:s.map(t=>e.jsxs("span",{className:"inline-flex items-center gap-1 rounded-full bg-[var(--otari-brand-tint)] px-2.5 py-1 font-mono text-xs text-[var(--otari-brand-dark)]",children:[t,e.jsx("button",{type:"button","aria-label":`Remove ${t}`,onClick:()=>g(t),className:"text-[var(--otari-brand-dark)] hover:text-red-700",children:"×"})]},t))}):null,o.length===0?e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"No users yet. Create users first, then assign them here or from the Users page."}):e.jsxs(E.Root,{allowsEmptyCollection:!0,menuTrigger:"input",inputValue:m,onInputChange:x,selectedKey:null,onSelectionChange:t=>{t!=null&&c(String(t))},className:"flex flex-col gap-1",children:[e.jsxs(E.InputGroup,{children:[e.jsx(de,{"aria-label":"Add a user",placeholder:"Search users…",autoComplete:"off"}),e.jsx(E.Trigger,{})]}),e.jsx(E.Popover,{children:e.jsx(oe,{items:p,className:"max-h-72 overflow-auto",children:t=>e.jsx(ue,{id:t.id,textValue:t.label,children:t.label})})})]})]})}const ge=new Intl.NumberFormat(void 0,{style:"currency",currency:"USD",maximumFractionDigits:2});function P(s){return ge.format(s)}const N=86400,$=3600,R=[{label:"No reset",seconds:null},{label:"Daily",seconds:N},{label:"Weekly",seconds:7*N},{label:"Monthly",seconds:30*N}];function he(s){if(s===null)return"No reset";const a=R.find(r=>r.seconds===s);return a?a.label:s%N===0?`Every ${s/N} days`:s%$===0?`Every ${s/$} hours`:`Every ${s}s`}function F(s){if(!s)return"—";const a=new Date(s);return Number.isNaN(a.getTime())?"—":a.toLocaleString()}function pe(s){const a=s.trim();if(a==="")return{value:null,valid:!0};const r=Number(a);return!Number.isFinite(r)||r<0?{value:null,valid:!1}:{value:r,valid:!0}}function O(s){return s!==null&&s%N===0?String(s/N):""}function fe({value:s,onChange:a,onInvalidChange:r}){const i=R.some(t=>t.seconds===s),[l,m]=d.useState(!i),[x,o]=d.useState(()=>O(s)),p=x.trim(),c=Number(p),g=p!==""&&(!Number.isSafeInteger(c)||c<=0);return d.useEffect(()=>{r==null||r(g)},[g,r]),e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsx("span",{className:"text-sm font-medium text-[var(--otari-ink)]",children:"Reset period"}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[R.map(t=>e.jsx(h,{size:"sm",variant:!l&&s===t.seconds?"primary":"outline",onPress:()=>{m(!1),o(O(t.seconds)),a(t.seconds)},children:t.label},t.label)),e.jsx(h,{size:"sm",variant:l?"primary":"outline",onPress:()=>m(!0),children:"Custom"})]}),l?e.jsx("div",{className:"flex items-end gap-2",children:e.jsx(I,{label:"Every N days",value:x,onChange:t=>{o(t);const u=Number(t.trim());a(t.trim()===""||!Number.isSafeInteger(u)||u<=0?null:u*N)},placeholder:"14",description:g?e.jsx("span",{className:"text-red-700",children:"Enter a whole number of days."}):"Whole days between resets."})}):null,e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"Spend returns to zero each period. A user’s clock starts when the budget is assigned to them."})]})}function H({title:s,submitLabel:a,initial:r,error:i,isPending:l,onSubmit:m,onClose:x,assignUsers:o}){const[p,c]=d.useState(r.name??""),[g,t]=d.useState(r.max_budget===null?"":String(r.max_budget)),[u,b]=d.useState(r.budget_duration_sec),[_,y]=d.useState(!1),[U,D]=d.useState([]),v=pe(g),w=!l&&v.valid&&!_,f=()=>{w&&m({name:p.trim()||null,max_budget:v.value,budget_duration_sec:u},U)};return e.jsx(B,{children:e.jsxs(B.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsx("div",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:s}),e.jsx(T,{error:i}),e.jsx(I,{label:"Name (optional)",value:p,onChange:c,autoFocus:!0,placeholder:"team-free-tier",description:"A label to recognize this budget later."}),e.jsx(I,{label:"Spending limit (USD)",value:g,onChange:t,placeholder:"100.00",description:v.valid?"The most a single user on this budget may spend per period. Leave blank for no limit.":e.jsx("span",{className:"text-red-700",children:"Enter a non-negative number, or leave blank for no limit."})}),e.jsx(fe,{value:u,onChange:b,onInvalidChange:y}),o?e.jsx(xe,{label:"Assign to users (optional)",description:"Attach this budget to existing users now. You can also manage assignments later on the Users page.",value:U,onChange:D,users:o}):null,e.jsxs("div",{className:"flex gap-2",children:[e.jsx(h,{variant:"primary",isDisabled:!w,onPress:f,children:l?"Saving…":a}),e.jsx(h,{variant:"ghost",isDisabled:l,onPress:x,children:"Cancel"})]})]})})}function je({budget:s}){if(s.user_count===0)return e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"No users assigned"});const a=s.total_spend;if(s.max_budget===null)return e.jsxs("span",{className:"text-xs text-[var(--otari-ink)]",children:[P(a)," spent",e.jsx("span",{className:"text-[var(--otari-muted)]",children:" · no limit"})]});const r=s.max_budget*s.user_count,i=r>0?Math.min(100,a/r*100):0,l=a>r;return e.jsxs("div",{className:"flex min-w-[140px] flex-col gap-1",children:[e.jsxs("div",{className:"flex items-baseline justify-between gap-2 text-xs",children:[e.jsx("span",{className:"text-[var(--otari-ink)]",children:P(a)}),e.jsxs("span",{className:"text-[var(--otari-muted)]",children:["of ",P(r)]})]}),e.jsx("div",{className:"h-1.5 w-full overflow-hidden rounded-full bg-[var(--otari-line)]",role:"progressbar","aria-valuenow":Math.round(i),"aria-valuemin":0,"aria-valuemax":100,"aria-label":"Aggregate spend against total allocation",children:e.jsx("div",{className:`h-full rounded-full ${l?"bg-red-500":"bg-[var(--otari-brand)]"}`,style:{width:`${Math.max(i,l?100:2)}%`}})})]})}function be({budgetId:s}){const a=te(s);if(a.isLoading)return e.jsxs("div",{className:"flex items-center gap-2 px-4 py-4 text-sm text-[var(--otari-muted)]",children:[e.jsx(ce,{size:"sm"})," Loading reset history…"]});if(a.error)return e.jsx("div",{className:"px-4 py-4",children:e.jsx(T,{error:a.error})});const r=a.data??[];return r.length===0?e.jsx("div",{className:"px-4 py-4 text-sm text-[var(--otari-muted)]",children:"No resets recorded yet for this budget."}):e.jsx("div",{className:"overflow-x-auto px-4 py-3",children:e.jsxs("table",{className:"w-full border-collapse text-xs",children:[e.jsx("thead",{className:"text-left text-[var(--otari-muted)]",children:e.jsxs("tr",{children:[e.jsx("th",{className:"py-1.5 pr-4 font-medium",children:"User"}),e.jsx("th",{className:"py-1.5 pr-4 font-medium",children:"Spend cleared"}),e.jsx("th",{className:"py-1.5 pr-4 font-medium",children:"Reset at"}),e.jsx("th",{className:"py-1.5 font-medium",children:"Next reset"})]})}),e.jsx("tbody",{children:r.map(i=>e.jsxs("tr",{className:"border-t border-[var(--otari-line)]",children:[e.jsx("td",{className:"py-1.5 pr-4",children:e.jsx("code",{children:i.user_id??"—"})}),e.jsx("td",{className:"py-1.5 pr-4 text-[var(--otari-ink)]",children:P(i.previous_spend)}),e.jsx("td",{className:"py-1.5 pr-4 text-[var(--otari-muted)]",children:F(i.reset_at)}),e.jsx("td",{className:"py-1.5 text-[var(--otari-muted)]",children:F(i.next_reset_at)})]},i.id))})]})})}function ve({onCreate:s}){return e.jsx(B,{children:e.jsxs(B.Content,{className:"flex flex-col gap-4 p-6",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-semibold text-[var(--otari-ink)]",children:"No budgets yet"}),e.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:"A budget caps how much a user may spend and, optionally, resets that spend on a schedule. Create one, then assign it to users to enforce a limit."})]}),e.jsx("div",{children:e.jsx(h,{variant:"primary",onPress:s,children:"Create your first budget"})})]})})}function Ne({label:s,isPending:a,onConfirm:r}){const[i,l]=d.useState(!1);return i?e.jsxs("div",{className:"flex flex-col items-end gap-1.5 rounded-lg border border-amber-200 bg-amber-50 p-2 text-right",children:[e.jsxs("span",{className:"max-w-xs text-xs text-amber-800",children:["Delete ",e.jsx("strong",{children:s}),"? Users keep their spend but lose this limit. Cannot be undone."]}),e.jsxs("span",{className:"inline-flex gap-1",children:[e.jsx(h,{size:"sm",variant:"danger",isDisabled:a,onPress:r,children:"Delete permanently"}),e.jsx(h,{size:"sm",variant:"ghost",isDisabled:a,onPress:()=>l(!1),children:"Cancel"})]})]}):e.jsx(h,{size:"sm",variant:"danger-soft",onPress:()=>l(!0),children:"Delete"})}function W(s){return s.split("-")[0]}function V(s){return s.name??W(s.budget_id)}function Ue(){const s=G(),a=K(),r=Q(),i=X(),l=J(),m=Z(),[x,o]=d.useState(!1),[p,c]=d.useState(null),[g,t]=d.useState(null),[u,b]=d.useState(null),[_,y]=d.useState(null),[U,D]=d.useState(!1),v=s.data??[],w=s.isLoading,f=v.find(n=>n.budget_id===p)??null,z=!w&&v.length===0&&!x,M=async(n,j)=>{D(!0),b(null);const A=await Promise.allSettled(j.map(L=>m.mutateAsync({id:L,body:{budget_id:n}})));D(!1);const k=A.flatMap((L,Y)=>L.status==="rejected"?[j[Y]]:[]);if(k.length>0){y({budgetId:n,userIds:k}),b(new Error(`Budget created, but could not assign it to: ${k.join(", ")}. Retry to try again.`));return}y(null),o(!1)},q=(n,j)=>{if(_){M(_.budgetId,_.userIds);return}b(null),r.mutate(n,{onSuccess:async A=>{if(j.length>0){await M(A.budget_id,j);return}o(!1)}})};return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(ee,{title:"Budgets",description:"Define spending limits and reset schedules. Assign a budget to users to enforce it.",action:x||z?null:e.jsx(h,{variant:"primary",onPress:()=>{c(null),b(null),y(null),o(!0)},children:"Create budget"})}),e.jsx(T,{error:s.error??r.error??i.error??l.error??m.error}),e.jsx(se,{children:"Assign a budget to users when you create it, or later from the Users page. Each row’s usage aggregates the spend of the users currently on that budget."}),z?e.jsx(ve,{onCreate:()=>{c(null),b(null),y(null),o(!0)}}):null,x?e.jsx(H,{title:"Create budget",submitLabel:_?"Retry assignments":"Create budget",initial:{name:null,max_budget:null,budget_duration_sec:null},error:r.error??u,isPending:r.isPending||U,assignUsers:a.data??[],onSubmit:q,onClose:()=>{b(null),y(null),o(!1)}}):null,f?e.jsx(H,{title:`Edit budget ${V(f)}`,submitLabel:"Save changes",initial:{name:f.name,max_budget:f.max_budget,budget_duration_sec:f.budget_duration_sec},error:i.error,isPending:i.isPending,onSubmit:n=>i.mutate({id:f.budget_id,body:n},{onSuccess:()=>c(null)}),onClose:()=>c(null)},f.budget_id):null,e.jsxs(re,{children:[e.jsx(ae,{children:e.jsxs("tr",{children:[e.jsx(S,{children:"Budget"}),e.jsx(S,{children:"Limit (per user)"}),e.jsx(S,{children:"Reset"}),e.jsx(S,{children:"Users"}),e.jsx(S,{children:"Usage"}),e.jsx(S,{className:"text-right",children:"Actions"})]})}),e.jsx("tbody",{children:w?e.jsx(ne,{colSpan:6}):v.length===0?e.jsx(ie,{colSpan:6,children:"No budgets yet. Create one to cap spending."}):v.map(n=>e.jsxs(d.Fragment,{children:[e.jsxs(le,{selected:p===n.budget_id,onClick:()=>{o(!1),c(n.budget_id)},children:[e.jsx(C,{className:"font-medium text-[var(--otari-ink)]",children:e.jsxs("div",{className:"flex flex-col gap-0.5",children:[e.jsx("span",{children:n.name??e.jsx("span",{className:"text-[var(--otari-muted)]",children:"(unnamed)"})}),e.jsx("code",{className:"text-[11px] text-[var(--otari-muted)]",title:n.budget_id,children:W(n.budget_id)})]})}),e.jsx(C,{children:n.max_budget===null?e.jsx("span",{className:"text-[var(--otari-muted)]",children:"Unlimited"}):P(n.max_budget)}),e.jsx(C,{className:"text-[var(--otari-muted)]",children:he(n.budget_duration_sec)}),e.jsx(C,{className:"text-[var(--otari-muted)]",children:n.user_count}),e.jsx(C,{children:e.jsx(je,{budget:n})}),e.jsx(C,{children:e.jsxs("div",{className:"flex items-center justify-end gap-1.5",onClick:j=>j.stopPropagation(),children:[e.jsx(h,{size:"sm",variant:"ghost",onPress:()=>t(j=>j===n.budget_id?null:n.budget_id),children:g===n.budget_id?"Hide history":"History"}),e.jsx(h,{size:"sm",variant:"ghost",onPress:()=>{o(!1),c(n.budget_id)},children:"Edit"}),e.jsx(Ne,{label:V(n),isPending:l.isPending,onConfirm:()=>l.mutate(n.budget_id)})]})})]}),g===n.budget_id?e.jsx("tr",{className:"border-b border-[var(--otari-line)] bg-[var(--otari-bg)]",children:e.jsx("td",{colSpan:6,children:e.jsx(be,{budgetId:n.budget_id})})}):null]},n.budget_id))})]})]})}export{Ue as BudgetsPage}; diff --git a/src/gateway/static/dashboard/assets/KeysPage-DCo4FFYU.js b/src/gateway/static/dashboard/assets/KeysPage-DkXRnk8b.js similarity index 99% rename from src/gateway/static/dashboard/assets/KeysPage-DCo4FFYU.js rename to src/gateway/static/dashboard/assets/KeysPage-DkXRnk8b.js index 2daf1e46..24becc66 100644 --- a/src/gateway/static/dashboard/assets/KeysPage-DCo4FFYU.js +++ b/src/gateway/static/dashboard/assets/KeysPage-DkXRnk8b.js @@ -1,4 +1,4 @@ -import{j as e}from"./tanstack-query-1t81HyiD.js";import{r as m}from"./react-dgEcD0HR.js";import{p as $,q as E,r as z,s as K,P as H,E as T,t as B,u as M,I as V}from"./index-BJySXQ_a.js";import{F as k}from"./Field-HzRk1KDP.js";import{M as O,a as A}from"./ModelScopeControl-DiX2Etqz.js";import{C as _,L as U,I as q,a as W,b as G,D as Y,B as g,f as P,d as C}from"./heroui-BX6JwHY-.js";import{T as J,a as Q,b as v,L as X,c as Z,d as ee,e as y}from"./Table-CLdjdyTx.js";function te({value:t,onChange:s,users:n,description:i}){const c=n.filter(a=>!a.user_id.startsWith("apikey-")).map(a=>({id:a.user_id,name:a.alias?`${a.user_id} (${a.alias})`:a.user_id})),[l,o]=m.useState(t),u=l.trim().toLowerCase(),j=c.filter(a=>!u||a.id.toLowerCase().includes(u)||a.name.toLowerCase().includes(u)).slice(0,50),p=a=>{const x=a.trim(),w=c.find(N=>N.id===x||N.name===x);return w?w.id:x},d=p(l),h=c.some(a=>a.id===d),f=d!==""&&!h?e.jsxs("span",{children:["Creates a new user ",e.jsx("code",{children:d}),"."]}):i??"Spend and budgets track against this user.";return e.jsxs(_.Root,{allowsCustomValue:!0,allowsEmptyCollection:!0,menuTrigger:"focus",inputValue:l,onInputChange:a=>{o(a),s(p(a))},onSelectionChange:a=>{if(a!=null){const x=String(a);o(x),s(x)}},className:"flex max-w-md flex-col gap-1",children:[e.jsx(U,{className:"text-sm font-medium text-[var(--otari-ink)]",children:"Owner"}),e.jsxs(_.InputGroup,{children:[e.jsx(q,{placeholder:"Pick a user, or type a new id…",autoComplete:"off","data-1p-ignore":!0,"data-lpignore":"true",onFocus:a=>a.currentTarget.select()}),e.jsx(_.Trigger,{})]}),e.jsx(_.Popover,{children:e.jsx(W,{items:j,className:"max-h-72 overflow-auto",children:a=>e.jsx(G,{id:a.id,textValue:a.name,children:a.name})})}),e.jsx(Y,{className:"text-xs text-[var(--otari-muted)]",children:f})]})}function L(t){if(!t)return"—";const s=new Date(t);return Number.isNaN(s.getTime())?"—":s.toLocaleDateString()}function se(t){if(!t)return null;const s=new Date(t).getTime();if(Number.isNaN(s))return null;const n=Math.round((s-Date.now())/1e3),i=Math.abs(n),c=[["day",86400],["hour",3600],["minute",60]],l=new Intl.RelativeTimeFormat(void 0,{numeric:"auto"});for(const[o,u]of c)if(i>=u)return l.format(Math.round(n/u),o);return l.format(n,"second")}function ne(t){if(!t.expires_at)return!1;const s=new Date(t.expires_at).getTime();return!Number.isNaN(s)&&sString(i).padStart(2,"0");return`${s.getFullYear()}-${n(s.getMonth()+1)}-${n(s.getDate())}T${n(s.getHours())}:${n(s.getMinutes())}`}const ae=t=>(t??"").startsWith("apikey-");function I({label:t,value:s,multiline:n=!1,fieldRef:i}){const c=m.useRef(null),l=i??c,[o,u]=m.useState(!1),[j,p]=m.useState(!1),d=async()=>{var f,a,x;(f=l.current)==null||f.focus(),(a=l.current)==null||a.select();try{if((x=navigator.clipboard)!=null&&x.writeText){await navigator.clipboard.writeText(s),u(!0),p(!1),window.setTimeout(()=>u(!1),2e3);return}}catch{}p(!0)},h="w-full rounded-lg border border-[var(--otari-line)] bg-[var(--otari-bg)] px-3 py-2 font-mono text-xs text-[var(--otari-ink)]";return e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-xs font-medium text-[var(--otari-muted)]",children:t}),e.jsx(g,{size:"sm",variant:"outline",onPress:d,children:o?"Copied":"Copy"})]}),n?e.jsx("textarea",{ref:l,readOnly:!0,rows:s.split(` +import{j as e}from"./tanstack-query-1t81HyiD.js";import{r as m}from"./react-dgEcD0HR.js";import{p as $,q as E,r as z,s as K,P as H,E as T,t as B,u as M,I as V}from"./index-C94BH4OZ.js";import{F as k}from"./Field-HzRk1KDP.js";import{M as O,a as A}from"./ModelScopeControl-CV1Wulbr.js";import{C as _,L as U,I as q,a as W,b as G,D as Y,B as g,f as P,d as C}from"./heroui-BX6JwHY-.js";import{T as J,a as Q,b as v,L as X,c as Z,d as ee,e as y}from"./Table-CLdjdyTx.js";function te({value:t,onChange:s,users:n,description:i}){const c=n.filter(a=>!a.user_id.startsWith("apikey-")).map(a=>({id:a.user_id,name:a.alias?`${a.user_id} (${a.alias})`:a.user_id})),[l,o]=m.useState(t),u=l.trim().toLowerCase(),j=c.filter(a=>!u||a.id.toLowerCase().includes(u)||a.name.toLowerCase().includes(u)).slice(0,50),p=a=>{const x=a.trim(),w=c.find(N=>N.id===x||N.name===x);return w?w.id:x},d=p(l),h=c.some(a=>a.id===d),f=d!==""&&!h?e.jsxs("span",{children:["Creates a new user ",e.jsx("code",{children:d}),"."]}):i??"Spend and budgets track against this user.";return e.jsxs(_.Root,{allowsCustomValue:!0,allowsEmptyCollection:!0,menuTrigger:"focus",inputValue:l,onInputChange:a=>{o(a),s(p(a))},onSelectionChange:a=>{if(a!=null){const x=String(a);o(x),s(x)}},className:"flex max-w-md flex-col gap-1",children:[e.jsx(U,{className:"text-sm font-medium text-[var(--otari-ink)]",children:"Owner"}),e.jsxs(_.InputGroup,{children:[e.jsx(q,{placeholder:"Pick a user, or type a new id…",autoComplete:"off","data-1p-ignore":!0,"data-lpignore":"true",onFocus:a=>a.currentTarget.select()}),e.jsx(_.Trigger,{})]}),e.jsx(_.Popover,{children:e.jsx(W,{items:j,className:"max-h-72 overflow-auto",children:a=>e.jsx(G,{id:a.id,textValue:a.name,children:a.name})})}),e.jsx(Y,{className:"text-xs text-[var(--otari-muted)]",children:f})]})}function L(t){if(!t)return"—";const s=new Date(t);return Number.isNaN(s.getTime())?"—":s.toLocaleDateString()}function se(t){if(!t)return null;const s=new Date(t).getTime();if(Number.isNaN(s))return null;const n=Math.round((s-Date.now())/1e3),i=Math.abs(n),c=[["day",86400],["hour",3600],["minute",60]],l=new Intl.RelativeTimeFormat(void 0,{numeric:"auto"});for(const[o,u]of c)if(i>=u)return l.format(Math.round(n/u),o);return l.format(n,"second")}function ne(t){if(!t.expires_at)return!1;const s=new Date(t.expires_at).getTime();return!Number.isNaN(s)&&sString(i).padStart(2,"0");return`${s.getFullYear()}-${n(s.getMonth()+1)}-${n(s.getDate())}T${n(s.getHours())}:${n(s.getMinutes())}`}const ae=t=>(t??"").startsWith("apikey-");function I({label:t,value:s,multiline:n=!1,fieldRef:i}){const c=m.useRef(null),l=i??c,[o,u]=m.useState(!1),[j,p]=m.useState(!1),d=async()=>{var f,a,x;(f=l.current)==null||f.focus(),(a=l.current)==null||a.select();try{if((x=navigator.clipboard)!=null&&x.writeText){await navigator.clipboard.writeText(s),u(!0),p(!1),window.setTimeout(()=>u(!1),2e3);return}}catch{}p(!0)},h="w-full rounded-lg border border-[var(--otari-line)] bg-[var(--otari-bg)] px-3 py-2 font-mono text-xs text-[var(--otari-ink)]";return e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-xs font-medium text-[var(--otari-muted)]",children:t}),e.jsx(g,{size:"sm",variant:"outline",onPress:d,children:o?"Copied":"Copy"})]}),n?e.jsx("textarea",{ref:l,readOnly:!0,rows:s.split(` `).length,value:s,onFocus:f=>f.currentTarget.select(),className:`${h} resize-none whitespace-pre`}):e.jsx("input",{ref:l,readOnly:!0,value:s,onFocus:f=>f.currentTarget.select(),className:h}),e.jsx("span",{"aria-live":"polite",className:"text-xs text-green-700",children:o?"Copied to clipboard.":""}),j?e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"Selected. Press Ctrl/Cmd-C to copy."}):null]})}function ie({title:t,result:s,onClose:n}){const i=m.useRef(null),c=m.useRef(null),l=typeof window<"u"?window.location.origin:"",o=s.key;m.useEffect(()=>{var d,h;(d=c.current)==null||d.focus(),(h=c.current)==null||h.select()},[]);const u=d=>{var x;if(d.key!=="Tab")return;const h=(x=i.current)==null?void 0:x.querySelectorAll('button, input, textarea, a[href], [tabindex]:not([tabindex="-1"])');if(!h||h.length===0)return;const f=h[0],a=h[h.length-1];d.shiftKey&&document.activeElement===f?(d.preventDefault(),a.focus()):!d.shiftKey&&document.activeElement===a&&(d.preventDefault(),f.focus())},j=[`curl ${l}/v1/chat/completions \\`,` -H "Otari-Key: ${o}" \\`,' -H "Content-Type: application/json" \\',` -d '{"model": "your-model", "messages": [{"role": "user", "content": "Hello"}]}'`].join(` `),p=["from openai import OpenAI","",`client = OpenAI(base_url="${l}/v1", api_key="${o}")`,"resp = client.chat.completions.create(",' model="your-model",',' messages=[{"role": "user", "content": "Hello"}],',")","print(resp.choices[0].message.content)"].join(` `);return e.jsx("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4",role:"presentation",children:e.jsxs("div",{ref:i,role:"dialog","aria-modal":"true","aria-labelledby":"reveal-title",onKeyDown:u,className:"flex max-h-[90vh] w-full max-w-2xl flex-col gap-4 overflow-y-auto rounded-xl bg-[var(--otari-surface)] p-6 shadow-xl",children:[e.jsx("h2",{id:"reveal-title",className:"text-lg font-semibold text-[var(--otari-ink)]",children:t}),e.jsx(V,{tone:"warning",children:"Copy this key now. For security it is shown only once and cannot be retrieved later. If you lose it, use Regenerate to issue a new secret."}),e.jsxs("p",{className:"text-xs text-[var(--otari-muted)]",children:["Model access: ",A(s.allowed_models).text,"."]}),e.jsx(I,{label:"Secret key",value:o,fieldRef:c}),e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-sm font-medium text-[var(--otari-ink)]",children:"Make your first call"}),e.jsxs("p",{className:"text-xs text-[var(--otari-muted)]",children:["Replace ",e.jsx("code",{children:"your-model"})," with a model from the Models page."]})]}),e.jsx(I,{label:"curl",value:j,multiline:!0}),e.jsx(I,{label:"Python (OpenAI SDK)",value:p,multiline:!0})]}),e.jsx("div",{className:"flex justify-end",children:e.jsx(g,{variant:"primary",onPress:n,children:"I’ve saved this key"})})]})})}function R({trigger:t,message:s,confirmLabel:n,isPending:i,onConfirm:c}){const[l,o]=m.useState(!1);return l?e.jsxs("div",{className:"flex flex-col items-end gap-1.5 rounded-lg border border-amber-200 bg-amber-50 p-2 text-right",children:[e.jsx("span",{className:"max-w-xs text-xs text-amber-800",children:s}),e.jsxs("span",{className:"inline-flex gap-1",children:[e.jsx(g,{size:"sm",variant:"danger",isDisabled:i,onPress:c,children:n}),e.jsx(g,{size:"sm",variant:"ghost",isDisabled:i,onPress:()=>o(!1),children:"Cancel"})]})]}):e.jsx(g,{size:"sm",variant:"danger-soft",onPress:()=>o(!0),children:t})}function F({userId:t,users:s}){const n=t.trim();if(n==="")return e.jsx("p",{className:"text-xs text-[var(--otari-muted)]",children:"Choose an owner above to see the models this key can inherit."});const i=s.find(o=>o.user_id===n);if(!i)return e.jsxs("p",{className:"text-xs text-[var(--otari-muted)]",children:["New user ",e.jsx("code",{children:n})," starts unrestricted, so this key may allow any model."]});const{text:c}=A(i.allowed_models),l=i.allowed_models&&i.allowed_models.length>0?i.allowed_models.join(", "):null;return e.jsxs("p",{className:"text-xs text-[var(--otari-muted)]",children:["Owner ",e.jsx("code",{children:n})," allows ",e.jsx("span",{className:"font-medium text-[var(--otari-ink)]",children:c.toLowerCase()}),l?e.jsxs(e.Fragment,{children:[" (",e.jsx("span",{className:"font-mono",children:l}),")"]}):null,". This key inherits that, or narrows within it."]})}function le({onClose:t,onCreated:s}){const n=B(),i=M(),[c,l]=m.useState(""),[o,u]=m.useState(""),[j,p]=m.useState(!1),[d,h]=m.useState(""),[f,a]=m.useState(null),[x,w]=m.useState(!0),N=o!==""&&new Date(o).getTime(){if(n.isPending||!x||r)return;const S={key_name:c.trim()||null,user_id:d.trim(),expires_at:o?new Date(o).toISOString():null,allowed_models:f};n.mutate(S,{onSuccess:D=>{s(D),t()}})};return e.jsx(C,{children:e.jsxs(C.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsx("div",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:"Create API key"}),e.jsx(T,{error:n.error}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsx(k,{label:"Name",value:c,onChange:l,placeholder:"ci-bot",autoFocus:!0,description:"A label to recognize this key later."}),e.jsx(k,{label:"Expires (optional)",value:o,onChange:u,type:"datetime-local",description:N?e.jsx("span",{className:"text-red-700",children:"That time is in the past; the key would be rejected immediately."}):"Leave blank for a key that never expires."})]}),e.jsx(te,{value:d,onChange:h,users:i.data??[]}),e.jsx("button",{type:"button",className:"self-start text-xs font-medium text-[var(--otari-brand-dark)]",onClick:()=>p(S=>!S),children:j?"Hide advanced":"Advanced (restrict models)"}),j?e.jsxs("div",{className:"flex flex-col gap-4 rounded-lg border border-[var(--otari-line)] p-4",children:[e.jsx(F,{userId:d,users:i.data??[]}),e.jsx(O,{title:"Restrict this key's models",description:"By default this key inherits its owner's access. Optionally narrow it to a subset; a key can never exceed its owner's allowed models.",anyLabel:"Inherit owner access",initial:null,onChange:(S,D)=>{a(S),w(D)}})]}):null,e.jsxs("div",{className:"flex gap-2",children:[e.jsx(g,{variant:"primary",isDisabled:n.isPending||!x||r,onPress:b,children:n.isPending?"Creating…":"Create key"}),e.jsx(g,{variant:"ghost",onPress:t,children:"Cancel"})]})]})})}function oe({apiKey:t,onClose:s}){const n=E(),i=M(),[c,l]=m.useState(t.key_name??""),[o,u]=m.useState(re(t.expires_at)),[j,p]=m.useState(t.allowed_models),[d,h]=m.useState(!0),f=()=>{n.isPending||!d||n.mutate({id:t.id,body:{key_name:c.trim()||null,expires_at:o?new Date(o).toISOString():null,allowed_models:j}},{onSuccess:s})};return e.jsx(C,{children:e.jsxs(C.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsxs("div",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:["Edit ",e.jsx("code",{children:t.key_name??t.id})]}),e.jsx(T,{error:n.error}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsx(k,{label:"Name",value:c,onChange:l,placeholder:"ci-bot"}),e.jsx(k,{label:"Expires",value:o,onChange:u,type:"datetime-local",description:"Blank clears the expiry."})]}),t.user_id?e.jsx(F,{userId:t.user_id,users:i.data??[]}):null,e.jsx(O,{title:"Restrict this key's models",description:"This key inherits its owner's access by default. Narrow it to a subset here; it can never exceed the owner's allowed models.",anyLabel:"Inherit owner access",initial:t.allowed_models,onChange:(a,x)=>{p(a),h(x)}}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(g,{variant:"primary",isDisabled:n.isPending||!d,onPress:f,children:n.isPending?"Saving…":"Save changes"}),e.jsx(g,{variant:"ghost",onPress:s,children:"Cancel"})]})]})})}function ce({apiKey:t}){return t.is_active?ne(t)?e.jsx(P,{size:"sm",color:"warning",children:"Expired"}):e.jsx(P,{size:"sm",color:"accent",children:"Active"}):e.jsx(P,{size:"sm",color:"default",children:"Disabled"})}function de({allowed:t}){const{text:s,tone:n}=A(t),i=n==="danger"?"text-red-700 font-medium":n==="muted"?"text-[var(--otari-muted)]":"text-[var(--otari-brand-dark)] font-medium",c=t&&t.length>0?t.join(", "):void 0;return e.jsx("span",{className:`text-xs ${i}`,title:c,children:s})}function ue({onCreate:t}){return e.jsx(C,{children:e.jsxs(C.Content,{className:"flex flex-col gap-4 p-6",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-semibold text-[var(--otari-ink)]",children:"No API keys yet"}),e.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:"An API key authenticates callers to this gateway. Create one to make your first request; the secret is shown once, so keep it somewhere safe."})]}),e.jsx("div",{children:e.jsx(g,{variant:"primary",onPress:t,children:"Create your first key"})})]})})}function ve(){const t=$(),s=E(),n=z(),i=K(),[c,l]=m.useState(!1),[o,u]=m.useState(null),[j,p]=m.useState(null),d=t.data??[],h=t.isLoading,f=d.find(r=>r.id===o)??null,a=!h&&d.length===0&&!c,x=r=>r.key_name??r.id,w=(r,b)=>s.mutate({id:r.id,body:{is_active:b}}),N=r=>n.mutate(r.id,{onSuccess:b=>p({title:`New secret for ${x(r)}`,result:b})});return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(H,{title:"API keys",description:"Issue and revoke the keys that authenticate callers to this gateway. Secrets are shown once at creation.",action:c?null:e.jsx(g,{variant:"primary",onPress:()=>{u(null),l(!0)},children:"Create key"})}),e.jsx(T,{error:t.error??s.error??n.error??i.error}),a?e.jsx(ue,{onCreate:()=>{u(null),l(!0)}}):null,c?e.jsx(le,{onClose:()=>l(!1),onCreated:r=>p({title:"API key created",result:r})}):null,f?e.jsx(oe,{apiKey:f,onClose:()=>u(null)},f.id):null,e.jsxs(J,{children:[e.jsx(Q,{children:e.jsxs("tr",{children:[e.jsx(v,{children:"Name"}),e.jsx(v,{children:"Status"}),e.jsx(v,{children:"Owner"}),e.jsx(v,{children:"Key"}),e.jsx(v,{children:"Created"}),e.jsx(v,{children:"Last used"}),e.jsx(v,{children:"Expires"}),e.jsx(v,{className:"text-right",children:"Actions"})]})}),e.jsx("tbody",{children:h?e.jsx(X,{colSpan:8}):d.length===0?e.jsx(Z,{colSpan:8,children:"No API keys yet. Create one to authenticate a caller."}):d.map(r=>e.jsxs(ee,{selected:o===r.id,onClick:()=>{l(!1),u(r.id)},children:[e.jsx(y,{className:"font-medium text-[var(--otari-ink)]",children:e.jsxs("div",{className:"flex flex-col gap-0.5",children:[e.jsx("span",{children:r.key_name??e.jsx("span",{className:"text-[var(--otari-muted)]",children:"(unnamed)"})}),e.jsx(de,{allowed:r.allowed_models})]})}),e.jsx(y,{children:e.jsx(ce,{apiKey:r})}),e.jsx(y,{className:"text-[var(--otari-muted)]",children:ae(r.user_id)?e.jsx("span",{className:"inline-flex items-center gap-1.5",children:e.jsx(P,{size:"sm",color:"default",children:"virtual"})}):e.jsx("code",{className:"text-xs",children:r.user_id??"—"})}),e.jsx(y,{children:e.jsx("code",{className:"text-xs text-[var(--otari-muted)]",children:r.key_prefix?`${r.key_prefix}…`:"—"})}),e.jsx(y,{className:"text-[var(--otari-muted)]",children:L(r.created_at)}),e.jsx(y,{className:"text-[var(--otari-muted)]",children:se(r.last_used_at)??"never"}),e.jsx(y,{className:"text-[var(--otari-muted)]",children:e.jsx("span",{title:r.expires_at?new Date(r.expires_at).toLocaleString():void 0,children:r.expires_at?L(r.expires_at):"never"})}),e.jsx(y,{children:e.jsxs("div",{className:"flex items-center justify-end gap-1.5",onClick:b=>b.stopPropagation(),children:[r.is_active?e.jsx(g,{size:"sm",variant:"outline",isDisabled:s.isPending,onPress:()=>w(r,!1),children:"Disable"}):e.jsx(g,{size:"sm",variant:"outline",isDisabled:s.isPending,onPress:()=>w(r,!0),children:"Enable"}),e.jsx(g,{size:"sm",variant:"ghost",onPress:()=>{l(!1),u(r.id)},children:"Edit"}),e.jsx(R,{trigger:"Regenerate",confirmLabel:"Regenerate",isPending:n.isPending,message:e.jsxs(e.Fragment,{children:["Regenerate the secret for ",e.jsx("strong",{children:x(r)}),"? The current secret stops working immediately, with no grace period."]}),onConfirm:()=>N(r)}),r.is_active?null:e.jsx(R,{trigger:"Delete",confirmLabel:"Delete permanently",isPending:i.isPending,message:e.jsxs(e.Fragment,{children:["Permanently delete ",e.jsx("strong",{children:x(r)}),"? This removes the key and unlinks its usage history. Cannot be undone."]}),onConfirm:()=>i.mutate(r.id)})]})})]},r.id))})]}),j?e.jsx(ie,{title:j.title,result:j.result,onClose:()=>{p(null),n.reset()}}):null]})}export{ve as KeysPage}; diff --git a/src/gateway/static/dashboard/assets/ModelScopeControl-DiX2Etqz.js b/src/gateway/static/dashboard/assets/ModelScopeControl-CV1Wulbr.js similarity index 98% rename from src/gateway/static/dashboard/assets/ModelScopeControl-DiX2Etqz.js rename to src/gateway/static/dashboard/assets/ModelScopeControl-CV1Wulbr.js index 98e12f81..2effbe3b 100644 --- a/src/gateway/static/dashboard/assets/ModelScopeControl-DiX2Etqz.js +++ b/src/gateway/static/dashboard/assets/ModelScopeControl-CV1Wulbr.js @@ -1 +1 @@ -import{j as t}from"./tanstack-query-1t81HyiD.js";import{r as n}from"./react-dgEcD0HR.js";import{J as A,e as $,f as P}from"./index-BJySXQ_a.js";import{C as d,I as R,a as T,b as V}from"./heroui-BX6JwHY-.js";function q(r){return r===null?"any":r.length===0?"block":"only"}const O=50;function Q({initial:r,onChange:m,title:N="Model access",description:w,anyLabel:C="Any model"}){const x=A(),u=$(),v=P(),[i,S]=n.useState(q(r)),[a,g]=n.useState(r??[]),[p,y]=n.useState(""),f=n.useMemo(()=>{var j,k;const e=new Set,s=[],l=(o,c)=>{o&&!e.has(o)&&(e.add(o),s.push({id:o,label:c}))};for(const o of((j=x.data)==null?void 0:j.providers)??[])l(`${o.instance}:*`,`${o.instance}:* · all ${o.instance} models`);for(const o of((k=u.data)==null?void 0:k.providers)??[])for(const c of o.models)l(c.key,c.key);for(const o of v.data??[])l(o.target,`${o.name} · alias`);return s},[x.data,u.data,v.data]),L=n.useMemo(()=>{const e=p.trim().toLowerCase();return f.filter(s=>!a.includes(s.id)).filter(s=>!e||s.id.toLowerCase().includes(e)||s.label.toLowerCase().includes(e)).slice(0,O)},[f,a,p]),h=(e,s)=>{e==="any"?m(null,!0):e==="block"?m([],!0):m(s,s.length>0)},B=e=>{S(e),h(e,a)},M=e=>{const s=a.includes(e)?a:[...a,e];g(s),y(""),h("only",s)},E=e=>{const s=a.filter(l=>l!==e);g(s),h("only",s)},b=(e,s)=>t.jsx("button",{type:"button","aria-pressed":i===e,onClick:()=>B(e),className:i===e?"rounded-md bg-white px-3 py-1.5 text-sm font-medium text-[var(--otari-ink)] shadow-sm":"rounded-md px-3 py-1.5 text-sm text-[var(--otari-muted)] hover:text-[var(--otari-ink)]",children:s}),I=!u.isLoading&&!x.isLoading&&f.length===0;return t.jsxs("div",{className:"flex flex-col gap-3",children:[t.jsxs("div",{children:[t.jsx("span",{className:"text-sm font-medium text-[var(--otari-ink)]",children:N}),t.jsx("p",{className:"text-xs text-[var(--otari-muted)]",children:w??"Which models this key may list and call. The master key is never restricted, so blocking a key cannot lock you out of the dashboard."})]}),t.jsxs("div",{className:"flex w-fit items-center gap-1 rounded-lg bg-[var(--otari-bg)] p-1",children:[b("any",C),b("only","Only selected"),b("block","Block all")]}),i==="block"?t.jsxs("div",{className:"rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-xs text-amber-800",children:["Blocked from ",t.jsx("strong",{children:"every"})," model until you change this access."]}):null,i==="only"?t.jsxs("div",{className:"flex flex-col gap-2",children:[t.jsx("div",{className:"flex flex-wrap gap-1.5",children:a.length===0?t.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"Pick at least one model below, or choose “Block all”."}):a.map(e=>t.jsxs("span",{className:"inline-flex items-center gap-1 rounded-full bg-[var(--otari-brand-tint)] px-2.5 py-1 font-mono text-xs text-[var(--otari-brand-dark)]",children:[e,t.jsx("button",{type:"button","aria-label":`Remove ${e}`,onClick:()=>E(e),className:"text-[var(--otari-brand-dark)] hover:text-red-700",children:"×"})]},e))}),I?t.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"No providers or models discovered yet. Configure a provider first, then scope this key."}):t.jsxs(d.Root,{allowsEmptyCollection:!0,menuTrigger:"input",inputValue:p,onInputChange:y,selectedKey:null,onSelectionChange:e=>{e!=null&&M(String(e))},className:"flex max-w-md flex-col gap-1",children:[t.jsxs(d.InputGroup,{children:[t.jsx(R,{"aria-label":"Add a model",placeholder:"Search providers, models, aliases…",autoComplete:"off"}),t.jsx(d.Trigger,{})]}),t.jsx(d.Popover,{children:t.jsx(T,{items:L,className:"max-h-72 overflow-auto",children:e=>t.jsx(V,{id:e.id,textValue:e.label,children:e.label})})})]})]}):null]})}function W(r){return r===null?{text:"All models",tone:"muted"}:r.length===0?{text:"No models",tone:"danger"}:{text:"Selected models",tone:"normal"}}export{Q as M,W as a}; +import{j as t}from"./tanstack-query-1t81HyiD.js";import{r as n}from"./react-dgEcD0HR.js";import{J as A,e as $,f as P}from"./index-C94BH4OZ.js";import{C as d,I as R,a as T,b as V}from"./heroui-BX6JwHY-.js";function q(r){return r===null?"any":r.length===0?"block":"only"}const O=50;function Q({initial:r,onChange:m,title:N="Model access",description:w,anyLabel:C="Any model"}){const x=A(),u=$(),v=P(),[i,S]=n.useState(q(r)),[a,g]=n.useState(r??[]),[p,y]=n.useState(""),f=n.useMemo(()=>{var j,k;const e=new Set,s=[],l=(o,c)=>{o&&!e.has(o)&&(e.add(o),s.push({id:o,label:c}))};for(const o of((j=x.data)==null?void 0:j.providers)??[])l(`${o.instance}:*`,`${o.instance}:* · all ${o.instance} models`);for(const o of((k=u.data)==null?void 0:k.providers)??[])for(const c of o.models)l(c.key,c.key);for(const o of v.data??[])l(o.target,`${o.name} · alias`);return s},[x.data,u.data,v.data]),L=n.useMemo(()=>{const e=p.trim().toLowerCase();return f.filter(s=>!a.includes(s.id)).filter(s=>!e||s.id.toLowerCase().includes(e)||s.label.toLowerCase().includes(e)).slice(0,O)},[f,a,p]),h=(e,s)=>{e==="any"?m(null,!0):e==="block"?m([],!0):m(s,s.length>0)},B=e=>{S(e),h(e,a)},M=e=>{const s=a.includes(e)?a:[...a,e];g(s),y(""),h("only",s)},E=e=>{const s=a.filter(l=>l!==e);g(s),h("only",s)},b=(e,s)=>t.jsx("button",{type:"button","aria-pressed":i===e,onClick:()=>B(e),className:i===e?"rounded-md bg-white px-3 py-1.5 text-sm font-medium text-[var(--otari-ink)] shadow-sm":"rounded-md px-3 py-1.5 text-sm text-[var(--otari-muted)] hover:text-[var(--otari-ink)]",children:s}),I=!u.isLoading&&!x.isLoading&&f.length===0;return t.jsxs("div",{className:"flex flex-col gap-3",children:[t.jsxs("div",{children:[t.jsx("span",{className:"text-sm font-medium text-[var(--otari-ink)]",children:N}),t.jsx("p",{className:"text-xs text-[var(--otari-muted)]",children:w??"Which models this key may list and call. The master key is never restricted, so blocking a key cannot lock you out of the dashboard."})]}),t.jsxs("div",{className:"flex w-fit items-center gap-1 rounded-lg bg-[var(--otari-bg)] p-1",children:[b("any",C),b("only","Only selected"),b("block","Block all")]}),i==="block"?t.jsxs("div",{className:"rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-xs text-amber-800",children:["Blocked from ",t.jsx("strong",{children:"every"})," model until you change this access."]}):null,i==="only"?t.jsxs("div",{className:"flex flex-col gap-2",children:[t.jsx("div",{className:"flex flex-wrap gap-1.5",children:a.length===0?t.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"Pick at least one model below, or choose “Block all”."}):a.map(e=>t.jsxs("span",{className:"inline-flex items-center gap-1 rounded-full bg-[var(--otari-brand-tint)] px-2.5 py-1 font-mono text-xs text-[var(--otari-brand-dark)]",children:[e,t.jsx("button",{type:"button","aria-label":`Remove ${e}`,onClick:()=>E(e),className:"text-[var(--otari-brand-dark)] hover:text-red-700",children:"×"})]},e))}),I?t.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"No providers or models discovered yet. Configure a provider first, then scope this key."}):t.jsxs(d.Root,{allowsEmptyCollection:!0,menuTrigger:"input",inputValue:p,onInputChange:y,selectedKey:null,onSelectionChange:e=>{e!=null&&M(String(e))},className:"flex max-w-md flex-col gap-1",children:[t.jsxs(d.InputGroup,{children:[t.jsx(R,{"aria-label":"Add a model",placeholder:"Search providers, models, aliases…",autoComplete:"off"}),t.jsx(d.Trigger,{})]}),t.jsx(d.Popover,{children:t.jsx(T,{items:L,className:"max-h-72 overflow-auto",children:e=>t.jsx(V,{id:e.id,textValue:e.label,children:e.label})})})]})]}):null]})}function W(r){return r===null?{text:"All models",tone:"muted"}:r.length===0?{text:"No models",tone:"danger"}:{text:"Selected models",tone:"normal"}}export{Q as M,W as a}; diff --git a/src/gateway/static/dashboard/assets/ModelsPage-C028BOtV.js b/src/gateway/static/dashboard/assets/ModelsPage-C-ZlmFwf.js similarity index 99% rename from src/gateway/static/dashboard/assets/ModelsPage-C028BOtV.js rename to src/gateway/static/dashboard/assets/ModelsPage-C-ZlmFwf.js index bb337196..617be06f 100644 --- a/src/gateway/static/dashboard/assets/ModelsPage-C028BOtV.js +++ b/src/gateway/static/dashboard/assets/ModelsPage-C-ZlmFwf.js @@ -1 +1 @@ -import{j as e}from"./tanstack-query-1t81HyiD.js";import{i as rt,u as nt,r as c}from"./react-dgEcD0HR.js";import{v as at,w as st,e as lt,x as ct,P as ot,E as ut,F as E,I as dt,y as ne,z as pt,A as ht,B as xt,D as A,G as $e,H as Ee,C as Ae,h as me}from"./index-BJySXQ_a.js";import{T as mt,a as ft,d as Ce,b as re,L as vt,e as U,c as bt}from"./Table-CLdjdyTx.js";import{B as L,d as ke,f as K}from"./heroui-BX6JwHY-.js";function We(t){const i=t.indexOf(":");return i>0?t.slice(0,i):"—"}function gt(t,i=Date.now()){const r=new Map;for(const n of t){const a=r.get(n.model_key)??[];a.push(n),r.set(n.model_key,a)}const s=[];for(const n of r.values()){const a=[...n].sort((h,p)=>Date.parse(h.effective_at)-Date.parse(p.effective_at)),d=[...a].reverse().find(h=>Date.parse(h.effective_at)<=i);s.push(d??a[0])}return s.sort((n,a)=>n.model_key.localeCompare(a.model_key))}const _t="otari",Me=[{value:"vision",label:"Vision",test:t=>Array.isArray(t.input_modalities)&&t.input_modalities.includes("image")},{value:"tool_call",label:"Tool calling",test:t=>!!t.tool_call},{value:"reasoning",label:"Reasoning",test:t=>!!t.reasoning},{value:"structured_output",label:"Structured output",test:t=>!!t.structured_output},{value:"attachment",label:"Attachments",test:t=>!!t.attachment},{value:"audio",label:"Audio",test:t=>Array.isArray(t.input_modalities)&&t.input_modalities.includes("audio")},{value:"pdf",label:"PDF",test:t=>Array.isArray(t.input_modalities)&&t.input_modalities.includes("pdf")}],jt=[{key:"reasoning",label:"Reasoning"},{key:"tool_call",label:"Tool calling"},{key:"structured_output",label:"Structured output"},{key:"attachment",label:"Attachments"},{key:"temperature",label:"Temperature"}],Te={text:"Text",image:"Image",audio:"Audio",video:"Video",pdf:"PDF"},Pt=[{value:"0",label:"Any context"},{value:"8000",label:"≥ 8K"},{value:"32000",label:"≥ 32K"},{value:"128000",label:"≥ 128K"},{value:"200000",label:"≥ 200K"},{value:"1000000",label:"≥ 1M"}],yt=[{value:"",label:"Any price"},{value:"1",label:"≤ $1 / 1M in"},{value:"3",label:"≤ $3 / 1M in"},{value:"10",label:"≤ $10 / 1M in"},{value:"30",label:"≤ $30 / 1M in"}],Nt=[{value:"",label:"Base prices"},{value:"8000",label:"Compare at 8K"},{value:"128000",label:"Compare at 128K"},{value:"200000",label:"Compare at 200K"},{value:"500000",label:"Compare at 500K"},{value:"1000000",label:"Compare at 1M"}],St=[{value:"all",label:"Any release date"},{value:"365",label:"Past year"},{value:"730",label:"Past 2 years"},{value:"1095",label:"Past 3 years"}],Ct=1440*60*1e3;function Ie(t,i){const r=`${i}:`;return t.startsWith(r)?t.slice(r.length):t}function kt(t,i){const r={inputPrice:t.inputPrice,outputPrice:t.outputPrice,cacheReadPrice:t.cacheReadPrice,cacheWritePrice:t.cacheWritePrice,cacheWrite1hPrice:t.cacheWrite1hPrice};if(i==null)return r;const s=t.pricingTiers.filter(n=>n.min_input_tokens<=i).sort((n,a)=>a.min_input_tokens-n.min_input_tokens)[0];return s?{inputPrice:s.input_price_per_million??r.inputPrice,outputPrice:s.output_price_per_million??r.outputPrice,cacheReadPrice:s.cache_read_price_per_million??r.cacheReadPrice,cacheWritePrice:s.cache_write_price_per_million??r.cacheWritePrice,cacheWrite1hPrice:s.cache_write_1h_price_per_million??r.cacheWrite1hPrice}:r}function ae(t){const i=Number(t);return t.trim()!==""&&Number.isFinite(i)&&i>=0}function R(t){if(t.trim()==="")return!0;const i=Number(t);return Number.isFinite(i)&&i>=0}function V(t){return t.trim()===""?null:Number(t)}function De(t){return t.map((i,r)=>({id:r,minInputTokens:String(i.min_input_tokens),input:i.input_price_per_million==null?"":String(i.input_price_per_million),output:i.output_price_per_million==null?"":String(i.output_price_per_million),cacheRead:i.cache_read_price_per_million==null?"":String(i.cache_read_price_per_million),cacheWrite:i.cache_write_price_per_million==null?"":String(i.cache_write_price_per_million),cacheWrite1h:i.cache_write_1h_price_per_million==null?"":String(i.cache_write_1h_price_per_million)}))}function Oe(t){const i=new Set;return t.every(r=>{const s=Number(r.minInputTokens),n=[r.input,r.output,r.cacheRead,r.cacheWrite,r.cacheWrite1h].some(a=>a.trim()!=="");return!Number.isInteger(s)||s<=0||i.has(s)||!n?!1:(i.add(s),[r.input,r.output,r.cacheRead,r.cacheWrite,r.cacheWrite1h].every(R))})}function Fe(t){return t.map(i=>({min_input_tokens:Number(i.minInputTokens),...i.input.trim()===""?{}:{input_price_per_million:Number(i.input)},...i.output.trim()===""?{}:{output_price_per_million:Number(i.output)},...i.cacheRead.trim()===""?{}:{cache_read_price_per_million:Number(i.cacheRead)},...i.cacheWrite.trim()===""?{}:{cache_write_price_per_million:Number(i.cacheWrite)},...i.cacheWrite1h.trim()===""?{}:{cache_write_1h_price_per_million:Number(i.cacheWrite1h)}}))}function j({value:t,onChange:i,ariaLabel:r}){return e.jsx("input",{type:"number",step:"any",min:"0",inputMode:"decimal","aria-label":r,value:t,onChange:s=>i(s.target.value),className:"w-28 rounded-md border border-[var(--otari-line)] bg-white px-2 py-1 text-right text-sm tabular-nums focus:border-[var(--otari-brand)] focus:outline-none"})}function ze({tiers:t,onChange:i}){const r=(n,a,d)=>{i(t.map(h=>h.id===n?{...h,[a]:d}:h))},s=()=>{const n=t.reduce((a,d)=>Math.max(a,d.id),-1)+1;i([...t,{id:n,minInputTokens:"128000",input:"",output:"",cacheRead:"",cacheWrite:"",cacheWrite1h:""}])};return e.jsxs("div",{className:"flex flex-col gap-2 rounded-lg border border-[var(--otari-line)] p-3",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-xs font-medium text-[var(--otari-ink)]",children:"Long-context price tiers"}),e.jsx("p",{className:"text-xs text-[var(--otari-muted)]",children:"At a threshold, listed rates replace the base rate for the whole request."})]}),e.jsx(L,{size:"sm",variant:"outline",onPress:s,children:"Add tier"})]}),t.map(n=>e.jsxs("div",{className:"flex flex-wrap items-end gap-2 border-t border-[var(--otari-line)] pt-2",children:[e.jsxs("label",{className:"flex flex-col gap-1 text-xs text-[var(--otari-muted)]",children:["Context ≥ tokens",e.jsx("input",{type:"number",min:"1",step:"1",inputMode:"numeric","aria-label":"Tier context threshold",value:n.minInputTokens,onChange:a=>r(n.id,"minInputTokens",a.target.value),className:"w-28 rounded-md border border-[var(--otari-line)] bg-white px-2 py-1 text-right text-sm tabular-nums focus:border-[var(--otari-brand)] focus:outline-none"})]}),e.jsxs("label",{className:"flex flex-col gap-1 text-xs text-[var(--otari-muted)]",children:["Input",e.jsx(j,{value:n.input,onChange:a=>r(n.id,"input",a),ariaLabel:"Tier input price"})]}),e.jsxs("label",{className:"flex flex-col gap-1 text-xs text-[var(--otari-muted)]",children:["Output",e.jsx(j,{value:n.output,onChange:a=>r(n.id,"output",a),ariaLabel:"Tier output price"})]}),e.jsxs("label",{className:"flex flex-col gap-1 text-xs text-[var(--otari-muted)]",children:["Cache read",e.jsx(j,{value:n.cacheRead,onChange:a=>r(n.id,"cacheRead",a),ariaLabel:"Tier cache read price"})]}),e.jsxs("label",{className:"flex flex-col gap-1 text-xs text-[var(--otari-muted)]",children:["Cache write",e.jsx(j,{value:n.cacheWrite,onChange:a=>r(n.id,"cacheWrite",a),ariaLabel:"Tier cache write price"})]}),e.jsxs("label",{className:"flex flex-col gap-1 text-xs text-[var(--otari-muted)]",children:["1h write",e.jsx(j,{value:n.cacheWrite1h,onChange:a=>r(n.id,"cacheWrite1h",a),ariaLabel:"Tier 1 hour cache write price"})]}),e.jsx(L,{size:"sm",variant:"ghost",onPress:()=>i(t.filter(a=>a.id!==n.id)),children:"Remove"})]},n.id))]})}function Wt({source:t}){return t==="configured"?e.jsx(K,{size:"sm",color:"default",children:"configured"}):t==="default"||t==="alias"?e.jsx(K,{size:"sm",color:"accent",children:t}):e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"not priced"})}function se({label:t,tone:i="info",children:r}){const s=c.useId();return e.jsxs("span",{className:"group relative inline-flex items-center font-normal normal-case",children:[e.jsx("button",{type:"button","aria-label":t,"aria-describedby":s,className:`inline-flex h-4 w-4 items-center justify-center rounded-full border text-[10px] leading-none ${i==="warning"?"border-[#c2843a] text-[#b45309]":"border-[var(--otari-line)] text-[var(--otari-muted)] hover:border-[var(--otari-brand)] hover:text-[var(--otari-brand)]"}`,children:"i"}),e.jsx("span",{id:s,role:"tooltip",className:"pointer-events-none absolute top-full right-0 z-20 mt-1.5 w-72 rounded-lg border border-[var(--otari-line)] bg-[var(--otari-surface)] px-3 py-2 text-left text-xs font-normal whitespace-normal break-words text-[var(--otari-ink)] opacity-0 shadow-lg transition-opacity group-hover:opacity-100 group-focus-within:opacity-100",children:r})]})}function Mt(){const t=xt();return t.data?t.data.default_pricing?e.jsx(se,{label:"How unpriced models are metered",tone:"info",children:"Default pricing is on: models without a configured price are metered using community-maintained rates (the bundled genai-prices dataset). Set a price to override the fallback."}):e.jsxs(se,{label:"How unpriced models are metered",tone:"warning",children:["Default pricing is off: only models with a configured price are metered.",t.data.require_pricing?" Requests for any other model are rejected (HTTP 402) because require_pricing is on.":" Other models are served without cost tracking."]}):null}function T({label:t,value:i}){return e.jsxs("div",{className:"flex items-baseline justify-between gap-3",children:[e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:t}),e.jsx("span",{className:"text-right text-sm text-[var(--otari-ink)] tabular-nums",children:i})]})}function ie({title:t,children:i}){return e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsx("span",{className:"text-xs font-semibold uppercase tracking-wide text-[var(--otari-muted)]",children:t}),i]})}function Tt({row:t}){const i=$e(),r=Ee(),[s,n]=c.useState(!1),[a,d]=c.useState(""),[h,p]=c.useState(""),[v,P]=c.useState(""),[m,S]=c.useState(""),[k,W]=c.useState(""),[D,y]=c.useState([]),Y=()=>{d(t.inputPrice==null?"":String(t.inputPrice)),p(t.outputPrice==null?"":String(t.outputPrice)),P(t.cacheReadPrice==null?"":String(t.cacheReadPrice)),S(t.cacheWritePrice==null?"":String(t.cacheWritePrice)),W(t.cacheWrite1hPrice==null?"":String(t.cacheWrite1hPrice)),y(De(t.pricingTiers)),n(!0)},M=ae(a)&&ae(h)&&R(v)&&R(m)&&R(k)&&Oe(D),G=()=>{M&&i.mutate({model_key:t.key,input_price_per_million:Number(a),output_price_per_million:Number(h),cache_read_price_per_million:V(v),cache_write_price_per_million:V(m),cache_write_1h_price_per_million:V(k),pricing_tiers:Fe(D)},{onSuccess:()=>n(!1)})};return s?e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"Input $ / 1M"}),e.jsx(j,{value:a,onChange:d,ariaLabel:`Input price for ${t.key}`})]}),e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"Output $ / 1M"}),e.jsx(j,{value:h,onChange:p,ariaLabel:`Output price for ${t.key}`})]}),e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"Cache read $ / 1M"}),e.jsx(j,{value:v,onChange:P,ariaLabel:`Cache read price for ${t.key}`})]}),e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"Cache write $ / 1M"}),e.jsx(j,{value:m,onChange:S,ariaLabel:`Cache write price for ${t.key}`})]}),e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"1h cache write $ / 1M"}),e.jsx(j,{value:k,onChange:W,ariaLabel:`1 hour cache write price for ${t.key}`})]}),e.jsx(ze,{tiers:D,onChange:y}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(L,{size:"sm",variant:"primary",isDisabled:i.isPending||!M,onPress:G,children:"Save"}),e.jsx(L,{size:"sm",variant:"ghost",isDisabled:i.isPending,onPress:()=>n(!1),children:"Cancel"})]}),i.error?e.jsx("span",{className:"text-xs text-red-700",children:me(i.error)}):null]}):e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsx(T,{label:"Input",value:t.inputPrice==null?"—":`${A(t.inputPrice)} / 1M`}),e.jsx(T,{label:"Output",value:t.outputPrice==null?"—":`${A(t.outputPrice)} / 1M`}),e.jsx(T,{label:"Cache read",value:t.cacheReadPrice==null?"—":`${A(t.cacheReadPrice)} / 1M`}),e.jsx(T,{label:"Cache write",value:t.cacheWritePrice==null?"—":`${A(t.cacheWritePrice)} / 1M`}),e.jsx(T,{label:"1h cache write",value:t.cacheWrite1hPrice==null?"—":`${A(t.cacheWrite1hPrice)} / 1M`}),e.jsx(T,{label:"Context tiers",value:t.pricingTiers.length?`${t.pricingTiers.length} configured`:"—"}),e.jsxs("div",{className:"flex items-center gap-2 pt-1",children:[e.jsx(L,{size:"sm",variant:"outline",onPress:Y,children:t.source==="configured"?"Edit price":"Set price"}),t.source==="configured"?e.jsxs(e.Fragment,{children:[e.jsx(Ae,{confirmLabel:"Reset",isPending:r.isPending,onConfirm:()=>r.mutate(t.key),children:"Reset"}),e.jsx(se,{label:"What reset does",children:"Removes the custom price. The model reverts to the default rate (genai-prices) when default pricing is on, otherwise it is metered at no cost."})]}):null,r.error?e.jsx("span",{className:"text-xs text-red-700",children:me(r.error)}):null]})]})}function It({row:t,metadata:i,metadataAvailable:r,onMakeAlias:s,onClose:n}){const a=(i==null?void 0:i.input_modalities)??[],d=(i==null?void 0:i.output_modalities)??[],h=jt.filter(({key:p})=>i==null?void 0:i[p]);return e.jsx(ke,{children:e.jsxs(ke.Content,{className:"flex flex-col gap-5 p-5",children:[e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("h2",{className:"text-base font-semibold break-all text-[var(--otari-ink)]",children:t.model}),i!=null&&i.deprecated?e.jsx(K,{size:"sm",color:"danger",children:"deprecated"}):null]}),e.jsxs("p",{className:"mt-1 text-xs break-all text-[var(--otari-muted)]",children:["Selector: ",e.jsx("code",{children:t.key})]}),i!=null&&i.family?e.jsx("p",{className:"text-xs text-[var(--otari-muted)]",children:i.family}):null]}),e.jsx("button",{type:"button","aria-label":"Close model details",onClick:n,className:"-mt-1 -mr-1 shrink-0 rounded-md px-1.5 py-0.5 text-lg leading-none text-[var(--otari-muted)] hover:bg-[var(--otari-bg)] hover:text-[var(--otari-ink)]",children:"✕"})]}),i!=null&&i.description?e.jsx("p",{className:"text-sm text-[var(--otari-ink)]",children:i.description}):null,e.jsxs(ie,{title:"Pricing",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Wt,{source:t.source}),t.isDiscovered?null:e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"not discovered"})]}),e.jsx(Tt,{row:t},t.key),e.jsx(L,{size:"sm",variant:"outline",onPress:()=>s(t.key),children:"Make an alias"})]}),e.jsxs(ie,{title:"Specs",children:[e.jsx(T,{label:"Context window",value:ne(t.contextWindow)}),e.jsx(T,{label:"Max output",value:ne((i==null?void 0:i.max_output_tokens)??null)}),e.jsx(T,{label:"Knowledge cutoff",value:(i==null?void 0:i.knowledge_cutoff)??"—"}),e.jsx(T,{label:"Released",value:ht(i==null?void 0:i.release_date)}),e.jsx(T,{label:"Open weights",value:i?i.open_weights?"Yes":"No":"—"})]}),e.jsx(ie,{title:"Modalities",children:a.length===0&&d.length===0?e.jsx("span",{className:"text-sm text-[var(--otari-muted)]",children:"Unknown."}):e.jsxs("div",{className:"flex flex-col gap-1.5 text-xs text-[var(--otari-muted)]",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-1",children:[e.jsx("span",{children:"In:"}),a.map(p=>e.jsx(K,{size:"sm",color:"default",children:Te[p]??p},p))]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-1",children:[e.jsx("span",{children:"Out:"}),d.map(p=>e.jsx(K,{size:"sm",color:"default",children:Te[p]??p},p))]})]})}),e.jsx(ie,{title:"Capabilities",children:h.length>0?e.jsx("div",{className:"flex flex-wrap gap-1.5",children:h.map(({key:p,label:v})=>e.jsx(K,{size:"sm",color:"default",children:v},p))}):e.jsx("span",{className:"text-sm text-[var(--otari-muted)]",children:r?"None reported.":"Extended metadata unavailable (models.dev disabled or unreachable)."})})]})})}const Lt=15,$t=[{value:"15",label:"15 per page"},{value:"25",label:"25 per page"},{value:"50",label:"50 per page"}];function Et({value:t,onChange:i,placeholder:r}){return e.jsx("input",{type:"search",value:t,onChange:s=>i(s.target.value),placeholder:r,"aria-label":r,className:"w-full max-w-xs rounded-md border border-[var(--otari-line)] bg-white px-3 py-1.5 text-sm focus:border-[var(--otari-brand)] focus:outline-none"})}function At({page:t,pageCount:i,total:r,pageSize:s,onPage:n,onPageSize:a}){return e.jsxs("div",{className:"flex items-center justify-between px-1 pt-1 text-sm text-[var(--otari-muted)]",children:[e.jsxs("span",{children:[i>1?`Page ${t+1} of ${i} · `:"",pt(r)," model",r===1?"":"s"]}),e.jsxs("span",{className:"inline-flex gap-2",children:[e.jsx(E,{ariaLabel:"Rows per page",value:String(s),onChange:d=>a(Number(d)),options:$t}),i>1?e.jsxs(e.Fragment,{children:[e.jsx(L,{size:"sm",variant:"outline",isDisabled:t===0,onPress:()=>n(t-1),children:"Prev"}),e.jsx(L,{size:"sm",variant:"outline",isDisabled:t>=i-1,onPress:()=>n(t+1),children:"Next"})]}):null]})]})}const Be="otari.dashboard.modelsSort",xe={col:"model",dir:"asc"},Dt=["model","released","input","output"];function Ot(){if(typeof window>"u")return xe;try{const t=window.localStorage.getItem(Be);if(!t)return xe;const i=JSON.parse(t);if(Dt.includes(i.col)&&(i.dir==="asc"||i.dir==="desc"))return{col:i.col,dir:i.dir}}catch{}return xe}function Le({label:t,col:i,sort:r,onSort:s,align:n="left",info:a}){const d=r.col===i;return e.jsx(re,{className:n==="right"?"text-right":void 0,ariaSort:d?r.dir==="asc"?"ascending":"descending":"none",children:e.jsxs("span",{className:`inline-flex items-center gap-1.5 ${n==="right"?"flex-row-reverse":""}`,children:[e.jsxs("button",{type:"button",onClick:()=>s(i),className:`inline-flex items-center gap-1 ${n==="right"?"flex-row-reverse":""} hover:text-[var(--otari-ink)]`,children:[t,e.jsx("span",{className:"text-[10px] text-[var(--otari-muted)]",children:d?r.dir==="asc"?"▲":"▼":"↕"})]}),a]})})}function Ft({row:t,onClose:i}){const r=$e(),s=Ee(),[n,a]=c.useState(t.inputPrice==null?"":String(t.inputPrice)),[d,h]=c.useState(t.outputPrice==null?"":String(t.outputPrice)),[p,v]=c.useState(t.cacheReadPrice==null?"":String(t.cacheReadPrice)),[P,m]=c.useState(t.cacheWritePrice==null?"":String(t.cacheWritePrice)),[S,k]=c.useState(t.cacheWrite1hPrice==null?"":String(t.cacheWrite1hPrice)),[W,D]=c.useState(De(t.pricingTiers)),y=ae(n)&&ae(d)&&R(p)&&R(P)&&R(S)&&Oe(W),Y=()=>{y&&r.mutate({model_key:t.key,input_price_per_million:Number(n),output_price_per_million:Number(d),cache_read_price_per_million:V(p),cache_write_price_per_million:V(P),cache_write_1h_price_per_million:V(S),pricing_tiers:Fe(W)},{onSuccess:i})};return e.jsxs("div",{className:"flex flex-col gap-3 px-4 py-3",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsx("span",{className:"text-xs font-medium break-all text-[var(--otari-muted)]",children:t.key}),e.jsxs("label",{className:"flex items-center gap-1.5 text-xs text-[var(--otari-muted)]",children:["Input $ / 1M",e.jsx(j,{value:n,onChange:a,ariaLabel:`Input price for ${t.key}`})]}),e.jsxs("label",{className:"flex items-center gap-1.5 text-xs text-[var(--otari-muted)]",children:["Output $ / 1M",e.jsx(j,{value:d,onChange:h,ariaLabel:`Output price for ${t.key}`})]}),e.jsxs("label",{className:"flex items-center gap-1.5 text-xs text-[var(--otari-muted)]",children:["Cache read $ / 1M",e.jsx(j,{value:p,onChange:v,ariaLabel:`Cache read price for ${t.key}`})]}),e.jsxs("label",{className:"flex items-center gap-1.5 text-xs text-[var(--otari-muted)]",children:["Cache write $ / 1M",e.jsx(j,{value:P,onChange:m,ariaLabel:`Cache write price for ${t.key}`})]}),e.jsxs("label",{className:"flex items-center gap-1.5 text-xs text-[var(--otari-muted)]",children:["1h cache write $ / 1M",e.jsx(j,{value:S,onChange:k,ariaLabel:`1 hour cache write price for ${t.key}`})]}),e.jsx(L,{size:"sm",variant:"primary",isDisabled:r.isPending||!y,onPress:Y,children:r.isPending?"Saving…":"Save"}),e.jsx(L,{size:"sm",variant:"ghost",isDisabled:r.isPending,onPress:i,children:"Cancel"}),t.source==="configured"?e.jsxs("span",{className:"inline-flex items-center gap-1",children:[e.jsx(Ae,{confirmLabel:"Reset",isPending:s.isPending,onConfirm:()=>s.mutate(t.key,{onSuccess:i}),children:"Reset"}),e.jsx(se,{label:"What reset does",children:"Removes the custom price. The model reverts to the default rate (genai-prices) when default pricing is on, otherwise it is metered at no cost."})]}):null,r.error||s.error?e.jsx("span",{className:"text-xs text-red-700",children:me(r.error??s.error)}):null]}),e.jsx(ze,{tiers:W,onChange:D})]})}function zt({primary:t,secondary:i,rowKey:r,primaryLabel:s,secondaryLabel:n,onEdit:a}){const d=(h,p)=>e.jsx("button",{type:"button","aria-label":`Edit ${p} price for ${r}`,className:"tabular-nums hover:text-[var(--otari-brand-dark)] hover:underline",onClick:v=>{v.stopPropagation(),a()},children:h==null?"—":A(h)});return e.jsxs("span",{className:"inline-flex items-center justify-end gap-1",children:[d(t,s),e.jsx("span",{className:"text-[var(--otari-muted)]",children:"/"}),d(i,n)]})}function Bt({rates:t,rowKey:i,onEdit:r}){const s=[t.cacheReadPrice==null?null:`R ${A(t.cacheReadPrice)}`,t.cacheWritePrice==null?null:`W ${A(t.cacheWritePrice)}`,t.cacheWrite1hPrice==null?null:`1h ${A(t.cacheWrite1hPrice)}`].filter(n=>n!==null);return e.jsx("button",{type:"button","aria-label":`Edit caching price for ${i}`,className:"max-w-44 text-right text-xs leading-5 text-[var(--otari-muted)] hover:text-[var(--otari-brand-dark)] hover:underline",onClick:n=>{n.stopPropagation(),r()},children:s.length>0?s.join(" · "):"Input-rate fallback"})}function Rt({row:t,onEdit:i}){const r=[...t.pricingTiers].sort((n,a)=>n.min_input_tokens-a.min_input_tokens).map(n=>ne(n.min_input_tokens)),s=r.length===0?"Base only":`${r.length} tier${r.length===1?"":"s"} · ≥ ${r.join(", ")}`;return e.jsx("button",{type:"button","aria-label":`Edit pricing policy for ${t.key}`,className:"max-w-40 text-right text-xs leading-5 text-[var(--otari-muted)] hover:text-[var(--otari-brand-dark)] hover:underline",onClick:n=>{n.stopPropagation(),i()},children:s})}function Kt({rows:t,isLoading:i,empty:r,sort:s,onSort:n,selectedKey:a,onSelect:d,pricingKey:h,onSetPricingKey:p,comparisonContextTokens:v}){const P=v==null?"Base":`at ${ne(v)}`;return e.jsxs(mt,{children:[e.jsx(ft,{children:e.jsxs(Ce,{children:[e.jsx(Le,{label:"Model",col:"model",sort:s,onSort:n}),e.jsx(re,{children:"Provider"}),e.jsx(Le,{label:`${P} in / out $ / 1M`,col:"input",sort:s,onSort:n,align:"right",info:e.jsx(Mt,{})}),e.jsxs(re,{className:"text-right",children:["Caching ",v==null?"policy":P]}),e.jsx(re,{className:"text-right",children:"Pricing policy"})]})}),e.jsx("tbody",{children:i?e.jsx(vt,{colSpan:5}):t.length>0?t.map(m=>{const S=()=>p(h===m.key?null:m.key),k=kt(m,v);return e.jsxs(c.Fragment,{children:[e.jsxs(Ce,{onClick:()=>d(m.key),selected:m.key===a,children:[e.jsxs(U,{className:"font-medium break-all",children:[m.model,e.jsx("span",{className:"sr-only",children:m.key})]}),e.jsx(U,{className:"text-[var(--otari-muted)]",children:m.provider}),e.jsx(U,{className:"text-right",children:e.jsx(zt,{primary:k.inputPrice,secondary:k.outputPrice,rowKey:m.key,primaryLabel:"input",secondaryLabel:"output",onEdit:S})}),e.jsx(U,{className:"text-right",children:e.jsx(Bt,{rates:k,rowKey:m.key,onEdit:S})}),e.jsx(U,{className:"text-right",children:e.jsx(Rt,{row:m,onEdit:S})})]}),h===m.key?e.jsx("tr",{className:"border-b border-[var(--otari-line)] bg-[var(--otari-bg)] last:border-b-0",children:e.jsx("td",{colSpan:5,children:e.jsx(Ft,{row:m,onClose:()=>p(null)})})}):null]},m.key)}):e.jsx(bt,{colSpan:5,children:r})})]})}function Vt({providers:t}){return t.length===0?null:e.jsxs(dt,{tone:"warning",children:["Could not list ",t.map(i=>i.provider).join(", "),". Check that provider's credentials in config.yml; its models are missing from the list below."]})}function Jt(){var je,Pe,ye;const t=rt(),[i]=nt(),r=at(),s=st(),n=lt(),a=ct(),[d,h]=c.useState(""),[p,v]=c.useState(0),[P,m]=c.useState(Lt),[S,k]=c.useState(null),[W,D]=c.useState(null),[y,Y]=c.useState(Ot);c.useEffect(()=>{try{window.localStorage.setItem(Be,JSON.stringify(y))}catch{}},[y]);const[M,G]=c.useState(i.get("provider")||"all"),[F,Re]=c.useState("all"),[H,Ke]=c.useState("all"),[q,Ve]=c.useState("all"),[le,Ye]=c.useState("0"),[J,He]=c.useState(""),[Z,qe]=c.useState("all"),[ce,we]=c.useState(""),O=((je=a.data)==null?void 0:je.models)??{},Ue=((Pe=a.data)==null?void 0:Pe.available)??!1,fe=c.useMemo(()=>{var l;return new Set((((l=n.data)==null?void 0:l.providers)??[]).flatMap(f=>f.models.map(o=>o.key)))},[n.data]),Ge=l=>{h(l),v(0)},z=l=>f=>{l(f),v(0)},Je=l=>{Y(f=>f.col===l?{col:l,dir:f.dir==="asc"?"desc":"asc"}:{col:l,dir:l==="released"?"desc":"asc"}),v(0)},X=c.useMemo(()=>{var C,g,_,$,I,B,Ne;const l=new Map(gt(s.data??[]).map(u=>[u.model_key,u])),f=[],o=new Set,b=(u,he,Se,x)=>{if(o.has(u))return;o.add(u);const N=l.get(u);f.push({key:u,model:Ie(he,Se),provider:Se,isDiscovered:fe.has(u),contextWindow:(x==null?void 0:x.contextWindow)??null,inputPrice:N?N.input_price_per_million:(x==null?void 0:x.inputPrice)??null,outputPrice:N?N.output_price_per_million:(x==null?void 0:x.outputPrice)??null,cacheReadPrice:N?N.cache_read_price_per_million:(x==null?void 0:x.cacheReadPrice)??null,cacheWritePrice:N?N.cache_write_price_per_million:(x==null?void 0:x.cacheWritePrice)??null,cacheWrite1hPrice:N?N.cache_write_1h_price_per_million??null:(x==null?void 0:x.cacheWrite1hPrice)??null,pricingTiers:N?N.pricing_tiers??[]:(x==null?void 0:x.pricingTiers)??[],source:N?"configured":(x==null?void 0:x.source)??"none"})};for(const u of((C=r.data)==null?void 0:C.data)??[]){if(u.owned_by===_t)continue;const he=u.pricing_source==="default"?"default":u.pricing?"configured":"none";b(u.id,u.id,u.owned_by||We(u.id),{key:u.id,model:u.id,provider:u.owned_by,contextWindow:u.context_window,inputPrice:((g=u.pricing)==null?void 0:g.input_price_per_million)??null,outputPrice:((_=u.pricing)==null?void 0:_.output_price_per_million)??null,cacheReadPrice:(($=u.pricing)==null?void 0:$.cache_read_price_per_million)??null,cacheWritePrice:((I=u.pricing)==null?void 0:I.cache_write_price_per_million)??null,cacheWrite1hPrice:((B=u.pricing)==null?void 0:B.cache_write_1h_price_per_million)??null,pricingTiers:((Ne=u.pricing)==null?void 0:Ne.pricing_tiers)??[],source:he})}for(const u of l.keys())b(u,u,We(u));return f},[r.data,s.data,fe]),Ze=c.useMemo(()=>new Map(X.map(l=>[l.key,l])),[X]),Q=c.useMemo(()=>{var o,b,C;const l=X.map(g=>{var _,$;return{...g,contextWindow:g.contextWindow??((_=O[g.key])==null?void 0:_.context_window)??null,releaseDate:(($=O[g.key])==null?void 0:$.release_date)??null}}),f=new Set(l.map(g=>g.key));for(const g of((o=n.data)==null?void 0:o.providers)??[])for(const _ of g.models)f.has(_.key)||(f.add(_.key),l.push({key:_.key,model:Ie(_.key,g.provider),provider:g.provider,isDiscovered:!0,contextWindow:((b=O[_.key])==null?void 0:b.context_window)??null,releaseDate:((C=O[_.key])==null?void 0:C.release_date)??null,inputPrice:null,outputPrice:null,cacheReadPrice:null,cacheWritePrice:null,cacheWrite1hPrice:null,pricingTiers:[],source:"none"}));return l},[X,n.data,O]),Xe=(((ye=n.data)==null?void 0:ye.providers)??[]).filter(l=>!l.ok),ee=c.useMemo(()=>{const l=Array.from(new Set(Q.map(f=>f.provider))).sort((f,o)=>f.localeCompare(o));return[{value:"all",label:"All providers"},...l.map(f=>({value:f,label:f}))]},[Q]);c.useEffect(()=>{M==="all"||ee.length<=1||ee.some(l=>l.value===M)||G("all")},[ee,M]);const w=d.trim().toLowerCase(),oe=Number(le)||0,ue=J===""?Number.POSITIVE_INFINITY:Number(J),Qe=ce===""?null:Number(ce),de=Z==="all"?null:Date.now()-Number(Z)*Ct,pe=c.useMemo(()=>{const l=o=>{if(w&&!o.key.toLowerCase().includes(w)&&!o.provider.toLowerCase().includes(w)||M!=="all"&&o.provider!==M||F==="configured"&&o.source!=="configured"||F==="default"&&o.source!=="default"||F==="priced"&&o.inputPrice==null||F==="unpriced"&&o.inputPrice!=null||H==="discovered"&&!o.isDiscovered||H==="custom"&&o.isDiscovered)return!1;if(q!=="all"){const b=Me.find(g=>g.value===q),C=O[o.key];if(!b||!C||!b.test(C))return!1}if(oe>0&&(o.contextWindow==null||o.contextWindowue))return!1;if(de!=null){const b=o.releaseDate?Date.parse(o.releaseDate):Number.NaN;if(Number.isNaN(b)||b{const C=y.dir==="asc"?1:-1;if(y.col==="model")return o.model.localeCompare(b.model)*C;if(y.col==="released"){const I=o.releaseDate??null,B=b.releaseDate??null;return!I&&!B?o.model.localeCompare(b.model):I?B?(IB?1:0)*C||o.model.localeCompare(b.model):-1:1}const g=I=>y.col==="input"?I.inputPrice:I.outputPrice,_=g(o),$=g(b);return _==null&&$==null?o.model.localeCompare(b.model):_==null?1:$==null?-1:(_-$)*C||o.model.localeCompare(b.model)};return Q.filter(l).sort(f)},[Q,w,M,F,H,q,oe,ue,de,O,y]),ve=pe.length,be=Math.max(1,Math.ceil(ve/P)),ge=Math.min(p,be-1),_e=ge*P,et=pe.slice(_e,_e+P),tt=r.isLoading||s.isLoading||n.isLoading,it=w!==""||M!=="all"||F!=="all"||H!=="all"||q!=="all"||le!=="0"||J!==""||Z!=="all"?"No models match your filters.":"No models yet. Add a provider on the Providers page, or price a model below.",te=W?pe.find(l=>l.key===W)??Ze.get(W)??null:null;return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(ot,{title:"Models",description:"Every model your providers can serve. Set a price on any model so budgets and usage tracking work."}),e.jsx(ut,{error:r.error??s.error??n.error??a.error}),e.jsxs("div",{className:`grid gap-4 lg:items-start ${te?"lg:grid-cols-[minmax(0,1fr)_360px]":"grid-cols-1"}`,children:[e.jsxs("div",{className:"flex min-w-0 flex-col gap-3",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx(Et,{value:d,onChange:Ge,placeholder:"Search models…"}),e.jsx(E,{ariaLabel:"Filter by provider",value:M,onChange:z(G),options:ee}),e.jsx(E,{ariaLabel:"Filter by pricing",value:F,onChange:z(Re),options:[{value:"all",label:"Any pricing"},{value:"configured",label:"Custom price"},{value:"default",label:"Default price"},{value:"priced",label:"Priced"},{value:"unpriced",label:"Unpriced"}]}),e.jsx(E,{ariaLabel:"Filter by source",value:H,onChange:z(Ke),options:[{value:"all",label:"Any source"},{value:"discovered",label:"Discovered"},{value:"custom",label:"Custom (not discovered)"}]}),e.jsx(E,{ariaLabel:"Filter by capability",value:q,onChange:z(Ve),options:[{value:"all",label:"Any capability"},...Me.map(l=>({value:l.value,label:l.label}))]}),e.jsx(E,{ariaLabel:"Minimum context window",value:le,onChange:z(Ye),options:Pt}),e.jsx(E,{ariaLabel:"Maximum input price",value:J,onChange:z(He),options:yt}),e.jsx(E,{ariaLabel:"Compare prices at context",value:ce,onChange:we,options:Nt}),e.jsx(E,{ariaLabel:"Filter by release date",value:Z,onChange:z(qe),options:St})]}),e.jsx(Vt,{providers:Xe}),e.jsx(Kt,{rows:et,isLoading:tt,empty:it,sort:y,onSort:Je,selectedKey:W,onSelect:D,pricingKey:S,onSetPricingKey:k,comparisonContextTokens:Qe}),e.jsx("div",{className:"flex flex-wrap items-center justify-between gap-2",children:e.jsx(At,{page:ge,pageCount:be,total:ve,pageSize:P,onPage:v,onPageSize:l=>{m(l),v(0)}})})]}),te?e.jsx("aside",{className:"lg:sticky lg:top-4",children:e.jsx(It,{row:te,metadata:O[te.key],metadataAvailable:Ue,onMakeAlias:l=>t(`/aliases?target=${encodeURIComponent(l)}`),onClose:()=>D(null)})}):null]})]})}export{Jt as ModelsPage}; +import{j as e}from"./tanstack-query-1t81HyiD.js";import{i as rt,u as nt,r as c}from"./react-dgEcD0HR.js";import{v as at,w as st,e as lt,x as ct,P as ot,E as ut,F as E,I as dt,y as ne,z as pt,A as ht,B as xt,D as A,G as $e,H as Ee,C as Ae,h as me}from"./index-C94BH4OZ.js";import{T as mt,a as ft,d as Ce,b as re,L as vt,e as U,c as bt}from"./Table-CLdjdyTx.js";import{B as L,d as ke,f as K}from"./heroui-BX6JwHY-.js";function We(t){const i=t.indexOf(":");return i>0?t.slice(0,i):"—"}function gt(t,i=Date.now()){const r=new Map;for(const n of t){const a=r.get(n.model_key)??[];a.push(n),r.set(n.model_key,a)}const s=[];for(const n of r.values()){const a=[...n].sort((h,p)=>Date.parse(h.effective_at)-Date.parse(p.effective_at)),d=[...a].reverse().find(h=>Date.parse(h.effective_at)<=i);s.push(d??a[0])}return s.sort((n,a)=>n.model_key.localeCompare(a.model_key))}const _t="otari",Me=[{value:"vision",label:"Vision",test:t=>Array.isArray(t.input_modalities)&&t.input_modalities.includes("image")},{value:"tool_call",label:"Tool calling",test:t=>!!t.tool_call},{value:"reasoning",label:"Reasoning",test:t=>!!t.reasoning},{value:"structured_output",label:"Structured output",test:t=>!!t.structured_output},{value:"attachment",label:"Attachments",test:t=>!!t.attachment},{value:"audio",label:"Audio",test:t=>Array.isArray(t.input_modalities)&&t.input_modalities.includes("audio")},{value:"pdf",label:"PDF",test:t=>Array.isArray(t.input_modalities)&&t.input_modalities.includes("pdf")}],jt=[{key:"reasoning",label:"Reasoning"},{key:"tool_call",label:"Tool calling"},{key:"structured_output",label:"Structured output"},{key:"attachment",label:"Attachments"},{key:"temperature",label:"Temperature"}],Te={text:"Text",image:"Image",audio:"Audio",video:"Video",pdf:"PDF"},Pt=[{value:"0",label:"Any context"},{value:"8000",label:"≥ 8K"},{value:"32000",label:"≥ 32K"},{value:"128000",label:"≥ 128K"},{value:"200000",label:"≥ 200K"},{value:"1000000",label:"≥ 1M"}],yt=[{value:"",label:"Any price"},{value:"1",label:"≤ $1 / 1M in"},{value:"3",label:"≤ $3 / 1M in"},{value:"10",label:"≤ $10 / 1M in"},{value:"30",label:"≤ $30 / 1M in"}],Nt=[{value:"",label:"Base prices"},{value:"8000",label:"Compare at 8K"},{value:"128000",label:"Compare at 128K"},{value:"200000",label:"Compare at 200K"},{value:"500000",label:"Compare at 500K"},{value:"1000000",label:"Compare at 1M"}],St=[{value:"all",label:"Any release date"},{value:"365",label:"Past year"},{value:"730",label:"Past 2 years"},{value:"1095",label:"Past 3 years"}],Ct=1440*60*1e3;function Ie(t,i){const r=`${i}:`;return t.startsWith(r)?t.slice(r.length):t}function kt(t,i){const r={inputPrice:t.inputPrice,outputPrice:t.outputPrice,cacheReadPrice:t.cacheReadPrice,cacheWritePrice:t.cacheWritePrice,cacheWrite1hPrice:t.cacheWrite1hPrice};if(i==null)return r;const s=t.pricingTiers.filter(n=>n.min_input_tokens<=i).sort((n,a)=>a.min_input_tokens-n.min_input_tokens)[0];return s?{inputPrice:s.input_price_per_million??r.inputPrice,outputPrice:s.output_price_per_million??r.outputPrice,cacheReadPrice:s.cache_read_price_per_million??r.cacheReadPrice,cacheWritePrice:s.cache_write_price_per_million??r.cacheWritePrice,cacheWrite1hPrice:s.cache_write_1h_price_per_million??r.cacheWrite1hPrice}:r}function ae(t){const i=Number(t);return t.trim()!==""&&Number.isFinite(i)&&i>=0}function R(t){if(t.trim()==="")return!0;const i=Number(t);return Number.isFinite(i)&&i>=0}function V(t){return t.trim()===""?null:Number(t)}function De(t){return t.map((i,r)=>({id:r,minInputTokens:String(i.min_input_tokens),input:i.input_price_per_million==null?"":String(i.input_price_per_million),output:i.output_price_per_million==null?"":String(i.output_price_per_million),cacheRead:i.cache_read_price_per_million==null?"":String(i.cache_read_price_per_million),cacheWrite:i.cache_write_price_per_million==null?"":String(i.cache_write_price_per_million),cacheWrite1h:i.cache_write_1h_price_per_million==null?"":String(i.cache_write_1h_price_per_million)}))}function Oe(t){const i=new Set;return t.every(r=>{const s=Number(r.minInputTokens),n=[r.input,r.output,r.cacheRead,r.cacheWrite,r.cacheWrite1h].some(a=>a.trim()!=="");return!Number.isInteger(s)||s<=0||i.has(s)||!n?!1:(i.add(s),[r.input,r.output,r.cacheRead,r.cacheWrite,r.cacheWrite1h].every(R))})}function Fe(t){return t.map(i=>({min_input_tokens:Number(i.minInputTokens),...i.input.trim()===""?{}:{input_price_per_million:Number(i.input)},...i.output.trim()===""?{}:{output_price_per_million:Number(i.output)},...i.cacheRead.trim()===""?{}:{cache_read_price_per_million:Number(i.cacheRead)},...i.cacheWrite.trim()===""?{}:{cache_write_price_per_million:Number(i.cacheWrite)},...i.cacheWrite1h.trim()===""?{}:{cache_write_1h_price_per_million:Number(i.cacheWrite1h)}}))}function j({value:t,onChange:i,ariaLabel:r}){return e.jsx("input",{type:"number",step:"any",min:"0",inputMode:"decimal","aria-label":r,value:t,onChange:s=>i(s.target.value),className:"w-28 rounded-md border border-[var(--otari-line)] bg-white px-2 py-1 text-right text-sm tabular-nums focus:border-[var(--otari-brand)] focus:outline-none"})}function ze({tiers:t,onChange:i}){const r=(n,a,d)=>{i(t.map(h=>h.id===n?{...h,[a]:d}:h))},s=()=>{const n=t.reduce((a,d)=>Math.max(a,d.id),-1)+1;i([...t,{id:n,minInputTokens:"128000",input:"",output:"",cacheRead:"",cacheWrite:"",cacheWrite1h:""}])};return e.jsxs("div",{className:"flex flex-col gap-2 rounded-lg border border-[var(--otari-line)] p-3",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-xs font-medium text-[var(--otari-ink)]",children:"Long-context price tiers"}),e.jsx("p",{className:"text-xs text-[var(--otari-muted)]",children:"At a threshold, listed rates replace the base rate for the whole request."})]}),e.jsx(L,{size:"sm",variant:"outline",onPress:s,children:"Add tier"})]}),t.map(n=>e.jsxs("div",{className:"flex flex-wrap items-end gap-2 border-t border-[var(--otari-line)] pt-2",children:[e.jsxs("label",{className:"flex flex-col gap-1 text-xs text-[var(--otari-muted)]",children:["Context ≥ tokens",e.jsx("input",{type:"number",min:"1",step:"1",inputMode:"numeric","aria-label":"Tier context threshold",value:n.minInputTokens,onChange:a=>r(n.id,"minInputTokens",a.target.value),className:"w-28 rounded-md border border-[var(--otari-line)] bg-white px-2 py-1 text-right text-sm tabular-nums focus:border-[var(--otari-brand)] focus:outline-none"})]}),e.jsxs("label",{className:"flex flex-col gap-1 text-xs text-[var(--otari-muted)]",children:["Input",e.jsx(j,{value:n.input,onChange:a=>r(n.id,"input",a),ariaLabel:"Tier input price"})]}),e.jsxs("label",{className:"flex flex-col gap-1 text-xs text-[var(--otari-muted)]",children:["Output",e.jsx(j,{value:n.output,onChange:a=>r(n.id,"output",a),ariaLabel:"Tier output price"})]}),e.jsxs("label",{className:"flex flex-col gap-1 text-xs text-[var(--otari-muted)]",children:["Cache read",e.jsx(j,{value:n.cacheRead,onChange:a=>r(n.id,"cacheRead",a),ariaLabel:"Tier cache read price"})]}),e.jsxs("label",{className:"flex flex-col gap-1 text-xs text-[var(--otari-muted)]",children:["Cache write",e.jsx(j,{value:n.cacheWrite,onChange:a=>r(n.id,"cacheWrite",a),ariaLabel:"Tier cache write price"})]}),e.jsxs("label",{className:"flex flex-col gap-1 text-xs text-[var(--otari-muted)]",children:["1h write",e.jsx(j,{value:n.cacheWrite1h,onChange:a=>r(n.id,"cacheWrite1h",a),ariaLabel:"Tier 1 hour cache write price"})]}),e.jsx(L,{size:"sm",variant:"ghost",onPress:()=>i(t.filter(a=>a.id!==n.id)),children:"Remove"})]},n.id))]})}function Wt({source:t}){return t==="configured"?e.jsx(K,{size:"sm",color:"default",children:"configured"}):t==="default"||t==="alias"?e.jsx(K,{size:"sm",color:"accent",children:t}):e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"not priced"})}function se({label:t,tone:i="info",children:r}){const s=c.useId();return e.jsxs("span",{className:"group relative inline-flex items-center font-normal normal-case",children:[e.jsx("button",{type:"button","aria-label":t,"aria-describedby":s,className:`inline-flex h-4 w-4 items-center justify-center rounded-full border text-[10px] leading-none ${i==="warning"?"border-[#c2843a] text-[#b45309]":"border-[var(--otari-line)] text-[var(--otari-muted)] hover:border-[var(--otari-brand)] hover:text-[var(--otari-brand)]"}`,children:"i"}),e.jsx("span",{id:s,role:"tooltip",className:"pointer-events-none absolute top-full right-0 z-20 mt-1.5 w-72 rounded-lg border border-[var(--otari-line)] bg-[var(--otari-surface)] px-3 py-2 text-left text-xs font-normal whitespace-normal break-words text-[var(--otari-ink)] opacity-0 shadow-lg transition-opacity group-hover:opacity-100 group-focus-within:opacity-100",children:r})]})}function Mt(){const t=xt();return t.data?t.data.default_pricing?e.jsx(se,{label:"How unpriced models are metered",tone:"info",children:"Default pricing is on: models without a configured price are metered using community-maintained rates (the bundled genai-prices dataset). Set a price to override the fallback."}):e.jsxs(se,{label:"How unpriced models are metered",tone:"warning",children:["Default pricing is off: only models with a configured price are metered.",t.data.require_pricing?" Requests for any other model are rejected (HTTP 402) because require_pricing is on.":" Other models are served without cost tracking."]}):null}function T({label:t,value:i}){return e.jsxs("div",{className:"flex items-baseline justify-between gap-3",children:[e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:t}),e.jsx("span",{className:"text-right text-sm text-[var(--otari-ink)] tabular-nums",children:i})]})}function ie({title:t,children:i}){return e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsx("span",{className:"text-xs font-semibold uppercase tracking-wide text-[var(--otari-muted)]",children:t}),i]})}function Tt({row:t}){const i=$e(),r=Ee(),[s,n]=c.useState(!1),[a,d]=c.useState(""),[h,p]=c.useState(""),[v,P]=c.useState(""),[m,S]=c.useState(""),[k,W]=c.useState(""),[D,y]=c.useState([]),Y=()=>{d(t.inputPrice==null?"":String(t.inputPrice)),p(t.outputPrice==null?"":String(t.outputPrice)),P(t.cacheReadPrice==null?"":String(t.cacheReadPrice)),S(t.cacheWritePrice==null?"":String(t.cacheWritePrice)),W(t.cacheWrite1hPrice==null?"":String(t.cacheWrite1hPrice)),y(De(t.pricingTiers)),n(!0)},M=ae(a)&&ae(h)&&R(v)&&R(m)&&R(k)&&Oe(D),G=()=>{M&&i.mutate({model_key:t.key,input_price_per_million:Number(a),output_price_per_million:Number(h),cache_read_price_per_million:V(v),cache_write_price_per_million:V(m),cache_write_1h_price_per_million:V(k),pricing_tiers:Fe(D)},{onSuccess:()=>n(!1)})};return s?e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"Input $ / 1M"}),e.jsx(j,{value:a,onChange:d,ariaLabel:`Input price for ${t.key}`})]}),e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"Output $ / 1M"}),e.jsx(j,{value:h,onChange:p,ariaLabel:`Output price for ${t.key}`})]}),e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"Cache read $ / 1M"}),e.jsx(j,{value:v,onChange:P,ariaLabel:`Cache read price for ${t.key}`})]}),e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"Cache write $ / 1M"}),e.jsx(j,{value:m,onChange:S,ariaLabel:`Cache write price for ${t.key}`})]}),e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"1h cache write $ / 1M"}),e.jsx(j,{value:k,onChange:W,ariaLabel:`1 hour cache write price for ${t.key}`})]}),e.jsx(ze,{tiers:D,onChange:y}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(L,{size:"sm",variant:"primary",isDisabled:i.isPending||!M,onPress:G,children:"Save"}),e.jsx(L,{size:"sm",variant:"ghost",isDisabled:i.isPending,onPress:()=>n(!1),children:"Cancel"})]}),i.error?e.jsx("span",{className:"text-xs text-red-700",children:me(i.error)}):null]}):e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsx(T,{label:"Input",value:t.inputPrice==null?"—":`${A(t.inputPrice)} / 1M`}),e.jsx(T,{label:"Output",value:t.outputPrice==null?"—":`${A(t.outputPrice)} / 1M`}),e.jsx(T,{label:"Cache read",value:t.cacheReadPrice==null?"—":`${A(t.cacheReadPrice)} / 1M`}),e.jsx(T,{label:"Cache write",value:t.cacheWritePrice==null?"—":`${A(t.cacheWritePrice)} / 1M`}),e.jsx(T,{label:"1h cache write",value:t.cacheWrite1hPrice==null?"—":`${A(t.cacheWrite1hPrice)} / 1M`}),e.jsx(T,{label:"Context tiers",value:t.pricingTiers.length?`${t.pricingTiers.length} configured`:"—"}),e.jsxs("div",{className:"flex items-center gap-2 pt-1",children:[e.jsx(L,{size:"sm",variant:"outline",onPress:Y,children:t.source==="configured"?"Edit price":"Set price"}),t.source==="configured"?e.jsxs(e.Fragment,{children:[e.jsx(Ae,{confirmLabel:"Reset",isPending:r.isPending,onConfirm:()=>r.mutate(t.key),children:"Reset"}),e.jsx(se,{label:"What reset does",children:"Removes the custom price. The model reverts to the default rate (genai-prices) when default pricing is on, otherwise it is metered at no cost."})]}):null,r.error?e.jsx("span",{className:"text-xs text-red-700",children:me(r.error)}):null]})]})}function It({row:t,metadata:i,metadataAvailable:r,onMakeAlias:s,onClose:n}){const a=(i==null?void 0:i.input_modalities)??[],d=(i==null?void 0:i.output_modalities)??[],h=jt.filter(({key:p})=>i==null?void 0:i[p]);return e.jsx(ke,{children:e.jsxs(ke.Content,{className:"flex flex-col gap-5 p-5",children:[e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("h2",{className:"text-base font-semibold break-all text-[var(--otari-ink)]",children:t.model}),i!=null&&i.deprecated?e.jsx(K,{size:"sm",color:"danger",children:"deprecated"}):null]}),e.jsxs("p",{className:"mt-1 text-xs break-all text-[var(--otari-muted)]",children:["Selector: ",e.jsx("code",{children:t.key})]}),i!=null&&i.family?e.jsx("p",{className:"text-xs text-[var(--otari-muted)]",children:i.family}):null]}),e.jsx("button",{type:"button","aria-label":"Close model details",onClick:n,className:"-mt-1 -mr-1 shrink-0 rounded-md px-1.5 py-0.5 text-lg leading-none text-[var(--otari-muted)] hover:bg-[var(--otari-bg)] hover:text-[var(--otari-ink)]",children:"✕"})]}),i!=null&&i.description?e.jsx("p",{className:"text-sm text-[var(--otari-ink)]",children:i.description}):null,e.jsxs(ie,{title:"Pricing",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Wt,{source:t.source}),t.isDiscovered?null:e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"not discovered"})]}),e.jsx(Tt,{row:t},t.key),e.jsx(L,{size:"sm",variant:"outline",onPress:()=>s(t.key),children:"Make an alias"})]}),e.jsxs(ie,{title:"Specs",children:[e.jsx(T,{label:"Context window",value:ne(t.contextWindow)}),e.jsx(T,{label:"Max output",value:ne((i==null?void 0:i.max_output_tokens)??null)}),e.jsx(T,{label:"Knowledge cutoff",value:(i==null?void 0:i.knowledge_cutoff)??"—"}),e.jsx(T,{label:"Released",value:ht(i==null?void 0:i.release_date)}),e.jsx(T,{label:"Open weights",value:i?i.open_weights?"Yes":"No":"—"})]}),e.jsx(ie,{title:"Modalities",children:a.length===0&&d.length===0?e.jsx("span",{className:"text-sm text-[var(--otari-muted)]",children:"Unknown."}):e.jsxs("div",{className:"flex flex-col gap-1.5 text-xs text-[var(--otari-muted)]",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-1",children:[e.jsx("span",{children:"In:"}),a.map(p=>e.jsx(K,{size:"sm",color:"default",children:Te[p]??p},p))]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-1",children:[e.jsx("span",{children:"Out:"}),d.map(p=>e.jsx(K,{size:"sm",color:"default",children:Te[p]??p},p))]})]})}),e.jsx(ie,{title:"Capabilities",children:h.length>0?e.jsx("div",{className:"flex flex-wrap gap-1.5",children:h.map(({key:p,label:v})=>e.jsx(K,{size:"sm",color:"default",children:v},p))}):e.jsx("span",{className:"text-sm text-[var(--otari-muted)]",children:r?"None reported.":"Extended metadata unavailable (models.dev disabled or unreachable)."})})]})})}const Lt=15,$t=[{value:"15",label:"15 per page"},{value:"25",label:"25 per page"},{value:"50",label:"50 per page"}];function Et({value:t,onChange:i,placeholder:r}){return e.jsx("input",{type:"search",value:t,onChange:s=>i(s.target.value),placeholder:r,"aria-label":r,className:"w-full max-w-xs rounded-md border border-[var(--otari-line)] bg-white px-3 py-1.5 text-sm focus:border-[var(--otari-brand)] focus:outline-none"})}function At({page:t,pageCount:i,total:r,pageSize:s,onPage:n,onPageSize:a}){return e.jsxs("div",{className:"flex items-center justify-between px-1 pt-1 text-sm text-[var(--otari-muted)]",children:[e.jsxs("span",{children:[i>1?`Page ${t+1} of ${i} · `:"",pt(r)," model",r===1?"":"s"]}),e.jsxs("span",{className:"inline-flex gap-2",children:[e.jsx(E,{ariaLabel:"Rows per page",value:String(s),onChange:d=>a(Number(d)),options:$t}),i>1?e.jsxs(e.Fragment,{children:[e.jsx(L,{size:"sm",variant:"outline",isDisabled:t===0,onPress:()=>n(t-1),children:"Prev"}),e.jsx(L,{size:"sm",variant:"outline",isDisabled:t>=i-1,onPress:()=>n(t+1),children:"Next"})]}):null]})]})}const Be="otari.dashboard.modelsSort",xe={col:"model",dir:"asc"},Dt=["model","released","input","output"];function Ot(){if(typeof window>"u")return xe;try{const t=window.localStorage.getItem(Be);if(!t)return xe;const i=JSON.parse(t);if(Dt.includes(i.col)&&(i.dir==="asc"||i.dir==="desc"))return{col:i.col,dir:i.dir}}catch{}return xe}function Le({label:t,col:i,sort:r,onSort:s,align:n="left",info:a}){const d=r.col===i;return e.jsx(re,{className:n==="right"?"text-right":void 0,ariaSort:d?r.dir==="asc"?"ascending":"descending":"none",children:e.jsxs("span",{className:`inline-flex items-center gap-1.5 ${n==="right"?"flex-row-reverse":""}`,children:[e.jsxs("button",{type:"button",onClick:()=>s(i),className:`inline-flex items-center gap-1 ${n==="right"?"flex-row-reverse":""} hover:text-[var(--otari-ink)]`,children:[t,e.jsx("span",{className:"text-[10px] text-[var(--otari-muted)]",children:d?r.dir==="asc"?"▲":"▼":"↕"})]}),a]})})}function Ft({row:t,onClose:i}){const r=$e(),s=Ee(),[n,a]=c.useState(t.inputPrice==null?"":String(t.inputPrice)),[d,h]=c.useState(t.outputPrice==null?"":String(t.outputPrice)),[p,v]=c.useState(t.cacheReadPrice==null?"":String(t.cacheReadPrice)),[P,m]=c.useState(t.cacheWritePrice==null?"":String(t.cacheWritePrice)),[S,k]=c.useState(t.cacheWrite1hPrice==null?"":String(t.cacheWrite1hPrice)),[W,D]=c.useState(De(t.pricingTiers)),y=ae(n)&&ae(d)&&R(p)&&R(P)&&R(S)&&Oe(W),Y=()=>{y&&r.mutate({model_key:t.key,input_price_per_million:Number(n),output_price_per_million:Number(d),cache_read_price_per_million:V(p),cache_write_price_per_million:V(P),cache_write_1h_price_per_million:V(S),pricing_tiers:Fe(W)},{onSuccess:i})};return e.jsxs("div",{className:"flex flex-col gap-3 px-4 py-3",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsx("span",{className:"text-xs font-medium break-all text-[var(--otari-muted)]",children:t.key}),e.jsxs("label",{className:"flex items-center gap-1.5 text-xs text-[var(--otari-muted)]",children:["Input $ / 1M",e.jsx(j,{value:n,onChange:a,ariaLabel:`Input price for ${t.key}`})]}),e.jsxs("label",{className:"flex items-center gap-1.5 text-xs text-[var(--otari-muted)]",children:["Output $ / 1M",e.jsx(j,{value:d,onChange:h,ariaLabel:`Output price for ${t.key}`})]}),e.jsxs("label",{className:"flex items-center gap-1.5 text-xs text-[var(--otari-muted)]",children:["Cache read $ / 1M",e.jsx(j,{value:p,onChange:v,ariaLabel:`Cache read price for ${t.key}`})]}),e.jsxs("label",{className:"flex items-center gap-1.5 text-xs text-[var(--otari-muted)]",children:["Cache write $ / 1M",e.jsx(j,{value:P,onChange:m,ariaLabel:`Cache write price for ${t.key}`})]}),e.jsxs("label",{className:"flex items-center gap-1.5 text-xs text-[var(--otari-muted)]",children:["1h cache write $ / 1M",e.jsx(j,{value:S,onChange:k,ariaLabel:`1 hour cache write price for ${t.key}`})]}),e.jsx(L,{size:"sm",variant:"primary",isDisabled:r.isPending||!y,onPress:Y,children:r.isPending?"Saving…":"Save"}),e.jsx(L,{size:"sm",variant:"ghost",isDisabled:r.isPending,onPress:i,children:"Cancel"}),t.source==="configured"?e.jsxs("span",{className:"inline-flex items-center gap-1",children:[e.jsx(Ae,{confirmLabel:"Reset",isPending:s.isPending,onConfirm:()=>s.mutate(t.key,{onSuccess:i}),children:"Reset"}),e.jsx(se,{label:"What reset does",children:"Removes the custom price. The model reverts to the default rate (genai-prices) when default pricing is on, otherwise it is metered at no cost."})]}):null,r.error||s.error?e.jsx("span",{className:"text-xs text-red-700",children:me(r.error??s.error)}):null]}),e.jsx(ze,{tiers:W,onChange:D})]})}function zt({primary:t,secondary:i,rowKey:r,primaryLabel:s,secondaryLabel:n,onEdit:a}){const d=(h,p)=>e.jsx("button",{type:"button","aria-label":`Edit ${p} price for ${r}`,className:"tabular-nums hover:text-[var(--otari-brand-dark)] hover:underline",onClick:v=>{v.stopPropagation(),a()},children:h==null?"—":A(h)});return e.jsxs("span",{className:"inline-flex items-center justify-end gap-1",children:[d(t,s),e.jsx("span",{className:"text-[var(--otari-muted)]",children:"/"}),d(i,n)]})}function Bt({rates:t,rowKey:i,onEdit:r}){const s=[t.cacheReadPrice==null?null:`R ${A(t.cacheReadPrice)}`,t.cacheWritePrice==null?null:`W ${A(t.cacheWritePrice)}`,t.cacheWrite1hPrice==null?null:`1h ${A(t.cacheWrite1hPrice)}`].filter(n=>n!==null);return e.jsx("button",{type:"button","aria-label":`Edit caching price for ${i}`,className:"max-w-44 text-right text-xs leading-5 text-[var(--otari-muted)] hover:text-[var(--otari-brand-dark)] hover:underline",onClick:n=>{n.stopPropagation(),r()},children:s.length>0?s.join(" · "):"Input-rate fallback"})}function Rt({row:t,onEdit:i}){const r=[...t.pricingTiers].sort((n,a)=>n.min_input_tokens-a.min_input_tokens).map(n=>ne(n.min_input_tokens)),s=r.length===0?"Base only":`${r.length} tier${r.length===1?"":"s"} · ≥ ${r.join(", ")}`;return e.jsx("button",{type:"button","aria-label":`Edit pricing policy for ${t.key}`,className:"max-w-40 text-right text-xs leading-5 text-[var(--otari-muted)] hover:text-[var(--otari-brand-dark)] hover:underline",onClick:n=>{n.stopPropagation(),i()},children:s})}function Kt({rows:t,isLoading:i,empty:r,sort:s,onSort:n,selectedKey:a,onSelect:d,pricingKey:h,onSetPricingKey:p,comparisonContextTokens:v}){const P=v==null?"Base":`at ${ne(v)}`;return e.jsxs(mt,{children:[e.jsx(ft,{children:e.jsxs(Ce,{children:[e.jsx(Le,{label:"Model",col:"model",sort:s,onSort:n}),e.jsx(re,{children:"Provider"}),e.jsx(Le,{label:`${P} in / out $ / 1M`,col:"input",sort:s,onSort:n,align:"right",info:e.jsx(Mt,{})}),e.jsxs(re,{className:"text-right",children:["Caching ",v==null?"policy":P]}),e.jsx(re,{className:"text-right",children:"Pricing policy"})]})}),e.jsx("tbody",{children:i?e.jsx(vt,{colSpan:5}):t.length>0?t.map(m=>{const S=()=>p(h===m.key?null:m.key),k=kt(m,v);return e.jsxs(c.Fragment,{children:[e.jsxs(Ce,{onClick:()=>d(m.key),selected:m.key===a,children:[e.jsxs(U,{className:"font-medium break-all",children:[m.model,e.jsx("span",{className:"sr-only",children:m.key})]}),e.jsx(U,{className:"text-[var(--otari-muted)]",children:m.provider}),e.jsx(U,{className:"text-right",children:e.jsx(zt,{primary:k.inputPrice,secondary:k.outputPrice,rowKey:m.key,primaryLabel:"input",secondaryLabel:"output",onEdit:S})}),e.jsx(U,{className:"text-right",children:e.jsx(Bt,{rates:k,rowKey:m.key,onEdit:S})}),e.jsx(U,{className:"text-right",children:e.jsx(Rt,{row:m,onEdit:S})})]}),h===m.key?e.jsx("tr",{className:"border-b border-[var(--otari-line)] bg-[var(--otari-bg)] last:border-b-0",children:e.jsx("td",{colSpan:5,children:e.jsx(Ft,{row:m,onClose:()=>p(null)})})}):null]},m.key)}):e.jsx(bt,{colSpan:5,children:r})})]})}function Vt({providers:t}){return t.length===0?null:e.jsxs(dt,{tone:"warning",children:["Could not list ",t.map(i=>i.provider).join(", "),". Check that provider's credentials in config.yml; its models are missing from the list below."]})}function Jt(){var je,Pe,ye;const t=rt(),[i]=nt(),r=at(),s=st(),n=lt(),a=ct(),[d,h]=c.useState(""),[p,v]=c.useState(0),[P,m]=c.useState(Lt),[S,k]=c.useState(null),[W,D]=c.useState(null),[y,Y]=c.useState(Ot);c.useEffect(()=>{try{window.localStorage.setItem(Be,JSON.stringify(y))}catch{}},[y]);const[M,G]=c.useState(i.get("provider")||"all"),[F,Re]=c.useState("all"),[H,Ke]=c.useState("all"),[q,Ve]=c.useState("all"),[le,Ye]=c.useState("0"),[J,He]=c.useState(""),[Z,qe]=c.useState("all"),[ce,we]=c.useState(""),O=((je=a.data)==null?void 0:je.models)??{},Ue=((Pe=a.data)==null?void 0:Pe.available)??!1,fe=c.useMemo(()=>{var l;return new Set((((l=n.data)==null?void 0:l.providers)??[]).flatMap(f=>f.models.map(o=>o.key)))},[n.data]),Ge=l=>{h(l),v(0)},z=l=>f=>{l(f),v(0)},Je=l=>{Y(f=>f.col===l?{col:l,dir:f.dir==="asc"?"desc":"asc"}:{col:l,dir:l==="released"?"desc":"asc"}),v(0)},X=c.useMemo(()=>{var C,g,_,$,I,B,Ne;const l=new Map(gt(s.data??[]).map(u=>[u.model_key,u])),f=[],o=new Set,b=(u,he,Se,x)=>{if(o.has(u))return;o.add(u);const N=l.get(u);f.push({key:u,model:Ie(he,Se),provider:Se,isDiscovered:fe.has(u),contextWindow:(x==null?void 0:x.contextWindow)??null,inputPrice:N?N.input_price_per_million:(x==null?void 0:x.inputPrice)??null,outputPrice:N?N.output_price_per_million:(x==null?void 0:x.outputPrice)??null,cacheReadPrice:N?N.cache_read_price_per_million:(x==null?void 0:x.cacheReadPrice)??null,cacheWritePrice:N?N.cache_write_price_per_million:(x==null?void 0:x.cacheWritePrice)??null,cacheWrite1hPrice:N?N.cache_write_1h_price_per_million??null:(x==null?void 0:x.cacheWrite1hPrice)??null,pricingTiers:N?N.pricing_tiers??[]:(x==null?void 0:x.pricingTiers)??[],source:N?"configured":(x==null?void 0:x.source)??"none"})};for(const u of((C=r.data)==null?void 0:C.data)??[]){if(u.owned_by===_t)continue;const he=u.pricing_source==="default"?"default":u.pricing?"configured":"none";b(u.id,u.id,u.owned_by||We(u.id),{key:u.id,model:u.id,provider:u.owned_by,contextWindow:u.context_window,inputPrice:((g=u.pricing)==null?void 0:g.input_price_per_million)??null,outputPrice:((_=u.pricing)==null?void 0:_.output_price_per_million)??null,cacheReadPrice:(($=u.pricing)==null?void 0:$.cache_read_price_per_million)??null,cacheWritePrice:((I=u.pricing)==null?void 0:I.cache_write_price_per_million)??null,cacheWrite1hPrice:((B=u.pricing)==null?void 0:B.cache_write_1h_price_per_million)??null,pricingTiers:((Ne=u.pricing)==null?void 0:Ne.pricing_tiers)??[],source:he})}for(const u of l.keys())b(u,u,We(u));return f},[r.data,s.data,fe]),Ze=c.useMemo(()=>new Map(X.map(l=>[l.key,l])),[X]),Q=c.useMemo(()=>{var o,b,C;const l=X.map(g=>{var _,$;return{...g,contextWindow:g.contextWindow??((_=O[g.key])==null?void 0:_.context_window)??null,releaseDate:(($=O[g.key])==null?void 0:$.release_date)??null}}),f=new Set(l.map(g=>g.key));for(const g of((o=n.data)==null?void 0:o.providers)??[])for(const _ of g.models)f.has(_.key)||(f.add(_.key),l.push({key:_.key,model:Ie(_.key,g.provider),provider:g.provider,isDiscovered:!0,contextWindow:((b=O[_.key])==null?void 0:b.context_window)??null,releaseDate:((C=O[_.key])==null?void 0:C.release_date)??null,inputPrice:null,outputPrice:null,cacheReadPrice:null,cacheWritePrice:null,cacheWrite1hPrice:null,pricingTiers:[],source:"none"}));return l},[X,n.data,O]),Xe=(((ye=n.data)==null?void 0:ye.providers)??[]).filter(l=>!l.ok),ee=c.useMemo(()=>{const l=Array.from(new Set(Q.map(f=>f.provider))).sort((f,o)=>f.localeCompare(o));return[{value:"all",label:"All providers"},...l.map(f=>({value:f,label:f}))]},[Q]);c.useEffect(()=>{M==="all"||ee.length<=1||ee.some(l=>l.value===M)||G("all")},[ee,M]);const w=d.trim().toLowerCase(),oe=Number(le)||0,ue=J===""?Number.POSITIVE_INFINITY:Number(J),Qe=ce===""?null:Number(ce),de=Z==="all"?null:Date.now()-Number(Z)*Ct,pe=c.useMemo(()=>{const l=o=>{if(w&&!o.key.toLowerCase().includes(w)&&!o.provider.toLowerCase().includes(w)||M!=="all"&&o.provider!==M||F==="configured"&&o.source!=="configured"||F==="default"&&o.source!=="default"||F==="priced"&&o.inputPrice==null||F==="unpriced"&&o.inputPrice!=null||H==="discovered"&&!o.isDiscovered||H==="custom"&&o.isDiscovered)return!1;if(q!=="all"){const b=Me.find(g=>g.value===q),C=O[o.key];if(!b||!C||!b.test(C))return!1}if(oe>0&&(o.contextWindow==null||o.contextWindowue))return!1;if(de!=null){const b=o.releaseDate?Date.parse(o.releaseDate):Number.NaN;if(Number.isNaN(b)||b{const C=y.dir==="asc"?1:-1;if(y.col==="model")return o.model.localeCompare(b.model)*C;if(y.col==="released"){const I=o.releaseDate??null,B=b.releaseDate??null;return!I&&!B?o.model.localeCompare(b.model):I?B?(IB?1:0)*C||o.model.localeCompare(b.model):-1:1}const g=I=>y.col==="input"?I.inputPrice:I.outputPrice,_=g(o),$=g(b);return _==null&&$==null?o.model.localeCompare(b.model):_==null?1:$==null?-1:(_-$)*C||o.model.localeCompare(b.model)};return Q.filter(l).sort(f)},[Q,w,M,F,H,q,oe,ue,de,O,y]),ve=pe.length,be=Math.max(1,Math.ceil(ve/P)),ge=Math.min(p,be-1),_e=ge*P,et=pe.slice(_e,_e+P),tt=r.isLoading||s.isLoading||n.isLoading,it=w!==""||M!=="all"||F!=="all"||H!=="all"||q!=="all"||le!=="0"||J!==""||Z!=="all"?"No models match your filters.":"No models yet. Add a provider on the Providers page, or price a model below.",te=W?pe.find(l=>l.key===W)??Ze.get(W)??null:null;return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(ot,{title:"Models",description:"Every model your providers can serve. Set a price on any model so budgets and usage tracking work."}),e.jsx(ut,{error:r.error??s.error??n.error??a.error}),e.jsxs("div",{className:`grid gap-4 lg:items-start ${te?"lg:grid-cols-[minmax(0,1fr)_360px]":"grid-cols-1"}`,children:[e.jsxs("div",{className:"flex min-w-0 flex-col gap-3",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx(Et,{value:d,onChange:Ge,placeholder:"Search models…"}),e.jsx(E,{ariaLabel:"Filter by provider",value:M,onChange:z(G),options:ee}),e.jsx(E,{ariaLabel:"Filter by pricing",value:F,onChange:z(Re),options:[{value:"all",label:"Any pricing"},{value:"configured",label:"Custom price"},{value:"default",label:"Default price"},{value:"priced",label:"Priced"},{value:"unpriced",label:"Unpriced"}]}),e.jsx(E,{ariaLabel:"Filter by source",value:H,onChange:z(Ke),options:[{value:"all",label:"Any source"},{value:"discovered",label:"Discovered"},{value:"custom",label:"Custom (not discovered)"}]}),e.jsx(E,{ariaLabel:"Filter by capability",value:q,onChange:z(Ve),options:[{value:"all",label:"Any capability"},...Me.map(l=>({value:l.value,label:l.label}))]}),e.jsx(E,{ariaLabel:"Minimum context window",value:le,onChange:z(Ye),options:Pt}),e.jsx(E,{ariaLabel:"Maximum input price",value:J,onChange:z(He),options:yt}),e.jsx(E,{ariaLabel:"Compare prices at context",value:ce,onChange:we,options:Nt}),e.jsx(E,{ariaLabel:"Filter by release date",value:Z,onChange:z(qe),options:St})]}),e.jsx(Vt,{providers:Xe}),e.jsx(Kt,{rows:et,isLoading:tt,empty:it,sort:y,onSort:Je,selectedKey:W,onSelect:D,pricingKey:S,onSetPricingKey:k,comparisonContextTokens:Qe}),e.jsx("div",{className:"flex flex-wrap items-center justify-between gap-2",children:e.jsx(At,{page:ge,pageCount:be,total:ve,pageSize:P,onPage:v,onPageSize:l=>{m(l),v(0)}})})]}),te?e.jsx("aside",{className:"lg:sticky lg:top-4",children:e.jsx(It,{row:te,metadata:O[te.key],metadataAvailable:Ue,onMakeAlias:l=>t(`/aliases?target=${encodeURIComponent(l)}`),onClose:()=>D(null)})}):null]})]})}export{Jt as ModelsPage}; diff --git a/src/gateway/static/dashboard/assets/OverviewPage-KThfhw1Z.js b/src/gateway/static/dashboard/assets/OverviewPage-Cb1DW9ZC.js similarity index 99% rename from src/gateway/static/dashboard/assets/OverviewPage-KThfhw1Z.js rename to src/gateway/static/dashboard/assets/OverviewPage-Cb1DW9ZC.js index de31c991..70a4cdb1 100644 --- a/src/gateway/static/dashboard/assets/OverviewPage-KThfhw1Z.js +++ b/src/gateway/static/dashboard/assets/OverviewPage-Cb1DW9ZC.js @@ -1 +1 @@ -import{j as t}from"./tanstack-query-1t81HyiD.js";import{r as f,i as Z,N as G}from"./react-dgEcD0HR.js";import{J as tt,c as N,K as et,j as rt,p as at,u as st,a as nt,L as _,P as ot,E as Y,S as p,M as D,N as R,z as E,O as k,Q as it}from"./index-BJySXQ_a.js";import{S as H}from"./charts-Cr3Dij9t.js";import{T as lt,a as dt,b,L as ct,c as ut,d as xt,e as j}from"./Table-CLdjdyTx.js";import{d as B,B as mt}from"./heroui-BX6JwHY-.js";import"./recharts-CR3TAEof.js";function U(e){return e==="neutral"?void 0:e}const vt=.02,ht=.1;function F(e){if(!e||e.request_count===0)return{rate:null,status:"neutral"};const n=e.error_count/e.request_count,a=n>=ht?"alert":n>=vt?"warn":"ok";return{rate:n,status:a}}function pt(e){return!e||e.total===0?"neutral":e.healthy>=e.total?"ok":e.healthy===0?"alert":"warn"}const ft=.8;function gt(e){if(e.length===0)return{status:"neutral",label:"No budgets configured",overCount:0,nearCount:0,cappedCount:0};const n=e.filter(s=>s.max_budget!==null&&s.user_count>0);if(n.length===0)return{status:"neutral",label:"No capped budgets",overCount:0,nearCount:0,cappedCount:0};let a=0,r=0,c,m=-1;for(const s of n){const o=s.max_budget*s.user_count,i=o>0?s.total_spend/o:0;i>=1?a+=1:i>=ft&&(r+=1),i>m&&(m=i,c={name:s.name??s.budget_id,spent:s.total_spend,allocated:o,pct:i})}const u=a>0?"alert":r>0?"warn":"ok",g=a>0?`${a} over limit`:r>0?`${r} near limit`:"All within budget";return{status:u,label:g,overCount:a,nearCount:r,cappedCount:n.length,worst:c}}const K=864e5,W=30;function I(){const e=new Date;return`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,"0")}-${String(e.getDate()).padStart(2,"0")}`}function bt(){const[e,n]=f.useState(I);return f.useEffect(()=>{const a=()=>{if(document.visibilityState==="visible"){const r=I();n(c=>c===r?c:r)}};return document.addEventListener("visibilitychange",a),window.addEventListener("focus",a),()=>{document.removeEventListener("visibilitychange",a),window.removeEventListener("focus",a)}},[]),f.useMemo(()=>{const a=Date.now(),r=new Date(a);return{today:new Date(r.getFullYear(),r.getMonth(),r.getDate()).toISOString(),periodStart:new Date(a-W*K).toISOString(),prevStart:new Date(a-2*W*K).toISOString()}},[e])}const jt={ok:"Healthy",warn:"Elevated",alert:"High"},St={ok:"On track",warn:"Near limit",alert:"Over budget"};function Pt(){const e=tt();return e.isLoading?null:t.jsx(yt,{needsSetup:e.isSuccess&&e.data.providers.length===0})}function yt({needsSetup:e=!1}){var $,A,P,T,M,q;const n=bt(),a=f.useMemo(()=>({start_date:n.today}),[n]),r=f.useMemo(()=>({start_date:n.periodStart}),[n]),c=f.useMemo(()=>({start_date:n.prevStart,end_date:n.periodStart}),[n]),m=N(a,"hour"),u=N(r,"day"),g=N(c,"day"),s=et(),o=rt(),i=at(),S=st(),y=nt({},0,5),C=($=m.data)==null?void 0:$.totals,x=(A=u.data)==null?void 0:A.totals,v=(P=g.data)==null?void 0:P.totals,w=((T=u.data)==null?void 0:T.series)??[],O=w.length>1,l=F(x),L=F(v),z=l.rate!==null&&L.rate!==null?_(l.rate,L.rate):null,d=gt(o.data??[]),J=pt(s.data),Q=(i.data??[]).filter(h=>h.is_active).length,V=(S.data??[]).filter(h=>!h.blocked).length,X=m.error??u.error??s.error??o.error??i.error??S.error;return t.jsxs("div",{className:"flex flex-col gap-6",children:[t.jsx(ot,{title:"Overview",description:"At-a-glance spend, traffic, and health across the gateway."}),e?t.jsx(wt,{}):null,t.jsx(Y,{error:X}),t.jsx(_t,{providerHealth:J,healthy:((M=s.data)==null?void 0:M.healthy)??0,total:((q=s.data)==null?void 0:q.total)??0,budget:d,errStatus:l.status,errRate:l.rate,ready:s.isSuccess&&o.isSuccess&&u.isSuccess,failed:s.isError||o.isError||u.isError}),t.jsxs("div",{className:"grid grid-cols-2 gap-4 sm:grid-cols-3 xl:grid-cols-4",children:[t.jsx(p,{label:"Spend today",value:C?D(C.cost):"—"}),t.jsx(p,{label:"Spend, last 30 days",value:x?D(x.cost):"—",hint:x?t.jsx(R,{fraction:_(x.cost,v==null?void 0:v.cost)}):null,chart:O?t.jsx(H,{values:w.map(h=>h.cost),ariaLabel:"Spend trend over the last 30 days"}):void 0}),t.jsx(p,{label:"Requests, last 30 days",value:x?E(x.request_count):"—",hint:x?t.jsx(R,{fraction:_(x.request_count,v==null?void 0:v.request_count)}):null,chart:O?t.jsx(H,{values:w.map(h=>h.requests),ariaLabel:"Request volume trend over the last 30 days"}):void 0}),t.jsx(p,{label:"Error rate, last 30 days",value:l.rate===null?"—":k(l.rate),status:U(l.status),statusLabel:l.status==="neutral"?void 0:jt[l.status],hint:l.rate!==null?t.jsx(R,{fraction:z}):null}),t.jsx(p,{label:"Budget health",value:o.data&&d.worst?k(d.worst.pct):"—",status:o.data?U(d.status):void 0,statusLabel:o.data&&d.status!=="neutral"?St[d.status]:void 0,hint:o.data?d.worst?`${d.label} · worst: ${d.worst.name}`:d.label:void 0,to:"/budgets"}),t.jsx(p,{label:"Active keys",value:i.data?E(Q):"—",to:"/keys"}),t.jsx(p,{label:"Active users",value:S.data?E(V):"—",to:"/users"})]}),t.jsx(Et,{entries:y.data??[],loading:y.isLoading,error:y.error})]})}function wt(){const e=Z();return t.jsx(B,{children:t.jsxs(B.Content,{className:"flex flex-col gap-3 p-6",children:[t.jsxs("div",{children:[t.jsx("h2",{className:"text-lg font-semibold text-[var(--otari-ink)]",children:"Get started with Otari"}),t.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:"Add a provider to begin serving models. Once it is configured, this page will show your gateway’s traffic, spend, and health."})]}),t.jsx("div",{children:t.jsx(mt,{variant:"primary",onPress:()=>e("/providers"),children:"Add your first provider"})})]})})}function Nt({text:e}){return t.jsx("div",{role:"status",className:"flex items-center gap-2 rounded-xl border border-[var(--otari-line)] bg-[var(--otari-bg)] px-4 py-3 text-sm text-[var(--otari-muted)]",children:e})}function _t({providerHealth:e,healthy:n,total:a,budget:r,errStatus:c,errRate:m,ready:u,failed:g}){if(g)return t.jsx(Nt,{text:"Some status data could not be loaded."});if(!u)return null;const s=[];if((e==="warn"||e==="alert")&&a>0){const o=a-n;s.push({text:`${o} provider${o===1?"":"s"} unreachable`,to:"/providers"})}return r.overCount>0?s.push({text:`${r.overCount} budget${r.overCount===1?"":"s"} over limit`,to:"/budgets"}):r.nearCount>0&&s.push({text:`${r.nearCount} budget${r.nearCount===1?"":"s"} near limit`,to:"/budgets"}),c==="alert"&&m!==null&&s.push({text:`error rate ${k(m)}`,to:"/activity?status=error"}),s.length===0?null:t.jsxs("div",{role:"alert",className:"flex flex-col gap-2 rounded-xl border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-900 sm:flex-row sm:flex-wrap sm:items-center",children:[t.jsx("span",{className:"font-medium",children:"Needs attention:"}),s.map((o,i)=>t.jsxs("span",{className:"flex items-center gap-2",children:[i>0?t.jsx("span",{"aria-hidden":!0,className:"text-amber-400",children:"·"}):null,t.jsx(G,{to:o.to,className:"underline underline-offset-2 hover:text-amber-950",children:o.text})]},o.to+o.text))]})}function Rt(e){return e==="error"?"error":"ok"}function Et({entries:e,loading:n,error:a}){return t.jsxs("div",{className:"flex flex-col gap-3",children:[t.jsxs("div",{className:"flex items-center justify-between",children:[t.jsx("h2",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:"Recent activity"}),t.jsx(G,{to:"/activity",className:"text-sm text-[var(--otari-brand-dark)] hover:underline",children:"View all →"})]}),t.jsx(Y,{error:a}),t.jsxs(lt,{children:[t.jsx(dt,{children:t.jsxs("tr",{children:[t.jsx(b,{children:"Time"}),t.jsx(b,{children:"Model"}),t.jsx(b,{className:"text-right",children:"Cost"}),t.jsx(b,{children:"Status"})]})}),t.jsx("tbody",{children:n?t.jsx(ct,{colSpan:4}):e.length===0?t.jsx(ut,{colSpan:4,children:"No requests yet. Once the gateway serves traffic, it appears here."}):e.map(r=>t.jsxs(xt,{children:[t.jsx(j,{className:"text-[var(--otari-muted)]",children:t.jsx("span",{title:new Date(r.timestamp).toLocaleString(),children:it(r.timestamp)})}),t.jsx(j,{className:"text-[var(--otari-ink)]",children:r.model}),t.jsx(j,{className:"text-right tabular-nums",children:r.cost===null?"—":D(r.cost)}),t.jsx(j,{children:t.jsx("span",{className:`inline-flex items-center rounded-full border px-2 py-0.5 text-xs font-medium ${r.status==="error"?"border-red-200 bg-red-50 text-red-700":"border-[var(--otari-line)] bg-[var(--otari-brand-tint)] text-[var(--otari-brand-dark)]"}`,children:Rt(r.status)})})]},r.id))})]})]})}export{Pt as OverviewIndex,yt as OverviewPage,I as localDayKey}; +import{j as t}from"./tanstack-query-1t81HyiD.js";import{r as f,i as Z,N as G}from"./react-dgEcD0HR.js";import{J as tt,c as N,K as et,j as rt,p as at,u as st,a as nt,L as _,P as ot,E as Y,S as p,M as D,N as R,z as E,O as k,Q as it}from"./index-C94BH4OZ.js";import{S as H}from"./charts-Cr3Dij9t.js";import{T as lt,a as dt,b,L as ct,c as ut,d as xt,e as j}from"./Table-CLdjdyTx.js";import{d as B,B as mt}from"./heroui-BX6JwHY-.js";import"./recharts-CR3TAEof.js";function U(e){return e==="neutral"?void 0:e}const vt=.02,ht=.1;function F(e){if(!e||e.request_count===0)return{rate:null,status:"neutral"};const n=e.error_count/e.request_count,a=n>=ht?"alert":n>=vt?"warn":"ok";return{rate:n,status:a}}function pt(e){return!e||e.total===0?"neutral":e.healthy>=e.total?"ok":e.healthy===0?"alert":"warn"}const ft=.8;function gt(e){if(e.length===0)return{status:"neutral",label:"No budgets configured",overCount:0,nearCount:0,cappedCount:0};const n=e.filter(s=>s.max_budget!==null&&s.user_count>0);if(n.length===0)return{status:"neutral",label:"No capped budgets",overCount:0,nearCount:0,cappedCount:0};let a=0,r=0,c,m=-1;for(const s of n){const o=s.max_budget*s.user_count,i=o>0?s.total_spend/o:0;i>=1?a+=1:i>=ft&&(r+=1),i>m&&(m=i,c={name:s.name??s.budget_id,spent:s.total_spend,allocated:o,pct:i})}const u=a>0?"alert":r>0?"warn":"ok",g=a>0?`${a} over limit`:r>0?`${r} near limit`:"All within budget";return{status:u,label:g,overCount:a,nearCount:r,cappedCount:n.length,worst:c}}const K=864e5,W=30;function I(){const e=new Date;return`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,"0")}-${String(e.getDate()).padStart(2,"0")}`}function bt(){const[e,n]=f.useState(I);return f.useEffect(()=>{const a=()=>{if(document.visibilityState==="visible"){const r=I();n(c=>c===r?c:r)}};return document.addEventListener("visibilitychange",a),window.addEventListener("focus",a),()=>{document.removeEventListener("visibilitychange",a),window.removeEventListener("focus",a)}},[]),f.useMemo(()=>{const a=Date.now(),r=new Date(a);return{today:new Date(r.getFullYear(),r.getMonth(),r.getDate()).toISOString(),periodStart:new Date(a-W*K).toISOString(),prevStart:new Date(a-2*W*K).toISOString()}},[e])}const jt={ok:"Healthy",warn:"Elevated",alert:"High"},St={ok:"On track",warn:"Near limit",alert:"Over budget"};function Pt(){const e=tt();return e.isLoading?null:t.jsx(yt,{needsSetup:e.isSuccess&&e.data.providers.length===0})}function yt({needsSetup:e=!1}){var $,A,P,T,M,q;const n=bt(),a=f.useMemo(()=>({start_date:n.today}),[n]),r=f.useMemo(()=>({start_date:n.periodStart}),[n]),c=f.useMemo(()=>({start_date:n.prevStart,end_date:n.periodStart}),[n]),m=N(a,"hour"),u=N(r,"day"),g=N(c,"day"),s=et(),o=rt(),i=at(),S=st(),y=nt({},0,5),C=($=m.data)==null?void 0:$.totals,x=(A=u.data)==null?void 0:A.totals,v=(P=g.data)==null?void 0:P.totals,w=((T=u.data)==null?void 0:T.series)??[],O=w.length>1,l=F(x),L=F(v),z=l.rate!==null&&L.rate!==null?_(l.rate,L.rate):null,d=gt(o.data??[]),J=pt(s.data),Q=(i.data??[]).filter(h=>h.is_active).length,V=(S.data??[]).filter(h=>!h.blocked).length,X=m.error??u.error??s.error??o.error??i.error??S.error;return t.jsxs("div",{className:"flex flex-col gap-6",children:[t.jsx(ot,{title:"Overview",description:"At-a-glance spend, traffic, and health across the gateway."}),e?t.jsx(wt,{}):null,t.jsx(Y,{error:X}),t.jsx(_t,{providerHealth:J,healthy:((M=s.data)==null?void 0:M.healthy)??0,total:((q=s.data)==null?void 0:q.total)??0,budget:d,errStatus:l.status,errRate:l.rate,ready:s.isSuccess&&o.isSuccess&&u.isSuccess,failed:s.isError||o.isError||u.isError}),t.jsxs("div",{className:"grid grid-cols-2 gap-4 sm:grid-cols-3 xl:grid-cols-4",children:[t.jsx(p,{label:"Spend today",value:C?D(C.cost):"—"}),t.jsx(p,{label:"Spend, last 30 days",value:x?D(x.cost):"—",hint:x?t.jsx(R,{fraction:_(x.cost,v==null?void 0:v.cost)}):null,chart:O?t.jsx(H,{values:w.map(h=>h.cost),ariaLabel:"Spend trend over the last 30 days"}):void 0}),t.jsx(p,{label:"Requests, last 30 days",value:x?E(x.request_count):"—",hint:x?t.jsx(R,{fraction:_(x.request_count,v==null?void 0:v.request_count)}):null,chart:O?t.jsx(H,{values:w.map(h=>h.requests),ariaLabel:"Request volume trend over the last 30 days"}):void 0}),t.jsx(p,{label:"Error rate, last 30 days",value:l.rate===null?"—":k(l.rate),status:U(l.status),statusLabel:l.status==="neutral"?void 0:jt[l.status],hint:l.rate!==null?t.jsx(R,{fraction:z}):null}),t.jsx(p,{label:"Budget health",value:o.data&&d.worst?k(d.worst.pct):"—",status:o.data?U(d.status):void 0,statusLabel:o.data&&d.status!=="neutral"?St[d.status]:void 0,hint:o.data?d.worst?`${d.label} · worst: ${d.worst.name}`:d.label:void 0,to:"/budgets"}),t.jsx(p,{label:"Active keys",value:i.data?E(Q):"—",to:"/keys"}),t.jsx(p,{label:"Active users",value:S.data?E(V):"—",to:"/users"})]}),t.jsx(Et,{entries:y.data??[],loading:y.isLoading,error:y.error})]})}function wt(){const e=Z();return t.jsx(B,{children:t.jsxs(B.Content,{className:"flex flex-col gap-3 p-6",children:[t.jsxs("div",{children:[t.jsx("h2",{className:"text-lg font-semibold text-[var(--otari-ink)]",children:"Get started with Otari"}),t.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:"Add a provider to begin serving models. Once it is configured, this page will show your gateway’s traffic, spend, and health."})]}),t.jsx("div",{children:t.jsx(mt,{variant:"primary",onPress:()=>e("/providers"),children:"Add your first provider"})})]})})}function Nt({text:e}){return t.jsx("div",{role:"status",className:"flex items-center gap-2 rounded-xl border border-[var(--otari-line)] bg-[var(--otari-bg)] px-4 py-3 text-sm text-[var(--otari-muted)]",children:e})}function _t({providerHealth:e,healthy:n,total:a,budget:r,errStatus:c,errRate:m,ready:u,failed:g}){if(g)return t.jsx(Nt,{text:"Some status data could not be loaded."});if(!u)return null;const s=[];if((e==="warn"||e==="alert")&&a>0){const o=a-n;s.push({text:`${o} provider${o===1?"":"s"} unreachable`,to:"/providers"})}return r.overCount>0?s.push({text:`${r.overCount} budget${r.overCount===1?"":"s"} over limit`,to:"/budgets"}):r.nearCount>0&&s.push({text:`${r.nearCount} budget${r.nearCount===1?"":"s"} near limit`,to:"/budgets"}),c==="alert"&&m!==null&&s.push({text:`error rate ${k(m)}`,to:"/activity?status=error"}),s.length===0?null:t.jsxs("div",{role:"alert",className:"flex flex-col gap-2 rounded-xl border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-900 sm:flex-row sm:flex-wrap sm:items-center",children:[t.jsx("span",{className:"font-medium",children:"Needs attention:"}),s.map((o,i)=>t.jsxs("span",{className:"flex items-center gap-2",children:[i>0?t.jsx("span",{"aria-hidden":!0,className:"text-amber-400",children:"·"}):null,t.jsx(G,{to:o.to,className:"underline underline-offset-2 hover:text-amber-950",children:o.text})]},o.to+o.text))]})}function Rt(e){return e==="error"?"error":"ok"}function Et({entries:e,loading:n,error:a}){return t.jsxs("div",{className:"flex flex-col gap-3",children:[t.jsxs("div",{className:"flex items-center justify-between",children:[t.jsx("h2",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:"Recent activity"}),t.jsx(G,{to:"/activity",className:"text-sm text-[var(--otari-brand-dark)] hover:underline",children:"View all →"})]}),t.jsx(Y,{error:a}),t.jsxs(lt,{children:[t.jsx(dt,{children:t.jsxs("tr",{children:[t.jsx(b,{children:"Time"}),t.jsx(b,{children:"Model"}),t.jsx(b,{className:"text-right",children:"Cost"}),t.jsx(b,{children:"Status"})]})}),t.jsx("tbody",{children:n?t.jsx(ct,{colSpan:4}):e.length===0?t.jsx(ut,{colSpan:4,children:"No requests yet. Once the gateway serves traffic, it appears here."}):e.map(r=>t.jsxs(xt,{children:[t.jsx(j,{className:"text-[var(--otari-muted)]",children:t.jsx("span",{title:new Date(r.timestamp).toLocaleString(),children:it(r.timestamp)})}),t.jsx(j,{className:"text-[var(--otari-ink)]",children:r.model}),t.jsx(j,{className:"text-right tabular-nums",children:r.cost===null?"—":D(r.cost)}),t.jsx(j,{children:t.jsx("span",{className:`inline-flex items-center rounded-full border px-2 py-0.5 text-xs font-medium ${r.status==="error"?"border-red-200 bg-red-50 text-red-700":"border-[var(--otari-line)] bg-[var(--otari-brand-tint)] text-[var(--otari-brand-dark)]"}`,children:Rt(r.status)})})]},r.id))})]})]})}export{Pt as OverviewIndex,yt as OverviewPage,I as localDayKey}; diff --git a/src/gateway/static/dashboard/assets/ProvidersPage-BEN5bHZD.js b/src/gateway/static/dashboard/assets/ProvidersPage-CLe2cN4-.js similarity index 99% rename from src/gateway/static/dashboard/assets/ProvidersPage-BEN5bHZD.js rename to src/gateway/static/dashboard/assets/ProvidersPage-CLe2cN4-.js index f4849c22..f08e3ea8 100644 --- a/src/gateway/static/dashboard/assets/ProvidersPage-BEN5bHZD.js +++ b/src/gateway/static/dashboard/assets/ProvidersPage-CLe2cN4-.js @@ -1 +1 @@ -import{j as e}from"./tanstack-query-1t81HyiD.js";import{r as x,L as Q}from"./react-dgEcD0HR.js";import{J as X,R as Z,B as ee,K as se,T as te,U as ae,V as ne,P as re,E as R,I as ie,C as oe,W as de,X as le,Q as U,h as M,Y,Z as ce,_ as me,$ as ue}from"./index-BJySXQ_a.js";import{F as A}from"./Field-HzRk1KDP.js";import{T as xe,a as pe,b as _,L as he,c as ve,d as ge,e as C}from"./Table-CLdjdyTx.js";import{B as g,f as z,d as T,S as fe,T as je,L as V,I as W,D as be,C as E,a as ye,b as ke}from"./heroui-BX6JwHY-.js";function B({value:t,onChange:a,label:s,placeholder:n,description:i}){return e.jsxs(je,{value:t,onChange:a,className:"flex max-w-md flex-col gap-1",children:[e.jsx(V,{className:"text-sm font-medium text-[var(--otari-ink)]",children:s}),e.jsx(W,{type:"password",placeholder:n??"sk-…",autoComplete:"off",autoCorrect:"off",autoCapitalize:"off",spellCheck:!1,"data-1p-ignore":!0,"data-lpignore":"true"}),i?e.jsx(be,{className:"text-xs text-[var(--otari-muted)]",children:i}):null]})}function G({label:t,value:a,onChange:s,description:n,placeholder:i,extra:l=[],includeCatalog:m=!0}){var y;const v=me(),u=x.useMemo(()=>m?[...l,...(v.data??[]).map(o=>({id:o.id,name:o.name}))]:l,[v.data,l,m]),[p,c]=x.useState(()=>{var o;return((o=u.find(j=>j.id===a))==null?void 0:o.name)??""}),f=((y=u.find(o=>o.id===a))==null?void 0:y.name)??"",h=p.trim()===f.trim()?"":p.trim().toLowerCase(),d=u.filter(o=>!h||o.name.toLowerCase().includes(h)||o.id.toLowerCase().includes(h)).slice(0,50);return e.jsxs(E.Root,{allowsEmptyCollection:!0,menuTrigger:"focus",inputValue:p,onInputChange:c,onSelectionChange:o=>{var j;o!=null?(s(String(o)),c(((j=u.find(P=>P.id===String(o)))==null?void 0:j.name)??"")):(s(""),c(""))},className:"flex max-w-md flex-col gap-1",children:[e.jsx(V,{className:"text-sm font-medium text-[var(--otari-ink)]",children:t}),e.jsxs(E.InputGroup,{children:[e.jsx(W,{placeholder:i??"Search providers…",autoComplete:"off","data-1p-ignore":!0,"data-lpignore":"true",onFocus:o=>o.currentTarget.select()}),e.jsx(E.Trigger,{})]}),e.jsx(E.Popover,{children:e.jsx(ye,{items:d,className:"max-h-72 overflow-auto",children:o=>e.jsx(ke,{id:o.id,textValue:o.name,children:o.name})})}),n?e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:n}):null]})}function J({getPayload:t}){const a=ue(),s=t();return e.jsxs("div",{className:"flex flex-col gap-1.5",children:[e.jsx(g,{variant:"outline",isDisabled:s===null||a.isPending,onPress:()=>{s&&a.mutate(s)},children:a.isPending?"Testing…":"Test connection"}),e.jsx("span",{role:"status","aria-live":"polite",children:a.isPending?null:a.error?e.jsx("span",{className:"text-xs text-red-700",children:M(a.error)}):a.data?a.data.ok?e.jsxs("span",{className:"text-xs font-medium text-green-700",children:["Connected. ",a.data.model_count," model",a.data.model_count===1?"":"s"," available."]}):e.jsx("span",{className:"block max-w-md break-words text-xs text-red-700",children:a.data.error??"Connection failed."}):null})]})}function Pe({onClose:t}){var I;const a=Y(),[s,n]=x.useState(""),[i,l]=x.useState(""),[m,v]=x.useState(!1),[u,p]=x.useState(""),[c,f]=x.useState(""),h=ce(s),d=((I=h.data)==null?void 0:I.id)===s?h.data:void 0;x.useEffect(()=>{d&&p(d.default_api_base??"")},[d]);const y=(d==null?void 0:d.env_key_present)??!1,o=((d==null?void 0:d.requires_api_key)??!0)&&!y,j=c.trim()!==""&&c.trim()!==s,P=/[:/]/.test(c),k=s!==""&&!P&&(!o||i.trim()!=="")&&!a.isPending,w=()=>{k&&a.mutate({instance:j?c.trim():s,provider_type:j?s:null,api_base:u.trim()||null,api_key:i.trim()||null},{onSuccess:t})};return e.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsx(R,{error:a.error}),e.jsx(G,{label:"Provider",value:s,onChange:N=>{n(N),f(""),p("")},description:"Its endpoint is built in."}),e.jsx(B,{value:i,onChange:l,label:d&&!o?"API key (optional)":"API key",description:d?o?`${d.name}'s endpoint is built in — just add your key.`:y?`${d.env_key} is set on the server, so a key is optional here. Paste one to override it.`:`${d.name} needs no API key.`:"Stored encrypted. Requires OTARI_SECRET_KEY on the server."}),e.jsx("button",{type:"button",className:"self-start text-xs font-medium text-[var(--otari-brand-dark)]",onClick:()=>v(N=>!N),children:m?"Hide advanced":"Advanced (API base, rename)"}),m?e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsx(A,{label:"API base",value:u,onChange:p,placeholder:(d==null?void 0:d.default_api_base)??"https://…/v1",description:"Only if you route through a proxy. Blank uses the built-in default."}),e.jsx(A,{label:"Name",value:c,onChange:f,placeholder:s||"instance name",description:P?e.jsx("span",{className:"text-red-700",children:"A name cannot contain “:” or “/”."}):"Rename to run two instances of the same provider."})]}):null,e.jsxs("div",{className:"flex flex-wrap items-start gap-2",children:[e.jsx(g,{variant:"primary",isDisabled:!k,onPress:w,children:a.isPending?"Adding…":"Add provider"}),e.jsx(g,{variant:"ghost",onPress:t,children:"Cancel"}),e.jsx(J,{getPayload:()=>s===""?null:{instance:j?c.trim():s,provider_type:j?s:null,api_base:u.trim()||null,api_key:i.trim()||null}})]})]})}function Ne({onClose:t}){const a=Y(),[s,n]=x.useState(""),[i,l]=x.useState("openai-compatible"),[m,v]=x.useState(""),[u,p]=x.useState(""),c=/[:/]/.test(s),f=s.trim()!==""&&!c&&m.trim()!==""&&!a.isPending,h=()=>{f&&a.mutate({instance:s.trim(),provider_type:i||"openai-compatible",api_base:m.trim(),api_key:u.trim()||null},{onSuccess:t})};return e.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsx(R,{error:a.error}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsx(A,{label:"Name",value:s,onChange:n,placeholder:"my-local-llm",isRequired:!0,autoFocus:!0,description:c?e.jsx("span",{className:"text-red-700",children:"A name cannot contain “:” or “/”."}):"Call it whatever you want."}),e.jsx(G,{label:"Compatible with",value:i,onChange:l,includeCatalog:!1,description:"The API this endpoint speaks.",extra:[{id:"openai-compatible",name:"OpenAI"},{id:"anthropic-compatible",name:"Anthropic"}]})]}),e.jsx(A,{label:"API base",value:m,onChange:v,placeholder:"http://localhost:8000/v1",isRequired:!0,description:"The endpoint URL of your server."}),e.jsx(B,{value:u,onChange:p,label:"API key (optional)",description:"Many local backends need none. Stored encrypted."}),e.jsxs("div",{className:"flex flex-wrap items-start gap-2",children:[e.jsx(g,{variant:"primary",isDisabled:!f,onPress:h,children:a.isPending?"Adding…":"Add provider"}),e.jsx(g,{variant:"ghost",onPress:t,children:"Cancel"}),e.jsx(J,{getPayload:()=>s.trim()===""||m.trim()===""?null:{instance:s.trim(),provider_type:i||"openai-compatible",api_base:m.trim(),api_key:u.trim()||null}})]})]})}function Se({onClose:t}){const[a,s]=x.useState("known");return e.jsx(T,{children:e.jsxs(T.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsx("div",{className:"flex items-center justify-between",children:e.jsx("div",{className:"flex items-center gap-1 rounded-lg bg-[var(--otari-bg)] p-1",children:[["known","Known provider"],["custom","Custom endpoint"]].map(([n,i])=>e.jsx("button",{type:"button","aria-pressed":a===n,onClick:()=>s(n),className:a===n?"rounded-md bg-white px-3 py-1.5 text-sm font-medium text-[var(--otari-ink)] shadow-sm":"rounded-md px-3 py-1.5 text-sm text-[var(--otari-muted)] hover:text-[var(--otari-ink)]",children:i},n))})}),a==="known"?e.jsx(Pe,{onClose:t}):e.jsx(Ne,{onClose:t})]})})}function _e({provider:t,onClose:a}){const s=de(),[n,i]=x.useState(t.provider_type??""),[l,m]=x.useState(t.api_base??""),[v,u]=x.useState(!1),[p,c]=x.useState(""),f=()=>{if(s.isPending)return;const h={provider_type:n.trim()||null,api_base:l.trim()||null,expected_updated_at:t.updated_at};v&&p.trim()&&(h.api_key=p.trim()),s.mutate({instance:t.instance,body:h},{onSuccess:a})};return e.jsx(T,{children:e.jsxs(T.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsxs("div",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:["Edit ",e.jsx("code",{children:t.instance})]}),e.jsx(R,{error:s.error}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsx(A,{label:"Provider type",value:n,onChange:i,placeholder:"openai"}),e.jsx(A,{label:"API base",value:l,onChange:m,placeholder:"https://api.openai.com/v1"})]}),e.jsx("div",{className:"flex flex-col gap-2",children:v?e.jsxs(e.Fragment,{children:[e.jsx(B,{value:p,onChange:c,label:"New API key",description:"Stored encrypted. The old key is replaced when you save."}),e.jsx("button",{type:"button",className:"self-start text-xs font-medium text-[var(--otari-brand-dark)]",onClick:()=>{u(!1),c("")},children:"Keep the current key"})]}):e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsxs("span",{className:"text-sm text-[var(--otari-muted)]",children:["API key: ",e.jsx("code",{children:t.last4?`••••${t.last4}`:"none set"})]}),e.jsx(g,{size:"sm",variant:"outline",onPress:()=>u(!0),children:"Replace key"})]})}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(g,{variant:"primary",isDisabled:s.isPending,onPress:f,children:s.isPending?"Saving…":"Save changes"}),e.jsx(g,{variant:"ghost",onPress:a,children:"Cancel"})]})]})})}function Ce(t,a){const s=new Map((a??[]).map(l=>[l.instance,l])),n=new Map((t??[]).map(l=>[l.instance,l]));return[...new Set([...s.keys(),...n.keys()])].sort().map(l=>{const m=s.get(l);return{instance:l,source:m?"stored":"config",stored:m,meta:n.get(l)}})}function Ae({state:t}){return t?t.status==="pending"?e.jsxs("span",{className:"inline-flex items-center gap-1.5 text-xs text-[var(--otari-muted)]",children:[e.jsx(fe,{size:"sm"})," Testing…"]}):t.ok?e.jsxs("span",{className:"text-xs font-medium text-green-700",children:["Connected. ",t.model_count," model",t.model_count===1?"":"s"," available."]}):e.jsx("span",{className:"block max-w-xs break-words text-xs text-red-700",children:t.error??"Connection failed."}):null}function Te({health:t}){if(!t)return e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"—"});const a=t.ok?"border-green-200 bg-green-50 text-green-700":"border-red-200 bg-red-50 text-red-700",s=t.checked_at?`Last checked ${U(t.checked_at)}`:"Not checked yet",n=t.ok?s:`${t.error??"Unreachable"} · ${s}`;return e.jsxs("span",{title:n,className:`inline-flex items-center gap-1.5 rounded-full border px-2.5 py-0.5 text-xs font-medium ${a}`,children:[e.jsx("span",{"aria-hidden":!0,className:`h-1.5 w-1.5 rounded-full ${t.ok?"bg-green-500":"bg-red-500"}`}),t.ok?"Reachable":"Unreachable"]})}function we({healthy:t,total:a,checkedAt:s}){const n=t===a,i=le();return e.jsxs("div",{className:"flex flex-wrap items-center gap-3 rounded-xl border border-[var(--otari-line)] bg-[var(--otari-surface)] px-4 py-2.5 text-sm",children:[e.jsx("span",{"aria-hidden":!0,className:`h-2 w-2 rounded-full ${n?"bg-green-500":"bg-red-500"}`}),e.jsxs("span",{className:"font-medium text-[var(--otari-ink)]",children:[t," of ",a," provider",a===1?"":"s"," reachable"]}),s?e.jsxs("span",{className:"text-[var(--otari-muted)]",children:["Last checked ",U(s)]}):null,e.jsx(g,{size:"sm",variant:"ghost",className:"ml-auto",isDisabled:i.isPending,onPress:()=>i.mutate(),children:i.isPending?"Re-checking…":"Re-check all"})]})}function K({n:t,title:a,children:s}){return e.jsxs("li",{className:"flex gap-3",children:[e.jsx("span",{className:"flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-[var(--otari-brand-tint)] text-xs font-semibold text-[var(--otari-brand-dark)]",children:t}),e.jsxs("div",{className:"text-sm",children:[e.jsx("div",{className:"font-medium text-[var(--otari-ink)]",children:a}),e.jsx("div",{className:"text-[var(--otari-muted)]",children:s})]})]})}function Ie({onAddProvider:t,needsPricing:a,onEnablePricing:s,enabling:n,secretKeyConfigured:i}){return e.jsx(T,{children:e.jsxs(T.Content,{className:"flex flex-col gap-4 p-6",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-semibold text-[var(--otari-ink)]",children:"Welcome to Otari"}),e.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:"You are signed in. Add a provider to start serving models: three quick steps."})]}),e.jsxs("ol",{className:"flex flex-col gap-3",children:[e.jsxs(K,{n:1,title:"Add a provider",children:["Enter a provider name (like ",e.jsx("code",{children:"openai"}),") and its API key. Keys are encrypted at rest."]}),e.jsxs(K,{n:2,title:"Test the connection",children:["Use ",e.jsx("strong",{children:"Test"})," on the provider row to confirm the key works and see how many models it serves."]}),e.jsxs(K,{n:3,title:"Send your first request",children:["Point your app at ",e.jsx("code",{children:"/v1"})," on this gateway with the API key printed in the server logs (",e.jsx("code",{children:"gw-…"}),"). See the"," ",e.jsx("a",{href:"/welcome",className:"font-medium text-[var(--otari-brand-dark)]",children:"quickstart"}),"."]})]}),a?e.jsxs("p",{className:"text-sm text-[var(--otari-muted)]",children:["Tip: ",e.jsx("code",{children:"require_pricing"})," is on, so requests are rejected until pricing is set."," ",e.jsx("button",{type:"button",className:"font-medium text-[var(--otari-brand-dark)] disabled:opacity-50",disabled:n,onClick:s,children:"Enable default pricing"})," ","to meter new models with public rates."]}):null,e.jsx("div",{children:e.jsx(g,{variant:"primary",isDisabled:!i,onPress:t,children:"Add your first provider"})})]})})}function $e(){var N,L,D,$;const t=X(),a=Z(),s=ee(),n=se(),i=te(),l=ae(),m=ne(),[v,u]=x.useState(!1),[p,c]=x.useState(null),[f,h]=x.useState({}),d=Ce((N=t.data)==null?void 0:N.providers,a.data),y=new Map((((L=n.data)==null?void 0:L.providers)??[]).map(r=>[r.instance,r])),o=t.isLoading||a.isLoading,j=((D=a.data)==null?void 0:D.find(r=>r.instance===p))??null,P=(($=s.data)==null?void 0:$.require_pricing)===!0&&s.data.default_pricing===!1,k=s.data?s.data.secret_key_configured!==!1:!s.isError,w=!o&&d.length===0&&!v,I=r=>{h(b=>({...b,[r]:{status:"pending"}})),l.mutate(r,{onSuccess:b=>h(S=>({...S,[r]:{status:"done",...b}})),onError:b=>h(S=>({...S,[r]:{status:"done",ok:!1,model_count:0,error:M(b)}}))})};return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(re,{title:"Providers",description:"Add provider API keys here to serve models without editing config.yml. Keys are encrypted at rest.",action:v||w?null:e.jsx(g,{variant:"primary",isDisabled:!k,onPress:()=>{c(null),u(!0)},children:"Add provider"})}),e.jsx(R,{error:t.error??a.error??s.error??n.error??m.error??i.error}),k?null:e.jsxs(ie,{tone:"warning",children:[e.jsx("code",{children:"OTARI_SECRET_KEY"})," is not set, so provider keys can't be encrypted at rest and adding providers from the dashboard is disabled. Set it on the server and restart to add providers here. Providers defined in"," ",e.jsx("code",{children:"config.yml"})," keep working without it."]}),w?e.jsx(Ie,{onAddProvider:()=>{c(null),u(!0)},needsPricing:P,onEnablePricing:()=>m.mutate({default_pricing:!0}),enabling:m.isPending,secretKeyConfigured:k}):null,v&&k?e.jsx(Se,{onClose:()=>u(!1)}):null,j?e.jsx(_e,{provider:j,onClose:()=>c(null)}):null,!o&&d.length>0&&n.data&&n.data.total>0?e.jsx(we,{healthy:n.data.healthy,total:n.data.total,checkedAt:n.data.checked_at}):null,e.jsxs(xe,{children:[e.jsx(pe,{children:e.jsxs("tr",{children:[e.jsx(_,{children:"Provider"}),e.jsx(_,{children:"Type"}),e.jsx(_,{children:"Source"}),e.jsx(_,{children:"API key"}),e.jsx(_,{children:"Status"}),e.jsx(_,{className:"text-right",children:"Actions"})]})}),e.jsx("tbody",{children:o?e.jsx(he,{colSpan:6}):d.length===0?e.jsx(ve,{colSpan:6,children:"No providers yet. Add your first provider to start serving models."}):d.map(r=>{var b,S,O,q,F,H;return e.jsxs(ge,{children:[e.jsx(C,{className:"font-medium",children:e.jsx(Q,{to:`/models?provider=${encodeURIComponent(r.instance)}`,className:"text-[var(--otari-ink)] hover:text-[var(--otari-brand-dark)] hover:underline",children:r.instance})}),e.jsx(C,{className:"text-[var(--otari-muted)]",children:((b=r.meta)==null?void 0:b.provider_type)??((S=r.stored)==null?void 0:S.provider_type)??r.instance}),e.jsx(C,{children:r.source==="stored"?e.jsx(z,{size:"sm",color:"accent",children:"stored"}):e.jsx(z,{size:"sm",color:"default",children:"config"})}),e.jsx(C,{className:"text-[var(--otari-muted)]",children:r.source==="stored"?r.stored&&!r.stored.decryptable?e.jsx("span",{className:"text-amber-700",title:"This key can't be decrypted with the current OTARI_SECRET_KEY. Replace the key, or restore the original OTARI_SECRET_KEY.",children:"⚠ key unreadable"}):e.jsx("code",{children:(O=r.stored)!=null&&O.last4?`••••${r.stored.last4}`:"none set"}):(q=r.meta)!=null&&q.env_key?e.jsxs("span",{children:["via ",e.jsx("code",{children:r.meta.env_key})]}):"config.yml"}),e.jsx(C,{children:e.jsx(Te,{health:y.get(r.instance)})}),e.jsx(C,{children:r.source==="stored"?e.jsxs("div",{className:"flex flex-col items-end gap-1.5",children:[e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx(g,{size:"sm",variant:"outline",isDisabled:((F=f[r.instance])==null?void 0:F.status)==="pending"||((H=r.stored)==null?void 0:H.decryptable)===!1,onPress:()=>I(r.instance),children:"Test"}),e.jsx(g,{size:"sm",variant:"ghost",onPress:()=>{u(!1),c(r.instance)},children:"Edit"}),e.jsx(oe,{confirmLabel:"Delete",isPending:i.isPending,onConfirm:()=>i.mutate(r.instance),children:"Delete"})]}),e.jsx(Ae,{state:f[r.instance]})]}):e.jsx("span",{className:"block text-right text-xs text-[var(--otari-muted)]",children:"managed in config.yml"})})]},r.instance)})})]})]})}export{$e as ProvidersPage}; +import{j as e}from"./tanstack-query-1t81HyiD.js";import{r as x,L as Q}from"./react-dgEcD0HR.js";import{J as X,R as Z,B as ee,K as se,T as te,U as ae,V as ne,P as re,E as R,I as ie,C as oe,W as de,X as le,Q as U,h as M,Y,Z as ce,_ as me,$ as ue}from"./index-C94BH4OZ.js";import{F as A}from"./Field-HzRk1KDP.js";import{T as xe,a as pe,b as _,L as he,c as ve,d as ge,e as C}from"./Table-CLdjdyTx.js";import{B as g,f as z,d as T,S as fe,T as je,L as V,I as W,D as be,C as E,a as ye,b as ke}from"./heroui-BX6JwHY-.js";function B({value:t,onChange:a,label:s,placeholder:n,description:i}){return e.jsxs(je,{value:t,onChange:a,className:"flex max-w-md flex-col gap-1",children:[e.jsx(V,{className:"text-sm font-medium text-[var(--otari-ink)]",children:s}),e.jsx(W,{type:"password",placeholder:n??"sk-…",autoComplete:"off",autoCorrect:"off",autoCapitalize:"off",spellCheck:!1,"data-1p-ignore":!0,"data-lpignore":"true"}),i?e.jsx(be,{className:"text-xs text-[var(--otari-muted)]",children:i}):null]})}function G({label:t,value:a,onChange:s,description:n,placeholder:i,extra:l=[],includeCatalog:m=!0}){var y;const v=me(),u=x.useMemo(()=>m?[...l,...(v.data??[]).map(o=>({id:o.id,name:o.name}))]:l,[v.data,l,m]),[p,c]=x.useState(()=>{var o;return((o=u.find(j=>j.id===a))==null?void 0:o.name)??""}),f=((y=u.find(o=>o.id===a))==null?void 0:y.name)??"",h=p.trim()===f.trim()?"":p.trim().toLowerCase(),d=u.filter(o=>!h||o.name.toLowerCase().includes(h)||o.id.toLowerCase().includes(h)).slice(0,50);return e.jsxs(E.Root,{allowsEmptyCollection:!0,menuTrigger:"focus",inputValue:p,onInputChange:c,onSelectionChange:o=>{var j;o!=null?(s(String(o)),c(((j=u.find(P=>P.id===String(o)))==null?void 0:j.name)??"")):(s(""),c(""))},className:"flex max-w-md flex-col gap-1",children:[e.jsx(V,{className:"text-sm font-medium text-[var(--otari-ink)]",children:t}),e.jsxs(E.InputGroup,{children:[e.jsx(W,{placeholder:i??"Search providers…",autoComplete:"off","data-1p-ignore":!0,"data-lpignore":"true",onFocus:o=>o.currentTarget.select()}),e.jsx(E.Trigger,{})]}),e.jsx(E.Popover,{children:e.jsx(ye,{items:d,className:"max-h-72 overflow-auto",children:o=>e.jsx(ke,{id:o.id,textValue:o.name,children:o.name})})}),n?e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:n}):null]})}function J({getPayload:t}){const a=ue(),s=t();return e.jsxs("div",{className:"flex flex-col gap-1.5",children:[e.jsx(g,{variant:"outline",isDisabled:s===null||a.isPending,onPress:()=>{s&&a.mutate(s)},children:a.isPending?"Testing…":"Test connection"}),e.jsx("span",{role:"status","aria-live":"polite",children:a.isPending?null:a.error?e.jsx("span",{className:"text-xs text-red-700",children:M(a.error)}):a.data?a.data.ok?e.jsxs("span",{className:"text-xs font-medium text-green-700",children:["Connected. ",a.data.model_count," model",a.data.model_count===1?"":"s"," available."]}):e.jsx("span",{className:"block max-w-md break-words text-xs text-red-700",children:a.data.error??"Connection failed."}):null})]})}function Pe({onClose:t}){var I;const a=Y(),[s,n]=x.useState(""),[i,l]=x.useState(""),[m,v]=x.useState(!1),[u,p]=x.useState(""),[c,f]=x.useState(""),h=ce(s),d=((I=h.data)==null?void 0:I.id)===s?h.data:void 0;x.useEffect(()=>{d&&p(d.default_api_base??"")},[d]);const y=(d==null?void 0:d.env_key_present)??!1,o=((d==null?void 0:d.requires_api_key)??!0)&&!y,j=c.trim()!==""&&c.trim()!==s,P=/[:/]/.test(c),k=s!==""&&!P&&(!o||i.trim()!=="")&&!a.isPending,w=()=>{k&&a.mutate({instance:j?c.trim():s,provider_type:j?s:null,api_base:u.trim()||null,api_key:i.trim()||null},{onSuccess:t})};return e.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsx(R,{error:a.error}),e.jsx(G,{label:"Provider",value:s,onChange:N=>{n(N),f(""),p("")},description:"Its endpoint is built in."}),e.jsx(B,{value:i,onChange:l,label:d&&!o?"API key (optional)":"API key",description:d?o?`${d.name}'s endpoint is built in — just add your key.`:y?`${d.env_key} is set on the server, so a key is optional here. Paste one to override it.`:`${d.name} needs no API key.`:"Stored encrypted. Requires OTARI_SECRET_KEY on the server."}),e.jsx("button",{type:"button",className:"self-start text-xs font-medium text-[var(--otari-brand-dark)]",onClick:()=>v(N=>!N),children:m?"Hide advanced":"Advanced (API base, rename)"}),m?e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsx(A,{label:"API base",value:u,onChange:p,placeholder:(d==null?void 0:d.default_api_base)??"https://…/v1",description:"Only if you route through a proxy. Blank uses the built-in default."}),e.jsx(A,{label:"Name",value:c,onChange:f,placeholder:s||"instance name",description:P?e.jsx("span",{className:"text-red-700",children:"A name cannot contain “:” or “/”."}):"Rename to run two instances of the same provider."})]}):null,e.jsxs("div",{className:"flex flex-wrap items-start gap-2",children:[e.jsx(g,{variant:"primary",isDisabled:!k,onPress:w,children:a.isPending?"Adding…":"Add provider"}),e.jsx(g,{variant:"ghost",onPress:t,children:"Cancel"}),e.jsx(J,{getPayload:()=>s===""?null:{instance:j?c.trim():s,provider_type:j?s:null,api_base:u.trim()||null,api_key:i.trim()||null}})]})]})}function Ne({onClose:t}){const a=Y(),[s,n]=x.useState(""),[i,l]=x.useState("openai-compatible"),[m,v]=x.useState(""),[u,p]=x.useState(""),c=/[:/]/.test(s),f=s.trim()!==""&&!c&&m.trim()!==""&&!a.isPending,h=()=>{f&&a.mutate({instance:s.trim(),provider_type:i||"openai-compatible",api_base:m.trim(),api_key:u.trim()||null},{onSuccess:t})};return e.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsx(R,{error:a.error}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsx(A,{label:"Name",value:s,onChange:n,placeholder:"my-local-llm",isRequired:!0,autoFocus:!0,description:c?e.jsx("span",{className:"text-red-700",children:"A name cannot contain “:” or “/”."}):"Call it whatever you want."}),e.jsx(G,{label:"Compatible with",value:i,onChange:l,includeCatalog:!1,description:"The API this endpoint speaks.",extra:[{id:"openai-compatible",name:"OpenAI"},{id:"anthropic-compatible",name:"Anthropic"}]})]}),e.jsx(A,{label:"API base",value:m,onChange:v,placeholder:"http://localhost:8000/v1",isRequired:!0,description:"The endpoint URL of your server."}),e.jsx(B,{value:u,onChange:p,label:"API key (optional)",description:"Many local backends need none. Stored encrypted."}),e.jsxs("div",{className:"flex flex-wrap items-start gap-2",children:[e.jsx(g,{variant:"primary",isDisabled:!f,onPress:h,children:a.isPending?"Adding…":"Add provider"}),e.jsx(g,{variant:"ghost",onPress:t,children:"Cancel"}),e.jsx(J,{getPayload:()=>s.trim()===""||m.trim()===""?null:{instance:s.trim(),provider_type:i||"openai-compatible",api_base:m.trim(),api_key:u.trim()||null}})]})]})}function Se({onClose:t}){const[a,s]=x.useState("known");return e.jsx(T,{children:e.jsxs(T.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsx("div",{className:"flex items-center justify-between",children:e.jsx("div",{className:"flex items-center gap-1 rounded-lg bg-[var(--otari-bg)] p-1",children:[["known","Known provider"],["custom","Custom endpoint"]].map(([n,i])=>e.jsx("button",{type:"button","aria-pressed":a===n,onClick:()=>s(n),className:a===n?"rounded-md bg-white px-3 py-1.5 text-sm font-medium text-[var(--otari-ink)] shadow-sm":"rounded-md px-3 py-1.5 text-sm text-[var(--otari-muted)] hover:text-[var(--otari-ink)]",children:i},n))})}),a==="known"?e.jsx(Pe,{onClose:t}):e.jsx(Ne,{onClose:t})]})})}function _e({provider:t,onClose:a}){const s=de(),[n,i]=x.useState(t.provider_type??""),[l,m]=x.useState(t.api_base??""),[v,u]=x.useState(!1),[p,c]=x.useState(""),f=()=>{if(s.isPending)return;const h={provider_type:n.trim()||null,api_base:l.trim()||null,expected_updated_at:t.updated_at};v&&p.trim()&&(h.api_key=p.trim()),s.mutate({instance:t.instance,body:h},{onSuccess:a})};return e.jsx(T,{children:e.jsxs(T.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsxs("div",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:["Edit ",e.jsx("code",{children:t.instance})]}),e.jsx(R,{error:s.error}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsx(A,{label:"Provider type",value:n,onChange:i,placeholder:"openai"}),e.jsx(A,{label:"API base",value:l,onChange:m,placeholder:"https://api.openai.com/v1"})]}),e.jsx("div",{className:"flex flex-col gap-2",children:v?e.jsxs(e.Fragment,{children:[e.jsx(B,{value:p,onChange:c,label:"New API key",description:"Stored encrypted. The old key is replaced when you save."}),e.jsx("button",{type:"button",className:"self-start text-xs font-medium text-[var(--otari-brand-dark)]",onClick:()=>{u(!1),c("")},children:"Keep the current key"})]}):e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsxs("span",{className:"text-sm text-[var(--otari-muted)]",children:["API key: ",e.jsx("code",{children:t.last4?`••••${t.last4}`:"none set"})]}),e.jsx(g,{size:"sm",variant:"outline",onPress:()=>u(!0),children:"Replace key"})]})}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(g,{variant:"primary",isDisabled:s.isPending,onPress:f,children:s.isPending?"Saving…":"Save changes"}),e.jsx(g,{variant:"ghost",onPress:a,children:"Cancel"})]})]})})}function Ce(t,a){const s=new Map((a??[]).map(l=>[l.instance,l])),n=new Map((t??[]).map(l=>[l.instance,l]));return[...new Set([...s.keys(),...n.keys()])].sort().map(l=>{const m=s.get(l);return{instance:l,source:m?"stored":"config",stored:m,meta:n.get(l)}})}function Ae({state:t}){return t?t.status==="pending"?e.jsxs("span",{className:"inline-flex items-center gap-1.5 text-xs text-[var(--otari-muted)]",children:[e.jsx(fe,{size:"sm"})," Testing…"]}):t.ok?e.jsxs("span",{className:"text-xs font-medium text-green-700",children:["Connected. ",t.model_count," model",t.model_count===1?"":"s"," available."]}):e.jsx("span",{className:"block max-w-xs break-words text-xs text-red-700",children:t.error??"Connection failed."}):null}function Te({health:t}){if(!t)return e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"—"});const a=t.ok?"border-green-200 bg-green-50 text-green-700":"border-red-200 bg-red-50 text-red-700",s=t.checked_at?`Last checked ${U(t.checked_at)}`:"Not checked yet",n=t.ok?s:`${t.error??"Unreachable"} · ${s}`;return e.jsxs("span",{title:n,className:`inline-flex items-center gap-1.5 rounded-full border px-2.5 py-0.5 text-xs font-medium ${a}`,children:[e.jsx("span",{"aria-hidden":!0,className:`h-1.5 w-1.5 rounded-full ${t.ok?"bg-green-500":"bg-red-500"}`}),t.ok?"Reachable":"Unreachable"]})}function we({healthy:t,total:a,checkedAt:s}){const n=t===a,i=le();return e.jsxs("div",{className:"flex flex-wrap items-center gap-3 rounded-xl border border-[var(--otari-line)] bg-[var(--otari-surface)] px-4 py-2.5 text-sm",children:[e.jsx("span",{"aria-hidden":!0,className:`h-2 w-2 rounded-full ${n?"bg-green-500":"bg-red-500"}`}),e.jsxs("span",{className:"font-medium text-[var(--otari-ink)]",children:[t," of ",a," provider",a===1?"":"s"," reachable"]}),s?e.jsxs("span",{className:"text-[var(--otari-muted)]",children:["Last checked ",U(s)]}):null,e.jsx(g,{size:"sm",variant:"ghost",className:"ml-auto",isDisabled:i.isPending,onPress:()=>i.mutate(),children:i.isPending?"Re-checking…":"Re-check all"})]})}function K({n:t,title:a,children:s}){return e.jsxs("li",{className:"flex gap-3",children:[e.jsx("span",{className:"flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-[var(--otari-brand-tint)] text-xs font-semibold text-[var(--otari-brand-dark)]",children:t}),e.jsxs("div",{className:"text-sm",children:[e.jsx("div",{className:"font-medium text-[var(--otari-ink)]",children:a}),e.jsx("div",{className:"text-[var(--otari-muted)]",children:s})]})]})}function Ie({onAddProvider:t,needsPricing:a,onEnablePricing:s,enabling:n,secretKeyConfigured:i}){return e.jsx(T,{children:e.jsxs(T.Content,{className:"flex flex-col gap-4 p-6",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-semibold text-[var(--otari-ink)]",children:"Welcome to Otari"}),e.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:"You are signed in. Add a provider to start serving models: three quick steps."})]}),e.jsxs("ol",{className:"flex flex-col gap-3",children:[e.jsxs(K,{n:1,title:"Add a provider",children:["Enter a provider name (like ",e.jsx("code",{children:"openai"}),") and its API key. Keys are encrypted at rest."]}),e.jsxs(K,{n:2,title:"Test the connection",children:["Use ",e.jsx("strong",{children:"Test"})," on the provider row to confirm the key works and see how many models it serves."]}),e.jsxs(K,{n:3,title:"Send your first request",children:["Point your app at ",e.jsx("code",{children:"/v1"})," on this gateway with the API key printed in the server logs (",e.jsx("code",{children:"gw-…"}),"). See the"," ",e.jsx("a",{href:"/welcome",className:"font-medium text-[var(--otari-brand-dark)]",children:"quickstart"}),"."]})]}),a?e.jsxs("p",{className:"text-sm text-[var(--otari-muted)]",children:["Tip: ",e.jsx("code",{children:"require_pricing"})," is on, so requests are rejected until pricing is set."," ",e.jsx("button",{type:"button",className:"font-medium text-[var(--otari-brand-dark)] disabled:opacity-50",disabled:n,onClick:s,children:"Enable default pricing"})," ","to meter new models with public rates."]}):null,e.jsx("div",{children:e.jsx(g,{variant:"primary",isDisabled:!i,onPress:t,children:"Add your first provider"})})]})})}function $e(){var N,L,D,$;const t=X(),a=Z(),s=ee(),n=se(),i=te(),l=ae(),m=ne(),[v,u]=x.useState(!1),[p,c]=x.useState(null),[f,h]=x.useState({}),d=Ce((N=t.data)==null?void 0:N.providers,a.data),y=new Map((((L=n.data)==null?void 0:L.providers)??[]).map(r=>[r.instance,r])),o=t.isLoading||a.isLoading,j=((D=a.data)==null?void 0:D.find(r=>r.instance===p))??null,P=(($=s.data)==null?void 0:$.require_pricing)===!0&&s.data.default_pricing===!1,k=s.data?s.data.secret_key_configured!==!1:!s.isError,w=!o&&d.length===0&&!v,I=r=>{h(b=>({...b,[r]:{status:"pending"}})),l.mutate(r,{onSuccess:b=>h(S=>({...S,[r]:{status:"done",...b}})),onError:b=>h(S=>({...S,[r]:{status:"done",ok:!1,model_count:0,error:M(b)}}))})};return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(re,{title:"Providers",description:"Add provider API keys here to serve models without editing config.yml. Keys are encrypted at rest.",action:v||w?null:e.jsx(g,{variant:"primary",isDisabled:!k,onPress:()=>{c(null),u(!0)},children:"Add provider"})}),e.jsx(R,{error:t.error??a.error??s.error??n.error??m.error??i.error}),k?null:e.jsxs(ie,{tone:"warning",children:[e.jsx("code",{children:"OTARI_SECRET_KEY"})," is not set, so provider keys can't be encrypted at rest and adding providers from the dashboard is disabled. Set it on the server and restart to add providers here. Providers defined in"," ",e.jsx("code",{children:"config.yml"})," keep working without it."]}),w?e.jsx(Ie,{onAddProvider:()=>{c(null),u(!0)},needsPricing:P,onEnablePricing:()=>m.mutate({default_pricing:!0}),enabling:m.isPending,secretKeyConfigured:k}):null,v&&k?e.jsx(Se,{onClose:()=>u(!1)}):null,j?e.jsx(_e,{provider:j,onClose:()=>c(null)}):null,!o&&d.length>0&&n.data&&n.data.total>0?e.jsx(we,{healthy:n.data.healthy,total:n.data.total,checkedAt:n.data.checked_at}):null,e.jsxs(xe,{children:[e.jsx(pe,{children:e.jsxs("tr",{children:[e.jsx(_,{children:"Provider"}),e.jsx(_,{children:"Type"}),e.jsx(_,{children:"Source"}),e.jsx(_,{children:"API key"}),e.jsx(_,{children:"Status"}),e.jsx(_,{className:"text-right",children:"Actions"})]})}),e.jsx("tbody",{children:o?e.jsx(he,{colSpan:6}):d.length===0?e.jsx(ve,{colSpan:6,children:"No providers yet. Add your first provider to start serving models."}):d.map(r=>{var b,S,O,q,F,H;return e.jsxs(ge,{children:[e.jsx(C,{className:"font-medium",children:e.jsx(Q,{to:`/models?provider=${encodeURIComponent(r.instance)}`,className:"text-[var(--otari-ink)] hover:text-[var(--otari-brand-dark)] hover:underline",children:r.instance})}),e.jsx(C,{className:"text-[var(--otari-muted)]",children:((b=r.meta)==null?void 0:b.provider_type)??((S=r.stored)==null?void 0:S.provider_type)??r.instance}),e.jsx(C,{children:r.source==="stored"?e.jsx(z,{size:"sm",color:"accent",children:"stored"}):e.jsx(z,{size:"sm",color:"default",children:"config"})}),e.jsx(C,{className:"text-[var(--otari-muted)]",children:r.source==="stored"?r.stored&&!r.stored.decryptable?e.jsx("span",{className:"text-amber-700",title:"This key can't be decrypted with the current OTARI_SECRET_KEY. Replace the key, or restore the original OTARI_SECRET_KEY.",children:"⚠ key unreadable"}):e.jsx("code",{children:(O=r.stored)!=null&&O.last4?`••••${r.stored.last4}`:"none set"}):(q=r.meta)!=null&&q.env_key?e.jsxs("span",{children:["via ",e.jsx("code",{children:r.meta.env_key})]}):"config.yml"}),e.jsx(C,{children:e.jsx(Te,{health:y.get(r.instance)})}),e.jsx(C,{children:r.source==="stored"?e.jsxs("div",{className:"flex flex-col items-end gap-1.5",children:[e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx(g,{size:"sm",variant:"outline",isDisabled:((F=f[r.instance])==null?void 0:F.status)==="pending"||((H=r.stored)==null?void 0:H.decryptable)===!1,onPress:()=>I(r.instance),children:"Test"}),e.jsx(g,{size:"sm",variant:"ghost",onPress:()=>{u(!1),c(r.instance)},children:"Edit"}),e.jsx(oe,{confirmLabel:"Delete",isPending:i.isPending,onConfirm:()=>i.mutate(r.instance),children:"Delete"})]}),e.jsx(Ae,{state:f[r.instance]})]}):e.jsx("span",{className:"block text-right text-xs text-[var(--otari-muted)]",children:"managed in config.yml"})})]},r.instance)})})]})]})}export{$e as ProvidersPage}; diff --git a/src/gateway/static/dashboard/assets/SettingsPage-hENBFRMI.js b/src/gateway/static/dashboard/assets/SettingsPage-BdorKXf4.js similarity index 99% rename from src/gateway/static/dashboard/assets/SettingsPage-hENBFRMI.js rename to src/gateway/static/dashboard/assets/SettingsPage-BdorKXf4.js index 6fba6cdb..5158d517 100644 --- a/src/gateway/static/dashboard/assets/SettingsPage-hENBFRMI.js +++ b/src/gateway/static/dashboard/assets/SettingsPage-BdorKXf4.js @@ -1 +1 @@ -import{j as e}from"./tanstack-query-1t81HyiD.js";import{r as u}from"./react-dgEcD0HR.js";import{B as R,V as C,P,E as y,a0 as E,a1 as T,a2 as _,F as D,a3 as A,R as O,a4 as F,I as w}from"./index-BJySXQ_a.js";import{d as v,B as h,A as d,g as I,I as K}from"./heroui-BX6JwHY-.js";function b(t,r){return{[t]:r}}function z(t,r){let s=0;for(const a of r)if(a===t[s]&&(s+=1),s===t.length)return!0;return t.length===0}function M(t,r){const s=r.trim().toLowerCase();if(s==="")return!0;const a=`${t.key} ${t.description??""} ${t.group}`.toLowerCase(),n=t.key.toLowerCase().replace(/[^a-z0-9]/g,"");return s.split(/\s+/).every(i=>a.includes(i)||z(i,n))}function B({checked:t,onChange:r,label:s,disabled:a}){return e.jsx("button",{type:"button",role:"switch","aria-checked":t,"aria-label":s,disabled:a,onClick:()=>r(!t),className:`relative inline-flex h-6 w-11 shrink-0 items-center rounded-full transition-colors disabled:opacity-50 ${t?"bg-[var(--otari-brand)]":"bg-[var(--otari-line)]"}`,children:e.jsx("span",{className:`inline-block h-5 w-5 transform rounded-full bg-white shadow transition-transform ${t?"translate-x-5":"translate-x-0.5"}`})})}function L({field:t,onSave:r,disabled:s}){const a=typeof t.value=="number"?t.value:0,[n,i]=u.useState(String(a)),o=t.type==="float";u.useEffect(()=>{i(String(a))},[a]);const c=Number(n),p=n.trim()!==""&&Number.isFinite(c)&&(o||Number.isInteger(c)),m=t.minimum??void 0,x=t.exclusive_minimum??void 0,g=x!==void 0?c>x:m!==void 0?c>=m:c>=0,l=p&&g&&c!==a;return e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(K,{type:"number",min:"0",step:o?"any":"1",inputMode:o?"decimal":"numeric","aria-label":t.key,value:n,disabled:s,onChange:f=>i(f.target.value),className:"w-28 rounded-md border border-[var(--otari-line)] bg-white px-2 py-1 text-right text-sm tabular-nums focus:border-[var(--otari-brand)] focus:outline-none disabled:opacity-50"}),e.jsx(h,{size:"sm",variant:"primary","aria-label":`Save ${t.key}`,isDisabled:s||!l,onPress:()=>r(c),children:"Save"})]})}function $({field:t,onSave:r,disabled:s}){const a=typeof t.value=="string"?t.value:"",[n,i]=u.useState(a);u.useEffect(()=>{i(a)},[a]);const o=n!==a;return e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("input",{type:"text","aria-label":t.key,value:n,disabled:s,placeholder:"unset",onChange:c=>i(c.target.value),className:"w-56 rounded-md border border-[var(--otari-line)] bg-white px-2 py-1 text-sm focus:border-[var(--otari-brand)] focus:outline-none disabled:opacity-50"}),e.jsx(h,{size:"sm",variant:"primary","aria-label":`Save ${t.key}`,isDisabled:s||!o,onPress:()=>r(n.trim()===""?null:n),children:"Save"})]})}function H(t){const{value:r}=t;return r==null?"unset":typeof r=="boolean"?r?"on":"off":Array.isArray(r)?r.length?r.join(", "):"none":String(r)}function Y({field:t,patch:r,disabled:s}){return t.settable?t.type==="bool"?e.jsx(B,{checked:t.value===!0,onChange:a=>r(b(t.key,a)),label:t.key,disabled:s}):t.options&&t.options.length>0?e.jsx(D,{ariaLabel:t.key,value:String(t.value??""),onChange:a=>r(b(t.key,a)),options:t.options.map(a=>({value:a,label:a}))}):t.type==="int"||t.type==="float"?e.jsx(L,{field:t,onSave:a=>r(b(t.key,a)),disabled:s}):e.jsx($,{field:t,onSave:a=>r(b(t.key,a)),disabled:s}):e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-sm tabular-nums text-[var(--otari-ink)]",children:H(t)}),e.jsx("span",{className:"rounded-full border border-[var(--otari-line)] px-2 py-0.5 text-xs text-[var(--otari-muted)]",children:"startup-only"})]})}function q({field:t,patch:r,disabled:s}){return e.jsxs("div",{className:"flex items-start justify-between gap-6 py-4",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("code",{className:"text-sm font-medium text-[var(--otari-ink)]",children:t.key}),t.description?e.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:t.description}):null]}),e.jsx("div",{className:"shrink-0 pt-0.5",children:e.jsx(Y,{field:t,patch:r,disabled:s})})]})}function V({value:t,fieldRef:r}){const s=u.useRef(null),a=r??s,[n,i]=u.useState(!1),[o,c]=u.useState(!1),p=async()=>{var m,x,g;(m=a.current)==null||m.focus(),(x=a.current)==null||x.select();try{if((g=navigator.clipboard)!=null&&g.writeText){await navigator.clipboard.writeText(t),i(!0),c(!1),window.setTimeout(()=>i(!1),2e3);return}}catch{}c(!0)};return e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-xs font-medium text-[var(--otari-muted)]",children:"New master key"}),e.jsx(h,{size:"sm",variant:"outline",onPress:p,children:n?"Copied":"Copy"})]}),e.jsx("input",{ref:a,readOnly:!0,value:t,onFocus:m=>m.currentTarget.select(),autoComplete:"off",autoCorrect:"off",autoCapitalize:"off",spellCheck:!1,"data-1p-ignore":!0,"data-lpignore":"true"}),e.jsx("span",{"aria-live":"polite",className:"text-xs text-[var(--otari-brand-dark)]",children:n?"Copied to clipboard.":""}),o?e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"Selected. Press Ctrl/Cmd-C to copy."}):null]})}function U({masterKey:t,error:r,isPending:s,onRegenerate:a,onClose:n}){const i=u.useRef(null);return u.useEffect(()=>{var o,c;t!==void 0&&((o=i.current)==null||o.focus(),(c=i.current)==null||c.select())},[t]),e.jsx(d.Backdrop,{children:e.jsx(d.Container,{placement:"center",size:"lg",children:e.jsxs(d.Dialog,{children:[e.jsx(d.Header,{children:e.jsx(d.Heading,{children:t!==void 0?"Master key regenerated":"Regenerate master key?"})}),e.jsx(d.Body,{className:"flex flex-col gap-4",children:t!==void 0?e.jsxs(e.Fragment,{children:[e.jsx(w,{tone:"warning",children:"Copy this key now. It is shown once and cannot be retrieved again after you close this dialog."}),e.jsx("p",{className:"text-sm text-[var(--otari-muted)]",children:"The previous master key has stopped working. This browser tab now uses the new key."}),e.jsx(V,{value:t,fieldRef:i})]}):e.jsxs(e.Fragment,{children:[e.jsx(w,{tone:"warning",children:"This immediately invalidates the current dashboard master key. Other signed-in dashboard sessions will need the new key to continue."}),e.jsx("p",{className:"text-sm text-[var(--otari-muted)]",children:"The replacement key will be shown once. Save it before closing the next screen."}),e.jsx(y,{error:r})]})}),e.jsx(d.Footer,{children:t!==void 0?e.jsx(h,{variant:"primary",onPress:n,children:"I’ve saved this key"}):e.jsxs(e.Fragment,{children:[e.jsx(h,{variant:"ghost",isDisabled:s,onPress:n,children:"Cancel"}),e.jsx(h,{variant:"danger",isPending:s,onPress:a,children:"Regenerate key"})]})})]})})})}function G({source:t}){const r=A(),[s,a]=u.useState(!1),[n,i]=u.useState(),o=t==="generated",c=()=>r.mutate(void 0,{onSuccess:x=>{i(x.master_key)}}),p=()=>{a(!1),i(void 0),r.reset()},m=x=>{x?(r.reset(),a(!0)):n===void 0&&p()};return e.jsx("div",{className:"flex flex-col gap-4 py-4",children:e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("code",{className:"text-sm font-medium text-[var(--otari-ink)]",children:"master_key"}),e.jsx("p",{className:"mt-1 max-w-3xl text-sm text-[var(--otari-muted)]",children:o?"This gateway uses its first-run generated dashboard key. Regeneration invalidates the current key immediately.":"This gateway uses a key managed through OTARI_MASTER_KEY or config.yml. Rotate it in configuration, then restart the gateway."})]}),e.jsxs(d,{isOpen:s,onOpenChange:m,children:[o?e.jsx(d.Trigger,{className:I({size:"sm",variant:"danger-soft"}),children:"Regenerate"}):e.jsx(h,{size:"sm",variant:"danger-soft",isDisabled:!0,children:"Managed in configuration"}),s?e.jsx(U,{masterKey:n,error:r.error,isPending:r.isPending,onRegenerate:c,onClose:p}):null]})]})})}function X(){var o;const t=O(),r=F(),s=r.data,a=((o=t.data)==null?void 0:o.length)??0,n=(t.data??[]).filter(c=>!c.decryptable).length,i=a>0;return e.jsxs("div",{className:"flex flex-col gap-4 py-4",children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("code",{className:"text-sm font-medium text-[var(--otari-ink)]",children:"OTARI_SECRET_KEY"}),e.jsxs("p",{className:"mt-1 max-w-3xl text-sm text-[var(--otari-muted)]",children:["Generate a new key with ",e.jsx("code",{children:"uv run otari gen-secret-key"}),", then restart with"," ",e.jsx("code",{children:"OTARI_SECRET_KEY=,"}),". Re-encrypt the stored provider keys, then restart with ",e.jsx("code",{children:"OTARI_SECRET_KEY="})," once none are unreadable."]})]}),e.jsx("div",{className:"shrink-0",children:e.jsx(h,{size:"sm",variant:"outline",isDisabled:!i||r.isPending,onPress:()=>r.mutate(),children:r.isPending?"Re-encrypting…":"Re-encrypt provider keys"})})]}),e.jsx(y,{error:t.error??r.error}),n>0?e.jsxs(w,{tone:"warning",children:[n," stored provider key",n===1?"":"s"," cannot be decrypted with the current"," ",e.jsx("code",{children:"OTARI_SECRET_KEY"}),". Restore the old secret key and re-encrypt, or edit each affected provider and replace its key."]}):null,s?e.jsxs("p",{className:"text-sm text-[var(--otari-muted)]",role:"status","aria-live":"polite",children:["Re-encrypted ",s.reencrypted," provider key",s.reencrypted===1?"":"s",".",s.unreadable>0?` ${s.unreadable} still need replacement.`:" All decryptable stored keys now use the primary secret key."]}):!t.isLoading&&!i?e.jsx("p",{className:"text-sm text-[var(--otari-muted)]",children:"No stored provider keys need re-encryption."}):null]})}function J({masterKeySource:t}){return e.jsxs("section",{className:"flex flex-col gap-2",children:[e.jsxs("h2",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:["Credential security ",e.jsx("span",{className:"font-normal text-[var(--otari-muted)]",children:"(2)"})]}),e.jsx(v,{children:e.jsxs(v.Content,{className:"flex flex-col divide-y divide-[var(--otari-line)] px-5 py-1",children:[e.jsx(G,{source:t}),e.jsx(X,{})]})})]})}function Q({preview:t,error:r,isPending:s,onAccept:a,onReject:n}){return e.jsx(d.Backdrop,{children:e.jsx(d.Container,{placement:"center",size:"lg",children:e.jsxs(d.Dialog,{children:[e.jsx(d.Header,{children:e.jsx(d.Heading,{children:"Review default price updates"})}),e.jsxs(d.Body,{className:"flex flex-col gap-4",children:[e.jsxs("p",{className:"text-sm text-[var(--otari-muted)]",children:[t.added_count," added, ",t.changed_count," changed, and ",t.removed_count," removed upstream model prices. The accepted catalog is saved in the database with source ",e.jsx("code",{children:"genai-prices"})," and reloads after a restart. Your ",t.protected_model_count," custom model price",t.protected_model_count===1?"":"s"," remain unchanged."]}),t.changes.length>0?e.jsx("ul",{className:"max-h-60 list-disc overflow-auto pl-5 text-sm text-[var(--otari-ink)]",children:t.changes.map(i=>e.jsxs("li",{children:[i.model_key,": ",i.change]},i.model_key))}):null,t.changes_truncated?e.jsx("p",{className:"text-xs text-[var(--otari-muted)]",children:"Only the first 100 changes are shown."}):null,e.jsx(y,{error:r})]}),e.jsxs(d.Footer,{children:[e.jsx(h,{variant:"ghost",isDisabled:s,onPress:n,children:"Reject changes"}),e.jsx(h,{variant:"primary",isPending:s,onPress:a,children:"Accept price updates"})]})]})})})}function W(){const t=E(),r=T(),s=_(),a=t.data,n=r.isPending||s.isPending,i=()=>{a===void 0||n||s.mutate(void 0,{onSuccess:t.reset})};return e.jsxs("section",{className:"flex flex-col gap-2",children:[e.jsx("h2",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:"Default pricing catalog"}),e.jsx(v,{children:e.jsxs(v.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"text-sm font-medium text-[var(--otari-ink)]",children:"genai-prices defaults"}),e.jsxs("p",{className:"mt-1 max-w-3xl text-sm text-[var(--otari-muted)]",children:["Fetch the latest upstream catalog, review the proposed change summary, then accept or reject it. Accepted data is stored as ",e.jsx("code",{children:"genai-prices"}),"; custom prices remain separate and always take precedence."]})]}),e.jsx(h,{size:"sm",variant:"outline",isDisabled:t.isPending||n,onPress:()=>t.mutate(),children:t.isPending?"Checking prices…":"Check for price updates"})]}),e.jsx(y,{error:t.error})]})}),e.jsxs(d,{isOpen:a!==void 0,onOpenChange:o=>o?void 0:i(),children:[e.jsx(d.Trigger,{className:"hidden",children:"Review price updates"}),a?e.jsx(Q,{preview:a,error:r.error??s.error,isPending:n,onAccept:()=>r.mutate(void 0,{onSuccess:t.reset}),onReject:i}):null]})]})}function Z(t){const r=[],s=new Map;for(const a of t){let n=s.get(a.group);n||(n={name:a.group,fields:[]},s.set(a.group,n),r.push(n)),n.fields.push(a)}return r}function ae(){const t=R(),r=C(),s=t.data,a=r.isPending,[n,i]=u.useState(""),[o,c]=u.useState(!1),p=u.useRef(null);u.useEffect(()=>{function l(f){var N;const j=f.target,S=j&&(j.tagName==="INPUT"||j.tagName==="TEXTAREA"||j.tagName==="SELECT");f.key==="/"&&!S&&(f.preventDefault(),(N=p.current)==null||N.focus())}return window.addEventListener("keydown",l),()=>window.removeEventListener("keydown",l)},[]);const m=l=>r.mutate(l),x=(s==null?void 0:s.config)??[],g=x.filter(l=>(o?l.settable:!0)&&M(l,n)),k=Z(g);return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(P,{title:"Settings",description:"Every effective gateway setting. Settable fields apply immediately and persist across restarts; startup-only fields are shown for reference and change only via config.yml or environment variables (then a restart)."}),e.jsx(y,{error:t.error??r.error}),e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsx("input",{ref:p,type:"search","aria-label":"Search settings",placeholder:"Search settings (press / to focus)…",value:n,onChange:l=>i(l.target.value),onKeyDown:l=>{l.key==="Escape"&&i("")},className:"min-w-0 flex-1 rounded-lg border border-[var(--otari-line)] bg-[var(--otari-bg)] px-3 py-2 text-sm text-[var(--otari-ink)] focus:border-[var(--otari-brand)] focus:outline-none"}),e.jsxs("label",{className:"flex items-center gap-2 text-sm text-[var(--otari-muted)]",children:[e.jsx("input",{type:"checkbox",checked:o,onChange:l=>c(l.target.checked),className:"h-4 w-4 accent-[var(--otari-brand)]"}),"Settable only"]})]}),s?e.jsxs("p",{className:"text-xs text-[var(--otari-muted)]",children:["Showing ",g.length," of ",x.length," settings"]}):null,s&&g.length===0?e.jsx("p",{className:"text-sm text-[var(--otari-muted)]",children:"No settings match your search."}):null,k.map(l=>e.jsxs("section",{className:"flex flex-col gap-2",children:[e.jsxs("h2",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:[l.name," ",e.jsxs("span",{className:"font-normal text-[var(--otari-muted)]",children:["(",l.fields.length,")"]})]}),e.jsx(v,{children:e.jsx(v.Content,{className:"flex flex-col divide-y divide-[var(--otari-line)] px-5 py-1",children:l.fields.map(f=>e.jsx(q,{field:f,patch:m,disabled:!s||a},f.key))})})]},l.name)),s?e.jsx(W,{}):null,s?e.jsx(J,{masterKeySource:s.master_key_source}):null,s?e.jsxs("p",{className:"text-xs text-[var(--otari-muted)]",children:["Mode: ",s.mode," · Version ",s.version,s.require_pricing?" · require_pricing on":""]}):null]})}export{ae as SettingsPage,M as fieldMatches}; +import{j as e}from"./tanstack-query-1t81HyiD.js";import{r as u}from"./react-dgEcD0HR.js";import{B as R,V as C,P,E as y,a0 as E,a1 as T,a2 as _,F as D,a3 as A,R as O,a4 as F,I as w}from"./index-C94BH4OZ.js";import{d as v,B as h,A as d,g as I,I as K}from"./heroui-BX6JwHY-.js";function b(t,r){return{[t]:r}}function z(t,r){let s=0;for(const a of r)if(a===t[s]&&(s+=1),s===t.length)return!0;return t.length===0}function M(t,r){const s=r.trim().toLowerCase();if(s==="")return!0;const a=`${t.key} ${t.description??""} ${t.group}`.toLowerCase(),n=t.key.toLowerCase().replace(/[^a-z0-9]/g,"");return s.split(/\s+/).every(i=>a.includes(i)||z(i,n))}function B({checked:t,onChange:r,label:s,disabled:a}){return e.jsx("button",{type:"button",role:"switch","aria-checked":t,"aria-label":s,disabled:a,onClick:()=>r(!t),className:`relative inline-flex h-6 w-11 shrink-0 items-center rounded-full transition-colors disabled:opacity-50 ${t?"bg-[var(--otari-brand)]":"bg-[var(--otari-line)]"}`,children:e.jsx("span",{className:`inline-block h-5 w-5 transform rounded-full bg-white shadow transition-transform ${t?"translate-x-5":"translate-x-0.5"}`})})}function L({field:t,onSave:r,disabled:s}){const a=typeof t.value=="number"?t.value:0,[n,i]=u.useState(String(a)),o=t.type==="float";u.useEffect(()=>{i(String(a))},[a]);const c=Number(n),p=n.trim()!==""&&Number.isFinite(c)&&(o||Number.isInteger(c)),m=t.minimum??void 0,x=t.exclusive_minimum??void 0,g=x!==void 0?c>x:m!==void 0?c>=m:c>=0,l=p&&g&&c!==a;return e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(K,{type:"number",min:"0",step:o?"any":"1",inputMode:o?"decimal":"numeric","aria-label":t.key,value:n,disabled:s,onChange:f=>i(f.target.value),className:"w-28 rounded-md border border-[var(--otari-line)] bg-white px-2 py-1 text-right text-sm tabular-nums focus:border-[var(--otari-brand)] focus:outline-none disabled:opacity-50"}),e.jsx(h,{size:"sm",variant:"primary","aria-label":`Save ${t.key}`,isDisabled:s||!l,onPress:()=>r(c),children:"Save"})]})}function $({field:t,onSave:r,disabled:s}){const a=typeof t.value=="string"?t.value:"",[n,i]=u.useState(a);u.useEffect(()=>{i(a)},[a]);const o=n!==a;return e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("input",{type:"text","aria-label":t.key,value:n,disabled:s,placeholder:"unset",onChange:c=>i(c.target.value),className:"w-56 rounded-md border border-[var(--otari-line)] bg-white px-2 py-1 text-sm focus:border-[var(--otari-brand)] focus:outline-none disabled:opacity-50"}),e.jsx(h,{size:"sm",variant:"primary","aria-label":`Save ${t.key}`,isDisabled:s||!o,onPress:()=>r(n.trim()===""?null:n),children:"Save"})]})}function H(t){const{value:r}=t;return r==null?"unset":typeof r=="boolean"?r?"on":"off":Array.isArray(r)?r.length?r.join(", "):"none":String(r)}function Y({field:t,patch:r,disabled:s}){return t.settable?t.type==="bool"?e.jsx(B,{checked:t.value===!0,onChange:a=>r(b(t.key,a)),label:t.key,disabled:s}):t.options&&t.options.length>0?e.jsx(D,{ariaLabel:t.key,value:String(t.value??""),onChange:a=>r(b(t.key,a)),options:t.options.map(a=>({value:a,label:a}))}):t.type==="int"||t.type==="float"?e.jsx(L,{field:t,onSave:a=>r(b(t.key,a)),disabled:s}):e.jsx($,{field:t,onSave:a=>r(b(t.key,a)),disabled:s}):e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-sm tabular-nums text-[var(--otari-ink)]",children:H(t)}),e.jsx("span",{className:"rounded-full border border-[var(--otari-line)] px-2 py-0.5 text-xs text-[var(--otari-muted)]",children:"startup-only"})]})}function q({field:t,patch:r,disabled:s}){return e.jsxs("div",{className:"flex items-start justify-between gap-6 py-4",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("code",{className:"text-sm font-medium text-[var(--otari-ink)]",children:t.key}),t.description?e.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:t.description}):null]}),e.jsx("div",{className:"shrink-0 pt-0.5",children:e.jsx(Y,{field:t,patch:r,disabled:s})})]})}function V({value:t,fieldRef:r}){const s=u.useRef(null),a=r??s,[n,i]=u.useState(!1),[o,c]=u.useState(!1),p=async()=>{var m,x,g;(m=a.current)==null||m.focus(),(x=a.current)==null||x.select();try{if((g=navigator.clipboard)!=null&&g.writeText){await navigator.clipboard.writeText(t),i(!0),c(!1),window.setTimeout(()=>i(!1),2e3);return}}catch{}c(!0)};return e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-xs font-medium text-[var(--otari-muted)]",children:"New master key"}),e.jsx(h,{size:"sm",variant:"outline",onPress:p,children:n?"Copied":"Copy"})]}),e.jsx("input",{ref:a,readOnly:!0,value:t,onFocus:m=>m.currentTarget.select(),autoComplete:"off",autoCorrect:"off",autoCapitalize:"off",spellCheck:!1,"data-1p-ignore":!0,"data-lpignore":"true"}),e.jsx("span",{"aria-live":"polite",className:"text-xs text-[var(--otari-brand-dark)]",children:n?"Copied to clipboard.":""}),o?e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"Selected. Press Ctrl/Cmd-C to copy."}):null]})}function U({masterKey:t,error:r,isPending:s,onRegenerate:a,onClose:n}){const i=u.useRef(null);return u.useEffect(()=>{var o,c;t!==void 0&&((o=i.current)==null||o.focus(),(c=i.current)==null||c.select())},[t]),e.jsx(d.Backdrop,{children:e.jsx(d.Container,{placement:"center",size:"lg",children:e.jsxs(d.Dialog,{children:[e.jsx(d.Header,{children:e.jsx(d.Heading,{children:t!==void 0?"Master key regenerated":"Regenerate master key?"})}),e.jsx(d.Body,{className:"flex flex-col gap-4",children:t!==void 0?e.jsxs(e.Fragment,{children:[e.jsx(w,{tone:"warning",children:"Copy this key now. It is shown once and cannot be retrieved again after you close this dialog."}),e.jsx("p",{className:"text-sm text-[var(--otari-muted)]",children:"The previous master key has stopped working. This browser tab now uses the new key."}),e.jsx(V,{value:t,fieldRef:i})]}):e.jsxs(e.Fragment,{children:[e.jsx(w,{tone:"warning",children:"This immediately invalidates the current dashboard master key. Other signed-in dashboard sessions will need the new key to continue."}),e.jsx("p",{className:"text-sm text-[var(--otari-muted)]",children:"The replacement key will be shown once. Save it before closing the next screen."}),e.jsx(y,{error:r})]})}),e.jsx(d.Footer,{children:t!==void 0?e.jsx(h,{variant:"primary",onPress:n,children:"I’ve saved this key"}):e.jsxs(e.Fragment,{children:[e.jsx(h,{variant:"ghost",isDisabled:s,onPress:n,children:"Cancel"}),e.jsx(h,{variant:"danger",isPending:s,onPress:a,children:"Regenerate key"})]})})]})})})}function G({source:t}){const r=A(),[s,a]=u.useState(!1),[n,i]=u.useState(),o=t==="generated",c=()=>r.mutate(void 0,{onSuccess:x=>{i(x.master_key)}}),p=()=>{a(!1),i(void 0),r.reset()},m=x=>{x?(r.reset(),a(!0)):n===void 0&&p()};return e.jsx("div",{className:"flex flex-col gap-4 py-4",children:e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("code",{className:"text-sm font-medium text-[var(--otari-ink)]",children:"master_key"}),e.jsx("p",{className:"mt-1 max-w-3xl text-sm text-[var(--otari-muted)]",children:o?"This gateway uses its first-run generated dashboard key. Regeneration invalidates the current key immediately.":"This gateway uses a key managed through OTARI_MASTER_KEY or config.yml. Rotate it in configuration, then restart the gateway."})]}),e.jsxs(d,{isOpen:s,onOpenChange:m,children:[o?e.jsx(d.Trigger,{className:I({size:"sm",variant:"danger-soft"}),children:"Regenerate"}):e.jsx(h,{size:"sm",variant:"danger-soft",isDisabled:!0,children:"Managed in configuration"}),s?e.jsx(U,{masterKey:n,error:r.error,isPending:r.isPending,onRegenerate:c,onClose:p}):null]})]})})}function X(){var o;const t=O(),r=F(),s=r.data,a=((o=t.data)==null?void 0:o.length)??0,n=(t.data??[]).filter(c=>!c.decryptable).length,i=a>0;return e.jsxs("div",{className:"flex flex-col gap-4 py-4",children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("code",{className:"text-sm font-medium text-[var(--otari-ink)]",children:"OTARI_SECRET_KEY"}),e.jsxs("p",{className:"mt-1 max-w-3xl text-sm text-[var(--otari-muted)]",children:["Generate a new key with ",e.jsx("code",{children:"uv run otari gen-secret-key"}),", then restart with"," ",e.jsx("code",{children:"OTARI_SECRET_KEY=,"}),". Re-encrypt the stored provider keys, then restart with ",e.jsx("code",{children:"OTARI_SECRET_KEY="})," once none are unreadable."]})]}),e.jsx("div",{className:"shrink-0",children:e.jsx(h,{size:"sm",variant:"outline",isDisabled:!i||r.isPending,onPress:()=>r.mutate(),children:r.isPending?"Re-encrypting…":"Re-encrypt provider keys"})})]}),e.jsx(y,{error:t.error??r.error}),n>0?e.jsxs(w,{tone:"warning",children:[n," stored provider key",n===1?"":"s"," cannot be decrypted with the current"," ",e.jsx("code",{children:"OTARI_SECRET_KEY"}),". Restore the old secret key and re-encrypt, or edit each affected provider and replace its key."]}):null,s?e.jsxs("p",{className:"text-sm text-[var(--otari-muted)]",role:"status","aria-live":"polite",children:["Re-encrypted ",s.reencrypted," provider key",s.reencrypted===1?"":"s",".",s.unreadable>0?` ${s.unreadable} still need replacement.`:" All decryptable stored keys now use the primary secret key."]}):!t.isLoading&&!i?e.jsx("p",{className:"text-sm text-[var(--otari-muted)]",children:"No stored provider keys need re-encryption."}):null]})}function J({masterKeySource:t}){return e.jsxs("section",{className:"flex flex-col gap-2",children:[e.jsxs("h2",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:["Credential security ",e.jsx("span",{className:"font-normal text-[var(--otari-muted)]",children:"(2)"})]}),e.jsx(v,{children:e.jsxs(v.Content,{className:"flex flex-col divide-y divide-[var(--otari-line)] px-5 py-1",children:[e.jsx(G,{source:t}),e.jsx(X,{})]})})]})}function Q({preview:t,error:r,isPending:s,onAccept:a,onReject:n}){return e.jsx(d.Backdrop,{children:e.jsx(d.Container,{placement:"center",size:"lg",children:e.jsxs(d.Dialog,{children:[e.jsx(d.Header,{children:e.jsx(d.Heading,{children:"Review default price updates"})}),e.jsxs(d.Body,{className:"flex flex-col gap-4",children:[e.jsxs("p",{className:"text-sm text-[var(--otari-muted)]",children:[t.added_count," added, ",t.changed_count," changed, and ",t.removed_count," removed upstream model prices. The accepted catalog is saved in the database with source ",e.jsx("code",{children:"genai-prices"})," and reloads after a restart. Your ",t.protected_model_count," custom model price",t.protected_model_count===1?"":"s"," remain unchanged."]}),t.changes.length>0?e.jsx("ul",{className:"max-h-60 list-disc overflow-auto pl-5 text-sm text-[var(--otari-ink)]",children:t.changes.map(i=>e.jsxs("li",{children:[i.model_key,": ",i.change]},i.model_key))}):null,t.changes_truncated?e.jsx("p",{className:"text-xs text-[var(--otari-muted)]",children:"Only the first 100 changes are shown."}):null,e.jsx(y,{error:r})]}),e.jsxs(d.Footer,{children:[e.jsx(h,{variant:"ghost",isDisabled:s,onPress:n,children:"Reject changes"}),e.jsx(h,{variant:"primary",isPending:s,onPress:a,children:"Accept price updates"})]})]})})})}function W(){const t=E(),r=T(),s=_(),a=t.data,n=r.isPending||s.isPending,i=()=>{a===void 0||n||s.mutate(void 0,{onSuccess:t.reset})};return e.jsxs("section",{className:"flex flex-col gap-2",children:[e.jsx("h2",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:"Default pricing catalog"}),e.jsx(v,{children:e.jsxs(v.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"text-sm font-medium text-[var(--otari-ink)]",children:"genai-prices defaults"}),e.jsxs("p",{className:"mt-1 max-w-3xl text-sm text-[var(--otari-muted)]",children:["Fetch the latest upstream catalog, review the proposed change summary, then accept or reject it. Accepted data is stored as ",e.jsx("code",{children:"genai-prices"}),"; custom prices remain separate and always take precedence."]})]}),e.jsx(h,{size:"sm",variant:"outline",isDisabled:t.isPending||n,onPress:()=>t.mutate(),children:t.isPending?"Checking prices…":"Check for price updates"})]}),e.jsx(y,{error:t.error})]})}),e.jsxs(d,{isOpen:a!==void 0,onOpenChange:o=>o?void 0:i(),children:[e.jsx(d.Trigger,{className:"hidden",children:"Review price updates"}),a?e.jsx(Q,{preview:a,error:r.error??s.error,isPending:n,onAccept:()=>r.mutate(void 0,{onSuccess:t.reset}),onReject:i}):null]})]})}function Z(t){const r=[],s=new Map;for(const a of t){let n=s.get(a.group);n||(n={name:a.group,fields:[]},s.set(a.group,n),r.push(n)),n.fields.push(a)}return r}function ae(){const t=R(),r=C(),s=t.data,a=r.isPending,[n,i]=u.useState(""),[o,c]=u.useState(!1),p=u.useRef(null);u.useEffect(()=>{function l(f){var N;const j=f.target,S=j&&(j.tagName==="INPUT"||j.tagName==="TEXTAREA"||j.tagName==="SELECT");f.key==="/"&&!S&&(f.preventDefault(),(N=p.current)==null||N.focus())}return window.addEventListener("keydown",l),()=>window.removeEventListener("keydown",l)},[]);const m=l=>r.mutate(l),x=(s==null?void 0:s.config)??[],g=x.filter(l=>(o?l.settable:!0)&&M(l,n)),k=Z(g);return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(P,{title:"Settings",description:"Every effective gateway setting. Settable fields apply immediately and persist across restarts; startup-only fields are shown for reference and change only via config.yml or environment variables (then a restart)."}),e.jsx(y,{error:t.error??r.error}),e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsx("input",{ref:p,type:"search","aria-label":"Search settings",placeholder:"Search settings (press / to focus)…",value:n,onChange:l=>i(l.target.value),onKeyDown:l=>{l.key==="Escape"&&i("")},className:"min-w-0 flex-1 rounded-lg border border-[var(--otari-line)] bg-[var(--otari-bg)] px-3 py-2 text-sm text-[var(--otari-ink)] focus:border-[var(--otari-brand)] focus:outline-none"}),e.jsxs("label",{className:"flex items-center gap-2 text-sm text-[var(--otari-muted)]",children:[e.jsx("input",{type:"checkbox",checked:o,onChange:l=>c(l.target.checked),className:"h-4 w-4 accent-[var(--otari-brand)]"}),"Settable only"]})]}),s?e.jsxs("p",{className:"text-xs text-[var(--otari-muted)]",children:["Showing ",g.length," of ",x.length," settings"]}):null,s&&g.length===0?e.jsx("p",{className:"text-sm text-[var(--otari-muted)]",children:"No settings match your search."}):null,k.map(l=>e.jsxs("section",{className:"flex flex-col gap-2",children:[e.jsxs("h2",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:[l.name," ",e.jsxs("span",{className:"font-normal text-[var(--otari-muted)]",children:["(",l.fields.length,")"]})]}),e.jsx(v,{children:e.jsx(v.Content,{className:"flex flex-col divide-y divide-[var(--otari-line)] px-5 py-1",children:l.fields.map(f=>e.jsx(q,{field:f,patch:m,disabled:!s||a},f.key))})})]},l.name)),s?e.jsx(W,{}):null,s?e.jsx(J,{masterKeySource:s.master_key_source}):null,s?e.jsxs("p",{className:"text-xs text-[var(--otari-muted)]",children:["Mode: ",s.mode," · Version ",s.version,s.require_pricing?" · require_pricing on":""]}):null]})}export{ae as SettingsPage,M as fieldMatches}; diff --git a/src/gateway/static/dashboard/assets/ToolsGuardrailsPage-DWSik0Ga.js b/src/gateway/static/dashboard/assets/ToolsGuardrailsPage-D8Qsr-tI.js similarity index 99% rename from src/gateway/static/dashboard/assets/ToolsGuardrailsPage-DWSik0Ga.js rename to src/gateway/static/dashboard/assets/ToolsGuardrailsPage-D8Qsr-tI.js index 8a8ae507..66f27831 100644 --- a/src/gateway/static/dashboard/assets/ToolsGuardrailsPage-DWSik0Ga.js +++ b/src/gateway/static/dashboard/assets/ToolsGuardrailsPage-D8Qsr-tI.js @@ -1 +1 @@ -import{j as e}from"./tanstack-query-1t81HyiD.js";import{r as x}from"./react-dgEcD0HR.js";import{a5 as C,a6 as L,P as E,E as P,h as w,a7 as R,F as D}from"./index-BJySXQ_a.js";import{d as N,B as b}from"./heroui-BX6JwHY-.js";function M(s,t){return{[s]:t}}const U=[{key:"web_search",label:"Web search",blurb:"Backend for otari_web_search tools (a SearXNG instance or a search adapter).",order:["web_search_url","web_search_engines","web_search_max_results","web_search_extract","web_search_purpose_hint"]},{key:"sandbox",label:"Code execution",blurb:"Backend for otari_code_execution tools (the sandbox that runs generated code).",order:["sandbox_url","sandbox_purpose_hint"]},{key:"guardrails",label:"Guardrails",blurb:"Default input-guardrails service used when a request does not pass its own guardrail URL.",order:["guardrails_url"]}];function B(){const[s,t]=x.useState(null),a=x.useRef(void 0),n=r=>{t(r),window.clearTimeout(a.current),a.current=window.setTimeout(()=>t(null),2500)};return x.useEffect(()=>()=>window.clearTimeout(a.current),[]),[s,n]}function $({message:s}){return s?e.jsxs("div",{role:"status","aria-live":"polite",className:"fixed right-4 bottom-4 z-50 flex items-center gap-2 rounded-lg border border-green-200 bg-green-50 px-4 py-3 text-sm font-medium text-green-700 shadow-lg",children:[e.jsx("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2","aria-hidden":!0,className:"h-5 w-5",children:e.jsx("path",{d:"M20 6 9 17l-5-5",strokeLinecap:"round",strokeLinejoin:"round"})}),s]}):null}const S="rounded-md border border-[var(--otari-line)] bg-[var(--otari-surface)] px-2 py-1 text-sm focus:border-[var(--otari-brand)] focus:outline-none disabled:opacity-50",g="grid gap-x-4 gap-y-1.5 py-4 sm:grid-cols-[minmax(0,1fr)_16rem_10rem] sm:items-start",_=`w-full sm:col-start-2 ${S}`,k="flex items-center gap-2 sm:col-start-3",f="flex flex-col gap-1 sm:col-span-2 sm:col-start-2";function j({message:s}){return s?e.jsx("span",{className:"break-words text-xs text-red-700",children:s}):null}function y({field:s,help:t}){return e.jsxs("div",{className:"min-w-0 sm:col-start-1",children:[e.jsx("code",{className:"text-sm font-medium text-[var(--otari-ink)]",children:s.key}),s.description?e.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:s.description}):null,t?e.jsx("p",{className:"mt-1 text-xs text-[var(--otari-muted)]",children:t}):null]})}function z({field:s,onSave:t,saveError:a,disabled:n}){const r=typeof s.value=="string"?s.value:"",[l,i]=x.useState(r),[m,p]=x.useState(null),c=R();x.useEffect(()=>{i(r)},[r]);const o=l.trim()!==r,d=l.trim(),h=m!==null&&m===d;return e.jsxs("div",{className:g,children:[e.jsx(y,{field:s,help:"Leave blank and Save to fall back to the configured default."}),e.jsx("input",{type:"text",inputMode:"url","aria-label":s.key,value:l,disabled:n,placeholder:"unset",onChange:v=>{i(v.target.value),c.reset()},className:_}),e.jsxs("div",{className:k,children:[e.jsx(b,{size:"sm",variant:"primary","aria-label":`Save ${s.key}`,isDisabled:n||!o,onPress:()=>t(d===""?null:d),children:"Save"}),e.jsx(b,{size:"sm",variant:"outline","aria-label":`Test ${s.service}`,isDisabled:d===""||c.isPending,onPress:()=>{p(d),c.mutate({service:s.service,url:d})},children:c.isPending?"Testing…":"Test"})]}),e.jsxs("div",{className:f,children:[e.jsx("span",{role:"status","aria-live":"polite",className:"block break-words text-xs",children:c.isPending||!h?null:c.error?e.jsx("span",{className:"text-red-700",children:w(c.error)}):c.data?e.jsx("span",{className:c.data.ok?"font-medium text-green-700":"text-red-700",children:c.data.reason}):null}),e.jsx(j,{message:a})]})]})}function G({field:s,onSave:t,saveError:a,disabled:n}){const r=typeof s.value=="string"?s.value:"",[l,i]=x.useState(r);x.useEffect(()=>{i(r)},[r]);const m=l!==r;return e.jsxs("div",{className:g,children:[e.jsx(y,{field:s}),e.jsx("input",{type:"text","aria-label":s.key,value:l,disabled:n,placeholder:"default",onChange:p=>i(p.target.value),className:_}),e.jsx("div",{className:k,children:e.jsx(b,{size:"sm",variant:"primary","aria-label":`Save ${s.key}`,isDisabled:n||!m,onPress:()=>t(l.trim()===""?null:l.trim()),children:"Save"})}),a?e.jsx("div",{className:f,children:e.jsx(j,{message:a})}):null]})}function I({field:s,onSave:t,saveError:a,disabled:n}){const r=typeof s.value=="number"?String(s.value):"",[l,i]=x.useState(r);x.useEffect(()=>{i(r)},[r]);const m=l.trim(),p=Number(m),o=(m===""||Number.isInteger(p)&&p>=1)&&m!==r;return e.jsxs("div",{className:g,children:[e.jsx(y,{field:s,help:"Leave blank to use the backend default."}),e.jsx("input",{type:"number",min:"1",step:"1",inputMode:"numeric","aria-label":s.key,value:l,disabled:n,placeholder:"default",onChange:d=>i(d.target.value),className:`w-full text-right tabular-nums sm:col-start-2 sm:w-28 sm:justify-self-end ${S}`}),e.jsx("div",{className:k,children:e.jsx(b,{size:"sm",variant:"primary","aria-label":`Save ${s.key}`,isDisabled:n||!o,onPress:()=>t(m===""?null:p),children:"Save"})}),a?e.jsx("div",{className:f,children:e.jsx(j,{message:a})}):null]})}function A({field:s,onSave:t,saveError:a,disabled:n}){const r=s.value===!0?"on":s.value===!1?"off":"default";return e.jsxs("div",{className:g,children:[e.jsx(y,{field:s}),e.jsx("div",{className:"sm:col-start-2 sm:justify-self-start",children:e.jsx(D,{ariaLabel:s.key,value:r,onChange:l=>t(l==="default"?null:l==="on"),options:[{value:"default",label:"Default"},{value:"on",label:"On"},{value:"off",label:"Off"}],disabled:n})}),a?e.jsx("div",{className:f,children:e.jsx(j,{message:a})}):null]})}function F({field:s,onSave:t,saveError:a,disabled:n}){return s.type==="url"?e.jsx(z,{field:s,onSave:t,saveError:a,disabled:n}):s.type==="int"?e.jsx(I,{field:s,onSave:t,saveError:a,disabled:n}):s.type==="bool"?e.jsx(A,{field:s,onSave:t,saveError:a,disabled:n}):e.jsx(G,{field:s,onSave:t,saveError:a,disabled:n})}function K(){const s=C(),t=L(),[a,n]=B(),[r,l]=x.useState({}),i=s.data,m=!i||t.isPending,p=new Map(((i==null?void 0:i.fields)??[]).map(o=>[o.key,o])),c=(o,d)=>{l(h=>{const{[o.key]:v,...u}=h;return u}),t.mutate(M(o.key,d),{onSuccess:()=>n(`${o.key} saved`),onError:h=>l(v=>({...v,[o.key]:w(h)}))})};return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(E,{title:"Tools & Guardrails",description:"Configure the built-in tool and guardrail service endpoints without a restart. Changes apply immediately and persist. URLs are validated for shape (http/https) and can be tested for reachability before saving; the network-safety gates for these services live on the Settings page."}),e.jsx(P,{error:s.error}),U.map(o=>{const d=o.order.map(u=>p.get(u)).filter(u=>u!==void 0),h=((i==null?void 0:i.fields)??[]).filter(u=>u.service===o.key&&!o.order.includes(u.key)),v=[...d,...h];return v.length===0?null:e.jsxs("section",{className:"flex flex-col gap-2",children:[e.jsx("h2",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:o.label}),e.jsx("p",{className:"text-sm text-[var(--otari-muted)]",children:o.blurb}),e.jsx(N,{children:e.jsx(N.Content,{className:"flex flex-col divide-y divide-[var(--otari-line)] px-5 py-1",children:v.map(u=>e.jsx(F,{field:u,onSave:T=>c(u,T),saveError:r[u.key],disabled:m},u.key))})})]},o.key)}),e.jsx($,{message:a})]})}export{K as ToolsGuardrailsPage}; +import{j as e}from"./tanstack-query-1t81HyiD.js";import{r as x}from"./react-dgEcD0HR.js";import{a5 as C,a6 as L,P as E,E as P,h as w,a7 as R,F as D}from"./index-C94BH4OZ.js";import{d as N,B as b}from"./heroui-BX6JwHY-.js";function M(s,t){return{[s]:t}}const U=[{key:"web_search",label:"Web search",blurb:"Backend for otari_web_search tools (a SearXNG instance or a search adapter).",order:["web_search_url","web_search_engines","web_search_max_results","web_search_extract","web_search_purpose_hint"]},{key:"sandbox",label:"Code execution",blurb:"Backend for otari_code_execution tools (the sandbox that runs generated code).",order:["sandbox_url","sandbox_purpose_hint"]},{key:"guardrails",label:"Guardrails",blurb:"Default input-guardrails service used when a request does not pass its own guardrail URL.",order:["guardrails_url"]}];function B(){const[s,t]=x.useState(null),a=x.useRef(void 0),n=r=>{t(r),window.clearTimeout(a.current),a.current=window.setTimeout(()=>t(null),2500)};return x.useEffect(()=>()=>window.clearTimeout(a.current),[]),[s,n]}function $({message:s}){return s?e.jsxs("div",{role:"status","aria-live":"polite",className:"fixed right-4 bottom-4 z-50 flex items-center gap-2 rounded-lg border border-green-200 bg-green-50 px-4 py-3 text-sm font-medium text-green-700 shadow-lg",children:[e.jsx("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2","aria-hidden":!0,className:"h-5 w-5",children:e.jsx("path",{d:"M20 6 9 17l-5-5",strokeLinecap:"round",strokeLinejoin:"round"})}),s]}):null}const S="rounded-md border border-[var(--otari-line)] bg-[var(--otari-surface)] px-2 py-1 text-sm focus:border-[var(--otari-brand)] focus:outline-none disabled:opacity-50",g="grid gap-x-4 gap-y-1.5 py-4 sm:grid-cols-[minmax(0,1fr)_16rem_10rem] sm:items-start",_=`w-full sm:col-start-2 ${S}`,k="flex items-center gap-2 sm:col-start-3",f="flex flex-col gap-1 sm:col-span-2 sm:col-start-2";function j({message:s}){return s?e.jsx("span",{className:"break-words text-xs text-red-700",children:s}):null}function y({field:s,help:t}){return e.jsxs("div",{className:"min-w-0 sm:col-start-1",children:[e.jsx("code",{className:"text-sm font-medium text-[var(--otari-ink)]",children:s.key}),s.description?e.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:s.description}):null,t?e.jsx("p",{className:"mt-1 text-xs text-[var(--otari-muted)]",children:t}):null]})}function z({field:s,onSave:t,saveError:a,disabled:n}){const r=typeof s.value=="string"?s.value:"",[l,i]=x.useState(r),[m,p]=x.useState(null),c=R();x.useEffect(()=>{i(r)},[r]);const o=l.trim()!==r,d=l.trim(),h=m!==null&&m===d;return e.jsxs("div",{className:g,children:[e.jsx(y,{field:s,help:"Leave blank and Save to fall back to the configured default."}),e.jsx("input",{type:"text",inputMode:"url","aria-label":s.key,value:l,disabled:n,placeholder:"unset",onChange:v=>{i(v.target.value),c.reset()},className:_}),e.jsxs("div",{className:k,children:[e.jsx(b,{size:"sm",variant:"primary","aria-label":`Save ${s.key}`,isDisabled:n||!o,onPress:()=>t(d===""?null:d),children:"Save"}),e.jsx(b,{size:"sm",variant:"outline","aria-label":`Test ${s.service}`,isDisabled:d===""||c.isPending,onPress:()=>{p(d),c.mutate({service:s.service,url:d})},children:c.isPending?"Testing…":"Test"})]}),e.jsxs("div",{className:f,children:[e.jsx("span",{role:"status","aria-live":"polite",className:"block break-words text-xs",children:c.isPending||!h?null:c.error?e.jsx("span",{className:"text-red-700",children:w(c.error)}):c.data?e.jsx("span",{className:c.data.ok?"font-medium text-green-700":"text-red-700",children:c.data.reason}):null}),e.jsx(j,{message:a})]})]})}function G({field:s,onSave:t,saveError:a,disabled:n}){const r=typeof s.value=="string"?s.value:"",[l,i]=x.useState(r);x.useEffect(()=>{i(r)},[r]);const m=l!==r;return e.jsxs("div",{className:g,children:[e.jsx(y,{field:s}),e.jsx("input",{type:"text","aria-label":s.key,value:l,disabled:n,placeholder:"default",onChange:p=>i(p.target.value),className:_}),e.jsx("div",{className:k,children:e.jsx(b,{size:"sm",variant:"primary","aria-label":`Save ${s.key}`,isDisabled:n||!m,onPress:()=>t(l.trim()===""?null:l.trim()),children:"Save"})}),a?e.jsx("div",{className:f,children:e.jsx(j,{message:a})}):null]})}function I({field:s,onSave:t,saveError:a,disabled:n}){const r=typeof s.value=="number"?String(s.value):"",[l,i]=x.useState(r);x.useEffect(()=>{i(r)},[r]);const m=l.trim(),p=Number(m),o=(m===""||Number.isInteger(p)&&p>=1)&&m!==r;return e.jsxs("div",{className:g,children:[e.jsx(y,{field:s,help:"Leave blank to use the backend default."}),e.jsx("input",{type:"number",min:"1",step:"1",inputMode:"numeric","aria-label":s.key,value:l,disabled:n,placeholder:"default",onChange:d=>i(d.target.value),className:`w-full text-right tabular-nums sm:col-start-2 sm:w-28 sm:justify-self-end ${S}`}),e.jsx("div",{className:k,children:e.jsx(b,{size:"sm",variant:"primary","aria-label":`Save ${s.key}`,isDisabled:n||!o,onPress:()=>t(m===""?null:p),children:"Save"})}),a?e.jsx("div",{className:f,children:e.jsx(j,{message:a})}):null]})}function A({field:s,onSave:t,saveError:a,disabled:n}){const r=s.value===!0?"on":s.value===!1?"off":"default";return e.jsxs("div",{className:g,children:[e.jsx(y,{field:s}),e.jsx("div",{className:"sm:col-start-2 sm:justify-self-start",children:e.jsx(D,{ariaLabel:s.key,value:r,onChange:l=>t(l==="default"?null:l==="on"),options:[{value:"default",label:"Default"},{value:"on",label:"On"},{value:"off",label:"Off"}],disabled:n})}),a?e.jsx("div",{className:f,children:e.jsx(j,{message:a})}):null]})}function F({field:s,onSave:t,saveError:a,disabled:n}){return s.type==="url"?e.jsx(z,{field:s,onSave:t,saveError:a,disabled:n}):s.type==="int"?e.jsx(I,{field:s,onSave:t,saveError:a,disabled:n}):s.type==="bool"?e.jsx(A,{field:s,onSave:t,saveError:a,disabled:n}):e.jsx(G,{field:s,onSave:t,saveError:a,disabled:n})}function K(){const s=C(),t=L(),[a,n]=B(),[r,l]=x.useState({}),i=s.data,m=!i||t.isPending,p=new Map(((i==null?void 0:i.fields)??[]).map(o=>[o.key,o])),c=(o,d)=>{l(h=>{const{[o.key]:v,...u}=h;return u}),t.mutate(M(o.key,d),{onSuccess:()=>n(`${o.key} saved`),onError:h=>l(v=>({...v,[o.key]:w(h)}))})};return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(E,{title:"Tools & Guardrails",description:"Configure the built-in tool and guardrail service endpoints without a restart. Changes apply immediately and persist. URLs are validated for shape (http/https) and can be tested for reachability before saving; the network-safety gates for these services live on the Settings page."}),e.jsx(P,{error:s.error}),U.map(o=>{const d=o.order.map(u=>p.get(u)).filter(u=>u!==void 0),h=((i==null?void 0:i.fields)??[]).filter(u=>u.service===o.key&&!o.order.includes(u.key)),v=[...d,...h];return v.length===0?null:e.jsxs("section",{className:"flex flex-col gap-2",children:[e.jsx("h2",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:o.label}),e.jsx("p",{className:"text-sm text-[var(--otari-muted)]",children:o.blurb}),e.jsx(N,{children:e.jsx(N.Content,{className:"flex flex-col divide-y divide-[var(--otari-line)] px-5 py-1",children:v.map(u=>e.jsx(F,{field:u,onSave:T=>c(u,T),saveError:r[u.key],disabled:m},u.key))})})]},o.key)}),e.jsx($,{message:a})]})}export{K as ToolsGuardrailsPage}; diff --git a/src/gateway/static/dashboard/assets/UsagePage-B95PT-hq.js b/src/gateway/static/dashboard/assets/UsagePage-CRzEneXv.js similarity index 99% rename from src/gateway/static/dashboard/assets/UsagePage-B95PT-hq.js rename to src/gateway/static/dashboard/assets/UsagePage-CRzEneXv.js index 55dc67f5..e9ff555f 100644 --- a/src/gateway/static/dashboard/assets/UsagePage-B95PT-hq.js +++ b/src/gateway/static/dashboard/assets/UsagePage-CRzEneXv.js @@ -1 +1 @@ -import{j as e}from"./tanstack-query-1t81HyiD.js";import{i as ie,r as x}from"./react-dgEcD0HR.js";import{u as ce,c as D,P as de,E as ue,d as J,S as v,N as b,L as p,M as $,O as he,a8 as S}from"./index-BJySXQ_a.js";import{S as E,B as me}from"./charts-Cr3Dij9t.js";import{T as xe,a as ge,b as M,L as fe,c as ve,d as je,e as O}from"./Table-CLdjdyTx.js";import{B as k,S as K}from"./heroui-BX6JwHY-.js";import"./recharts-CR3TAEof.js";function z(a){return a.toLocaleString()}function be(a){return a===null?"—":a<1e3?`${Math.round(a)} ms`:`${(a/1e3).toFixed(2)} s`}const pe=3600,R=86400,L=[{label:"Last hour",seconds:pe,bucket:"hour"},{label:"24h",seconds:R,bucket:"hour"},{label:"7d",seconds:7*R,bucket:"day"},{label:"30d",seconds:30*R,bucket:"day"},{label:"All",seconds:null,bucket:"day"}],U=L[3],A=15;function B(a){return new Date(Date.now()-a*1e3).toISOString()}function Q({title:a,rows:r,totalCost:n,emptyLabel:f,onDrill:c,loading:d}){const[u,_]=x.useState(!1),g=u?r:r.slice(0,A),N=r.length-g.length;return e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsx("h2",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:a}),e.jsxs(xe,{children:[e.jsx(ge,{children:e.jsxs("tr",{children:[e.jsx(M,{children:a.replace("Spend by ","")}),e.jsx(M,{className:"text-right",children:"Requests"}),e.jsx(M,{className:"text-right",children:"Spend"})]})}),e.jsx("tbody",{children:d?e.jsx(fe,{colSpan:3}):r.length===0?e.jsx(ve,{colSpan:3,children:f}):g.map((o,T)=>{const m=o.is_other,y=!m&&o.key!==null,h=n>0?o.cost/n:0;return e.jsxs(je,{onClick:y?()=>c(o.key):void 0,children:[e.jsx(O,{className:"text-[var(--otari-ink)]",children:e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx("span",{className:"truncate",children:m?`Other (${o.requests.toLocaleString()} req)`:o.key??"(unknown)"}),e.jsx("span",{className:"h-1 w-full overflow-hidden rounded-full bg-[var(--otari-line)]",children:e.jsx("span",{className:"block h-full rounded-full bg-[var(--otari-brand)]",style:{width:`${Math.min(100,h*100)}%`}})})]})}),e.jsx(O,{className:"text-right tabular-nums text-[var(--otari-muted)]",children:z(o.requests)}),e.jsx(O,{className:"text-right tabular-nums text-[var(--otari-ink)]",children:$(o.cost)})]},o.key??`__null_${T}`)})})]}),!d&&N>0?e.jsxs(k,{size:"sm",variant:"ghost",onPress:()=>_(!0),children:["Show all ",r.length]}):null,!d&&u&&r.length>A?e.jsxs(k,{size:"sm",variant:"ghost",onPress:()=>_(!1),children:["Show top ",A]}):null]})}const ke=[{key:"cost",label:"Cost"},{key:"tokens",label:"Tokens"},{key:"requests",label:"Requests"}];function _e(a,r){return r==="cost"?a.cost:r==="tokens"?a.tokens:a.requests}function W(a,r){return r==="cost"?$(a):r==="tokens"?S(a):z(a)}function ye(a,r){const n=new Date(a);return Number.isNaN(n.getTime())?a:r==="hour"?n.toLocaleTimeString(void 0,{hour:"2-digit",minute:"2-digit",timeZone:"UTC"}):n.toLocaleDateString(void 0,{month:"short",day:"numeric",timeZone:"UTC"})}function Se(a,r,n){const f=a.map(d=>({label:ye(d.bucket_start,n),value:_e(d,r)})),c=f.length?Math.max(...f.map(d=>d.value)):0;return{points:f,peak:c,count:a.length}}function De(){var V,Z,Y;const a=ie(),r=ce(),[n,f]=x.useState(U),[c,d]=x.useState(()=>U.seconds===null?void 0:B(U.seconds)),[u,_]=x.useState(""),[g,N]=x.useState(""),[o,T]=x.useState("cost"),m=x.useMemo(()=>({start_date:c,model:u.trim()||void 0,user_id:g||void 0}),[c,u,g]),y=x.useMemo(()=>n.seconds===null||!c?null:{...m,start_date:new Date(new Date(c).getTime()-n.seconds*1e3).toISOString(),end_date:c},[m,n.seconds,c]),h=D(m,n.bucket),X=D(y??m,n.bucket,y!==null),i=h.data,t=i==null?void 0:i.totals,l=y!==null?(V=X.data)==null?void 0:V.totals:void 0,ee=x.useMemo(()=>({...m,model:void 0}),[m]),q=((Y=(Z=D(ee,n.bucket).data)==null?void 0:Z.by_model)==null?void 0:Y.filter(s=>!s.is_other&&s.key!==null).map(s=>s.key))??[],se=(r.data??[]).map(s=>({value:s.user_id,label:s.alias?`${s.alias} (${s.user_id})`:s.user_id})),te=(u&&!q.includes(u)?[u,...q]:q).map(s=>({value:s,label:s})),w=!!(u.trim()||g||n.seconds!==null),ae=!!(i&&t&&t.request_count===0&&!w),H=s=>{f(s),d(s.seconds===null?void 0:B(s.seconds))},ne=()=>{H(L[L.length-1]),_(""),N("")},re=()=>{n.seconds!==null&&d(B(n.seconds)),h.refetch()},I=s=>{const P=new URLSearchParams;c&&P.set("start_date",c);for(const[oe,G]of Object.entries(s))G&&P.set(oe,G);a(`/activity?${P.toString()}`)},le=t&&t.request_count>0?t.error_count/t.request_count:0,j=(i==null?void 0:i.series)??[],C=j.length>1,F=Se(j,o,n.bucket);return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(de,{title:"Usage & analytics",description:"Aggregate spend, tokens, and request volume over time. Click a model or user to drill into the request log.",action:e.jsx(k,{variant:"outline",onPress:re,isDisabled:h.isFetching,children:"Refresh"})}),e.jsx(ue,{error:h.error}),e.jsxs("div",{className:"flex flex-wrap items-end gap-3",children:[e.jsx("div",{className:"flex flex-wrap gap-2",children:L.map(s=>e.jsx(k,{size:"sm",variant:n.label===s.label?"primary":"outline",onPress:()=>H(s),children:s.label},s.label))}),e.jsxs("div",{className:"flex flex-wrap items-end gap-3",children:[e.jsx(J,{label:"User",value:g,onChange:N,options:se,placeholder:"All users"}),e.jsx(J,{label:"Model",value:u,onChange:_,options:te,placeholder:"All models"}),w?e.jsx(k,{size:"sm",variant:"ghost",onPress:ne,children:"Clear filters"}):null]})]}),ae?e.jsx("div",{className:"rounded-xl border border-[var(--otari-line)] bg-[var(--otari-surface)] px-4 py-10 text-center text-sm text-[var(--otari-muted)]",children:"No usage yet. Once the gateway serves requests, spend and volume appear here."}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex flex-wrap gap-4",children:[e.jsx(v,{label:"Spend",value:t?$(t.cost):"—",hint:t?e.jsx(b,{fraction:p(t.cost,l==null?void 0:l.cost)}):null,chart:C?e.jsx(E,{values:j.map(s=>s.cost),ariaLabel:"Spend trend over the selected window"}):void 0}),e.jsx(v,{label:"Requests",value:t?z(t.request_count):"—",hint:t?e.jsxs("span",{className:"text-[var(--otari-muted)]",children:[he(le)," errors",l?e.jsxs(e.Fragment,{children:[" · ",e.jsx(b,{fraction:p(t.request_count,l.request_count)})]}):null]}):null,chart:C?e.jsx(E,{values:j.map(s=>s.requests),ariaLabel:"Request volume trend over the selected window"}):void 0}),e.jsx(v,{label:"Tokens",value:t?S(t.total_tokens):"—",hint:t?e.jsx(b,{fraction:p(t.total_tokens,l==null?void 0:l.total_tokens)}):null,chart:C?e.jsx(E,{values:j.map(s=>s.tokens),ariaLabel:"Token usage trend over the selected window"}):void 0}),e.jsx(v,{label:"Cache read",value:t?S(t.cache_read_tokens):"—",hint:t?e.jsx(b,{fraction:p(t.cache_read_tokens,l==null?void 0:l.cache_read_tokens)}):null}),e.jsx(v,{label:"Cache write",value:t?S(t.cache_write_tokens):"—",hint:t?e.jsx(b,{fraction:p(t.cache_write_tokens,l==null?void 0:l.cache_write_tokens)}):null}),e.jsx(v,{label:"1h cache write",value:t?S(t.cache_write_1h_tokens??0):"—",hint:t?e.jsx(b,{fraction:p(t.cache_write_1h_tokens??0,(l==null?void 0:l.cache_write_1h_tokens)??0)}):null}),e.jsx(v,{label:"Avg latency",value:t?be(t.avg_latency_ms):"—"})]}),e.jsxs("div",{className:"grid gap-6 lg:grid-cols-2",children:[e.jsx(Q,{title:"Spend by model",rows:(i==null?void 0:i.by_model)??[],totalCost:(t==null?void 0:t.cost)??0,emptyLabel:w?"No usage matches these filters.":"No usage recorded yet.",onDrill:s=>I({model:s,user_id:g||void 0}),loading:h.isLoading}),e.jsx(Q,{title:"Spend by user",rows:(i==null?void 0:i.by_user)??[],totalCost:(t==null?void 0:t.cost)??0,emptyLabel:w?"No usage matches these filters.":"No usage recorded yet.",onDrill:s=>I({user_id:s,model:u.trim()||void 0}),loading:h.isLoading})]}),e.jsxs("div",{className:"flex flex-col gap-3 rounded-xl border border-[var(--otari-line)] bg-[var(--otari-surface)] p-4",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsx("h2",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:"Over time"}),e.jsxs("div",{className:"inline-flex gap-1.5",children:[ke.map(s=>e.jsx(k,{size:"sm",variant:o===s.key?"primary":"outline",onPress:()=>T(s.key),children:s.label},s.key)),h.isFetching?e.jsx(K,{size:"sm"}):null]})]}),h.isLoading?e.jsx("div",{className:"flex h-48 items-center justify-center",children:e.jsx(K,{size:"sm"})}):j.length===0?e.jsx("div",{className:"flex h-48 items-center justify-center text-sm text-[var(--otari-muted)]",children:"No data in this range."}):e.jsxs("figure",{className:"flex flex-col gap-2",children:[e.jsx(me,{data:F.points,formatValue:s=>W(s,o),ariaLabel:`${o} per ${n.bucket}`}),e.jsxs("figcaption",{className:"text-xs text-[var(--otari-muted)]",children:[W(F.peak,o)," peak · ",F.count," ",n.bucket==="hour"?"hours":"days"," (times in UTC)"]})]})]})]})]})}export{De as UsagePage}; +import{j as e}from"./tanstack-query-1t81HyiD.js";import{i as ie,r as x}from"./react-dgEcD0HR.js";import{u as ce,c as D,P as de,E as ue,d as J,S as v,N as b,L as p,M as $,O as he,a8 as S}from"./index-C94BH4OZ.js";import{S as E,B as me}from"./charts-Cr3Dij9t.js";import{T as xe,a as ge,b as M,L as fe,c as ve,d as je,e as O}from"./Table-CLdjdyTx.js";import{B as k,S as K}from"./heroui-BX6JwHY-.js";import"./recharts-CR3TAEof.js";function z(a){return a.toLocaleString()}function be(a){return a===null?"—":a<1e3?`${Math.round(a)} ms`:`${(a/1e3).toFixed(2)} s`}const pe=3600,R=86400,L=[{label:"Last hour",seconds:pe,bucket:"hour"},{label:"24h",seconds:R,bucket:"hour"},{label:"7d",seconds:7*R,bucket:"day"},{label:"30d",seconds:30*R,bucket:"day"},{label:"All",seconds:null,bucket:"day"}],U=L[3],A=15;function B(a){return new Date(Date.now()-a*1e3).toISOString()}function Q({title:a,rows:r,totalCost:n,emptyLabel:f,onDrill:c,loading:d}){const[u,_]=x.useState(!1),g=u?r:r.slice(0,A),N=r.length-g.length;return e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsx("h2",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:a}),e.jsxs(xe,{children:[e.jsx(ge,{children:e.jsxs("tr",{children:[e.jsx(M,{children:a.replace("Spend by ","")}),e.jsx(M,{className:"text-right",children:"Requests"}),e.jsx(M,{className:"text-right",children:"Spend"})]})}),e.jsx("tbody",{children:d?e.jsx(fe,{colSpan:3}):r.length===0?e.jsx(ve,{colSpan:3,children:f}):g.map((o,T)=>{const m=o.is_other,y=!m&&o.key!==null,h=n>0?o.cost/n:0;return e.jsxs(je,{onClick:y?()=>c(o.key):void 0,children:[e.jsx(O,{className:"text-[var(--otari-ink)]",children:e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx("span",{className:"truncate",children:m?`Other (${o.requests.toLocaleString()} req)`:o.key??"(unknown)"}),e.jsx("span",{className:"h-1 w-full overflow-hidden rounded-full bg-[var(--otari-line)]",children:e.jsx("span",{className:"block h-full rounded-full bg-[var(--otari-brand)]",style:{width:`${Math.min(100,h*100)}%`}})})]})}),e.jsx(O,{className:"text-right tabular-nums text-[var(--otari-muted)]",children:z(o.requests)}),e.jsx(O,{className:"text-right tabular-nums text-[var(--otari-ink)]",children:$(o.cost)})]},o.key??`__null_${T}`)})})]}),!d&&N>0?e.jsxs(k,{size:"sm",variant:"ghost",onPress:()=>_(!0),children:["Show all ",r.length]}):null,!d&&u&&r.length>A?e.jsxs(k,{size:"sm",variant:"ghost",onPress:()=>_(!1),children:["Show top ",A]}):null]})}const ke=[{key:"cost",label:"Cost"},{key:"tokens",label:"Tokens"},{key:"requests",label:"Requests"}];function _e(a,r){return r==="cost"?a.cost:r==="tokens"?a.tokens:a.requests}function W(a,r){return r==="cost"?$(a):r==="tokens"?S(a):z(a)}function ye(a,r){const n=new Date(a);return Number.isNaN(n.getTime())?a:r==="hour"?n.toLocaleTimeString(void 0,{hour:"2-digit",minute:"2-digit",timeZone:"UTC"}):n.toLocaleDateString(void 0,{month:"short",day:"numeric",timeZone:"UTC"})}function Se(a,r,n){const f=a.map(d=>({label:ye(d.bucket_start,n),value:_e(d,r)})),c=f.length?Math.max(...f.map(d=>d.value)):0;return{points:f,peak:c,count:a.length}}function De(){var V,Z,Y;const a=ie(),r=ce(),[n,f]=x.useState(U),[c,d]=x.useState(()=>U.seconds===null?void 0:B(U.seconds)),[u,_]=x.useState(""),[g,N]=x.useState(""),[o,T]=x.useState("cost"),m=x.useMemo(()=>({start_date:c,model:u.trim()||void 0,user_id:g||void 0}),[c,u,g]),y=x.useMemo(()=>n.seconds===null||!c?null:{...m,start_date:new Date(new Date(c).getTime()-n.seconds*1e3).toISOString(),end_date:c},[m,n.seconds,c]),h=D(m,n.bucket),X=D(y??m,n.bucket,y!==null),i=h.data,t=i==null?void 0:i.totals,l=y!==null?(V=X.data)==null?void 0:V.totals:void 0,ee=x.useMemo(()=>({...m,model:void 0}),[m]),q=((Y=(Z=D(ee,n.bucket).data)==null?void 0:Z.by_model)==null?void 0:Y.filter(s=>!s.is_other&&s.key!==null).map(s=>s.key))??[],se=(r.data??[]).map(s=>({value:s.user_id,label:s.alias?`${s.alias} (${s.user_id})`:s.user_id})),te=(u&&!q.includes(u)?[u,...q]:q).map(s=>({value:s,label:s})),w=!!(u.trim()||g||n.seconds!==null),ae=!!(i&&t&&t.request_count===0&&!w),H=s=>{f(s),d(s.seconds===null?void 0:B(s.seconds))},ne=()=>{H(L[L.length-1]),_(""),N("")},re=()=>{n.seconds!==null&&d(B(n.seconds)),h.refetch()},I=s=>{const P=new URLSearchParams;c&&P.set("start_date",c);for(const[oe,G]of Object.entries(s))G&&P.set(oe,G);a(`/activity?${P.toString()}`)},le=t&&t.request_count>0?t.error_count/t.request_count:0,j=(i==null?void 0:i.series)??[],C=j.length>1,F=Se(j,o,n.bucket);return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(de,{title:"Usage & analytics",description:"Aggregate spend, tokens, and request volume over time. Click a model or user to drill into the request log.",action:e.jsx(k,{variant:"outline",onPress:re,isDisabled:h.isFetching,children:"Refresh"})}),e.jsx(ue,{error:h.error}),e.jsxs("div",{className:"flex flex-wrap items-end gap-3",children:[e.jsx("div",{className:"flex flex-wrap gap-2",children:L.map(s=>e.jsx(k,{size:"sm",variant:n.label===s.label?"primary":"outline",onPress:()=>H(s),children:s.label},s.label))}),e.jsxs("div",{className:"flex flex-wrap items-end gap-3",children:[e.jsx(J,{label:"User",value:g,onChange:N,options:se,placeholder:"All users"}),e.jsx(J,{label:"Model",value:u,onChange:_,options:te,placeholder:"All models"}),w?e.jsx(k,{size:"sm",variant:"ghost",onPress:ne,children:"Clear filters"}):null]})]}),ae?e.jsx("div",{className:"rounded-xl border border-[var(--otari-line)] bg-[var(--otari-surface)] px-4 py-10 text-center text-sm text-[var(--otari-muted)]",children:"No usage yet. Once the gateway serves requests, spend and volume appear here."}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex flex-wrap gap-4",children:[e.jsx(v,{label:"Spend",value:t?$(t.cost):"—",hint:t?e.jsx(b,{fraction:p(t.cost,l==null?void 0:l.cost)}):null,chart:C?e.jsx(E,{values:j.map(s=>s.cost),ariaLabel:"Spend trend over the selected window"}):void 0}),e.jsx(v,{label:"Requests",value:t?z(t.request_count):"—",hint:t?e.jsxs("span",{className:"text-[var(--otari-muted)]",children:[he(le)," errors",l?e.jsxs(e.Fragment,{children:[" · ",e.jsx(b,{fraction:p(t.request_count,l.request_count)})]}):null]}):null,chart:C?e.jsx(E,{values:j.map(s=>s.requests),ariaLabel:"Request volume trend over the selected window"}):void 0}),e.jsx(v,{label:"Tokens",value:t?S(t.total_tokens):"—",hint:t?e.jsx(b,{fraction:p(t.total_tokens,l==null?void 0:l.total_tokens)}):null,chart:C?e.jsx(E,{values:j.map(s=>s.tokens),ariaLabel:"Token usage trend over the selected window"}):void 0}),e.jsx(v,{label:"Cache read",value:t?S(t.cache_read_tokens):"—",hint:t?e.jsx(b,{fraction:p(t.cache_read_tokens,l==null?void 0:l.cache_read_tokens)}):null}),e.jsx(v,{label:"Cache write",value:t?S(t.cache_write_tokens):"—",hint:t?e.jsx(b,{fraction:p(t.cache_write_tokens,l==null?void 0:l.cache_write_tokens)}):null}),e.jsx(v,{label:"1h cache write",value:t?S(t.cache_write_1h_tokens??0):"—",hint:t?e.jsx(b,{fraction:p(t.cache_write_1h_tokens??0,(l==null?void 0:l.cache_write_1h_tokens)??0)}):null}),e.jsx(v,{label:"Avg latency",value:t?be(t.avg_latency_ms):"—"})]}),e.jsxs("div",{className:"grid gap-6 lg:grid-cols-2",children:[e.jsx(Q,{title:"Spend by model",rows:(i==null?void 0:i.by_model)??[],totalCost:(t==null?void 0:t.cost)??0,emptyLabel:w?"No usage matches these filters.":"No usage recorded yet.",onDrill:s=>I({model:s,user_id:g||void 0}),loading:h.isLoading}),e.jsx(Q,{title:"Spend by user",rows:(i==null?void 0:i.by_user)??[],totalCost:(t==null?void 0:t.cost)??0,emptyLabel:w?"No usage matches these filters.":"No usage recorded yet.",onDrill:s=>I({user_id:s,model:u.trim()||void 0}),loading:h.isLoading})]}),e.jsxs("div",{className:"flex flex-col gap-3 rounded-xl border border-[var(--otari-line)] bg-[var(--otari-surface)] p-4",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsx("h2",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:"Over time"}),e.jsxs("div",{className:"inline-flex gap-1.5",children:[ke.map(s=>e.jsx(k,{size:"sm",variant:o===s.key?"primary":"outline",onPress:()=>T(s.key),children:s.label},s.key)),h.isFetching?e.jsx(K,{size:"sm"}):null]})]}),h.isLoading?e.jsx("div",{className:"flex h-48 items-center justify-center",children:e.jsx(K,{size:"sm"})}):j.length===0?e.jsx("div",{className:"flex h-48 items-center justify-center text-sm text-[var(--otari-muted)]",children:"No data in this range."}):e.jsxs("figure",{className:"flex flex-col gap-2",children:[e.jsx(me,{data:F.points,formatValue:s=>W(s,o),ariaLabel:`${o} per ${n.bucket}`}),e.jsxs("figcaption",{className:"text-xs text-[var(--otari-muted)]",children:[W(F.peak,o)," peak · ",F.count," ",n.bucket==="hour"?"hours":"days"," (times in UTC)"]})]})]})]})]})}export{De as UsagePage}; diff --git a/src/gateway/static/dashboard/assets/UsersPage-D5CmT8Bq.js b/src/gateway/static/dashboard/assets/UsersPage-zP5EVG6k.js similarity index 98% rename from src/gateway/static/dashboard/assets/UsersPage-D5CmT8Bq.js rename to src/gateway/static/dashboard/assets/UsersPage-zP5EVG6k.js index 1a1bfa43..24e31620 100644 --- a/src/gateway/static/dashboard/assets/UsersPage-D5CmT8Bq.js +++ b/src/gateway/static/dashboard/assets/UsersPage-zP5EVG6k.js @@ -1 +1 @@ -import{j as e}from"./tanstack-query-1t81HyiD.js";import{r as n}from"./react-dgEcD0HR.js";import{u as E,j as w,n as I,a9 as V,P as L,E as A,aa as O}from"./index-BJySXQ_a.js";import{F as N}from"./Field-HzRk1KDP.js";import{M as B,a as R}from"./ModelScopeControl-DiX2Etqz.js";import{T as H,a as $,b as f,L as q,c as W,d as G,e as b}from"./Table-CLdjdyTx.js";import{B as o,f as P,d as v}from"./heroui-BX6JwHY-.js";const J=new Intl.NumberFormat(void 0,{style:"currency",currency:"USD",maximumFractionDigits:4});function S(t){return J.format(t)}const _=t=>t.startsWith("apikey-");function D(t){return t.split("-")[0]}function M(t){return t.name??D(t.budget_id)}function T({value:t,onChange:i,budgets:r}){return e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx("label",{htmlFor:"user-budget",className:"text-sm font-medium text-[var(--otari-ink)]",children:"Budget"}),e.jsxs("select",{id:"user-budget",value:t??"",onChange:a=>i(a.target.value||null),className:"w-full rounded-lg border border-[var(--otari-line)] bg-[var(--otari-bg)] px-3 py-2 text-sm text-[var(--otari-ink)]",children:[e.jsx("option",{value:"",children:"No budget (unlimited)"}),r.map(a=>e.jsxs("option",{value:a.budget_id,children:[M(a),a.max_budget===null?" · no limit":` · ${S(a.max_budget)}`]},a.budget_id))]}),e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"The spending limit this user is held to. Manage budgets on the Budgets page."})]})}function K({onClose:t}){const i=O(),r=w(),[a,l]=n.useState(""),[d,c]=n.useState(""),[u,j]=n.useState(null),[y,x]=n.useState(null),[g,p]=n.useState(!0),m=()=>{if(i.isPending||!g||a.trim()==="")return;const h={user_id:a.trim(),alias:d.trim()||null,budget_id:u,allowed_models:y};i.mutate(h,{onSuccess:t})};return e.jsx(v,{children:e.jsxs(v.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsx("div",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:"Create user"}),e.jsx(A,{error:i.error}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsx(N,{label:"User ID",value:a,onChange:l,placeholder:"alice@example.com",isRequired:!0,autoFocus:!0,description:"The identifier callers send as the `user` field; spend and budgets track against it."}),e.jsx(N,{label:"Alias (optional)",value:d,onChange:c,placeholder:"Alice"})]}),e.jsx(T,{value:u,onChange:j,budgets:r.data??[]}),e.jsx(B,{title:"Model access (default for this user's keys)",description:"The models this user's keys may list and call by default. A key can narrow this, but never exceed it.",initial:null,onChange:(h,C)=>{x(h),p(C)}}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(o,{variant:"primary",isDisabled:i.isPending||!g||a.trim()==="",onPress:m,children:i.isPending?"Creating…":"Create user"}),e.jsx(o,{variant:"ghost",onPress:t,children:"Cancel"})]})]})})}function Q({user:t,onClose:i}){const r=I(),a=w(),[l,d]=n.useState(t.alias??""),[c,u]=n.useState(t.budget_id),[j,y]=n.useState(t.allowed_models),[x,g]=n.useState(!0),p=()=>{if(r.isPending||!x)return;const m={alias:l.trim()||null,budget_id:c,allowed_models:j};r.mutate({id:t.user_id,body:m},{onSuccess:i})};return e.jsx(v,{children:e.jsxs(v.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsxs("div",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:["Edit ",e.jsx("code",{children:t.user_id})]}),e.jsx(A,{error:r.error}),e.jsx(N,{label:"Alias",value:l,onChange:d,placeholder:"Alice"}),e.jsx(T,{value:c,onChange:u,budgets:a.data??[]}),e.jsx(B,{title:"Model access (default for this user's keys)",description:"The models this user's keys may list and call by default. A key can narrow this, but never exceed it.",initial:t.allowed_models,onChange:(m,h)=>{y(m),g(h)}}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(o,{variant:"primary",isDisabled:r.isPending||!x,onPress:p,children:r.isPending?"Saving…":"Save changes"}),e.jsx(o,{variant:"ghost",onPress:i,children:"Cancel"})]})]})})}function X({trigger:t,message:i,confirmLabel:r,isPending:a,onConfirm:l}){const[d,c]=n.useState(!1);return d?e.jsxs("div",{className:"flex flex-col items-end gap-1.5 rounded-lg border border-amber-200 bg-amber-50 p-2 text-right",children:[e.jsx("span",{className:"max-w-xs text-xs text-amber-800",children:i}),e.jsxs("span",{className:"inline-flex gap-1",children:[e.jsx(o,{size:"sm",variant:"danger",isDisabled:a,onPress:l,children:r}),e.jsx(o,{size:"sm",variant:"ghost",isDisabled:a,onPress:()=>c(!1),children:"Cancel"})]})]}):e.jsx(o,{size:"sm",variant:"danger-soft",onPress:()=>c(!0),children:t})}function Y({user:t}){return t.blocked?e.jsx(P,{size:"sm",color:"warning",children:"Blocked"}):e.jsx(P,{size:"sm",color:"accent",children:"Active"})}function Z({allowed:t}){const{text:i,tone:r}=R(t),a=r==="danger"?"text-red-700 font-medium":r==="muted"?"text-[var(--otari-muted)]":"text-[var(--otari-brand-dark)] font-medium",l=t&&t.length>0?t.join(", "):void 0;return e.jsx("span",{className:`text-xs ${a}`,title:l,children:i})}function ee({onCreate:t}){return e.jsx(v,{children:e.jsxs(v.Content,{className:"flex flex-col gap-4 p-6",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-semibold text-[var(--otari-ink)]",children:"No users yet"}),e.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:"A user owns API keys and carries the budget and default model access those keys inherit. Create a user here, then issue its keys on the API keys page."})]}),e.jsx("div",{children:e.jsx(o,{variant:"primary",onPress:t,children:"Create your first user"})})]})})}function de(){const t=E(),i=w(),r=I(),a=V(),[l,d]=n.useState(!1),[c,u]=n.useState(null),[j,y]=n.useState(!1),x=t.data??[],g=t.isLoading,p=x.filter(s=>_(s.user_id)).length,m=j?x:x.filter(s=>!_(s.user_id)),h=x.find(s=>s.user_id===c)??null,C=!g&&m.length===0&&!l,z=new Map((i.data??[]).map(s=>[s.budget_id,s])),U=(s,k)=>r.mutate({id:s.user_id,body:{blocked:k}});return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(L,{title:"Users",description:"People and teams that own API keys. Set each one's budget and default model access here; issue their keys on the API keys page.",action:l?null:e.jsx(o,{variant:"primary",onPress:()=>{u(null),d(!0)},children:"Create user"})}),e.jsx(A,{error:t.error??r.error??a.error}),C?e.jsx(ee,{onCreate:()=>{u(null),d(!0)}}):null,p>0?e.jsxs("label",{className:"flex w-fit items-center gap-2 text-xs text-[var(--otari-muted)]",children:[e.jsx("input",{type:"checkbox",checked:j,onChange:s=>y(s.target.checked)}),"Show auto-created (virtual) users (",p,")"]}):null,l?e.jsx(K,{onClose:()=>d(!1)}):null,h?e.jsx(Q,{user:h,onClose:()=>u(null)},h.user_id):null,e.jsxs(H,{children:[e.jsx($,{children:e.jsxs("tr",{children:[e.jsx(f,{children:"User"}),e.jsx(f,{children:"Status"}),e.jsx(f,{children:"Budget"}),e.jsx(f,{children:"Spend"}),e.jsx(f,{children:"Model access"}),e.jsx(f,{className:"text-right",children:"Actions"})]})}),e.jsx("tbody",{children:g?e.jsx(q,{colSpan:6}):m.length===0?e.jsx(W,{colSpan:6,children:"No users yet. Create one, or create an API key to auto-create one."}):m.map(s=>{const k=s.budget_id?z.get(s.budget_id):void 0;return e.jsxs(G,{selected:c===s.user_id,onClick:()=>{d(!1),u(s.user_id)},children:[e.jsx(b,{className:"font-medium text-[var(--otari-ink)]",children:e.jsxs("div",{className:"flex flex-col gap-0.5",children:[e.jsxs("span",{className:"inline-flex items-center gap-1.5",children:[e.jsx("code",{className:"text-xs",children:s.user_id}),_(s.user_id)?e.jsx(P,{size:"sm",color:"default",children:"virtual"}):null]}),s.alias?e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:s.alias}):null]})}),e.jsx(b,{children:e.jsx(Y,{user:s})}),e.jsx(b,{className:"text-[var(--otari-muted)]",children:s.budget_id?e.jsx("span",{title:s.budget_id,children:k?M(k):D(s.budget_id)}):"—"}),e.jsxs(b,{className:"text-[var(--otari-muted)]",children:[S(s.spend),s.reserved>0?e.jsxs("span",{className:"text-[var(--otari-muted)]",children:[" (+",S(s.reserved)," held)"]}):null]}),e.jsx(b,{children:e.jsx(Z,{allowed:s.allowed_models})}),e.jsx(b,{children:e.jsxs("div",{className:"flex items-center justify-end gap-1.5",onClick:F=>F.stopPropagation(),children:[s.blocked?e.jsx(o,{size:"sm",variant:"outline",isDisabled:r.isPending,onPress:()=>U(s,!1),children:"Unblock"}):e.jsx(o,{size:"sm",variant:"outline",isDisabled:r.isPending,onPress:()=>U(s,!0),children:"Block"}),e.jsx(o,{size:"sm",variant:"ghost",onPress:()=>{d(!1),u(s.user_id)},children:"Edit"}),e.jsx(X,{trigger:"Delete",confirmLabel:"Delete user",isPending:a.isPending,message:e.jsxs(e.Fragment,{children:["Delete ",e.jsx("strong",{children:s.user_id}),"? This deactivates its API keys and hides the user; usage history is preserved."]}),onConfirm:()=>a.mutate(s.user_id)})]})})]},s.user_id)})})]})]})}export{de as UsersPage}; +import{j as e}from"./tanstack-query-1t81HyiD.js";import{r as n}from"./react-dgEcD0HR.js";import{u as E,j as w,n as I,a9 as V,P as L,E as A,aa as O}from"./index-C94BH4OZ.js";import{F as N}from"./Field-HzRk1KDP.js";import{M as B,a as R}from"./ModelScopeControl-CV1Wulbr.js";import{T as H,a as $,b as f,L as q,c as W,d as G,e as b}from"./Table-CLdjdyTx.js";import{B as o,f as P,d as v}from"./heroui-BX6JwHY-.js";const J=new Intl.NumberFormat(void 0,{style:"currency",currency:"USD",maximumFractionDigits:4});function S(t){return J.format(t)}const _=t=>t.startsWith("apikey-");function D(t){return t.split("-")[0]}function M(t){return t.name??D(t.budget_id)}function T({value:t,onChange:i,budgets:r}){return e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx("label",{htmlFor:"user-budget",className:"text-sm font-medium text-[var(--otari-ink)]",children:"Budget"}),e.jsxs("select",{id:"user-budget",value:t??"",onChange:a=>i(a.target.value||null),className:"w-full rounded-lg border border-[var(--otari-line)] bg-[var(--otari-bg)] px-3 py-2 text-sm text-[var(--otari-ink)]",children:[e.jsx("option",{value:"",children:"No budget (unlimited)"}),r.map(a=>e.jsxs("option",{value:a.budget_id,children:[M(a),a.max_budget===null?" · no limit":` · ${S(a.max_budget)}`]},a.budget_id))]}),e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:"The spending limit this user is held to. Manage budgets on the Budgets page."})]})}function K({onClose:t}){const i=O(),r=w(),[a,l]=n.useState(""),[d,c]=n.useState(""),[u,j]=n.useState(null),[y,x]=n.useState(null),[g,p]=n.useState(!0),m=()=>{if(i.isPending||!g||a.trim()==="")return;const h={user_id:a.trim(),alias:d.trim()||null,budget_id:u,allowed_models:y};i.mutate(h,{onSuccess:t})};return e.jsx(v,{children:e.jsxs(v.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsx("div",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:"Create user"}),e.jsx(A,{error:i.error}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsx(N,{label:"User ID",value:a,onChange:l,placeholder:"alice@example.com",isRequired:!0,autoFocus:!0,description:"The identifier callers send as the `user` field; spend and budgets track against it."}),e.jsx(N,{label:"Alias (optional)",value:d,onChange:c,placeholder:"Alice"})]}),e.jsx(T,{value:u,onChange:j,budgets:r.data??[]}),e.jsx(B,{title:"Model access (default for this user's keys)",description:"The models this user's keys may list and call by default. A key can narrow this, but never exceed it.",initial:null,onChange:(h,C)=>{x(h),p(C)}}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(o,{variant:"primary",isDisabled:i.isPending||!g||a.trim()==="",onPress:m,children:i.isPending?"Creating…":"Create user"}),e.jsx(o,{variant:"ghost",onPress:t,children:"Cancel"})]})]})})}function Q({user:t,onClose:i}){const r=I(),a=w(),[l,d]=n.useState(t.alias??""),[c,u]=n.useState(t.budget_id),[j,y]=n.useState(t.allowed_models),[x,g]=n.useState(!0),p=()=>{if(r.isPending||!x)return;const m={alias:l.trim()||null,budget_id:c,allowed_models:j};r.mutate({id:t.user_id,body:m},{onSuccess:i})};return e.jsx(v,{children:e.jsxs(v.Content,{className:"flex flex-col gap-4 p-5",children:[e.jsxs("div",{className:"text-sm font-semibold text-[var(--otari-ink)]",children:["Edit ",e.jsx("code",{children:t.user_id})]}),e.jsx(A,{error:r.error}),e.jsx(N,{label:"Alias",value:l,onChange:d,placeholder:"Alice"}),e.jsx(T,{value:c,onChange:u,budgets:a.data??[]}),e.jsx(B,{title:"Model access (default for this user's keys)",description:"The models this user's keys may list and call by default. A key can narrow this, but never exceed it.",initial:t.allowed_models,onChange:(m,h)=>{y(m),g(h)}}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(o,{variant:"primary",isDisabled:r.isPending||!x,onPress:p,children:r.isPending?"Saving…":"Save changes"}),e.jsx(o,{variant:"ghost",onPress:i,children:"Cancel"})]})]})})}function X({trigger:t,message:i,confirmLabel:r,isPending:a,onConfirm:l}){const[d,c]=n.useState(!1);return d?e.jsxs("div",{className:"flex flex-col items-end gap-1.5 rounded-lg border border-amber-200 bg-amber-50 p-2 text-right",children:[e.jsx("span",{className:"max-w-xs text-xs text-amber-800",children:i}),e.jsxs("span",{className:"inline-flex gap-1",children:[e.jsx(o,{size:"sm",variant:"danger",isDisabled:a,onPress:l,children:r}),e.jsx(o,{size:"sm",variant:"ghost",isDisabled:a,onPress:()=>c(!1),children:"Cancel"})]})]}):e.jsx(o,{size:"sm",variant:"danger-soft",onPress:()=>c(!0),children:t})}function Y({user:t}){return t.blocked?e.jsx(P,{size:"sm",color:"warning",children:"Blocked"}):e.jsx(P,{size:"sm",color:"accent",children:"Active"})}function Z({allowed:t}){const{text:i,tone:r}=R(t),a=r==="danger"?"text-red-700 font-medium":r==="muted"?"text-[var(--otari-muted)]":"text-[var(--otari-brand-dark)] font-medium",l=t&&t.length>0?t.join(", "):void 0;return e.jsx("span",{className:`text-xs ${a}`,title:l,children:i})}function ee({onCreate:t}){return e.jsx(v,{children:e.jsxs(v.Content,{className:"flex flex-col gap-4 p-6",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-semibold text-[var(--otari-ink)]",children:"No users yet"}),e.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:"A user owns API keys and carries the budget and default model access those keys inherit. Create a user here, then issue its keys on the API keys page."})]}),e.jsx("div",{children:e.jsx(o,{variant:"primary",onPress:t,children:"Create your first user"})})]})})}function de(){const t=E(),i=w(),r=I(),a=V(),[l,d]=n.useState(!1),[c,u]=n.useState(null),[j,y]=n.useState(!1),x=t.data??[],g=t.isLoading,p=x.filter(s=>_(s.user_id)).length,m=j?x:x.filter(s=>!_(s.user_id)),h=x.find(s=>s.user_id===c)??null,C=!g&&m.length===0&&!l,z=new Map((i.data??[]).map(s=>[s.budget_id,s])),U=(s,k)=>r.mutate({id:s.user_id,body:{blocked:k}});return e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(L,{title:"Users",description:"People and teams that own API keys. Set each one's budget and default model access here; issue their keys on the API keys page.",action:l?null:e.jsx(o,{variant:"primary",onPress:()=>{u(null),d(!0)},children:"Create user"})}),e.jsx(A,{error:t.error??r.error??a.error}),C?e.jsx(ee,{onCreate:()=>{u(null),d(!0)}}):null,p>0?e.jsxs("label",{className:"flex w-fit items-center gap-2 text-xs text-[var(--otari-muted)]",children:[e.jsx("input",{type:"checkbox",checked:j,onChange:s=>y(s.target.checked)}),"Show auto-created (virtual) users (",p,")"]}):null,l?e.jsx(K,{onClose:()=>d(!1)}):null,h?e.jsx(Q,{user:h,onClose:()=>u(null)},h.user_id):null,e.jsxs(H,{children:[e.jsx($,{children:e.jsxs("tr",{children:[e.jsx(f,{children:"User"}),e.jsx(f,{children:"Status"}),e.jsx(f,{children:"Budget"}),e.jsx(f,{children:"Spend"}),e.jsx(f,{children:"Model access"}),e.jsx(f,{className:"text-right",children:"Actions"})]})}),e.jsx("tbody",{children:g?e.jsx(q,{colSpan:6}):m.length===0?e.jsx(W,{colSpan:6,children:"No users yet. Create one, or create an API key to auto-create one."}):m.map(s=>{const k=s.budget_id?z.get(s.budget_id):void 0;return e.jsxs(G,{selected:c===s.user_id,onClick:()=>{d(!1),u(s.user_id)},children:[e.jsx(b,{className:"font-medium text-[var(--otari-ink)]",children:e.jsxs("div",{className:"flex flex-col gap-0.5",children:[e.jsxs("span",{className:"inline-flex items-center gap-1.5",children:[e.jsx("code",{className:"text-xs",children:s.user_id}),_(s.user_id)?e.jsx(P,{size:"sm",color:"default",children:"virtual"}):null]}),s.alias?e.jsx("span",{className:"text-xs text-[var(--otari-muted)]",children:s.alias}):null]})}),e.jsx(b,{children:e.jsx(Y,{user:s})}),e.jsx(b,{className:"text-[var(--otari-muted)]",children:s.budget_id?e.jsx("span",{title:s.budget_id,children:k?M(k):D(s.budget_id)}):"—"}),e.jsxs(b,{className:"text-[var(--otari-muted)]",children:[S(s.spend),s.reserved>0?e.jsxs("span",{className:"text-[var(--otari-muted)]",children:[" (+",S(s.reserved)," held)"]}):null]}),e.jsx(b,{children:e.jsx(Z,{allowed:s.allowed_models})}),e.jsx(b,{children:e.jsxs("div",{className:"flex items-center justify-end gap-1.5",onClick:F=>F.stopPropagation(),children:[s.blocked?e.jsx(o,{size:"sm",variant:"outline",isDisabled:r.isPending,onPress:()=>U(s,!1),children:"Unblock"}):e.jsx(o,{size:"sm",variant:"outline",isDisabled:r.isPending,onPress:()=>U(s,!0),children:"Block"}),e.jsx(o,{size:"sm",variant:"ghost",onPress:()=>{d(!1),u(s.user_id)},children:"Edit"}),e.jsx(X,{trigger:"Delete",confirmLabel:"Delete user",isPending:a.isPending,message:e.jsxs(e.Fragment,{children:["Delete ",e.jsx("strong",{children:s.user_id}),"? This deactivates its API keys and hides the user; usage history is preserved."]}),onConfirm:()=>a.mutate(s.user_id)})]})})]},s.user_id)})})]})]})}export{de as UsersPage}; diff --git a/src/gateway/static/dashboard/assets/index-BJySXQ_a.js b/src/gateway/static/dashboard/assets/index-C94BH4OZ.js similarity index 96% rename from src/gateway/static/dashboard/assets/index-BJySXQ_a.js rename to src/gateway/static/dashboard/assets/index-C94BH4OZ.js index 87984804..540ad6b6 100644 --- a/src/gateway/static/dashboard/assets/index-BJySXQ_a.js +++ b/src/gateway/static/dashboard/assets/index-C94BH4OZ.js @@ -1,2 +1,2 @@ -const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/ActivityPage-BrL4O-hT.js","assets/tanstack-query-1t81HyiD.js","assets/react-dgEcD0HR.js","assets/Table-CLdjdyTx.js","assets/heroui-BX6JwHY-.js","assets/AliasesPage-RDVKM-by.js","assets/Field-HzRk1KDP.js","assets/BudgetsPage-Ctwj8twD.js","assets/KeysPage-DCo4FFYU.js","assets/ModelScopeControl-DiX2Etqz.js","assets/ModelsPage-C028BOtV.js","assets/OverviewPage-KThfhw1Z.js","assets/charts-Cr3Dij9t.js","assets/recharts-CR3TAEof.js","assets/ProvidersPage-BEN5bHZD.js","assets/SettingsPage-hENBFRMI.js","assets/ToolsGuardrailsPage-DWSik0Ga.js","assets/UsagePage-B95PT-hq.js","assets/UsersPage-D5CmT8Bq.js"])))=>i.map(i=>d[i]); -var be=Object.defineProperty;var je=(e,r,s)=>r in e?be(e,r,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[r]=s;var ee=(e,r,s)=>je(e,typeof r!="symbol"?r+"":r,s);import{u as x,j as t,a as v,b as f,k as Q,Q as we,c as Se}from"./tanstack-query-1t81HyiD.js";import{d as ke,r as o,N as ie,O as Pe,H as Ee,e as Ne,f as b,h as Ce}from"./react-dgEcD0HR.js";import{C as I,L as oe,I as le,a as Te,b as _e,B as P,d as L,c as C,T as Ae,e as Le}from"./heroui-BX6JwHY-.js";(function(){const r=document.createElement("link").relList;if(r&&r.supports&&r.supports("modulepreload"))return;for(const n of document.querySelectorAll('link[rel="modulepreload"]'))a(n);new MutationObserver(n=>{for(const l of n)if(l.type==="childList")for(const d of l.addedNodes)d.tagName==="LINK"&&d.rel==="modulepreload"&&a(d)}).observe(document,{childList:!0,subtree:!0});function s(n){const l={};return n.integrity&&(l.integrity=n.integrity),n.referrerPolicy&&(l.referrerPolicy=n.referrerPolicy),n.crossOrigin==="use-credentials"?l.credentials="include":n.crossOrigin==="anonymous"?l.credentials="omit":l.credentials="same-origin",l}function a(n){if(n.ep)return;n.ep=!0;const l=s(n);fetch(n.href,l)}})();var Ie=ke();const qe="modulepreload",Re=function(e){return"/"+e},te={},S=function(r,s,a){let n=Promise.resolve();if(s&&s.length>0){let d=function(h){return Promise.all(h.map(p=>Promise.resolve(p).then(g=>({status:"fulfilled",value:g}),g=>({status:"rejected",reason:g}))))};document.getElementsByTagName("link");const u=document.querySelector("meta[property=csp-nonce]"),y=(u==null?void 0:u.nonce)||(u==null?void 0:u.getAttribute("nonce"));n=d(s.map(h=>{if(h=Re(h),h in te)return;te[h]=!0;const p=h.endsWith(".css"),g=p?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${h}"]${g}`))return;const m=document.createElement("link");if(m.rel=p?"stylesheet":qe,p||(m.as="script"),m.crossOrigin="",m.href=h,y&&m.setAttribute("nonce",y),document.head.appendChild(m),p)return new Promise((c,j)=>{m.addEventListener("load",c),m.addEventListener("error",()=>j(new Error(`Unable to preload CSS for ${h}`)))})}))}function l(d){const u=new Event("vite:preloadError",{cancelable:!0});if(u.payload=d,window.dispatchEvent(u),!u.defaultPrevented)throw d}return n.then(d=>{for(const u of d||[])u.status==="rejected"&&l(u.reason);return r().catch(l)})};class E extends Error{constructor(s,a){super(a);ee(this,"status");this.name="ApiError",this.status=s}}let q=null;function re(e){q=e}async function $(e){try{const r=await e.json();if(typeof r.detail=="string")return r.detail;if(r.detail!=null)return JSON.stringify(r.detail)}catch{}return e.statusText||`Request failed (${e.status})`}async function Oe(e){let r;try{r=await fetch("/v1/auth/session",{method:"POST",headers:{Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify({master_key:e})})}catch{throw new E(0,"Network error: could not reach the gateway.")}if(r.status===401||r.status===403)return!1;if(!r.ok)throw new E(r.status,await $(r));return!0}async function De(){try{await fetch("/v1/auth/session",{method:"DELETE"})}catch{}}async function i(e,r={}){const s=new Headers(r.headers);s.set("Accept","application/json"),r.body!=null&&!s.has("Content-Type")&&s.set("Content-Type","application/json");let a;try{a=await fetch(e,{...r,headers:s})}catch{throw new E(0,"Network error: could not reach the gateway.")}if(a.status===401||a.status===403)throw q==null||q(),new E(a.status,await $(a));if(!a.ok)throw new E(a.status,await $(a));if(a.status!==204)return await a.json()}const z="otari.dashboard.hasSession",ce=o.createContext(null);function Fe(){try{return window.localStorage.getItem(z)==="1"}catch{return!1}}function Me({children:e}){const r=x(),[s,a]=o.useState(Fe),n=o.useCallback(()=>{De(),a(!1),r.clear();try{window.localStorage.removeItem(z)}catch{}},[r]),l=o.useCallback(()=>{r.clear(),a(!0);try{window.localStorage.setItem(z,"1")}catch{}},[r]);o.useEffect(()=>(re(n),()=>re(null)),[n]);const d=o.useMemo(()=>({isAuthenticated:s,login:l,logout:n}),[s,l,n]);return t.jsx(ce.Provider,{value:d,children:e})}function V(){const e=o.useContext(ce);if(!e)throw new Error("useAuth must be used within an AuthProvider");return e}function Ke(e){return e instanceof E&&e.status===0}function Ue(){const e=x(),[r,s]=o.useState(!1);return o.useEffect(()=>{const a=e.getQueryCache(),n=()=>a.getAll().some(l=>l.state.status==="error"&&Ke(l.state.error));return s(n()),a.subscribe(()=>s(n()))},[e]),r}function Be(){return Ue()?t.jsxs("div",{role:"alert","aria-live":"assertive",className:"fixed right-4 bottom-4 z-50 flex max-w-sm items-start gap-2.5 rounded-lg border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700 shadow-lg",children:[t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2","aria-hidden":!0,className:"mt-0.5 h-5 w-5 shrink-0",children:[t.jsx("path",{d:"M12 9v4M12 17h.01",strokeLinecap:"round",strokeLinejoin:"round"}),t.jsx("path",{d:"M10.3 3.9 1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0z",strokeLinejoin:"round"})]}),t.jsxs("span",{children:[t.jsx("strong",{className:"font-semibold",children:"Can’t reach the gateway."})," The backend isn’t responding; data won’t load or save until the connection is restored."]})]}):null}const N="models",O="pricing",ue="settings",de="tool-settings",H="aliases",W="discoverable",G="providers",J="provider-health",me="stored-providers",$e="model-metadata",ze="build",T="keys",_="budgets",fe="users",Y="usage",Qe=6e4,se=60*6e4;function Dt(){return v({queryKey:[N],queryFn:()=>i("/v1/models"),staleTime:6e4})}function Ve(){return v({queryKey:[ze],queryFn:()=>i("/dashboard-build.json"),refetchInterval:Qe,refetchOnWindowFocus:!0,staleTime:0,retry:!1})}function Ft(){return v({queryKey:[W],queryFn:()=>i("/v1/models/discoverable"),staleTime:5*6e4})}function Mt(){return v({queryKey:[G],queryFn:()=>i("/v1/providers"),staleTime:5*6e4})}function Kt(){return v({queryKey:["provider-catalog"],queryFn:()=>i("/v1/providers/catalog"),staleTime:1/0})}function Ut(e){return v({queryKey:["provider-catalog",e],queryFn:()=>i(`/v1/providers/catalog/${encodeURIComponent(e)}`),enabled:e!=="",staleTime:1/0})}function Bt(){return v({queryKey:[J],queryFn:()=>i("/v1/providers/health"),staleTime:se,refetchInterval:se})}function $t(){const e=x();return f({mutationFn:()=>i("/v1/providers/health?refresh=true"),onSuccess:r=>e.setQueryData([J],r)})}function zt(){return v({queryKey:[me],queryFn:()=>i("/v1/provider-credentials"),staleTime:6e4})}function D(e){e.invalidateQueries({queryKey:[me]}),e.invalidateQueries({queryKey:[G]}),e.invalidateQueries({queryKey:[N]}),e.invalidateQueries({queryKey:[W]}),e.invalidateQueries({queryKey:[J]})}function Qt(){const e=x();return f({mutationFn:r=>i("/v1/provider-credentials",{method:"POST",body:JSON.stringify(r)}),onSuccess:()=>D(e)})}function Vt(){const e=x();return f({mutationFn:({instance:r,body:s})=>i(`/v1/provider-credentials/${encodeURIComponent(r)}`,{method:"PATCH",body:JSON.stringify(s)}),onSuccess:()=>D(e)})}function Ht(){const e=x();return f({mutationFn:r=>i(`/v1/provider-credentials/${encodeURIComponent(r)}`,{method:"DELETE"}),onSuccess:()=>D(e)})}function Wt(){const e=x();return f({mutationFn:()=>i("/v1/provider-credentials/reencrypt",{method:"POST"}),onSuccess:()=>D(e)})}function Gt(){return f({mutationFn:e=>i(`/v1/provider-credentials/${encodeURIComponent(e)}/test`,{method:"POST"})})}function Jt(){return f({mutationFn:e=>i("/v1/provider-credentials/test",{method:"POST",body:JSON.stringify(e)})})}function Yt(){return v({queryKey:[$e],queryFn:()=>i("/v1/models/metadata"),staleTime:10*6e4})}function Xt(){return v({queryKey:[H],queryFn:()=>i("/v1/aliases"),staleTime:6e4})}function Zt(){const e=x();return f({mutationFn:r=>i("/v1/aliases",{method:"POST",body:JSON.stringify(r)}),onSuccess:()=>{e.invalidateQueries({queryKey:[H]}),e.invalidateQueries({queryKey:[N]})}})}function er(){const e=x();return f({mutationFn:r=>i(`/v1/aliases/${encodeURIComponent(r)}`,{method:"DELETE"}),onSuccess:()=>{e.invalidateQueries({queryKey:[H]}),e.invalidateQueries({queryKey:[N]})}})}function He(){return v({queryKey:[ue],queryFn:()=>i("/v1/settings"),staleTime:6e4})}function We(){const e=x();return f({mutationFn:r=>i("/v1/settings",{method:"PATCH",body:JSON.stringify(r)}),onSuccess:r=>{e.setQueryData([ue],r),e.invalidateQueries({queryKey:[N]}),e.invalidateQueries({queryKey:[W]})}})}function tr(){return f({mutationFn:()=>i("/v1/settings/master-key/rotate",{method:"POST"})})}function rr(){return v({queryKey:[de],queryFn:()=>i("/v1/tool-settings"),staleTime:6e4})}function sr(){const e=x();return f({mutationFn:r=>i("/v1/tool-settings",{method:"PATCH",body:JSON.stringify(r)}),onSuccess:r=>{e.setQueryData([de],r)}})}function nr(){return f({mutationFn:({service:e,url:r})=>i(`/v1/tool-settings/${encodeURIComponent(e)}/test`,{method:"POST",body:JSON.stringify({url:r})})})}const F=1e3,Ge=100;async function Je(){const e=[];for(let r=0;ri("/v1/pricing",{method:"POST",body:JSON.stringify(r)}),onSuccess:()=>{e.invalidateQueries({queryKey:[O]}),e.invalidateQueries({queryKey:[N]})}})}function or(){const e=x();return f({mutationFn:r=>i(`/v1/pricing/${encodeURIComponent(r)}`,{method:"DELETE"}),onSuccess:()=>{e.invalidateQueries({queryKey:[O]}),e.invalidateQueries({queryKey:[N]})}})}function lr(){return f({mutationFn:()=>i("/v1/pricing/refresh",{method:"POST"})})}function cr(){const e=x();return f({mutationFn:()=>i("/v1/pricing/refresh/confirm",{method:"POST"}),onSuccess:()=>{e.invalidateQueries({queryKey:[O]}),e.invalidateQueries({queryKey:[N]}),e.invalidateQueries({queryKey:[G]})}})}function ur(){return f({mutationFn:()=>i("/v1/pricing/refresh/reject",{method:"POST"})})}const M=1e3,Ye=100;async function Xe(){const e=[];for(let r=0;ri("/v1/keys",{method:"POST",body:JSON.stringify(r)}),onSuccess:()=>void e.invalidateQueries({queryKey:[T]})})}function fr(){const e=x();return f({mutationFn:({id:r,body:s})=>i(`/v1/keys/${encodeURIComponent(r)}`,{method:"PATCH",body:JSON.stringify(s)}),onSuccess:()=>void e.invalidateQueries({queryKey:[T]})})}function hr(){const e=x();return f({mutationFn:r=>i(`/v1/keys/${encodeURIComponent(r)}/rotate`,{method:"POST"}),onSuccess:()=>void e.invalidateQueries({queryKey:[T]})})}function xr(){const e=x();return f({mutationFn:r=>i(`/v1/keys/${encodeURIComponent(r)}`,{method:"DELETE"}),onSuccess:()=>void e.invalidateQueries({queryKey:[T]})})}const K=1e3,Ze=100;async function et(){const e=[];for(let r=0;ri(`/v1/budgets/${encodeURIComponent(e)}/reset-logs`),enabled:e!==null,staleTime:6e4})}function gr(){const e=x();return f({mutationFn:r=>i("/v1/budgets",{method:"POST",body:JSON.stringify(r)}),onSuccess:()=>void e.invalidateQueries({queryKey:[_]})})}function pr(){const e=x();return f({mutationFn:({id:r,body:s})=>i(`/v1/budgets/${encodeURIComponent(r)}`,{method:"PATCH",body:JSON.stringify(s)}),onSuccess:()=>void e.invalidateQueries({queryKey:[_]})})}function br(){const e=x();return f({mutationFn:r=>i(`/v1/budgets/${encodeURIComponent(r)}`,{method:"DELETE"}),onSuccess:()=>void e.invalidateQueries({queryKey:[_]})})}const U=1e3,tt=100;async function rt(){const e=[];for(let r=0;ri("/v1/users",{method:"POST",body:JSON.stringify(r)}),onSuccess:()=>X(e)})}function Sr(){const e=x();return f({mutationFn:({id:r,body:s})=>i(`/v1/users/${encodeURIComponent(r)}`,{method:"PATCH",body:JSON.stringify(s)}),onSuccess:()=>X(e)})}function kr(){const e=x();return f({mutationFn:r=>i(`/v1/users/${encodeURIComponent(r)}`,{method:"DELETE"}),onSuccess:()=>{X(e),e.invalidateQueries({queryKey:[T]})}})}function Z(e){const r=new URLSearchParams;return e.start_date&&r.set("start_date",e.start_date),e.end_date&&r.set("end_date",e.end_date),e.status&&r.set("status",e.status),e.model&&r.set("model",e.model),e.endpoint&&r.set("endpoint",e.endpoint),e.user_id&&r.set("user_id",e.user_id),r}function Pr(e,r,s){return v({queryKey:[Y,"list",e,r,s],queryFn:()=>{const a=Z(e);return a.set("skip",String(r*s)),a.set("limit",String(s)),i(`/v1/usage?${a.toString()}`)},placeholderData:Q,staleTime:1e4})}function Er(e){return v({queryKey:[Y,"count",e],queryFn:()=>i(`/v1/usage/count?${Z(e).toString()}`),placeholderData:Q,staleTime:1e4})}function Nr(e,r,s=!0){return v({queryKey:[Y,"summary",e,r],queryFn:()=>{const a=Z(e);return a.set("bucket",r),i(`/v1/usage/summary?${a.toString()}`)},enabled:s,placeholderData:Q,staleTime:3e4})}function Cr(e){return e==null?"0":new Intl.NumberFormat("en-US").format(e)}function Tr(e){if(e==null)return"$0.00";const r=e!==0&&Math.abs(e)<.01?4:2;return new Intl.NumberFormat("en-US",{style:"currency",currency:"USD",minimumFractionDigits:2,maximumFractionDigits:r}).format(e)}function _r(e){if(e==null)return"—";if(e>=1e6){const r=e/1e6;return`${Number.isInteger(r)?r:r.toFixed(1)}M`}if(e>=1e3){const r=Math.round(e/1e3);return r>=1e3?"1M":`${r}K`}return String(e)}const st=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];function Ar(e){if(!e)return"—";const r=/^(\d{4})-(\d{2})/.exec(e);if(!r)return e;const s=Number(r[2])-1;return s<0||s>11?r[1]:`${st[s]} ${r[1]}`}const nt=new Intl.NumberFormat("en-US",{style:"currency",currency:"USD",maximumFractionDigits:2});function Lr(e){return nt.format(e)}function Ir(e){return e>=1e6?`${(e/1e6).toFixed(1)}M`:e>=1e3?`${(e/1e3).toFixed(1)}k`:String(e)}function at(e){return`${(e*100).toFixed(1)}%`}function qr(e,r){return r===void 0||r===0?null:(e-r)/r}function Rr(e,r=Date.now()){if(!e)return"never";const s=new Date(e);if(Number.isNaN(s.getTime()))return e;const a=Math.round((r-s.getTime())/1e3),n=a<0,l=Math.abs(a),d=[["second",60],["minute",60],["hour",24],["day",30],["month",12],["year",Number.POSITIVE_INFINITY]];let u=l,y="second";for(const[p,g]of d){if(y=p,u0?"▲":e<0?"▼":"•";return t.jsxs("span",{className:"text-[var(--otari-muted)]",children:[r," ",at(Math.abs(e))," vs prev"]})}function it(e){return e instanceof E||e instanceof Error?e.message:"Something went wrong."}function ot({error:e}){return e?t.jsx("div",{role:"alert",className:"rounded-lg border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700",children:it(e)}):null}function lt({tone:e="info",children:r}){const s=e==="warning"?"border-amber-200 bg-amber-50 text-amber-800":"border-[var(--otari-brand)] bg-[var(--otari-brand-tint)] text-[var(--otari-brand-dark)]";return t.jsx("div",{className:`rounded-lg border px-4 py-3 text-sm ${s}`,children:r})}function Fr({title:e,description:r,action:s}){return t.jsxs("div",{className:"flex flex-col gap-3",children:[t.jsxs("div",{children:[t.jsx("h1",{className:"text-xl font-semibold text-[var(--otari-ink)]",children:e}),r?t.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:r}):null]}),s?t.jsx("div",{className:"flex flex-wrap gap-2",children:s}):null]})}function Mr({children:e,confirmLabel:r,onConfirm:s,isPending:a}){const[n,l]=o.useState(!1);return n?t.jsxs("span",{className:"inline-flex items-center gap-1",children:[t.jsx(P,{size:"sm",variant:"danger",isDisabled:a,onPress:s,children:r}),t.jsx(P,{size:"sm",variant:"ghost",isDisabled:a,onPress:()=>l(!1),children:"Cancel"})]}):t.jsx(P,{size:"sm",variant:"danger-soft",onPress:()=>l(!0),children:e})}const ct="rounded-lg border border-[var(--otari-line)] bg-[var(--otari-bg)] px-3 py-2 text-sm text-[var(--otari-ink)] focus:border-[var(--otari-brand)] focus:outline-none";function Kr({id:e,label:r,ariaLabel:s,value:a,onChange:n,options:l,children:d,disabled:u}){const y=o.useId(),h=e??(r?y:void 0),p=t.jsx("select",{id:h,"aria-label":r?void 0:s,value:a,disabled:u,onChange:g=>n(g.target.value),className:ct,children:l?l.map(g=>t.jsx("option",{value:g.value,children:g.label},g.value)):d});return r?t.jsxs("div",{className:"flex flex-col gap-1",children:[t.jsx("label",{htmlFor:h,className:"text-xs font-medium text-[var(--otari-muted)]",children:r}),p]}):p}function Ur({label:e,value:r,onChange:s,options:a,placeholder:n,maxVisible:l=50,allowsCustom:d=!1}){const u=m=>{var c;return((c=a.find(j=>j.value===m))==null?void 0:c.label)??m},[y,h]=o.useState(()=>u(r));o.useEffect(()=>{h(u(r))},[r]);const p=y.trim().toLowerCase(),g=a.filter(m=>!p||m.value.toLowerCase().includes(p)||m.label.toLowerCase().includes(p)).slice(0,l);return t.jsxs(I.Root,{allowsEmptyCollection:!0,allowsCustomValue:d,menuTrigger:"focus",inputValue:y,onInputChange:m=>{h(m),d?s(m.trim()):m.trim()===""&&s("")},onSelectionChange:m=>{m!=null&&s(String(m))},className:"flex flex-col gap-1",children:[t.jsx(oe,{className:"text-xs font-medium text-[var(--otari-muted)]",children:e}),t.jsxs(I.InputGroup,{children:[t.jsx(le,{placeholder:n,autoComplete:"off",onFocus:m=>m.currentTarget.select()}),t.jsx(I.Trigger,{})]}),t.jsx(I.Popover,{children:t.jsx(Te,{items:g,className:"max-h-72 overflow-auto",children:m=>t.jsx(_e,{id:m.value,textValue:m.label,children:m.label})})})]})}function ut(){var l;const e=He(),r=We(),[s,a]=o.useState(!1);return!(((l=e.data)==null?void 0:l.require_pricing)===!0&&e.data.default_pricing===!1)||s?null:t.jsx("div",{className:"shrink-0 px-6 pt-3",children:t.jsx(lt,{tone:"warning",children:t.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[t.jsxs("span",{children:["Requests are rejected until pricing is set (",t.jsx("code",{children:"require_pricing"})," is on). Enable default pricing to meter new models with public rates right away."]}),t.jsxs("span",{className:"flex items-center gap-2",children:[t.jsx(P,{size:"sm",variant:"primary",isDisabled:r.isPending,onPress:()=>r.mutate({default_pricing:!0}),children:r.isPending?"Enabling…":"Enable default pricing"}),t.jsx(P,{size:"sm",variant:"ghost",onPress:()=>a(!0),children:"Dismiss"})]})]})})})}function dt(){const{data:e}=Ve(),r=o.useRef(null);return e&&r.current===null&&(r.current=e.build),e!=null&&r.current!=null&&e.build!==r.current}function mt(){const e=dt(),[r,s]=o.useState(!1);return!e||r?null:t.jsx("div",{className:"pointer-events-none absolute inset-x-0 top-0 z-50 flex justify-center",children:t.jsxs("div",{role:"status",className:"pointer-events-auto mt-1.5 flex items-center gap-3 rounded-full border border-[var(--otari-brand)] bg-[var(--otari-brand-tint)] py-1.5 pr-1.5 pl-4 text-sm text-[var(--otari-brand-dark)] shadow-md",children:[t.jsxs("span",{children:[t.jsx("strong",{className:"font-semibold",children:"An update is available."})," Reloading keeps you signed in."]}),t.jsx(P,{size:"sm",variant:"primary",onPress:()=>window.location.reload(),children:"Update now"}),t.jsx(P,{size:"sm",variant:"ghost",onPress:()=>s(!0),children:"Later"})]})})}const he=200,xe=480,B=240,ft=60,ye="otari.dashboard.sidebarWidth",ve="otari.dashboard.sidebarCollapsed",ae=16,R=e=>Math.min(xe,Math.max(he,e));function ht(){if(typeof window>"u")return B;try{const e=window.localStorage.getItem(ye),r=e?Number.parseInt(e,10):Number.NaN;return Number.isNaN(r)?B:R(r)}catch{return B}}function xt(){if(typeof window>"u")return!1;try{return window.localStorage.getItem(ve)==="1"}catch{return!1}}const yt=[{key:"home"},{key:"observability",label:"Observability"},{key:"catalog",label:"Catalog"},{key:"access",label:"Access"},{key:"system"}],vt=[{to:"/",section:"home",label:"Overview",end:!0,icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("rect",{x:"3.5",y:"3.5",width:"7",height:"7",rx:"1.5",strokeLinejoin:"round"}),t.jsx("rect",{x:"13.5",y:"3.5",width:"7",height:"7",rx:"1.5",strokeLinejoin:"round"}),t.jsx("rect",{x:"3.5",y:"13.5",width:"7",height:"7",rx:"1.5",strokeLinejoin:"round"}),t.jsx("rect",{x:"13.5",y:"13.5",width:"7",height:"7",rx:"1.5",strokeLinejoin:"round"})]})},{to:"/activity",section:"observability",label:"Activity",icon:t.jsx("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:t.jsx("path",{d:"M3 12h4l2.5-6 4 12 2.5-6H21",strokeLinecap:"round",strokeLinejoin:"round"})})},{to:"/usage",section:"observability",label:"Usage",icon:t.jsx("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:t.jsx("path",{d:"M4 20V10M10 20V4M16 20v-7M22 20H2",strokeLinecap:"round",strokeLinejoin:"round"})})},{to:"/providers",section:"catalog",label:"Providers",icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("rect",{x:"3.5",y:"4.5",width:"17",height:"6",rx:"1.5",strokeLinejoin:"round"}),t.jsx("rect",{x:"3.5",y:"13.5",width:"17",height:"6",rx:"1.5",strokeLinejoin:"round"}),t.jsx("path",{d:"M7 7.5h.01M7 16.5h.01",strokeLinecap:"round",strokeLinejoin:"round"})]})},{to:"/users",section:"access",label:"Users",icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("circle",{cx:"9",cy:"8",r:"3.2",strokeLinejoin:"round"}),t.jsx("path",{d:"M3.5 19a5.5 5.5 0 0 1 11 0",strokeLinecap:"round",strokeLinejoin:"round"}),t.jsx("path",{d:"M16 5.2a3.2 3.2 0 0 1 0 5.6M17.5 19a5.5 5.5 0 0 0-3-4.9",strokeLinecap:"round",strokeLinejoin:"round"})]})},{to:"/keys",section:"access",label:"API keys",icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("circle",{cx:"7.5",cy:"15.5",r:"3.5"}),t.jsx("path",{d:"M10 13l7-7M14 5l3 3M16.5 7.5l2-2",strokeLinecap:"round",strokeLinejoin:"round"})]})},{to:"/budgets",section:"access",label:"Budgets",icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("path",{d:"M3 7.5A1.5 1.5 0 0 1 4.5 6H18a1.5 1.5 0 0 1 1.5 1.5V9",strokeLinejoin:"round"}),t.jsx("rect",{x:"3",y:"7.5",width:"18",height:"12",rx:"1.5",strokeLinejoin:"round"}),t.jsx("path",{d:"M16 13.5h.01",strokeLinecap:"round",strokeLinejoin:"round"}),t.jsx("path",{d:"M21 12v3h-3.5a1.5 1.5 0 0 1 0-3H21z",strokeLinejoin:"round"})]})},{to:"/models",section:"catalog",label:"Models",icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("path",{d:"M12 3l8 4.5v9L12 21l-8-4.5v-9L12 3z",strokeLinejoin:"round"}),t.jsx("path",{d:"M12 12l8-4.5M12 12v9M12 12L4 7.5",strokeLinejoin:"round"})]})},{to:"/aliases",section:"catalog",label:"Aliases",icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("path",{d:"M20.6 13.4L13.4 20.6a2 2 0 0 1-2.8 0l-7-7A2 2 0 0 1 3 12.2V5a2 2 0 0 1 2-2h7.2a2 2 0 0 1 1.4.6l7 7a2 2 0 0 1 0 2.8z",strokeLinejoin:"round"}),t.jsx("circle",{cx:"7.5",cy:"7.5",r:"1.5"})]})},{to:"/tools",section:"system",label:"Tools & Guardrails",icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("path",{d:"M14.7 6.3a4 4 0 0 1 5 5l-8.4 8.4a2 2 0 0 1-2.8 0l-2.2-2.2a2 2 0 0 1 0-2.8z",strokeLinejoin:"round"}),t.jsx("path",{d:"M12 9 5 16",strokeLinecap:"round"})]})},{to:"/settings",section:"system",label:"Settings",icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("circle",{cx:"12",cy:"12",r:"3"}),t.jsx("path",{d:"M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z",strokeLinejoin:"round"})]})}];function gt(){const{logout:e}=V(),r=o.useRef(null),[s,a]=o.useState(ht),[n,l]=o.useState(xt),[d,u]=o.useState(!1);o.useEffect(()=>{const c=window.setTimeout(()=>{try{window.localStorage.setItem(ye,String(Math.round(s)))}catch{}},200);return()=>window.clearTimeout(c)},[s]),o.useEffect(()=>{try{window.localStorage.setItem(ve,n?"1":"0")}catch{}},[n]);const y=o.useCallback(c=>{c.preventDefault(),c.currentTarget.setPointerCapture(c.pointerId),u(!0)},[]),h=o.useCallback(c=>{var A;if(!c.currentTarget.hasPointerCapture(c.pointerId))return;const j=((A=r.current)==null?void 0:A.getBoundingClientRect().left)??0;a(R(c.clientX-j))},[]),p=o.useCallback(c=>{c.currentTarget.hasPointerCapture(c.pointerId)&&c.currentTarget.releasePointerCapture(c.pointerId),u(!1)},[]),g=o.useCallback(c=>{c.key==="ArrowLeft"?(c.preventDefault(),a(j=>R(j-ae))):c.key==="ArrowRight"&&(c.preventDefault(),a(j=>R(j+ae)))},[]),m=n?ft:s;return t.jsxs("div",{className:C("relative flex h-full flex-col overflow-hidden",d&&"cursor-col-resize select-none"),children:[t.jsxs("header",{className:"flex shrink-0 items-center justify-between border-b border-[var(--otari-line)] bg-[var(--otari-surface)] px-5 py-3",children:[t.jsxs("div",{className:"flex items-center gap-2.5",children:[t.jsx("img",{src:"/favicon.svg",alt:"",className:"h-7 w-7 shrink-0"}),t.jsx("span",{className:"text-base font-semibold text-[var(--otari-ink)]",children:"Otari"})]}),t.jsx(P,{size:"sm",variant:"outline",onPress:e,"aria-label":"Sign out",children:"Sign out"})]}),t.jsx(mt,{}),t.jsx(Be,{}),t.jsx(ut,{}),t.jsxs("div",{className:"flex min-h-0 flex-1",children:[t.jsxs("aside",{ref:r,style:{width:m},className:C("relative flex shrink-0 flex-col border-r border-[var(--otari-line)] bg-[var(--otari-surface)]",!d&&"transition-[width] duration-150"),children:[t.jsx("button",{type:"button",onClick:()=>l(c=>!c),"aria-label":n?"Expand sidebar":"Collapse sidebar","aria-pressed":n,title:n?"Expand sidebar":"Collapse sidebar",className:"absolute -right-3 top-4 z-30 flex h-6 w-6 items-center justify-center rounded-full border border-[var(--otari-line)] bg-[var(--otari-surface)] text-[var(--otari-muted)] shadow-sm transition-colors hover:border-[var(--otari-brand)] hover:text-[var(--otari-brand-dark)]",children:t.jsx("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",className:C("h-3.5 w-3.5 transition-transform",n&&"rotate-180"),children:t.jsx("path",{d:"M15 6l-6 6 6 6",strokeLinecap:"round",strokeLinejoin:"round"})})}),t.jsx("nav",{className:C("flex flex-col py-4",n?"px-2":"px-3"),children:yt.map((c,j)=>{const A=vt.filter(k=>k.section===c.key);return A.length===0?null:t.jsxs("div",{className:j>0?"mt-4":void 0,children:[!n&&c.label?t.jsx("div",{className:"px-3 pb-1 text-[11px] font-semibold tracking-wider text-[var(--otari-muted)] uppercase",children:c.label}):null,j>0&&(n||!c.label)?t.jsx("div",{className:"mx-1 mb-2 border-t border-[var(--otari-line)]"}):null,t.jsx("div",{className:"flex flex-col gap-1",children:A.map(k=>t.jsxs(ie,{to:k.to,end:k.end,"aria-label":n?k.label:void 0,title:n?k.label:void 0,className:({isActive:pe})=>C("flex items-center rounded-lg py-2 text-sm font-medium transition-colors",n?"justify-center px-0":"gap-3 px-3",pe?"bg-[var(--otari-brand-tint)] text-[var(--otari-brand-dark)]":"text-[var(--otari-muted)] hover:bg-[var(--otari-bg)] hover:text-[var(--otari-ink)]"),children:[k.icon,n?null:k.label]},k.to))})]},c.key)})}),t.jsxs("a",{href:"https://otari.ai",target:"_blank",rel:"noreferrer",title:"otari.ai — the hosted Otari gateway",className:C("mt-auto mb-3 flex items-center rounded-lg py-2 text-xs font-medium text-[var(--otari-muted)] transition-colors hover:bg-[var(--otari-bg)] hover:text-[var(--otari-brand-dark)]",n?"mx-2 justify-center px-0":"mx-3 gap-2 px-3"),children:[t.jsx("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-4 w-4 shrink-0",children:t.jsx("path",{d:"M18 10h-1.26A8 8 0 1 0 9 20h9a5 5 0 0 0 0-10z",strokeLinejoin:"round"})}),n?null:t.jsxs("span",{className:"flex-1",children:["otari.ai ",t.jsx("span",{"aria-hidden":!0,children:"↗"})]})]}),n?null:t.jsx("div",{role:"separator","aria-orientation":"vertical","aria-label":"Resize sidebar","aria-valuenow":Math.round(s),"aria-valuemin":he,"aria-valuemax":xe,tabIndex:0,onPointerDown:y,onPointerMove:h,onPointerUp:p,onKeyDown:g,className:C("absolute top-0 right-0 z-10 h-full w-1.5 cursor-col-resize touch-none transition-colors","hover:bg-[var(--otari-brand)] focus-visible:bg-[var(--otari-brand)] focus:outline-none",d?"bg-[var(--otari-brand)]":"bg-transparent")})]}),t.jsx("main",{className:"flex-1 overflow-y-auto",children:t.jsx("div",{className:"mx-auto flex max-w-[1800px] flex-col gap-6 px-6 py-6",children:t.jsx(Pe,{})})})]})]})}function pt(){const{login:e}=V(),[r,s]=o.useState(""),[a,n]=o.useState(null),[l,d]=o.useState(!1),u=async()=>{const y=r.trim();if(!(!y||l)){d(!0),n(null);try{await Oe(y)?e():n(new Error("Invalid master key."))}catch(h){n(h)}finally{d(!1)}}};return t.jsx("div",{className:"flex min-h-full items-center justify-center p-6",children:t.jsx(L,{className:"w-full max-w-md",children:t.jsxs(L.Content,{className:"flex flex-col gap-5 p-7",children:[t.jsxs("div",{className:"flex flex-col items-center gap-3 text-center",children:[t.jsx("img",{src:"/favicon.svg",alt:"Otari",className:"h-12 w-12"}),t.jsxs("div",{children:[t.jsx("h1",{className:"text-lg font-semibold text-[var(--otari-ink)]",children:"Otari Dashboard"}),t.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:"Sign in with your master key to browse models, set pricing, and manage settings."})]})]}),t.jsxs("form",{className:"flex flex-col gap-4",onSubmit:y=>{y.preventDefault(),u()},children:[t.jsxs(Ae,{value:r,onChange:y=>{s(y),a&&n(null)},type:"password",isRequired:!0,className:"flex flex-col gap-1",children:[t.jsx(oe,{className:"text-sm font-medium text-[var(--otari-ink)]",children:"Master key"}),t.jsx(le,{placeholder:"otari-mk-… or your master key",autoFocus:!0,autoComplete:"off"})]}),t.jsxs("details",{className:"text-xs text-[var(--otari-muted)]",children:[t.jsx("summary",{className:"cursor-pointer font-medium text-[var(--otari-brand-dark)]",children:"First run? Where to find your key"}),t.jsxs("p",{className:"mt-2 leading-relaxed",children:["If you did not set ",t.jsx("code",{children:"OTARI_MASTER_KEY"}),", Otari generated one and printed it to the server logs on startup. Look for the line ",t.jsx("code",{children:"Your master key:"})," (for example, run"," ",t.jsx("code",{children:"docker logs "}),") and paste it above."]})]}),t.jsx(ot,{error:a}),t.jsx(P,{type:"submit",variant:"primary",fullWidth:!0,isDisabled:!r.trim()||l,children:l?"Signing in…":"Sign in"})]}),t.jsx("p",{className:"text-center text-xs text-[var(--otari-muted)]",children:"The key is sent once to this gateway and exchanged for a session cookie; it is never stored in the browser."}),t.jsx("div",{className:"border-t border-[var(--otari-line)] pt-4 text-center",children:t.jsx(Le,{href:"/welcome",className:"text-sm font-medium text-[var(--otari-brand-dark)]",children:"New to Otari? Open the welcome guide"})})]})})})}const bt=o.lazy(async()=>({default:(await S(async()=>{const{ActivityPage:e}=await import("./ActivityPage-BrL4O-hT.js");return{ActivityPage:e}},__vite__mapDeps([0,1,2,3,4]))).ActivityPage})),jt=o.lazy(async()=>({default:(await S(async()=>{const{AliasesPage:e}=await import("./AliasesPage-RDVKM-by.js");return{AliasesPage:e}},__vite__mapDeps([5,1,2,6,4,3]))).AliasesPage})),wt=o.lazy(async()=>({default:(await S(async()=>{const{BudgetsPage:e}=await import("./BudgetsPage-Ctwj8twD.js");return{BudgetsPage:e}},__vite__mapDeps([7,1,2,6,4,3]))).BudgetsPage})),St=o.lazy(async()=>({default:(await S(async()=>{const{KeysPage:e}=await import("./KeysPage-DCo4FFYU.js");return{KeysPage:e}},__vite__mapDeps([8,1,2,6,4,9,3]))).KeysPage})),kt=o.lazy(async()=>({default:(await S(async()=>{const{ModelsPage:e}=await import("./ModelsPage-C028BOtV.js");return{ModelsPage:e}},__vite__mapDeps([10,1,2,3,4]))).ModelsPage})),Pt=o.lazy(async()=>({default:(await S(async()=>{const{OverviewIndex:e}=await import("./OverviewPage-KThfhw1Z.js");return{OverviewIndex:e}},__vite__mapDeps([11,1,2,12,13,4,3]))).OverviewIndex})),Et=o.lazy(async()=>({default:(await S(async()=>{const{ProvidersPage:e}=await import("./ProvidersPage-BEN5bHZD.js");return{ProvidersPage:e}},__vite__mapDeps([14,1,2,6,4,3]))).ProvidersPage})),Nt=o.lazy(async()=>({default:(await S(async()=>{const{SettingsPage:e}=await import("./SettingsPage-hENBFRMI.js");return{SettingsPage:e}},__vite__mapDeps([15,1,2,4]))).SettingsPage})),Ct=o.lazy(async()=>({default:(await S(async()=>{const{ToolsGuardrailsPage:e}=await import("./ToolsGuardrailsPage-DWSik0Ga.js");return{ToolsGuardrailsPage:e}},__vite__mapDeps([16,1,2,4]))).ToolsGuardrailsPage})),Tt=o.lazy(async()=>({default:(await S(async()=>{const{UsagePage:e}=await import("./UsagePage-B95PT-hq.js");return{UsagePage:e}},__vite__mapDeps([17,1,2,12,13,4,3]))).UsagePage})),_t=o.lazy(async()=>({default:(await S(async()=>{const{UsersPage:e}=await import("./UsersPage-D5CmT8Bq.js");return{UsersPage:e}},__vite__mapDeps([18,1,2,6,4,9,3]))).UsersPage}));function w(e){return t.jsx(o.Suspense,{fallback:t.jsx("div",{role:"status",children:"Loading page…"}),children:e})}function At(){const{isAuthenticated:e}=V();return e?t.jsx(Ee,{children:t.jsx(Ne,{children:t.jsxs(b,{element:t.jsx(gt,{}),children:[t.jsx(b,{index:!0,element:w(t.jsx(Pt,{}))}),t.jsx(b,{path:"providers",element:w(t.jsx(Et,{}))}),t.jsx(b,{path:"keys",element:w(t.jsx(St,{}))}),t.jsx(b,{path:"users",element:w(t.jsx(_t,{}))}),t.jsx(b,{path:"budgets",element:w(t.jsx(wt,{}))}),t.jsx(b,{path:"activity",element:w(t.jsx(bt,{}))}),t.jsx(b,{path:"usage",element:w(t.jsx(Tt,{}))}),t.jsx(b,{path:"models",element:w(t.jsx(kt,{}))}),t.jsx(b,{path:"aliases",element:w(t.jsx(jt,{}))}),t.jsx(b,{path:"tools",element:w(t.jsx(Ct,{}))}),t.jsx(b,{path:"settings",element:w(t.jsx(Nt,{}))}),t.jsx(b,{path:"*",element:t.jsx(Ce,{to:"/",replace:!0})})]})})}):t.jsx(pt,{})}function Lt({children:e}){const[r]=o.useState(()=>new we({defaultOptions:{queries:{refetchOnWindowFocus:!1,retry:(s,a)=>a instanceof E&&(a.status===401||a.status===403)?!1:s<2}}}));return t.jsx(Se,{client:r,children:t.jsx(Me,{children:e})})}const ge=document.getElementById("root");if(!ge)throw new Error("Root element #root not found");Ie.createRoot(ge).render(t.jsx(o.StrictMode,{children:t.jsx(Lt,{children:t.jsx(At,{})})}));export{Jt as $,Ar as A,He as B,Mr as C,Tr as D,ot as E,Kr as F,ir as G,or as H,lt as I,Mt as J,Bt as K,qr as L,Lr as M,Dr as N,at as O,Fr as P,Rr as Q,zt as R,Or as S,Ht as T,Gt as U,We as V,Vt as W,$t as X,Qt as Y,Ut as Z,Kt as _,Pr as a,lr as a0,cr as a1,ur as a2,tr as a3,Wt as a4,rr as a5,sr as a6,nr as a7,Ir as a8,kr as a9,wr as aa,Er as b,Nr as c,Ur as d,Ft as e,Xt as f,er as g,it as h,Zt as i,yr as j,gr as k,pr as l,br as m,Sr as n,vr as o,dr as p,fr as q,hr as r,xr as s,mr as t,jr as u,Dt as v,ar as w,Yt as x,_r as y,Cr as z}; +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/ActivityPage-dbjTjmS5.js","assets/tanstack-query-1t81HyiD.js","assets/react-dgEcD0HR.js","assets/Table-CLdjdyTx.js","assets/heroui-BX6JwHY-.js","assets/AliasesPage-DqjEr6cA.js","assets/Field-HzRk1KDP.js","assets/BudgetsPage-DK4vAOyb.js","assets/KeysPage-DkXRnk8b.js","assets/ModelScopeControl-CV1Wulbr.js","assets/ModelsPage-C-ZlmFwf.js","assets/OverviewPage-Cb1DW9ZC.js","assets/charts-Cr3Dij9t.js","assets/recharts-CR3TAEof.js","assets/ProvidersPage-CLe2cN4-.js","assets/SettingsPage-BdorKXf4.js","assets/ToolsGuardrailsPage-D8Qsr-tI.js","assets/UsagePage-CRzEneXv.js","assets/UsersPage-zP5EVG6k.js"])))=>i.map(i=>d[i]); +var be=Object.defineProperty;var je=(e,r,s)=>r in e?be(e,r,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[r]=s;var ee=(e,r,s)=>je(e,typeof r!="symbol"?r+"":r,s);import{u as x,j as t,a as v,b as f,k as Q,Q as we,c as Se}from"./tanstack-query-1t81HyiD.js";import{d as ke,r as o,N as ie,O as Pe,H as Ee,e as Ne,f as b,h as Ce}from"./react-dgEcD0HR.js";import{C as I,L as oe,I as le,a as Te,b as _e,B as P,d as L,c as C,T as Ae,e as Le}from"./heroui-BX6JwHY-.js";(function(){const r=document.createElement("link").relList;if(r&&r.supports&&r.supports("modulepreload"))return;for(const n of document.querySelectorAll('link[rel="modulepreload"]'))a(n);new MutationObserver(n=>{for(const l of n)if(l.type==="childList")for(const d of l.addedNodes)d.tagName==="LINK"&&d.rel==="modulepreload"&&a(d)}).observe(document,{childList:!0,subtree:!0});function s(n){const l={};return n.integrity&&(l.integrity=n.integrity),n.referrerPolicy&&(l.referrerPolicy=n.referrerPolicy),n.crossOrigin==="use-credentials"?l.credentials="include":n.crossOrigin==="anonymous"?l.credentials="omit":l.credentials="same-origin",l}function a(n){if(n.ep)return;n.ep=!0;const l=s(n);fetch(n.href,l)}})();var Ie=ke();const qe="modulepreload",Re=function(e){return"/"+e},te={},S=function(r,s,a){let n=Promise.resolve();if(s&&s.length>0){let d=function(h){return Promise.all(h.map(p=>Promise.resolve(p).then(g=>({status:"fulfilled",value:g}),g=>({status:"rejected",reason:g}))))};document.getElementsByTagName("link");const u=document.querySelector("meta[property=csp-nonce]"),y=(u==null?void 0:u.nonce)||(u==null?void 0:u.getAttribute("nonce"));n=d(s.map(h=>{if(h=Re(h),h in te)return;te[h]=!0;const p=h.endsWith(".css"),g=p?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${h}"]${g}`))return;const m=document.createElement("link");if(m.rel=p?"stylesheet":qe,p||(m.as="script"),m.crossOrigin="",m.href=h,y&&m.setAttribute("nonce",y),document.head.appendChild(m),p)return new Promise((c,j)=>{m.addEventListener("load",c),m.addEventListener("error",()=>j(new Error(`Unable to preload CSS for ${h}`)))})}))}function l(d){const u=new Event("vite:preloadError",{cancelable:!0});if(u.payload=d,window.dispatchEvent(u),!u.defaultPrevented)throw d}return n.then(d=>{for(const u of d||[])u.status==="rejected"&&l(u.reason);return r().catch(l)})};class E extends Error{constructor(s,a){super(a);ee(this,"status");this.name="ApiError",this.status=s}}let q=null;function re(e){q=e}async function $(e){try{const r=await e.json();if(typeof r.detail=="string")return r.detail;if(r.detail!=null)return JSON.stringify(r.detail)}catch{}return e.statusText||`Request failed (${e.status})`}async function Oe(e){let r;try{r=await fetch("/v1/auth/session",{method:"POST",headers:{Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify({master_key:e})})}catch{throw new E(0,"Network error: could not reach the gateway.")}if(r.status===401||r.status===403)return!1;if(!r.ok)throw new E(r.status,await $(r));return!0}async function De(){try{await fetch("/v1/auth/session",{method:"DELETE"})}catch{}}async function i(e,r={}){const s=new Headers(r.headers);s.set("Accept","application/json"),r.body!=null&&!s.has("Content-Type")&&s.set("Content-Type","application/json");let a;try{a=await fetch(e,{...r,headers:s})}catch{throw new E(0,"Network error: could not reach the gateway.")}if(a.status===401||a.status===403)throw q==null||q(),new E(a.status,await $(a));if(!a.ok)throw new E(a.status,await $(a));if(a.status!==204)return await a.json()}const z="otari.dashboard.hasSession",ce=o.createContext(null);function Fe(){try{return window.localStorage.getItem(z)==="1"}catch{return!1}}function Me({children:e}){const r=x(),[s,a]=o.useState(Fe),n=o.useCallback(()=>{De(),a(!1),r.clear();try{window.localStorage.removeItem(z)}catch{}},[r]),l=o.useCallback(()=>{r.clear(),a(!0);try{window.localStorage.setItem(z,"1")}catch{}},[r]);o.useEffect(()=>(re(n),()=>re(null)),[n]);const d=o.useMemo(()=>({isAuthenticated:s,login:l,logout:n}),[s,l,n]);return t.jsx(ce.Provider,{value:d,children:e})}function V(){const e=o.useContext(ce);if(!e)throw new Error("useAuth must be used within an AuthProvider");return e}function Ke(e){return e instanceof E&&e.status===0}function Ue(){const e=x(),[r,s]=o.useState(!1);return o.useEffect(()=>{const a=e.getQueryCache(),n=()=>a.getAll().some(l=>l.state.status==="error"&&Ke(l.state.error));return s(n()),a.subscribe(()=>s(n()))},[e]),r}function Be(){return Ue()?t.jsxs("div",{role:"alert","aria-live":"assertive",className:"fixed right-4 bottom-4 z-50 flex max-w-sm items-start gap-2.5 rounded-lg border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700 shadow-lg",children:[t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2","aria-hidden":!0,className:"mt-0.5 h-5 w-5 shrink-0",children:[t.jsx("path",{d:"M12 9v4M12 17h.01",strokeLinecap:"round",strokeLinejoin:"round"}),t.jsx("path",{d:"M10.3 3.9 1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0z",strokeLinejoin:"round"})]}),t.jsxs("span",{children:[t.jsx("strong",{className:"font-semibold",children:"Can’t reach the gateway."})," The backend isn’t responding; data won’t load or save until the connection is restored."]})]}):null}const N="models",O="pricing",ue="settings",de="tool-settings",H="aliases",W="discoverable",G="providers",J="provider-health",me="stored-providers",$e="model-metadata",ze="build",T="keys",_="budgets",fe="users",Y="usage",Qe=6e4,se=60*6e4;function Dt(){return v({queryKey:[N],queryFn:()=>i("/v1/models"),staleTime:6e4})}function Ve(){return v({queryKey:[ze],queryFn:()=>i("/dashboard-build.json"),refetchInterval:Qe,refetchOnWindowFocus:!0,staleTime:0,retry:!1})}function Ft(){return v({queryKey:[W],queryFn:()=>i("/v1/models/discoverable"),staleTime:5*6e4})}function Mt(){return v({queryKey:[G],queryFn:()=>i("/v1/providers"),staleTime:5*6e4})}function Kt(){return v({queryKey:["provider-catalog"],queryFn:()=>i("/v1/providers/catalog"),staleTime:1/0})}function Ut(e){return v({queryKey:["provider-catalog",e],queryFn:()=>i(`/v1/providers/catalog/${encodeURIComponent(e)}`),enabled:e!=="",staleTime:1/0})}function Bt(){return v({queryKey:[J],queryFn:()=>i("/v1/providers/health"),staleTime:se,refetchInterval:se})}function $t(){const e=x();return f({mutationFn:()=>i("/v1/providers/health?refresh=true"),onSuccess:r=>e.setQueryData([J],r)})}function zt(){return v({queryKey:[me],queryFn:()=>i("/v1/provider-credentials"),staleTime:6e4})}function D(e){e.invalidateQueries({queryKey:[me]}),e.invalidateQueries({queryKey:[G]}),e.invalidateQueries({queryKey:[N]}),e.invalidateQueries({queryKey:[W]}),e.invalidateQueries({queryKey:[J]})}function Qt(){const e=x();return f({mutationFn:r=>i("/v1/provider-credentials",{method:"POST",body:JSON.stringify(r)}),onSuccess:()=>D(e)})}function Vt(){const e=x();return f({mutationFn:({instance:r,body:s})=>i(`/v1/provider-credentials/${encodeURIComponent(r)}`,{method:"PATCH",body:JSON.stringify(s)}),onSuccess:()=>D(e)})}function Ht(){const e=x();return f({mutationFn:r=>i(`/v1/provider-credentials/${encodeURIComponent(r)}`,{method:"DELETE"}),onSuccess:()=>D(e)})}function Wt(){const e=x();return f({mutationFn:()=>i("/v1/provider-credentials/reencrypt",{method:"POST"}),onSuccess:()=>D(e)})}function Gt(){return f({mutationFn:e=>i(`/v1/provider-credentials/${encodeURIComponent(e)}/test`,{method:"POST"})})}function Jt(){return f({mutationFn:e=>i("/v1/provider-credentials/test",{method:"POST",body:JSON.stringify(e)})})}function Yt(){return v({queryKey:[$e],queryFn:()=>i("/v1/models/metadata"),staleTime:10*6e4})}function Xt(){return v({queryKey:[H],queryFn:()=>i("/v1/aliases"),staleTime:6e4})}function Zt(){const e=x();return f({mutationFn:r=>i("/v1/aliases",{method:"POST",body:JSON.stringify(r)}),onSuccess:()=>{e.invalidateQueries({queryKey:[H]}),e.invalidateQueries({queryKey:[N]})}})}function er(){const e=x();return f({mutationFn:r=>i(`/v1/aliases/${encodeURIComponent(r)}`,{method:"DELETE"}),onSuccess:()=>{e.invalidateQueries({queryKey:[H]}),e.invalidateQueries({queryKey:[N]})}})}function He(){return v({queryKey:[ue],queryFn:()=>i("/v1/settings"),staleTime:6e4})}function We(){const e=x();return f({mutationFn:r=>i("/v1/settings",{method:"PATCH",body:JSON.stringify(r)}),onSuccess:r=>{e.setQueryData([ue],r),e.invalidateQueries({queryKey:[N]}),e.invalidateQueries({queryKey:[W]})}})}function tr(){return f({mutationFn:()=>i("/v1/settings/master-key/rotate",{method:"POST"})})}function rr(){return v({queryKey:[de],queryFn:()=>i("/v1/tool-settings"),staleTime:6e4})}function sr(){const e=x();return f({mutationFn:r=>i("/v1/tool-settings",{method:"PATCH",body:JSON.stringify(r)}),onSuccess:r=>{e.setQueryData([de],r)}})}function nr(){return f({mutationFn:({service:e,url:r})=>i(`/v1/tool-settings/${encodeURIComponent(e)}/test`,{method:"POST",body:JSON.stringify({url:r})})})}const F=1e3,Ge=100;async function Je(){const e=[];for(let r=0;ri("/v1/pricing",{method:"POST",body:JSON.stringify(r)}),onSuccess:()=>{e.invalidateQueries({queryKey:[O]}),e.invalidateQueries({queryKey:[N]})}})}function or(){const e=x();return f({mutationFn:r=>i(`/v1/pricing/${encodeURIComponent(r)}`,{method:"DELETE"}),onSuccess:()=>{e.invalidateQueries({queryKey:[O]}),e.invalidateQueries({queryKey:[N]})}})}function lr(){return f({mutationFn:()=>i("/v1/pricing/refresh",{method:"POST"})})}function cr(){const e=x();return f({mutationFn:()=>i("/v1/pricing/refresh/confirm",{method:"POST"}),onSuccess:()=>{e.invalidateQueries({queryKey:[O]}),e.invalidateQueries({queryKey:[N]}),e.invalidateQueries({queryKey:[G]})}})}function ur(){return f({mutationFn:()=>i("/v1/pricing/refresh/reject",{method:"POST"})})}const M=1e3,Ye=100;async function Xe(){const e=[];for(let r=0;ri("/v1/keys",{method:"POST",body:JSON.stringify(r)}),onSuccess:()=>void e.invalidateQueries({queryKey:[T]})})}function fr(){const e=x();return f({mutationFn:({id:r,body:s})=>i(`/v1/keys/${encodeURIComponent(r)}`,{method:"PATCH",body:JSON.stringify(s)}),onSuccess:()=>void e.invalidateQueries({queryKey:[T]})})}function hr(){const e=x();return f({mutationFn:r=>i(`/v1/keys/${encodeURIComponent(r)}/rotate`,{method:"POST"}),onSuccess:()=>void e.invalidateQueries({queryKey:[T]})})}function xr(){const e=x();return f({mutationFn:r=>i(`/v1/keys/${encodeURIComponent(r)}`,{method:"DELETE"}),onSuccess:()=>void e.invalidateQueries({queryKey:[T]})})}const K=1e3,Ze=100;async function et(){const e=[];for(let r=0;ri(`/v1/budgets/${encodeURIComponent(e)}/reset-logs`),enabled:e!==null,staleTime:6e4})}function gr(){const e=x();return f({mutationFn:r=>i("/v1/budgets",{method:"POST",body:JSON.stringify(r)}),onSuccess:()=>void e.invalidateQueries({queryKey:[_]})})}function pr(){const e=x();return f({mutationFn:({id:r,body:s})=>i(`/v1/budgets/${encodeURIComponent(r)}`,{method:"PATCH",body:JSON.stringify(s)}),onSuccess:()=>void e.invalidateQueries({queryKey:[_]})})}function br(){const e=x();return f({mutationFn:r=>i(`/v1/budgets/${encodeURIComponent(r)}`,{method:"DELETE"}),onSuccess:()=>void e.invalidateQueries({queryKey:[_]})})}const U=1e3,tt=100;async function rt(){const e=[];for(let r=0;ri("/v1/users",{method:"POST",body:JSON.stringify(r)}),onSuccess:()=>X(e)})}function Sr(){const e=x();return f({mutationFn:({id:r,body:s})=>i(`/v1/users/${encodeURIComponent(r)}`,{method:"PATCH",body:JSON.stringify(s)}),onSuccess:()=>X(e)})}function kr(){const e=x();return f({mutationFn:r=>i(`/v1/users/${encodeURIComponent(r)}`,{method:"DELETE"}),onSuccess:()=>{X(e),e.invalidateQueries({queryKey:[T]})}})}function Z(e){const r=new URLSearchParams;return e.start_date&&r.set("start_date",e.start_date),e.end_date&&r.set("end_date",e.end_date),e.status&&r.set("status",e.status),e.model&&r.set("model",e.model),e.endpoint&&r.set("endpoint",e.endpoint),e.user_id&&r.set("user_id",e.user_id),r}function Pr(e,r,s){return v({queryKey:[Y,"list",e,r,s],queryFn:()=>{const a=Z(e);return a.set("skip",String(r*s)),a.set("limit",String(s)),i(`/v1/usage?${a.toString()}`)},placeholderData:Q,staleTime:1e4})}function Er(e){return v({queryKey:[Y,"count",e],queryFn:()=>i(`/v1/usage/count?${Z(e).toString()}`),placeholderData:Q,staleTime:1e4})}function Nr(e,r,s=!0){return v({queryKey:[Y,"summary",e,r],queryFn:()=>{const a=Z(e);return a.set("bucket",r),i(`/v1/usage/summary?${a.toString()}`)},enabled:s,placeholderData:Q,staleTime:3e4})}function Cr(e){return e==null?"0":new Intl.NumberFormat("en-US").format(e)}function Tr(e){if(e==null)return"$0.00";const r=e!==0&&Math.abs(e)<.01?4:2;return new Intl.NumberFormat("en-US",{style:"currency",currency:"USD",minimumFractionDigits:2,maximumFractionDigits:r}).format(e)}function _r(e){if(e==null)return"—";if(e>=1e6){const r=e/1e6;return`${Number.isInteger(r)?r:r.toFixed(1)}M`}if(e>=1e3){const r=Math.round(e/1e3);return r>=1e3?"1M":`${r}K`}return String(e)}const st=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];function Ar(e){if(!e)return"—";const r=/^(\d{4})-(\d{2})/.exec(e);if(!r)return e;const s=Number(r[2])-1;return s<0||s>11?r[1]:`${st[s]} ${r[1]}`}const nt=new Intl.NumberFormat("en-US",{style:"currency",currency:"USD",maximumFractionDigits:2});function Lr(e){return nt.format(e)}function Ir(e){return e>=1e6?`${(e/1e6).toFixed(1)}M`:e>=1e3?`${(e/1e3).toFixed(1)}k`:String(e)}function at(e){return`${(e*100).toFixed(1)}%`}function qr(e,r){return r===void 0||r===0?null:(e-r)/r}function Rr(e,r=Date.now()){if(!e)return"never";const s=new Date(e);if(Number.isNaN(s.getTime()))return e;const a=Math.round((r-s.getTime())/1e3),n=a<0,l=Math.abs(a),d=[["second",60],["minute",60],["hour",24],["day",30],["month",12],["year",Number.POSITIVE_INFINITY]];let u=l,y="second";for(const[p,g]of d){if(y=p,u0?"▲":e<0?"▼":"•";return t.jsxs("span",{className:"text-[var(--otari-muted)]",children:[r," ",at(Math.abs(e))," vs prev"]})}function it(e){return e instanceof E||e instanceof Error?e.message:"Something went wrong."}function ot({error:e}){return e?t.jsx("div",{role:"alert",className:"rounded-lg border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700",children:it(e)}):null}function lt({tone:e="info",children:r}){const s=e==="warning"?"border-amber-200 bg-amber-50 text-amber-800":"border-[var(--otari-brand)] bg-[var(--otari-brand-tint)] text-[var(--otari-brand-dark)]";return t.jsx("div",{className:`rounded-lg border px-4 py-3 text-sm ${s}`,children:r})}function Fr({title:e,description:r,action:s}){return t.jsxs("div",{className:"flex flex-col gap-3",children:[t.jsxs("div",{children:[t.jsx("h1",{className:"text-xl font-semibold text-[var(--otari-ink)]",children:e}),r?t.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:r}):null]}),s?t.jsx("div",{className:"flex flex-wrap gap-2",children:s}):null]})}function Mr({children:e,confirmLabel:r,onConfirm:s,isPending:a}){const[n,l]=o.useState(!1);return n?t.jsxs("span",{className:"inline-flex items-center gap-1",children:[t.jsx(P,{size:"sm",variant:"danger",isDisabled:a,onPress:s,children:r}),t.jsx(P,{size:"sm",variant:"ghost",isDisabled:a,onPress:()=>l(!1),children:"Cancel"})]}):t.jsx(P,{size:"sm",variant:"danger-soft",onPress:()=>l(!0),children:e})}const ct="rounded-lg border border-[var(--otari-line)] bg-[var(--otari-bg)] px-3 py-2 text-sm text-[var(--otari-ink)] focus:border-[var(--otari-brand)] focus:outline-none";function Kr({id:e,label:r,ariaLabel:s,value:a,onChange:n,options:l,children:d,disabled:u}){const y=o.useId(),h=e??(r?y:void 0),p=t.jsx("select",{id:h,"aria-label":r?void 0:s,value:a,disabled:u,onChange:g=>n(g.target.value),className:ct,children:l?l.map(g=>t.jsx("option",{value:g.value,children:g.label},g.value)):d});return r?t.jsxs("div",{className:"flex flex-col gap-1",children:[t.jsx("label",{htmlFor:h,className:"text-xs font-medium text-[var(--otari-muted)]",children:r}),p]}):p}function Ur({label:e,value:r,onChange:s,options:a,placeholder:n,maxVisible:l=50,allowsCustom:d=!1}){const u=m=>{var c;return((c=a.find(j=>j.value===m))==null?void 0:c.label)??m},[y,h]=o.useState(()=>u(r));o.useEffect(()=>{h(u(r))},[r]);const p=y.trim().toLowerCase(),g=a.filter(m=>!p||m.value.toLowerCase().includes(p)||m.label.toLowerCase().includes(p)).slice(0,l);return t.jsxs(I.Root,{allowsEmptyCollection:!0,allowsCustomValue:d,menuTrigger:"focus",inputValue:y,onInputChange:m=>{h(m),d?s(m.trim()):m.trim()===""&&s("")},onSelectionChange:m=>{m!=null&&s(String(m))},className:"flex flex-col gap-1",children:[t.jsx(oe,{className:"text-xs font-medium text-[var(--otari-muted)]",children:e}),t.jsxs(I.InputGroup,{children:[t.jsx(le,{placeholder:n,autoComplete:"off",onFocus:m=>m.currentTarget.select()}),t.jsx(I.Trigger,{})]}),t.jsx(I.Popover,{children:t.jsx(Te,{items:g,className:"max-h-72 overflow-auto",children:m=>t.jsx(_e,{id:m.value,textValue:m.label,children:m.label})})})]})}function ut(){var l;const e=He(),r=We(),[s,a]=o.useState(!1);return!(((l=e.data)==null?void 0:l.require_pricing)===!0&&e.data.default_pricing===!1)||s?null:t.jsx("div",{className:"shrink-0 px-6 pt-3",children:t.jsx(lt,{tone:"warning",children:t.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[t.jsxs("span",{children:["Requests are rejected until pricing is set (",t.jsx("code",{children:"require_pricing"})," is on). Enable default pricing to meter new models with public rates right away."]}),t.jsxs("span",{className:"flex items-center gap-2",children:[t.jsx(P,{size:"sm",variant:"primary",isDisabled:r.isPending,onPress:()=>r.mutate({default_pricing:!0}),children:r.isPending?"Enabling…":"Enable default pricing"}),t.jsx(P,{size:"sm",variant:"ghost",onPress:()=>a(!0),children:"Dismiss"})]})]})})})}function dt(){const{data:e}=Ve(),r=o.useRef(null);return e&&r.current===null&&(r.current=e.build),e!=null&&r.current!=null&&e.build!==r.current}function mt(){const e=dt(),[r,s]=o.useState(!1);return!e||r?null:t.jsx("div",{className:"pointer-events-none absolute inset-x-0 top-0 z-50 flex justify-center",children:t.jsxs("div",{role:"status",className:"pointer-events-auto mt-1.5 flex items-center gap-3 rounded-full border border-[var(--otari-brand)] bg-[var(--otari-brand-tint)] py-1.5 pr-1.5 pl-4 text-sm text-[var(--otari-brand-dark)] shadow-md",children:[t.jsxs("span",{children:[t.jsx("strong",{className:"font-semibold",children:"An update is available."})," Reloading keeps you signed in."]}),t.jsx(P,{size:"sm",variant:"primary",onPress:()=>window.location.reload(),children:"Update now"}),t.jsx(P,{size:"sm",variant:"ghost",onPress:()=>s(!0),children:"Later"})]})})}const he=200,xe=480,B=240,ft=60,ye="otari.dashboard.sidebarWidth",ve="otari.dashboard.sidebarCollapsed",ae=16,R=e=>Math.min(xe,Math.max(he,e));function ht(){if(typeof window>"u")return B;try{const e=window.localStorage.getItem(ye),r=e?Number.parseInt(e,10):Number.NaN;return Number.isNaN(r)?B:R(r)}catch{return B}}function xt(){if(typeof window>"u")return!1;try{return window.localStorage.getItem(ve)==="1"}catch{return!1}}const yt=[{key:"home"},{key:"observability",label:"Observability"},{key:"catalog",label:"Catalog"},{key:"access",label:"Access"},{key:"system"}],vt=[{to:"/",section:"home",label:"Overview",end:!0,icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("rect",{x:"3.5",y:"3.5",width:"7",height:"7",rx:"1.5",strokeLinejoin:"round"}),t.jsx("rect",{x:"13.5",y:"3.5",width:"7",height:"7",rx:"1.5",strokeLinejoin:"round"}),t.jsx("rect",{x:"3.5",y:"13.5",width:"7",height:"7",rx:"1.5",strokeLinejoin:"round"}),t.jsx("rect",{x:"13.5",y:"13.5",width:"7",height:"7",rx:"1.5",strokeLinejoin:"round"})]})},{to:"/activity",section:"observability",label:"Activity",icon:t.jsx("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:t.jsx("path",{d:"M3 12h4l2.5-6 4 12 2.5-6H21",strokeLinecap:"round",strokeLinejoin:"round"})})},{to:"/usage",section:"observability",label:"Usage",icon:t.jsx("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:t.jsx("path",{d:"M4 20V10M10 20V4M16 20v-7M22 20H2",strokeLinecap:"round",strokeLinejoin:"round"})})},{to:"/providers",section:"catalog",label:"Providers",icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("rect",{x:"3.5",y:"4.5",width:"17",height:"6",rx:"1.5",strokeLinejoin:"round"}),t.jsx("rect",{x:"3.5",y:"13.5",width:"17",height:"6",rx:"1.5",strokeLinejoin:"round"}),t.jsx("path",{d:"M7 7.5h.01M7 16.5h.01",strokeLinecap:"round",strokeLinejoin:"round"})]})},{to:"/users",section:"access",label:"Users",icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("circle",{cx:"9",cy:"8",r:"3.2",strokeLinejoin:"round"}),t.jsx("path",{d:"M3.5 19a5.5 5.5 0 0 1 11 0",strokeLinecap:"round",strokeLinejoin:"round"}),t.jsx("path",{d:"M16 5.2a3.2 3.2 0 0 1 0 5.6M17.5 19a5.5 5.5 0 0 0-3-4.9",strokeLinecap:"round",strokeLinejoin:"round"})]})},{to:"/keys",section:"access",label:"API keys",icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("circle",{cx:"7.5",cy:"15.5",r:"3.5"}),t.jsx("path",{d:"M10 13l7-7M14 5l3 3M16.5 7.5l2-2",strokeLinecap:"round",strokeLinejoin:"round"})]})},{to:"/budgets",section:"access",label:"Budgets",icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("path",{d:"M3 7.5A1.5 1.5 0 0 1 4.5 6H18a1.5 1.5 0 0 1 1.5 1.5V9",strokeLinejoin:"round"}),t.jsx("rect",{x:"3",y:"7.5",width:"18",height:"12",rx:"1.5",strokeLinejoin:"round"}),t.jsx("path",{d:"M16 13.5h.01",strokeLinecap:"round",strokeLinejoin:"round"}),t.jsx("path",{d:"M21 12v3h-3.5a1.5 1.5 0 0 1 0-3H21z",strokeLinejoin:"round"})]})},{to:"/models",section:"catalog",label:"Models",icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("path",{d:"M12 3l8 4.5v9L12 21l-8-4.5v-9L12 3z",strokeLinejoin:"round"}),t.jsx("path",{d:"M12 12l8-4.5M12 12v9M12 12L4 7.5",strokeLinejoin:"round"})]})},{to:"/aliases",section:"catalog",label:"Aliases",icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("path",{d:"M20.6 13.4L13.4 20.6a2 2 0 0 1-2.8 0l-7-7A2 2 0 0 1 3 12.2V5a2 2 0 0 1 2-2h7.2a2 2 0 0 1 1.4.6l7 7a2 2 0 0 1 0 2.8z",strokeLinejoin:"round"}),t.jsx("circle",{cx:"7.5",cy:"7.5",r:"1.5"})]})},{to:"/tools",section:"system",label:"Tools & Guardrails",icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("path",{d:"M14.7 6.3a4 4 0 0 1 5 5l-8.4 8.4a2 2 0 0 1-2.8 0l-2.2-2.2a2 2 0 0 1 0-2.8z",strokeLinejoin:"round"}),t.jsx("path",{d:"M12 9 5 16",strokeLinecap:"round"})]})},{to:"/settings",section:"system",label:"Settings",icon:t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-5 w-5 shrink-0",children:[t.jsx("circle",{cx:"12",cy:"12",r:"3"}),t.jsx("path",{d:"M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z",strokeLinejoin:"round"})]})}];function gt(){const{logout:e}=V(),r=o.useRef(null),[s,a]=o.useState(ht),[n,l]=o.useState(xt),[d,u]=o.useState(!1);o.useEffect(()=>{const c=window.setTimeout(()=>{try{window.localStorage.setItem(ye,String(Math.round(s)))}catch{}},200);return()=>window.clearTimeout(c)},[s]),o.useEffect(()=>{try{window.localStorage.setItem(ve,n?"1":"0")}catch{}},[n]);const y=o.useCallback(c=>{c.preventDefault(),c.currentTarget.setPointerCapture(c.pointerId),u(!0)},[]),h=o.useCallback(c=>{var A;if(!c.currentTarget.hasPointerCapture(c.pointerId))return;const j=((A=r.current)==null?void 0:A.getBoundingClientRect().left)??0;a(R(c.clientX-j))},[]),p=o.useCallback(c=>{c.currentTarget.hasPointerCapture(c.pointerId)&&c.currentTarget.releasePointerCapture(c.pointerId),u(!1)},[]),g=o.useCallback(c=>{c.key==="ArrowLeft"?(c.preventDefault(),a(j=>R(j-ae))):c.key==="ArrowRight"&&(c.preventDefault(),a(j=>R(j+ae)))},[]),m=n?ft:s;return t.jsxs("div",{className:C("relative flex h-full flex-col overflow-hidden",d&&"cursor-col-resize select-none"),children:[t.jsxs("header",{className:"flex shrink-0 items-center justify-between border-b border-[var(--otari-line)] bg-[var(--otari-surface)] px-5 py-3",children:[t.jsxs("div",{className:"flex items-center gap-2.5",children:[t.jsx("img",{src:"/favicon.svg",alt:"",className:"h-7 w-7 shrink-0"}),t.jsx("span",{className:"text-base font-semibold text-[var(--otari-ink)]",children:"Otari"})]}),t.jsx(P,{size:"sm",variant:"outline",onPress:e,"aria-label":"Sign out",children:"Sign out"})]}),t.jsx(mt,{}),t.jsx(Be,{}),t.jsx(ut,{}),t.jsxs("div",{className:"flex min-h-0 flex-1",children:[t.jsxs("aside",{ref:r,style:{width:m},className:C("relative flex shrink-0 flex-col border-r border-[var(--otari-line)] bg-[var(--otari-surface)]",!d&&"transition-[width] duration-150"),children:[t.jsx("button",{type:"button",onClick:()=>l(c=>!c),"aria-label":n?"Expand sidebar":"Collapse sidebar","aria-pressed":n,title:n?"Expand sidebar":"Collapse sidebar",className:"absolute -right-3 top-4 z-30 flex h-6 w-6 items-center justify-center rounded-full border border-[var(--otari-line)] bg-[var(--otari-surface)] text-[var(--otari-muted)] shadow-sm transition-colors hover:border-[var(--otari-brand)] hover:text-[var(--otari-brand-dark)]",children:t.jsx("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",className:C("h-3.5 w-3.5 transition-transform",n&&"rotate-180"),children:t.jsx("path",{d:"M15 6l-6 6 6 6",strokeLinecap:"round",strokeLinejoin:"round"})})}),t.jsx("nav",{className:C("flex flex-col py-4",n?"px-2":"px-3"),children:yt.map((c,j)=>{const A=vt.filter(k=>k.section===c.key);return A.length===0?null:t.jsxs("div",{className:j>0?"mt-4":void 0,children:[!n&&c.label?t.jsx("div",{className:"px-3 pb-1 text-[11px] font-semibold tracking-wider text-[var(--otari-muted)] uppercase",children:c.label}):null,j>0&&(n||!c.label)?t.jsx("div",{className:"mx-1 mb-2 border-t border-[var(--otari-line)]"}):null,t.jsx("div",{className:"flex flex-col gap-1",children:A.map(k=>t.jsxs(ie,{to:k.to,end:k.end,"aria-label":n?k.label:void 0,title:n?k.label:void 0,className:({isActive:pe})=>C("flex items-center rounded-lg py-2 text-sm font-medium transition-colors",n?"justify-center px-0":"gap-3 px-3",pe?"bg-[var(--otari-brand-tint)] text-[var(--otari-brand-dark)]":"text-[var(--otari-muted)] hover:bg-[var(--otari-bg)] hover:text-[var(--otari-ink)]"),children:[k.icon,n?null:k.label]},k.to))})]},c.key)})}),t.jsxs("a",{href:"https://otari.ai",target:"_blank",rel:"noreferrer",title:"otari.ai — the hosted Otari gateway",className:C("mt-auto mb-3 flex items-center rounded-lg py-2 text-xs font-medium text-[var(--otari-muted)] transition-colors hover:bg-[var(--otari-bg)] hover:text-[var(--otari-brand-dark)]",n?"mx-2 justify-center px-0":"mx-3 gap-2 px-3"),children:[t.jsx("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"h-4 w-4 shrink-0",children:t.jsx("path",{d:"M18 10h-1.26A8 8 0 1 0 9 20h9a5 5 0 0 0 0-10z",strokeLinejoin:"round"})}),n?null:t.jsxs("span",{className:"flex-1",children:["otari.ai ",t.jsx("span",{"aria-hidden":!0,children:"↗"})]})]}),n?null:t.jsx("div",{role:"separator","aria-orientation":"vertical","aria-label":"Resize sidebar","aria-valuenow":Math.round(s),"aria-valuemin":he,"aria-valuemax":xe,tabIndex:0,onPointerDown:y,onPointerMove:h,onPointerUp:p,onKeyDown:g,className:C("absolute top-0 right-0 z-10 h-full w-1.5 cursor-col-resize touch-none transition-colors","hover:bg-[var(--otari-brand)] focus-visible:bg-[var(--otari-brand)] focus:outline-none",d?"bg-[var(--otari-brand)]":"bg-transparent")})]}),t.jsx("main",{className:"flex-1 overflow-y-auto",children:t.jsx("div",{className:"mx-auto flex max-w-[1800px] flex-col gap-6 px-6 py-6",children:t.jsx(Pe,{})})})]})]})}function pt(){const{login:e}=V(),[r,s]=o.useState(""),[a,n]=o.useState(null),[l,d]=o.useState(!1),u=async()=>{const y=r.trim();if(!(!y||l)){d(!0),n(null);try{await Oe(y)?e():n(new Error("Invalid master key."))}catch(h){n(h)}finally{d(!1)}}};return t.jsx("div",{className:"flex min-h-full items-center justify-center p-6",children:t.jsx(L,{className:"w-full max-w-md",children:t.jsxs(L.Content,{className:"flex flex-col gap-5 p-7",children:[t.jsxs("div",{className:"flex flex-col items-center gap-3 text-center",children:[t.jsx("img",{src:"/favicon.svg",alt:"Otari",className:"h-12 w-12"}),t.jsxs("div",{children:[t.jsx("h1",{className:"text-lg font-semibold text-[var(--otari-ink)]",children:"Otari Dashboard"}),t.jsx("p",{className:"mt-1 text-sm text-[var(--otari-muted)]",children:"Sign in with your master key to browse models, set pricing, and manage settings."})]})]}),t.jsxs("form",{className:"flex flex-col gap-4",onSubmit:y=>{y.preventDefault(),u()},children:[t.jsxs(Ae,{value:r,onChange:y=>{s(y),a&&n(null)},type:"password",isRequired:!0,className:"flex flex-col gap-1",children:[t.jsx(oe,{className:"text-sm font-medium text-[var(--otari-ink)]",children:"Master key"}),t.jsx(le,{placeholder:"otari-mk-… or your master key",autoFocus:!0,autoComplete:"off"})]}),t.jsxs("details",{className:"text-xs text-[var(--otari-muted)]",children:[t.jsx("summary",{className:"cursor-pointer font-medium text-[var(--otari-brand-dark)]",children:"First run? Where to find your key"}),t.jsxs("p",{className:"mt-2 leading-relaxed",children:["If you did not set ",t.jsx("code",{children:"OTARI_MASTER_KEY"}),", Otari generated one and printed it to the server logs on startup. Look for the line ",t.jsx("code",{children:"Your master key:"})," (for example, run"," ",t.jsx("code",{children:"docker logs "}),") and paste it above."]})]}),t.jsx(ot,{error:a}),t.jsx(P,{type:"submit",variant:"primary",fullWidth:!0,isDisabled:!r.trim()||l,children:l?"Signing in…":"Sign in"})]}),t.jsx("p",{className:"text-center text-xs text-[var(--otari-muted)]",children:"The key is sent once to this gateway and exchanged for a session cookie; it is never stored in the browser."}),t.jsx("div",{className:"border-t border-[var(--otari-line)] pt-4 text-center",children:t.jsx(Le,{href:"/welcome",className:"text-sm font-medium text-[var(--otari-brand-dark)]",children:"New to Otari? Open the welcome guide"})})]})})})}const bt=o.lazy(async()=>({default:(await S(async()=>{const{ActivityPage:e}=await import("./ActivityPage-dbjTjmS5.js");return{ActivityPage:e}},__vite__mapDeps([0,1,2,3,4]))).ActivityPage})),jt=o.lazy(async()=>({default:(await S(async()=>{const{AliasesPage:e}=await import("./AliasesPage-DqjEr6cA.js");return{AliasesPage:e}},__vite__mapDeps([5,1,2,6,4,3]))).AliasesPage})),wt=o.lazy(async()=>({default:(await S(async()=>{const{BudgetsPage:e}=await import("./BudgetsPage-DK4vAOyb.js");return{BudgetsPage:e}},__vite__mapDeps([7,1,2,6,4,3]))).BudgetsPage})),St=o.lazy(async()=>({default:(await S(async()=>{const{KeysPage:e}=await import("./KeysPage-DkXRnk8b.js");return{KeysPage:e}},__vite__mapDeps([8,1,2,6,4,9,3]))).KeysPage})),kt=o.lazy(async()=>({default:(await S(async()=>{const{ModelsPage:e}=await import("./ModelsPage-C-ZlmFwf.js");return{ModelsPage:e}},__vite__mapDeps([10,1,2,3,4]))).ModelsPage})),Pt=o.lazy(async()=>({default:(await S(async()=>{const{OverviewIndex:e}=await import("./OverviewPage-Cb1DW9ZC.js");return{OverviewIndex:e}},__vite__mapDeps([11,1,2,12,13,4,3]))).OverviewIndex})),Et=o.lazy(async()=>({default:(await S(async()=>{const{ProvidersPage:e}=await import("./ProvidersPage-CLe2cN4-.js");return{ProvidersPage:e}},__vite__mapDeps([14,1,2,6,4,3]))).ProvidersPage})),Nt=o.lazy(async()=>({default:(await S(async()=>{const{SettingsPage:e}=await import("./SettingsPage-BdorKXf4.js");return{SettingsPage:e}},__vite__mapDeps([15,1,2,4]))).SettingsPage})),Ct=o.lazy(async()=>({default:(await S(async()=>{const{ToolsGuardrailsPage:e}=await import("./ToolsGuardrailsPage-D8Qsr-tI.js");return{ToolsGuardrailsPage:e}},__vite__mapDeps([16,1,2,4]))).ToolsGuardrailsPage})),Tt=o.lazy(async()=>({default:(await S(async()=>{const{UsagePage:e}=await import("./UsagePage-CRzEneXv.js");return{UsagePage:e}},__vite__mapDeps([17,1,2,12,13,4,3]))).UsagePage})),_t=o.lazy(async()=>({default:(await S(async()=>{const{UsersPage:e}=await import("./UsersPage-zP5EVG6k.js");return{UsersPage:e}},__vite__mapDeps([18,1,2,6,4,9,3]))).UsersPage}));function w(e){return t.jsx(o.Suspense,{fallback:t.jsx("div",{role:"status",children:"Loading page…"}),children:e})}function At(){const{isAuthenticated:e}=V();return e?t.jsx(Ee,{children:t.jsx(Ne,{children:t.jsxs(b,{element:t.jsx(gt,{}),children:[t.jsx(b,{index:!0,element:w(t.jsx(Pt,{}))}),t.jsx(b,{path:"providers",element:w(t.jsx(Et,{}))}),t.jsx(b,{path:"keys",element:w(t.jsx(St,{}))}),t.jsx(b,{path:"users",element:w(t.jsx(_t,{}))}),t.jsx(b,{path:"budgets",element:w(t.jsx(wt,{}))}),t.jsx(b,{path:"activity",element:w(t.jsx(bt,{}))}),t.jsx(b,{path:"usage",element:w(t.jsx(Tt,{}))}),t.jsx(b,{path:"models",element:w(t.jsx(kt,{}))}),t.jsx(b,{path:"aliases",element:w(t.jsx(jt,{}))}),t.jsx(b,{path:"tools",element:w(t.jsx(Ct,{}))}),t.jsx(b,{path:"settings",element:w(t.jsx(Nt,{}))}),t.jsx(b,{path:"*",element:t.jsx(Ce,{to:"/",replace:!0})})]})})}):t.jsx(pt,{})}function Lt({children:e}){const[r]=o.useState(()=>new we({defaultOptions:{queries:{refetchOnWindowFocus:!1,retry:(s,a)=>a instanceof E&&(a.status===401||a.status===403)?!1:s<2}}}));return t.jsx(Se,{client:r,children:t.jsx(Me,{children:e})})}const ge=document.getElementById("root");if(!ge)throw new Error("Root element #root not found");Ie.createRoot(ge).render(t.jsx(o.StrictMode,{children:t.jsx(Lt,{children:t.jsx(At,{})})}));export{Jt as $,Ar as A,He as B,Mr as C,Tr as D,ot as E,Kr as F,ir as G,or as H,lt as I,Mt as J,Bt as K,qr as L,Lr as M,Dr as N,at as O,Fr as P,Rr as Q,zt as R,Or as S,Ht as T,Gt as U,We as V,Vt as W,$t as X,Qt as Y,Ut as Z,Kt as _,Pr as a,lr as a0,cr as a1,ur as a2,tr as a3,Wt as a4,rr as a5,sr as a6,nr as a7,Ir as a8,kr as a9,wr as aa,Er as b,Nr as c,Ur as d,Ft as e,Xt as f,er as g,it as h,Zt as i,yr as j,gr as k,pr as l,br as m,Sr as n,vr as o,dr as p,fr as q,hr as r,xr as s,mr as t,jr as u,Dt as v,ar as w,Yt as x,_r as y,Cr as z}; diff --git a/src/gateway/static/dashboard/index.html b/src/gateway/static/dashboard/index.html index 630b0c06..7784d273 100644 --- a/src/gateway/static/dashboard/index.html +++ b/src/gateway/static/dashboard/index.html @@ -6,7 +6,7 @@ Otari Dashboard - + diff --git a/web/src/pages/BudgetsPage.test.tsx b/web/src/pages/BudgetsPage.test.tsx index a2ea516f..e4ab8429 100644 --- a/web/src/pages/BudgetsPage.test.tsx +++ b/web/src/pages/BudgetsPage.test.tsx @@ -271,7 +271,7 @@ describe("BudgetsPage", () => { ).toBe(false); }); - it("does not submit a custom period that rounds down to zero days", async () => { + it("blocks a custom period below one whole day instead of rounding it to zero", async () => { const fetchMock = mockApi({ budgets: [] }); const user = userEvent.setup(); renderPage(); @@ -280,16 +280,12 @@ describe("BudgetsPage", () => { await user.click(screen.getByRole("button", { name: "Custom" })); await user.click(screen.getByLabelText("Every N days")); await user.paste("0.1"); - await user.click(screen.getByRole("button", { name: "Create budget" })); - const post = await vi.waitFor(() => { - const call = fetchMock.mock.calls.find( - ([url, init]) => String(url).includes("/v1/budgets") && (init?.method ?? "") === "POST", - ); - if (!call) throw new Error("no budget POST"); - return call; - }); - expect(JSON.parse(String(post[1]?.body))).toMatchObject({ budget_duration_sec: null }); + expect(await screen.findByText("Enter a whole number of days.")).toBeInTheDocument(); + expect(screen.getByRole("button", { name: "Create budget" })).toBeDisabled(); + expect( + fetchMock.mock.calls.some(([u, init]) => String(u).includes("/v1/budgets") && (init?.method ?? "") === "POST"), + ).toBe(false); }); it("rejects a fractional custom period instead of rounding it up", async () => { @@ -302,18 +298,33 @@ describe("BudgetsPage", () => { await user.click(screen.getByLabelText("Every N days")); await user.paste("1.5"); - // 1.5 is flagged and held unsaved, never silently rounded to 2 days. + // 1.5 is flagged and blocks submit, never silently rounded to 2 days. expect(await screen.findByText("Enter a whole number of days.")).toBeInTheDocument(); - await user.click(screen.getByRole("button", { name: "Create budget" })); + expect(screen.getByRole("button", { name: "Create budget" })).toBeDisabled(); + expect( + fetchMock.mock.calls.some(([u, init]) => String(u).includes("/v1/budgets") && (init?.method ?? "") === "POST"), + ).toBe(false); + }); - const post = await vi.waitFor(() => { - const call = fetchMock.mock.calls.find( - ([url, init]) => String(url).includes("/v1/budgets") && (init?.method ?? "") === "POST", - ); - if (!call) throw new Error("no budget POST"); - return call; - }); - expect(JSON.parse(String(post[1]?.body))).toMatchObject({ budget_duration_sec: null }); + it("keeps a fractional edit visible with an error and blocks save (does not wipe the field)", async () => { + // 14 days is a custom period (not a preset), so Edit opens with the field + // seeded to "14"; making it fractional exercises the committed-value path the + // paste-into-empty tests miss. + mockApi({ budgets: [budget({ budget_duration_sec: 1_209_600 })] }); + const user = userEvent.setup(); + renderPage(); + + await user.click(await screen.findByText("11111111")); + const field = await screen.findByLabelText("Every N days"); + expect(field).toHaveValue("14"); + + await user.type(field, ".5"); + + // The invalid entry persists with an error instead of being wiped, and Save is + // blocked so it cannot clear the committed period to "no reset". + expect(field).toHaveValue("14.5"); + expect(screen.getByText("Enter a whole number of days.")).toBeInTheDocument(); + expect(screen.getByRole("button", { name: "Save changes" })).toBeDisabled(); }); it("creates an unlimited budget when the limit is left blank", async () => { diff --git a/web/src/pages/BudgetsPage.tsx b/web/src/pages/BudgetsPage.tsx index bb925ade..21296fd9 100644 --- a/web/src/pages/BudgetsPage.tsx +++ b/web/src/pages/BudgetsPage.tsx @@ -63,19 +63,34 @@ function parseLimit(raw: string): { value: number | null; valid: boolean } { return { value: n, valid: true }; } -// seconds shown as a whole number of days when it divides evenly, so the custom -// field speaks the same unit an operator thinks in. -function PeriodPicker({ value, onChange }: { value: number | null; onChange: (seconds: number | null) => void }) { +// Whole-day string for a duration, or "" when it is not a whole number of days, +// so the custom field speaks the same unit an operator thinks in. +function daysString(seconds: number | null): string { + return seconds !== null && seconds % DAY === 0 ? String(seconds / DAY) : ""; +} + +function PeriodPicker({ + value, + onChange, + onInvalidChange, +}: { + value: number | null; + onChange: (seconds: number | null) => void; + // Reports whether the custom field currently holds an invalid entry, so the + // form can block Save (an invalid entry emits null, which would otherwise + // clear the committed period on save). + onInvalidChange?: (invalid: boolean) => void; +}) { const isPreset = PERIOD_PRESETS.some((p) => p.seconds === value); const [custom, setCustom] = useState(!isPreset); - const committedDays = value !== null && value % DAY === 0 ? String(value / DAY) : ""; - // A local draft so an in-progress, not-yet-valid entry (e.g. "1.5") stays on - // screen to be flagged, rather than being coerced. Reseed it when the committed - // value changes from outside (a preset click, or editing a different budget). - const [draft, setDraft] = useState(committedDays); - useEffect(() => { - setDraft(committedDays); - }, [committedDays]); + // The custom field's own draft, so an in-progress, not-yet-valid entry (e.g. + // "1.5") stays on screen to be flagged rather than being coerced. It is seeded + // on mount and reset only by an explicit action here (a preset click), never + // from `value`: the only thing that changes `value` in place is this component's + // own onChange, so reseeding from it would wipe the invalid entry on the very + // null we emit for it, before the operator can read the error. Editing a + // different budget remounts the form (it is keyed), reseeding from the new value. + const [draft, setDraft] = useState(() => daysString(value)); const trimmedDays = draft.trim(); const daysValue = Number(trimmedDays); @@ -84,6 +99,11 @@ function PeriodPicker({ value, onChange }: { value: number | null; onChange: (se // 1.5 never becomes 2. isSafeInteger also rules out an overflowing day count. const invalidDays = trimmedDays !== "" && (!Number.isSafeInteger(daysValue) || daysValue <= 0); + // Surface validity to the form so Save is gated on it (like the limit field). + useEffect(() => { + onInvalidChange?.(invalidDays); + }, [invalidDays, onInvalidChange]); + return (
Reset period @@ -95,6 +115,9 @@ function PeriodPicker({ value, onChange }: { value: number | null; onChange: (se variant={!custom && value === preset.seconds ? "primary" : "outline"} onPress={() => { setCustom(false); + // Keep the (hidden) custom draft in step, so reopening Custom shows + // the preset's day count rather than a stale earlier entry. + setDraft(daysString(preset.seconds)); onChange(preset.seconds); }} > @@ -162,12 +185,14 @@ function BudgetForm({ const [name, setName] = useState(initial.name ?? ""); const [limit, setLimit] = useState(initial.max_budget === null ? "" : String(initial.max_budget)); const [durationSec, setDurationSec] = useState(initial.budget_duration_sec); + const [periodInvalid, setPeriodInvalid] = useState(false); const [userIds, setUserIds] = useState([]); const parsed = parseLimit(limit); + const canSubmit = !isPending && parsed.valid && !periodInvalid; const submit = () => { - if (isPending || !parsed.valid) return; + if (!canSubmit) return; // Send name as null (not "") when blank so it clears to unnamed on the wire. onSubmit({ name: name.trim() || null, max_budget: parsed.value, budget_duration_sec: durationSec }, userIds); }; @@ -198,7 +223,7 @@ function BudgetForm({ ) } /> - + {assignUsers ? ( ) : null}
-