ldrouter 1.19.0 → 1.19.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,21 @@ All notable changes to this project are documented here. The format follows
4
4
  [Keep a Changelog](https://keepachangelog.com/) and the project adheres to
5
5
  [Semantic Versioning](https://semver.org/).
6
6
 
7
+ ## [1.19.2] - 2026-10-22
8
+
9
+ ### Fixed
10
+
11
+ - Request details now stay inside a scrollable, width-constrained dialog so long curl and JSON payloads no longer overflow the admin page.
12
+ - Request and attempt detail from completed UTC days is deleted automatically at startup and once per day; daily statistics and today's request history are preserved.
13
+
14
+ ## [1.19.1] - 2026-10-12
15
+
16
+ ### Fixed
17
+
18
+ - **Streamed requests to OpenAI-compatible providers logged `Tokens 0`.** Such providers omit `usage` from a streamed answer unless the caller opts in with `stream_options.include_usage`, and the gateway dropped that field when converting the client body to the canonical request — so the upstream was never asked and every streamed request to those providers persisted 0 tokens. Upstream resale platforms read that as a zero-usage request and flag the key (`zero_usage_rewritten`). The gateway now always sends `stream_options: { include_usage: true }` on streamed OpenAI-compatible upstream calls, so request logs, statistics and the dashboard carry real token counts. Anthropic-compatible providers are unaffected: `/v1/messages` reports usage unconditionally. Non-streaming calls already carried usage in the response body.
19
+
20
+ - **Statistics failed with `Statistics ranges overlapping compacted history must include complete UTC days.`** A day was treated as compacted history as soon as it had a row in `daily_model_stats` — but that aggregate is written for every logged request, so every day with traffic has one. Any range that clipped such a day was refused with 400, and because the preset windows started at "now minus N days" they always clipped their own first day: the Statistics page showed only "Failed to load statistics" for Today, 7 days and 30 days alike once a day's raw detail had been pruned by retention or left behind by a compact restore. A day is now served from its aggregate only when its raw detail is genuinely gone (it holds fewer raw rows than it logged), and the preset windows are aligned to UTC day boundaries so the day they start on is whole rather than clipped.
21
+
7
22
  ## [1.19.0] - 2026-10-12
8
23
 
9
24
  ### Added
@@ -22,6 +22,7 @@ import { registerGatewayRoutes } from './routes/gateway.js';
22
22
  import { registerHealthRoutes } from './routes/health.js';
23
23
  import { registerAdminIpGate } from './security/admin-ip-gate.js';
24
24
  import { metricsRegistry } from './metrics/registry.js';
25
+ import { runDailyRequestHistoryCleanup } from './maintenance/retention.js';
25
26
  import { fatal, lifecycle, formatError, getDebugFlags, errorLine, requestLogFields, requestLogLevel, requestLogMessage } from './logging/debug.js';
26
27
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
27
28
  export async function buildApp(opts = {}) {
@@ -180,6 +181,30 @@ export async function buildApp(opts = {}) {
180
181
  else {
181
182
  log.info({ dbFile: cfg.dbFile }, 'LateDev Router ready (first-run setup required)');
182
183
  }
184
+ let lastCleanupDay = '';
185
+ const dailyCleanup = setInterval(() => {
186
+ const day = new Date().toISOString().slice(0, 10);
187
+ if (day === lastCleanupDay)
188
+ return;
189
+ try {
190
+ const result = runDailyRequestHistoryCleanup();
191
+ lastCleanupDay = day;
192
+ log.info({ ...result }, 'daily request history cleanup completed');
193
+ }
194
+ catch (error) {
195
+ log.warn({ err: String(error) }, 'daily request history cleanup failed');
196
+ }
197
+ }, 60_000);
198
+ dailyCleanup.unref?.();
199
+ app.addHook('onClose', async () => clearInterval(dailyCleanup));
200
+ try {
201
+ const result = runDailyRequestHistoryCleanup();
202
+ lastCleanupDay = new Date().toISOString().slice(0, 10);
203
+ log.info({ ...result }, 'daily request history cleanup completed');
204
+ }
205
+ catch (error) {
206
+ log.warn({ err: String(error) }, 'daily request history cleanup failed');
207
+ }
183
208
  });
184
209
  return app;
185
210
  }
@@ -34,6 +34,30 @@ export function runRetentionCleanup(now = new Date(), opts = {}) {
34
34
  }
35
35
  return { deletedRequests, deletedAttempts, dryRun: false, cutoff };
36
36
  }
37
+ /** Delete complete UTC days of request detail while preserving daily aggregates. */
38
+ export function runDailyRequestHistoryCleanup(now = new Date()) {
39
+ const beforeDay = now.toISOString().slice(0, 10);
40
+ const db = getDb();
41
+ let deletedRequests = 0;
42
+ let deletedAttempts = 0;
43
+ while (true) {
44
+ const rows = db
45
+ .select({ id: schema.requests.id })
46
+ .from(schema.requests)
47
+ .where(sql `substr(${schema.requests.createdAt}, 1, 10) < ${beforeDay}`)
48
+ .limit(BATCH_SIZE)
49
+ .all();
50
+ if (rows.length === 0)
51
+ break;
52
+ const ids = rows.map((r) => r.id);
53
+ const idList = sql.join(ids.map((id) => sql `${id}`), sql `, `);
54
+ deletedAttempts += db.delete(schema.requestAttempts).where(sql `${schema.requestAttempts.requestId} IN (${idList})`).run().changes ?? 0;
55
+ deletedRequests += db.delete(schema.requests).where(sql `${schema.requests.id} IN (${idList})`).run().changes ?? 0;
56
+ if (rows.length < BATCH_SIZE)
57
+ break;
58
+ }
59
+ return { deletedRequests, deletedAttempts, beforeDay };
60
+ }
37
61
  export function applyDbSizeGuard(dataDir) {
38
62
  const s = getSettings();
39
63
  const dbFile = path.join(dataDir, 'data.sqlite');
@@ -78,6 +78,7 @@ export function openAIToCanonical(req) {
78
78
  maxOutputTokens: req.max_tokens,
79
79
  stop: Array.isArray(req.stop) ? req.stop : req.stop ? [req.stop] : undefined,
80
80
  stream: Boolean(req.stream),
81
+ streamIncludeUsage: Boolean(req.stream_options?.include_usage),
81
82
  responseFormat,
82
83
  reasoning: req.reasoning_effort ? { effort: req.reasoning_effort } : undefined,
83
84
  };
@@ -88,6 +89,11 @@ export function canonicalToOpenAIRequest(req, targetModel) {
88
89
  stream: req.stream,
89
90
  messages: [],
90
91
  };
92
+ // OpenAI-compatible upstreams omit `usage` from a streamed answer unless the
93
+ // request opts in. Without this the gateway persisted 0 tokens for every
94
+ // streamed request to such a provider (live: "Tokens 0" on the Requests page).
95
+ if (req.stream)
96
+ out.stream_options = { include_usage: true };
91
97
  if (req.system)
92
98
  out.messages.push({ role: 'system', content: req.system });
93
99
  for (const m of req.messages) {
@@ -4,19 +4,29 @@ import { getDb, schema } from '../../db/index.js';
4
4
  import { requireAdminAuth } from '../../auth/middleware.js';
5
5
  import { GatewayError } from '../../errors.js';
6
6
  import { toSummary, loadSummaryMaps } from './requests.js';
7
+ /**
8
+ * Midnight UTC, `offsetDays` from the day containing `now`.
9
+ *
10
+ * Preset windows are day-aligned on purpose. A rolling window always clips its first day, and a
11
+ * clipped day whose raw rows were pruned cannot be reconstructed from the day-granular aggregate —
12
+ * so a compacted install answered 400 for every preset the UI can send. Aligning the window makes
13
+ * the first day whole and leaves only today partial, which is never served from an aggregate.
14
+ */
15
+ function utcDayStart(now, offsetDays) {
16
+ return new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate() + offsetDays));
17
+ }
7
18
  const PRESETS = {
8
19
  today: () => {
9
20
  const now = new Date();
10
- const from = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()));
11
- return { from, to: now, bucket: 'hour' };
21
+ return { from: utcDayStart(now, 0), to: now, bucket: 'hour' };
12
22
  },
13
23
  '7d': () => {
14
24
  const now = new Date();
15
- return { from: new Date(now.getTime() - 7 * 24 * 3600 * 1000), to: now, bucket: 'day' };
25
+ return { from: utcDayStart(now, -6), to: now, bucket: 'day' };
16
26
  },
17
27
  '30d': () => {
18
28
  const now = new Date();
19
- return { from: new Date(now.getTime() - 30 * 24 * 3600 * 1000), to: now, bucket: 'day' };
29
+ return { from: utcDayStart(now, -29), to: now, bucket: 'day' };
20
30
  },
21
31
  };
22
32
  /**
@@ -50,10 +60,43 @@ function cacheHitRateFor(db, conds) {
50
60
  function rangeFromQuery(q) {
51
61
  if (q.preset && PRESETS[q.preset])
52
62
  return PRESETS[q.preset]();
53
- const from = q.from ? new Date(q.from) : new Date(Date.now() - 7 * 24 * 3600 * 1000);
54
- const to = q.to ? new Date(q.to) : new Date();
63
+ const now = new Date();
64
+ const from = q.from ? new Date(q.from) : utcDayStart(now, -6);
65
+ const to = q.to ? new Date(q.to) : now;
55
66
  return { from, to, bucket: q.bucket === 'hour' ? 'hour' : 'day' };
56
67
  }
68
+ /**
69
+ * UTC days whose raw request detail is gone and that therefore must be answered from the
70
+ * day-granular aggregate.
71
+ *
72
+ * Having a `daily_model_stats` row proves nothing: the aggregate is written for EVERY logged
73
+ * request, so every day with traffic has one, and treating that as "compacted" made every
74
+ * rolling preset (whose window always clips its first day) answer 400. Only the raw log
75
+ * separates the states, and only a day holding FEWER raw rows than it logged needs its
76
+ * aggregate — which is exactly what retention (cutoff mid-day) and a compact export/restore
77
+ * leave behind.
78
+ *
79
+ * Counted over whole UTC days, never the requested window: a clipped first day still has all
80
+ * of its raw rows, and comparing a window-scoped count against a whole-day aggregate would
81
+ * report every such day as pruned. `created_at` is indexed, so this is one grouped range scan.
82
+ */
83
+ function aggregateRequiredDays(db, aggregateRows) {
84
+ const loggedByDay = new Map();
85
+ for (const r of aggregateRows)
86
+ loggedByDay.set(r.day, (loggedByDay.get(r.day) ?? 0) + r.requests);
87
+ if (loggedByDay.size === 0)
88
+ return [];
89
+ // ISO-8601 UTC dates sort lexicographically, so min/max bound the whole-day scan.
90
+ const days = [...loggedByDay.keys()].sort();
91
+ const rawCounts = db
92
+ .select({ day: sql `substr(created_at,1,10)`, c: sql `COUNT(*)` })
93
+ .from(schema.requests)
94
+ .where(and(gte(schema.requests.createdAt, `${days[0]}T00:00:00.000Z`), lte(schema.requests.createdAt, `${days[days.length - 1]}T23:59:59.999Z`)))
95
+ .groupBy(sql `substr(created_at,1,10)`)
96
+ .all();
97
+ const rawByDay = new Map(rawCounts.map((r) => [r.day, Number(r.c)]));
98
+ return [...loggedByDay].filter(([day, logged]) => (rawByDay.get(day) ?? 0) < logged).map(([day]) => day);
99
+ }
57
100
  export async function registerStatsRoutes(app) {
58
101
  app.addHook('preHandler', requireAdminAuth);
59
102
  app.get('/api/admin/stats', async (req) => {
@@ -65,9 +108,12 @@ export async function registerStatsRoutes(app) {
65
108
  const conds = [gte(schema.requests.createdAt, fromIso), lte(schema.requests.createdAt, toIso)];
66
109
  const utcToday = new Date().toISOString().slice(0, 10);
67
110
  const aggregateRows = db.select().from(schema.dailyModelStats).where(and(gte(schema.dailyModelStats.day, fromIso.slice(0, 10)), lte(schema.dailyModelStats.day, toIso.slice(0, 10)))).all();
68
- const overlappingAggregateDays = [...new Set(aggregateRows.map((r) => r.day))].filter((day) => day < utcToday && `${day}T00:00:00.000Z` <= toIso && `${day}T23:59:59.999Z` >= fromIso);
69
- const aggregateDays = overlappingAggregateDays.filter((day) => `${day}T00:00:00.000Z` >= fromIso && `${day}T23:59:59.999Z` <= toIso);
70
- if (aggregateDays.length !== overlappingAggregateDays.length) {
111
+ // Only days whose raw detail is actually gone are answered from the day-granular aggregate.
112
+ // A day that still has its raw rows is served from raw, exactly like a fresh install.
113
+ const aggregateDays = aggregateRequiredDays(db, aggregateRows)
114
+ .filter((day) => day < utcToday && `${day}T00:00:00.000Z` <= toIso && `${day}T23:59:59.999Z` >= fromIso);
115
+ const clippedDays = aggregateDays.filter((day) => `${day}T00:00:00.000Z` < fromIso || `${day}T23:59:59.999Z` > toIso);
116
+ if (clippedDays.length > 0) {
71
117
  throw new GatewayError('invalid_request_error', 'Statistics ranges overlapping compacted history must include complete UTC days.', { status: 400 });
72
118
  }
73
119
  const percentilesAvailable = aggregateDays.length === 0;
@@ -306,7 +352,8 @@ export async function registerStatsRoutes(app) {
306
352
  function buildSummary(db, fromIso, toIso) {
307
353
  // For previous period, use the same aggregate/raw partition as the primary range.
308
354
  const days = db.select().from(schema.dailyModelStats).where(and(gte(schema.dailyModelStats.day, fromIso.slice(0, 10)), lte(schema.dailyModelStats.day, toIso.slice(0, 10)))).all();
309
- const daySet = [...new Set(days.map((x) => x.day))].filter((day) => day < new Date().toISOString().slice(0, 10) && `${day}T00:00:00.000Z` >= fromIso && `${day}T23:59:59.999Z` <= toIso);
355
+ // Same rule as the primary range: a day only needs its aggregate when its raw detail is gone.
356
+ const daySet = aggregateRequiredDays(db, days).filter((day) => day < new Date().toISOString().slice(0, 10) && `${day}T00:00:00.000Z` >= fromIso && `${day}T23:59:59.999Z` <= toIso);
310
357
  const aggregates = days.filter((x) => daySet.includes(x.day));
311
358
  const rawOnly = daySet.length ? and(gte(schema.requests.createdAt, fromIso), lte(schema.requests.createdAt, toIso), sql `substr(created_at,1,10) NOT IN (${sql.join(daySet.map((day) => sql `${day}`), sql `, `)})`) : and(gte(schema.requests.createdAt, fromIso), lte(schema.requests.createdAt, toIso));
312
359
  const agg = aggregates.reduce((a, x) => ({ total: a.total + x.requests, success: a.success + x.successfulRequests, failed: a.failed + x.failedRequests, input: a.input + x.inputTokens, output: a.output + x.outputTokens, cacheRead: a.cacheRead + x.cacheReadTokens, cacheWrite: a.cacheWrite + x.cacheWriteTokens, reasoning: a.reasoning + x.reasoningTokens, gateway: a.gateway + x.gatewayCacheHits, fallback: a.fallback + x.fallbackRequests, latency: a.latency + x.latencySuccessSumMs, latencyCount: a.latencyCount + x.latencySuccessCount, ttft: a.ttft + x.ttftSumMs, ttftCount: a.ttftCount + x.ttftCount }), { total: 0, success: 0, failed: 0, input: 0, output: 0, cacheRead: 0, cacheWrite: 0, reasoning: 0, gateway: 0, fallback: 0, latency: 0, latencyCount: 0, ttft: 0, ttftCount: 0 });
@@ -0,0 +1 @@
1
+ *,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,-apple-system,Segoe UI,Roboto,sans-serif;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}:root{--background: 0 0% 100%;--foreground: 240 10% 3.9%;--card: 0 0% 100%;--card-foreground: 240 10% 3.9%;--popover: 0 0% 100%;--popover-foreground: 240 10% 3.9%;--primary: 341 86% 41%;--primary-foreground: 0 0% 100%;--secondary: 240 4.8% 95.9%;--secondary-foreground: 240 5.9% 10%;--muted: 240 4.8% 95.9%;--muted-foreground: 240 3.8% 46.1%;--accent: 240 4.8% 95.9%;--accent-foreground: 240 5.9% 10%;--destructive: 0 84.2% 60.2%;--destructive-foreground: 0 0% 98%;--border: 240 5.9% 90%;--input: 240 5.9% 90%;--ring: 341 86% 41%;--sidebar: 240 5.9% 98%;--sidebar-foreground: 240 10% 3.9%;--radius: .5rem}.dark{--background: 240 10% 3.9%;--foreground: 0 0% 98%;--card: 240 10% 6%;--card-foreground: 0 0% 98%;--popover: 240 10% 5%;--popover-foreground: 0 0% 98%;--primary: 341 86% 55%;--primary-foreground: 0 0% 100%;--secondary: 240 3.7% 15.9%;--secondary-foreground: 0 0% 98%;--muted: 240 3.7% 15.9%;--muted-foreground: 240 5% 64.9%;--accent: 240 3.7% 15.9%;--accent-foreground: 0 0% 98%;--destructive: 0 72% 51%;--destructive-foreground: 0 0% 98%;--border: 240 3.7% 15.9%;--input: 240 3.7% 15.9%;--ring: 341 86% 55%;--sidebar: 240 10% 5%;--sidebar-foreground: 0 0% 98%}*{border-color:hsl(var(--border))}body{background-color:hsl(var(--background));color:hsl(var(--foreground));font-feature-settings:"rlig" 1,"calt" 1}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.pointer-events-none{pointer-events:none}.visible{visibility:visible}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.inset-0{top:0;right:0;bottom:0;left:0}.left-1\/2{left:50%}.left-2{left:.5rem}.left-2\.5{left:.625rem}.left-\[50\%\]{left:50%}.right-2{right:.5rem}.right-4{right:1rem}.top-1\/2{top:50%}.top-16{top:4rem}.top-2\.5{top:.625rem}.top-4{top:1rem}.top-\[50\%\]{top:50%}.z-10{z-index:10}.z-50{z-index:50}.-mx-1{margin-left:-.25rem;margin-right:-.25rem}.my-1{margin-top:.25rem;margin-bottom:.25rem}.mb-1{margin-bottom:.25rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-6{margin-bottom:1.5rem}.ml-0\.5{margin-left:.125rem}.ml-1{margin-left:.25rem}.ml-1\.5{margin-left:.375rem}.ml-2{margin-left:.5rem}.mr-0\.5{margin-right:.125rem}.mr-1{margin-right:.25rem}.mr-2{margin-right:.5rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-6{margin-top:1.5rem}.block{display:block}.inline-block{display:inline-block}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.hidden{display:none}.h-10{height:2.5rem}.h-14{height:3.5rem}.h-2{height:.5rem}.h-20{height:5rem}.h-3{height:.75rem}.h-3\.5{height:.875rem}.h-4{height:1rem}.h-40{height:10rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-7{height:1.75rem}.h-8{height:2rem}.h-9{height:2.25rem}.h-auto{height:auto}.h-full{height:100%}.h-px{height:1px}.h-screen{height:100vh}.max-h-32{max-height:8rem}.max-h-40{max-height:10rem}.max-h-48{max-height:12rem}.max-h-60{max-height:15rem}.max-h-64{max-height:16rem}.max-h-72{max-height:18rem}.max-h-80{max-height:20rem}.max-h-96{max-height:24rem}.max-h-\[90vh\]{max-height:90vh}.max-h-\[calc\(100vh-2rem\)\]{max-height:calc(100vh - 2rem)}.max-h-\[calc\(100vh-8rem\)\]{max-height:calc(100vh - 8rem)}.min-h-0{min-height:0px}.min-h-32{min-height:8rem}.min-h-\[60px\]{min-height:60px}.min-h-screen{min-height:100vh}.w-1\.5{width:.375rem}.w-16{width:4rem}.w-2{width:.5rem}.w-20{width:5rem}.w-28{width:7rem}.w-3{width:.75rem}.w-3\.5{width:.875rem}.w-32{width:8rem}.w-36{width:9rem}.w-4{width:1rem}.w-40{width:10rem}.w-5{width:1.25rem}.w-56{width:14rem}.w-60{width:15rem}.w-7{width:1.75rem}.w-8{width:2rem}.w-80{width:20rem}.w-9{width:2.25rem}.w-full{width:100%}.min-w-0{min-width:0px}.min-w-\[10rem\]{min-width:10rem}.min-w-\[8rem\]{min-width:8rem}.min-w-\[9rem\]{min-width:9rem}.min-w-\[var\(--radix-select-trigger-width\)\]{min-width:var(--radix-select-trigger-width)}.max-w-2xl{max-width:42rem}.max-w-3xl{max-width:48rem}.max-w-5xl{max-width:64rem}.max-w-64{max-width:16rem}.max-w-lg{max-width:32rem}.max-w-md{max-width:28rem}.max-w-sm{max-width:24rem}.max-w-xs{max-width:20rem}.flex-1{flex:1 1 0%}.shrink-0{flex-shrink:0}.caption-bottom{caption-side:bottom}.translate-x-\[-50\%\]{--tw-translate-x: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-y-\[-50\%\]{--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-rotate-90{--tw-rotate: -90deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.cursor-default{cursor:default}.cursor-grab{cursor:grab}.cursor-pointer{cursor:pointer}.touch-none{touch-action:none}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-rows-\[auto_minmax\(0\,1fr\)_auto\]{grid-template-rows:auto minmax(0,1fr) auto}.flex-row{flex-direction:row}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.items-baseline{align-items:baseline}.items-stretch{align-items:stretch}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.space-x-1>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(.25rem * var(--tw-space-x-reverse));margin-left:calc(.25rem * calc(1 - var(--tw-space-x-reverse)))}.space-y-0\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.125rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.125rem * var(--tw-space-y-reverse))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-1\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.375rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.375rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.break-all{word-break:break-all}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:var(--radius)}.rounded-md{border-radius:calc(var(--radius) - 2px)}.rounded-sm{border-radius:calc(var(--radius) - 4px)}.border{border-width:1px}.border-2{border-width:2px}.border-b{border-bottom-width:1px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-amber-200{--tw-border-opacity: 1;border-color:rgb(253 230 138 / var(--tw-border-opacity, 1))}.border-amber-500\/40{border-color:#f59e0b66}.border-amber-600\/50{border-color:#d9770680}.border-border{border-color:hsl(var(--border))}.border-destructive{border-color:hsl(var(--destructive))}.border-destructive\/40{border-color:hsl(var(--destructive) / .4)}.border-input{border-color:hsl(var(--input))}.border-primary{border-color:hsl(var(--primary))}.border-transparent{border-color:transparent}.bg-amber-400{--tw-bg-opacity: 1;background-color:rgb(251 191 36 / var(--tw-bg-opacity, 1))}.bg-amber-50{--tw-bg-opacity: 1;background-color:rgb(255 251 235 / var(--tw-bg-opacity, 1))}.bg-amber-500{--tw-bg-opacity: 1;background-color:rgb(245 158 11 / var(--tw-bg-opacity, 1))}.bg-amber-500\/10{background-color:#f59e0b1a}.bg-amber-500\/90{background-color:#f59e0be6}.bg-background{background-color:hsl(var(--background))}.bg-black\/15{background-color:#00000026}.bg-black\/80{background-color:#000c}.bg-card{background-color:hsl(var(--card))}.bg-destructive{background-color:hsl(var(--destructive))}.bg-destructive\/10{background-color:hsl(var(--destructive) / .1)}.bg-emerald-100{--tw-bg-opacity: 1;background-color:rgb(209 250 229 / var(--tw-bg-opacity, 1))}.bg-emerald-400{--tw-bg-opacity: 1;background-color:rgb(52 211 153 / var(--tw-bg-opacity, 1))}.bg-emerald-500{--tw-bg-opacity: 1;background-color:rgb(16 185 129 / var(--tw-bg-opacity, 1))}.bg-emerald-600{--tw-bg-opacity: 1;background-color:rgb(5 150 105 / var(--tw-bg-opacity, 1))}.bg-green-100{--tw-bg-opacity: 1;background-color:rgb(220 252 231 / var(--tw-bg-opacity, 1))}.bg-muted{background-color:hsl(var(--muted))}.bg-muted\/20{background-color:hsl(var(--muted) / .2)}.bg-muted\/60{background-color:hsl(var(--muted) / .6)}.bg-popover{background-color:hsl(var(--popover))}.bg-primary{background-color:hsl(var(--primary))}.bg-primary\/10{background-color:hsl(var(--primary) / .1)}.bg-primary\/70{background-color:hsl(var(--primary) / .7)}.bg-red-100{--tw-bg-opacity: 1;background-color:rgb(254 226 226 / var(--tw-bg-opacity, 1))}.bg-red-400{--tw-bg-opacity: 1;background-color:rgb(248 113 113 / var(--tw-bg-opacity, 1))}.bg-secondary{background-color:hsl(var(--secondary))}.bg-sidebar{background-color:hsl(var(--sidebar))}.bg-transparent{background-color:transparent}.fill-amber-400{fill:#fbbf24}.fill-amber-500\/10{fill:#f59e0b1a}.fill-emerald-400{fill:#34d399}.fill-emerald-500{fill:#10b981}.fill-foreground{fill:hsl(var(--foreground))}.fill-muted-foreground{fill:hsl(var(--muted-foreground))}.fill-primary\/10{fill:hsl(var(--primary) / .1)}.fill-red-400{fill:#f87171}.fill-red-500{fill:#ef4444}.stroke-amber-500{stroke:#f59e0b}.stroke-emerald-500{stroke:#10b981}.stroke-primary{stroke:hsl(var(--primary))}.object-contain{-o-object-fit:contain;object-fit:contain}.p-1{padding:.25rem}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-6{padding:1.5rem}.px-1{padding-left:.25rem;padding-right:.25rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.pb-1{padding-bottom:.25rem}.pb-2{padding-bottom:.5rem}.pb-6{padding-bottom:1.5rem}.pl-8{padding-left:2rem}.pr-0{padding-right:0}.pr-1{padding-right:.25rem}.pr-2{padding-right:.5rem}.pt-0{padding-top:0}.pt-2{padding-top:.5rem}.pt-4{padding-top:1rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.align-middle{vertical-align:middle}.align-text-bottom{vertical-align:text-bottom}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}.text-2xl{font-size:1.5rem;line-height:2rem}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-medium{font-weight:500}.font-normal{font-weight:400}.font-semibold{font-weight:600}.tabular-nums{--tw-numeric-spacing: tabular-nums;font-variant-numeric:var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)}.leading-none{line-height:1}.tracking-tight{letter-spacing:-.025em}.text-amber-500{--tw-text-opacity: 1;color:rgb(245 158 11 / var(--tw-text-opacity, 1))}.text-amber-600{--tw-text-opacity: 1;color:rgb(217 119 6 / var(--tw-text-opacity, 1))}.text-amber-800{--tw-text-opacity: 1;color:rgb(146 64 14 / var(--tw-text-opacity, 1))}.text-amber-900{--tw-text-opacity: 1;color:rgb(120 53 15 / var(--tw-text-opacity, 1))}.text-amber-950{--tw-text-opacity: 1;color:rgb(69 26 3 / var(--tw-text-opacity, 1))}.text-blue-500{--tw-text-opacity: 1;color:rgb(59 130 246 / var(--tw-text-opacity, 1))}.text-card-foreground{color:hsl(var(--card-foreground))}.text-current{color:currentColor}.text-destructive{color:hsl(var(--destructive))}.text-destructive-foreground{color:hsl(var(--destructive-foreground))}.text-emerald-500{--tw-text-opacity: 1;color:rgb(16 185 129 / var(--tw-text-opacity, 1))}.text-emerald-600{--tw-text-opacity: 1;color:rgb(5 150 105 / var(--tw-text-opacity, 1))}.text-emerald-700{--tw-text-opacity: 1;color:rgb(4 120 87 / var(--tw-text-opacity, 1))}.text-foreground{color:hsl(var(--foreground))}.text-green-800{--tw-text-opacity: 1;color:rgb(22 101 52 / var(--tw-text-opacity, 1))}.text-muted-foreground{color:hsl(var(--muted-foreground))}.text-muted-foreground\/60{color:hsl(var(--muted-foreground) / .6)}.text-popover-foreground{color:hsl(var(--popover-foreground))}.text-primary{color:hsl(var(--primary))}.text-primary-foreground{color:hsl(var(--primary-foreground))}.text-red-500{--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.text-red-700{--tw-text-opacity: 1;color:rgb(185 28 28 / var(--tw-text-opacity, 1))}.text-secondary-foreground{color:hsl(var(--secondary-foreground))}.text-sidebar-foreground{color:hsl(var(--sidebar-foreground))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.underline{text-decoration-line:underline}.underline-offset-4{text-underline-offset:4px}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.opacity-90{opacity:.9}.shadow{--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1);--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-md{--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.outline-none{outline:2px solid transparent;outline-offset:2px}.outline{outline-style:solid}.ring-0{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-offset-background{--tw-ring-offset-color: hsl(var(--background))}.blur{--tw-blur: blur(8px);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.invert{--tw-invert: invert(100%);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-200{transition-duration:.2s}@keyframes route-active-pulse{0%{opacity:.35}50%{opacity:1}to{opacity:.35}}.route-active{animation:route-active-pulse 1.4s ease-in-out infinite}::-webkit-scrollbar{width:8px;height:8px}::-webkit-scrollbar-thumb{background:hsl(var(--border));border-radius:4px}::-webkit-scrollbar-track{background:transparent}.file\:border-0::file-selector-button{border-width:0px}.file\:bg-transparent::file-selector-button{background-color:transparent}.file\:text-sm::file-selector-button{font-size:.875rem;line-height:1.25rem}.file\:font-medium::file-selector-button{font-weight:500}.placeholder\:text-muted-foreground::-moz-placeholder{color:hsl(var(--muted-foreground))}.placeholder\:text-muted-foreground::placeholder{color:hsl(var(--muted-foreground))}.last\:border-0:last-child{border-width:0px}.hover\:bg-accent:hover{background-color:hsl(var(--accent))}.hover\:bg-destructive\/90:hover{background-color:hsl(var(--destructive) / .9)}.hover\:bg-muted:hover{background-color:hsl(var(--muted))}.hover\:bg-muted\/50:hover{background-color:hsl(var(--muted) / .5)}.hover\:bg-primary\/90:hover{background-color:hsl(var(--primary) / .9)}.hover\:bg-secondary\/80:hover{background-color:hsl(var(--secondary) / .8)}.hover\:text-accent-foreground:hover{color:hsl(var(--accent-foreground))}.hover\:text-foreground:hover{color:hsl(var(--foreground))}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-100:hover{opacity:1}.hover\:opacity-95:hover{opacity:.95}.focus\:bg-accent:focus{background-color:hsl(var(--accent))}.focus\:text-accent-foreground:focus{color:hsl(var(--accent-foreground))}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-1:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-ring:focus{--tw-ring-color: hsl(var(--ring))}.focus-visible\:outline-none:focus-visible{outline:2px solid transparent;outline-offset:2px}.focus-visible\:ring-1:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\:ring-2:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\:ring-ring:focus-visible{--tw-ring-color: hsl(var(--ring))}.focus-visible\:ring-offset-2:focus-visible{--tw-ring-offset-width: 2px}.focus-visible\:ring-offset-background:focus-visible{--tw-ring-offset-color: hsl(var(--background))}.active\:cursor-grabbing:active{cursor:grabbing}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-50:disabled{opacity:.5}.peer:disabled~.peer-disabled\:cursor-not-allowed{cursor:not-allowed}.peer:disabled~.peer-disabled\:opacity-70{opacity:.7}.data-\[disabled\]\:pointer-events-none[data-disabled]{pointer-events:none}.data-\[state\=checked\]\:translate-x-4[data-state=checked]{--tw-translate-x: 1rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[state\=unchecked\]\:translate-x-0[data-state=unchecked]{--tw-translate-x: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[state\=active\]\:bg-background[data-state=active]{background-color:hsl(var(--background))}.data-\[state\=checked\]\:bg-primary[data-state=checked]{background-color:hsl(var(--primary))}.data-\[state\=selected\]\:bg-muted[data-state=selected]{background-color:hsl(var(--muted))}.data-\[state\=unchecked\]\:bg-input[data-state=unchecked]{background-color:hsl(var(--input))}.data-\[state\=active\]\:text-foreground[data-state=active]{color:hsl(var(--foreground))}.data-\[state\=checked\]\:text-primary-foreground[data-state=checked]{color:hsl(var(--primary-foreground))}.data-\[disabled\]\:opacity-50[data-disabled]{opacity:.5}.data-\[state\=active\]\:shadow[data-state=active]{--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1);--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.dark\:border-amber-800:is(.dark *){--tw-border-opacity: 1;border-color:rgb(146 64 14 / var(--tw-border-opacity, 1))}.dark\:bg-amber-950\/20:is(.dark *){background-color:#451a0333}.dark\:bg-emerald-900\/40:is(.dark *){background-color:#064e3b66}.dark\:bg-green-900:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(20 83 45 / var(--tw-bg-opacity, 1))}.dark\:bg-red-900\/40:is(.dark *){background-color:#7f1d1d66}.dark\:text-amber-200:is(.dark *){--tw-text-opacity: 1;color:rgb(253 230 138 / var(--tw-text-opacity, 1))}.dark\:text-amber-300:is(.dark *){--tw-text-opacity: 1;color:rgb(252 211 77 / var(--tw-text-opacity, 1))}.dark\:text-emerald-300:is(.dark *){--tw-text-opacity: 1;color:rgb(110 231 183 / var(--tw-text-opacity, 1))}.dark\:text-green-200:is(.dark *){--tw-text-opacity: 1;color:rgb(187 247 208 / var(--tw-text-opacity, 1))}.dark\:text-red-300:is(.dark *){--tw-text-opacity: 1;color:rgb(252 165 165 / var(--tw-text-opacity, 1))}@media(min-width:640px){.sm\:inline{display:inline}.sm\:max-w-\[425px\]{max-width:425px}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-\[10rem_1fr\]{grid-template-columns:10rem 1fr}.sm\:flex-row{flex-direction:row}.sm\:justify-end{justify-content:flex-end}.sm\:space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(.5rem * var(--tw-space-x-reverse));margin-left:calc(.5rem * calc(1 - var(--tw-space-x-reverse)))}.sm\:rounded-lg{border-radius:var(--radius)}.sm\:text-left{text-align:left}}@media(min-width:768px){.md\:flex{display:flex}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:flex-col{flex-direction:column}}@media(min-width:1024px){.lg\:col-span-2{grid-column:span 2 / span 2}.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))}}.\[\&_tr\:last-child\]\:border-0 tr:last-child{border-width:0px}.\[\&_tr\]\:border-b tr{border-bottom-width:1px}
@@ -345,5 +345,5 @@ Please change the parent <Route path="${R}"> to <Route path="${R==="/"?"*":`${R}
345
345
  To pick up a draggable item, press the space bar.
346
346
  While dragging, use the arrow keys to move the item.
347
347
  Press space again to drop the item in its new position, or press escape to cancel.
348
- `},$_={onDragStart(n){let{active:a}=n;return"Picked up draggable item "+a.id+"."},onDragOver(n){let{active:a,over:l}=n;return l?"Draggable item "+a.id+" was moved over droppable area "+l.id+".":"Draggable item "+a.id+" is no longer over a droppable area."},onDragEnd(n){let{active:a,over:l}=n;return l?"Draggable item "+a.id+" was dropped over droppable area "+l.id:"Draggable item "+a.id+" was dropped."},onDragCancel(n){let{active:a}=n;return"Dragging was cancelled. Draggable item "+a.id+" was dropped."}};function Y_(n){let{announcements:a=$_,container:l,hiddenTextDescribedById:s,screenReaderInstructions:c=V_}=n;const{announce:u,announcement:f}=I_(),p=xi("DndLiveRegion"),[g,v]=m.useState(!1);if(m.useEffect(()=>{v(!0)},[]),P_(m.useMemo(()=>({onDragStart(y){let{active:b}=y;u(a.onDragStart({active:b}))},onDragMove(y){let{active:b,over:w}=y;a.onDragMove&&u(a.onDragMove({active:b,over:w}))},onDragOver(y){let{active:b,over:w}=y;u(a.onDragOver({active:b,over:w}))},onDragEnd(y){let{active:b,over:w}=y;u(a.onDragEnd({active:b,over:w}))},onDragCancel(y){let{active:b,over:w}=y;u(a.onDragCancel({active:b,over:w}))}}),[u,a])),!g)return null;const x=ue.createElement(ue.Fragment,null,ue.createElement(B_,{id:s,value:c.draggable}),ue.createElement(H_,{id:p,announcement:f}));return l?Ca.createPortal(x,l):x}var Zt;(function(n){n.DragStart="dragStart",n.DragMove="dragMove",n.DragEnd="dragEnd",n.DragCancel="dragCancel",n.DragOver="dragOver",n.RegisterDroppable="registerDroppable",n.SetDroppableDisabled="setDroppableDisabled",n.UnregisterDroppable="unregisterDroppable"})(Zt||(Zt={}));function fu(){}function Ab(n,a){return m.useMemo(()=>({sensor:n,options:a??{}}),[n,a])}function G_(){for(var n=arguments.length,a=new Array(n),l=0;l<n;l++)a[l]=arguments[l];return m.useMemo(()=>[...a].filter(s=>s!=null),[...a])}const Ma=Object.freeze({x:0,y:0});function iS(n,a){return Math.sqrt(Math.pow(n.x-a.x,2)+Math.pow(n.y-a.y,2))}function cS(n,a){let{data:{value:l}}=n,{data:{value:s}}=a;return l-s}function F_(n,a){let{data:{value:l}}=n,{data:{value:s}}=a;return s-l}function Db(n){let{left:a,top:l,height:s,width:c}=n;return[{x:a,y:l},{x:a+c,y:l},{x:a,y:l+s},{x:a+c,y:l+s}]}function uS(n,a){if(!n||n.length===0)return null;const[l]=n;return l[a]}function Ob(n,a,l){return a===void 0&&(a=n.left),l===void 0&&(l=n.top),{x:a+n.width*.5,y:l+n.height*.5}}const K_=n=>{let{collisionRect:a,droppableRects:l,droppableContainers:s}=n;const c=Ob(a,a.left,a.top),u=[];for(const f of s){const{id:p}=f,g=l.get(p);if(g){const v=iS(Ob(g),c);u.push({id:p,data:{droppableContainer:f,value:v}})}}return u.sort(cS)},X_=n=>{let{collisionRect:a,droppableRects:l,droppableContainers:s}=n;const c=Db(a),u=[];for(const f of s){const{id:p}=f,g=l.get(p);if(g){const v=Db(g),x=c.reduce((b,w,E)=>b+iS(v[E],w),0),y=Number((x/4).toFixed(4));u.push({id:p,data:{droppableContainer:f,value:y}})}}return u.sort(cS)};function Q_(n,a){const l=Math.max(a.top,n.top),s=Math.max(a.left,n.left),c=Math.min(a.left+a.width,n.left+n.width),u=Math.min(a.top+a.height,n.top+n.height),f=c-s,p=u-l;if(s<c&&l<u){const g=a.width*a.height,v=n.width*n.height,x=f*p,y=x/(g+v-x);return Number(y.toFixed(4))}return 0}const Z_=n=>{let{collisionRect:a,droppableRects:l,droppableContainers:s}=n;const c=[];for(const u of s){const{id:f}=u,p=l.get(f);if(p){const g=Q_(p,a);g>0&&c.push({id:f,data:{droppableContainer:u,value:g}})}}return c.sort(F_)};function J_(n,a,l){return{...n,scaleX:a&&l?a.width/l.width:1,scaleY:a&&l?a.height/l.height:1}}function dS(n,a){return n&&a?{x:n.left-a.left,y:n.top-a.top}:Ma}function W_(n){return function(l){for(var s=arguments.length,c=new Array(s>1?s-1:0),u=1;u<s;u++)c[u-1]=arguments[u];return c.reduce((f,p)=>({...f,top:f.top+n*p.y,bottom:f.bottom+n*p.y,left:f.left+n*p.x,right:f.right+n*p.x}),{...l})}}const ek=W_(1);function tk(n){if(n.startsWith("matrix3d(")){const a=n.slice(9,-1).split(/, /);return{x:+a[12],y:+a[13],scaleX:+a[0],scaleY:+a[5]}}else if(n.startsWith("matrix(")){const a=n.slice(7,-1).split(/, /);return{x:+a[4],y:+a[5],scaleX:+a[0],scaleY:+a[3]}}return null}function nk(n,a,l){const s=tk(a);if(!s)return n;const{scaleX:c,scaleY:u,x:f,y:p}=s,g=n.left-f-(1-c)*parseFloat(l),v=n.top-p-(1-u)*parseFloat(l.slice(l.indexOf(" ")+1)),x=c?n.width/c:n.width,y=u?n.height/u:n.height;return{width:x,height:y,top:v,right:g+x,bottom:v+y,left:g}}const ak={ignoreTransform:!1};function Qs(n,a){a===void 0&&(a=ak);let l=n.getBoundingClientRect();if(a.ignoreTransform){const{transform:v,transformOrigin:x}=In(n).getComputedStyle(n);v&&(l=nk(l,v,x))}const{top:s,left:c,width:u,height:f,bottom:p,right:g}=l;return{top:s,left:c,width:u,height:f,bottom:p,right:g}}function _b(n){return Qs(n,{ignoreTransform:!0})}function rk(n){const a=n.innerWidth,l=n.innerHeight;return{top:0,left:0,right:a,bottom:l,width:a,height:l}}function lk(n,a){return a===void 0&&(a=In(n).getComputedStyle(n)),a.position==="fixed"}function sk(n,a){a===void 0&&(a=In(n).getComputedStyle(n));const l=/(auto|scroll|overlay)/;return["overflow","overflowX","overflowY"].some(c=>{const u=a[c];return typeof u=="string"?l.test(u):!1})}function Ku(n,a){const l=[];function s(c){if(a!=null&&l.length>=a||!c)return l;if(Rp(c)&&c.scrollingElement!=null&&!l.includes(c.scrollingElement))return l.push(c.scrollingElement),l;if(!gi(c)||lS(c)||l.includes(c))return l;const u=In(n).getComputedStyle(c);return c!==n&&sk(c,u)&&l.push(c),lk(c,u)?l:s(c.parentNode)}return n?s(n):l}function fS(n){const[a]=Ku(n,1);return a??null}function kh(n){return!Fu||!n?null:Ks(n)?n:Ep(n)?Rp(n)||n===Xs(n).scrollingElement?window:gi(n)?n:null:null}function hS(n){return Ks(n)?n.scrollX:n.scrollLeft}function mS(n){return Ks(n)?n.scrollY:n.scrollTop}function hm(n){return{x:hS(n),y:mS(n)}}var rn;(function(n){n[n.Forward=1]="Forward",n[n.Backward=-1]="Backward"})(rn||(rn={}));function pS(n){return!Fu||!n?!1:n===document.scrollingElement}function gS(n){const a={x:0,y:0},l=pS(n)?{height:window.innerHeight,width:window.innerWidth}:{height:n.clientHeight,width:n.clientWidth},s={x:n.scrollWidth-l.width,y:n.scrollHeight-l.height},c=n.scrollTop<=a.y,u=n.scrollLeft<=a.x,f=n.scrollTop>=s.y,p=n.scrollLeft>=s.x;return{isTop:c,isLeft:u,isBottom:f,isRight:p,maxScroll:s,minScroll:a}}const ok={x:.2,y:.2};function ik(n,a,l,s,c){let{top:u,left:f,right:p,bottom:g}=l;s===void 0&&(s=10),c===void 0&&(c=ok);const{isTop:v,isBottom:x,isLeft:y,isRight:b}=gS(n),w={x:0,y:0},E={x:0,y:0},j={height:a.height*c.y,width:a.width*c.x};return!v&&u<=a.top+j.height?(w.y=rn.Backward,E.y=s*Math.abs((a.top+j.height-u)/j.height)):!x&&g>=a.bottom-j.height&&(w.y=rn.Forward,E.y=s*Math.abs((a.bottom-j.height-g)/j.height)),!b&&p>=a.right-j.width?(w.x=rn.Forward,E.x=s*Math.abs((a.right-j.width-p)/j.width)):!y&&f<=a.left+j.width&&(w.x=rn.Backward,E.x=s*Math.abs((a.left+j.width-f)/j.width)),{direction:w,speed:E}}function ck(n){if(n===document.scrollingElement){const{innerWidth:u,innerHeight:f}=window;return{top:0,left:0,right:u,bottom:f,width:u,height:f}}const{top:a,left:l,right:s,bottom:c}=n.getBoundingClientRect();return{top:a,left:l,right:s,bottom:c,width:n.clientWidth,height:n.clientHeight}}function vS(n){return n.reduce((a,l)=>Us(a,hm(l)),Ma)}function uk(n){return n.reduce((a,l)=>a+hS(l),0)}function dk(n){return n.reduce((a,l)=>a+mS(l),0)}function fk(n,a){if(a===void 0&&(a=Qs),!n)return;const{top:l,left:s,bottom:c,right:u}=a(n);fS(n)&&(c<=0||u<=0||l>=window.innerHeight||s>=window.innerWidth)&&n.scrollIntoView({block:"center",inline:"center"})}const hk=[["x",["left","right"],uk],["y",["top","bottom"],dk]];class Mp{constructor(a,l){this.rect=void 0,this.width=void 0,this.height=void 0,this.top=void 0,this.bottom=void 0,this.right=void 0,this.left=void 0;const s=Ku(l),c=vS(s);this.rect={...a},this.width=a.width,this.height=a.height;for(const[u,f,p]of hk)for(const g of f)Object.defineProperty(this,g,{get:()=>{const v=p(s),x=c[u]-v;return this.rect[g]+x},enumerable:!0});Object.defineProperty(this,"rect",{enumerable:!1})}}class Ko{constructor(a){this.target=void 0,this.listeners=[],this.removeAll=()=>{this.listeners.forEach(l=>{var s;return(s=this.target)==null?void 0:s.removeEventListener(...l)})},this.target=a}add(a,l,s){var c;(c=this.target)==null||c.addEventListener(a,l,s),this.listeners.push([a,l,s])}}function mk(n){const{EventTarget:a}=In(n);return n instanceof a?n:Xs(n)}function zh(n,a){const l=Math.abs(n.x),s=Math.abs(n.y);return typeof a=="number"?Math.sqrt(l**2+s**2)>a:"x"in a&&"y"in a?l>a.x&&s>a.y:"x"in a?l>a.x:"y"in a?s>a.y:!1}var ca;(function(n){n.Click="click",n.DragStart="dragstart",n.Keydown="keydown",n.ContextMenu="contextmenu",n.Resize="resize",n.SelectionChange="selectionchange",n.VisibilityChange="visibilitychange"})(ca||(ca={}));function kb(n){n.preventDefault()}function pk(n){n.stopPropagation()}var Fe;(function(n){n.Space="Space",n.Down="ArrowDown",n.Right="ArrowRight",n.Left="ArrowLeft",n.Up="ArrowUp",n.Esc="Escape",n.Enter="Enter",n.Tab="Tab"})(Fe||(Fe={}));const xS={start:[Fe.Space,Fe.Enter],cancel:[Fe.Esc],end:[Fe.Space,Fe.Enter,Fe.Tab]},gk=(n,a)=>{let{currentCoordinates:l}=a;switch(n.code){case Fe.Right:return{...l,x:l.x+25};case Fe.Left:return{...l,x:l.x-25};case Fe.Down:return{...l,y:l.y+25};case Fe.Up:return{...l,y:l.y-25}}};class Ap{constructor(a){this.props=void 0,this.autoScrollEnabled=!1,this.referenceCoordinates=void 0,this.listeners=void 0,this.windowListeners=void 0,this.props=a;const{event:{target:l}}=a;this.props=a,this.listeners=new Ko(Xs(l)),this.windowListeners=new Ko(In(l)),this.handleKeyDown=this.handleKeyDown.bind(this),this.handleCancel=this.handleCancel.bind(this),this.attach()}attach(){this.handleStart(),this.windowListeners.add(ca.Resize,this.handleCancel),this.windowListeners.add(ca.VisibilityChange,this.handleCancel),setTimeout(()=>this.listeners.add(ca.Keydown,this.handleKeyDown))}handleStart(){const{activeNode:a,onStart:l}=this.props,s=a.node.current;s&&fk(s),l(Ma)}handleKeyDown(a){if(Tp(a)){const{active:l,context:s,options:c}=this.props,{keyboardCodes:u=xS,coordinateGetter:f=gk,scrollBehavior:p="smooth"}=c,{code:g}=a;if(u.end.includes(g)){this.handleEnd(a);return}if(u.cancel.includes(g)){this.handleCancel(a);return}const{collisionRect:v}=s.current,x=v?{x:v.left,y:v.top}:Ma;this.referenceCoordinates||(this.referenceCoordinates=x);const y=f(a,{active:l,context:s.current,currentCoordinates:x});if(y){const b=ni(y,x),w={x:0,y:0},{scrollableAncestors:E}=s.current;for(const j of E){const C=a.code,{isTop:R,isRight:M,isLeft:T,isBottom:D,maxScroll:_,minScroll:A}=gS(j),U=ck(j),O={x:Math.min(C===Fe.Right?U.right-U.width/2:U.right,Math.max(C===Fe.Right?U.left:U.left+U.width/2,y.x)),y:Math.min(C===Fe.Down?U.bottom-U.height/2:U.bottom,Math.max(C===Fe.Down?U.top:U.top+U.height/2,y.y))},q=C===Fe.Right&&!M||C===Fe.Left&&!T,K=C===Fe.Down&&!D||C===Fe.Up&&!R;if(q&&O.x!==y.x){const te=j.scrollLeft+b.x,G=C===Fe.Right&&te<=_.x||C===Fe.Left&&te>=A.x;if(G&&!b.y){j.scrollTo({left:te,behavior:p});return}G?w.x=j.scrollLeft-te:w.x=C===Fe.Right?j.scrollLeft-_.x:j.scrollLeft-A.x,w.x&&j.scrollBy({left:-w.x,behavior:p});break}else if(K&&O.y!==y.y){const te=j.scrollTop+b.y,G=C===Fe.Down&&te<=_.y||C===Fe.Up&&te>=A.y;if(G&&!b.x){j.scrollTo({top:te,behavior:p});return}G?w.y=j.scrollTop-te:w.y=C===Fe.Down?j.scrollTop-_.y:j.scrollTop-A.y,w.y&&j.scrollBy({top:-w.y,behavior:p});break}}this.handleMove(a,Us(ni(y,this.referenceCoordinates),w))}}}handleMove(a,l){const{onMove:s}=this.props;a.preventDefault(),s(l)}handleEnd(a){const{onEnd:l}=this.props;a.preventDefault(),this.detach(),l()}handleCancel(a){const{onCancel:l}=this.props;a.preventDefault(),this.detach(),l()}detach(){this.listeners.removeAll(),this.windowListeners.removeAll()}}Ap.activators=[{eventName:"onKeyDown",handler:(n,a,l)=>{let{keyboardCodes:s=xS,onActivation:c}=a,{active:u}=l;const{code:f}=n.nativeEvent;if(s.start.includes(f)){const p=u.activatorNode.current;return p&&n.target!==p?!1:(n.preventDefault(),c==null||c({event:n.nativeEvent}),!0)}return!1}}];function zb(n){return!!(n&&"distance"in n)}function Lb(n){return!!(n&&"delay"in n)}class Dp{constructor(a,l,s){var c;s===void 0&&(s=mk(a.event.target)),this.props=void 0,this.events=void 0,this.autoScrollEnabled=!0,this.document=void 0,this.activated=!1,this.initialCoordinates=void 0,this.timeoutId=null,this.listeners=void 0,this.documentListeners=void 0,this.windowListeners=void 0,this.props=a,this.events=l;const{event:u}=a,{target:f}=u;this.props=a,this.events=l,this.document=Xs(f),this.documentListeners=new Ko(this.document),this.listeners=new Ko(s),this.windowListeners=new Ko(In(f)),this.initialCoordinates=(c=fm(u))!=null?c:Ma,this.handleStart=this.handleStart.bind(this),this.handleMove=this.handleMove.bind(this),this.handleEnd=this.handleEnd.bind(this),this.handleCancel=this.handleCancel.bind(this),this.handleKeydown=this.handleKeydown.bind(this),this.removeTextSelection=this.removeTextSelection.bind(this),this.attach()}attach(){const{events:a,props:{options:{activationConstraint:l,bypassActivationConstraint:s}}}=this;if(this.listeners.add(a.move.name,this.handleMove,{passive:!1}),this.listeners.add(a.end.name,this.handleEnd),a.cancel&&this.listeners.add(a.cancel.name,this.handleCancel),this.windowListeners.add(ca.Resize,this.handleCancel),this.windowListeners.add(ca.DragStart,kb),this.windowListeners.add(ca.VisibilityChange,this.handleCancel),this.windowListeners.add(ca.ContextMenu,kb),this.documentListeners.add(ca.Keydown,this.handleKeydown),l){if(s!=null&&s({event:this.props.event,activeNode:this.props.activeNode,options:this.props.options}))return this.handleStart();if(Lb(l)){this.timeoutId=setTimeout(this.handleStart,l.delay),this.handlePending(l);return}if(zb(l)){this.handlePending(l);return}}this.handleStart()}detach(){this.listeners.removeAll(),this.windowListeners.removeAll(),setTimeout(this.documentListeners.removeAll,50),this.timeoutId!==null&&(clearTimeout(this.timeoutId),this.timeoutId=null)}handlePending(a,l){const{active:s,onPending:c}=this.props;c(s,a,this.initialCoordinates,l)}handleStart(){const{initialCoordinates:a}=this,{onStart:l}=this.props;a&&(this.activated=!0,this.documentListeners.add(ca.Click,pk,{capture:!0}),this.removeTextSelection(),this.documentListeners.add(ca.SelectionChange,this.removeTextSelection),l(a))}handleMove(a){var l;const{activated:s,initialCoordinates:c,props:u}=this,{onMove:f,options:{activationConstraint:p}}=u;if(!c)return;const g=(l=fm(a))!=null?l:Ma,v=ni(c,g);if(!s&&p){if(zb(p)){if(p.tolerance!=null&&zh(v,p.tolerance))return this.handleCancel();if(zh(v,p.distance))return this.handleStart()}if(Lb(p)&&zh(v,p.tolerance))return this.handleCancel();this.handlePending(p,v);return}a.cancelable&&a.preventDefault(),f(g)}handleEnd(){const{onAbort:a,onEnd:l}=this.props;this.detach(),this.activated||a(this.props.active),l()}handleCancel(){const{onAbort:a,onCancel:l}=this.props;this.detach(),this.activated||a(this.props.active),l()}handleKeydown(a){a.code===Fe.Esc&&this.handleCancel()}removeTextSelection(){var a;(a=this.document.getSelection())==null||a.removeAllRanges()}}const vk={cancel:{name:"pointercancel"},move:{name:"pointermove"},end:{name:"pointerup"}};class Op extends Dp{constructor(a){const{event:l}=a,s=Xs(l.target);super(a,vk,s)}}Op.activators=[{eventName:"onPointerDown",handler:(n,a)=>{let{nativeEvent:l}=n,{onActivation:s}=a;return!l.isPrimary||l.button!==0?!1:(s==null||s({event:l}),!0)}}];const xk={move:{name:"mousemove"},end:{name:"mouseup"}};var mm;(function(n){n[n.RightClick=2]="RightClick"})(mm||(mm={}));class yk extends Dp{constructor(a){super(a,xk,Xs(a.event.target))}}yk.activators=[{eventName:"onMouseDown",handler:(n,a)=>{let{nativeEvent:l}=n,{onActivation:s}=a;return l.button===mm.RightClick?!1:(s==null||s({event:l}),!0)}}];const Lh={cancel:{name:"touchcancel"},move:{name:"touchmove"},end:{name:"touchend"}};class bk extends Dp{constructor(a){super(a,Lh)}static setup(){return window.addEventListener(Lh.move.name,a,{capture:!1,passive:!1}),function(){window.removeEventListener(Lh.move.name,a)};function a(){}}}bk.activators=[{eventName:"onTouchStart",handler:(n,a)=>{let{nativeEvent:l}=n,{onActivation:s}=a;const{touches:c}=l;return c.length>1?!1:(s==null||s({event:l}),!0)}}];var Xo;(function(n){n[n.Pointer=0]="Pointer",n[n.DraggableRect=1]="DraggableRect"})(Xo||(Xo={}));var hu;(function(n){n[n.TreeOrder=0]="TreeOrder",n[n.ReversedTreeOrder=1]="ReversedTreeOrder"})(hu||(hu={}));function wk(n){let{acceleration:a,activator:l=Xo.Pointer,canScroll:s,draggingRect:c,enabled:u,interval:f=5,order:p=hu.TreeOrder,pointerCoordinates:g,scrollableAncestors:v,scrollableAncestorRects:x,delta:y,threshold:b}=n;const w=jk({delta:y,disabled:!u}),[E,j]=__(),C=m.useRef({x:0,y:0}),R=m.useRef({x:0,y:0}),M=m.useMemo(()=>{switch(l){case Xo.Pointer:return g?{top:g.y,bottom:g.y,left:g.x,right:g.x}:null;case Xo.DraggableRect:return c}},[l,c,g]),T=m.useRef(null),D=m.useCallback(()=>{const A=T.current;if(!A)return;const U=C.current.x*R.current.x,O=C.current.y*R.current.y;A.scrollBy(U,O)},[]),_=m.useMemo(()=>p===hu.TreeOrder?[...v].reverse():v,[p,v]);m.useEffect(()=>{if(!u||!v.length||!M){j();return}for(const A of _){if((s==null?void 0:s(A))===!1)continue;const U=v.indexOf(A),O=x[U];if(!O)continue;const{direction:q,speed:K}=ik(A,O,M,a,b);for(const te of["x","y"])w[te][q[te]]||(K[te]=0,q[te]=0);if(K.x>0||K.y>0){j(),T.current=A,E(D,f),C.current=K,R.current=q;return}}C.current={x:0,y:0},R.current={x:0,y:0},j()},[a,D,s,j,u,f,JSON.stringify(M),JSON.stringify(w),E,v,_,x,JSON.stringify(b)])}const Sk={x:{[rn.Backward]:!1,[rn.Forward]:!1},y:{[rn.Backward]:!1,[rn.Forward]:!1}};function jk(n){let{delta:a,disabled:l}=n;const s=dm(a);return vi(c=>{if(l||!s||!c)return Sk;const u={x:Math.sign(a.x-s.x),y:Math.sign(a.y-s.y)};return{x:{[rn.Backward]:c.x[rn.Backward]||u.x===-1,[rn.Forward]:c.x[rn.Forward]||u.x===1},y:{[rn.Backward]:c.y[rn.Backward]||u.y===-1,[rn.Forward]:c.y[rn.Forward]||u.y===1}}},[l,a,s])}function Ck(n,a){const l=a!=null?n.get(a):void 0,s=l?l.node.current:null;return vi(c=>{var u;return a==null?null:(u=s??c)!=null?u:null},[s,a])}function Ek(n,a){return m.useMemo(()=>n.reduce((l,s)=>{const{sensor:c}=s,u=c.activators.map(f=>({eventName:f.eventName,handler:a(f.handler,s)}));return[...l,...u]},[]),[n,a])}var ai;(function(n){n[n.Always=0]="Always",n[n.BeforeDragging=1]="BeforeDragging",n[n.WhileDragging=2]="WhileDragging"})(ai||(ai={}));var pm;(function(n){n.Optimized="optimized"})(pm||(pm={}));const Ub=new Map;function Rk(n,a){let{dragging:l,dependencies:s,config:c}=a;const[u,f]=m.useState(null),{frequency:p,measure:g,strategy:v}=c,x=m.useRef(n),y=C(),b=ti(y),w=m.useCallback(function(R){R===void 0&&(R=[]),!b.current&&f(M=>M===null?R:M.concat(R.filter(T=>!M.includes(T))))},[b]),E=m.useRef(null),j=vi(R=>{if(y&&!l)return Ub;if(!R||R===Ub||x.current!==n||u!=null){const M=new Map;for(let T of n){if(!T)continue;if(u&&u.length>0&&!u.includes(T.id)&&T.rect.current){M.set(T.id,T.rect.current);continue}const D=T.node.current,_=D?new Mp(g(D),D):null;T.rect.current=_,_&&M.set(T.id,_)}return M}return R},[n,u,l,y,g]);return m.useEffect(()=>{x.current=n},[n]),m.useEffect(()=>{y||w()},[l,y]),m.useEffect(()=>{u&&u.length>0&&f(null)},[JSON.stringify(u)]),m.useEffect(()=>{y||typeof p!="number"||E.current!==null||(E.current=setTimeout(()=>{w(),E.current=null},p))},[p,y,w,...s]),{droppableRects:j,measureDroppableContainers:w,measuringScheduled:u!=null};function C(){switch(v){case ai.Always:return!1;case ai.BeforeDragging:return l;default:return!l}}}function yS(n,a){return vi(l=>n?l||(typeof a=="function"?a(n):n):null,[a,n])}function Nk(n,a){return yS(n,a)}function Tk(n){let{callback:a,disabled:l}=n;const s=Np(a),c=m.useMemo(()=>{if(l||typeof window>"u"||typeof window.MutationObserver>"u")return;const{MutationObserver:u}=window;return new u(s)},[s,l]);return m.useEffect(()=>()=>c==null?void 0:c.disconnect(),[c]),c}function Xu(n){let{callback:a,disabled:l}=n;const s=Np(a),c=m.useMemo(()=>{if(l||typeof window>"u"||typeof window.ResizeObserver>"u")return;const{ResizeObserver:u}=window;return new u(s)},[l]);return m.useEffect(()=>()=>c==null?void 0:c.disconnect(),[c]),c}function Mk(n){return new Mp(Qs(n),n)}function Bb(n,a,l){a===void 0&&(a=Mk);const[s,c]=m.useState(null);function u(){c(g=>{if(!n)return null;if(n.isConnected===!1){var v;return(v=g??l)!=null?v:null}const x=a(n);return JSON.stringify(g)===JSON.stringify(x)?g:x})}const f=Tk({callback(g){if(n)for(const v of g){const{type:x,target:y}=v;if(x==="childList"&&y instanceof HTMLElement&&y.contains(n)){u();break}}}}),p=Xu({callback:u});return Va(()=>{u(),n?(p==null||p.observe(n),f==null||f.observe(document.body,{childList:!0,subtree:!0})):(p==null||p.disconnect(),f==null||f.disconnect())},[n]),s}function Ak(n){const a=yS(n);return dS(n,a)}const Hb=[];function Dk(n){const a=m.useRef(n),l=vi(s=>n?s&&s!==Hb&&n&&a.current&&n.parentNode===a.current.parentNode?s:Ku(n):Hb,[n]);return m.useEffect(()=>{a.current=n},[n]),l}function Ok(n){const[a,l]=m.useState(null),s=m.useRef(n),c=m.useCallback(u=>{const f=kh(u.target);f&&l(p=>p?(p.set(f,hm(f)),new Map(p)):null)},[]);return m.useEffect(()=>{const u=s.current;if(n!==u){f(u);const p=n.map(g=>{const v=kh(g);return v?(v.addEventListener("scroll",c,{passive:!0}),[v,hm(v)]):null}).filter(g=>g!=null);l(p.length?new Map(p):null),s.current=n}return()=>{f(n),f(u)};function f(p){p.forEach(g=>{const v=kh(g);v==null||v.removeEventListener("scroll",c)})}},[c,n]),m.useMemo(()=>n.length?a?Array.from(a.values()).reduce((u,f)=>Us(u,f),Ma):vS(n):Ma,[n,a])}function Ib(n,a){a===void 0&&(a=[]);const l=m.useRef(null);return m.useEffect(()=>{l.current=null},a),m.useEffect(()=>{const s=n!==Ma;s&&!l.current&&(l.current=n),!s&&l.current&&(l.current=null)},[n]),l.current?ni(n,l.current):Ma}function _k(n){m.useEffect(()=>{if(!Fu)return;const a=n.map(l=>{let{sensor:s}=l;return s.setup==null?void 0:s.setup()});return()=>{for(const l of a)l==null||l()}},n.map(a=>{let{sensor:l}=a;return l}))}function kk(n,a){return m.useMemo(()=>n.reduce((l,s)=>{let{eventName:c,handler:u}=s;return l[c]=f=>{u(f,a)},l},{}),[n,a])}function bS(n){return m.useMemo(()=>n?rk(n):null,[n])}const Pb=[];function zk(n,a){a===void 0&&(a=Qs);const[l]=n,s=bS(l?In(l):null),[c,u]=m.useState(Pb);function f(){u(()=>n.length?n.map(g=>pS(g)?s:new Mp(a(g),g)):Pb)}const p=Xu({callback:f});return Va(()=>{p==null||p.disconnect(),f(),n.forEach(g=>p==null?void 0:p.observe(g))},[n]),c}function Lk(n){if(!n)return null;if(n.children.length>1)return n;const a=n.children[0];return gi(a)?a:n}function Uk(n){let{measure:a}=n;const[l,s]=m.useState(null),c=m.useCallback(v=>{for(const{target:x}of v)if(gi(x)){s(y=>{const b=a(x);return y?{...y,width:b.width,height:b.height}:b});break}},[a]),u=Xu({callback:c}),f=m.useCallback(v=>{const x=Lk(v);u==null||u.disconnect(),x&&(u==null||u.observe(x)),s(x?a(x):null)},[a,u]),[p,g]=uu(f);return m.useMemo(()=>({nodeRef:p,rect:l,setRef:g}),[l,p,g])}const Bk=[{sensor:Op,options:{}},{sensor:Ap,options:{}}],Hk={current:{}},eu={draggable:{measure:_b},droppable:{measure:_b,strategy:ai.WhileDragging,frequency:pm.Optimized},dragOverlay:{measure:Qs}};class Qo extends Map{get(a){var l;return a!=null&&(l=super.get(a))!=null?l:void 0}toArray(){return Array.from(this.values())}getEnabled(){return this.toArray().filter(a=>{let{disabled:l}=a;return!l})}getNodeFor(a){var l,s;return(l=(s=this.get(a))==null?void 0:s.node.current)!=null?l:void 0}}const Ik={activatorEvent:null,active:null,activeNode:null,activeNodeRect:null,collisions:null,containerNodeRect:null,draggableNodes:new Map,droppableRects:new Map,droppableContainers:new Qo,over:null,dragOverlay:{nodeRef:{current:null},rect:null,setRef:fu},scrollableAncestors:[],scrollableAncestorRects:[],measuringConfiguration:eu,measureDroppableContainers:fu,windowRect:null,measuringScheduled:!1},Pk={activatorEvent:null,activators:[],active:null,activeNodeRect:null,ariaDescribedById:{draggable:""},dispatch:fu,draggableNodes:new Map,over:null,measureDroppableContainers:fu},Qu=m.createContext(Pk),wS=m.createContext(Ik);function qk(){return{draggable:{active:null,initialCoordinates:{x:0,y:0},nodes:new Map,translate:{x:0,y:0}},droppable:{containers:new Qo}}}function Vk(n,a){switch(a.type){case Zt.DragStart:return{...n,draggable:{...n.draggable,initialCoordinates:a.initialCoordinates,active:a.active}};case Zt.DragMove:return n.draggable.active==null?n:{...n,draggable:{...n.draggable,translate:{x:a.coordinates.x-n.draggable.initialCoordinates.x,y:a.coordinates.y-n.draggable.initialCoordinates.y}}};case Zt.DragEnd:case Zt.DragCancel:return{...n,draggable:{...n.draggable,active:null,initialCoordinates:{x:0,y:0},translate:{x:0,y:0}}};case Zt.RegisterDroppable:{const{element:l}=a,{id:s}=l,c=new Qo(n.droppable.containers);return c.set(s,l),{...n,droppable:{...n.droppable,containers:c}}}case Zt.SetDroppableDisabled:{const{id:l,key:s,disabled:c}=a,u=n.droppable.containers.get(l);if(!u||s!==u.key)return n;const f=new Qo(n.droppable.containers);return f.set(l,{...u,disabled:c}),{...n,droppable:{...n.droppable,containers:f}}}case Zt.UnregisterDroppable:{const{id:l,key:s}=a,c=n.droppable.containers.get(l);if(!c||s!==c.key)return n;const u=new Qo(n.droppable.containers);return u.delete(l),{...n,droppable:{...n.droppable,containers:u}}}default:return n}}function $k(n){let{disabled:a}=n;const{active:l,activatorEvent:s,draggableNodes:c}=m.useContext(Qu),u=dm(s),f=dm(l==null?void 0:l.id);return m.useEffect(()=>{if(!a&&!s&&u&&f!=null){if(!Tp(u)||document.activeElement===u.target)return;const p=c.get(f);if(!p)return;const{activatorNode:g,node:v}=p;if(!g.current&&!v.current)return;requestAnimationFrame(()=>{for(const x of[g.current,v.current]){if(!x)continue;const y=L_(x);if(y){y.focus();break}}})}},[s,a,c,f,u]),null}function Yk(n,a){let{transform:l,...s}=a;return n!=null&&n.length?n.reduce((c,u)=>u({transform:c,...s}),l):l}function Gk(n){return m.useMemo(()=>({draggable:{...eu.draggable,...n==null?void 0:n.draggable},droppable:{...eu.droppable,...n==null?void 0:n.droppable},dragOverlay:{...eu.dragOverlay,...n==null?void 0:n.dragOverlay}}),[n==null?void 0:n.draggable,n==null?void 0:n.droppable,n==null?void 0:n.dragOverlay])}function Fk(n){let{activeNode:a,measure:l,initialRect:s,config:c=!0}=n;const u=m.useRef(!1),{x:f,y:p}=typeof c=="boolean"?{x:c,y:c}:c;Va(()=>{if(!f&&!p||!a){u.current=!1;return}if(u.current||!s)return;const v=a==null?void 0:a.node.current;if(!v||v.isConnected===!1)return;const x=l(v),y=dS(x,s);if(f||(y.x=0),p||(y.y=0),u.current=!0,Math.abs(y.x)>0||Math.abs(y.y)>0){const b=fS(v);b&&b.scrollBy({top:y.y,left:y.x})}},[a,f,p,s,l])}const SS=m.createContext({...Ma,scaleX:1,scaleY:1});var rl;(function(n){n[n.Uninitialized=0]="Uninitialized",n[n.Initializing=1]="Initializing",n[n.Initialized=2]="Initialized"})(rl||(rl={}));const Kk=m.memo(function(a){var l,s,c,u;let{id:f,accessibility:p,autoScroll:g=!0,children:v,sensors:x=Bk,collisionDetection:y=Z_,measuring:b,modifiers:w,...E}=a;const j=m.useReducer(Vk,void 0,qk),[C,R]=j,[M,T]=q_(),[D,_]=m.useState(rl.Uninitialized),A=D===rl.Initialized,{draggable:{active:U,nodes:O,translate:q},droppable:{containers:K}}=C,te=U!=null?O.get(U):null,G=m.useRef({initial:null,translated:null}),ie=m.useMemo(()=>{var Ct;return U!=null?{id:U,data:(Ct=te==null?void 0:te.data)!=null?Ct:Hk,rect:G}:null},[U,te]),ce=m.useRef(null),[le,k]=m.useState(null),[H,Q]=m.useState(null),J=ti(E,Object.values(E)),ee=xi("DndDescribedBy",f),z=m.useMemo(()=>K.getEnabled(),[K]),I=Gk(b),{droppableRects:X,measureDroppableContainers:re,measuringScheduled:fe}=Rk(z,{dragging:A,dependencies:[q.x,q.y],config:I.droppable}),ve=Ck(O,U),V=m.useMemo(()=>H?fm(H):null,[H]),oe=Tr(),de=Nk(ve,I.draggable.measure);Fk({activeNode:U!=null?O.get(U):null,config:oe.layoutShiftCompensation,initialRect:de,measure:I.draggable.measure});const me=Bb(ve,I.draggable.measure,de),xe=Bb(ve?ve.parentElement:null),we=m.useRef({activatorEvent:null,active:null,activeNode:ve,collisionRect:null,collisions:null,droppableRects:X,draggableNodes:O,draggingNode:null,draggingNodeRect:null,droppableContainers:K,over:null,scrollableAncestors:[],scrollAdjustedTranslate:null}),Me=K.getNodeFor((l=we.current.over)==null?void 0:l.id),Ye=Uk({measure:I.dragOverlay.measure}),Qe=(s=Ye.nodeRef.current)!=null?s:ve,st=A?(c=Ye.rect)!=null?c:me:null,Kt=!!(Ye.nodeRef.current&&Ye.rect),ot=Ak(Kt?null:me),Lt=bS(Qe?In(Qe):null),Ot=Dk(A?Me??ve:null),It=zk(Ot),en=Yk(w,{transform:{x:q.x-ot.x,y:q.y-ot.y,scaleX:1,scaleY:1},activatorEvent:H,active:ie,activeNodeRect:me,containerNodeRect:xe,draggingNodeRect:st,over:we.current.over,overlayNodeRect:Ye.rect,scrollableAncestors:Ot,scrollableAncestorRects:It,windowRect:Lt}),Pt=V?Us(V,q):null,xt=Ok(Ot),on=Ib(xt),St=Ib(xt,[me]),jt=Us(en,on),tn=st?ek(st,en):null,se=ie&&tn?y({active:ie,collisionRect:tn,droppableRects:X,droppableContainers:z,pointerCoordinates:Pt}):null,qe=uS(se,"id"),[it,Cn]=m.useState(null),cn=Kt?en:Us(en,St),yt=J_(cn,(u=it==null?void 0:it.rect)!=null?u:null,me),vn=m.useRef(null),_t=m.useCallback((Ct,lt)=>{let{sensor:qt,options:Re}=lt;if(ce.current==null)return;const ke=O.get(ce.current);if(!ke)return;const Le=Ct.nativeEvent,bt=new qt({active:ce.current,activeNode:ke,event:Le,options:Re,context:we,onAbort(dt){if(!O.get(dt))return;const{onDragAbort:Et}=J.current,Ut={id:dt};Et==null||Et(Ut),M({type:"onDragAbort",event:Ut})},onPending(dt,Xt,Et,Ut){if(!O.get(dt))return;const{onDragPending:Ka}=J.current,xa={id:dt,constraint:Xt,initialCoordinates:Et,offset:Ut};Ka==null||Ka(xa),M({type:"onDragPending",event:xa})},onStart(dt){const Xt=ce.current;if(Xt==null)return;const Et=O.get(Xt);if(!Et)return;const{onDragStart:Ut}=J.current,Fa={activatorEvent:Le,active:{id:Xt,data:Et.data,rect:G}};Ca.unstable_batchedUpdates(()=>{Ut==null||Ut(Fa),_(rl.Initializing),R({type:Zt.DragStart,initialCoordinates:dt,active:Xt}),M({type:"onDragStart",event:Fa}),k(vn.current),Q(Le)})},onMove(dt){R({type:Zt.DragMove,coordinates:dt})},onEnd:Mt(Zt.DragEnd),onCancel:Mt(Zt.DragCancel)});vn.current=bt;function Mt(dt){return async function(){const{active:Et,collisions:Ut,over:Fa,scrollAdjustedTranslate:Ka}=we.current;let xa=null;if(Et&&Ka){const{cancelDrop:Mr}=J.current;xa={activatorEvent:Le,active:Et,collisions:Ut,delta:Ka,over:Fa},dt===Zt.DragEnd&&typeof Mr=="function"&&await Promise.resolve(Mr(xa))&&(dt=Zt.DragCancel)}ce.current=null,Ca.unstable_batchedUpdates(()=>{R({type:dt}),_(rl.Uninitialized),Cn(null),k(null),Q(null),vn.current=null;const Mr=dt===Zt.DragEnd?"onDragEnd":"onDragCancel";if(xa){const Zn=J.current[Mr];Zn==null||Zn(xa),M({type:Mr,event:xa})}})}}},[O]),Js=m.useCallback((Ct,lt)=>(qt,Re)=>{const ke=qt.nativeEvent,Le=O.get(Re);if(ce.current!==null||!Le||ke.dndKit||ke.defaultPrevented)return;const bt={active:Le};Ct(qt,lt.options,bt)===!0&&(ke.dndKit={capturedBy:lt.sensor},ce.current=Re,_t(qt,lt))},[O,_t]),Pl=Ek(x,Js);_k(x),Va(()=>{me&&D===rl.Initializing&&_(rl.Initialized)},[me,D]),m.useEffect(()=>{const{onDragMove:Ct}=J.current,{active:lt,activatorEvent:qt,collisions:Re,over:ke}=we.current;if(!lt||!qt)return;const Le={active:lt,activatorEvent:qt,collisions:Re,delta:{x:jt.x,y:jt.y},over:ke};Ca.unstable_batchedUpdates(()=>{Ct==null||Ct(Le),M({type:"onDragMove",event:Le})})},[jt.x,jt.y]),m.useEffect(()=>{const{active:Ct,activatorEvent:lt,collisions:qt,droppableContainers:Re,scrollAdjustedTranslate:ke}=we.current;if(!Ct||ce.current==null||!lt||!ke)return;const{onDragOver:Le}=J.current,bt=Re.get(qe),Mt=bt&&bt.rect.current?{id:bt.id,rect:bt.rect.current,data:bt.data,disabled:bt.disabled}:null,dt={active:Ct,activatorEvent:lt,collisions:qt,delta:{x:ke.x,y:ke.y},over:Mt};Ca.unstable_batchedUpdates(()=>{Cn(Mt),Le==null||Le(dt),M({type:"onDragOver",event:dt})})},[qe]),Va(()=>{we.current={activatorEvent:H,active:ie,activeNode:ve,collisionRect:tn,collisions:se,droppableRects:X,draggableNodes:O,draggingNode:Qe,draggingNodeRect:st,droppableContainers:K,over:it,scrollableAncestors:Ot,scrollAdjustedTranslate:jt},G.current={initial:st,translated:tn}},[ie,ve,se,tn,O,Qe,st,X,K,it,Ot,jt]),wk({...oe,delta:q,draggingRect:tn,pointerCoordinates:Pt,scrollableAncestors:Ot,scrollableAncestorRects:It});const ql=m.useMemo(()=>({active:ie,activeNode:ve,activeNodeRect:me,activatorEvent:H,collisions:se,containerNodeRect:xe,dragOverlay:Ye,draggableNodes:O,droppableContainers:K,droppableRects:X,over:it,measureDroppableContainers:re,scrollableAncestors:Ot,scrollableAncestorRects:It,measuringConfiguration:I,measuringScheduled:fe,windowRect:Lt}),[ie,ve,me,H,se,xe,Ye,O,K,X,it,re,Ot,It,I,fe,Lt]),Ga=m.useMemo(()=>({activatorEvent:H,activators:Pl,active:ie,activeNodeRect:me,ariaDescribedById:{draggable:ee},dispatch:R,draggableNodes:O,over:it,measureDroppableContainers:re}),[H,Pl,ie,me,R,ee,O,it,re]);return ue.createElement(oS.Provider,{value:T},ue.createElement(Qu.Provider,{value:Ga},ue.createElement(wS.Provider,{value:ql},ue.createElement(SS.Provider,{value:yt},v)),ue.createElement($k,{disabled:(p==null?void 0:p.restoreFocus)===!1})),ue.createElement(Y_,{...p,hiddenTextDescribedById:ee}));function Tr(){const Ct=(le==null?void 0:le.autoScrollEnabled)===!1,lt=typeof g=="object"?g.enabled===!1:g===!1,qt=A&&!Ct&&!lt;return typeof g=="object"?{...g,enabled:qt}:{enabled:qt}}}),Xk=m.createContext(null),qb="button",Qk="Draggable";function Zk(n){let{id:a,data:l,disabled:s=!1,attributes:c}=n;const u=xi(Qk),{activators:f,activatorEvent:p,active:g,activeNodeRect:v,ariaDescribedById:x,draggableNodes:y,over:b}=m.useContext(Qu),{role:w=qb,roleDescription:E="draggable",tabIndex:j=0}=c??{},C=(g==null?void 0:g.id)===a,R=m.useContext(C?SS:Xk),[M,T]=uu(),[D,_]=uu(),A=kk(f,a),U=ti(l);Va(()=>(y.set(a,{id:a,key:u,node:M,activatorNode:D,data:U}),()=>{const q=y.get(a);q&&q.key===u&&y.delete(a)}),[y,a]);const O=m.useMemo(()=>({role:w,tabIndex:j,"aria-disabled":s,"aria-pressed":C&&w===qb?!0:void 0,"aria-roledescription":E,"aria-describedby":x.draggable}),[s,w,j,C,E,x.draggable]);return{active:g,activatorEvent:p,activeNodeRect:v,attributes:O,isDragging:C,listeners:s?void 0:A,node:M,over:b,setNodeRef:T,setActivatorNodeRef:_,transform:R}}function Jk(){return m.useContext(wS)}const Wk="Droppable",e3={timeout:25};function t3(n){let{data:a,disabled:l=!1,id:s,resizeObserverConfig:c}=n;const u=xi(Wk),{active:f,dispatch:p,over:g,measureDroppableContainers:v}=m.useContext(Qu),x=m.useRef({disabled:l}),y=m.useRef(!1),b=m.useRef(null),w=m.useRef(null),{disabled:E,updateMeasurementsFor:j,timeout:C}={...e3,...c},R=ti(j??s),M=m.useCallback(()=>{if(!y.current){y.current=!0;return}w.current!=null&&clearTimeout(w.current),w.current=setTimeout(()=>{v(Array.isArray(R.current)?R.current:[R.current]),w.current=null},C)},[C]),T=Xu({callback:M,disabled:E||!f}),D=m.useCallback((O,q)=>{T&&(q&&(T.unobserve(q),y.current=!1),O&&T.observe(O))},[T]),[_,A]=uu(D),U=ti(a);return m.useEffect(()=>{!T||!_.current||(T.disconnect(),y.current=!1,T.observe(_.current))},[_,T]),m.useEffect(()=>(p({type:Zt.RegisterDroppable,element:{id:s,key:u,disabled:l,node:_,rect:b,data:U}}),()=>p({type:Zt.UnregisterDroppable,key:u,id:s})),[s]),m.useEffect(()=>{l!==x.current.disabled&&(p({type:Zt.SetDroppableDisabled,id:s,key:u,disabled:l}),x.current.disabled=l)},[s,u,l,p]),{active:f,rect:b,isOver:(g==null?void 0:g.id)===s,node:_,over:g,setNodeRef:A}}function n3(n,a,l){const s={...n};return a.top+n.y<=l.top?s.y=l.top-a.top:a.bottom+n.y>=l.top+l.height&&(s.y=l.top+l.height-a.bottom),a.left+n.x<=l.left?s.x=l.left-a.left:a.right+n.x>=l.left+l.width&&(s.x=l.left+l.width-a.right),s}const a3=n=>{let{containerNodeRect:a,draggingNodeRect:l,transform:s}=n;return!l||!a?s:n3(s,l,a)},r3=n=>{let{transform:a}=n;return{...a,x:0}};function _p(n,a,l){const s=n.slice();return s.splice(l<0?s.length+l:l,0,s.splice(a,1)[0]),s}function l3(n,a){return n.reduce((l,s,c)=>{const u=a.get(s);return u&&(l[c]=u),l},Array(n.length))}function Pc(n){return n!==null&&n>=0}function s3(n,a){if(n===a)return!0;if(n.length!==a.length)return!1;for(let l=0;l<n.length;l++)if(n[l]!==a[l])return!1;return!0}function o3(n){return typeof n=="boolean"?{draggable:n,droppable:n}:n}const jS=n=>{let{rects:a,activeIndex:l,overIndex:s,index:c}=n;const u=_p(a,s,l),f=a[c],p=u[c];return!p||!f?null:{x:p.left-f.left,y:p.top-f.top,scaleX:p.width/f.width,scaleY:p.height/f.height}},qc={scaleX:1,scaleY:1},i3=n=>{var a;let{activeIndex:l,activeNodeRect:s,index:c,rects:u,overIndex:f}=n;const p=(a=u[l])!=null?a:s;if(!p)return null;if(c===l){const v=u[f];return v?{x:0,y:l<f?v.top+v.height-(p.top+p.height):v.top-p.top,...qc}:null}const g=c3(u,c,l);return c>l&&c<=f?{x:0,y:-p.height-g,...qc}:c<l&&c>=f?{x:0,y:p.height+g,...qc}:{x:0,y:0,...qc}};function c3(n,a,l){const s=n[a],c=n[a-1],u=n[a+1];return s?l<a?c?s.top-(c.top+c.height):u?u.top-(s.top+s.height):0:u?u.top-(s.top+s.height):c?s.top-(c.top+c.height):0:0}const CS="Sortable",ES=ue.createContext({activeIndex:-1,containerId:CS,disableTransforms:!1,items:[],overIndex:-1,useDragOverlay:!1,sortedRects:[],strategy:jS,disabled:{draggable:!1,droppable:!1}});function u3(n){let{children:a,id:l,items:s,strategy:c=jS,disabled:u=!1}=n;const{active:f,dragOverlay:p,droppableRects:g,over:v,measureDroppableContainers:x}=Jk(),y=xi(CS,l),b=p.rect!==null,w=m.useMemo(()=>s.map(A=>typeof A=="object"&&"id"in A?A.id:A),[s]),E=f!=null,j=f?w.indexOf(f.id):-1,C=v?w.indexOf(v.id):-1,R=m.useRef(w),M=!s3(w,R.current),T=C!==-1&&j===-1||M,D=o3(u);Va(()=>{M&&E&&x(w)},[M,w,E,x]),m.useEffect(()=>{R.current=w},[w]);const _=m.useMemo(()=>({activeIndex:j,containerId:y,disabled:D,disableTransforms:T,items:w,overIndex:C,useDragOverlay:b,sortedRects:l3(w,g),strategy:c}),[j,y,D.draggable,D.droppable,T,w,C,g,b,c]);return ue.createElement(ES.Provider,{value:_},a)}const d3=n=>{let{id:a,items:l,activeIndex:s,overIndex:c}=n;return _p(l,s,c).indexOf(a)},f3=n=>{let{containerId:a,isSorting:l,wasDragging:s,index:c,items:u,newIndex:f,previousItems:p,previousContainerId:g,transition:v}=n;return!v||!s||p!==u&&c===f?!1:l?!0:f!==c&&a===g},h3={duration:200,easing:"ease"},RS="transform",m3=du.Transition.toString({property:RS,duration:0,easing:"linear"}),p3={roleDescription:"sortable"};function g3(n){let{disabled:a,index:l,node:s,rect:c}=n;const[u,f]=m.useState(null),p=m.useRef(l);return Va(()=>{if(!a&&l!==p.current&&s.current){const g=c.current;if(g){const v=Qs(s.current,{ignoreTransform:!0}),x={x:g.left-v.left,y:g.top-v.top,scaleX:g.width/v.width,scaleY:g.height/v.height};(x.x||x.y)&&f(x)}}l!==p.current&&(p.current=l)},[a,l,s,c]),m.useEffect(()=>{u&&f(null)},[u]),u}function v3(n){let{animateLayoutChanges:a=f3,attributes:l,disabled:s,data:c,getNewIndex:u=d3,id:f,strategy:p,resizeObserverConfig:g,transition:v=h3}=n;const{items:x,containerId:y,activeIndex:b,disabled:w,disableTransforms:E,sortedRects:j,overIndex:C,useDragOverlay:R,strategy:M}=m.useContext(ES),T=x3(s,w),D=x.indexOf(f),_=m.useMemo(()=>({sortable:{containerId:y,index:D,items:x},...c}),[y,c,D,x]),A=m.useMemo(()=>x.slice(x.indexOf(f)),[x,f]),{rect:U,node:O,isOver:q,setNodeRef:K}=t3({id:f,data:_,disabled:T.droppable,resizeObserverConfig:{updateMeasurementsFor:A,...g}}),{active:te,activatorEvent:G,activeNodeRect:ie,attributes:ce,setNodeRef:le,listeners:k,isDragging:H,over:Q,setActivatorNodeRef:J,transform:ee}=Zk({id:f,data:_,attributes:{...p3,...l},disabled:T.draggable}),z=O_(K,le),I=!!te,X=I&&!E&&Pc(b)&&Pc(C),re=!R&&H,fe=re&&X?ee:null,V=X?fe??(p??M)({rects:j,activeNodeRect:ie,activeIndex:b,overIndex:C,index:D}):null,oe=Pc(b)&&Pc(C)?u({id:f,items:x,activeIndex:b,overIndex:C}):D,de=te==null?void 0:te.id,me=m.useRef({activeId:de,items:x,newIndex:oe,containerId:y}),xe=x!==me.current.items,we=a({active:te,containerId:y,isDragging:H,isSorting:I,id:f,index:D,items:x,newIndex:me.current.newIndex,previousItems:me.current.items,previousContainerId:me.current.containerId,transition:v,wasDragging:me.current.activeId!=null}),Me=g3({disabled:!we,index:D,node:O,rect:U});return m.useEffect(()=>{I&&me.current.newIndex!==oe&&(me.current.newIndex=oe),y!==me.current.containerId&&(me.current.containerId=y),x!==me.current.items&&(me.current.items=x)},[I,oe,y,x]),m.useEffect(()=>{if(de===me.current.activeId)return;if(de!=null&&me.current.activeId==null){me.current.activeId=de;return}const Qe=setTimeout(()=>{me.current.activeId=de},50);return()=>clearTimeout(Qe)},[de]),{active:te,activeIndex:b,attributes:ce,data:_,rect:U,index:D,newIndex:oe,items:x,isOver:q,isSorting:I,isDragging:H,listeners:k,node:O,overIndex:C,over:Q,setNodeRef:z,setActivatorNodeRef:J,setDroppableNodeRef:K,setDraggableNodeRef:le,transform:Me??V,transition:Ye()};function Ye(){if(Me||xe&&me.current.newIndex===D)return m3;if(!(re&&!Tp(G)||!v)&&(I||we))return du.Transition.toString({...v,property:RS})}}function x3(n,a){var l,s;return typeof n=="boolean"?{draggable:n,droppable:!1}:{draggable:(l=n==null?void 0:n.draggable)!=null?l:a.draggable,droppable:(s=n==null?void 0:n.droppable)!=null?s:a.droppable}}function mu(n){if(!n)return!1;const a=n.data.current;return!!(a&&"sortable"in a&&typeof a.sortable=="object"&&"containerId"in a.sortable&&"items"in a.sortable&&"index"in a.sortable)}const y3=[Fe.Down,Fe.Right,Fe.Up,Fe.Left],b3=(n,a)=>{let{context:{active:l,collisionRect:s,droppableRects:c,droppableContainers:u,over:f,scrollableAncestors:p}}=a;if(y3.includes(n.code)){if(n.preventDefault(),!l||!s)return;const g=[];u.getEnabled().forEach(y=>{if(!y||y!=null&&y.disabled)return;const b=c.get(y.id);if(b)switch(n.code){case Fe.Down:s.top<b.top&&g.push(y);break;case Fe.Up:s.top>b.top&&g.push(y);break;case Fe.Left:s.left>b.left&&g.push(y);break;case Fe.Right:s.left<b.left&&g.push(y);break}});const v=X_({collisionRect:s,droppableRects:c,droppableContainers:g});let x=uS(v,"id");if(x===(f==null?void 0:f.id)&&v.length>1&&(x=v[1].id),x!=null){const y=u.get(l.id),b=u.get(x),w=b?c.get(b.id):null,E=b==null?void 0:b.node.current;if(E&&w&&y&&b){const C=Ku(E).some((A,U)=>p[U]!==A),R=NS(y,b),M=w3(y,b),T=C||!R?{x:0,y:0}:{x:M?s.width-w.width:0,y:M?s.height-w.height:0},D={x:w.left,y:w.top};return T.x&&T.y?D:ni(D,T)}}}};function NS(n,a){return!mu(n)||!mu(a)?!1:n.data.current.sortable.containerId===a.data.current.sortable.containerId}function w3(n,a){return!mu(n)||!mu(a)||!NS(n,a)?!1:n.data.current.sortable.index<a.data.current.sortable.index}const Uh={maxTotalAttempts:3,fallbackOnConnection:!0,fallbackOnConnectTimeout:!0,fallbackOnFirstTokenTimeout:!0,fallbackOn408:!0,fallbackOn429:!0,fallbackOn5xx:!0},S3={member_disabled:"member disabled",model_missing:"model missing",provider_disabled:"provider disabled",provider_down:"provider down",model_disabled:"model disabled",upstream_unavailable:"upstream unavailable",circuit_open:"circuit open",chat_capability_unavailable:"chat capability unavailable"},pu=n=>n.map((a,l)=>({...a,position:l}));function j3(){const[n,a]=m.useState([]),[l,s]=m.useState([]),[c,u]=m.useState(!1),[f,p]=m.useState(!1),[g,v]=m.useState(null),[x,y]=m.useState(!1),[b,w]=m.useState(!1),[E,j]=m.useState(null),[C,R]=m.useState(null),[M,T]=m.useState({name:"",slug:"",enabled:!0,...Uh,members:[]}),[D,_]=m.useState({name:"",slug:"",enabled:!0,...Uh,members:[]}),[A,U]=m.useState(null),O=async()=>{const[k,H]=await Promise.all([Ce.get("/api/admin/combos"),Ce.get("/api/admin/models")]);a(k.combos),s(H.models)};m.useEffect(()=>{O()},[]);const q=async k=>{j(k.id);try{R(await Ce.post("/api/admin/combos/"+k.id+"/test"))}catch(H){ge.error(H.message)}finally{j(null)}},K=async()=>{if(M.members.length===0){ge.error("Add at least one member");return}y(!0);try{await Ce.post("/api/admin/combos",{name:M.name,slug:M.slug.trim()||void 0,enabled:M.enabled,...M,members:M.members}),ge.success("Combo created"),u(!1),T({name:"",slug:"",enabled:!0,...Uh,members:[]}),O()}catch(k){ge.error(k.message)}finally{y(!1)}},te=async k=>{try{const Q=(await Ce.get(`/api/admin/combos/${k.id}`)).combo;v(Q.id),_({name:Q.name,slug:Q.publicModelId.startsWith("combo/")?Q.slug:"",enabled:Q.enabled,maxTotalAttempts:Q.maxTotalAttempts,fallbackOnConnection:Q.fallbackOnConnection,fallbackOnConnectTimeout:Q.fallbackOnConnectTimeout,fallbackOnFirstTokenTimeout:Q.fallbackOnFirstTokenTimeout,fallbackOn408:Q.fallbackOn408,fallbackOn429:Q.fallbackOn429,fallbackOn5xx:Q.fallbackOn5xx,members:Q.members.map(J=>({modelId:J.modelId,position:J.position,enabled:J.enabled}))}),p(!0)}catch(H){ge.error(H.message)}},G=async()=>{if(g){if(D.members.length===0){ge.error("Add at least one member");return}w(!0);try{await Ce.patch("/api/admin/combos",{id:g,name:D.name,slug:D.slug.trim()||void 0,enabled:D.enabled,...D,members:D.members}),ge.success("Combo updated"),p(!1),v(null),O()}catch(k){ge.error(k.message)}finally{w(!1)}}},ie=k=>{T(H=>({...H,members:pu([...H.members,{modelId:k,position:H.members.length,enabled:!0}])}))},ce=k=>{_(H=>({...H,members:pu([...H.members,{modelId:k,position:H.members.length,enabled:!0}])}))},le=async k=>{try{await Ce.del(`/api/admin/combos/${k}`),ge.success("Combo removed"),U(null),O()}catch(H){ge.error(H.message)}};return o.jsxs("div",{children:[o.jsx(Ya,{title:"Combos",description:"Virtual models combining physical models",actions:o.jsxs(kn,{open:c,onOpenChange:u,children:[o.jsx(mi,{asChild:!0,children:o.jsxs(he,{children:[o.jsx(wu,{className:"mr-1 h-4 w-4"})," New combo"]})}),o.jsxs(wn,{className:"max-h-[calc(100vh-2rem)] max-w-2xl grid-rows-[auto_minmax(0,1fr)_auto] overflow-hidden",children:[o.jsx(Sn,{children:o.jsx(jn,{children:"New combo"})}),o.jsxs("div",{className:"min-h-0 space-y-3 overflow-y-auto pr-1",children:[o.jsxs("div",{children:[o.jsx(Se,{children:"Name"}),o.jsx(De,{value:M.name,onChange:k=>T({...M,name:k.target.value})})]}),o.jsxs("div",{children:[o.jsx(Se,{children:"Slug (optional — empty uses the name as the model ID)"}),o.jsx(De,{value:M.slug,onChange:k=>T({...M,slug:k.target.value}),placeholder:"empty → gpt-5.5 · set → combo/gpt-5.5"})]}),o.jsxs("div",{className:"flex items-center gap-2",children:[o.jsx(Ta,{checked:M.enabled,onCheckedChange:k=>T({...M,enabled:k})}),o.jsx(Se,{children:"Enabled"})]}),o.jsx(Vb,{value:M,onChange:k=>T(H=>({...H,...k}))}),o.jsxs("div",{children:[o.jsx(Se,{children:"Members — priority order · drag to reorder"}),o.jsx(Gb,{models:l,addedIds:M.members.map(k=>k.modelId),onAdd:ie}),o.jsx($b,{members:M.members,modelFor:k=>l.find(H=>H.id===k.modelId)??null}),o.jsx(Yb,{className:"mt-2",members:M.members,label:k=>{var H;return((H=l.find(Q=>Q.id===k.modelId))==null?void 0:H.publicModelId)??k.modelId},modelFor:k=>l.find(H=>H.id===k.modelId)??null,onChange:k=>T(H=>({...H,members:k}))})]})]}),o.jsxs(zn,{children:[o.jsx(he,{variant:"outline",onClick:()=>u(!1),children:"Cancel"}),o.jsx(he,{disabled:!M.name||x,onClick:K,children:x?"Creating…":"Create"})]})]})]})}),o.jsxs(tt,{children:[o.jsxs(nt,{children:[o.jsx(at,{className:"text-base",children:"All combos"}),o.jsxs(bn,{children:[n.length," total"]})]}),o.jsx(rt,{children:o.jsxs(pa,{children:[o.jsx(ga,{children:o.jsxs(We,{children:[o.jsx(be,{children:"Public ID"}),o.jsx(be,{children:"Members"}),o.jsx(be,{children:"Status"}),o.jsx(be,{children:"Enabled"}),o.jsx(be,{})]})}),o.jsxs(va,{children:[n.length===0&&o.jsx(We,{children:o.jsx(pe,{colSpan:5,className:"text-center text-muted-foreground",children:"No combos yet."})}),n.map(k=>o.jsxs(We,{children:[o.jsx(pe,{className:"font-mono text-xs",children:k.publicModelId}),o.jsx(pe,{children:k.memberCount}),o.jsxs(pe,{children:[o.jsxs(Xe,{variant:k.status==="ready"?"success":k.status==="disabled"?"secondary":"destructive",children:[k.healthyMemberCount,"/",k.memberCount," ready"]}),k.capabilityWarnings.length>0&&o.jsx("div",{className:"text-xs text-amber-600",children:"Capability metadata differs"}),k.status==="unavailable"&&k.unavailableReasons.length>0&&o.jsx("div",{className:"text-xs text-muted-foreground",children:k.unavailableReasons.map(H=>S3[H]??H).join(", ")})]}),o.jsx(pe,{children:k.enabled?"Yes":"No"}),o.jsx(pe,{className:"text-right",children:o.jsxs("div",{className:"flex items-center justify-end gap-1",children:[o.jsxs(he,{size:"sm",variant:"outline",title:"Sends a real non-streaming inference request",onClick:()=>void q(k),disabled:E===k.id,children:[E===k.id?o.jsx(_s,{className:"mr-1 h-3.5 w-3.5 animate-spin"}):o.jsx(D0,{className:"mr-1 h-3.5 w-3.5"})," Test"]}),o.jsxs(he,{size:"sm",variant:"outline",onClick:()=>void te(k),children:[o.jsx(wR,{className:"h-3.5 w-3.5"})," Sửa"]}),o.jsxs(he,{size:"sm",variant:"destructive",onClick:()=>U(k),children:[o.jsx(Su,{className:"h-3.5 w-3.5"})," Delete"]})]})})]},k.id))]})]})})]}),o.jsx(kn,{open:f,onOpenChange:p,children:o.jsxs(wn,{className:"max-h-[calc(100vh-2rem)] max-w-2xl grid-rows-[auto_minmax(0,1fr)_auto] overflow-hidden",children:[o.jsx(Sn,{children:o.jsx(jn,{children:"Edit combo"})}),o.jsxs("div",{className:"min-h-0 space-y-3 overflow-y-auto pr-1",children:[o.jsxs("div",{children:[o.jsx(Se,{children:"Name"}),o.jsx(De,{value:D.name,onChange:k=>_({...D,name:k.target.value})})]}),o.jsxs("div",{children:[o.jsx(Se,{children:"Slug (optional — leave empty to use the name as the model ID)"}),o.jsx(De,{value:D.slug,onChange:k=>_({...D,slug:k.target.value}),placeholder:"empty → gpt-5.5 · set → combo/gpt-5.5"})]}),o.jsxs("div",{className:"flex items-center gap-2",children:[o.jsx(Ta,{checked:D.enabled,onCheckedChange:k=>_({...D,enabled:k})}),o.jsx(Se,{children:"Enabled"})]}),o.jsx(Vb,{value:D,onChange:k=>_(H=>({...H,...k}))}),o.jsxs("div",{children:[o.jsx(Se,{children:"Members — priority order · drag to reorder"}),o.jsx(Gb,{models:l,addedIds:D.members.map(k=>k.modelId),onAdd:ce}),o.jsx($b,{members:D.members,modelFor:k=>l.find(H=>H.id===k.modelId)??null}),o.jsx(Yb,{className:"mt-2",members:D.members,label:k=>{var H;return((H=l.find(Q=>Q.id===k.modelId))==null?void 0:H.publicModelId)??k.modelId},modelFor:k=>l.find(H=>H.id===k.modelId)??null,onChange:k=>_(H=>({...H,members:k}))})]})]}),o.jsxs(zn,{children:[o.jsx(he,{variant:"outline",onClick:()=>p(!1),children:"Cancel"}),o.jsx(he,{disabled:!D.name||b,onClick:G,children:b?"Saving…":"Save"})]})]})}),o.jsx(kn,{open:C!==null,onOpenChange:k=>{k||R(null)},children:o.jsxs(wn,{className:"max-w-2xl",children:[o.jsxs(Sn,{children:[o.jsx(jn,{children:"Combo test result"}),o.jsx("p",{className:"text-sm text-muted-foreground",children:"Test sends a real non-streaming inference request through this combo."})]}),C&&o.jsx(C3,{result:C}),o.jsx(zn,{children:o.jsx(he,{onClick:()=>R(null),children:"Close"})})]})}),o.jsx(dp,{open:A!==null,onOpenChange:k=>{k||U(null)},children:o.jsxs(Iu,{children:[o.jsxs(fp,{children:[o.jsx(Pu,{children:"Delete combo?"}),o.jsx(qu,{children:"This removes the virtual model and its ordered fallback configuration. Request history is preserved."})]}),o.jsxs(hp,{children:[o.jsx($u,{children:"Cancel"}),o.jsx(Vu,{onClick:()=>A&&void le(A.id),children:"Delete"})]})]})})]})}function Vb({value:n,onChange:a}){const l=[["fallbackOnConnection","Connection failure"],["fallbackOnConnectTimeout","Connect timeout"],["fallbackOnFirstTokenTimeout","First-token timeout"],["fallbackOn408","HTTP 408"],["fallbackOn429","HTTP 429"],["fallbackOn5xx","HTTP 5xx"]];return o.jsxs("div",{className:"rounded border bg-muted/20 p-3",children:[o.jsx("div",{className:"mb-2 text-sm font-medium",children:"Fallback policy"}),o.jsxs("div",{className:"grid gap-3 sm:grid-cols-[10rem_1fr]",children:[o.jsxs("div",{children:[o.jsx(Se,{children:"Max total attempts"}),o.jsx(De,{type:"number",min:1,max:8,value:n.maxTotalAttempts,onChange:s=>a({maxTotalAttempts:Math.min(8,Math.max(1,Number(s.target.value)||1))})})]}),o.jsx("div",{className:"grid gap-2 sm:grid-cols-2",children:l.map(([s,c])=>o.jsxs("label",{className:"flex items-center gap-2 text-xs",children:[o.jsx(Ta,{checked:!!n[s],onCheckedChange:u=>a({[s]:u})}),o.jsx("span",{children:c})]},s))})]})]})}function $b({members:n,modelFor:a}){if(n.length===0)return null;const l=n.map(a).filter(c=>!!c),s=["chat","streaming","tools","structured_output","image_input","reasoning"].filter(c=>new Set(l.map(u=>u.capabilities[c]===!0?"yes":u.capabilities[c]===!1?"no":"unknown")).size>1);return o.jsxs("div",{className:"rounded border bg-muted/20 p-2 text-xs",children:[o.jsxs("div",{className:"mb-1 font-medium",children:["Route preview ",o.jsx("span",{className:"font-normal text-muted-foreground",children:"(first available member wins)"})]}),s.length>0&&o.jsxs("div",{className:"mb-2 flex items-center gap-1 text-amber-600",children:[o.jsx(_0,{className:"h-3.5 w-3.5"})," Members differ on: ",s.join(", ")]}),o.jsx("div",{className:"space-y-1",children:n.map((c,u)=>{const f=a(c);return o.jsxs("div",{className:"flex items-center gap-2 font-mono",children:[o.jsxs("span",{className:"w-4 text-muted-foreground",children:[u+1,"."]}),o.jsx("span",{children:(f==null?void 0:f.publicModelId)??c.modelId}),o.jsxs("span",{className:"text-muted-foreground",children:["→ ",(f==null?void 0:f.upstreamModelId)??"upstream model unknown"]})]},c.id??c.modelId)})})]})}function C3({result:n}){return o.jsxs("div",{className:"space-y-4",children:[o.jsxs("div",{className:"flex items-center justify-between rounded border p-3",children:[o.jsxs("div",{className:"flex items-center gap-2",children:[n.success?o.jsx(ci,{className:"h-4 w-4 text-emerald-600"}):o.jsx(_0,{className:"h-4 w-4 text-amber-600"}),o.jsx(Xe,{variant:n.success?"success":"warning",children:n.success?"Success":"Failed"})]}),o.jsxs("span",{className:"text-xs text-muted-foreground",children:[n.latencyMs," ms total"]})]}),o.jsxs("div",{children:[o.jsx("div",{className:"mb-1 text-sm font-medium",children:"Selected upstream"}),n.selectedModel?o.jsxs("div",{className:"rounded border bg-muted/20 p-2 font-mono text-xs",children:[n.selectedModel.publicModelId," → ",n.selectedModel.upstreamModelId,o.jsxs("span",{className:"ml-2 text-muted-foreground",children:["(",n.selectedModel.providerSlug,")"]})]}):o.jsx("p",{className:"text-sm text-muted-foreground",children:"No member completed successfully."})]}),o.jsxs("div",{children:[o.jsx("div",{className:"mb-1 text-sm font-medium",children:"Attempts"}),o.jsx("div",{className:"space-y-1",children:n.attempts.map((a,l)=>o.jsxs("div",{className:"flex items-center gap-2 rounded border p-2 text-xs",children:[o.jsxs("span",{className:"w-4 text-muted-foreground",children:[l+1,"."]}),o.jsxs("span",{className:"min-w-0 flex-1 font-mono",children:[a.publicModelId," → ",a.upstreamModelId]}),o.jsxs("span",{className:"text-muted-foreground",children:[a.latencyMs," ms"]}),o.jsx(Xe,{variant:a.success?"success":"warning",children:a.success?"Used":a.failureReason??"Skipped"})]},a.publicModelId+"-"+l))})]}),n.text&&o.jsx("pre",{className:"max-h-32 overflow-auto whitespace-pre-wrap rounded border bg-muted/20 p-2 text-xs",children:n.text})]})}function Yb({members:n,label:a,modelFor:l,onChange:s,className:c}){const u=G_(Ab(Op,{activationConstraint:{distance:4}}),Ab(Ap,{coordinateGetter:b3}));if(n.length===0)return o.jsx("p",{className:Ee("text-xs text-muted-foreground",c),children:"No members yet — add at least one."});const f=({active:p,over:g})=>{!g||p.id===g.id||s(pu(_p(n,Number(p.id),Number(g.id))))};return o.jsx(Kk,{sensors:u,collisionDetection:K_,modifiers:[r3,a3],onDragEnd:f,children:o.jsx(u3,{items:n.map((p,g)=>g),strategy:i3,children:o.jsx("div",{className:Ee("space-y-1",c),children:n.map((p,g)=>o.jsx(E3,{index:g,label:a(p),model:l(p),onRemove:()=>s(pu(n.filter((v,x)=>x!==g)))},p.id??p.modelId))})})})}function E3({index:n,label:a,model:l,onRemove:s}){const{attributes:c,listeners:u,setNodeRef:f,transform:p,transition:g,isDragging:v}=v3({id:n});return o.jsxs("div",{ref:f,style:{transform:p?`translate3d(${p.x}px, ${p.y}px, 0)`:void 0,transition:g},className:Ee("flex items-center gap-2 rounded border p-2 text-sm",v&&"relative z-10 bg-muted/60 shadow-sm"),children:[o.jsx("button",{type:"button",...c,...u,"aria-label":`Reorder ${a}`,title:"Drag to change priority",className:"cursor-grab touch-none rounded p-1 text-muted-foreground hover:bg-muted hover:text-foreground active:cursor-grabbing",children:o.jsx(fR,{className:"h-4 w-4"})}),o.jsx("span",{className:"w-5 text-xs tabular-nums text-muted-foreground",children:n+1}),o.jsxs("div",{className:"min-w-0 flex-1",children:[o.jsx("div",{className:"truncate font-mono text-xs",children:a}),o.jsxs("div",{className:"truncate text-[11px] text-muted-foreground",children:[(l==null?void 0:l.providerSlug)||"provider"," · upstream: ",(l==null?void 0:l.upstreamModelId)??"unknown"]})]}),o.jsx(Xe,{variant:l&&l.enabled&&l.providerEnabled&&l.providerHealth!=="down"&&l.providerHealth!=="circuit_open"&&!l.circuitOpen&&l.upstreamAvailable&&l.capabilities.chat!==!1?"success":"warning",children:l&&l.enabled&&l.providerEnabled&&l.providerHealth!=="down"&&l.providerHealth!=="circuit_open"&&!l.circuitOpen&&l.upstreamAvailable&&l.capabilities.chat!==!1?"Ready":"Unavailable"}),o.jsx(he,{size:"sm",variant:"outline",onClick:s,children:"Remove"})]})}function Gb({models:n,addedIds:a,onAdd:l}){const[s,c]=m.useState(""),f=(s?n.filter(p=>{const g=s.toLowerCase();return p.publicModelId.toLowerCase().includes(g)||p.displayName.toLowerCase().includes(g)}):n).filter(p=>!a.includes(p.id));return o.jsxs("div",{className:"space-y-1",children:[o.jsxs("div",{className:"relative",children:[o.jsx(O0,{className:"absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground"}),o.jsx(De,{className:"pl-8",placeholder:"Search models…",value:s,onChange:p=>c(p.target.value)}),s&&o.jsx("button",{className:"absolute right-2 top-2.5 text-muted-foreground hover:text-foreground",onClick:()=>c(""),children:o.jsx(ju,{className:"h-4 w-4"})})]}),f.length===0?o.jsx("p",{className:"text-xs text-muted-foreground",children:"No models match."}):o.jsx("div",{className:"max-h-40 space-y-1 overflow-auto rounded border p-1",children:f.map(p=>o.jsxs("div",{className:"flex items-center justify-between rounded p-1 text-sm hover:bg-accent",children:[o.jsx("span",{className:"font-mono text-xs",children:p.publicModelId}),o.jsx(he,{size:"sm",variant:"ghost",onClick:()=>l(p.id),children:"+ Add"})]},p.id))})]})}function R3(){const[n,a]=m.useState([]),[l,s]=m.useState([]),[c,u]=m.useState([]),[f,p]=m.useState(!1),[g,v]=m.useState({alias:"",targetKind:"model",targetId:"",enabled:!0}),x=async()=>{const[b,w,E]=await Promise.all([Ce.get("/api/admin/aliases"),Ce.get("/api/admin/models"),Ce.get("/api/admin/combos")]);a(b.aliases),s(w.models),u(E.combos)};m.useEffect(()=>{x()},[]);const y=async()=>{try{await Ce.post("/api/admin/aliases",g),ge.success("Alias created"),p(!1),v({alias:"",targetKind:"model",targetId:"",enabled:!0}),x()}catch(b){ge.error(b.message)}};return o.jsxs("div",{children:[o.jsx(Ya,{title:"Aliases",description:"Stable client-visible names for models or combos",actions:o.jsxs(kn,{open:f,onOpenChange:p,children:[o.jsx(mi,{asChild:!0,children:o.jsxs(he,{children:[o.jsx(wu,{className:"mr-1 h-4 w-4"})," New alias"]})}),o.jsxs(wn,{children:[o.jsx(Sn,{children:o.jsx(jn,{children:"New alias"})}),o.jsxs("div",{className:"space-y-3",children:[o.jsxs("div",{children:[o.jsx(Se,{children:"Alias"}),o.jsx(De,{value:g.alias,onChange:b=>v({...g,alias:b.target.value}),placeholder:"coding"})]}),o.jsxs("div",{children:[o.jsx(Se,{children:"Target type"}),o.jsxs(Ra,{value:g.targetKind,onValueChange:b=>v({...g,targetKind:b}),children:[o.jsx(da,{children:o.jsx(Na,{})}),o.jsxs(fa,{children:[o.jsx(wt,{value:"model",children:"Model"}),o.jsx(wt,{value:"combo",children:"Combo"})]})]})]}),o.jsxs("div",{children:[o.jsx(Se,{children:"Target"}),o.jsxs(Ra,{value:g.targetId,onValueChange:b=>v({...g,targetId:b}),children:[o.jsx(da,{children:o.jsx(Na,{placeholder:"Choose target"})}),o.jsx(fa,{children:(g.targetKind==="model"?l:c).map(b=>o.jsx(wt,{value:b.id,children:b.publicModelId},b.id))})]})]}),o.jsxs("div",{className:"flex items-center gap-2",children:[o.jsx(Ta,{checked:g.enabled,onCheckedChange:b=>v({...g,enabled:b})}),o.jsx(Se,{children:"Enabled"})]})]}),o.jsxs(zn,{children:[o.jsx(he,{variant:"outline",onClick:()=>p(!1),children:"Cancel"}),o.jsx(he,{disabled:!g.alias||!g.targetId,onClick:y,children:"Create"})]})]})]})}),o.jsxs(tt,{children:[o.jsxs(nt,{children:[o.jsx(at,{className:"text-base",children:"All aliases"}),o.jsxs(bn,{children:[n.length," total"]})]}),o.jsx(rt,{children:o.jsxs(pa,{children:[o.jsx(ga,{children:o.jsxs(We,{children:[o.jsx(be,{children:"Alias"}),o.jsx(be,{children:"Target"}),o.jsx(be,{children:"Type"}),o.jsx(be,{children:"Enabled"}),o.jsx(be,{})]})}),o.jsxs(va,{children:[n.length===0&&o.jsx(We,{children:o.jsx(pe,{colSpan:5,className:"text-center text-muted-foreground",children:"No aliases yet."})}),n.map(b=>o.jsxs(We,{children:[o.jsx(pe,{className:"font-mono text-xs",children:b.alias}),o.jsx(pe,{className:"font-mono text-xs",children:b.targetName??b.targetId}),o.jsx(pe,{children:o.jsx(Xe,{variant:"outline",children:b.targetKind})}),o.jsx(pe,{children:b.enabled?"Yes":"No"}),o.jsx(pe,{className:"text-right",children:o.jsx(he,{size:"sm",variant:"outline",onClick:async()=>{await Ce.del(`/api/admin/aliases/${b.id}`),ge.success("Removed"),x()},children:"Delete"})})]},b.id))]})]})})]})]})}function N3(){const[n,a]=m.useState([]),[l,s]=m.useState([]),[c,u]=m.useState([]),[f,p]=m.useState(!1),[g,v]=m.useState(null),[x,y]=m.useState(null),[b,w]=m.useState(null),[E,j]=m.useState({name:"",expiresAt:"",allowAll:!0,permissions:[],rpmLimit:"",tpmLimit:"",concurrency:"",customSecret:""}),C=async()=>{const[A,U,O]=await Promise.all([Ce.get("/api/admin/api-keys"),Ce.get("/api/admin/models"),Ce.get("/api/admin/combos")]);a(A.apiKeys),s(U.models),u(O.combos)};m.useEffect(()=>{C()},[]);const R=async()=>{try{if(g){await Ce.patch("/api/admin/api-keys",{id:g,name:E.name,expiresAt:E.expiresAt||null,allowAllModels:E.allowAll,permissions:E.allowAll?[]:E.permissions,rpmLimit:E.rpmLimit?Number(E.rpmLimit):null,tpmLimit:E.tpmLimit?Number(E.tpmLimit):null,maxConcurrent:E.concurrency?Number(E.concurrency):null}),p(!1),v(null),j({name:"",expiresAt:"",allowAll:!0,permissions:[],rpmLimit:"",tpmLimit:"",concurrency:"",customSecret:""}),ge.success("Key updated"),C();return}const A=await Ce.post("/api/admin/api-keys",{name:E.name,expiresAt:E.expiresAt||null,allowAllModels:E.allowAll,permissions:E.allowAll?void 0:E.permissions,rpmLimit:E.rpmLimit?Number(E.rpmLimit):null,tpmLimit:E.tpmLimit?Number(E.tpmLimit):null,maxConcurrent:E.concurrency?Number(E.concurrency):null,...E.customSecret.trim()?{secret:E.customSecret.trim()}:{}});p(!1),y({secret:A.secret,name:A.name}),j({name:"",expiresAt:"",allowAll:!0,permissions:[],rpmLimit:"",tpmLimit:"",concurrency:"",customSecret:""}),C()}catch(A){ge.error(A.message)}},M=async A=>{try{const O=((await Ce.get(`/api/admin/api-keys/${A.id}`)).apiKey.permissions??[]).filter(q=>q.targetKind==="model"||q.targetKind==="combo");v(A.id),j({name:A.name,expiresAt:A.expiresAt?A.expiresAt.slice(0,16):"",allowAll:A.allowAllModels,permissions:O,rpmLimit:A.rpmLimit!=null?String(A.rpmLimit):"",tpmLimit:A.tpmLimit!=null?String(A.tpmLimit):"",concurrency:A.concurrencyLimit!=null?String(A.concurrencyLimit):"",customSecret:""}),p(!0)}catch(U){ge.error(U.message)}},T=()=>{p(!1),v(null),j({name:"",expiresAt:"",allowAll:!0,permissions:[],rpmLimit:"",tpmLimit:"",concurrency:"",customSecret:""})},D=async(A,U)=>{try{await Ce.patch("/api/admin/api-keys",{id:A,enabled:!U}),ge.success(U?"Key disabled":"Key enabled"),C()}catch(O){ge.error(O.message)}},_=async A=>{if(window.confirm("Delete this API key? This cannot be undone."))try{await Ce.del(`/api/admin/api-keys/${A}`),ge.success("Key deleted"),C()}catch(U){ge.error(U.message)}};return o.jsxs("div",{children:[o.jsx(Ya,{title:"API Keys",description:"Gateway bearer keys for client applications",actions:o.jsxs(kn,{open:f,onOpenChange:A=>{A?p(!0):T()},children:[o.jsx(mi,{asChild:!0,children:o.jsxs(he,{children:[o.jsx(wu,{className:"mr-1 h-4 w-4"})," New key"]})}),o.jsxs(wn,{className:"max-w-2xl",children:[o.jsx(Sn,{children:o.jsx(jn,{children:g?"Edit API key":"New API key"})}),o.jsxs("div",{className:"space-y-3",children:[o.jsxs("div",{children:[o.jsx(Se,{children:"Name"}),o.jsx(De,{value:E.name,onChange:A=>j({...E,name:A.target.value})})]}),o.jsxs("div",{children:[o.jsx(Se,{children:"Expires (optional)"}),o.jsx(De,{type:"datetime-local",value:E.expiresAt,onChange:A=>j({...E,expiresAt:A.target.value})})]}),o.jsxs("div",{className:"grid grid-cols-3 gap-2",children:[o.jsxs("div",{children:[o.jsx(Se,{children:"RPM limit"}),o.jsx(De,{value:E.rpmLimit,onChange:A=>j({...E,rpmLimit:A.target.value}),type:"number"})]}),o.jsxs("div",{children:[o.jsx(Se,{children:"TPM limit"}),o.jsx(De,{value:E.tpmLimit,onChange:A=>j({...E,tpmLimit:A.target.value}),type:"number"})]}),o.jsxs("div",{children:[o.jsx(Se,{children:"Concurrency"}),o.jsx(De,{value:E.concurrency,onChange:A=>j({...E,concurrency:A.target.value}),type:"number"})]})]}),!g&&o.jsxs("div",{children:[o.jsx(Se,{children:"Key value (optional)"}),o.jsx(De,{value:E.customSecret,onChange:A=>j({...E,customSecret:A.target.value}),placeholder:"Leave empty to auto-generate ld-…"}),o.jsx("p",{className:"text-xs text-muted-foreground",children:"If provided, this exact value is stored as the key. Otherwise a random ld-… key is generated."})]}),o.jsxs("div",{className:"flex items-center gap-2",children:[o.jsx(Ta,{checked:E.allowAll,onCheckedChange:A=>j({...E,allowAll:A})}),o.jsx(Se,{children:"Allow all current and future models"})]}),!E.allowAll&&o.jsxs("div",{children:[o.jsx(Se,{children:"Scope"}),o.jsx("div",{className:"max-h-48 space-y-1 overflow-auto rounded border p-2",children:[...l.map(A=>({targetKind:"model",targetId:A.id,label:A.publicModelId})),...c.map(A=>({targetKind:"combo",targetId:A.id,label:A.publicModelId}))].map(A=>{const U=E.permissions.some(O=>O.targetKind===A.targetKind&&O.targetId===A.targetId);return o.jsxs("label",{className:"flex items-center gap-2 rounded p-1 text-sm hover:bg-accent",children:[o.jsx(Cp,{checked:U,onCheckedChange:O=>{j(q=>({...q,permissions:O?[...q.permissions,{targetKind:A.targetKind,targetId:A.targetId}]:q.permissions.filter(K=>!(K.targetKind===A.targetKind&&K.targetId===A.targetId))}))}}),o.jsx("span",{className:"font-mono text-xs",children:A.label}),o.jsx(Xe,{variant:"outline",className:"ml-1",children:A.targetKind})]},`${A.targetKind}:${A.targetId}`)})})]})]}),o.jsxs(zn,{children:[o.jsx(he,{variant:"outline",onClick:T,children:"Cancel"}),o.jsx(he,{disabled:!E.name,onClick:R,children:g?"Save changes":"Create"})]})]})]})}),o.jsxs(tt,{children:[o.jsxs(nt,{children:[o.jsx(at,{className:"text-base",children:"All keys"}),o.jsxs(bn,{children:[n.length," total"]})]}),o.jsx(rt,{children:o.jsxs(pa,{children:[o.jsx(ga,{children:o.jsxs(We,{children:[o.jsx(be,{children:"Name"}),o.jsx(be,{children:"Prefix"}),o.jsx(be,{children:"Status"}),o.jsx(be,{children:"Scope"}),o.jsx(be,{children:"RPM/TPM/Conc"}),o.jsx(be,{})]})}),o.jsxs(va,{children:[n.length===0&&o.jsx(We,{children:o.jsx(pe,{colSpan:6,className:"text-center text-muted-foreground",children:"No API keys yet."})}),n.map(A=>o.jsxs(We,{children:[o.jsx(pe,{className:"font-medium",children:A.name}),o.jsxs(pe,{className:"font-mono text-xs",children:[A.keyPrefix,"…"]}),o.jsx(pe,{children:A.enabled?o.jsx(Xe,{variant:"success",children:"enabled"}):o.jsx(Xe,{variant:"destructive",children:"disabled"})}),o.jsx(pe,{children:A.allowAllModels?"all":`${A.modelScopeCount} scoped`}),o.jsx(pe,{className:"text-xs",children:[A.rpmLimit,A.tpmLimit,A.concurrencyLimit].map((U,O)=>U?["","RPM","TPM","Conc"][O+1]:null).filter(Boolean).join(" / ")||"—"}),o.jsx(pe,{className:"text-right",children:o.jsxs("div",{className:"flex items-center justify-end gap-1",children:[A.secret&&o.jsxs(o.Fragment,{children:[o.jsx(he,{size:"sm",variant:"ghost",title:"Copy secret",onClick:()=>{navigator.clipboard.writeText(A.secret),ge.success("Copied")},children:o.jsx(Xc,{className:"h-3.5 w-3.5"})}),o.jsx(he,{size:"sm",variant:"ghost",title:"Show secret",onClick:()=>w({secret:A.secret,name:A.name}),children:o.jsx(cR,{className:"h-3.5 w-3.5"})})]}),o.jsx(he,{size:"sm",variant:"ghost",title:"Edit",onClick:()=>void M(A),children:o.jsx(gR,{className:"h-3.5 w-3.5"})}),o.jsxs(he,{size:"sm",variant:"outline",onClick:()=>D(A.id,A.enabled),children:[A.enabled?o.jsx(JE,{className:"mr-1 h-3.5 w-3.5"}):o.jsx(ci,{className:"mr-1 h-3.5 w-3.5"}),A.enabled?"Disable":"Enable"]}),o.jsx(he,{size:"sm",variant:"destructive",onClick:()=>_(A.id),children:o.jsx(Su,{className:"h-3.5 w-3.5"})})]})})]},A.id))]})]})})]}),o.jsx(kn,{open:!!x,onOpenChange:A=>{A||y(null)},children:o.jsxs(wn,{children:[o.jsxs(Sn,{children:[o.jsx(jn,{children:"API key created"}),o.jsx(cu,{children:"Copy now — this secret will not be shown again."})]}),o.jsx("div",{className:"rounded border bg-muted p-3 font-mono text-xs break-all",children:x==null?void 0:x.secret}),o.jsxs(zn,{children:[o.jsxs(he,{onClick:()=>{x&&(navigator.clipboard.writeText(x.secret),ge.success("Copied"))},children:[o.jsx(Xc,{className:"mr-1 h-4 w-4"})," Copy"]}),o.jsx(he,{variant:"outline",onClick:()=>y(null),children:"I have saved it"})]})]})}),o.jsx(kn,{open:!!b,onOpenChange:A=>{A||w(null)},children:o.jsxs(wn,{children:[o.jsxs(Sn,{children:[o.jsxs(jn,{children:["API key: ",b==null?void 0:b.name]}),o.jsx(cu,{children:"Full secret for this key, readable any time."})]}),o.jsx("div",{className:"rounded border bg-muted p-3 font-mono text-xs break-all",children:b==null?void 0:b.secret}),o.jsxs(zn,{children:[o.jsxs(he,{onClick:()=>{b&&(navigator.clipboard.writeText(b.secret),ge.success("Copied"))},children:[o.jsx(Xc,{className:"mr-1 h-4 w-4"})," Copy"]}),o.jsx(he,{variant:"outline",onClick:()=>w(null),children:"Close"})]})]})})]})}const T3=3e3;function M3(n,a){return!(a.success!=="all"&&n.success!==(a.success==="true")||a.protocol!=="all"&&n.protocol!==a.protocol||a.streaming!=="all"&&n.streaming!==(a.streaming==="true")||a.model&&!n.requestedModel.toLowerCase().includes(a.model.toLowerCase()))}function A3(){const[n,a]=m.useState([]),[l,s]=m.useState(0),[c,u]=m.useState(0),[f,p]=m.useState({success:"all",protocol:"all",streaming:"all",model:""}),[g,v]=m.useState(null),[x,y]=m.useState(null),[b,w]=m.useState(0),E=50,j=m.useRef(Date.now()),C=m.useRef(new Set),R=m.useRef(f);R.current=f;const M=m.useRef(c);M.current=c;const T=m.useCallback(async()=>{const _=new URLSearchParams;_.set("limit",String(E)),_.set("offset",String(c)),f.success!=="all"&&_.set("success",f.success),f.protocol!=="all"&&_.set("protocol",f.protocol),f.streaming!=="all"&&_.set("streaming",f.streaming),f.model&&_.set("requestedModel",f.model);const A=await Ce.get(`/api/admin/requests?${_.toString()}`);a(A.requests),s(A.total);for(const U of A.requests)C.current.add(U.id)},[c,f]);m.useEffect(()=>{T()},[T]),m.useEffect(()=>{w(0)},[c,f]),m.useEffect(()=>{let _=!1,A=null;const U=new Set,O=()=>{_||(A=new EventSource(`/api/admin/requests/stream?since=${j.current}`),A.addEventListener("request",q=>{if(!_)try{const K=JSON.parse(q.data),te=new Date(K.createdAt).getTime();if(Number.isFinite(te)&&(j.current=Math.max(j.current,te)),C.current.has(K.id))return;C.current.add(K.id),w(G=>G+1),M.current===0&&M3(K,R.current)&&(a(G=>G.some(ie=>ie.id===K.id)?G:[K,...G].slice(0,E)),s(G=>G+1))}catch{}}),A.onerror=()=>{A==null||A.close(),A=null,_||U.add(setTimeout(O,T3))})};return O(),()=>{_=!0,A==null||A.close();for(const q of U)clearTimeout(q);U.clear()}},[]);const D=async _=>{v(_);const A=await Ce.get(`/api/admin/requests/${_}`);y(A)};return o.jsxs("div",{children:[o.jsx(Ya,{title:"Requests",description:`${l} matching · live updates`}),o.jsxs(tt,{children:[o.jsxs(nt,{children:[o.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[o.jsxs(Ra,{value:f.success,onValueChange:_=>{u(0),p({...f,success:_})},children:[o.jsx(da,{className:"w-36",children:o.jsx(Na,{})}),o.jsxs(fa,{children:[o.jsx(wt,{value:"all",children:"All"}),o.jsx(wt,{value:"true",children:"Success"}),o.jsx(wt,{value:"false",children:"Failed"})]})]}),o.jsxs(Ra,{value:f.protocol,onValueChange:_=>{u(0),p({...f,protocol:_})},children:[o.jsx(da,{className:"w-32",children:o.jsx(Na,{})}),o.jsxs(fa,{children:[o.jsx(wt,{value:"all",children:"Any protocol"}),o.jsx(wt,{value:"openai",children:"OpenAI"}),o.jsx(wt,{value:"anthropic",children:"Anthropic"})]})]}),o.jsxs(Ra,{value:f.streaming,onValueChange:_=>{u(0),p({...f,streaming:_})},children:[o.jsx(da,{className:"w-32",children:o.jsx(Na,{})}),o.jsxs(fa,{children:[o.jsx(wt,{value:"all",children:"Any"}),o.jsx(wt,{value:"true",children:"Streaming"}),o.jsx(wt,{value:"false",children:"Non-stream"})]})]}),o.jsx(De,{className:"max-w-xs",placeholder:"Model contains…",value:f.model,onChange:_=>{u(0),p({...f,model:_.target.value})}}),b>0&&o.jsxs(he,{size:"sm",variant:"secondary",onClick:()=>{w(0),T()},children:[b," new request",b>1?"s":""," — refresh"]})]}),o.jsx(at,{className:"mt-3 text-base",children:"Results"})]}),o.jsxs(rt,{children:[o.jsxs(pa,{children:[o.jsx(ga,{children:o.jsxs(We,{children:[o.jsx(be,{children:"Time"}),o.jsx(be,{children:"Status"}),o.jsx(be,{children:"Requested"}),o.jsx(be,{children:"Final"}),o.jsx(be,{children:"Tokens"}),o.jsx(be,{children:"Latency"}),o.jsx(be,{children:"Attempts"}),o.jsx(be,{children:"Key"}),o.jsx(be,{children:"IP"}),o.jsx(be,{})]})}),o.jsxs(va,{children:[n.length===0&&o.jsx(We,{children:o.jsx(pe,{colSpan:10,className:"text-center text-muted-foreground",children:"No requests yet."})}),n.map(_=>o.jsxs(We,{className:"cursor-pointer",onClick:()=>D(_.id),children:[o.jsx(pe,{className:"text-xs",children:Um(_.createdAt)}),o.jsx(pe,{children:_.success?o.jsx(Xe,{variant:"success",children:_.httpStatus}):o.jsx(Xe,{variant:"destructive",children:_.httpStatus})}),o.jsx(pe,{className:"font-mono text-xs",children:_.requestedModel}),o.jsx(pe,{className:"font-mono text-xs text-muted-foreground",children:_.finalModelPublicId??"—"}),o.jsxs(pe,{className:"text-xs",children:[Jt(_.inputTokens+_.outputTokens)," ",_.cacheReadTokens?o.jsxs("span",{className:"text-amber-600",children:["(+",_.cacheReadTokens," cache)"]}):null]}),o.jsxs(pe,{className:"text-xs",children:[Ol(_.totalLatencyMs),_.ttftMs?o.jsxs("span",{className:"text-muted-foreground",children:[" · ttft ",_.ttftMs,"ms"]}):null]}),o.jsxs(pe,{className:"text-xs",children:[_.attemptsCount,_.gatewayCacheHit?o.jsx(Xe,{variant:"secondary",className:"ml-1",children:"cache"}):null]}),o.jsx(pe,{className:"text-xs",children:_.apiKeyName??"—"}),o.jsx(pe,{className:"text-xs",children:_.clientIp}),o.jsx(pe,{className:"text-right",children:o.jsx(he,{size:"sm",variant:"ghost",children:"View"})})]},_.id))]})]}),o.jsxs("div",{className:"mt-3 flex items-center justify-between",children:[o.jsxs("span",{className:"text-xs text-muted-foreground",children:["Showing ",c+1,"–",Math.min(c+E,l)," of ",l]}),o.jsxs("div",{className:"flex gap-2",children:[o.jsx(he,{size:"sm",variant:"outline",disabled:c===0,onClick:()=>u(Math.max(0,c-E)),children:"Prev"}),o.jsx(he,{size:"sm",variant:"outline",disabled:c+E>=l,onClick:()=>u(c+E),children:"Next"})]})]})]})]}),o.jsx(kn,{open:!!g,onOpenChange:_=>{_||(v(null),y(null))},children:o.jsxs(wn,{className:"max-w-3xl",children:[o.jsx(Sn,{children:o.jsxs(jn,{children:["Request ",rN(g,16)]})}),x?o.jsxs("div",{className:"space-y-3 text-sm",children:[o.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[o.jsxs("div",{children:[o.jsx("div",{className:"text-muted-foreground text-xs",children:"Requested model"}),o.jsx("span",{className:"font-mono text-xs",children:x.request.requestedModel})]}),o.jsxs("div",{children:[o.jsx("div",{className:"text-muted-foreground text-xs",children:"Upstream model"}),o.jsx("span",{className:"font-mono text-xs",children:x.request.finalModelUpstreamId??"—"})]}),o.jsxs("div",{children:[o.jsx("div",{className:"text-muted-foreground text-xs",children:"Provider"}),x.request.providerId?o.jsx(ia,{className:"text-primary underline",to:`/providers?providerId=${encodeURIComponent(x.request.providerId)}`,children:x.request.providerName??x.request.providerSlug??x.request.providerId}):"—"]}),o.jsxs("div",{children:[o.jsx("div",{className:"text-muted-foreground text-xs",children:"Route"}),x.request.resolvedTargetId?o.jsx(ia,{className:"text-primary underline",to:x.request.resolvedTargetKind==="combo"?"/combos":"/models",children:x.request.resolvedTargetKind??"target"}):"—"]}),o.jsxs("div",{children:[o.jsx("div",{className:"text-muted-foreground text-xs",children:"Status"}),x.request.success?o.jsx(Xe,{variant:"success",children:x.request.httpStatus}):o.jsx(Xe,{variant:"destructive",children:x.request.httpStatus})]}),o.jsxs("div",{children:[o.jsx("div",{className:"text-muted-foreground text-xs",children:"Latency"}),Ol(x.request.totalLatencyMs)]}),o.jsxs("div",{children:[o.jsx("div",{className:"text-muted-foreground text-xs",children:"Tokens"}),"in ",Jt(x.request.inputTokens)," · out ",Jt(x.request.outputTokens)," · cache ",Jt(x.request.cacheReadTokens)]}),o.jsxs("div",{children:[o.jsx("div",{className:"text-muted-foreground text-xs",children:"Attempts"}),x.request.attemptsCount]})]}),x.request.errorType&&o.jsxs("div",{className:"rounded border border-destructive/40 bg-destructive/10 p-2",children:[o.jsx("div",{className:"text-xs text-muted-foreground",children:"Error"}),o.jsxs("div",{className:"font-mono text-xs",children:[x.request.errorType,": ",x.request.errorMessage]})]}),x.request.fallbackReasons.length>0&&o.jsxs("div",{className:"rounded border border-amber-500/40 bg-amber-500/10 p-2",children:[o.jsx("div",{className:"text-xs text-muted-foreground",children:"Fallback reasons"}),o.jsx("div",{className:"text-xs",children:x.request.fallbackReasons.join(", ")})]}),o.jsxs("div",{children:[o.jsxs("div",{className:"mb-1 flex items-center justify-between text-xs text-muted-foreground",children:[o.jsx("span",{children:"Safe replay curl"}),o.jsxs(he,{size:"sm",variant:"ghost",onClick:()=>{navigator.clipboard.writeText(x.request.reproductionCurl).then(()=>ge.success("Curl copied"))},children:[o.jsx(Xc,{className:"mr-1 h-3.5 w-3.5"})," Copy"]})]}),o.jsx("pre",{className:"max-h-36 overflow-auto whitespace-pre-wrap rounded bg-muted p-2 font-mono text-xs",children:x.request.reproductionCurl}),o.jsx("p",{className:"mt-1 text-xs text-muted-foreground",children:"Replace the placeholder key before running. No stored secret is included."})]}),x.request.requestPayload&&o.jsxs("div",{children:[o.jsx("div",{className:"text-xs text-muted-foreground",children:"Request content"}),o.jsx("pre",{className:"max-h-60 overflow-auto rounded bg-muted p-2 font-mono text-xs whitespace-pre-wrap",children:x.request.requestPayload})]}),x.request.responsePayload&&o.jsxs("div",{children:[o.jsx("div",{className:"text-xs text-muted-foreground",children:"Response content"}),o.jsx("pre",{className:"max-h-60 overflow-auto rounded bg-muted p-2 font-mono text-xs whitespace-pre-wrap",children:x.request.responsePayload})]}),x.attempts.length>0&&o.jsxs("div",{children:[o.jsx("div",{className:"text-xs text-muted-foreground",children:"Attempts"}),o.jsxs(pa,{children:[o.jsx(ga,{children:o.jsxs(We,{children:[o.jsx(be,{children:"#"}),o.jsx(be,{children:"Provider"}),o.jsx(be,{children:"Model"}),o.jsx(be,{children:"Status"}),o.jsx(be,{children:"Latency"}),o.jsx(be,{children:"Reason"})]})}),o.jsx(va,{children:x.attempts.map(_=>o.jsxs(We,{children:[o.jsx(pe,{children:_.attemptNumber}),o.jsx(pe,{children:_.providerName}),o.jsxs(pe,{children:[o.jsx("div",{className:"font-mono text-xs",children:_.modelPublicId}),o.jsxs("div",{className:"text-[11px] text-muted-foreground",children:["upstream: ",_.upstreamModelId]})]}),o.jsx(pe,{children:_.success?o.jsx(Xe,{variant:"success",children:String(_.statusCode??"OK")}):o.jsx(Xe,{variant:"destructive",children:String(_.statusCode??"err")})}),o.jsx(pe,{className:"text-xs",children:Ol(_.latencyMs)}),o.jsx(pe,{className:"text-xs",children:_.failureReason??_.selectionReason})]},_.id))})]})]})]}):o.jsx("div",{className:"text-muted-foreground",children:"Loading…"})]})})]})}var D3=Object.defineProperty,Zs=(n,a)=>D3(n,"name",{value:a,configurable:!0}),kp="Tabs",[O3,n5]=Hn(kp,[zu]),TS=zu(),[_3,zp]=O3(kp),k3=m.forwardRef(Zs(function(a,l){const{__scopeTabs:s,value:c,onValueChange:u,defaultValue:f,orientation:p="horizontal",dir:g,activationMode:v="automatic",...x}=a,y=di(g),[b,w]=br({prop:c,onChange:u,defaultProp:f??"",caller:kp});return o.jsx(_3,{scope:s,baseId:Ha(),value:b,onValueChange:w,orientation:p,dir:y,activationMode:v,children:o.jsx(Pe.div,{dir:y,"data-orientation":p,...x,ref:l})})},"Tabs")),z3="TabsList",L3=m.forwardRef(Zs(function(a,l){const{__scopeTabs:s,loop:c=!0,...u}=a,f=zp(z3,s),p=TS(s);return o.jsx(F1,{asChild:!0,...p,orientation:f.orientation,dir:f.dir,loop:c,children:o.jsx(Pe.div,{role:"tablist","aria-orientation":f.orientation,...u,ref:l})})},"TabsList")),U3="TabsTrigger",B3=m.forwardRef(Zs(function(a,l){const{__scopeTabs:s,value:c,disabled:u=!1,...f}=a,p=zp(U3,s),g=TS(s),v=Lp(p.baseId,c),x=Up(p.baseId,c),y=c===p.value;return o.jsx(K1,{asChild:!0,...g,focusable:!u,active:y,children:o.jsx(Pe.button,{type:"button",role:"tab","aria-selected":y,"aria-controls":x,"data-state":y?"active":"inactive","data-disabled":u?"":void 0,disabled:u,id:v,...f,ref:l,onMouseDown:Te(a.onMouseDown,b=>{!u&&b.button===0&&b.ctrlKey===!1?p.onValueChange(c):b.preventDefault()}),onKeyDown:Te(a.onKeyDown,b=>{u||b.target!==b.currentTarget||[" ","Enter"].includes(b.key)&&p.onValueChange(c)}),onFocus:Te(a.onFocus,()=>{const b=p.activationMode!=="manual";!y&&!u&&b&&p.onValueChange(c)})})})},"TabsTrigger")),H3="TabsContent",I3=m.forwardRef(Zs(function(a,l){const{__scopeTabs:s,value:c,forceMount:u,children:f,...p}=a,g=zp(H3,s),v=Lp(g.baseId,c),x=Up(g.baseId,c),y=c===g.value,b=m.useRef(y);return m.useEffect(()=>{const w=requestAnimationFrame(()=>b.current=!1);return()=>cancelAnimationFrame(w)},[]),o.jsx(Er,{present:u||y,children:({present:w})=>o.jsx(Pe.div,{"data-state":y?"active":"inactive","data-orientation":g.orientation,role:"tabpanel","aria-labelledby":v,hidden:!w,id:x,tabIndex:0,...p,ref:l,style:{...a.style,animationDuration:b.current?"0s":void 0},children:w&&f})})},"TabsContent"));function Lp(n,a){return`${n}-trigger-${a}`}Zs(Lp,"makeTriggerId");function Up(n,a){return`${n}-content-${a}`}Zs(Up,"makeContentId");var P3=k3,MS=L3,AS=B3,DS=I3;const OS=P3,Bp=m.forwardRef(({className:n,...a},l)=>o.jsx(MS,{ref:l,className:Ee("inline-flex h-9 items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground",n),...a}));Bp.displayName=MS.displayName;const pr=m.forwardRef(({className:n,...a},l)=>o.jsx(AS,{ref:l,className:Ee("inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow",n),...a}));pr.displayName=AS.displayName;const Os=m.forwardRef(({className:n,...a},l)=>o.jsx(DS,{ref:l,className:Ee("mt-2 ring-offset-background focus-visible:outline-none",n),...a}));Os.displayName=DS.displayName;const q3=3e3,V3=1600,$3=10,Y3=3,G3=12,F3=10*6e4,K3={cacheReadTokens:0,promptTokens:0,gatewayCacheHits:0,fallbacks:0};function _S(n,a,l){return l==="anthropic"?n+a:n}function X3(n){return n.promptTokens>0?n.cacheReadTokens/n.promptTokens:0}function Q3(n,a){return a>0?n.fallbacks/a:0}function Z3(n,a){return a>0?n.gatewayCacheHits/a:0}function J3(n,a,l){const s=n.totalRequests+1,c=n.successfulRequests+(l.success?1:0),u={cacheReadTokens:a.cacheReadTokens+l.cacheReadTokens,promptTokens:a.promptTokens+_S(l.inputTokens,l.cacheReadTokens,l.providerType),gatewayCacheHits:a.gatewayCacheHits+(l.gatewayCacheHit?1:0),fallbacks:a.fallbacks+(l.attemptsCount>1?1:0)};return{...n,...u,totalRequests:s,successfulRequests:c,failedRequests:n.failedRequests+(l.success?0:1),successRate:c/s,inputTokens:n.inputTokens+l.inputTokens,outputTokens:n.outputTokens+l.outputTokens,totalTokens:n.totalTokens+l.inputTokens+l.outputTokens,cacheHitRate:X3(u),gatewayCacheHitRate:Z3(u,s),fallbackRate:Q3(u,s),averageLatencyMs:(n.averageLatencyMs*n.totalRequests+l.totalLatencyMs)/s}}function W3(n){const[a,l]=m.useState(null),[s,c]=m.useState(null),[u,f]=m.useState([]),[p,g]=m.useState([]),[v,x]=m.useState([]),[y,b]=m.useState([]),[w,E]=m.useState(!0),[j,C]=m.useState(null),R=m.useRef([]),M=m.useRef(null),T=m.useRef(K3),D=m.useRef(new Set),_=m.useRef(Date.now()),A=m.useRef(0),U=m.useRef([]),O=m.useRef([]);return m.useEffect(()=>{let q=!1;return E(!0),C(null),D.current=new Set,_.current=Date.now(),Ce.get(`/api/admin/stats?preset=${n}`).then(K=>{if(!q){l(K),c(K.summary),M.current=K.summary,T.current={cacheReadTokens:K.summary.cacheReadTokens,promptTokens:K.summary.cacheHitRate!==null&&K.summary.cacheHitRate>0?Math.round(K.summary.cacheReadTokens/K.summary.cacheHitRate):K.summary.inputTokens,gatewayCacheHits:Math.round(K.summary.gatewayCacheHitRate*K.summary.totalRequests),fallbacks:Math.round(K.summary.fallbackRate*K.summary.totalRequests)},f(K.recent),g(K.providers),R.current=K.providers;for(const te of K.recent)D.current.add(te.id);E(!1)}}).catch(K=>{q||(C(K.message),E(!1))}),()=>{q=!0}},[n]),m.useEffect(()=>{let q=!1,K=null;const te=new Set,G=()=>{q||(K=new EventSource(`/api/admin/requests/stream?since=${_.current}`),K.addEventListener("request",ce=>{if(!q)try{const le=JSON.parse(ce.data),k=new Date(le.createdAt).getTime();if(Number.isFinite(k)&&(_.current=Math.max(_.current,k)),D.current.has(le.id))return;D.current.add(le.id);const H={cacheReadTokens:T.current.cacheReadTokens+le.cacheReadTokens,promptTokens:T.current.promptTokens+_S(le.inputTokens,le.cacheReadTokens,le.providerType),gatewayCacheHits:T.current.gatewayCacheHits+(le.gatewayCacheHit?1:0),fallbacks:T.current.fallbacks+(le.attemptsCount>1?1:0)};if(T.current=H,M.current&&c(J3(M.current,H,le)),f(Q=>Q.some(J=>J.id===le.id)?Q:[le,...Q].slice(0,$3)),le.providerId){R.current=R.current.map(z=>z.id===le.providerId?{...z,requests:z.requests+1,errorRate:z.requests+1?(z.errorRate*z.requests+(le.success?0:1))/(z.requests+1):0}:z),g(R.current);const Q=`p${++A.current}`,J={id:Q,providerId:le.providerId,success:le.success};U.current=[...U.current.slice(-(Y3*4)),J],x(U.current);const ee=setTimeout(()=>{U.current=U.current.filter(z=>z.id!==Q),x(U.current)},V3);te.add(ee)}O.current.some(Q=>Q.id===le.id)&&(O.current=O.current.filter(Q=>Q.id!==le.id),b(O.current))}catch{}}),K.addEventListener("request_started",ce=>{if(!q)try{const le=JSON.parse(ce.data);if(!le.providerId||le.providerId==="")return;O.current=[...O.current.filter(k=>k.id!==le.requestId).slice(-(G3-1)),{id:le.requestId,providerId:le.providerId,startedAt:Date.now(),ttftMs:le.ttftMs??0}],b(O.current)}catch{}}),K.onerror=()=>{K==null||K.close(),K=null,q||te.add(setTimeout(G,q3))})};G();const ie=setInterval(()=>{const ce=Date.now()-F3;O.current.some(le=>le.startedAt<ce)&&(O.current=O.current.filter(le=>le.startedAt>=ce),b(O.current))},3e4);return()=>{q=!0,K==null||K.close();for(const ce of te)clearTimeout(ce);te.clear(),clearInterval(ie)}},[]),m.useEffect(()=>{const q=setInterval(()=>{Ce.get("/api/admin/providers").then(K=>{const te=new Map(K.providers.map(G=>[G.id,G]));R.current=R.current.map(G=>{const ie=te.get(G.id);return ie?{...G,health:ie.health,enabled:ie.enabled}:G}),g(R.current)}).catch(()=>{})},3e4);return()=>clearInterval(q)},[]),{snapshot:a,live:s??(a==null?void 0:a.summary)??e4,recent:u,providers:p,pulses:v,activeRoutes:y,loading:w,error:j}}const e4={totalRequests:0,successfulRequests:0,failedRequests:0,successRate:0,inputTokens:0,outputTokens:0,totalTokens:0,cacheReadTokens:0,cacheWriteTokens:0,reasoningTokens:0,averageLatencyMs:0,p95LatencyMs:0,averageTtftMs:null,p95TtftMs:null,cacheHitRate:0,gatewayCacheHitRate:0,fallbackRate:0};function kS({data:n,className:a,strokeClass:l="stroke-primary",fillClass:s}){if(n.length===0)return o.jsx("svg",{className:Ee("h-6 w-20",a),viewBox:"0 0 80 24"});const f=Math.max(...n),p=Math.min(...n),g=f-p||1,x=n.map((y,b)=>{const w=b/(n.length-1)*78+1,E=22-(y-p)/g*20;return`${w.toFixed(1)},${E.toFixed(1)}`}).join(" ");return o.jsxs("svg",{className:Ee("h-6 w-20",a),viewBox:"0 0 80 24",preserveAspectRatio:"none",children:[s&&o.jsx("polygon",{points:`1,23 ${x} 79,23`,className:s}),o.jsx("polyline",{points:x,fill:"none",strokeWidth:1.5,strokeLinecap:"round",strokeLinejoin:"round",className:l})]})}function t4(n,a,l){const s=performance.now();let c=0;const u=f=>{const p=Math.min((f-s)/a,1),g=Math.round(n*p);g!==c&&(c=g,l(g)),p<1&&requestAnimationFrame(u)};requestAnimationFrame(u)}function n4({delta:n,inverse:a}){if(Math.abs(n)<.005)return null;const l=n>0,s=a?!l:l,c=`${(Math.abs(n)*100).toFixed(1)}%`;return o.jsxs("span",{className:Ee("ml-1.5 inline-flex items-center rounded-full px-1.5 py-0.5 text-[10px] font-semibold leading-none",s?"bg-emerald-100 text-emerald-700 dark:bg-emerald-900/40 dark:text-emerald-300":"bg-red-100 text-red-700 dark:bg-red-900/40 dark:text-red-300"),children:[o.jsx("span",{className:"mr-0.5",children:l?"▲":"▼"}),c]})}function tl({icon:n,label:a,value:l,format:s="number",delta:c,deltaInverse:u,sparkData:f,sparkStroke:p}){const[g,v]=m.useState(0),x=m.useRef(0);m.useEffect(()=>{const b=x.current,w=l;w!==null&&(x.current=w,b!==w&&t4(Math.abs(w-b),600,E=>v(b+(w>b?E:-E))))},[l]);const y=l===null?"Unavailable":s==="percent"?Cu(g):s==="latency"?Ol(g):Jt(Math.round(g));return o.jsxs(tt,{children:[o.jsxs(nt,{className:"flex flex-row items-center justify-between pb-1",children:[o.jsxs(at,{className:"flex items-center gap-2 text-sm font-medium text-muted-foreground",children:[o.jsx(n,{className:"h-4 w-4"}),a]}),c!==void 0&&o.jsx(n4,{delta:c,inverse:u})]}),o.jsxs(rt,{className:"flex items-end justify-between",children:[o.jsx("span",{className:"text-2xl font-semibold tabular-nums",children:y}),f&&f.length>1&&o.jsx(kS,{data:f,strokeClass:p??"stroke-primary",fillClass:"fill-primary/10"})]})]})}const zS=1e3,Fb=380,Vc=60,nl=zS/2,al=720,Bh=62,a4=260;function r4(n){return n==="healthy"?"fill-emerald-400":n==="degraded"?"fill-amber-400":"fill-red-400"}function $c(n,a,l,s){const c=n+(l-n)*.45,u=n+(l-n)*.55;return`M${n},${a} C${c},${a} ${u},${s} ${l},${s}`}function l4({liveRequests:n,successRate:a,providers:l,pulses:s,activeRoutes:c}){const u=Fb/2,f=u,p=Math.max(1,l.reduce((x,y)=>x+y.requests,0)),g=new Set(c.map(x=>x.providerId)),v=g.size>0;return o.jsxs(tt,{children:[o.jsx(nt,{className:"pb-2",children:o.jsxs("div",{className:"flex items-center justify-between",children:[o.jsx(at,{className:"text-base",children:"Real-time Request Routing"}),o.jsxs("div",{className:"flex items-center gap-3 text-xs text-muted-foreground",children:[o.jsxs("span",{className:"flex items-center gap-1",children:[o.jsx("span",{className:"inline-block h-2 w-2 rounded-full bg-emerald-400"})," healthy"]}),o.jsxs("span",{className:"flex items-center gap-1",children:[o.jsx("span",{className:"inline-block h-2 w-2 rounded-full bg-amber-400"})," degraded"]}),o.jsxs("span",{className:"flex items-center gap-1",children:[o.jsx("span",{className:"inline-block h-2 w-2 rounded-full bg-red-400"})," down"]})]})]})}),o.jsx(rt,{className:"pt-0",children:o.jsx("div",{className:"relative w-full",children:o.jsxs("svg",{viewBox:`0 0 ${zS} ${Fb}`,className:"w-full h-auto",preserveAspectRatio:"xMidYMid meet",children:[o.jsx("defs",{children:o.jsxs("filter",{id:"glow",x:"-50%",y:"-50%",width:"200%",height:"200%",children:[o.jsx("feGaussianBlur",{stdDeviation:"3",result:"blur"}),o.jsxs("feMerge",{children:[o.jsx("feMergeNode",{in:"blur"}),o.jsx("feMergeNode",{in:"SourceGraphic"})]})]})}),l.map(x=>{const b=60+l.indexOf(x)*Bh,w=x.requests/p,E=Math.max(1.5,Math.min(6,2+w*8)),j=g.has(x.id);return o.jsxs("g",{children:[j&&o.jsx("path",{d:$c(nl,u,al-20,b),fill:"none",stroke:"hsl(var(--primary) / 0.25)",strokeWidth:E+6,strokeLinecap:"round"}),o.jsx("path",{d:$c(nl,u,al-20,b),fill:"none",stroke:j?"hsl(var(--primary))":"hsl(var(--border))",strokeWidth:j?E+1:E,strokeLinecap:"round",opacity:j?.95:.6,className:j?"route-active":void 0})]},x.id)}),o.jsx("path",{d:$c(Vc+30,f,nl-30,u),fill:"none",stroke:v?"hsl(var(--primary))":"hsl(var(--border))",strokeWidth:3,strokeLinecap:"round",strokeDasharray:"6 3",opacity:v?.9:.5,className:v?"route-active":void 0}),s.map(x=>{const y=l.findIndex(j=>j.id===x.providerId);if(y===-1)return null;const b=60+y*Bh,w=$c(nl,u,al-20,b),E=x.success?"var(--primary)":"#f87171";return o.jsxs("g",{filter:"url(#glow)",children:[o.jsx("circle",{r:5,fill:E,opacity:.9,children:o.jsx("animateMotion",{dur:"1.4s",fill:"freeze",path:w})}),o.jsx("circle",{r:9,fill:E,opacity:.25,children:o.jsx("animateMotion",{dur:"1.4s",fill:"freeze",path:w})})]},x.id)}),o.jsx("circle",{cx:Vc,cy:f,r:28,fill:"hsl(var(--card))",stroke:"hsl(var(--border))",strokeWidth:1.5}),o.jsx("text",{x:Vc,y:f-4,textAnchor:"middle",className:"fill-foreground",fontSize:12,fontWeight:600,children:Kb(n)}),o.jsx("text",{x:Vc,y:f+10,textAnchor:"middle",className:"fill-muted-foreground",fontSize:9,children:"requests"}),o.jsx("circle",{cx:nl,cy:u,r:36,fill:"hsl(var(--card))",stroke:"var(--primary)",strokeWidth:2}),o.jsx("image",{x:nl-12,y:u-16,width:24,height:24,href:"/logo.png"}),o.jsx("text",{x:nl,y:u+28,textAnchor:"middle",className:"fill-muted-foreground",fontSize:9,children:"AI Gateway"}),o.jsxs("text",{x:nl,y:u+38,textAnchor:"middle",className:"fill-emerald-500",fontSize:10,fontWeight:600,children:[(a*100).toFixed(1),"%"]}),l.map((x,y)=>{const b=60+y*Bh,w=x.requests/p,E=!x.enabled||x.requests===0;return o.jsxs("g",{opacity:E?.4:1,children:[o.jsx("rect",{x:al-20,y:b-14,width:a4,height:50,rx:8,fill:"hsl(var(--card))",stroke:"hsl(var(--border))",strokeWidth:1}),o.jsx("circle",{cx:al-6,cy:b+10,r:4,className:r4(x.health)}),o.jsx("text",{x:al+6,y:b-2,className:"fill-foreground",fontSize:12,fontWeight:500,children:x.name}),o.jsxs("text",{x:al+6,y:b+12,className:"fill-muted-foreground",fontSize:10,children:[x.modelCount," model",x.modelCount!==1?"s":""," · ",Kb(x.requests)," req"]}),o.jsxs("text",{x:al+6,y:b+25,className:"fill-muted-foreground",fontSize:10,children:[(w*100).toFixed(1),"% traffic · ",x.avgLatencyMs<1e3?`${Math.round(x.avgLatencyMs)}ms`:`${(x.avgLatencyMs/1e3).toFixed(1)}s`," avg",x.errorRate>0&&o.jsxs("tspan",{className:"fill-red-500",children:[" · ",(x.errorRate*100).toFixed(0),"% err"]})]})]},x.id)})]})})})]})}function Kb(n){return n>=1e6?`${(n/1e6).toFixed(1)}M`:n>=1e3?`${(n/1e3).toFixed(1)}K`:String(n)}function s4({rows:n}){return o.jsxs(tt,{children:[o.jsx(nt,{className:"pb-2",children:o.jsx(at,{className:"text-base",children:"Recent Requests"})}),o.jsx(rt,{children:n.length===0?o.jsx("div",{className:"py-6 text-center text-sm text-muted-foreground",children:"No requests yet — traffic will appear here live."}):o.jsxs(pa,{children:[o.jsx(ga,{children:o.jsxs(We,{children:[o.jsx(be,{children:"Model"}),o.jsx(be,{children:"Provider"}),o.jsx(be,{children:"Tokens"}),o.jsx(be,{children:"Status"}),o.jsx(be,{children:"Time"})]})}),o.jsx(va,{children:n.map(a=>o.jsxs(We,{children:[o.jsx(pe,{className:"font-mono text-xs",children:a.requestedModel}),o.jsx(pe,{className:"text-xs text-muted-foreground",children:a.providerName??"—"}),o.jsxs(pe,{className:"text-xs",children:[o.jsxs("span",{className:"font-mono",children:["in ",Jt(a.inputTokens)," · out ",Jt(a.outputTokens)]}),a.cacheReadTokens>0&&o.jsxs("span",{className:"ml-1 text-amber-600",children:["(+",Jt(a.cacheReadTokens)," cache)"]})]}),o.jsx(pe,{children:o.jsxs("span",{className:"inline-flex items-center gap-1.5",children:[o.jsx("span",{className:a.success?"h-2 w-2 rounded-full bg-emerald-400":"h-2 w-2 rounded-full bg-red-400"}),o.jsx("span",{className:"text-xs",children:a.success?a.httpStatus:`${a.httpStatus} err`})]})}),o.jsx(pe,{className:"text-xs text-muted-foreground",children:lN(a.createdAt)})]},a.id))})]})})]})}const gm=34,Xb=2*Math.PI*gm;function o4(n){return n>=.95?{stroke:"#4ade80",text:"text-emerald-500"}:n>=.8?{stroke:"#fbbf24",text:"text-amber-500"}:{stroke:"#f87171",text:"text-red-500"}}function i4({successRate:n,averageLatencyMs:a,latencySpark:l}){const{stroke:s,text:c}=o4(n),u=Math.min(1,Math.max(0,n)),f=Xb*(1-u);return o.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[o.jsxs(tt,{children:[o.jsx(nt,{className:"pb-2",children:o.jsx(at,{className:"text-base",children:"Success Rate"})}),o.jsxs(rt,{className:"flex items-center gap-4",children:[o.jsxs("div",{className:"relative h-20 w-20",children:[o.jsxs("svg",{viewBox:"0 0 80 80",className:"h-20 w-20 -rotate-90",children:[o.jsx("circle",{cx:"40",cy:"40",r:gm,fill:"none",stroke:"hsl(var(--border))",strokeWidth:7}),o.jsx("circle",{cx:"40",cy:"40",r:gm,fill:"none",stroke:s,strokeWidth:7,strokeLinecap:"round",strokeDasharray:Xb,strokeDashoffset:f,style:{transition:"stroke-dashoffset 0.6s ease, stroke 0.4s ease"}})]}),o.jsx("span",{className:`absolute inset-0 flex items-center justify-center text-sm font-semibold tabular-nums ${c}`,children:Cu(n)})]}),o.jsx("p",{className:"text-sm text-muted-foreground",children:"Share of requests that completed successfully over the selected window. Updated in real time."})]})]}),o.jsxs(tt,{children:[o.jsx(nt,{className:"pb-2",children:o.jsx(at,{className:"text-base",children:"Average Latency"})}),o.jsxs(rt,{className:"flex items-end justify-between",children:[o.jsxs("div",{children:[o.jsx("div",{className:"text-2xl font-semibold tabular-nums",children:Ol(a)}),o.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"Live average across the selected window"})]}),o.jsx(kS,{data:l,strokeClass:"stroke-amber-500",fillClass:"fill-amber-500/10",className:"h-10 w-28"})]})]})]})}function c4(){const[n,a]=m.useState("7d"),{snapshot:l,live:s,recent:c,providers:u,pulses:f,activeRoutes:p,loading:g,error:v}=W3(n);if(g)return o.jsx("div",{className:"text-muted-foreground",children:"Loading…"});if(v||!l)return o.jsxs("div",{className:"text-destructive",children:["Failed to load statistics: ",v??"unknown error"]});const x=s,y=l.previous,b=l.series;function w(C,R){return R>0?(C-R)/R:void 0}const E=b.map(C=>C.requests),j=b.map(C=>C.avgLatency);return o.jsxs("div",{children:[o.jsx(Ya,{title:"Statistics",description:"Real-time monitoring dashboard",actions:o.jsx(OS,{value:n,onValueChange:C=>void a(C),children:o.jsxs(Bp,{children:[o.jsx(pr,{value:"today",children:"Today"}),o.jsx(pr,{value:"7d",children:"7 days"}),o.jsx(pr,{value:"30d",children:"30 days"})]})})}),!l.percentilesAvailable&&o.jsx("p",{className:"mb-3 text-sm text-muted-foreground",children:"Percentiles are unavailable for compacted historical data; cache hit rate is unavailable when provider token semantics were not retained."}),o.jsxs("div",{className:"grid gap-4 md:grid-cols-2 lg:grid-cols-4",children:[o.jsx(tl,{icon:zm,label:"Requests",value:x.totalRequests,delta:w(x.totalRequests,y.totalRequests),sparkData:E}),o.jsx(tl,{icon:ci,label:"Success rate",format:"percent",value:x.successRate,delta:w(x.successRate,y.successRate),sparkData:E,sparkStroke:"stroke-emerald-500"}),o.jsx(tl,{icon:oR,label:"Total tokens",value:x.totalTokens,delta:w(x.totalTokens,y.totalTokens),sparkData:b.map(C=>C.inputTokens+C.outputTokens)}),o.jsx(tl,{icon:iR,label:"Cache hit rate",format:"percent",value:x.cacheHitRate,delta:x.cacheHitRate!==null&&y.cacheHitRate!==null?w(x.cacheHitRate,y.cacheHitRate):void 0,sparkData:b.map(C=>C.cacheRead)}),o.jsx(tl,{icon:rR,label:"Avg latency",format:"latency",value:x.averageLatencyMs,delta:w(x.averageLatencyMs,y.averageLatencyMs),deltaInverse:!0,sparkData:j,sparkStroke:"stroke-amber-500"}),o.jsx(tl,{icon:N0,label:"p95 latency",format:"latency",value:x.p95LatencyMs}),o.jsx(tl,{icon:jR,label:"Avg TTFT",format:"latency",value:x.averageTtftMs}),o.jsx(tl,{icon:vR,label:"Fallback rate",format:"percent",value:x.fallbackRate,delta:w(x.fallbackRate,y.fallbackRate),deltaInverse:!0})]}),o.jsx("div",{className:"mt-6",children:o.jsx(l4,{liveRequests:x.totalRequests,successRate:x.successRate,providers:u,pulses:f,activeRoutes:p})}),o.jsxs("div",{className:"mt-6 grid gap-4 lg:grid-cols-3",children:[o.jsx("div",{className:"lg:col-span-2",children:o.jsx(s4,{rows:c})}),o.jsxs("div",{className:"space-y-4",children:[o.jsxs(tt,{children:[o.jsx(nt,{className:"pb-2",children:o.jsx(at,{className:"text-base",children:"Top Models"})}),o.jsx(rt,{children:o.jsxs(pa,{children:[o.jsx(ga,{children:o.jsxs(We,{children:[o.jsx(be,{children:"Model"}),o.jsx(be,{children:"Req"}),o.jsx(be,{children:"Errors"}),o.jsx(be,{children:"Tokens"})]})}),o.jsxs(va,{children:[l.topModels.length===0&&o.jsx(We,{children:o.jsx(pe,{colSpan:4,className:"text-muted-foreground text-center",children:"No data"})}),l.topModels.map(C=>o.jsxs(We,{children:[o.jsx(pe,{className:"font-mono text-xs",children:C.publicId}),o.jsx(pe,{className:"text-xs",children:Jt(C.requests)}),o.jsx(pe,{className:"text-xs",children:o.jsx("span",{className:C.errorRate>.1?"text-destructive":"text-muted-foreground",children:Cu(C.errorRate)})}),o.jsx(pe,{className:"text-xs",children:Jt(C.totalTokens)})]},C.publicId))]})]})})]}),o.jsxs(tt,{children:[o.jsx(nt,{className:"pb-2",children:o.jsx(at,{className:"text-base",children:"Top API Keys"})}),o.jsx(rt,{children:o.jsxs(pa,{children:[o.jsx(ga,{children:o.jsxs(We,{children:[o.jsx(be,{children:"Key"}),o.jsx(be,{children:"Requests"}),o.jsx(be,{children:"Tokens"})]})}),o.jsxs(va,{children:[l.topApiKeys.length===0&&o.jsx(We,{children:o.jsx(pe,{colSpan:3,className:"text-muted-foreground text-center",children:"No data"})}),l.topApiKeys.map((C,R)=>o.jsxs(We,{children:[o.jsx(pe,{className:"text-xs",children:C.name}),o.jsx(pe,{className:"text-xs",children:Jt(C.requests)}),o.jsx(pe,{className:"text-xs",children:Jt(C.totalTokens)})]},R))]})]})})]})]})]}),o.jsx("div",{className:"mt-6",children:o.jsx(i4,{successRate:x.successRate,averageLatencyMs:x.averageLatencyMs,latencySpark:j})})]})}function u4(){const[n,a]=m.useState([]),[l,s]=m.useState(0);return m.useEffect(()=>{Ce.get("/api/admin/audit?limit=200").then(c=>{a(c.rows),s(c.total)})},[]),o.jsxs("div",{children:[o.jsx(Ya,{title:"Audit Logs",description:`${l} entries · immutable`}),o.jsxs(tt,{children:[o.jsx(nt,{children:o.jsx(at,{className:"text-base",children:"All entries"})}),o.jsx(rt,{children:o.jsxs(pa,{children:[o.jsx(ga,{children:o.jsxs(We,{children:[o.jsx(be,{children:"Time"}),o.jsx(be,{children:"Action"}),o.jsx(be,{children:"Status"}),o.jsx(be,{children:"Target"}),o.jsx(be,{children:"IP"}),o.jsx(be,{children:"Actor"})]})}),o.jsxs(va,{children:[n.length===0&&o.jsx(We,{children:o.jsx(pe,{colSpan:6,className:"text-center text-muted-foreground",children:"No audit events yet."})}),n.map(c=>o.jsxs(We,{children:[o.jsx(pe,{className:"text-xs",children:Um(c.createdAt)}),o.jsx(pe,{className:"font-mono text-xs",children:c.action}),o.jsx(pe,{children:c.success?o.jsx(Xe,{variant:"success",children:"ok"}):o.jsx(Xe,{variant:"destructive",children:"fail"})}),o.jsx(pe,{className:"text-xs",children:c.targetName??c.targetId??"—"}),o.jsx(pe,{className:"text-xs",children:c.ip}),o.jsx(pe,{className:"text-xs",children:c.actor})]},c.id))]})]})})]})]})}const vm={enabled:!0,sound:!0};let ri=vm,xm=!1,Yc=null;const ym=new Set;function LS(){for(const n of ym)n()}function US(n=!1){return xm&&!n?Promise.resolve():(!n&&Yc||(Yc=(async()=>{try{const a=await Ce.get("/api/admin/settings");ri={enabled:a.settings.notificationsEnabled??vm.enabled,sound:a.settings.notificationSoundEnabled??vm.sound},xm=!0,LS()}catch{}})()),Yc)}async function Qb(n){const a={};n.enabled!==void 0&&(a.notificationsEnabled=n.enabled),n.sound!==void 0&&(a.notificationSoundEnabled=n.sound),await Ce.patch("/api/admin/settings",a),ri={...ri,...n},xm=!0,LS()}function d4(n){return ym.add(n),()=>ym.delete(n)}function BS(){return m.useSyncExternalStore(d4,()=>ri,()=>ri)}const bm=m.forwardRef(({className:n,...a},l)=>o.jsx("textarea",{ref:l,className:Ee("flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",n),...a}));bm.displayName="Textarea";function f4(){const[n]=PE(),[a,l]=m.useState(null),[s,c]=m.useState(null),[u,f]=m.useState({current:"",next:""}),[p,g]=m.useState(""),[v,x]=m.useState(""),[y,b]=m.useState(null),[w,E]=m.useState(!1),[j,C]=m.useState("idle"),[R,M]=m.useState(null),T=async(se=!1)=>{C("checking"),M(null);try{const qe=await Ce.get(`/api/admin/update/check${se?"?force=1":""}`);b(qe),C("idle")}catch(qe){M(qe.message),C("error")}},D=async()=>{E(!0),C("installing"),M(null);try{const se=await Ce.post("/api/admin/update/run");C("restarting"),ge.success(se.message||"Update started — the gateway will restart shortly.");const qe=setInterval(()=>{fetch("/health").then(it=>{it.ok&&(clearInterval(qe),window.location.reload())}).catch(()=>{})},3e3);setTimeout(()=>clearInterval(qe),12e4)}catch(se){ge.error(se.message),M(se.message),C("error")}finally{E(!1)}},[_,A]=m.useState("disabled"),[U,O]=m.useState(""),[q,K]=m.useState(""),[te,G]=m.useState(""),[ie,ce]=m.useState([]),[le,k]=m.useState(""),[H,Q]=m.useState(""),[J,ee]=m.useState(!1),[z,I]=m.useState(null),[X,re]=m.useState(""),[fe,ve]=m.useState(""),[V,oe]=m.useState(""),[de,me]=m.useState("compact"),[xe,we]=m.useState("idle"),[Me,Ye]=m.useState(null),Qe=m.useRef(null),[st,Kt]=m.useState(null),ot=async()=>{const se=await Ce.get("/api/admin/settings");l(se.settings),g(se.settings.adminIpAllow??""),x(se.settings.adminIpBlock??"");const qe=await Ce.get("/api/admin/settings/system");c(qe);try{const it=await Ce.get("/api/admin/me");A(it.totpEnabled?"enabled":"disabled")}catch{}};if(m.useEffect(()=>{US(!0)},[]),m.useEffect(()=>{ot(),T(!0)},[]),m.useEffect(()=>{Ce.get("/api/admin/backup/capabilities").then(se=>Kt(se.maxUploadBytes)).catch(()=>Kt(null))},[]),!a)return o.jsx("div",{className:"text-muted-foreground",children:"Loading…"});const Lt=async se=>{try{await Ce.patch("/api/admin/settings",se),ge.success("Saved"),ot()}catch(qe){ge.error(qe.message)}},Ot=async()=>{try{const se=await Ce.post("/api/admin/account/totp/begin");O(se.secret),K(se.qr),A("setup"),ge.info("Scan the QR code with your authenticator app")}catch(se){ge.error(se.message)}},It=async()=>{if(!te||te.length!==6){ge.error("Enter a 6-digit code");return}try{const se=await Ce.post("/api/admin/account/totp/verify",{code:te});ce(se.recoveryCodes),A("showingRecovery"),ge.success("TOTP enabled successfully")}catch(se){ge.error(se.message)}},en=async()=>{if(!le){ge.error("Enter your password");return}if(!H){ge.error("Enter a TOTP code or recovery code");return}try{await Ce.post("/api/admin/account/totp/disable",{password:le,totp:H}),A("disabled"),k(""),Q(""),ge.success("TOTP disabled"),ot()}catch(se){ge.error(se.message)}},Pt=async()=>{ee(!0);try{const se=await Ce.post("/api/admin/account/totp/recovery/regenerate",{password:le,totp:H});ce(se.recoveryCodes),A("showingRecovery"),ge.success("Recovery codes regenerated")}catch(se){ge.error(se.message)}ee(!1)},xt=async()=>{var se,qe;try{const it=await _m("/api/admin/backup/create",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({passphrase:X,profile:de})});if(!it.ok)throw new Error(((qe=(se=await it.json().catch(()=>null))==null?void 0:se.error)==null?void 0:qe.message)??"Backup failed");const Cn=await it.blob(),cn=URL.createObjectURL(Cn),yt=document.createElement("a");yt.href=cn,yt.download=`latedev-backup-${new Date().toISOString().replace(/[:.]/g,"-")}.ldb`,yt.click(),URL.revokeObjectURL(cn),ge.success("Backup downloaded"),re(""),ve("")}catch(it){ge.error(it.message)}},on=async()=>{const se=z;if(!se)return;const qe=new AbortController;Qe.current=qe,Ye({loaded:0,total:se.size,percent:0}),we("uploading");let it;try{const Cn=await Rw({file:se,passphrase:V||void 0,signal:qe.signal,onProgress:cn=>{Ye(cn),cn.percent>=100&&(we("validating"),it=setTimeout(()=>we("restoring"),1500))}});clearTimeout(it),we("complete"),ge.success(Cn.message||"Restored. Reloading…"),I(null),setTimeout(()=>location.reload(),600)}catch(Cn){clearTimeout(it),Cn.name==="AbortError"?(ge.info("Restore cancelled"),we("idle")):(ge.error(Cn.message),we("failed"))}finally{Qe.current=null}},St=xe==="uploading"||xe==="validating"||xe==="restoring",jt=st!==null&&z!==null&&z.size>st,tn=n.get("tab")||"logging";return o.jsxs("div",{children:[o.jsx(Ya,{title:"Settings",description:"Logging, security, backup, and system info"}),o.jsxs(OS,{defaultValue:tn,children:[o.jsxs(Bp,{children:[o.jsx(pr,{value:"logging",children:"Logging"}),o.jsx(pr,{value:"access",children:"Access Control"}),o.jsx(pr,{value:"security",children:"Security"}),o.jsx(pr,{value:"backup",children:"Backup"}),o.jsx(pr,{value:"system",children:"System"})]}),o.jsx(Os,{value:"logging",children:o.jsxs(tt,{children:[o.jsx(nt,{children:o.jsx(at,{className:"text-base",children:"Logging policy"})}),o.jsxs(rt,{className:"space-y-3",children:[o.jsxs("div",{className:"space-y-1",children:[o.jsx(Se,{children:"Request-content logging"}),o.jsxs(Ra,{value:a.contentLogMode,onValueChange:se=>Lt({contentLogMode:se}),children:[o.jsx(da,{children:o.jsx(Na,{})}),o.jsxs(fa,{children:[o.jsx(wt,{value:"off",children:"Off"}),o.jsx(wt,{value:"metadata",children:"Metadata only (default)"}),o.jsx(wt,{value:"prompt",children:"Prompt (sanitized)"}),o.jsx(wt,{value:"prompt_and_response",children:"Prompt + response (sanitized)"})]})]})]}),o.jsxs("div",{className:"space-y-1",children:[o.jsx(Se,{children:"Retention (days)"}),o.jsx(De,{type:"number",min:1,max:3650,value:a.retentionDays,onChange:se=>Lt({retentionDays:Number(se.target.value)})})]}),o.jsxs("div",{className:"space-y-1",children:[o.jsx(Se,{children:"Database size limit (MB)"}),o.jsx(De,{type:"number",min:64,value:a.dbSizeLimitMb,onChange:se=>Lt({dbSizeLimitMb:Number(se.target.value)})})]}),o.jsx("div",{className:"flex items-center gap-2 pt-2",children:o.jsx(he,{onClick:async()=>{const se=await Ce.post("/api/admin/settings/cleanup");ge.success(`Deleted ${se.deletedRequests} old requests`)},children:"Run cleanup now"})})]})]})}),o.jsx(Os,{value:"access",children:o.jsxs(tt,{children:[o.jsxs(nt,{children:[o.jsx(at,{className:"text-base",children:"IP access control"}),o.jsx(bn,{children:"Allowlist / Blocklist for this admin website (not model traffic)"})]}),o.jsxs(rt,{className:"space-y-4",children:[o.jsxs("div",{className:"space-y-2",children:[o.jsx(Se,{children:"Allow only these IPs"}),o.jsx(bm,{placeholder:`192.168.1.0/24
348
+ `},$_={onDragStart(n){let{active:a}=n;return"Picked up draggable item "+a.id+"."},onDragOver(n){let{active:a,over:l}=n;return l?"Draggable item "+a.id+" was moved over droppable area "+l.id+".":"Draggable item "+a.id+" is no longer over a droppable area."},onDragEnd(n){let{active:a,over:l}=n;return l?"Draggable item "+a.id+" was dropped over droppable area "+l.id:"Draggable item "+a.id+" was dropped."},onDragCancel(n){let{active:a}=n;return"Dragging was cancelled. Draggable item "+a.id+" was dropped."}};function Y_(n){let{announcements:a=$_,container:l,hiddenTextDescribedById:s,screenReaderInstructions:c=V_}=n;const{announce:u,announcement:f}=I_(),p=xi("DndLiveRegion"),[g,v]=m.useState(!1);if(m.useEffect(()=>{v(!0)},[]),P_(m.useMemo(()=>({onDragStart(y){let{active:b}=y;u(a.onDragStart({active:b}))},onDragMove(y){let{active:b,over:w}=y;a.onDragMove&&u(a.onDragMove({active:b,over:w}))},onDragOver(y){let{active:b,over:w}=y;u(a.onDragOver({active:b,over:w}))},onDragEnd(y){let{active:b,over:w}=y;u(a.onDragEnd({active:b,over:w}))},onDragCancel(y){let{active:b,over:w}=y;u(a.onDragCancel({active:b,over:w}))}}),[u,a])),!g)return null;const x=ue.createElement(ue.Fragment,null,ue.createElement(B_,{id:s,value:c.draggable}),ue.createElement(H_,{id:p,announcement:f}));return l?Ca.createPortal(x,l):x}var Zt;(function(n){n.DragStart="dragStart",n.DragMove="dragMove",n.DragEnd="dragEnd",n.DragCancel="dragCancel",n.DragOver="dragOver",n.RegisterDroppable="registerDroppable",n.SetDroppableDisabled="setDroppableDisabled",n.UnregisterDroppable="unregisterDroppable"})(Zt||(Zt={}));function fu(){}function Ab(n,a){return m.useMemo(()=>({sensor:n,options:a??{}}),[n,a])}function G_(){for(var n=arguments.length,a=new Array(n),l=0;l<n;l++)a[l]=arguments[l];return m.useMemo(()=>[...a].filter(s=>s!=null),[...a])}const Ma=Object.freeze({x:0,y:0});function iS(n,a){return Math.sqrt(Math.pow(n.x-a.x,2)+Math.pow(n.y-a.y,2))}function cS(n,a){let{data:{value:l}}=n,{data:{value:s}}=a;return l-s}function F_(n,a){let{data:{value:l}}=n,{data:{value:s}}=a;return s-l}function Db(n){let{left:a,top:l,height:s,width:c}=n;return[{x:a,y:l},{x:a+c,y:l},{x:a,y:l+s},{x:a+c,y:l+s}]}function uS(n,a){if(!n||n.length===0)return null;const[l]=n;return l[a]}function Ob(n,a,l){return a===void 0&&(a=n.left),l===void 0&&(l=n.top),{x:a+n.width*.5,y:l+n.height*.5}}const K_=n=>{let{collisionRect:a,droppableRects:l,droppableContainers:s}=n;const c=Ob(a,a.left,a.top),u=[];for(const f of s){const{id:p}=f,g=l.get(p);if(g){const v=iS(Ob(g),c);u.push({id:p,data:{droppableContainer:f,value:v}})}}return u.sort(cS)},X_=n=>{let{collisionRect:a,droppableRects:l,droppableContainers:s}=n;const c=Db(a),u=[];for(const f of s){const{id:p}=f,g=l.get(p);if(g){const v=Db(g),x=c.reduce((b,w,E)=>b+iS(v[E],w),0),y=Number((x/4).toFixed(4));u.push({id:p,data:{droppableContainer:f,value:y}})}}return u.sort(cS)};function Q_(n,a){const l=Math.max(a.top,n.top),s=Math.max(a.left,n.left),c=Math.min(a.left+a.width,n.left+n.width),u=Math.min(a.top+a.height,n.top+n.height),f=c-s,p=u-l;if(s<c&&l<u){const g=a.width*a.height,v=n.width*n.height,x=f*p,y=x/(g+v-x);return Number(y.toFixed(4))}return 0}const Z_=n=>{let{collisionRect:a,droppableRects:l,droppableContainers:s}=n;const c=[];for(const u of s){const{id:f}=u,p=l.get(f);if(p){const g=Q_(p,a);g>0&&c.push({id:f,data:{droppableContainer:u,value:g}})}}return c.sort(F_)};function J_(n,a,l){return{...n,scaleX:a&&l?a.width/l.width:1,scaleY:a&&l?a.height/l.height:1}}function dS(n,a){return n&&a?{x:n.left-a.left,y:n.top-a.top}:Ma}function W_(n){return function(l){for(var s=arguments.length,c=new Array(s>1?s-1:0),u=1;u<s;u++)c[u-1]=arguments[u];return c.reduce((f,p)=>({...f,top:f.top+n*p.y,bottom:f.bottom+n*p.y,left:f.left+n*p.x,right:f.right+n*p.x}),{...l})}}const ek=W_(1);function tk(n){if(n.startsWith("matrix3d(")){const a=n.slice(9,-1).split(/, /);return{x:+a[12],y:+a[13],scaleX:+a[0],scaleY:+a[5]}}else if(n.startsWith("matrix(")){const a=n.slice(7,-1).split(/, /);return{x:+a[4],y:+a[5],scaleX:+a[0],scaleY:+a[3]}}return null}function nk(n,a,l){const s=tk(a);if(!s)return n;const{scaleX:c,scaleY:u,x:f,y:p}=s,g=n.left-f-(1-c)*parseFloat(l),v=n.top-p-(1-u)*parseFloat(l.slice(l.indexOf(" ")+1)),x=c?n.width/c:n.width,y=u?n.height/u:n.height;return{width:x,height:y,top:v,right:g+x,bottom:v+y,left:g}}const ak={ignoreTransform:!1};function Qs(n,a){a===void 0&&(a=ak);let l=n.getBoundingClientRect();if(a.ignoreTransform){const{transform:v,transformOrigin:x}=In(n).getComputedStyle(n);v&&(l=nk(l,v,x))}const{top:s,left:c,width:u,height:f,bottom:p,right:g}=l;return{top:s,left:c,width:u,height:f,bottom:p,right:g}}function _b(n){return Qs(n,{ignoreTransform:!0})}function rk(n){const a=n.innerWidth,l=n.innerHeight;return{top:0,left:0,right:a,bottom:l,width:a,height:l}}function lk(n,a){return a===void 0&&(a=In(n).getComputedStyle(n)),a.position==="fixed"}function sk(n,a){a===void 0&&(a=In(n).getComputedStyle(n));const l=/(auto|scroll|overlay)/;return["overflow","overflowX","overflowY"].some(c=>{const u=a[c];return typeof u=="string"?l.test(u):!1})}function Ku(n,a){const l=[];function s(c){if(a!=null&&l.length>=a||!c)return l;if(Rp(c)&&c.scrollingElement!=null&&!l.includes(c.scrollingElement))return l.push(c.scrollingElement),l;if(!gi(c)||lS(c)||l.includes(c))return l;const u=In(n).getComputedStyle(c);return c!==n&&sk(c,u)&&l.push(c),lk(c,u)?l:s(c.parentNode)}return n?s(n):l}function fS(n){const[a]=Ku(n,1);return a??null}function kh(n){return!Fu||!n?null:Ks(n)?n:Ep(n)?Rp(n)||n===Xs(n).scrollingElement?window:gi(n)?n:null:null}function hS(n){return Ks(n)?n.scrollX:n.scrollLeft}function mS(n){return Ks(n)?n.scrollY:n.scrollTop}function hm(n){return{x:hS(n),y:mS(n)}}var rn;(function(n){n[n.Forward=1]="Forward",n[n.Backward=-1]="Backward"})(rn||(rn={}));function pS(n){return!Fu||!n?!1:n===document.scrollingElement}function gS(n){const a={x:0,y:0},l=pS(n)?{height:window.innerHeight,width:window.innerWidth}:{height:n.clientHeight,width:n.clientWidth},s={x:n.scrollWidth-l.width,y:n.scrollHeight-l.height},c=n.scrollTop<=a.y,u=n.scrollLeft<=a.x,f=n.scrollTop>=s.y,p=n.scrollLeft>=s.x;return{isTop:c,isLeft:u,isBottom:f,isRight:p,maxScroll:s,minScroll:a}}const ok={x:.2,y:.2};function ik(n,a,l,s,c){let{top:u,left:f,right:p,bottom:g}=l;s===void 0&&(s=10),c===void 0&&(c=ok);const{isTop:v,isBottom:x,isLeft:y,isRight:b}=gS(n),w={x:0,y:0},E={x:0,y:0},j={height:a.height*c.y,width:a.width*c.x};return!v&&u<=a.top+j.height?(w.y=rn.Backward,E.y=s*Math.abs((a.top+j.height-u)/j.height)):!x&&g>=a.bottom-j.height&&(w.y=rn.Forward,E.y=s*Math.abs((a.bottom-j.height-g)/j.height)),!b&&p>=a.right-j.width?(w.x=rn.Forward,E.x=s*Math.abs((a.right-j.width-p)/j.width)):!y&&f<=a.left+j.width&&(w.x=rn.Backward,E.x=s*Math.abs((a.left+j.width-f)/j.width)),{direction:w,speed:E}}function ck(n){if(n===document.scrollingElement){const{innerWidth:u,innerHeight:f}=window;return{top:0,left:0,right:u,bottom:f,width:u,height:f}}const{top:a,left:l,right:s,bottom:c}=n.getBoundingClientRect();return{top:a,left:l,right:s,bottom:c,width:n.clientWidth,height:n.clientHeight}}function vS(n){return n.reduce((a,l)=>Us(a,hm(l)),Ma)}function uk(n){return n.reduce((a,l)=>a+hS(l),0)}function dk(n){return n.reduce((a,l)=>a+mS(l),0)}function fk(n,a){if(a===void 0&&(a=Qs),!n)return;const{top:l,left:s,bottom:c,right:u}=a(n);fS(n)&&(c<=0||u<=0||l>=window.innerHeight||s>=window.innerWidth)&&n.scrollIntoView({block:"center",inline:"center"})}const hk=[["x",["left","right"],uk],["y",["top","bottom"],dk]];class Mp{constructor(a,l){this.rect=void 0,this.width=void 0,this.height=void 0,this.top=void 0,this.bottom=void 0,this.right=void 0,this.left=void 0;const s=Ku(l),c=vS(s);this.rect={...a},this.width=a.width,this.height=a.height;for(const[u,f,p]of hk)for(const g of f)Object.defineProperty(this,g,{get:()=>{const v=p(s),x=c[u]-v;return this.rect[g]+x},enumerable:!0});Object.defineProperty(this,"rect",{enumerable:!1})}}class Ko{constructor(a){this.target=void 0,this.listeners=[],this.removeAll=()=>{this.listeners.forEach(l=>{var s;return(s=this.target)==null?void 0:s.removeEventListener(...l)})},this.target=a}add(a,l,s){var c;(c=this.target)==null||c.addEventListener(a,l,s),this.listeners.push([a,l,s])}}function mk(n){const{EventTarget:a}=In(n);return n instanceof a?n:Xs(n)}function zh(n,a){const l=Math.abs(n.x),s=Math.abs(n.y);return typeof a=="number"?Math.sqrt(l**2+s**2)>a:"x"in a&&"y"in a?l>a.x&&s>a.y:"x"in a?l>a.x:"y"in a?s>a.y:!1}var ca;(function(n){n.Click="click",n.DragStart="dragstart",n.Keydown="keydown",n.ContextMenu="contextmenu",n.Resize="resize",n.SelectionChange="selectionchange",n.VisibilityChange="visibilitychange"})(ca||(ca={}));function kb(n){n.preventDefault()}function pk(n){n.stopPropagation()}var Fe;(function(n){n.Space="Space",n.Down="ArrowDown",n.Right="ArrowRight",n.Left="ArrowLeft",n.Up="ArrowUp",n.Esc="Escape",n.Enter="Enter",n.Tab="Tab"})(Fe||(Fe={}));const xS={start:[Fe.Space,Fe.Enter],cancel:[Fe.Esc],end:[Fe.Space,Fe.Enter,Fe.Tab]},gk=(n,a)=>{let{currentCoordinates:l}=a;switch(n.code){case Fe.Right:return{...l,x:l.x+25};case Fe.Left:return{...l,x:l.x-25};case Fe.Down:return{...l,y:l.y+25};case Fe.Up:return{...l,y:l.y-25}}};class Ap{constructor(a){this.props=void 0,this.autoScrollEnabled=!1,this.referenceCoordinates=void 0,this.listeners=void 0,this.windowListeners=void 0,this.props=a;const{event:{target:l}}=a;this.props=a,this.listeners=new Ko(Xs(l)),this.windowListeners=new Ko(In(l)),this.handleKeyDown=this.handleKeyDown.bind(this),this.handleCancel=this.handleCancel.bind(this),this.attach()}attach(){this.handleStart(),this.windowListeners.add(ca.Resize,this.handleCancel),this.windowListeners.add(ca.VisibilityChange,this.handleCancel),setTimeout(()=>this.listeners.add(ca.Keydown,this.handleKeyDown))}handleStart(){const{activeNode:a,onStart:l}=this.props,s=a.node.current;s&&fk(s),l(Ma)}handleKeyDown(a){if(Tp(a)){const{active:l,context:s,options:c}=this.props,{keyboardCodes:u=xS,coordinateGetter:f=gk,scrollBehavior:p="smooth"}=c,{code:g}=a;if(u.end.includes(g)){this.handleEnd(a);return}if(u.cancel.includes(g)){this.handleCancel(a);return}const{collisionRect:v}=s.current,x=v?{x:v.left,y:v.top}:Ma;this.referenceCoordinates||(this.referenceCoordinates=x);const y=f(a,{active:l,context:s.current,currentCoordinates:x});if(y){const b=ni(y,x),w={x:0,y:0},{scrollableAncestors:E}=s.current;for(const j of E){const C=a.code,{isTop:R,isRight:M,isLeft:T,isBottom:D,maxScroll:_,minScroll:A}=gS(j),U=ck(j),O={x:Math.min(C===Fe.Right?U.right-U.width/2:U.right,Math.max(C===Fe.Right?U.left:U.left+U.width/2,y.x)),y:Math.min(C===Fe.Down?U.bottom-U.height/2:U.bottom,Math.max(C===Fe.Down?U.top:U.top+U.height/2,y.y))},q=C===Fe.Right&&!M||C===Fe.Left&&!T,K=C===Fe.Down&&!D||C===Fe.Up&&!R;if(q&&O.x!==y.x){const te=j.scrollLeft+b.x,G=C===Fe.Right&&te<=_.x||C===Fe.Left&&te>=A.x;if(G&&!b.y){j.scrollTo({left:te,behavior:p});return}G?w.x=j.scrollLeft-te:w.x=C===Fe.Right?j.scrollLeft-_.x:j.scrollLeft-A.x,w.x&&j.scrollBy({left:-w.x,behavior:p});break}else if(K&&O.y!==y.y){const te=j.scrollTop+b.y,G=C===Fe.Down&&te<=_.y||C===Fe.Up&&te>=A.y;if(G&&!b.x){j.scrollTo({top:te,behavior:p});return}G?w.y=j.scrollTop-te:w.y=C===Fe.Down?j.scrollTop-_.y:j.scrollTop-A.y,w.y&&j.scrollBy({top:-w.y,behavior:p});break}}this.handleMove(a,Us(ni(y,this.referenceCoordinates),w))}}}handleMove(a,l){const{onMove:s}=this.props;a.preventDefault(),s(l)}handleEnd(a){const{onEnd:l}=this.props;a.preventDefault(),this.detach(),l()}handleCancel(a){const{onCancel:l}=this.props;a.preventDefault(),this.detach(),l()}detach(){this.listeners.removeAll(),this.windowListeners.removeAll()}}Ap.activators=[{eventName:"onKeyDown",handler:(n,a,l)=>{let{keyboardCodes:s=xS,onActivation:c}=a,{active:u}=l;const{code:f}=n.nativeEvent;if(s.start.includes(f)){const p=u.activatorNode.current;return p&&n.target!==p?!1:(n.preventDefault(),c==null||c({event:n.nativeEvent}),!0)}return!1}}];function zb(n){return!!(n&&"distance"in n)}function Lb(n){return!!(n&&"delay"in n)}class Dp{constructor(a,l,s){var c;s===void 0&&(s=mk(a.event.target)),this.props=void 0,this.events=void 0,this.autoScrollEnabled=!0,this.document=void 0,this.activated=!1,this.initialCoordinates=void 0,this.timeoutId=null,this.listeners=void 0,this.documentListeners=void 0,this.windowListeners=void 0,this.props=a,this.events=l;const{event:u}=a,{target:f}=u;this.props=a,this.events=l,this.document=Xs(f),this.documentListeners=new Ko(this.document),this.listeners=new Ko(s),this.windowListeners=new Ko(In(f)),this.initialCoordinates=(c=fm(u))!=null?c:Ma,this.handleStart=this.handleStart.bind(this),this.handleMove=this.handleMove.bind(this),this.handleEnd=this.handleEnd.bind(this),this.handleCancel=this.handleCancel.bind(this),this.handleKeydown=this.handleKeydown.bind(this),this.removeTextSelection=this.removeTextSelection.bind(this),this.attach()}attach(){const{events:a,props:{options:{activationConstraint:l,bypassActivationConstraint:s}}}=this;if(this.listeners.add(a.move.name,this.handleMove,{passive:!1}),this.listeners.add(a.end.name,this.handleEnd),a.cancel&&this.listeners.add(a.cancel.name,this.handleCancel),this.windowListeners.add(ca.Resize,this.handleCancel),this.windowListeners.add(ca.DragStart,kb),this.windowListeners.add(ca.VisibilityChange,this.handleCancel),this.windowListeners.add(ca.ContextMenu,kb),this.documentListeners.add(ca.Keydown,this.handleKeydown),l){if(s!=null&&s({event:this.props.event,activeNode:this.props.activeNode,options:this.props.options}))return this.handleStart();if(Lb(l)){this.timeoutId=setTimeout(this.handleStart,l.delay),this.handlePending(l);return}if(zb(l)){this.handlePending(l);return}}this.handleStart()}detach(){this.listeners.removeAll(),this.windowListeners.removeAll(),setTimeout(this.documentListeners.removeAll,50),this.timeoutId!==null&&(clearTimeout(this.timeoutId),this.timeoutId=null)}handlePending(a,l){const{active:s,onPending:c}=this.props;c(s,a,this.initialCoordinates,l)}handleStart(){const{initialCoordinates:a}=this,{onStart:l}=this.props;a&&(this.activated=!0,this.documentListeners.add(ca.Click,pk,{capture:!0}),this.removeTextSelection(),this.documentListeners.add(ca.SelectionChange,this.removeTextSelection),l(a))}handleMove(a){var l;const{activated:s,initialCoordinates:c,props:u}=this,{onMove:f,options:{activationConstraint:p}}=u;if(!c)return;const g=(l=fm(a))!=null?l:Ma,v=ni(c,g);if(!s&&p){if(zb(p)){if(p.tolerance!=null&&zh(v,p.tolerance))return this.handleCancel();if(zh(v,p.distance))return this.handleStart()}if(Lb(p)&&zh(v,p.tolerance))return this.handleCancel();this.handlePending(p,v);return}a.cancelable&&a.preventDefault(),f(g)}handleEnd(){const{onAbort:a,onEnd:l}=this.props;this.detach(),this.activated||a(this.props.active),l()}handleCancel(){const{onAbort:a,onCancel:l}=this.props;this.detach(),this.activated||a(this.props.active),l()}handleKeydown(a){a.code===Fe.Esc&&this.handleCancel()}removeTextSelection(){var a;(a=this.document.getSelection())==null||a.removeAllRanges()}}const vk={cancel:{name:"pointercancel"},move:{name:"pointermove"},end:{name:"pointerup"}};class Op extends Dp{constructor(a){const{event:l}=a,s=Xs(l.target);super(a,vk,s)}}Op.activators=[{eventName:"onPointerDown",handler:(n,a)=>{let{nativeEvent:l}=n,{onActivation:s}=a;return!l.isPrimary||l.button!==0?!1:(s==null||s({event:l}),!0)}}];const xk={move:{name:"mousemove"},end:{name:"mouseup"}};var mm;(function(n){n[n.RightClick=2]="RightClick"})(mm||(mm={}));class yk extends Dp{constructor(a){super(a,xk,Xs(a.event.target))}}yk.activators=[{eventName:"onMouseDown",handler:(n,a)=>{let{nativeEvent:l}=n,{onActivation:s}=a;return l.button===mm.RightClick?!1:(s==null||s({event:l}),!0)}}];const Lh={cancel:{name:"touchcancel"},move:{name:"touchmove"},end:{name:"touchend"}};class bk extends Dp{constructor(a){super(a,Lh)}static setup(){return window.addEventListener(Lh.move.name,a,{capture:!1,passive:!1}),function(){window.removeEventListener(Lh.move.name,a)};function a(){}}}bk.activators=[{eventName:"onTouchStart",handler:(n,a)=>{let{nativeEvent:l}=n,{onActivation:s}=a;const{touches:c}=l;return c.length>1?!1:(s==null||s({event:l}),!0)}}];var Xo;(function(n){n[n.Pointer=0]="Pointer",n[n.DraggableRect=1]="DraggableRect"})(Xo||(Xo={}));var hu;(function(n){n[n.TreeOrder=0]="TreeOrder",n[n.ReversedTreeOrder=1]="ReversedTreeOrder"})(hu||(hu={}));function wk(n){let{acceleration:a,activator:l=Xo.Pointer,canScroll:s,draggingRect:c,enabled:u,interval:f=5,order:p=hu.TreeOrder,pointerCoordinates:g,scrollableAncestors:v,scrollableAncestorRects:x,delta:y,threshold:b}=n;const w=jk({delta:y,disabled:!u}),[E,j]=__(),C=m.useRef({x:0,y:0}),R=m.useRef({x:0,y:0}),M=m.useMemo(()=>{switch(l){case Xo.Pointer:return g?{top:g.y,bottom:g.y,left:g.x,right:g.x}:null;case Xo.DraggableRect:return c}},[l,c,g]),T=m.useRef(null),D=m.useCallback(()=>{const A=T.current;if(!A)return;const U=C.current.x*R.current.x,O=C.current.y*R.current.y;A.scrollBy(U,O)},[]),_=m.useMemo(()=>p===hu.TreeOrder?[...v].reverse():v,[p,v]);m.useEffect(()=>{if(!u||!v.length||!M){j();return}for(const A of _){if((s==null?void 0:s(A))===!1)continue;const U=v.indexOf(A),O=x[U];if(!O)continue;const{direction:q,speed:K}=ik(A,O,M,a,b);for(const te of["x","y"])w[te][q[te]]||(K[te]=0,q[te]=0);if(K.x>0||K.y>0){j(),T.current=A,E(D,f),C.current=K,R.current=q;return}}C.current={x:0,y:0},R.current={x:0,y:0},j()},[a,D,s,j,u,f,JSON.stringify(M),JSON.stringify(w),E,v,_,x,JSON.stringify(b)])}const Sk={x:{[rn.Backward]:!1,[rn.Forward]:!1},y:{[rn.Backward]:!1,[rn.Forward]:!1}};function jk(n){let{delta:a,disabled:l}=n;const s=dm(a);return vi(c=>{if(l||!s||!c)return Sk;const u={x:Math.sign(a.x-s.x),y:Math.sign(a.y-s.y)};return{x:{[rn.Backward]:c.x[rn.Backward]||u.x===-1,[rn.Forward]:c.x[rn.Forward]||u.x===1},y:{[rn.Backward]:c.y[rn.Backward]||u.y===-1,[rn.Forward]:c.y[rn.Forward]||u.y===1}}},[l,a,s])}function Ck(n,a){const l=a!=null?n.get(a):void 0,s=l?l.node.current:null;return vi(c=>{var u;return a==null?null:(u=s??c)!=null?u:null},[s,a])}function Ek(n,a){return m.useMemo(()=>n.reduce((l,s)=>{const{sensor:c}=s,u=c.activators.map(f=>({eventName:f.eventName,handler:a(f.handler,s)}));return[...l,...u]},[]),[n,a])}var ai;(function(n){n[n.Always=0]="Always",n[n.BeforeDragging=1]="BeforeDragging",n[n.WhileDragging=2]="WhileDragging"})(ai||(ai={}));var pm;(function(n){n.Optimized="optimized"})(pm||(pm={}));const Ub=new Map;function Rk(n,a){let{dragging:l,dependencies:s,config:c}=a;const[u,f]=m.useState(null),{frequency:p,measure:g,strategy:v}=c,x=m.useRef(n),y=C(),b=ti(y),w=m.useCallback(function(R){R===void 0&&(R=[]),!b.current&&f(M=>M===null?R:M.concat(R.filter(T=>!M.includes(T))))},[b]),E=m.useRef(null),j=vi(R=>{if(y&&!l)return Ub;if(!R||R===Ub||x.current!==n||u!=null){const M=new Map;for(let T of n){if(!T)continue;if(u&&u.length>0&&!u.includes(T.id)&&T.rect.current){M.set(T.id,T.rect.current);continue}const D=T.node.current,_=D?new Mp(g(D),D):null;T.rect.current=_,_&&M.set(T.id,_)}return M}return R},[n,u,l,y,g]);return m.useEffect(()=>{x.current=n},[n]),m.useEffect(()=>{y||w()},[l,y]),m.useEffect(()=>{u&&u.length>0&&f(null)},[JSON.stringify(u)]),m.useEffect(()=>{y||typeof p!="number"||E.current!==null||(E.current=setTimeout(()=>{w(),E.current=null},p))},[p,y,w,...s]),{droppableRects:j,measureDroppableContainers:w,measuringScheduled:u!=null};function C(){switch(v){case ai.Always:return!1;case ai.BeforeDragging:return l;default:return!l}}}function yS(n,a){return vi(l=>n?l||(typeof a=="function"?a(n):n):null,[a,n])}function Nk(n,a){return yS(n,a)}function Tk(n){let{callback:a,disabled:l}=n;const s=Np(a),c=m.useMemo(()=>{if(l||typeof window>"u"||typeof window.MutationObserver>"u")return;const{MutationObserver:u}=window;return new u(s)},[s,l]);return m.useEffect(()=>()=>c==null?void 0:c.disconnect(),[c]),c}function Xu(n){let{callback:a,disabled:l}=n;const s=Np(a),c=m.useMemo(()=>{if(l||typeof window>"u"||typeof window.ResizeObserver>"u")return;const{ResizeObserver:u}=window;return new u(s)},[l]);return m.useEffect(()=>()=>c==null?void 0:c.disconnect(),[c]),c}function Mk(n){return new Mp(Qs(n),n)}function Bb(n,a,l){a===void 0&&(a=Mk);const[s,c]=m.useState(null);function u(){c(g=>{if(!n)return null;if(n.isConnected===!1){var v;return(v=g??l)!=null?v:null}const x=a(n);return JSON.stringify(g)===JSON.stringify(x)?g:x})}const f=Tk({callback(g){if(n)for(const v of g){const{type:x,target:y}=v;if(x==="childList"&&y instanceof HTMLElement&&y.contains(n)){u();break}}}}),p=Xu({callback:u});return Va(()=>{u(),n?(p==null||p.observe(n),f==null||f.observe(document.body,{childList:!0,subtree:!0})):(p==null||p.disconnect(),f==null||f.disconnect())},[n]),s}function Ak(n){const a=yS(n);return dS(n,a)}const Hb=[];function Dk(n){const a=m.useRef(n),l=vi(s=>n?s&&s!==Hb&&n&&a.current&&n.parentNode===a.current.parentNode?s:Ku(n):Hb,[n]);return m.useEffect(()=>{a.current=n},[n]),l}function Ok(n){const[a,l]=m.useState(null),s=m.useRef(n),c=m.useCallback(u=>{const f=kh(u.target);f&&l(p=>p?(p.set(f,hm(f)),new Map(p)):null)},[]);return m.useEffect(()=>{const u=s.current;if(n!==u){f(u);const p=n.map(g=>{const v=kh(g);return v?(v.addEventListener("scroll",c,{passive:!0}),[v,hm(v)]):null}).filter(g=>g!=null);l(p.length?new Map(p):null),s.current=n}return()=>{f(n),f(u)};function f(p){p.forEach(g=>{const v=kh(g);v==null||v.removeEventListener("scroll",c)})}},[c,n]),m.useMemo(()=>n.length?a?Array.from(a.values()).reduce((u,f)=>Us(u,f),Ma):vS(n):Ma,[n,a])}function Ib(n,a){a===void 0&&(a=[]);const l=m.useRef(null);return m.useEffect(()=>{l.current=null},a),m.useEffect(()=>{const s=n!==Ma;s&&!l.current&&(l.current=n),!s&&l.current&&(l.current=null)},[n]),l.current?ni(n,l.current):Ma}function _k(n){m.useEffect(()=>{if(!Fu)return;const a=n.map(l=>{let{sensor:s}=l;return s.setup==null?void 0:s.setup()});return()=>{for(const l of a)l==null||l()}},n.map(a=>{let{sensor:l}=a;return l}))}function kk(n,a){return m.useMemo(()=>n.reduce((l,s)=>{let{eventName:c,handler:u}=s;return l[c]=f=>{u(f,a)},l},{}),[n,a])}function bS(n){return m.useMemo(()=>n?rk(n):null,[n])}const Pb=[];function zk(n,a){a===void 0&&(a=Qs);const[l]=n,s=bS(l?In(l):null),[c,u]=m.useState(Pb);function f(){u(()=>n.length?n.map(g=>pS(g)?s:new Mp(a(g),g)):Pb)}const p=Xu({callback:f});return Va(()=>{p==null||p.disconnect(),f(),n.forEach(g=>p==null?void 0:p.observe(g))},[n]),c}function Lk(n){if(!n)return null;if(n.children.length>1)return n;const a=n.children[0];return gi(a)?a:n}function Uk(n){let{measure:a}=n;const[l,s]=m.useState(null),c=m.useCallback(v=>{for(const{target:x}of v)if(gi(x)){s(y=>{const b=a(x);return y?{...y,width:b.width,height:b.height}:b});break}},[a]),u=Xu({callback:c}),f=m.useCallback(v=>{const x=Lk(v);u==null||u.disconnect(),x&&(u==null||u.observe(x)),s(x?a(x):null)},[a,u]),[p,g]=uu(f);return m.useMemo(()=>({nodeRef:p,rect:l,setRef:g}),[l,p,g])}const Bk=[{sensor:Op,options:{}},{sensor:Ap,options:{}}],Hk={current:{}},eu={draggable:{measure:_b},droppable:{measure:_b,strategy:ai.WhileDragging,frequency:pm.Optimized},dragOverlay:{measure:Qs}};class Qo extends Map{get(a){var l;return a!=null&&(l=super.get(a))!=null?l:void 0}toArray(){return Array.from(this.values())}getEnabled(){return this.toArray().filter(a=>{let{disabled:l}=a;return!l})}getNodeFor(a){var l,s;return(l=(s=this.get(a))==null?void 0:s.node.current)!=null?l:void 0}}const Ik={activatorEvent:null,active:null,activeNode:null,activeNodeRect:null,collisions:null,containerNodeRect:null,draggableNodes:new Map,droppableRects:new Map,droppableContainers:new Qo,over:null,dragOverlay:{nodeRef:{current:null},rect:null,setRef:fu},scrollableAncestors:[],scrollableAncestorRects:[],measuringConfiguration:eu,measureDroppableContainers:fu,windowRect:null,measuringScheduled:!1},Pk={activatorEvent:null,activators:[],active:null,activeNodeRect:null,ariaDescribedById:{draggable:""},dispatch:fu,draggableNodes:new Map,over:null,measureDroppableContainers:fu},Qu=m.createContext(Pk),wS=m.createContext(Ik);function qk(){return{draggable:{active:null,initialCoordinates:{x:0,y:0},nodes:new Map,translate:{x:0,y:0}},droppable:{containers:new Qo}}}function Vk(n,a){switch(a.type){case Zt.DragStart:return{...n,draggable:{...n.draggable,initialCoordinates:a.initialCoordinates,active:a.active}};case Zt.DragMove:return n.draggable.active==null?n:{...n,draggable:{...n.draggable,translate:{x:a.coordinates.x-n.draggable.initialCoordinates.x,y:a.coordinates.y-n.draggable.initialCoordinates.y}}};case Zt.DragEnd:case Zt.DragCancel:return{...n,draggable:{...n.draggable,active:null,initialCoordinates:{x:0,y:0},translate:{x:0,y:0}}};case Zt.RegisterDroppable:{const{element:l}=a,{id:s}=l,c=new Qo(n.droppable.containers);return c.set(s,l),{...n,droppable:{...n.droppable,containers:c}}}case Zt.SetDroppableDisabled:{const{id:l,key:s,disabled:c}=a,u=n.droppable.containers.get(l);if(!u||s!==u.key)return n;const f=new Qo(n.droppable.containers);return f.set(l,{...u,disabled:c}),{...n,droppable:{...n.droppable,containers:f}}}case Zt.UnregisterDroppable:{const{id:l,key:s}=a,c=n.droppable.containers.get(l);if(!c||s!==c.key)return n;const u=new Qo(n.droppable.containers);return u.delete(l),{...n,droppable:{...n.droppable,containers:u}}}default:return n}}function $k(n){let{disabled:a}=n;const{active:l,activatorEvent:s,draggableNodes:c}=m.useContext(Qu),u=dm(s),f=dm(l==null?void 0:l.id);return m.useEffect(()=>{if(!a&&!s&&u&&f!=null){if(!Tp(u)||document.activeElement===u.target)return;const p=c.get(f);if(!p)return;const{activatorNode:g,node:v}=p;if(!g.current&&!v.current)return;requestAnimationFrame(()=>{for(const x of[g.current,v.current]){if(!x)continue;const y=L_(x);if(y){y.focus();break}}})}},[s,a,c,f,u]),null}function Yk(n,a){let{transform:l,...s}=a;return n!=null&&n.length?n.reduce((c,u)=>u({transform:c,...s}),l):l}function Gk(n){return m.useMemo(()=>({draggable:{...eu.draggable,...n==null?void 0:n.draggable},droppable:{...eu.droppable,...n==null?void 0:n.droppable},dragOverlay:{...eu.dragOverlay,...n==null?void 0:n.dragOverlay}}),[n==null?void 0:n.draggable,n==null?void 0:n.droppable,n==null?void 0:n.dragOverlay])}function Fk(n){let{activeNode:a,measure:l,initialRect:s,config:c=!0}=n;const u=m.useRef(!1),{x:f,y:p}=typeof c=="boolean"?{x:c,y:c}:c;Va(()=>{if(!f&&!p||!a){u.current=!1;return}if(u.current||!s)return;const v=a==null?void 0:a.node.current;if(!v||v.isConnected===!1)return;const x=l(v),y=dS(x,s);if(f||(y.x=0),p||(y.y=0),u.current=!0,Math.abs(y.x)>0||Math.abs(y.y)>0){const b=fS(v);b&&b.scrollBy({top:y.y,left:y.x})}},[a,f,p,s,l])}const SS=m.createContext({...Ma,scaleX:1,scaleY:1});var rl;(function(n){n[n.Uninitialized=0]="Uninitialized",n[n.Initializing=1]="Initializing",n[n.Initialized=2]="Initialized"})(rl||(rl={}));const Kk=m.memo(function(a){var l,s,c,u;let{id:f,accessibility:p,autoScroll:g=!0,children:v,sensors:x=Bk,collisionDetection:y=Z_,measuring:b,modifiers:w,...E}=a;const j=m.useReducer(Vk,void 0,qk),[C,R]=j,[M,T]=q_(),[D,_]=m.useState(rl.Uninitialized),A=D===rl.Initialized,{draggable:{active:U,nodes:O,translate:q},droppable:{containers:K}}=C,te=U!=null?O.get(U):null,G=m.useRef({initial:null,translated:null}),ie=m.useMemo(()=>{var Ct;return U!=null?{id:U,data:(Ct=te==null?void 0:te.data)!=null?Ct:Hk,rect:G}:null},[U,te]),ce=m.useRef(null),[le,k]=m.useState(null),[H,Q]=m.useState(null),J=ti(E,Object.values(E)),ee=xi("DndDescribedBy",f),z=m.useMemo(()=>K.getEnabled(),[K]),I=Gk(b),{droppableRects:X,measureDroppableContainers:re,measuringScheduled:fe}=Rk(z,{dragging:A,dependencies:[q.x,q.y],config:I.droppable}),ve=Ck(O,U),V=m.useMemo(()=>H?fm(H):null,[H]),oe=Tr(),de=Nk(ve,I.draggable.measure);Fk({activeNode:U!=null?O.get(U):null,config:oe.layoutShiftCompensation,initialRect:de,measure:I.draggable.measure});const me=Bb(ve,I.draggable.measure,de),xe=Bb(ve?ve.parentElement:null),we=m.useRef({activatorEvent:null,active:null,activeNode:ve,collisionRect:null,collisions:null,droppableRects:X,draggableNodes:O,draggingNode:null,draggingNodeRect:null,droppableContainers:K,over:null,scrollableAncestors:[],scrollAdjustedTranslate:null}),Me=K.getNodeFor((l=we.current.over)==null?void 0:l.id),Ye=Uk({measure:I.dragOverlay.measure}),Qe=(s=Ye.nodeRef.current)!=null?s:ve,st=A?(c=Ye.rect)!=null?c:me:null,Kt=!!(Ye.nodeRef.current&&Ye.rect),ot=Ak(Kt?null:me),Lt=bS(Qe?In(Qe):null),Ot=Dk(A?Me??ve:null),It=zk(Ot),en=Yk(w,{transform:{x:q.x-ot.x,y:q.y-ot.y,scaleX:1,scaleY:1},activatorEvent:H,active:ie,activeNodeRect:me,containerNodeRect:xe,draggingNodeRect:st,over:we.current.over,overlayNodeRect:Ye.rect,scrollableAncestors:Ot,scrollableAncestorRects:It,windowRect:Lt}),Pt=V?Us(V,q):null,xt=Ok(Ot),on=Ib(xt),St=Ib(xt,[me]),jt=Us(en,on),tn=st?ek(st,en):null,se=ie&&tn?y({active:ie,collisionRect:tn,droppableRects:X,droppableContainers:z,pointerCoordinates:Pt}):null,qe=uS(se,"id"),[it,Cn]=m.useState(null),cn=Kt?en:Us(en,St),yt=J_(cn,(u=it==null?void 0:it.rect)!=null?u:null,me),vn=m.useRef(null),_t=m.useCallback((Ct,lt)=>{let{sensor:qt,options:Re}=lt;if(ce.current==null)return;const ke=O.get(ce.current);if(!ke)return;const Le=Ct.nativeEvent,bt=new qt({active:ce.current,activeNode:ke,event:Le,options:Re,context:we,onAbort(dt){if(!O.get(dt))return;const{onDragAbort:Et}=J.current,Ut={id:dt};Et==null||Et(Ut),M({type:"onDragAbort",event:Ut})},onPending(dt,Xt,Et,Ut){if(!O.get(dt))return;const{onDragPending:Ka}=J.current,xa={id:dt,constraint:Xt,initialCoordinates:Et,offset:Ut};Ka==null||Ka(xa),M({type:"onDragPending",event:xa})},onStart(dt){const Xt=ce.current;if(Xt==null)return;const Et=O.get(Xt);if(!Et)return;const{onDragStart:Ut}=J.current,Fa={activatorEvent:Le,active:{id:Xt,data:Et.data,rect:G}};Ca.unstable_batchedUpdates(()=>{Ut==null||Ut(Fa),_(rl.Initializing),R({type:Zt.DragStart,initialCoordinates:dt,active:Xt}),M({type:"onDragStart",event:Fa}),k(vn.current),Q(Le)})},onMove(dt){R({type:Zt.DragMove,coordinates:dt})},onEnd:Mt(Zt.DragEnd),onCancel:Mt(Zt.DragCancel)});vn.current=bt;function Mt(dt){return async function(){const{active:Et,collisions:Ut,over:Fa,scrollAdjustedTranslate:Ka}=we.current;let xa=null;if(Et&&Ka){const{cancelDrop:Mr}=J.current;xa={activatorEvent:Le,active:Et,collisions:Ut,delta:Ka,over:Fa},dt===Zt.DragEnd&&typeof Mr=="function"&&await Promise.resolve(Mr(xa))&&(dt=Zt.DragCancel)}ce.current=null,Ca.unstable_batchedUpdates(()=>{R({type:dt}),_(rl.Uninitialized),Cn(null),k(null),Q(null),vn.current=null;const Mr=dt===Zt.DragEnd?"onDragEnd":"onDragCancel";if(xa){const Zn=J.current[Mr];Zn==null||Zn(xa),M({type:Mr,event:xa})}})}}},[O]),Js=m.useCallback((Ct,lt)=>(qt,Re)=>{const ke=qt.nativeEvent,Le=O.get(Re);if(ce.current!==null||!Le||ke.dndKit||ke.defaultPrevented)return;const bt={active:Le};Ct(qt,lt.options,bt)===!0&&(ke.dndKit={capturedBy:lt.sensor},ce.current=Re,_t(qt,lt))},[O,_t]),Pl=Ek(x,Js);_k(x),Va(()=>{me&&D===rl.Initializing&&_(rl.Initialized)},[me,D]),m.useEffect(()=>{const{onDragMove:Ct}=J.current,{active:lt,activatorEvent:qt,collisions:Re,over:ke}=we.current;if(!lt||!qt)return;const Le={active:lt,activatorEvent:qt,collisions:Re,delta:{x:jt.x,y:jt.y},over:ke};Ca.unstable_batchedUpdates(()=>{Ct==null||Ct(Le),M({type:"onDragMove",event:Le})})},[jt.x,jt.y]),m.useEffect(()=>{const{active:Ct,activatorEvent:lt,collisions:qt,droppableContainers:Re,scrollAdjustedTranslate:ke}=we.current;if(!Ct||ce.current==null||!lt||!ke)return;const{onDragOver:Le}=J.current,bt=Re.get(qe),Mt=bt&&bt.rect.current?{id:bt.id,rect:bt.rect.current,data:bt.data,disabled:bt.disabled}:null,dt={active:Ct,activatorEvent:lt,collisions:qt,delta:{x:ke.x,y:ke.y},over:Mt};Ca.unstable_batchedUpdates(()=>{Cn(Mt),Le==null||Le(dt),M({type:"onDragOver",event:dt})})},[qe]),Va(()=>{we.current={activatorEvent:H,active:ie,activeNode:ve,collisionRect:tn,collisions:se,droppableRects:X,draggableNodes:O,draggingNode:Qe,draggingNodeRect:st,droppableContainers:K,over:it,scrollableAncestors:Ot,scrollAdjustedTranslate:jt},G.current={initial:st,translated:tn}},[ie,ve,se,tn,O,Qe,st,X,K,it,Ot,jt]),wk({...oe,delta:q,draggingRect:tn,pointerCoordinates:Pt,scrollableAncestors:Ot,scrollableAncestorRects:It});const ql=m.useMemo(()=>({active:ie,activeNode:ve,activeNodeRect:me,activatorEvent:H,collisions:se,containerNodeRect:xe,dragOverlay:Ye,draggableNodes:O,droppableContainers:K,droppableRects:X,over:it,measureDroppableContainers:re,scrollableAncestors:Ot,scrollableAncestorRects:It,measuringConfiguration:I,measuringScheduled:fe,windowRect:Lt}),[ie,ve,me,H,se,xe,Ye,O,K,X,it,re,Ot,It,I,fe,Lt]),Ga=m.useMemo(()=>({activatorEvent:H,activators:Pl,active:ie,activeNodeRect:me,ariaDescribedById:{draggable:ee},dispatch:R,draggableNodes:O,over:it,measureDroppableContainers:re}),[H,Pl,ie,me,R,ee,O,it,re]);return ue.createElement(oS.Provider,{value:T},ue.createElement(Qu.Provider,{value:Ga},ue.createElement(wS.Provider,{value:ql},ue.createElement(SS.Provider,{value:yt},v)),ue.createElement($k,{disabled:(p==null?void 0:p.restoreFocus)===!1})),ue.createElement(Y_,{...p,hiddenTextDescribedById:ee}));function Tr(){const Ct=(le==null?void 0:le.autoScrollEnabled)===!1,lt=typeof g=="object"?g.enabled===!1:g===!1,qt=A&&!Ct&&!lt;return typeof g=="object"?{...g,enabled:qt}:{enabled:qt}}}),Xk=m.createContext(null),qb="button",Qk="Draggable";function Zk(n){let{id:a,data:l,disabled:s=!1,attributes:c}=n;const u=xi(Qk),{activators:f,activatorEvent:p,active:g,activeNodeRect:v,ariaDescribedById:x,draggableNodes:y,over:b}=m.useContext(Qu),{role:w=qb,roleDescription:E="draggable",tabIndex:j=0}=c??{},C=(g==null?void 0:g.id)===a,R=m.useContext(C?SS:Xk),[M,T]=uu(),[D,_]=uu(),A=kk(f,a),U=ti(l);Va(()=>(y.set(a,{id:a,key:u,node:M,activatorNode:D,data:U}),()=>{const q=y.get(a);q&&q.key===u&&y.delete(a)}),[y,a]);const O=m.useMemo(()=>({role:w,tabIndex:j,"aria-disabled":s,"aria-pressed":C&&w===qb?!0:void 0,"aria-roledescription":E,"aria-describedby":x.draggable}),[s,w,j,C,E,x.draggable]);return{active:g,activatorEvent:p,activeNodeRect:v,attributes:O,isDragging:C,listeners:s?void 0:A,node:M,over:b,setNodeRef:T,setActivatorNodeRef:_,transform:R}}function Jk(){return m.useContext(wS)}const Wk="Droppable",e3={timeout:25};function t3(n){let{data:a,disabled:l=!1,id:s,resizeObserverConfig:c}=n;const u=xi(Wk),{active:f,dispatch:p,over:g,measureDroppableContainers:v}=m.useContext(Qu),x=m.useRef({disabled:l}),y=m.useRef(!1),b=m.useRef(null),w=m.useRef(null),{disabled:E,updateMeasurementsFor:j,timeout:C}={...e3,...c},R=ti(j??s),M=m.useCallback(()=>{if(!y.current){y.current=!0;return}w.current!=null&&clearTimeout(w.current),w.current=setTimeout(()=>{v(Array.isArray(R.current)?R.current:[R.current]),w.current=null},C)},[C]),T=Xu({callback:M,disabled:E||!f}),D=m.useCallback((O,q)=>{T&&(q&&(T.unobserve(q),y.current=!1),O&&T.observe(O))},[T]),[_,A]=uu(D),U=ti(a);return m.useEffect(()=>{!T||!_.current||(T.disconnect(),y.current=!1,T.observe(_.current))},[_,T]),m.useEffect(()=>(p({type:Zt.RegisterDroppable,element:{id:s,key:u,disabled:l,node:_,rect:b,data:U}}),()=>p({type:Zt.UnregisterDroppable,key:u,id:s})),[s]),m.useEffect(()=>{l!==x.current.disabled&&(p({type:Zt.SetDroppableDisabled,id:s,key:u,disabled:l}),x.current.disabled=l)},[s,u,l,p]),{active:f,rect:b,isOver:(g==null?void 0:g.id)===s,node:_,over:g,setNodeRef:A}}function n3(n,a,l){const s={...n};return a.top+n.y<=l.top?s.y=l.top-a.top:a.bottom+n.y>=l.top+l.height&&(s.y=l.top+l.height-a.bottom),a.left+n.x<=l.left?s.x=l.left-a.left:a.right+n.x>=l.left+l.width&&(s.x=l.left+l.width-a.right),s}const a3=n=>{let{containerNodeRect:a,draggingNodeRect:l,transform:s}=n;return!l||!a?s:n3(s,l,a)},r3=n=>{let{transform:a}=n;return{...a,x:0}};function _p(n,a,l){const s=n.slice();return s.splice(l<0?s.length+l:l,0,s.splice(a,1)[0]),s}function l3(n,a){return n.reduce((l,s,c)=>{const u=a.get(s);return u&&(l[c]=u),l},Array(n.length))}function Pc(n){return n!==null&&n>=0}function s3(n,a){if(n===a)return!0;if(n.length!==a.length)return!1;for(let l=0;l<n.length;l++)if(n[l]!==a[l])return!1;return!0}function o3(n){return typeof n=="boolean"?{draggable:n,droppable:n}:n}const jS=n=>{let{rects:a,activeIndex:l,overIndex:s,index:c}=n;const u=_p(a,s,l),f=a[c],p=u[c];return!p||!f?null:{x:p.left-f.left,y:p.top-f.top,scaleX:p.width/f.width,scaleY:p.height/f.height}},qc={scaleX:1,scaleY:1},i3=n=>{var a;let{activeIndex:l,activeNodeRect:s,index:c,rects:u,overIndex:f}=n;const p=(a=u[l])!=null?a:s;if(!p)return null;if(c===l){const v=u[f];return v?{x:0,y:l<f?v.top+v.height-(p.top+p.height):v.top-p.top,...qc}:null}const g=c3(u,c,l);return c>l&&c<=f?{x:0,y:-p.height-g,...qc}:c<l&&c>=f?{x:0,y:p.height+g,...qc}:{x:0,y:0,...qc}};function c3(n,a,l){const s=n[a],c=n[a-1],u=n[a+1];return s?l<a?c?s.top-(c.top+c.height):u?u.top-(s.top+s.height):0:u?u.top-(s.top+s.height):c?s.top-(c.top+c.height):0:0}const CS="Sortable",ES=ue.createContext({activeIndex:-1,containerId:CS,disableTransforms:!1,items:[],overIndex:-1,useDragOverlay:!1,sortedRects:[],strategy:jS,disabled:{draggable:!1,droppable:!1}});function u3(n){let{children:a,id:l,items:s,strategy:c=jS,disabled:u=!1}=n;const{active:f,dragOverlay:p,droppableRects:g,over:v,measureDroppableContainers:x}=Jk(),y=xi(CS,l),b=p.rect!==null,w=m.useMemo(()=>s.map(A=>typeof A=="object"&&"id"in A?A.id:A),[s]),E=f!=null,j=f?w.indexOf(f.id):-1,C=v?w.indexOf(v.id):-1,R=m.useRef(w),M=!s3(w,R.current),T=C!==-1&&j===-1||M,D=o3(u);Va(()=>{M&&E&&x(w)},[M,w,E,x]),m.useEffect(()=>{R.current=w},[w]);const _=m.useMemo(()=>({activeIndex:j,containerId:y,disabled:D,disableTransforms:T,items:w,overIndex:C,useDragOverlay:b,sortedRects:l3(w,g),strategy:c}),[j,y,D.draggable,D.droppable,T,w,C,g,b,c]);return ue.createElement(ES.Provider,{value:_},a)}const d3=n=>{let{id:a,items:l,activeIndex:s,overIndex:c}=n;return _p(l,s,c).indexOf(a)},f3=n=>{let{containerId:a,isSorting:l,wasDragging:s,index:c,items:u,newIndex:f,previousItems:p,previousContainerId:g,transition:v}=n;return!v||!s||p!==u&&c===f?!1:l?!0:f!==c&&a===g},h3={duration:200,easing:"ease"},RS="transform",m3=du.Transition.toString({property:RS,duration:0,easing:"linear"}),p3={roleDescription:"sortable"};function g3(n){let{disabled:a,index:l,node:s,rect:c}=n;const[u,f]=m.useState(null),p=m.useRef(l);return Va(()=>{if(!a&&l!==p.current&&s.current){const g=c.current;if(g){const v=Qs(s.current,{ignoreTransform:!0}),x={x:g.left-v.left,y:g.top-v.top,scaleX:g.width/v.width,scaleY:g.height/v.height};(x.x||x.y)&&f(x)}}l!==p.current&&(p.current=l)},[a,l,s,c]),m.useEffect(()=>{u&&f(null)},[u]),u}function v3(n){let{animateLayoutChanges:a=f3,attributes:l,disabled:s,data:c,getNewIndex:u=d3,id:f,strategy:p,resizeObserverConfig:g,transition:v=h3}=n;const{items:x,containerId:y,activeIndex:b,disabled:w,disableTransforms:E,sortedRects:j,overIndex:C,useDragOverlay:R,strategy:M}=m.useContext(ES),T=x3(s,w),D=x.indexOf(f),_=m.useMemo(()=>({sortable:{containerId:y,index:D,items:x},...c}),[y,c,D,x]),A=m.useMemo(()=>x.slice(x.indexOf(f)),[x,f]),{rect:U,node:O,isOver:q,setNodeRef:K}=t3({id:f,data:_,disabled:T.droppable,resizeObserverConfig:{updateMeasurementsFor:A,...g}}),{active:te,activatorEvent:G,activeNodeRect:ie,attributes:ce,setNodeRef:le,listeners:k,isDragging:H,over:Q,setActivatorNodeRef:J,transform:ee}=Zk({id:f,data:_,attributes:{...p3,...l},disabled:T.draggable}),z=O_(K,le),I=!!te,X=I&&!E&&Pc(b)&&Pc(C),re=!R&&H,fe=re&&X?ee:null,V=X?fe??(p??M)({rects:j,activeNodeRect:ie,activeIndex:b,overIndex:C,index:D}):null,oe=Pc(b)&&Pc(C)?u({id:f,items:x,activeIndex:b,overIndex:C}):D,de=te==null?void 0:te.id,me=m.useRef({activeId:de,items:x,newIndex:oe,containerId:y}),xe=x!==me.current.items,we=a({active:te,containerId:y,isDragging:H,isSorting:I,id:f,index:D,items:x,newIndex:me.current.newIndex,previousItems:me.current.items,previousContainerId:me.current.containerId,transition:v,wasDragging:me.current.activeId!=null}),Me=g3({disabled:!we,index:D,node:O,rect:U});return m.useEffect(()=>{I&&me.current.newIndex!==oe&&(me.current.newIndex=oe),y!==me.current.containerId&&(me.current.containerId=y),x!==me.current.items&&(me.current.items=x)},[I,oe,y,x]),m.useEffect(()=>{if(de===me.current.activeId)return;if(de!=null&&me.current.activeId==null){me.current.activeId=de;return}const Qe=setTimeout(()=>{me.current.activeId=de},50);return()=>clearTimeout(Qe)},[de]),{active:te,activeIndex:b,attributes:ce,data:_,rect:U,index:D,newIndex:oe,items:x,isOver:q,isSorting:I,isDragging:H,listeners:k,node:O,overIndex:C,over:Q,setNodeRef:z,setActivatorNodeRef:J,setDroppableNodeRef:K,setDraggableNodeRef:le,transform:Me??V,transition:Ye()};function Ye(){if(Me||xe&&me.current.newIndex===D)return m3;if(!(re&&!Tp(G)||!v)&&(I||we))return du.Transition.toString({...v,property:RS})}}function x3(n,a){var l,s;return typeof n=="boolean"?{draggable:n,droppable:!1}:{draggable:(l=n==null?void 0:n.draggable)!=null?l:a.draggable,droppable:(s=n==null?void 0:n.droppable)!=null?s:a.droppable}}function mu(n){if(!n)return!1;const a=n.data.current;return!!(a&&"sortable"in a&&typeof a.sortable=="object"&&"containerId"in a.sortable&&"items"in a.sortable&&"index"in a.sortable)}const y3=[Fe.Down,Fe.Right,Fe.Up,Fe.Left],b3=(n,a)=>{let{context:{active:l,collisionRect:s,droppableRects:c,droppableContainers:u,over:f,scrollableAncestors:p}}=a;if(y3.includes(n.code)){if(n.preventDefault(),!l||!s)return;const g=[];u.getEnabled().forEach(y=>{if(!y||y!=null&&y.disabled)return;const b=c.get(y.id);if(b)switch(n.code){case Fe.Down:s.top<b.top&&g.push(y);break;case Fe.Up:s.top>b.top&&g.push(y);break;case Fe.Left:s.left>b.left&&g.push(y);break;case Fe.Right:s.left<b.left&&g.push(y);break}});const v=X_({collisionRect:s,droppableRects:c,droppableContainers:g});let x=uS(v,"id");if(x===(f==null?void 0:f.id)&&v.length>1&&(x=v[1].id),x!=null){const y=u.get(l.id),b=u.get(x),w=b?c.get(b.id):null,E=b==null?void 0:b.node.current;if(E&&w&&y&&b){const C=Ku(E).some((A,U)=>p[U]!==A),R=NS(y,b),M=w3(y,b),T=C||!R?{x:0,y:0}:{x:M?s.width-w.width:0,y:M?s.height-w.height:0},D={x:w.left,y:w.top};return T.x&&T.y?D:ni(D,T)}}}};function NS(n,a){return!mu(n)||!mu(a)?!1:n.data.current.sortable.containerId===a.data.current.sortable.containerId}function w3(n,a){return!mu(n)||!mu(a)||!NS(n,a)?!1:n.data.current.sortable.index<a.data.current.sortable.index}const Uh={maxTotalAttempts:3,fallbackOnConnection:!0,fallbackOnConnectTimeout:!0,fallbackOnFirstTokenTimeout:!0,fallbackOn408:!0,fallbackOn429:!0,fallbackOn5xx:!0},S3={member_disabled:"member disabled",model_missing:"model missing",provider_disabled:"provider disabled",provider_down:"provider down",model_disabled:"model disabled",upstream_unavailable:"upstream unavailable",circuit_open:"circuit open",chat_capability_unavailable:"chat capability unavailable"},pu=n=>n.map((a,l)=>({...a,position:l}));function j3(){const[n,a]=m.useState([]),[l,s]=m.useState([]),[c,u]=m.useState(!1),[f,p]=m.useState(!1),[g,v]=m.useState(null),[x,y]=m.useState(!1),[b,w]=m.useState(!1),[E,j]=m.useState(null),[C,R]=m.useState(null),[M,T]=m.useState({name:"",slug:"",enabled:!0,...Uh,members:[]}),[D,_]=m.useState({name:"",slug:"",enabled:!0,...Uh,members:[]}),[A,U]=m.useState(null),O=async()=>{const[k,H]=await Promise.all([Ce.get("/api/admin/combos"),Ce.get("/api/admin/models")]);a(k.combos),s(H.models)};m.useEffect(()=>{O()},[]);const q=async k=>{j(k.id);try{R(await Ce.post("/api/admin/combos/"+k.id+"/test"))}catch(H){ge.error(H.message)}finally{j(null)}},K=async()=>{if(M.members.length===0){ge.error("Add at least one member");return}y(!0);try{await Ce.post("/api/admin/combos",{name:M.name,slug:M.slug.trim()||void 0,enabled:M.enabled,...M,members:M.members}),ge.success("Combo created"),u(!1),T({name:"",slug:"",enabled:!0,...Uh,members:[]}),O()}catch(k){ge.error(k.message)}finally{y(!1)}},te=async k=>{try{const Q=(await Ce.get(`/api/admin/combos/${k.id}`)).combo;v(Q.id),_({name:Q.name,slug:Q.publicModelId.startsWith("combo/")?Q.slug:"",enabled:Q.enabled,maxTotalAttempts:Q.maxTotalAttempts,fallbackOnConnection:Q.fallbackOnConnection,fallbackOnConnectTimeout:Q.fallbackOnConnectTimeout,fallbackOnFirstTokenTimeout:Q.fallbackOnFirstTokenTimeout,fallbackOn408:Q.fallbackOn408,fallbackOn429:Q.fallbackOn429,fallbackOn5xx:Q.fallbackOn5xx,members:Q.members.map(J=>({modelId:J.modelId,position:J.position,enabled:J.enabled}))}),p(!0)}catch(H){ge.error(H.message)}},G=async()=>{if(g){if(D.members.length===0){ge.error("Add at least one member");return}w(!0);try{await Ce.patch("/api/admin/combos",{id:g,name:D.name,slug:D.slug.trim()||void 0,enabled:D.enabled,...D,members:D.members}),ge.success("Combo updated"),p(!1),v(null),O()}catch(k){ge.error(k.message)}finally{w(!1)}}},ie=k=>{T(H=>({...H,members:pu([...H.members,{modelId:k,position:H.members.length,enabled:!0}])}))},ce=k=>{_(H=>({...H,members:pu([...H.members,{modelId:k,position:H.members.length,enabled:!0}])}))},le=async k=>{try{await Ce.del(`/api/admin/combos/${k}`),ge.success("Combo removed"),U(null),O()}catch(H){ge.error(H.message)}};return o.jsxs("div",{children:[o.jsx(Ya,{title:"Combos",description:"Virtual models combining physical models",actions:o.jsxs(kn,{open:c,onOpenChange:u,children:[o.jsx(mi,{asChild:!0,children:o.jsxs(he,{children:[o.jsx(wu,{className:"mr-1 h-4 w-4"})," New combo"]})}),o.jsxs(wn,{className:"max-h-[calc(100vh-2rem)] max-w-2xl grid-rows-[auto_minmax(0,1fr)_auto] overflow-hidden",children:[o.jsx(Sn,{children:o.jsx(jn,{children:"New combo"})}),o.jsxs("div",{className:"min-h-0 space-y-3 overflow-y-auto pr-1",children:[o.jsxs("div",{children:[o.jsx(Se,{children:"Name"}),o.jsx(De,{value:M.name,onChange:k=>T({...M,name:k.target.value})})]}),o.jsxs("div",{children:[o.jsx(Se,{children:"Slug (optional — empty uses the name as the model ID)"}),o.jsx(De,{value:M.slug,onChange:k=>T({...M,slug:k.target.value}),placeholder:"empty → gpt-5.5 · set → combo/gpt-5.5"})]}),o.jsxs("div",{className:"flex items-center gap-2",children:[o.jsx(Ta,{checked:M.enabled,onCheckedChange:k=>T({...M,enabled:k})}),o.jsx(Se,{children:"Enabled"})]}),o.jsx(Vb,{value:M,onChange:k=>T(H=>({...H,...k}))}),o.jsxs("div",{children:[o.jsx(Se,{children:"Members — priority order · drag to reorder"}),o.jsx(Gb,{models:l,addedIds:M.members.map(k=>k.modelId),onAdd:ie}),o.jsx($b,{members:M.members,modelFor:k=>l.find(H=>H.id===k.modelId)??null}),o.jsx(Yb,{className:"mt-2",members:M.members,label:k=>{var H;return((H=l.find(Q=>Q.id===k.modelId))==null?void 0:H.publicModelId)??k.modelId},modelFor:k=>l.find(H=>H.id===k.modelId)??null,onChange:k=>T(H=>({...H,members:k}))})]})]}),o.jsxs(zn,{children:[o.jsx(he,{variant:"outline",onClick:()=>u(!1),children:"Cancel"}),o.jsx(he,{disabled:!M.name||x,onClick:K,children:x?"Creating…":"Create"})]})]})]})}),o.jsxs(tt,{children:[o.jsxs(nt,{children:[o.jsx(at,{className:"text-base",children:"All combos"}),o.jsxs(bn,{children:[n.length," total"]})]}),o.jsx(rt,{children:o.jsxs(pa,{children:[o.jsx(ga,{children:o.jsxs(We,{children:[o.jsx(be,{children:"Public ID"}),o.jsx(be,{children:"Members"}),o.jsx(be,{children:"Status"}),o.jsx(be,{children:"Enabled"}),o.jsx(be,{})]})}),o.jsxs(va,{children:[n.length===0&&o.jsx(We,{children:o.jsx(pe,{colSpan:5,className:"text-center text-muted-foreground",children:"No combos yet."})}),n.map(k=>o.jsxs(We,{children:[o.jsx(pe,{className:"font-mono text-xs",children:k.publicModelId}),o.jsx(pe,{children:k.memberCount}),o.jsxs(pe,{children:[o.jsxs(Xe,{variant:k.status==="ready"?"success":k.status==="disabled"?"secondary":"destructive",children:[k.healthyMemberCount,"/",k.memberCount," ready"]}),k.capabilityWarnings.length>0&&o.jsx("div",{className:"text-xs text-amber-600",children:"Capability metadata differs"}),k.status==="unavailable"&&k.unavailableReasons.length>0&&o.jsx("div",{className:"text-xs text-muted-foreground",children:k.unavailableReasons.map(H=>S3[H]??H).join(", ")})]}),o.jsx(pe,{children:k.enabled?"Yes":"No"}),o.jsx(pe,{className:"text-right",children:o.jsxs("div",{className:"flex items-center justify-end gap-1",children:[o.jsxs(he,{size:"sm",variant:"outline",title:"Sends a real non-streaming inference request",onClick:()=>void q(k),disabled:E===k.id,children:[E===k.id?o.jsx(_s,{className:"mr-1 h-3.5 w-3.5 animate-spin"}):o.jsx(D0,{className:"mr-1 h-3.5 w-3.5"})," Test"]}),o.jsxs(he,{size:"sm",variant:"outline",onClick:()=>void te(k),children:[o.jsx(wR,{className:"h-3.5 w-3.5"})," Sửa"]}),o.jsxs(he,{size:"sm",variant:"destructive",onClick:()=>U(k),children:[o.jsx(Su,{className:"h-3.5 w-3.5"})," Delete"]})]})})]},k.id))]})]})})]}),o.jsx(kn,{open:f,onOpenChange:p,children:o.jsxs(wn,{className:"max-h-[calc(100vh-2rem)] max-w-2xl grid-rows-[auto_minmax(0,1fr)_auto] overflow-hidden",children:[o.jsx(Sn,{children:o.jsx(jn,{children:"Edit combo"})}),o.jsxs("div",{className:"min-h-0 space-y-3 overflow-y-auto pr-1",children:[o.jsxs("div",{children:[o.jsx(Se,{children:"Name"}),o.jsx(De,{value:D.name,onChange:k=>_({...D,name:k.target.value})})]}),o.jsxs("div",{children:[o.jsx(Se,{children:"Slug (optional — leave empty to use the name as the model ID)"}),o.jsx(De,{value:D.slug,onChange:k=>_({...D,slug:k.target.value}),placeholder:"empty → gpt-5.5 · set → combo/gpt-5.5"})]}),o.jsxs("div",{className:"flex items-center gap-2",children:[o.jsx(Ta,{checked:D.enabled,onCheckedChange:k=>_({...D,enabled:k})}),o.jsx(Se,{children:"Enabled"})]}),o.jsx(Vb,{value:D,onChange:k=>_(H=>({...H,...k}))}),o.jsxs("div",{children:[o.jsx(Se,{children:"Members — priority order · drag to reorder"}),o.jsx(Gb,{models:l,addedIds:D.members.map(k=>k.modelId),onAdd:ce}),o.jsx($b,{members:D.members,modelFor:k=>l.find(H=>H.id===k.modelId)??null}),o.jsx(Yb,{className:"mt-2",members:D.members,label:k=>{var H;return((H=l.find(Q=>Q.id===k.modelId))==null?void 0:H.publicModelId)??k.modelId},modelFor:k=>l.find(H=>H.id===k.modelId)??null,onChange:k=>_(H=>({...H,members:k}))})]})]}),o.jsxs(zn,{children:[o.jsx(he,{variant:"outline",onClick:()=>p(!1),children:"Cancel"}),o.jsx(he,{disabled:!D.name||b,onClick:G,children:b?"Saving…":"Save"})]})]})}),o.jsx(kn,{open:C!==null,onOpenChange:k=>{k||R(null)},children:o.jsxs(wn,{className:"max-w-2xl",children:[o.jsxs(Sn,{children:[o.jsx(jn,{children:"Combo test result"}),o.jsx("p",{className:"text-sm text-muted-foreground",children:"Test sends a real non-streaming inference request through this combo."})]}),C&&o.jsx(C3,{result:C}),o.jsx(zn,{children:o.jsx(he,{onClick:()=>R(null),children:"Close"})})]})}),o.jsx(dp,{open:A!==null,onOpenChange:k=>{k||U(null)},children:o.jsxs(Iu,{children:[o.jsxs(fp,{children:[o.jsx(Pu,{children:"Delete combo?"}),o.jsx(qu,{children:"This removes the virtual model and its ordered fallback configuration. Request history is preserved."})]}),o.jsxs(hp,{children:[o.jsx($u,{children:"Cancel"}),o.jsx(Vu,{onClick:()=>A&&void le(A.id),children:"Delete"})]})]})})]})}function Vb({value:n,onChange:a}){const l=[["fallbackOnConnection","Connection failure"],["fallbackOnConnectTimeout","Connect timeout"],["fallbackOnFirstTokenTimeout","First-token timeout"],["fallbackOn408","HTTP 408"],["fallbackOn429","HTTP 429"],["fallbackOn5xx","HTTP 5xx"]];return o.jsxs("div",{className:"rounded border bg-muted/20 p-3",children:[o.jsx("div",{className:"mb-2 text-sm font-medium",children:"Fallback policy"}),o.jsxs("div",{className:"grid gap-3 sm:grid-cols-[10rem_1fr]",children:[o.jsxs("div",{children:[o.jsx(Se,{children:"Max total attempts"}),o.jsx(De,{type:"number",min:1,max:8,value:n.maxTotalAttempts,onChange:s=>a({maxTotalAttempts:Math.min(8,Math.max(1,Number(s.target.value)||1))})})]}),o.jsx("div",{className:"grid gap-2 sm:grid-cols-2",children:l.map(([s,c])=>o.jsxs("label",{className:"flex items-center gap-2 text-xs",children:[o.jsx(Ta,{checked:!!n[s],onCheckedChange:u=>a({[s]:u})}),o.jsx("span",{children:c})]},s))})]})]})}function $b({members:n,modelFor:a}){if(n.length===0)return null;const l=n.map(a).filter(c=>!!c),s=["chat","streaming","tools","structured_output","image_input","reasoning"].filter(c=>new Set(l.map(u=>u.capabilities[c]===!0?"yes":u.capabilities[c]===!1?"no":"unknown")).size>1);return o.jsxs("div",{className:"rounded border bg-muted/20 p-2 text-xs",children:[o.jsxs("div",{className:"mb-1 font-medium",children:["Route preview ",o.jsx("span",{className:"font-normal text-muted-foreground",children:"(first available member wins)"})]}),s.length>0&&o.jsxs("div",{className:"mb-2 flex items-center gap-1 text-amber-600",children:[o.jsx(_0,{className:"h-3.5 w-3.5"})," Members differ on: ",s.join(", ")]}),o.jsx("div",{className:"space-y-1",children:n.map((c,u)=>{const f=a(c);return o.jsxs("div",{className:"flex items-center gap-2 font-mono",children:[o.jsxs("span",{className:"w-4 text-muted-foreground",children:[u+1,"."]}),o.jsx("span",{children:(f==null?void 0:f.publicModelId)??c.modelId}),o.jsxs("span",{className:"text-muted-foreground",children:["→ ",(f==null?void 0:f.upstreamModelId)??"upstream model unknown"]})]},c.id??c.modelId)})})]})}function C3({result:n}){return o.jsxs("div",{className:"space-y-4",children:[o.jsxs("div",{className:"flex items-center justify-between rounded border p-3",children:[o.jsxs("div",{className:"flex items-center gap-2",children:[n.success?o.jsx(ci,{className:"h-4 w-4 text-emerald-600"}):o.jsx(_0,{className:"h-4 w-4 text-amber-600"}),o.jsx(Xe,{variant:n.success?"success":"warning",children:n.success?"Success":"Failed"})]}),o.jsxs("span",{className:"text-xs text-muted-foreground",children:[n.latencyMs," ms total"]})]}),o.jsxs("div",{children:[o.jsx("div",{className:"mb-1 text-sm font-medium",children:"Selected upstream"}),n.selectedModel?o.jsxs("div",{className:"rounded border bg-muted/20 p-2 font-mono text-xs",children:[n.selectedModel.publicModelId," → ",n.selectedModel.upstreamModelId,o.jsxs("span",{className:"ml-2 text-muted-foreground",children:["(",n.selectedModel.providerSlug,")"]})]}):o.jsx("p",{className:"text-sm text-muted-foreground",children:"No member completed successfully."})]}),o.jsxs("div",{children:[o.jsx("div",{className:"mb-1 text-sm font-medium",children:"Attempts"}),o.jsx("div",{className:"space-y-1",children:n.attempts.map((a,l)=>o.jsxs("div",{className:"flex items-center gap-2 rounded border p-2 text-xs",children:[o.jsxs("span",{className:"w-4 text-muted-foreground",children:[l+1,"."]}),o.jsxs("span",{className:"min-w-0 flex-1 font-mono",children:[a.publicModelId," → ",a.upstreamModelId]}),o.jsxs("span",{className:"text-muted-foreground",children:[a.latencyMs," ms"]}),o.jsx(Xe,{variant:a.success?"success":"warning",children:a.success?"Used":a.failureReason??"Skipped"})]},a.publicModelId+"-"+l))})]}),n.text&&o.jsx("pre",{className:"max-h-32 overflow-auto whitespace-pre-wrap rounded border bg-muted/20 p-2 text-xs",children:n.text})]})}function Yb({members:n,label:a,modelFor:l,onChange:s,className:c}){const u=G_(Ab(Op,{activationConstraint:{distance:4}}),Ab(Ap,{coordinateGetter:b3}));if(n.length===0)return o.jsx("p",{className:Ee("text-xs text-muted-foreground",c),children:"No members yet — add at least one."});const f=({active:p,over:g})=>{!g||p.id===g.id||s(pu(_p(n,Number(p.id),Number(g.id))))};return o.jsx(Kk,{sensors:u,collisionDetection:K_,modifiers:[r3,a3],onDragEnd:f,children:o.jsx(u3,{items:n.map((p,g)=>g),strategy:i3,children:o.jsx("div",{className:Ee("space-y-1",c),children:n.map((p,g)=>o.jsx(E3,{index:g,label:a(p),model:l(p),onRemove:()=>s(pu(n.filter((v,x)=>x!==g)))},p.id??p.modelId))})})})}function E3({index:n,label:a,model:l,onRemove:s}){const{attributes:c,listeners:u,setNodeRef:f,transform:p,transition:g,isDragging:v}=v3({id:n});return o.jsxs("div",{ref:f,style:{transform:p?`translate3d(${p.x}px, ${p.y}px, 0)`:void 0,transition:g},className:Ee("flex items-center gap-2 rounded border p-2 text-sm",v&&"relative z-10 bg-muted/60 shadow-sm"),children:[o.jsx("button",{type:"button",...c,...u,"aria-label":`Reorder ${a}`,title:"Drag to change priority",className:"cursor-grab touch-none rounded p-1 text-muted-foreground hover:bg-muted hover:text-foreground active:cursor-grabbing",children:o.jsx(fR,{className:"h-4 w-4"})}),o.jsx("span",{className:"w-5 text-xs tabular-nums text-muted-foreground",children:n+1}),o.jsxs("div",{className:"min-w-0 flex-1",children:[o.jsx("div",{className:"truncate font-mono text-xs",children:a}),o.jsxs("div",{className:"truncate text-[11px] text-muted-foreground",children:[(l==null?void 0:l.providerSlug)||"provider"," · upstream: ",(l==null?void 0:l.upstreamModelId)??"unknown"]})]}),o.jsx(Xe,{variant:l&&l.enabled&&l.providerEnabled&&l.providerHealth!=="down"&&l.providerHealth!=="circuit_open"&&!l.circuitOpen&&l.upstreamAvailable&&l.capabilities.chat!==!1?"success":"warning",children:l&&l.enabled&&l.providerEnabled&&l.providerHealth!=="down"&&l.providerHealth!=="circuit_open"&&!l.circuitOpen&&l.upstreamAvailable&&l.capabilities.chat!==!1?"Ready":"Unavailable"}),o.jsx(he,{size:"sm",variant:"outline",onClick:s,children:"Remove"})]})}function Gb({models:n,addedIds:a,onAdd:l}){const[s,c]=m.useState(""),f=(s?n.filter(p=>{const g=s.toLowerCase();return p.publicModelId.toLowerCase().includes(g)||p.displayName.toLowerCase().includes(g)}):n).filter(p=>!a.includes(p.id));return o.jsxs("div",{className:"space-y-1",children:[o.jsxs("div",{className:"relative",children:[o.jsx(O0,{className:"absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground"}),o.jsx(De,{className:"pl-8",placeholder:"Search models…",value:s,onChange:p=>c(p.target.value)}),s&&o.jsx("button",{className:"absolute right-2 top-2.5 text-muted-foreground hover:text-foreground",onClick:()=>c(""),children:o.jsx(ju,{className:"h-4 w-4"})})]}),f.length===0?o.jsx("p",{className:"text-xs text-muted-foreground",children:"No models match."}):o.jsx("div",{className:"max-h-40 space-y-1 overflow-auto rounded border p-1",children:f.map(p=>o.jsxs("div",{className:"flex items-center justify-between rounded p-1 text-sm hover:bg-accent",children:[o.jsx("span",{className:"font-mono text-xs",children:p.publicModelId}),o.jsx(he,{size:"sm",variant:"ghost",onClick:()=>l(p.id),children:"+ Add"})]},p.id))})]})}function R3(){const[n,a]=m.useState([]),[l,s]=m.useState([]),[c,u]=m.useState([]),[f,p]=m.useState(!1),[g,v]=m.useState({alias:"",targetKind:"model",targetId:"",enabled:!0}),x=async()=>{const[b,w,E]=await Promise.all([Ce.get("/api/admin/aliases"),Ce.get("/api/admin/models"),Ce.get("/api/admin/combos")]);a(b.aliases),s(w.models),u(E.combos)};m.useEffect(()=>{x()},[]);const y=async()=>{try{await Ce.post("/api/admin/aliases",g),ge.success("Alias created"),p(!1),v({alias:"",targetKind:"model",targetId:"",enabled:!0}),x()}catch(b){ge.error(b.message)}};return o.jsxs("div",{children:[o.jsx(Ya,{title:"Aliases",description:"Stable client-visible names for models or combos",actions:o.jsxs(kn,{open:f,onOpenChange:p,children:[o.jsx(mi,{asChild:!0,children:o.jsxs(he,{children:[o.jsx(wu,{className:"mr-1 h-4 w-4"})," New alias"]})}),o.jsxs(wn,{children:[o.jsx(Sn,{children:o.jsx(jn,{children:"New alias"})}),o.jsxs("div",{className:"space-y-3",children:[o.jsxs("div",{children:[o.jsx(Se,{children:"Alias"}),o.jsx(De,{value:g.alias,onChange:b=>v({...g,alias:b.target.value}),placeholder:"coding"})]}),o.jsxs("div",{children:[o.jsx(Se,{children:"Target type"}),o.jsxs(Ra,{value:g.targetKind,onValueChange:b=>v({...g,targetKind:b}),children:[o.jsx(da,{children:o.jsx(Na,{})}),o.jsxs(fa,{children:[o.jsx(wt,{value:"model",children:"Model"}),o.jsx(wt,{value:"combo",children:"Combo"})]})]})]}),o.jsxs("div",{children:[o.jsx(Se,{children:"Target"}),o.jsxs(Ra,{value:g.targetId,onValueChange:b=>v({...g,targetId:b}),children:[o.jsx(da,{children:o.jsx(Na,{placeholder:"Choose target"})}),o.jsx(fa,{children:(g.targetKind==="model"?l:c).map(b=>o.jsx(wt,{value:b.id,children:b.publicModelId},b.id))})]})]}),o.jsxs("div",{className:"flex items-center gap-2",children:[o.jsx(Ta,{checked:g.enabled,onCheckedChange:b=>v({...g,enabled:b})}),o.jsx(Se,{children:"Enabled"})]})]}),o.jsxs(zn,{children:[o.jsx(he,{variant:"outline",onClick:()=>p(!1),children:"Cancel"}),o.jsx(he,{disabled:!g.alias||!g.targetId,onClick:y,children:"Create"})]})]})]})}),o.jsxs(tt,{children:[o.jsxs(nt,{children:[o.jsx(at,{className:"text-base",children:"All aliases"}),o.jsxs(bn,{children:[n.length," total"]})]}),o.jsx(rt,{children:o.jsxs(pa,{children:[o.jsx(ga,{children:o.jsxs(We,{children:[o.jsx(be,{children:"Alias"}),o.jsx(be,{children:"Target"}),o.jsx(be,{children:"Type"}),o.jsx(be,{children:"Enabled"}),o.jsx(be,{})]})}),o.jsxs(va,{children:[n.length===0&&o.jsx(We,{children:o.jsx(pe,{colSpan:5,className:"text-center text-muted-foreground",children:"No aliases yet."})}),n.map(b=>o.jsxs(We,{children:[o.jsx(pe,{className:"font-mono text-xs",children:b.alias}),o.jsx(pe,{className:"font-mono text-xs",children:b.targetName??b.targetId}),o.jsx(pe,{children:o.jsx(Xe,{variant:"outline",children:b.targetKind})}),o.jsx(pe,{children:b.enabled?"Yes":"No"}),o.jsx(pe,{className:"text-right",children:o.jsx(he,{size:"sm",variant:"outline",onClick:async()=>{await Ce.del(`/api/admin/aliases/${b.id}`),ge.success("Removed"),x()},children:"Delete"})})]},b.id))]})]})})]})]})}function N3(){const[n,a]=m.useState([]),[l,s]=m.useState([]),[c,u]=m.useState([]),[f,p]=m.useState(!1),[g,v]=m.useState(null),[x,y]=m.useState(null),[b,w]=m.useState(null),[E,j]=m.useState({name:"",expiresAt:"",allowAll:!0,permissions:[],rpmLimit:"",tpmLimit:"",concurrency:"",customSecret:""}),C=async()=>{const[A,U,O]=await Promise.all([Ce.get("/api/admin/api-keys"),Ce.get("/api/admin/models"),Ce.get("/api/admin/combos")]);a(A.apiKeys),s(U.models),u(O.combos)};m.useEffect(()=>{C()},[]);const R=async()=>{try{if(g){await Ce.patch("/api/admin/api-keys",{id:g,name:E.name,expiresAt:E.expiresAt||null,allowAllModels:E.allowAll,permissions:E.allowAll?[]:E.permissions,rpmLimit:E.rpmLimit?Number(E.rpmLimit):null,tpmLimit:E.tpmLimit?Number(E.tpmLimit):null,maxConcurrent:E.concurrency?Number(E.concurrency):null}),p(!1),v(null),j({name:"",expiresAt:"",allowAll:!0,permissions:[],rpmLimit:"",tpmLimit:"",concurrency:"",customSecret:""}),ge.success("Key updated"),C();return}const A=await Ce.post("/api/admin/api-keys",{name:E.name,expiresAt:E.expiresAt||null,allowAllModels:E.allowAll,permissions:E.allowAll?void 0:E.permissions,rpmLimit:E.rpmLimit?Number(E.rpmLimit):null,tpmLimit:E.tpmLimit?Number(E.tpmLimit):null,maxConcurrent:E.concurrency?Number(E.concurrency):null,...E.customSecret.trim()?{secret:E.customSecret.trim()}:{}});p(!1),y({secret:A.secret,name:A.name}),j({name:"",expiresAt:"",allowAll:!0,permissions:[],rpmLimit:"",tpmLimit:"",concurrency:"",customSecret:""}),C()}catch(A){ge.error(A.message)}},M=async A=>{try{const O=((await Ce.get(`/api/admin/api-keys/${A.id}`)).apiKey.permissions??[]).filter(q=>q.targetKind==="model"||q.targetKind==="combo");v(A.id),j({name:A.name,expiresAt:A.expiresAt?A.expiresAt.slice(0,16):"",allowAll:A.allowAllModels,permissions:O,rpmLimit:A.rpmLimit!=null?String(A.rpmLimit):"",tpmLimit:A.tpmLimit!=null?String(A.tpmLimit):"",concurrency:A.concurrencyLimit!=null?String(A.concurrencyLimit):"",customSecret:""}),p(!0)}catch(U){ge.error(U.message)}},T=()=>{p(!1),v(null),j({name:"",expiresAt:"",allowAll:!0,permissions:[],rpmLimit:"",tpmLimit:"",concurrency:"",customSecret:""})},D=async(A,U)=>{try{await Ce.patch("/api/admin/api-keys",{id:A,enabled:!U}),ge.success(U?"Key disabled":"Key enabled"),C()}catch(O){ge.error(O.message)}},_=async A=>{if(window.confirm("Delete this API key? This cannot be undone."))try{await Ce.del(`/api/admin/api-keys/${A}`),ge.success("Key deleted"),C()}catch(U){ge.error(U.message)}};return o.jsxs("div",{children:[o.jsx(Ya,{title:"API Keys",description:"Gateway bearer keys for client applications",actions:o.jsxs(kn,{open:f,onOpenChange:A=>{A?p(!0):T()},children:[o.jsx(mi,{asChild:!0,children:o.jsxs(he,{children:[o.jsx(wu,{className:"mr-1 h-4 w-4"})," New key"]})}),o.jsxs(wn,{className:"max-w-2xl",children:[o.jsx(Sn,{children:o.jsx(jn,{children:g?"Edit API key":"New API key"})}),o.jsxs("div",{className:"space-y-3",children:[o.jsxs("div",{children:[o.jsx(Se,{children:"Name"}),o.jsx(De,{value:E.name,onChange:A=>j({...E,name:A.target.value})})]}),o.jsxs("div",{children:[o.jsx(Se,{children:"Expires (optional)"}),o.jsx(De,{type:"datetime-local",value:E.expiresAt,onChange:A=>j({...E,expiresAt:A.target.value})})]}),o.jsxs("div",{className:"grid grid-cols-3 gap-2",children:[o.jsxs("div",{children:[o.jsx(Se,{children:"RPM limit"}),o.jsx(De,{value:E.rpmLimit,onChange:A=>j({...E,rpmLimit:A.target.value}),type:"number"})]}),o.jsxs("div",{children:[o.jsx(Se,{children:"TPM limit"}),o.jsx(De,{value:E.tpmLimit,onChange:A=>j({...E,tpmLimit:A.target.value}),type:"number"})]}),o.jsxs("div",{children:[o.jsx(Se,{children:"Concurrency"}),o.jsx(De,{value:E.concurrency,onChange:A=>j({...E,concurrency:A.target.value}),type:"number"})]})]}),!g&&o.jsxs("div",{children:[o.jsx(Se,{children:"Key value (optional)"}),o.jsx(De,{value:E.customSecret,onChange:A=>j({...E,customSecret:A.target.value}),placeholder:"Leave empty to auto-generate ld-…"}),o.jsx("p",{className:"text-xs text-muted-foreground",children:"If provided, this exact value is stored as the key. Otherwise a random ld-… key is generated."})]}),o.jsxs("div",{className:"flex items-center gap-2",children:[o.jsx(Ta,{checked:E.allowAll,onCheckedChange:A=>j({...E,allowAll:A})}),o.jsx(Se,{children:"Allow all current and future models"})]}),!E.allowAll&&o.jsxs("div",{children:[o.jsx(Se,{children:"Scope"}),o.jsx("div",{className:"max-h-48 space-y-1 overflow-auto rounded border p-2",children:[...l.map(A=>({targetKind:"model",targetId:A.id,label:A.publicModelId})),...c.map(A=>({targetKind:"combo",targetId:A.id,label:A.publicModelId}))].map(A=>{const U=E.permissions.some(O=>O.targetKind===A.targetKind&&O.targetId===A.targetId);return o.jsxs("label",{className:"flex items-center gap-2 rounded p-1 text-sm hover:bg-accent",children:[o.jsx(Cp,{checked:U,onCheckedChange:O=>{j(q=>({...q,permissions:O?[...q.permissions,{targetKind:A.targetKind,targetId:A.targetId}]:q.permissions.filter(K=>!(K.targetKind===A.targetKind&&K.targetId===A.targetId))}))}}),o.jsx("span",{className:"font-mono text-xs",children:A.label}),o.jsx(Xe,{variant:"outline",className:"ml-1",children:A.targetKind})]},`${A.targetKind}:${A.targetId}`)})})]})]}),o.jsxs(zn,{children:[o.jsx(he,{variant:"outline",onClick:T,children:"Cancel"}),o.jsx(he,{disabled:!E.name,onClick:R,children:g?"Save changes":"Create"})]})]})]})}),o.jsxs(tt,{children:[o.jsxs(nt,{children:[o.jsx(at,{className:"text-base",children:"All keys"}),o.jsxs(bn,{children:[n.length," total"]})]}),o.jsx(rt,{children:o.jsxs(pa,{children:[o.jsx(ga,{children:o.jsxs(We,{children:[o.jsx(be,{children:"Name"}),o.jsx(be,{children:"Prefix"}),o.jsx(be,{children:"Status"}),o.jsx(be,{children:"Scope"}),o.jsx(be,{children:"RPM/TPM/Conc"}),o.jsx(be,{})]})}),o.jsxs(va,{children:[n.length===0&&o.jsx(We,{children:o.jsx(pe,{colSpan:6,className:"text-center text-muted-foreground",children:"No API keys yet."})}),n.map(A=>o.jsxs(We,{children:[o.jsx(pe,{className:"font-medium",children:A.name}),o.jsxs(pe,{className:"font-mono text-xs",children:[A.keyPrefix,"…"]}),o.jsx(pe,{children:A.enabled?o.jsx(Xe,{variant:"success",children:"enabled"}):o.jsx(Xe,{variant:"destructive",children:"disabled"})}),o.jsx(pe,{children:A.allowAllModels?"all":`${A.modelScopeCount} scoped`}),o.jsx(pe,{className:"text-xs",children:[A.rpmLimit,A.tpmLimit,A.concurrencyLimit].map((U,O)=>U?["","RPM","TPM","Conc"][O+1]:null).filter(Boolean).join(" / ")||"—"}),o.jsx(pe,{className:"text-right",children:o.jsxs("div",{className:"flex items-center justify-end gap-1",children:[A.secret&&o.jsxs(o.Fragment,{children:[o.jsx(he,{size:"sm",variant:"ghost",title:"Copy secret",onClick:()=>{navigator.clipboard.writeText(A.secret),ge.success("Copied")},children:o.jsx(Xc,{className:"h-3.5 w-3.5"})}),o.jsx(he,{size:"sm",variant:"ghost",title:"Show secret",onClick:()=>w({secret:A.secret,name:A.name}),children:o.jsx(cR,{className:"h-3.5 w-3.5"})})]}),o.jsx(he,{size:"sm",variant:"ghost",title:"Edit",onClick:()=>void M(A),children:o.jsx(gR,{className:"h-3.5 w-3.5"})}),o.jsxs(he,{size:"sm",variant:"outline",onClick:()=>D(A.id,A.enabled),children:[A.enabled?o.jsx(JE,{className:"mr-1 h-3.5 w-3.5"}):o.jsx(ci,{className:"mr-1 h-3.5 w-3.5"}),A.enabled?"Disable":"Enable"]}),o.jsx(he,{size:"sm",variant:"destructive",onClick:()=>_(A.id),children:o.jsx(Su,{className:"h-3.5 w-3.5"})})]})})]},A.id))]})]})})]}),o.jsx(kn,{open:!!x,onOpenChange:A=>{A||y(null)},children:o.jsxs(wn,{children:[o.jsxs(Sn,{children:[o.jsx(jn,{children:"API key created"}),o.jsx(cu,{children:"Copy now — this secret will not be shown again."})]}),o.jsx("div",{className:"rounded border bg-muted p-3 font-mono text-xs break-all",children:x==null?void 0:x.secret}),o.jsxs(zn,{children:[o.jsxs(he,{onClick:()=>{x&&(navigator.clipboard.writeText(x.secret),ge.success("Copied"))},children:[o.jsx(Xc,{className:"mr-1 h-4 w-4"})," Copy"]}),o.jsx(he,{variant:"outline",onClick:()=>y(null),children:"I have saved it"})]})]})}),o.jsx(kn,{open:!!b,onOpenChange:A=>{A||w(null)},children:o.jsxs(wn,{children:[o.jsxs(Sn,{children:[o.jsxs(jn,{children:["API key: ",b==null?void 0:b.name]}),o.jsx(cu,{children:"Full secret for this key, readable any time."})]}),o.jsx("div",{className:"rounded border bg-muted p-3 font-mono text-xs break-all",children:b==null?void 0:b.secret}),o.jsxs(zn,{children:[o.jsxs(he,{onClick:()=>{b&&(navigator.clipboard.writeText(b.secret),ge.success("Copied"))},children:[o.jsx(Xc,{className:"mr-1 h-4 w-4"})," Copy"]}),o.jsx(he,{variant:"outline",onClick:()=>w(null),children:"Close"})]})]})})]})}const T3=3e3;function M3(n,a){return!(a.success!=="all"&&n.success!==(a.success==="true")||a.protocol!=="all"&&n.protocol!==a.protocol||a.streaming!=="all"&&n.streaming!==(a.streaming==="true")||a.model&&!n.requestedModel.toLowerCase().includes(a.model.toLowerCase()))}function A3(){const[n,a]=m.useState([]),[l,s]=m.useState(0),[c,u]=m.useState(0),[f,p]=m.useState({success:"all",protocol:"all",streaming:"all",model:""}),[g,v]=m.useState(null),[x,y]=m.useState(null),[b,w]=m.useState(0),E=50,j=m.useRef(Date.now()),C=m.useRef(new Set),R=m.useRef(f);R.current=f;const M=m.useRef(c);M.current=c;const T=m.useCallback(async()=>{const _=new URLSearchParams;_.set("limit",String(E)),_.set("offset",String(c)),f.success!=="all"&&_.set("success",f.success),f.protocol!=="all"&&_.set("protocol",f.protocol),f.streaming!=="all"&&_.set("streaming",f.streaming),f.model&&_.set("requestedModel",f.model);const A=await Ce.get(`/api/admin/requests?${_.toString()}`);a(A.requests),s(A.total);for(const U of A.requests)C.current.add(U.id)},[c,f]);m.useEffect(()=>{T()},[T]),m.useEffect(()=>{w(0)},[c,f]),m.useEffect(()=>{let _=!1,A=null;const U=new Set,O=()=>{_||(A=new EventSource(`/api/admin/requests/stream?since=${j.current}`),A.addEventListener("request",q=>{if(!_)try{const K=JSON.parse(q.data),te=new Date(K.createdAt).getTime();if(Number.isFinite(te)&&(j.current=Math.max(j.current,te)),C.current.has(K.id))return;C.current.add(K.id),w(G=>G+1),M.current===0&&M3(K,R.current)&&(a(G=>G.some(ie=>ie.id===K.id)?G:[K,...G].slice(0,E)),s(G=>G+1))}catch{}}),A.onerror=()=>{A==null||A.close(),A=null,_||U.add(setTimeout(O,T3))})};return O(),()=>{_=!0,A==null||A.close();for(const q of U)clearTimeout(q);U.clear()}},[]);const D=async _=>{v(_);const A=await Ce.get(`/api/admin/requests/${_}`);y(A)};return o.jsxs("div",{children:[o.jsx(Ya,{title:"Requests",description:`${l} matching · live updates`}),o.jsxs(tt,{children:[o.jsxs(nt,{children:[o.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[o.jsxs(Ra,{value:f.success,onValueChange:_=>{u(0),p({...f,success:_})},children:[o.jsx(da,{className:"w-36",children:o.jsx(Na,{})}),o.jsxs(fa,{children:[o.jsx(wt,{value:"all",children:"All"}),o.jsx(wt,{value:"true",children:"Success"}),o.jsx(wt,{value:"false",children:"Failed"})]})]}),o.jsxs(Ra,{value:f.protocol,onValueChange:_=>{u(0),p({...f,protocol:_})},children:[o.jsx(da,{className:"w-32",children:o.jsx(Na,{})}),o.jsxs(fa,{children:[o.jsx(wt,{value:"all",children:"Any protocol"}),o.jsx(wt,{value:"openai",children:"OpenAI"}),o.jsx(wt,{value:"anthropic",children:"Anthropic"})]})]}),o.jsxs(Ra,{value:f.streaming,onValueChange:_=>{u(0),p({...f,streaming:_})},children:[o.jsx(da,{className:"w-32",children:o.jsx(Na,{})}),o.jsxs(fa,{children:[o.jsx(wt,{value:"all",children:"Any"}),o.jsx(wt,{value:"true",children:"Streaming"}),o.jsx(wt,{value:"false",children:"Non-stream"})]})]}),o.jsx(De,{className:"max-w-xs",placeholder:"Model contains…",value:f.model,onChange:_=>{u(0),p({...f,model:_.target.value})}}),b>0&&o.jsxs(he,{size:"sm",variant:"secondary",onClick:()=>{w(0),T()},children:[b," new request",b>1?"s":""," — refresh"]})]}),o.jsx(at,{className:"mt-3 text-base",children:"Results"})]}),o.jsxs(rt,{children:[o.jsxs(pa,{children:[o.jsx(ga,{children:o.jsxs(We,{children:[o.jsx(be,{children:"Time"}),o.jsx(be,{children:"Status"}),o.jsx(be,{children:"Requested"}),o.jsx(be,{children:"Final"}),o.jsx(be,{children:"Tokens"}),o.jsx(be,{children:"Latency"}),o.jsx(be,{children:"Attempts"}),o.jsx(be,{children:"Key"}),o.jsx(be,{children:"IP"}),o.jsx(be,{})]})}),o.jsxs(va,{children:[n.length===0&&o.jsx(We,{children:o.jsx(pe,{colSpan:10,className:"text-center text-muted-foreground",children:"No requests yet."})}),n.map(_=>o.jsxs(We,{className:"cursor-pointer",onClick:()=>D(_.id),children:[o.jsx(pe,{className:"text-xs",children:Um(_.createdAt)}),o.jsx(pe,{children:_.success?o.jsx(Xe,{variant:"success",children:_.httpStatus}):o.jsx(Xe,{variant:"destructive",children:_.httpStatus})}),o.jsx(pe,{className:"font-mono text-xs",children:_.requestedModel}),o.jsx(pe,{className:"font-mono text-xs text-muted-foreground",children:_.finalModelPublicId??"—"}),o.jsxs(pe,{className:"text-xs",children:[Jt(_.inputTokens+_.outputTokens)," ",_.cacheReadTokens?o.jsxs("span",{className:"text-amber-600",children:["(+",_.cacheReadTokens," cache)"]}):null]}),o.jsxs(pe,{className:"text-xs",children:[Ol(_.totalLatencyMs),_.ttftMs?o.jsxs("span",{className:"text-muted-foreground",children:[" · ttft ",_.ttftMs,"ms"]}):null]}),o.jsxs(pe,{className:"text-xs",children:[_.attemptsCount,_.gatewayCacheHit?o.jsx(Xe,{variant:"secondary",className:"ml-1",children:"cache"}):null]}),o.jsx(pe,{className:"text-xs",children:_.apiKeyName??"—"}),o.jsx(pe,{className:"text-xs",children:_.clientIp}),o.jsx(pe,{className:"text-right",children:o.jsx(he,{size:"sm",variant:"ghost",children:"View"})})]},_.id))]})]}),o.jsxs("div",{className:"mt-3 flex items-center justify-between",children:[o.jsxs("span",{className:"text-xs text-muted-foreground",children:["Showing ",c+1,"–",Math.min(c+E,l)," of ",l]}),o.jsxs("div",{className:"flex gap-2",children:[o.jsx(he,{size:"sm",variant:"outline",disabled:c===0,onClick:()=>u(Math.max(0,c-E)),children:"Prev"}),o.jsx(he,{size:"sm",variant:"outline",disabled:c+E>=l,onClick:()=>u(c+E),children:"Next"})]})]})]})]}),o.jsx(kn,{open:!!g,onOpenChange:_=>{_||(v(null),y(null))},children:o.jsxs(wn,{className:"max-h-[90vh] max-w-5xl overflow-y-auto",children:[o.jsx(Sn,{children:o.jsxs(jn,{children:["Request ",rN(g,16)]})}),x?o.jsxs("div",{className:"min-w-0 space-y-3 text-sm",children:[o.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[o.jsxs("div",{children:[o.jsx("div",{className:"text-muted-foreground text-xs",children:"Requested model"}),o.jsx("span",{className:"font-mono text-xs",children:x.request.requestedModel})]}),o.jsxs("div",{children:[o.jsx("div",{className:"text-muted-foreground text-xs",children:"Upstream model"}),o.jsx("span",{className:"font-mono text-xs",children:x.request.finalModelUpstreamId??"—"})]}),o.jsxs("div",{children:[o.jsx("div",{className:"text-muted-foreground text-xs",children:"Provider"}),x.request.providerId?o.jsx(ia,{className:"text-primary underline",to:`/providers?providerId=${encodeURIComponent(x.request.providerId)}`,children:x.request.providerName??x.request.providerSlug??x.request.providerId}):"—"]}),o.jsxs("div",{children:[o.jsx("div",{className:"text-muted-foreground text-xs",children:"Route"}),x.request.resolvedTargetId?o.jsx(ia,{className:"text-primary underline",to:x.request.resolvedTargetKind==="combo"?"/combos":"/models",children:x.request.resolvedTargetKind??"target"}):"—"]}),o.jsxs("div",{children:[o.jsx("div",{className:"text-muted-foreground text-xs",children:"Status"}),x.request.success?o.jsx(Xe,{variant:"success",children:x.request.httpStatus}):o.jsx(Xe,{variant:"destructive",children:x.request.httpStatus})]}),o.jsxs("div",{children:[o.jsx("div",{className:"text-muted-foreground text-xs",children:"Latency"}),Ol(x.request.totalLatencyMs)]}),o.jsxs("div",{children:[o.jsx("div",{className:"text-muted-foreground text-xs",children:"Tokens"}),"in ",Jt(x.request.inputTokens)," · out ",Jt(x.request.outputTokens)," · cache ",Jt(x.request.cacheReadTokens)]}),o.jsxs("div",{children:[o.jsx("div",{className:"text-muted-foreground text-xs",children:"Attempts"}),x.request.attemptsCount]})]}),x.request.errorType&&o.jsxs("div",{className:"rounded border border-destructive/40 bg-destructive/10 p-2",children:[o.jsx("div",{className:"text-xs text-muted-foreground",children:"Error"}),o.jsxs("div",{className:"font-mono text-xs",children:[x.request.errorType,": ",x.request.errorMessage]})]}),x.request.fallbackReasons.length>0&&o.jsxs("div",{className:"rounded border border-amber-500/40 bg-amber-500/10 p-2",children:[o.jsx("div",{className:"text-xs text-muted-foreground",children:"Fallback reasons"}),o.jsx("div",{className:"text-xs",children:x.request.fallbackReasons.join(", ")})]}),o.jsxs("div",{className:"min-w-0",children:[o.jsxs("div",{className:"mb-1 flex items-center justify-between text-xs text-muted-foreground",children:[o.jsx("span",{children:"Safe replay curl"}),o.jsxs(he,{size:"sm",variant:"ghost",onClick:()=>{navigator.clipboard.writeText(x.request.reproductionCurl).then(()=>ge.success("Curl copied"))},children:[o.jsx(Xc,{className:"mr-1 h-3.5 w-3.5"})," Copy"]})]}),o.jsx("pre",{className:"max-h-48 overflow-auto whitespace-pre-wrap break-all rounded bg-muted p-2 font-mono text-xs",children:x.request.reproductionCurl}),o.jsx("p",{className:"mt-1 text-xs text-muted-foreground",children:"Replace the placeholder key before running. No stored secret is included."})]}),x.request.requestPayload&&o.jsxs("div",{children:[o.jsx("div",{className:"text-xs text-muted-foreground",children:"Request content"}),o.jsx("pre",{className:"max-h-72 overflow-auto break-all rounded bg-muted p-2 font-mono text-xs whitespace-pre-wrap",children:x.request.requestPayload})]}),x.request.responsePayload&&o.jsxs("div",{children:[o.jsx("div",{className:"text-xs text-muted-foreground",children:"Response content"}),o.jsx("pre",{className:"max-h-72 overflow-auto break-all rounded bg-muted p-2 font-mono text-xs whitespace-pre-wrap",children:x.request.responsePayload})]}),x.attempts.length>0&&o.jsxs("div",{children:[o.jsx("div",{className:"text-xs text-muted-foreground",children:"Attempts"}),o.jsxs(pa,{children:[o.jsx(ga,{children:o.jsxs(We,{children:[o.jsx(be,{children:"#"}),o.jsx(be,{children:"Provider"}),o.jsx(be,{children:"Model"}),o.jsx(be,{children:"Status"}),o.jsx(be,{children:"Latency"}),o.jsx(be,{children:"Reason"})]})}),o.jsx(va,{children:x.attempts.map(_=>o.jsxs(We,{children:[o.jsx(pe,{children:_.attemptNumber}),o.jsx(pe,{children:_.providerName}),o.jsxs(pe,{children:[o.jsx("div",{className:"font-mono text-xs",children:_.modelPublicId}),o.jsxs("div",{className:"text-[11px] text-muted-foreground",children:["upstream: ",_.upstreamModelId]})]}),o.jsx(pe,{children:_.success?o.jsx(Xe,{variant:"success",children:String(_.statusCode??"OK")}):o.jsx(Xe,{variant:"destructive",children:String(_.statusCode??"err")})}),o.jsx(pe,{className:"text-xs",children:Ol(_.latencyMs)}),o.jsx(pe,{className:"text-xs",children:_.failureReason??_.selectionReason})]},_.id))})]})]})]}):o.jsx("div",{className:"text-muted-foreground",children:"Loading…"})]})})]})}var D3=Object.defineProperty,Zs=(n,a)=>D3(n,"name",{value:a,configurable:!0}),kp="Tabs",[O3,n5]=Hn(kp,[zu]),TS=zu(),[_3,zp]=O3(kp),k3=m.forwardRef(Zs(function(a,l){const{__scopeTabs:s,value:c,onValueChange:u,defaultValue:f,orientation:p="horizontal",dir:g,activationMode:v="automatic",...x}=a,y=di(g),[b,w]=br({prop:c,onChange:u,defaultProp:f??"",caller:kp});return o.jsx(_3,{scope:s,baseId:Ha(),value:b,onValueChange:w,orientation:p,dir:y,activationMode:v,children:o.jsx(Pe.div,{dir:y,"data-orientation":p,...x,ref:l})})},"Tabs")),z3="TabsList",L3=m.forwardRef(Zs(function(a,l){const{__scopeTabs:s,loop:c=!0,...u}=a,f=zp(z3,s),p=TS(s);return o.jsx(F1,{asChild:!0,...p,orientation:f.orientation,dir:f.dir,loop:c,children:o.jsx(Pe.div,{role:"tablist","aria-orientation":f.orientation,...u,ref:l})})},"TabsList")),U3="TabsTrigger",B3=m.forwardRef(Zs(function(a,l){const{__scopeTabs:s,value:c,disabled:u=!1,...f}=a,p=zp(U3,s),g=TS(s),v=Lp(p.baseId,c),x=Up(p.baseId,c),y=c===p.value;return o.jsx(K1,{asChild:!0,...g,focusable:!u,active:y,children:o.jsx(Pe.button,{type:"button",role:"tab","aria-selected":y,"aria-controls":x,"data-state":y?"active":"inactive","data-disabled":u?"":void 0,disabled:u,id:v,...f,ref:l,onMouseDown:Te(a.onMouseDown,b=>{!u&&b.button===0&&b.ctrlKey===!1?p.onValueChange(c):b.preventDefault()}),onKeyDown:Te(a.onKeyDown,b=>{u||b.target!==b.currentTarget||[" ","Enter"].includes(b.key)&&p.onValueChange(c)}),onFocus:Te(a.onFocus,()=>{const b=p.activationMode!=="manual";!y&&!u&&b&&p.onValueChange(c)})})})},"TabsTrigger")),H3="TabsContent",I3=m.forwardRef(Zs(function(a,l){const{__scopeTabs:s,value:c,forceMount:u,children:f,...p}=a,g=zp(H3,s),v=Lp(g.baseId,c),x=Up(g.baseId,c),y=c===g.value,b=m.useRef(y);return m.useEffect(()=>{const w=requestAnimationFrame(()=>b.current=!1);return()=>cancelAnimationFrame(w)},[]),o.jsx(Er,{present:u||y,children:({present:w})=>o.jsx(Pe.div,{"data-state":y?"active":"inactive","data-orientation":g.orientation,role:"tabpanel","aria-labelledby":v,hidden:!w,id:x,tabIndex:0,...p,ref:l,style:{...a.style,animationDuration:b.current?"0s":void 0},children:w&&f})})},"TabsContent"));function Lp(n,a){return`${n}-trigger-${a}`}Zs(Lp,"makeTriggerId");function Up(n,a){return`${n}-content-${a}`}Zs(Up,"makeContentId");var P3=k3,MS=L3,AS=B3,DS=I3;const OS=P3,Bp=m.forwardRef(({className:n,...a},l)=>o.jsx(MS,{ref:l,className:Ee("inline-flex h-9 items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground",n),...a}));Bp.displayName=MS.displayName;const pr=m.forwardRef(({className:n,...a},l)=>o.jsx(AS,{ref:l,className:Ee("inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow",n),...a}));pr.displayName=AS.displayName;const Os=m.forwardRef(({className:n,...a},l)=>o.jsx(DS,{ref:l,className:Ee("mt-2 ring-offset-background focus-visible:outline-none",n),...a}));Os.displayName=DS.displayName;const q3=3e3,V3=1600,$3=10,Y3=3,G3=12,F3=10*6e4,K3={cacheReadTokens:0,promptTokens:0,gatewayCacheHits:0,fallbacks:0};function _S(n,a,l){return l==="anthropic"?n+a:n}function X3(n){return n.promptTokens>0?n.cacheReadTokens/n.promptTokens:0}function Q3(n,a){return a>0?n.fallbacks/a:0}function Z3(n,a){return a>0?n.gatewayCacheHits/a:0}function J3(n,a,l){const s=n.totalRequests+1,c=n.successfulRequests+(l.success?1:0),u={cacheReadTokens:a.cacheReadTokens+l.cacheReadTokens,promptTokens:a.promptTokens+_S(l.inputTokens,l.cacheReadTokens,l.providerType),gatewayCacheHits:a.gatewayCacheHits+(l.gatewayCacheHit?1:0),fallbacks:a.fallbacks+(l.attemptsCount>1?1:0)};return{...n,...u,totalRequests:s,successfulRequests:c,failedRequests:n.failedRequests+(l.success?0:1),successRate:c/s,inputTokens:n.inputTokens+l.inputTokens,outputTokens:n.outputTokens+l.outputTokens,totalTokens:n.totalTokens+l.inputTokens+l.outputTokens,cacheHitRate:X3(u),gatewayCacheHitRate:Z3(u,s),fallbackRate:Q3(u,s),averageLatencyMs:(n.averageLatencyMs*n.totalRequests+l.totalLatencyMs)/s}}function W3(n){const[a,l]=m.useState(null),[s,c]=m.useState(null),[u,f]=m.useState([]),[p,g]=m.useState([]),[v,x]=m.useState([]),[y,b]=m.useState([]),[w,E]=m.useState(!0),[j,C]=m.useState(null),R=m.useRef([]),M=m.useRef(null),T=m.useRef(K3),D=m.useRef(new Set),_=m.useRef(Date.now()),A=m.useRef(0),U=m.useRef([]),O=m.useRef([]);return m.useEffect(()=>{let q=!1;return E(!0),C(null),D.current=new Set,_.current=Date.now(),Ce.get(`/api/admin/stats?preset=${n}`).then(K=>{if(!q){l(K),c(K.summary),M.current=K.summary,T.current={cacheReadTokens:K.summary.cacheReadTokens,promptTokens:K.summary.cacheHitRate!==null&&K.summary.cacheHitRate>0?Math.round(K.summary.cacheReadTokens/K.summary.cacheHitRate):K.summary.inputTokens,gatewayCacheHits:Math.round(K.summary.gatewayCacheHitRate*K.summary.totalRequests),fallbacks:Math.round(K.summary.fallbackRate*K.summary.totalRequests)},f(K.recent),g(K.providers),R.current=K.providers;for(const te of K.recent)D.current.add(te.id);E(!1)}}).catch(K=>{q||(C(K.message),E(!1))}),()=>{q=!0}},[n]),m.useEffect(()=>{let q=!1,K=null;const te=new Set,G=()=>{q||(K=new EventSource(`/api/admin/requests/stream?since=${_.current}`),K.addEventListener("request",ce=>{if(!q)try{const le=JSON.parse(ce.data),k=new Date(le.createdAt).getTime();if(Number.isFinite(k)&&(_.current=Math.max(_.current,k)),D.current.has(le.id))return;D.current.add(le.id);const H={cacheReadTokens:T.current.cacheReadTokens+le.cacheReadTokens,promptTokens:T.current.promptTokens+_S(le.inputTokens,le.cacheReadTokens,le.providerType),gatewayCacheHits:T.current.gatewayCacheHits+(le.gatewayCacheHit?1:0),fallbacks:T.current.fallbacks+(le.attemptsCount>1?1:0)};if(T.current=H,M.current&&c(J3(M.current,H,le)),f(Q=>Q.some(J=>J.id===le.id)?Q:[le,...Q].slice(0,$3)),le.providerId){R.current=R.current.map(z=>z.id===le.providerId?{...z,requests:z.requests+1,errorRate:z.requests+1?(z.errorRate*z.requests+(le.success?0:1))/(z.requests+1):0}:z),g(R.current);const Q=`p${++A.current}`,J={id:Q,providerId:le.providerId,success:le.success};U.current=[...U.current.slice(-(Y3*4)),J],x(U.current);const ee=setTimeout(()=>{U.current=U.current.filter(z=>z.id!==Q),x(U.current)},V3);te.add(ee)}O.current.some(Q=>Q.id===le.id)&&(O.current=O.current.filter(Q=>Q.id!==le.id),b(O.current))}catch{}}),K.addEventListener("request_started",ce=>{if(!q)try{const le=JSON.parse(ce.data);if(!le.providerId||le.providerId==="")return;O.current=[...O.current.filter(k=>k.id!==le.requestId).slice(-(G3-1)),{id:le.requestId,providerId:le.providerId,startedAt:Date.now(),ttftMs:le.ttftMs??0}],b(O.current)}catch{}}),K.onerror=()=>{K==null||K.close(),K=null,q||te.add(setTimeout(G,q3))})};G();const ie=setInterval(()=>{const ce=Date.now()-F3;O.current.some(le=>le.startedAt<ce)&&(O.current=O.current.filter(le=>le.startedAt>=ce),b(O.current))},3e4);return()=>{q=!0,K==null||K.close();for(const ce of te)clearTimeout(ce);te.clear(),clearInterval(ie)}},[]),m.useEffect(()=>{const q=setInterval(()=>{Ce.get("/api/admin/providers").then(K=>{const te=new Map(K.providers.map(G=>[G.id,G]));R.current=R.current.map(G=>{const ie=te.get(G.id);return ie?{...G,health:ie.health,enabled:ie.enabled}:G}),g(R.current)}).catch(()=>{})},3e4);return()=>clearInterval(q)},[]),{snapshot:a,live:s??(a==null?void 0:a.summary)??e4,recent:u,providers:p,pulses:v,activeRoutes:y,loading:w,error:j}}const e4={totalRequests:0,successfulRequests:0,failedRequests:0,successRate:0,inputTokens:0,outputTokens:0,totalTokens:0,cacheReadTokens:0,cacheWriteTokens:0,reasoningTokens:0,averageLatencyMs:0,p95LatencyMs:0,averageTtftMs:null,p95TtftMs:null,cacheHitRate:0,gatewayCacheHitRate:0,fallbackRate:0};function kS({data:n,className:a,strokeClass:l="stroke-primary",fillClass:s}){if(n.length===0)return o.jsx("svg",{className:Ee("h-6 w-20",a),viewBox:"0 0 80 24"});const f=Math.max(...n),p=Math.min(...n),g=f-p||1,x=n.map((y,b)=>{const w=b/(n.length-1)*78+1,E=22-(y-p)/g*20;return`${w.toFixed(1)},${E.toFixed(1)}`}).join(" ");return o.jsxs("svg",{className:Ee("h-6 w-20",a),viewBox:"0 0 80 24",preserveAspectRatio:"none",children:[s&&o.jsx("polygon",{points:`1,23 ${x} 79,23`,className:s}),o.jsx("polyline",{points:x,fill:"none",strokeWidth:1.5,strokeLinecap:"round",strokeLinejoin:"round",className:l})]})}function t4(n,a,l){const s=performance.now();let c=0;const u=f=>{const p=Math.min((f-s)/a,1),g=Math.round(n*p);g!==c&&(c=g,l(g)),p<1&&requestAnimationFrame(u)};requestAnimationFrame(u)}function n4({delta:n,inverse:a}){if(Math.abs(n)<.005)return null;const l=n>0,s=a?!l:l,c=`${(Math.abs(n)*100).toFixed(1)}%`;return o.jsxs("span",{className:Ee("ml-1.5 inline-flex items-center rounded-full px-1.5 py-0.5 text-[10px] font-semibold leading-none",s?"bg-emerald-100 text-emerald-700 dark:bg-emerald-900/40 dark:text-emerald-300":"bg-red-100 text-red-700 dark:bg-red-900/40 dark:text-red-300"),children:[o.jsx("span",{className:"mr-0.5",children:l?"▲":"▼"}),c]})}function tl({icon:n,label:a,value:l,format:s="number",delta:c,deltaInverse:u,sparkData:f,sparkStroke:p}){const[g,v]=m.useState(0),x=m.useRef(0);m.useEffect(()=>{const b=x.current,w=l;w!==null&&(x.current=w,b!==w&&t4(Math.abs(w-b),600,E=>v(b+(w>b?E:-E))))},[l]);const y=l===null?"Unavailable":s==="percent"?Cu(g):s==="latency"?Ol(g):Jt(Math.round(g));return o.jsxs(tt,{children:[o.jsxs(nt,{className:"flex flex-row items-center justify-between pb-1",children:[o.jsxs(at,{className:"flex items-center gap-2 text-sm font-medium text-muted-foreground",children:[o.jsx(n,{className:"h-4 w-4"}),a]}),c!==void 0&&o.jsx(n4,{delta:c,inverse:u})]}),o.jsxs(rt,{className:"flex items-end justify-between",children:[o.jsx("span",{className:"text-2xl font-semibold tabular-nums",children:y}),f&&f.length>1&&o.jsx(kS,{data:f,strokeClass:p??"stroke-primary",fillClass:"fill-primary/10"})]})]})}const zS=1e3,Fb=380,Vc=60,nl=zS/2,al=720,Bh=62,a4=260;function r4(n){return n==="healthy"?"fill-emerald-400":n==="degraded"?"fill-amber-400":"fill-red-400"}function $c(n,a,l,s){const c=n+(l-n)*.45,u=n+(l-n)*.55;return`M${n},${a} C${c},${a} ${u},${s} ${l},${s}`}function l4({liveRequests:n,successRate:a,providers:l,pulses:s,activeRoutes:c}){const u=Fb/2,f=u,p=Math.max(1,l.reduce((x,y)=>x+y.requests,0)),g=new Set(c.map(x=>x.providerId)),v=g.size>0;return o.jsxs(tt,{children:[o.jsx(nt,{className:"pb-2",children:o.jsxs("div",{className:"flex items-center justify-between",children:[o.jsx(at,{className:"text-base",children:"Real-time Request Routing"}),o.jsxs("div",{className:"flex items-center gap-3 text-xs text-muted-foreground",children:[o.jsxs("span",{className:"flex items-center gap-1",children:[o.jsx("span",{className:"inline-block h-2 w-2 rounded-full bg-emerald-400"})," healthy"]}),o.jsxs("span",{className:"flex items-center gap-1",children:[o.jsx("span",{className:"inline-block h-2 w-2 rounded-full bg-amber-400"})," degraded"]}),o.jsxs("span",{className:"flex items-center gap-1",children:[o.jsx("span",{className:"inline-block h-2 w-2 rounded-full bg-red-400"})," down"]})]})]})}),o.jsx(rt,{className:"pt-0",children:o.jsx("div",{className:"relative w-full",children:o.jsxs("svg",{viewBox:`0 0 ${zS} ${Fb}`,className:"w-full h-auto",preserveAspectRatio:"xMidYMid meet",children:[o.jsx("defs",{children:o.jsxs("filter",{id:"glow",x:"-50%",y:"-50%",width:"200%",height:"200%",children:[o.jsx("feGaussianBlur",{stdDeviation:"3",result:"blur"}),o.jsxs("feMerge",{children:[o.jsx("feMergeNode",{in:"blur"}),o.jsx("feMergeNode",{in:"SourceGraphic"})]})]})}),l.map(x=>{const b=60+l.indexOf(x)*Bh,w=x.requests/p,E=Math.max(1.5,Math.min(6,2+w*8)),j=g.has(x.id);return o.jsxs("g",{children:[j&&o.jsx("path",{d:$c(nl,u,al-20,b),fill:"none",stroke:"hsl(var(--primary) / 0.25)",strokeWidth:E+6,strokeLinecap:"round"}),o.jsx("path",{d:$c(nl,u,al-20,b),fill:"none",stroke:j?"hsl(var(--primary))":"hsl(var(--border))",strokeWidth:j?E+1:E,strokeLinecap:"round",opacity:j?.95:.6,className:j?"route-active":void 0})]},x.id)}),o.jsx("path",{d:$c(Vc+30,f,nl-30,u),fill:"none",stroke:v?"hsl(var(--primary))":"hsl(var(--border))",strokeWidth:3,strokeLinecap:"round",strokeDasharray:"6 3",opacity:v?.9:.5,className:v?"route-active":void 0}),s.map(x=>{const y=l.findIndex(j=>j.id===x.providerId);if(y===-1)return null;const b=60+y*Bh,w=$c(nl,u,al-20,b),E=x.success?"var(--primary)":"#f87171";return o.jsxs("g",{filter:"url(#glow)",children:[o.jsx("circle",{r:5,fill:E,opacity:.9,children:o.jsx("animateMotion",{dur:"1.4s",fill:"freeze",path:w})}),o.jsx("circle",{r:9,fill:E,opacity:.25,children:o.jsx("animateMotion",{dur:"1.4s",fill:"freeze",path:w})})]},x.id)}),o.jsx("circle",{cx:Vc,cy:f,r:28,fill:"hsl(var(--card))",stroke:"hsl(var(--border))",strokeWidth:1.5}),o.jsx("text",{x:Vc,y:f-4,textAnchor:"middle",className:"fill-foreground",fontSize:12,fontWeight:600,children:Kb(n)}),o.jsx("text",{x:Vc,y:f+10,textAnchor:"middle",className:"fill-muted-foreground",fontSize:9,children:"requests"}),o.jsx("circle",{cx:nl,cy:u,r:36,fill:"hsl(var(--card))",stroke:"var(--primary)",strokeWidth:2}),o.jsx("image",{x:nl-12,y:u-16,width:24,height:24,href:"/logo.png"}),o.jsx("text",{x:nl,y:u+28,textAnchor:"middle",className:"fill-muted-foreground",fontSize:9,children:"AI Gateway"}),o.jsxs("text",{x:nl,y:u+38,textAnchor:"middle",className:"fill-emerald-500",fontSize:10,fontWeight:600,children:[(a*100).toFixed(1),"%"]}),l.map((x,y)=>{const b=60+y*Bh,w=x.requests/p,E=!x.enabled||x.requests===0;return o.jsxs("g",{opacity:E?.4:1,children:[o.jsx("rect",{x:al-20,y:b-14,width:a4,height:50,rx:8,fill:"hsl(var(--card))",stroke:"hsl(var(--border))",strokeWidth:1}),o.jsx("circle",{cx:al-6,cy:b+10,r:4,className:r4(x.health)}),o.jsx("text",{x:al+6,y:b-2,className:"fill-foreground",fontSize:12,fontWeight:500,children:x.name}),o.jsxs("text",{x:al+6,y:b+12,className:"fill-muted-foreground",fontSize:10,children:[x.modelCount," model",x.modelCount!==1?"s":""," · ",Kb(x.requests)," req"]}),o.jsxs("text",{x:al+6,y:b+25,className:"fill-muted-foreground",fontSize:10,children:[(w*100).toFixed(1),"% traffic · ",x.avgLatencyMs<1e3?`${Math.round(x.avgLatencyMs)}ms`:`${(x.avgLatencyMs/1e3).toFixed(1)}s`," avg",x.errorRate>0&&o.jsxs("tspan",{className:"fill-red-500",children:[" · ",(x.errorRate*100).toFixed(0),"% err"]})]})]},x.id)})]})})})]})}function Kb(n){return n>=1e6?`${(n/1e6).toFixed(1)}M`:n>=1e3?`${(n/1e3).toFixed(1)}K`:String(n)}function s4({rows:n}){return o.jsxs(tt,{children:[o.jsx(nt,{className:"pb-2",children:o.jsx(at,{className:"text-base",children:"Recent Requests"})}),o.jsx(rt,{children:n.length===0?o.jsx("div",{className:"py-6 text-center text-sm text-muted-foreground",children:"No requests yet — traffic will appear here live."}):o.jsxs(pa,{children:[o.jsx(ga,{children:o.jsxs(We,{children:[o.jsx(be,{children:"Model"}),o.jsx(be,{children:"Provider"}),o.jsx(be,{children:"Tokens"}),o.jsx(be,{children:"Status"}),o.jsx(be,{children:"Time"})]})}),o.jsx(va,{children:n.map(a=>o.jsxs(We,{children:[o.jsx(pe,{className:"font-mono text-xs",children:a.requestedModel}),o.jsx(pe,{className:"text-xs text-muted-foreground",children:a.providerName??"—"}),o.jsxs(pe,{className:"text-xs",children:[o.jsxs("span",{className:"font-mono",children:["in ",Jt(a.inputTokens)," · out ",Jt(a.outputTokens)]}),a.cacheReadTokens>0&&o.jsxs("span",{className:"ml-1 text-amber-600",children:["(+",Jt(a.cacheReadTokens)," cache)"]})]}),o.jsx(pe,{children:o.jsxs("span",{className:"inline-flex items-center gap-1.5",children:[o.jsx("span",{className:a.success?"h-2 w-2 rounded-full bg-emerald-400":"h-2 w-2 rounded-full bg-red-400"}),o.jsx("span",{className:"text-xs",children:a.success?a.httpStatus:`${a.httpStatus} err`})]})}),o.jsx(pe,{className:"text-xs text-muted-foreground",children:lN(a.createdAt)})]},a.id))})]})})]})}const gm=34,Xb=2*Math.PI*gm;function o4(n){return n>=.95?{stroke:"#4ade80",text:"text-emerald-500"}:n>=.8?{stroke:"#fbbf24",text:"text-amber-500"}:{stroke:"#f87171",text:"text-red-500"}}function i4({successRate:n,averageLatencyMs:a,latencySpark:l}){const{stroke:s,text:c}=o4(n),u=Math.min(1,Math.max(0,n)),f=Xb*(1-u);return o.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[o.jsxs(tt,{children:[o.jsx(nt,{className:"pb-2",children:o.jsx(at,{className:"text-base",children:"Success Rate"})}),o.jsxs(rt,{className:"flex items-center gap-4",children:[o.jsxs("div",{className:"relative h-20 w-20",children:[o.jsxs("svg",{viewBox:"0 0 80 80",className:"h-20 w-20 -rotate-90",children:[o.jsx("circle",{cx:"40",cy:"40",r:gm,fill:"none",stroke:"hsl(var(--border))",strokeWidth:7}),o.jsx("circle",{cx:"40",cy:"40",r:gm,fill:"none",stroke:s,strokeWidth:7,strokeLinecap:"round",strokeDasharray:Xb,strokeDashoffset:f,style:{transition:"stroke-dashoffset 0.6s ease, stroke 0.4s ease"}})]}),o.jsx("span",{className:`absolute inset-0 flex items-center justify-center text-sm font-semibold tabular-nums ${c}`,children:Cu(n)})]}),o.jsx("p",{className:"text-sm text-muted-foreground",children:"Share of requests that completed successfully over the selected window. Updated in real time."})]})]}),o.jsxs(tt,{children:[o.jsx(nt,{className:"pb-2",children:o.jsx(at,{className:"text-base",children:"Average Latency"})}),o.jsxs(rt,{className:"flex items-end justify-between",children:[o.jsxs("div",{children:[o.jsx("div",{className:"text-2xl font-semibold tabular-nums",children:Ol(a)}),o.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"Live average across the selected window"})]}),o.jsx(kS,{data:l,strokeClass:"stroke-amber-500",fillClass:"fill-amber-500/10",className:"h-10 w-28"})]})]})]})}function c4(){const[n,a]=m.useState("7d"),{snapshot:l,live:s,recent:c,providers:u,pulses:f,activeRoutes:p,loading:g,error:v}=W3(n);if(g)return o.jsx("div",{className:"text-muted-foreground",children:"Loading…"});if(v||!l)return o.jsxs("div",{className:"text-destructive",children:["Failed to load statistics: ",v??"unknown error"]});const x=s,y=l.previous,b=l.series;function w(C,R){return R>0?(C-R)/R:void 0}const E=b.map(C=>C.requests),j=b.map(C=>C.avgLatency);return o.jsxs("div",{children:[o.jsx(Ya,{title:"Statistics",description:"Real-time monitoring dashboard",actions:o.jsx(OS,{value:n,onValueChange:C=>void a(C),children:o.jsxs(Bp,{children:[o.jsx(pr,{value:"today",children:"Today"}),o.jsx(pr,{value:"7d",children:"7 days"}),o.jsx(pr,{value:"30d",children:"30 days"})]})})}),!l.percentilesAvailable&&o.jsx("p",{className:"mb-3 text-sm text-muted-foreground",children:"Percentiles are unavailable for compacted historical data; cache hit rate is unavailable when provider token semantics were not retained."}),o.jsxs("div",{className:"grid gap-4 md:grid-cols-2 lg:grid-cols-4",children:[o.jsx(tl,{icon:zm,label:"Requests",value:x.totalRequests,delta:w(x.totalRequests,y.totalRequests),sparkData:E}),o.jsx(tl,{icon:ci,label:"Success rate",format:"percent",value:x.successRate,delta:w(x.successRate,y.successRate),sparkData:E,sparkStroke:"stroke-emerald-500"}),o.jsx(tl,{icon:oR,label:"Total tokens",value:x.totalTokens,delta:w(x.totalTokens,y.totalTokens),sparkData:b.map(C=>C.inputTokens+C.outputTokens)}),o.jsx(tl,{icon:iR,label:"Cache hit rate",format:"percent",value:x.cacheHitRate,delta:x.cacheHitRate!==null&&y.cacheHitRate!==null?w(x.cacheHitRate,y.cacheHitRate):void 0,sparkData:b.map(C=>C.cacheRead)}),o.jsx(tl,{icon:rR,label:"Avg latency",format:"latency",value:x.averageLatencyMs,delta:w(x.averageLatencyMs,y.averageLatencyMs),deltaInverse:!0,sparkData:j,sparkStroke:"stroke-amber-500"}),o.jsx(tl,{icon:N0,label:"p95 latency",format:"latency",value:x.p95LatencyMs}),o.jsx(tl,{icon:jR,label:"Avg TTFT",format:"latency",value:x.averageTtftMs}),o.jsx(tl,{icon:vR,label:"Fallback rate",format:"percent",value:x.fallbackRate,delta:w(x.fallbackRate,y.fallbackRate),deltaInverse:!0})]}),o.jsx("div",{className:"mt-6",children:o.jsx(l4,{liveRequests:x.totalRequests,successRate:x.successRate,providers:u,pulses:f,activeRoutes:p})}),o.jsxs("div",{className:"mt-6 grid gap-4 lg:grid-cols-3",children:[o.jsx("div",{className:"lg:col-span-2",children:o.jsx(s4,{rows:c})}),o.jsxs("div",{className:"space-y-4",children:[o.jsxs(tt,{children:[o.jsx(nt,{className:"pb-2",children:o.jsx(at,{className:"text-base",children:"Top Models"})}),o.jsx(rt,{children:o.jsxs(pa,{children:[o.jsx(ga,{children:o.jsxs(We,{children:[o.jsx(be,{children:"Model"}),o.jsx(be,{children:"Req"}),o.jsx(be,{children:"Errors"}),o.jsx(be,{children:"Tokens"})]})}),o.jsxs(va,{children:[l.topModels.length===0&&o.jsx(We,{children:o.jsx(pe,{colSpan:4,className:"text-muted-foreground text-center",children:"No data"})}),l.topModels.map(C=>o.jsxs(We,{children:[o.jsx(pe,{className:"font-mono text-xs",children:C.publicId}),o.jsx(pe,{className:"text-xs",children:Jt(C.requests)}),o.jsx(pe,{className:"text-xs",children:o.jsx("span",{className:C.errorRate>.1?"text-destructive":"text-muted-foreground",children:Cu(C.errorRate)})}),o.jsx(pe,{className:"text-xs",children:Jt(C.totalTokens)})]},C.publicId))]})]})})]}),o.jsxs(tt,{children:[o.jsx(nt,{className:"pb-2",children:o.jsx(at,{className:"text-base",children:"Top API Keys"})}),o.jsx(rt,{children:o.jsxs(pa,{children:[o.jsx(ga,{children:o.jsxs(We,{children:[o.jsx(be,{children:"Key"}),o.jsx(be,{children:"Requests"}),o.jsx(be,{children:"Tokens"})]})}),o.jsxs(va,{children:[l.topApiKeys.length===0&&o.jsx(We,{children:o.jsx(pe,{colSpan:3,className:"text-muted-foreground text-center",children:"No data"})}),l.topApiKeys.map((C,R)=>o.jsxs(We,{children:[o.jsx(pe,{className:"text-xs",children:C.name}),o.jsx(pe,{className:"text-xs",children:Jt(C.requests)}),o.jsx(pe,{className:"text-xs",children:Jt(C.totalTokens)})]},R))]})]})})]})]})]}),o.jsx("div",{className:"mt-6",children:o.jsx(i4,{successRate:x.successRate,averageLatencyMs:x.averageLatencyMs,latencySpark:j})})]})}function u4(){const[n,a]=m.useState([]),[l,s]=m.useState(0);return m.useEffect(()=>{Ce.get("/api/admin/audit?limit=200").then(c=>{a(c.rows),s(c.total)})},[]),o.jsxs("div",{children:[o.jsx(Ya,{title:"Audit Logs",description:`${l} entries · immutable`}),o.jsxs(tt,{children:[o.jsx(nt,{children:o.jsx(at,{className:"text-base",children:"All entries"})}),o.jsx(rt,{children:o.jsxs(pa,{children:[o.jsx(ga,{children:o.jsxs(We,{children:[o.jsx(be,{children:"Time"}),o.jsx(be,{children:"Action"}),o.jsx(be,{children:"Status"}),o.jsx(be,{children:"Target"}),o.jsx(be,{children:"IP"}),o.jsx(be,{children:"Actor"})]})}),o.jsxs(va,{children:[n.length===0&&o.jsx(We,{children:o.jsx(pe,{colSpan:6,className:"text-center text-muted-foreground",children:"No audit events yet."})}),n.map(c=>o.jsxs(We,{children:[o.jsx(pe,{className:"text-xs",children:Um(c.createdAt)}),o.jsx(pe,{className:"font-mono text-xs",children:c.action}),o.jsx(pe,{children:c.success?o.jsx(Xe,{variant:"success",children:"ok"}):o.jsx(Xe,{variant:"destructive",children:"fail"})}),o.jsx(pe,{className:"text-xs",children:c.targetName??c.targetId??"—"}),o.jsx(pe,{className:"text-xs",children:c.ip}),o.jsx(pe,{className:"text-xs",children:c.actor})]},c.id))]})]})})]})]})}const vm={enabled:!0,sound:!0};let ri=vm,xm=!1,Yc=null;const ym=new Set;function LS(){for(const n of ym)n()}function US(n=!1){return xm&&!n?Promise.resolve():(!n&&Yc||(Yc=(async()=>{try{const a=await Ce.get("/api/admin/settings");ri={enabled:a.settings.notificationsEnabled??vm.enabled,sound:a.settings.notificationSoundEnabled??vm.sound},xm=!0,LS()}catch{}})()),Yc)}async function Qb(n){const a={};n.enabled!==void 0&&(a.notificationsEnabled=n.enabled),n.sound!==void 0&&(a.notificationSoundEnabled=n.sound),await Ce.patch("/api/admin/settings",a),ri={...ri,...n},xm=!0,LS()}function d4(n){return ym.add(n),()=>ym.delete(n)}function BS(){return m.useSyncExternalStore(d4,()=>ri,()=>ri)}const bm=m.forwardRef(({className:n,...a},l)=>o.jsx("textarea",{ref:l,className:Ee("flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",n),...a}));bm.displayName="Textarea";function f4(){const[n]=PE(),[a,l]=m.useState(null),[s,c]=m.useState(null),[u,f]=m.useState({current:"",next:""}),[p,g]=m.useState(""),[v,x]=m.useState(""),[y,b]=m.useState(null),[w,E]=m.useState(!1),[j,C]=m.useState("idle"),[R,M]=m.useState(null),T=async(se=!1)=>{C("checking"),M(null);try{const qe=await Ce.get(`/api/admin/update/check${se?"?force=1":""}`);b(qe),C("idle")}catch(qe){M(qe.message),C("error")}},D=async()=>{E(!0),C("installing"),M(null);try{const se=await Ce.post("/api/admin/update/run");C("restarting"),ge.success(se.message||"Update started — the gateway will restart shortly.");const qe=setInterval(()=>{fetch("/health").then(it=>{it.ok&&(clearInterval(qe),window.location.reload())}).catch(()=>{})},3e3);setTimeout(()=>clearInterval(qe),12e4)}catch(se){ge.error(se.message),M(se.message),C("error")}finally{E(!1)}},[_,A]=m.useState("disabled"),[U,O]=m.useState(""),[q,K]=m.useState(""),[te,G]=m.useState(""),[ie,ce]=m.useState([]),[le,k]=m.useState(""),[H,Q]=m.useState(""),[J,ee]=m.useState(!1),[z,I]=m.useState(null),[X,re]=m.useState(""),[fe,ve]=m.useState(""),[V,oe]=m.useState(""),[de,me]=m.useState("compact"),[xe,we]=m.useState("idle"),[Me,Ye]=m.useState(null),Qe=m.useRef(null),[st,Kt]=m.useState(null),ot=async()=>{const se=await Ce.get("/api/admin/settings");l(se.settings),g(se.settings.adminIpAllow??""),x(se.settings.adminIpBlock??"");const qe=await Ce.get("/api/admin/settings/system");c(qe);try{const it=await Ce.get("/api/admin/me");A(it.totpEnabled?"enabled":"disabled")}catch{}};if(m.useEffect(()=>{US(!0)},[]),m.useEffect(()=>{ot(),T(!0)},[]),m.useEffect(()=>{Ce.get("/api/admin/backup/capabilities").then(se=>Kt(se.maxUploadBytes)).catch(()=>Kt(null))},[]),!a)return o.jsx("div",{className:"text-muted-foreground",children:"Loading…"});const Lt=async se=>{try{await Ce.patch("/api/admin/settings",se),ge.success("Saved"),ot()}catch(qe){ge.error(qe.message)}},Ot=async()=>{try{const se=await Ce.post("/api/admin/account/totp/begin");O(se.secret),K(se.qr),A("setup"),ge.info("Scan the QR code with your authenticator app")}catch(se){ge.error(se.message)}},It=async()=>{if(!te||te.length!==6){ge.error("Enter a 6-digit code");return}try{const se=await Ce.post("/api/admin/account/totp/verify",{code:te});ce(se.recoveryCodes),A("showingRecovery"),ge.success("TOTP enabled successfully")}catch(se){ge.error(se.message)}},en=async()=>{if(!le){ge.error("Enter your password");return}if(!H){ge.error("Enter a TOTP code or recovery code");return}try{await Ce.post("/api/admin/account/totp/disable",{password:le,totp:H}),A("disabled"),k(""),Q(""),ge.success("TOTP disabled"),ot()}catch(se){ge.error(se.message)}},Pt=async()=>{ee(!0);try{const se=await Ce.post("/api/admin/account/totp/recovery/regenerate",{password:le,totp:H});ce(se.recoveryCodes),A("showingRecovery"),ge.success("Recovery codes regenerated")}catch(se){ge.error(se.message)}ee(!1)},xt=async()=>{var se,qe;try{const it=await _m("/api/admin/backup/create",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({passphrase:X,profile:de})});if(!it.ok)throw new Error(((qe=(se=await it.json().catch(()=>null))==null?void 0:se.error)==null?void 0:qe.message)??"Backup failed");const Cn=await it.blob(),cn=URL.createObjectURL(Cn),yt=document.createElement("a");yt.href=cn,yt.download=`latedev-backup-${new Date().toISOString().replace(/[:.]/g,"-")}.ldb`,yt.click(),URL.revokeObjectURL(cn),ge.success("Backup downloaded"),re(""),ve("")}catch(it){ge.error(it.message)}},on=async()=>{const se=z;if(!se)return;const qe=new AbortController;Qe.current=qe,Ye({loaded:0,total:se.size,percent:0}),we("uploading");let it;try{const Cn=await Rw({file:se,passphrase:V||void 0,signal:qe.signal,onProgress:cn=>{Ye(cn),cn.percent>=100&&(we("validating"),it=setTimeout(()=>we("restoring"),1500))}});clearTimeout(it),we("complete"),ge.success(Cn.message||"Restored. Reloading…"),I(null),setTimeout(()=>location.reload(),600)}catch(Cn){clearTimeout(it),Cn.name==="AbortError"?(ge.info("Restore cancelled"),we("idle")):(ge.error(Cn.message),we("failed"))}finally{Qe.current=null}},St=xe==="uploading"||xe==="validating"||xe==="restoring",jt=st!==null&&z!==null&&z.size>st,tn=n.get("tab")||"logging";return o.jsxs("div",{children:[o.jsx(Ya,{title:"Settings",description:"Logging, security, backup, and system info"}),o.jsxs(OS,{defaultValue:tn,children:[o.jsxs(Bp,{children:[o.jsx(pr,{value:"logging",children:"Logging"}),o.jsx(pr,{value:"access",children:"Access Control"}),o.jsx(pr,{value:"security",children:"Security"}),o.jsx(pr,{value:"backup",children:"Backup"}),o.jsx(pr,{value:"system",children:"System"})]}),o.jsx(Os,{value:"logging",children:o.jsxs(tt,{children:[o.jsx(nt,{children:o.jsx(at,{className:"text-base",children:"Logging policy"})}),o.jsxs(rt,{className:"space-y-3",children:[o.jsxs("div",{className:"space-y-1",children:[o.jsx(Se,{children:"Request-content logging"}),o.jsxs(Ra,{value:a.contentLogMode,onValueChange:se=>Lt({contentLogMode:se}),children:[o.jsx(da,{children:o.jsx(Na,{})}),o.jsxs(fa,{children:[o.jsx(wt,{value:"off",children:"Off"}),o.jsx(wt,{value:"metadata",children:"Metadata only (default)"}),o.jsx(wt,{value:"prompt",children:"Prompt (sanitized)"}),o.jsx(wt,{value:"prompt_and_response",children:"Prompt + response (sanitized)"})]})]})]}),o.jsxs("div",{className:"space-y-1",children:[o.jsx(Se,{children:"Retention (days)"}),o.jsx(De,{type:"number",min:1,max:3650,value:a.retentionDays,onChange:se=>Lt({retentionDays:Number(se.target.value)})})]}),o.jsxs("div",{className:"space-y-1",children:[o.jsx(Se,{children:"Database size limit (MB)"}),o.jsx(De,{type:"number",min:64,value:a.dbSizeLimitMb,onChange:se=>Lt({dbSizeLimitMb:Number(se.target.value)})})]}),o.jsx("div",{className:"flex items-center gap-2 pt-2",children:o.jsx(he,{onClick:async()=>{const se=await Ce.post("/api/admin/settings/cleanup");ge.success(`Deleted ${se.deletedRequests} old requests`)},children:"Run cleanup now"})})]})]})}),o.jsx(Os,{value:"access",children:o.jsxs(tt,{children:[o.jsxs(nt,{children:[o.jsx(at,{className:"text-base",children:"IP access control"}),o.jsx(bn,{children:"Allowlist / Blocklist for this admin website (not model traffic)"})]}),o.jsxs(rt,{className:"space-y-4",children:[o.jsxs("div",{className:"space-y-2",children:[o.jsx(Se,{children:"Allow only these IPs"}),o.jsx(bm,{placeholder:`192.168.1.0/24
349
349
  10.0.0.1`,value:p,onChange:se=>g(se.target.value)}),o.jsx("p",{className:"text-xs text-muted-foreground",children:"Newlines-delimited CIDR ranges (IPv4 only). Leave empty = no allow restrictions. When you save a non-empty list, your current IP is auto-added to prevent lockout."})]}),o.jsxs("div",{className:"space-y-2",children:[o.jsx(Se,{children:"Block these IPs"}),o.jsx(bm,{placeholder:"192.168.1.100",value:v,onChange:se=>x(se.target.value)}),o.jsx("p",{className:"text-xs text-muted-foreground",children:'Newlines-delimited CIDR ranges (IPv4 only). Blocked IPs are rejected with "Không có quyền truy cập" before any login page.'})]}),o.jsx(he,{onClick:()=>{const se={};p!==((a==null?void 0:a.adminIpAllow)??"")&&(se.adminIpAllow=p||null),v!==((a==null?void 0:a.adminIpBlock)??"")&&(se.adminIpBlock=v||null),Ce.patch("/api/admin/settings",se).then(qe=>{ge.success("Saved"+(qe.addedIp?` — added your IP: ${qe.addedIp}`:"")),ot(),g(""),x("")}).catch(qe=>ge.error(qe.message))},children:"Save access control"}),o.jsxs("div",{className:"rounded bg-amber-50 border border-amber-200 p-3 dark:bg-amber-950/20 dark:border-amber-800",children:[o.jsx("p",{className:"text-sm font-medium text-amber-900 dark:text-amber-200",children:"⚠️ If you enable an allow list, you cannot access the gateway unless your IP matches."}),o.jsx("p",{className:"text-xs text-amber-800 dark:text-amber-300",children:"The server automatically adds your current IP when you save — but if you configure it from a different machine, that machine will be locked out immediately."})]})]})]})}),o.jsx(Os,{value:"security",children:o.jsxs(tt,{children:[o.jsxs(nt,{children:[o.jsx(at,{className:"text-base",children:"Security"}),o.jsx(bn,{children:"Change password, 2FA, and trusted proxy configuration"})]}),o.jsxs(rt,{className:"space-y-4",children:[o.jsxs("div",{className:"space-y-2",children:[o.jsx(Se,{children:"Trusted proxy hops"}),o.jsx(De,{type:"number",min:0,max:8,value:a.trustProxyHops,onChange:se=>Lt({trustProxyHops:Number(se.target.value)})}),o.jsx("p",{className:"text-xs text-muted-foreground",children:"0 = never trust X-Forwarded-For (direct exposure). 1+ only when behind a single trusted reverse proxy."})]}),o.jsxs("div",{className:"space-y-2 border-t pt-4",children:[o.jsxs("div",{className:"flex items-center gap-2",children:[o.jsx(Se,{className:"text-base",children:"TOTP 2FA"}),_==="enabled"?o.jsx("span",{className:"rounded bg-green-100 px-2 py-0.5 text-xs font-medium text-green-800 dark:bg-green-900 dark:text-green-200",children:"Enabled"}):null,_==="disabled"?o.jsx("span",{className:"rounded bg-muted px-2 py-0.5 text-xs font-medium text-muted-foreground",children:"Disabled"}):null]}),_==="disabled"&&o.jsx(he,{variant:"outline",onClick:Ot,children:"Enable TOTP"}),_==="setup"&&o.jsxs("div",{className:"space-y-3 rounded border p-3",children:[o.jsx("p",{className:"text-sm text-muted-foreground",children:"Scan this QR code with your authenticator app, or enter the secret manually."}),q&&o.jsx("img",{src:q,alt:"TOTP QR code",className:"h-40 w-40"}),o.jsxs("div",{className:"text-xs font-mono text-muted-foreground",children:["Secret: ",U]}),o.jsxs("div",{className:"flex items-end gap-2",children:[o.jsxs("div",{className:"flex-1",children:[o.jsx(Se,{children:"Verify code"}),o.jsx(De,{value:te,onChange:se=>G(se.target.value),placeholder:"123456",maxLength:6})]}),o.jsx(he,{disabled:te.length<6,onClick:It,children:"Verify & enable"})]})]}),_==="showingRecovery"&&o.jsxs("div",{className:"space-y-3 rounded border border-amber-500/40 bg-amber-50 p-3 dark:bg-amber-950/20",children:[o.jsx("p",{className:"text-sm font-medium",children:"Recovery codes — save these now!"}),o.jsx("p",{className:"text-xs text-muted-foreground",children:"Each code can be used once to log in without your TOTP device. They will not be shown again."}),o.jsx("div",{className:"space-y-1",children:ie.map((se,qe)=>o.jsx("div",{className:"font-mono text-xs",children:se},qe))}),o.jsx(he,{onClick:()=>{A("enabled"),ge.success("Recovery codes saved")},children:"I have saved them"})]}),_==="enabled"&&o.jsxs("div",{className:"space-y-3 rounded border p-3",children:[o.jsxs("div",{className:"grid gap-2 sm:grid-cols-2",children:[o.jsxs("div",{children:[o.jsx(Se,{children:"Password"}),o.jsx(De,{type:"password",value:le,onChange:se=>k(se.target.value),placeholder:"Current password"})]}),o.jsxs("div",{children:[o.jsx(Se,{children:"TOTP code"}),o.jsx(De,{value:H,onChange:se=>Q(se.target.value),placeholder:"123456",maxLength:6})]})]}),o.jsxs("div",{className:"flex items-center gap-2",children:[o.jsx(he,{variant:"outline",size:"sm",disabled:J||!le||H.length<6,onClick:Pt,children:"Regenerate recovery codes"}),o.jsx(he,{variant:"destructive",size:"sm",disabled:!le||H.length<6,onClick:en,children:"Disable TOTP"})]})]})]}),o.jsxs("div",{className:"space-y-2 border-t pt-4",children:[o.jsx(Se,{children:"Change password"}),o.jsx(De,{type:"password",placeholder:"Current password",value:u.current,onChange:se=>f({...u,current:se.target.value})}),o.jsx(De,{type:"password",placeholder:"New password (12+ chars)",value:u.next,onChange:se=>f({...u,next:se.target.value})}),o.jsx(he,{disabled:!u.current||u.next.length<12,onClick:async()=>{try{await Ce.post("/api/admin/account/password",{currentPassword:u.current,newPassword:u.next}),ge.success("Password changed"),f({current:"",next:""})}catch(se){ge.error(se.message)}},children:"Change password"})]})]})]})}),o.jsx(Os,{value:"backup",children:o.jsxs(tt,{children:[o.jsxs(nt,{children:[o.jsx(at,{className:"text-base",children:"Backup & restore"}),o.jsx(bn,{children:"Download a snapshot or restore from a previous backup"})]}),o.jsxs(rt,{className:"space-y-3",children:[o.jsxs("div",{className:"space-y-2 rounded border p-3",children:[o.jsx(Se,{children:"Backup profile"}),o.jsxs(Ra,{value:de,onValueChange:se=>me(se),children:[o.jsx(da,{"data-testid":"backup-profile",children:o.jsx(Na,{})}),o.jsxs(fa,{children:[o.jsx(wt,{value:"compact",children:"Compact (default)"}),o.jsx(wt,{value:"full",children:"Full forensic"})]})]}),o.jsx("p",{className:"text-xs text-muted-foreground",children:de==="compact"?"Keeps configuration and daily statistics by model, provider, and API key. Excludes requests, attempts, audit logs, and the response cache — much smaller, less sensitive.":"Keeps everything, including requests, attempts, audit logs, and the response cache. May be much larger and contains sensitive request data."}),de==="full"&&o.jsx("p",{className:"rounded bg-amber-50 border border-amber-200 p-2 text-xs text-amber-900 dark:bg-amber-950/20 dark:border-amber-800 dark:text-amber-200",children:"⚠️ Full forensic backups include raw request content and audit logs. Store the file securely."})]}),o.jsxs("div",{className:"space-y-2 rounded border p-3",children:[o.jsx(Se,{children:"Backup passphrase (6 digits)"}),o.jsx(De,{inputMode:"numeric",maxLength:6,value:X,onChange:se=>re(se.target.value.replace(/\D/g,"")),placeholder:"123456"}),o.jsx(De,{inputMode:"numeric",maxLength:6,value:fe,onChange:se=>ve(se.target.value.replace(/\D/g,"")),placeholder:"Repeat passphrase"}),o.jsx("p",{className:"text-xs text-muted-foreground",children:"This passphrase encrypts the master key inside the backup. You must enter the same 6 digits when importing on a new instance. Without it, encrypted provider credentials cannot be recovered."})]}),o.jsx(he,{disabled:X.length!==6||X!==fe,onClick:xt,children:"Download backup"}),o.jsxs("div",{className:"space-y-2 rounded border p-3",children:[o.jsx(Se,{children:"Backup passphrase for restore"}),o.jsx(De,{inputMode:"numeric",maxLength:6,value:V,onChange:se=>oe(se.target.value.replace(/\D/g,"")),placeholder:"123456"}),o.jsx("p",{className:"text-xs text-muted-foreground",children:"Use the 6-digit passphrase entered when the backup was created. It is required to restore the master key and administrator access."})]}),o.jsxs(dp,{open:z!==null&&!St,onOpenChange:se=>{se||I(null)},children:[o.jsx(SO,{asChild:!0,children:o.jsxs("div",{children:[o.jsx(Se,{children:"Restore from backup file"}),o.jsx(De,{type:"file",accept:".ldb,.ldb.json,application/octet-stream,application/json","data-testid":"restore-file",disabled:St,onChange:se=>{var it;const qe=(it=se.target.files)==null?void 0:it[0];I(qe??null)}})]})}),o.jsxs(Iu,{children:[o.jsxs(fp,{children:[o.jsx(Pu,{children:"Restore backup?"}),o.jsxs(qu,{children:["Restoring will replace the entire current database with the selected backup (",(z==null?void 0:z.name)??"file","). This cannot be undone. A snapshot of the current database is kept for rollback only if validation fails."]})]}),o.jsxs(hp,{children:[o.jsx($u,{children:"Cancel"}),o.jsx(Vu,{disabled:jt,onClick:on,children:"Restore"})]})]})]}),jt&&o.jsxs("p",{"data-testid":"size-warning",className:"rounded bg-amber-50 border border-amber-200 p-2 text-xs text-amber-900 dark:bg-amber-950/20 dark:border-amber-800 dark:text-amber-200",children:["⚠️ This file is ",(((z==null?void 0:z.size)??0)/1048576).toFixed(1)," MiB, over the server limit of ",(st/1048576).toFixed(0)," MiB. The upload will be rejected — choose a smaller backup."]}),xe!=="idle"&&o.jsxs("div",{className:"space-y-2 rounded border p-3","data-testid":"restore-progress",children:[o.jsxs("div",{className:"flex items-center justify-between text-sm",children:[o.jsxs("span",{children:[xe==="uploading"&&"Uploading…",xe==="validating"&&"Validating…",xe==="restoring"&&"Restoring…",xe==="complete"&&"Complete",xe==="failed"&&"Failed"]}),xe==="uploading"&&Me&&o.jsxs("span",{className:"text-muted-foreground",children:[(Me.loaded/1048576).toFixed(1)," / ",(Me.total/1048576).toFixed(1)," MiB · ",Me.percent,"%"]})]}),o.jsx(Ew,{value:xe==="uploading"?(Me==null?void 0:Me.percent)??0:100,className:xe!=="uploading"?"animate-pulse":void 0}),o.jsxs("div",{className:"flex items-center gap-2",children:[xe==="uploading"&&o.jsx(he,{variant:"outline",size:"sm",onClick:()=>{var se;return(se=Qe.current)==null?void 0:se.abort()},children:"Cancel"}),o.jsx("span",{className:"text-xs text-muted-foreground",children:"Uploads are not resumable — cancelling restarts from the beginning."})]})]})]})]})}),o.jsxs(Os,{value:"system",children:[o.jsxs(tt,{children:[o.jsx(nt,{children:o.jsx(at,{className:"text-base",children:"System"})}),o.jsxs(rt,{className:"space-y-2 text-sm",children:[o.jsxs("div",{children:[o.jsx("span",{className:"text-muted-foreground",children:"App version:"})," ",s==null?void 0:s.appVersion]}),o.jsxs("div",{children:[o.jsx("span",{className:"text-muted-foreground",children:"Data directory:"})," ",o.jsx("span",{className:"font-mono",children:s==null?void 0:s.dataDir})]}),o.jsxs("div",{children:[o.jsx("span",{className:"text-muted-foreground",children:"Encryption:"})," ",s!=null&&s.masterKeyConfigured?"Configured":"Not configured"," (v",s==null?void 0:s.masterKeyVersion,")"]}),o.jsxs("div",{children:[o.jsx("span",{className:"text-muted-foreground",children:"Environment:"})," ",s==null?void 0:s.environment]}),o.jsxs("div",{className:"flex items-center gap-2 pt-2",children:[o.jsx(Ta,{checked:a.gatewayCacheEnabled,onCheckedChange:se=>Lt({gatewayCacheEnabled:se})}),o.jsx(Se,{children:"Gateway response cache (disabled by default)"})]}),o.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[o.jsxs("div",{children:[o.jsx(Se,{children:"Cache TTL (s)"}),o.jsx(De,{type:"number",min:1,value:a.gatewayCacheDefaultTtlSeconds,onChange:se=>Lt({gatewayCacheDefaultTtlSeconds:Number(se.target.value)})})]}),o.jsxs("div",{children:[o.jsx(Se,{children:"Cache max size (MB)"}),o.jsx(De,{type:"number",min:1,value:a.gatewayCacheMaxSizeMb,onChange:se=>Lt({gatewayCacheMaxSizeMb:Number(se.target.value)})})]})]}),o.jsx(he,{variant:"outline",onClick:async()=>{const se=await Ce.post("/api/admin/settings/cache/clear");ge.success(`Cleared ${se.deleted} entries`)},children:"Clear gateway cache"})]})]}),o.jsx(h4,{}),o.jsxs(tt,{className:"mt-4",children:[o.jsxs(nt,{children:[o.jsx(at,{className:"text-base",children:"Updates"}),o.jsx(bn,{children:"Automatic updates from the npm registry"})]}),o.jsxs(rt,{className:"space-y-3 text-sm",children:[j==="checking"&&!y&&o.jsxs("div",{className:"flex items-center gap-2 text-muted-foreground",children:[o.jsx(_s,{className:"h-4 w-4 animate-spin"})," Checking for updates…"]}),y&&o.jsxs(o.Fragment,{children:[o.jsxs("div",{className:"flex flex-wrap items-center gap-4",children:[o.jsxs("div",{children:[o.jsx("div",{className:"text-xs text-muted-foreground",children:"Current version"}),o.jsxs("div",{className:"font-mono",children:["v",y.currentVersion]})]}),o.jsx("span",{className:"text-muted-foreground",children:"→"}),o.jsxs("div",{children:[o.jsx("div",{className:"text-xs text-muted-foreground",children:"Latest version"}),o.jsx("div",{className:"font-mono",children:y.latestVersion?`v${y.latestVersion}`:"—"})]}),y.status.docker?o.jsx(Xe,{variant:"secondary",children:y.status.watchtower?"Docker + Watchtower":"Docker"}):y.latestVersion===null?o.jsx(Xe,{variant:"secondary",children:"Registry unreachable"}):y.hasUpdate?o.jsx(Xe,{variant:"success",children:"Update available"}):o.jsxs(Xe,{variant:"outline",children:[o.jsx(ci,{className:"mr-1 h-3 w-3"})," Up to date"]})]}),y.status.docker&&y.status.watchtower&&y.watchtowerReachable&&o.jsx("p",{className:"text-muted-foreground",children:"Watchtower pulls new images automatically every hour — or use Update now for an instant update."}),y.status.docker&&y.status.watchtower&&y.watchtowerReachable===!1&&o.jsxs("p",{className:"text-muted-foreground",children:["The Watchtower sidecar is configured but not running — start it with ",o.jsx("code",{className:"rounded bg-muted px-1 text-xs",children:"docker compose --profile updater up -d"}),"."]}),y.status.docker&&!y.status.watchtower&&o.jsx("p",{className:"text-muted-foreground",children:y.status.reason??"This instance runs in Docker — update by pulling the new image tag."}),!y.status.docker&&y.latestVersion===null&&o.jsxs("p",{className:"text-muted-foreground",children:["Could not reach the npm registry (offline or blocked). ",R&&o.jsx("span",{className:"text-destructive",children:R})]}),j==="installing"&&o.jsxs("div",{className:"flex items-center gap-2 text-muted-foreground",children:[o.jsx(_s,{className:"h-4 w-4 animate-spin"})," Applying the update… this can take a minute."]}),j==="restarting"&&o.jsxs("div",{className:"flex items-center gap-2 text-muted-foreground",children:[o.jsx(_s,{className:"h-4 w-4 animate-spin"})," Update applied — the gateway is restarting on the new version. This page reloads automatically."]}),o.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[y.hasUpdate&&j==="idle"&&(!y.status.docker||y.status.watchtower&&y.watchtowerReachable!==!1)&&o.jsxs(he,{disabled:w||y.status.docker&&y.watchtowerReachable===!1,onClick:D,children:[o.jsx(R0,{className:"mr-1 h-4 w-4"})," Update now"]}),y.hasUpdate&&y.changelogUrl&&o.jsx(he,{variant:"outline",asChild:!0,children:o.jsx("a",{href:y.changelogUrl,target:"_blank",rel:"noreferrer",children:"View changes"})}),j==="idle"&&o.jsx(he,{variant:"ghost",disabled:w,onClick:()=>T(!0),children:"Check again"})]})]})]})]})]})]})]})}function h4(){const n=BS();return o.jsxs(tt,{className:"mt-4",children:[o.jsx(nt,{children:o.jsxs(at,{className:"text-base flex items-center gap-2",children:[o.jsx(WE,{className:"h-4 w-4"})," Notifications"]})}),o.jsxs(rt,{className:"space-y-3 text-sm",children:[o.jsxs("div",{className:"flex items-center justify-between",children:[o.jsx("span",{children:"Show request notifications"}),o.jsx(Ta,{checked:n.enabled,onCheckedChange:a=>void Qb({enabled:a})})]}),o.jsxs("div",{className:"flex items-center justify-between",children:[o.jsxs("span",{className:"flex items-center gap-1",children:[o.jsx(CR,{className:"h-3 w-3"})," Play notification sound"]}),o.jsx(Ta,{checked:n.sound,onCheckedChange:a=>void Qb({sound:a})})]}),o.jsx("p",{className:"text-xs text-muted-foreground mt-2",children:"Notifications are disabled while muted. Changes apply immediately."})]})]})}function m4({items:n,onDismiss:a}){return n.length?o.jsx("div",{className:"fixed top-16 right-4 z-50 flex max-h-[calc(100vh-8rem)] w-80 flex-col gap-2 overflow-y-auto",children:n.map(l=>{const s=!l.success,c=l.success&&l.totalLatencyMs>15e3,u=Ee("rounded-md border shadow-lg transition-all",s&&"bg-destructive text-destructive-foreground border-destructive",c&&"bg-amber-500/90 text-amber-950 border-amber-600/50",!s&&!c&&"bg-card text-card-foreground border-border");return o.jsxs(ia,{to:"/requests",className:Ee("block shrink-0 p-3 hover:opacity-95",u),children:[o.jsxs("div",{className:"flex items-start justify-between gap-2",children:[o.jsxs("div",{className:"flex min-w-0 flex-1 items-center gap-2",children:[s?o.jsx(aR,{className:"h-4 w-4 shrink-0"}):l.success?o.jsx(ci,{className:"h-4 w-4 shrink-0"}):o.jsx(ER,{className:"h-4 w-4 shrink-0 opacity-70"}),o.jsx("div",{className:"min-w-0 truncate text-sm font-medium",title:l.requestedModel,children:l.requestedModel})]}),o.jsx("button",{className:"shrink-0 opacity-60 hover:opacity-100",onClick:f=>{f.preventDefault(),f.stopPropagation(),a(l.id)},"aria-label":"Dismiss",type:"button",children:o.jsx(ju,{className:"h-3.5 w-3.5"})})]}),o.jsxs("div",{className:"mt-1 text-xs",children:[l.success?"Thành công":"Thất bại",!l.success&&l.errorType&&o.jsx("span",{className:"ml-1 inline-block rounded bg-black/15 px-1 py-0.5 align-text-bottom text-[10px]",children:l.errorType})]}),o.jsxs("div",{className:"mt-1 text-[11px] opacity-90",children:["in ",Jt(l.inputTokens)," · out ",Jt(l.outputTokens),(l.cacheReadTokens>0||l.cacheWriteTokens>0)&&o.jsxs(o.Fragment,{children:[" · cache ",l.cacheReadTokens>0&&o.jsxs("span",{children:["r",Jt(l.cacheReadTokens)]}),l.cacheReadTokens>0&&l.cacheWriteTokens>0&&"/",l.cacheWriteTokens>0&&o.jsxs("span",{children:["w",Jt(l.cacheWriteTokens)]})]})]}),o.jsxs("div",{className:"mt-1 text-[11px] opacity-90",children:[Ol(l.totalLatencyMs),l.ttftMs!=null&&l.ttftMs>=0&&o.jsxs("span",{children:[" · TTFT ",Ol(l.ttftMs)]})]})]},l.id)})}):null}const p4=5e3,g4=8,v4=3e3;let Gc=null;function x4(){try{Gc||(Gc=new Audio("/notification.mp3")),Gc.currentTime=0,Gc.play().catch(()=>{})}catch{}}function y4(){const[n,a]=m.useState([]),l=m.useRef(null),s=m.useRef(new Map),c=m.useRef(Date.now()),u=m.useRef(new Set),f=BS(),p=m.useRef(f.sound);p.current=f.sound,m.useEffect(()=>{US()},[]);const g=f.enabled;return m.useEffect(()=>{var w;if(!g){(w=l.current)==null||w.close(),l.current=null;const E=s.current;for(const j of E.values())clearTimeout(j);E.clear(),a([]);return}let x=!1;const y=s.current,b=()=>{if(x)return;const E=new EventSource(`/api/admin/requests/stream?since=${c.current}`);l.current=E,E.addEventListener("request",j=>{if(!x)try{const C=JSON.parse(j.data),R=new Date(C.createdAt).getTime();if(Number.isFinite(R)&&(c.current=Math.max(c.current,R)),u.current.has(C.id))return;u.current.add(C.id),a(T=>T.some(D=>D.id===C.id)?T:[C,...T].slice(0,g4));const M=setTimeout(()=>{a(T=>T.filter(D=>D.id!==C.id)),y.delete(C.id)},p4);y.set(C.id,M),p.current&&x4()}catch{}}),E.onerror=()=>{E.close(),l.current=null,x||setTimeout(b,v4)}};return b(),()=>{var E;x=!0,(E=l.current)==null||E.close(),l.current=null;for(const j of y.values())clearTimeout(j);y.clear()}},[g]),{items:n,dismiss:x=>{const y=s.current.get(x);y&&(clearTimeout(y),s.current.delete(x)),a(b=>b.filter(w=>w.id!==x))}}}function b4({children:n}){const{user:a,loading:l}=km(),s=Bn();return l?o.jsx("div",{className:"flex h-screen items-center justify-center text-muted-foreground",children:"Loading…"}):a?o.jsx(o.Fragment,{children:n}):o.jsx(Ih,{to:"/login",state:{from:s},replace:!0})}function w4(){const{items:n,dismiss:a}=y4();return o.jsxs("div",{className:"flex h-screen bg-background text-foreground",children:[o.jsx(oN,{}),o.jsxs("div",{className:"flex flex-1 flex-col overflow-hidden",children:[o.jsx(iD,{}),o.jsx("main",{className:"flex-1 overflow-auto p-6",children:o.jsxs(v0,{children:[o.jsx(On,{index:!0,element:o.jsx($D,{})}),o.jsx(On,{path:"/providers",element:o.jsx(x_,{})}),o.jsx(On,{path:"/models",element:o.jsx(D_,{})}),o.jsx(On,{path:"/combos",element:o.jsx(j3,{})}),o.jsx(On,{path:"/aliases",element:o.jsx(R3,{})}),o.jsx(On,{path:"/api-keys",element:o.jsx(N3,{})}),o.jsx(On,{path:"/requests",element:o.jsx(A3,{})}),o.jsx(On,{path:"/statistics",element:o.jsx(c4,{})}),o.jsx(On,{path:"/audit",element:o.jsx(u4,{})}),o.jsx(On,{path:"/settings/*",element:o.jsx(f4,{})})]})})]}),o.jsx(m4,{items:n,onDismiss:a})]})}function S4({children:n}){const[a,l]=m.useState(null),s=Bn();return m.useEffect(()=>{Ce.get("/api/admin/setup/status").then(c=>l(c.setupComplete)).catch(()=>l(!0))},[]),a===null?o.jsx("div",{className:"flex h-screen items-center justify-center text-muted-foreground",children:"Loading…"}):!a&&s.pathname!=="/setup"?o.jsx(Ih,{to:"/setup",replace:!0}):a&&s.pathname==="/setup"?o.jsx(Ih,{to:"/",replace:!0}):o.jsx(o.Fragment,{children:n})}function j4(){return o.jsx(KE,{children:o.jsx(S4,{children:o.jsxs(v0,{children:[o.jsx(On,{path:"/setup",element:o.jsx(qD,{})}),o.jsx(On,{path:"/login",element:o.jsx(HD,{})}),o.jsx(On,{path:"/*",element:o.jsx(b4,{children:o.jsx(w4,{})})})]})})})}const C4=BD;var E4=Object.defineProperty,Ln=(n,a)=>E4(n,"name",{value:a,configurable:!0}),[Hp,a5]=Hn("Tooltip",[Fs]),R4=Fs(),N4="TooltipProvider",T4=700,Zb="tooltip.open",[M4,A4]=Hp(N4),D4=Ln(n=>{const{__scopeTooltip:a,delayDuration:l=T4,skipDelayDuration:s=300,disableHoverableContent:c=!1,children:u}=n,f=m.useRef(!0),p=m.useRef(!1),g=m.useRef(0);return m.useEffect(()=>{const v=g.current;return()=>window.clearTimeout(v)},[]),o.jsx(M4,{scope:a,isOpenDelayedRef:f,delayDuration:l,onOpen:m.useCallback(()=>{s<=0||(window.clearTimeout(g.current),f.current=!1)},[s]),onClose:m.useCallback(()=>{s<=0||(window.clearTimeout(g.current),g.current=window.setTimeout(()=>f.current=!0,s))},[s]),isPointerInTransitRef:p,onPointerInTransitChange:m.useCallback(v=>{p.current=v},[]),disableHoverableContent:c,children:u})},"TooltipProvider"),O4="Tooltip",[r5,Ip]=Hp(O4),_4="TooltipPortal",[l5,k4]=Hp(_4,{forceMount:void 0}),li="TooltipContent",z4=m.forwardRef(Ln(function(a,l){const s=k4(li,a.__scopeTooltip),{forceMount:c=s.forceMount,side:u="top",...f}=a,p=Ip(li,a.__scopeTooltip);return o.jsx(Er,{present:c||p.open,children:p.disableHoverableContent?o.jsx(HS,{side:u,...f,ref:l}):o.jsx(L4,{side:u,...f,ref:l})})},"TooltipContent")),L4=m.forwardRef(Ln(function(a,l){const s=Ip(li,a.__scopeTooltip),c=A4(li,a.__scopeTooltip),u=m.useRef(null),f=Ke(l,u),[p,g]=m.useState(null),{trigger:v,onClose:x}=s,y=u.current,{onPointerInTransitChange:b}=c,w=m.useCallback(()=>{g(null),b(!1)},[b]),E=m.useCallback((j,C)=>{const R=j.currentTarget,M={x:j.clientX,y:j.clientY},T=IS(M,R.getBoundingClientRect()),D=PS(M,T),_=qS(C.getBoundingClientRect()),A=$S([...D,..._]);g(A),b(!0)},[b]);return m.useEffect(()=>()=>w(),[w]),m.useEffect(()=>{if(v&&y){const j=Ln(R=>E(R,y),"handleTriggerLeave"),C=Ln(R=>E(R,v),"handleContentLeave");return v.addEventListener("pointerleave",j),y.addEventListener("pointerleave",C),()=>{v.removeEventListener("pointerleave",j),y.removeEventListener("pointerleave",C)}}},[v,y,E,w]),m.useEffect(()=>{if(p){const j=Ln(C=>{const R=C.target,M={x:C.clientX,y:C.clientY},T=(v==null?void 0:v.contains(R))||(y==null?void 0:y.contains(R)),D=!VS(M,p);T?w():D&&(w(),x())},"handleTrackPointerGrace");return document.addEventListener("pointermove",j),()=>document.removeEventListener("pointermove",j)}},[v,y,p,x,w]),o.jsx(HS,{...a,ref:f})},"TooltipContentHoverable")),U4=V0("TooltipContent"),HS=m.forwardRef(Ln(function(a,l){const{__scopeTooltip:s,children:c,"aria-label":u,id:f,onEscapeKeyDown:p,onPointerDownOutside:g,...v}=a,x=Ip(li,s),y=R4(s),{onClose:b}=x;m.useEffect(()=>(document.addEventListener(Zb,b),()=>document.removeEventListener(Zb,b)),[b]),m.useEffect(()=>{if(x.trigger){const E=Ln(j=>{j.target instanceof Node&&j.target.contains(x.trigger)&&b()},"handleScroll");return window.addEventListener("scroll",E,{capture:!0}),()=>window.removeEventListener("scroll",E,{capture:!0})}},[x.trigger,b]);const{setContentId:w}=x;return Wt(()=>(w(f),()=>{w(void 0)}),[f,w]),o.jsx(Ru,{asChild:!0,disableOutsidePointerEvents:!1,onEscapeKeyDown:p,onPointerDownOutside:g,onFocusOutside:E=>E.preventDefault(),onDismiss:b,children:o.jsxs(Zm,{"data-state":x.stateAttribute,role:u?void 0:"tooltip",id:u?void 0:x.contentId,...y,...v,ref:l,style:{...v.style,"--radix-tooltip-content-transform-origin":"var(--radix-popper-transform-origin)","--radix-tooltip-content-available-width":"var(--radix-popper-available-width)","--radix-tooltip-content-available-height":"var(--radix-popper-available-height)","--radix-tooltip-trigger-width":"var(--radix-popper-anchor-width)","--radix-tooltip-trigger-height":"var(--radix-popper-anchor-height)"},children:[o.jsx(U4,{children:c}),u?o.jsx(DO,{id:x.contentId,role:"tooltip",children:u}):null]})})},"TooltipContentImpl"));function IS(n,a){const l=Math.abs(a.top-n.y),s=Math.abs(a.bottom-n.y),c=Math.abs(a.right-n.x),u=Math.abs(a.left-n.x);switch(Math.min(l,s,c,u)){case u:return"left";case c:return"right";case l:return"top";case s:return"bottom";default:throw new Error("unreachable")}}Ln(IS,"getExitSideFromRect");function PS(n,a,l=5){const s=[];switch(a){case"top":s.push({x:n.x-l,y:n.y+l},{x:n.x+l,y:n.y+l});break;case"bottom":s.push({x:n.x-l,y:n.y-l},{x:n.x+l,y:n.y-l});break;case"left":s.push({x:n.x+l,y:n.y-l},{x:n.x+l,y:n.y+l});break;case"right":s.push({x:n.x-l,y:n.y-l},{x:n.x-l,y:n.y+l});break}return s}Ln(PS,"getPaddedExitPoints");function qS(n){const{top:a,right:l,bottom:s,left:c}=n;return[{x:c,y:a},{x:l,y:a},{x:l,y:s},{x:c,y:s}]}Ln(qS,"getPointsFromRect");function VS(n,a){const{x:l,y:s}=n;let c=!1;for(let u=0,f=a.length-1;u<a.length;f=u++){const p=a[u],g=a[f],v=p.x,x=p.y,y=g.x,b=g.y;x>s!=b>s&&l<(y-v)*(s-x)/(b-x)+v&&(c=!c)}return c}Ln(VS,"isPointInPolygon");function $S(n){const a=n.slice();return a.sort((l,s)=>l.x<s.x?-1:l.x>s.x?1:l.y<s.y?-1:l.y>s.y?1:0),YS(a)}Ln($S,"getHull");function YS(n){if(n.length<=1)return n.slice();const a=[];for(let s=0;s<n.length;s++){const c=n[s];for(;a.length>=2;){const u=a[a.length-1],f=a[a.length-2];if((u.x-f.x)*(c.y-f.y)>=(u.y-f.y)*(c.x-f.x))a.pop();else break}a.push(c)}a.pop();const l=[];for(let s=n.length-1;s>=0;s--){const c=n[s];for(;l.length>=2;){const u=l[l.length-1],f=l[l.length-2];if((u.x-f.x)*(c.y-f.y)>=(u.y-f.y)*(c.x-f.x))l.pop();else break}l.push(c)}return l.pop(),a.length===1&&l.length===1&&a[0].x===l[0].x&&a[0].y===l[0].y?a:a.concat(l)}Ln(YS,"getHullPresorted");var B4=D4,GS=z4;const H4=B4,I4=m.forwardRef(({className:n,sideOffset:a=4,...l},s)=>o.jsx(GS,{ref:s,sideOffset:a,className:Ee("z-50 overflow-hidden rounded-md bg-primary px-3 py-1.5 text-xs text-primary-foreground animate-in fade-in-0 zoom-in-95",n),...l}));I4.displayName=GS.displayName;m2.createRoot(document.getElementById("root")).render(o.jsx(ue.StrictMode,{children:o.jsx(gN,{defaultTheme:"dark",storageKey:"latedev-theme",children:o.jsxs(H4,{children:[o.jsx(UE,{children:o.jsx(j4,{})}),o.jsx(C4,{position:"top-right"})]})})}));
@@ -6,8 +6,8 @@
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
7
  <meta name="color-scheme" content="light dark" />
8
8
  <title>LateDev Router</title>
9
- <script type="module" crossorigin src="/assets/index-BdbskFHA.js"></script>
10
- <link rel="stylesheet" crossorigin href="/assets/index-n9bGQMSj.css">
9
+ <script type="module" crossorigin src="/assets/index-DB3SrV5y.js"></script>
10
+ <link rel="stylesheet" crossorigin href="/assets/index-0Izl91xT.css">
11
11
  </head>
12
12
  <body>
13
13
  <div id="root"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ldrouter",
3
- "version": "1.19.0",
3
+ "version": "1.19.2",
4
4
  "description": "LateDev Router — lightweight self-hosted LLM gateway with admin UI",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -1 +0,0 @@
1
- *,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,-apple-system,Segoe UI,Roboto,sans-serif;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}:root{--background: 0 0% 100%;--foreground: 240 10% 3.9%;--card: 0 0% 100%;--card-foreground: 240 10% 3.9%;--popover: 0 0% 100%;--popover-foreground: 240 10% 3.9%;--primary: 341 86% 41%;--primary-foreground: 0 0% 100%;--secondary: 240 4.8% 95.9%;--secondary-foreground: 240 5.9% 10%;--muted: 240 4.8% 95.9%;--muted-foreground: 240 3.8% 46.1%;--accent: 240 4.8% 95.9%;--accent-foreground: 240 5.9% 10%;--destructive: 0 84.2% 60.2%;--destructive-foreground: 0 0% 98%;--border: 240 5.9% 90%;--input: 240 5.9% 90%;--ring: 341 86% 41%;--sidebar: 240 5.9% 98%;--sidebar-foreground: 240 10% 3.9%;--radius: .5rem}.dark{--background: 240 10% 3.9%;--foreground: 0 0% 98%;--card: 240 10% 6%;--card-foreground: 0 0% 98%;--popover: 240 10% 5%;--popover-foreground: 0 0% 98%;--primary: 341 86% 55%;--primary-foreground: 0 0% 100%;--secondary: 240 3.7% 15.9%;--secondary-foreground: 0 0% 98%;--muted: 240 3.7% 15.9%;--muted-foreground: 240 5% 64.9%;--accent: 240 3.7% 15.9%;--accent-foreground: 0 0% 98%;--destructive: 0 72% 51%;--destructive-foreground: 0 0% 98%;--border: 240 3.7% 15.9%;--input: 240 3.7% 15.9%;--ring: 341 86% 55%;--sidebar: 240 10% 5%;--sidebar-foreground: 0 0% 98%}*{border-color:hsl(var(--border))}body{background-color:hsl(var(--background));color:hsl(var(--foreground));font-feature-settings:"rlig" 1,"calt" 1}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.pointer-events-none{pointer-events:none}.visible{visibility:visible}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.inset-0{top:0;right:0;bottom:0;left:0}.left-1\/2{left:50%}.left-2{left:.5rem}.left-2\.5{left:.625rem}.left-\[50\%\]{left:50%}.right-2{right:.5rem}.right-4{right:1rem}.top-1\/2{top:50%}.top-16{top:4rem}.top-2\.5{top:.625rem}.top-4{top:1rem}.top-\[50\%\]{top:50%}.z-10{z-index:10}.z-50{z-index:50}.-mx-1{margin-left:-.25rem;margin-right:-.25rem}.my-1{margin-top:.25rem;margin-bottom:.25rem}.mb-1{margin-bottom:.25rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-6{margin-bottom:1.5rem}.ml-0\.5{margin-left:.125rem}.ml-1{margin-left:.25rem}.ml-1\.5{margin-left:.375rem}.ml-2{margin-left:.5rem}.mr-0\.5{margin-right:.125rem}.mr-1{margin-right:.25rem}.mr-2{margin-right:.5rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-6{margin-top:1.5rem}.block{display:block}.inline-block{display:inline-block}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.hidden{display:none}.h-10{height:2.5rem}.h-14{height:3.5rem}.h-2{height:.5rem}.h-20{height:5rem}.h-3{height:.75rem}.h-3\.5{height:.875rem}.h-4{height:1rem}.h-40{height:10rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-7{height:1.75rem}.h-8{height:2rem}.h-9{height:2.25rem}.h-auto{height:auto}.h-full{height:100%}.h-px{height:1px}.h-screen{height:100vh}.max-h-32{max-height:8rem}.max-h-36{max-height:9rem}.max-h-40{max-height:10rem}.max-h-48{max-height:12rem}.max-h-60{max-height:15rem}.max-h-64{max-height:16rem}.max-h-80{max-height:20rem}.max-h-96{max-height:24rem}.max-h-\[calc\(100vh-2rem\)\]{max-height:calc(100vh - 2rem)}.max-h-\[calc\(100vh-8rem\)\]{max-height:calc(100vh - 8rem)}.min-h-0{min-height:0px}.min-h-32{min-height:8rem}.min-h-\[60px\]{min-height:60px}.min-h-screen{min-height:100vh}.w-1\.5{width:.375rem}.w-16{width:4rem}.w-2{width:.5rem}.w-20{width:5rem}.w-28{width:7rem}.w-3{width:.75rem}.w-3\.5{width:.875rem}.w-32{width:8rem}.w-36{width:9rem}.w-4{width:1rem}.w-40{width:10rem}.w-5{width:1.25rem}.w-56{width:14rem}.w-60{width:15rem}.w-7{width:1.75rem}.w-8{width:2rem}.w-80{width:20rem}.w-9{width:2.25rem}.w-full{width:100%}.min-w-0{min-width:0px}.min-w-\[10rem\]{min-width:10rem}.min-w-\[8rem\]{min-width:8rem}.min-w-\[9rem\]{min-width:9rem}.min-w-\[var\(--radix-select-trigger-width\)\]{min-width:var(--radix-select-trigger-width)}.max-w-2xl{max-width:42rem}.max-w-3xl{max-width:48rem}.max-w-64{max-width:16rem}.max-w-lg{max-width:32rem}.max-w-md{max-width:28rem}.max-w-sm{max-width:24rem}.max-w-xs{max-width:20rem}.flex-1{flex:1 1 0%}.shrink-0{flex-shrink:0}.caption-bottom{caption-side:bottom}.translate-x-\[-50\%\]{--tw-translate-x: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-y-\[-50\%\]{--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-rotate-90{--tw-rotate: -90deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.cursor-default{cursor:default}.cursor-grab{cursor:grab}.cursor-pointer{cursor:pointer}.touch-none{touch-action:none}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-rows-\[auto_minmax\(0\,1fr\)_auto\]{grid-template-rows:auto minmax(0,1fr) auto}.flex-row{flex-direction:row}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.items-baseline{align-items:baseline}.items-stretch{align-items:stretch}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.space-x-1>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(.25rem * var(--tw-space-x-reverse));margin-left:calc(.25rem * calc(1 - var(--tw-space-x-reverse)))}.space-y-0\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.125rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.125rem * var(--tw-space-y-reverse))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-1\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.375rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.375rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.break-all{word-break:break-all}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:var(--radius)}.rounded-md{border-radius:calc(var(--radius) - 2px)}.rounded-sm{border-radius:calc(var(--radius) - 4px)}.border{border-width:1px}.border-2{border-width:2px}.border-b{border-bottom-width:1px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-amber-200{--tw-border-opacity: 1;border-color:rgb(253 230 138 / var(--tw-border-opacity, 1))}.border-amber-500\/40{border-color:#f59e0b66}.border-amber-600\/50{border-color:#d9770680}.border-border{border-color:hsl(var(--border))}.border-destructive{border-color:hsl(var(--destructive))}.border-destructive\/40{border-color:hsl(var(--destructive) / .4)}.border-input{border-color:hsl(var(--input))}.border-primary{border-color:hsl(var(--primary))}.border-transparent{border-color:transparent}.bg-amber-400{--tw-bg-opacity: 1;background-color:rgb(251 191 36 / var(--tw-bg-opacity, 1))}.bg-amber-50{--tw-bg-opacity: 1;background-color:rgb(255 251 235 / var(--tw-bg-opacity, 1))}.bg-amber-500{--tw-bg-opacity: 1;background-color:rgb(245 158 11 / var(--tw-bg-opacity, 1))}.bg-amber-500\/10{background-color:#f59e0b1a}.bg-amber-500\/90{background-color:#f59e0be6}.bg-background{background-color:hsl(var(--background))}.bg-black\/15{background-color:#00000026}.bg-black\/80{background-color:#000c}.bg-card{background-color:hsl(var(--card))}.bg-destructive{background-color:hsl(var(--destructive))}.bg-destructive\/10{background-color:hsl(var(--destructive) / .1)}.bg-emerald-100{--tw-bg-opacity: 1;background-color:rgb(209 250 229 / var(--tw-bg-opacity, 1))}.bg-emerald-400{--tw-bg-opacity: 1;background-color:rgb(52 211 153 / var(--tw-bg-opacity, 1))}.bg-emerald-500{--tw-bg-opacity: 1;background-color:rgb(16 185 129 / var(--tw-bg-opacity, 1))}.bg-emerald-600{--tw-bg-opacity: 1;background-color:rgb(5 150 105 / var(--tw-bg-opacity, 1))}.bg-green-100{--tw-bg-opacity: 1;background-color:rgb(220 252 231 / var(--tw-bg-opacity, 1))}.bg-muted{background-color:hsl(var(--muted))}.bg-muted\/20{background-color:hsl(var(--muted) / .2)}.bg-muted\/60{background-color:hsl(var(--muted) / .6)}.bg-popover{background-color:hsl(var(--popover))}.bg-primary{background-color:hsl(var(--primary))}.bg-primary\/10{background-color:hsl(var(--primary) / .1)}.bg-primary\/70{background-color:hsl(var(--primary) / .7)}.bg-red-100{--tw-bg-opacity: 1;background-color:rgb(254 226 226 / var(--tw-bg-opacity, 1))}.bg-red-400{--tw-bg-opacity: 1;background-color:rgb(248 113 113 / var(--tw-bg-opacity, 1))}.bg-secondary{background-color:hsl(var(--secondary))}.bg-sidebar{background-color:hsl(var(--sidebar))}.bg-transparent{background-color:transparent}.fill-amber-400{fill:#fbbf24}.fill-amber-500\/10{fill:#f59e0b1a}.fill-emerald-400{fill:#34d399}.fill-emerald-500{fill:#10b981}.fill-foreground{fill:hsl(var(--foreground))}.fill-muted-foreground{fill:hsl(var(--muted-foreground))}.fill-primary\/10{fill:hsl(var(--primary) / .1)}.fill-red-400{fill:#f87171}.fill-red-500{fill:#ef4444}.stroke-amber-500{stroke:#f59e0b}.stroke-emerald-500{stroke:#10b981}.stroke-primary{stroke:hsl(var(--primary))}.object-contain{-o-object-fit:contain;object-fit:contain}.p-1{padding:.25rem}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-6{padding:1.5rem}.px-1{padding-left:.25rem;padding-right:.25rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.pb-1{padding-bottom:.25rem}.pb-2{padding-bottom:.5rem}.pb-6{padding-bottom:1.5rem}.pl-8{padding-left:2rem}.pr-0{padding-right:0}.pr-1{padding-right:.25rem}.pr-2{padding-right:.5rem}.pt-0{padding-top:0}.pt-2{padding-top:.5rem}.pt-4{padding-top:1rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.align-middle{vertical-align:middle}.align-text-bottom{vertical-align:text-bottom}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}.text-2xl{font-size:1.5rem;line-height:2rem}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-medium{font-weight:500}.font-normal{font-weight:400}.font-semibold{font-weight:600}.tabular-nums{--tw-numeric-spacing: tabular-nums;font-variant-numeric:var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)}.leading-none{line-height:1}.tracking-tight{letter-spacing:-.025em}.text-amber-500{--tw-text-opacity: 1;color:rgb(245 158 11 / var(--tw-text-opacity, 1))}.text-amber-600{--tw-text-opacity: 1;color:rgb(217 119 6 / var(--tw-text-opacity, 1))}.text-amber-800{--tw-text-opacity: 1;color:rgb(146 64 14 / var(--tw-text-opacity, 1))}.text-amber-900{--tw-text-opacity: 1;color:rgb(120 53 15 / var(--tw-text-opacity, 1))}.text-amber-950{--tw-text-opacity: 1;color:rgb(69 26 3 / var(--tw-text-opacity, 1))}.text-blue-500{--tw-text-opacity: 1;color:rgb(59 130 246 / var(--tw-text-opacity, 1))}.text-card-foreground{color:hsl(var(--card-foreground))}.text-current{color:currentColor}.text-destructive{color:hsl(var(--destructive))}.text-destructive-foreground{color:hsl(var(--destructive-foreground))}.text-emerald-500{--tw-text-opacity: 1;color:rgb(16 185 129 / var(--tw-text-opacity, 1))}.text-emerald-600{--tw-text-opacity: 1;color:rgb(5 150 105 / var(--tw-text-opacity, 1))}.text-emerald-700{--tw-text-opacity: 1;color:rgb(4 120 87 / var(--tw-text-opacity, 1))}.text-foreground{color:hsl(var(--foreground))}.text-green-800{--tw-text-opacity: 1;color:rgb(22 101 52 / var(--tw-text-opacity, 1))}.text-muted-foreground{color:hsl(var(--muted-foreground))}.text-muted-foreground\/60{color:hsl(var(--muted-foreground) / .6)}.text-popover-foreground{color:hsl(var(--popover-foreground))}.text-primary{color:hsl(var(--primary))}.text-primary-foreground{color:hsl(var(--primary-foreground))}.text-red-500{--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.text-red-700{--tw-text-opacity: 1;color:rgb(185 28 28 / var(--tw-text-opacity, 1))}.text-secondary-foreground{color:hsl(var(--secondary-foreground))}.text-sidebar-foreground{color:hsl(var(--sidebar-foreground))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.underline{text-decoration-line:underline}.underline-offset-4{text-underline-offset:4px}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.opacity-90{opacity:.9}.shadow{--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1);--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-md{--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.outline-none{outline:2px solid transparent;outline-offset:2px}.outline{outline-style:solid}.ring-0{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-offset-background{--tw-ring-offset-color: hsl(var(--background))}.blur{--tw-blur: blur(8px);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.invert{--tw-invert: invert(100%);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-200{transition-duration:.2s}@keyframes route-active-pulse{0%{opacity:.35}50%{opacity:1}to{opacity:.35}}.route-active{animation:route-active-pulse 1.4s ease-in-out infinite}::-webkit-scrollbar{width:8px;height:8px}::-webkit-scrollbar-thumb{background:hsl(var(--border));border-radius:4px}::-webkit-scrollbar-track{background:transparent}.file\:border-0::file-selector-button{border-width:0px}.file\:bg-transparent::file-selector-button{background-color:transparent}.file\:text-sm::file-selector-button{font-size:.875rem;line-height:1.25rem}.file\:font-medium::file-selector-button{font-weight:500}.placeholder\:text-muted-foreground::-moz-placeholder{color:hsl(var(--muted-foreground))}.placeholder\:text-muted-foreground::placeholder{color:hsl(var(--muted-foreground))}.last\:border-0:last-child{border-width:0px}.hover\:bg-accent:hover{background-color:hsl(var(--accent))}.hover\:bg-destructive\/90:hover{background-color:hsl(var(--destructive) / .9)}.hover\:bg-muted:hover{background-color:hsl(var(--muted))}.hover\:bg-muted\/50:hover{background-color:hsl(var(--muted) / .5)}.hover\:bg-primary\/90:hover{background-color:hsl(var(--primary) / .9)}.hover\:bg-secondary\/80:hover{background-color:hsl(var(--secondary) / .8)}.hover\:text-accent-foreground:hover{color:hsl(var(--accent-foreground))}.hover\:text-foreground:hover{color:hsl(var(--foreground))}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-100:hover{opacity:1}.hover\:opacity-95:hover{opacity:.95}.focus\:bg-accent:focus{background-color:hsl(var(--accent))}.focus\:text-accent-foreground:focus{color:hsl(var(--accent-foreground))}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-1:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-ring:focus{--tw-ring-color: hsl(var(--ring))}.focus-visible\:outline-none:focus-visible{outline:2px solid transparent;outline-offset:2px}.focus-visible\:ring-1:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\:ring-2:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\:ring-ring:focus-visible{--tw-ring-color: hsl(var(--ring))}.focus-visible\:ring-offset-2:focus-visible{--tw-ring-offset-width: 2px}.focus-visible\:ring-offset-background:focus-visible{--tw-ring-offset-color: hsl(var(--background))}.active\:cursor-grabbing:active{cursor:grabbing}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-50:disabled{opacity:.5}.peer:disabled~.peer-disabled\:cursor-not-allowed{cursor:not-allowed}.peer:disabled~.peer-disabled\:opacity-70{opacity:.7}.data-\[disabled\]\:pointer-events-none[data-disabled]{pointer-events:none}.data-\[state\=checked\]\:translate-x-4[data-state=checked]{--tw-translate-x: 1rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[state\=unchecked\]\:translate-x-0[data-state=unchecked]{--tw-translate-x: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[state\=active\]\:bg-background[data-state=active]{background-color:hsl(var(--background))}.data-\[state\=checked\]\:bg-primary[data-state=checked]{background-color:hsl(var(--primary))}.data-\[state\=selected\]\:bg-muted[data-state=selected]{background-color:hsl(var(--muted))}.data-\[state\=unchecked\]\:bg-input[data-state=unchecked]{background-color:hsl(var(--input))}.data-\[state\=active\]\:text-foreground[data-state=active]{color:hsl(var(--foreground))}.data-\[state\=checked\]\:text-primary-foreground[data-state=checked]{color:hsl(var(--primary-foreground))}.data-\[disabled\]\:opacity-50[data-disabled]{opacity:.5}.data-\[state\=active\]\:shadow[data-state=active]{--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1);--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.dark\:border-amber-800:is(.dark *){--tw-border-opacity: 1;border-color:rgb(146 64 14 / var(--tw-border-opacity, 1))}.dark\:bg-amber-950\/20:is(.dark *){background-color:#451a0333}.dark\:bg-emerald-900\/40:is(.dark *){background-color:#064e3b66}.dark\:bg-green-900:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(20 83 45 / var(--tw-bg-opacity, 1))}.dark\:bg-red-900\/40:is(.dark *){background-color:#7f1d1d66}.dark\:text-amber-200:is(.dark *){--tw-text-opacity: 1;color:rgb(253 230 138 / var(--tw-text-opacity, 1))}.dark\:text-amber-300:is(.dark *){--tw-text-opacity: 1;color:rgb(252 211 77 / var(--tw-text-opacity, 1))}.dark\:text-emerald-300:is(.dark *){--tw-text-opacity: 1;color:rgb(110 231 183 / var(--tw-text-opacity, 1))}.dark\:text-green-200:is(.dark *){--tw-text-opacity: 1;color:rgb(187 247 208 / var(--tw-text-opacity, 1))}.dark\:text-red-300:is(.dark *){--tw-text-opacity: 1;color:rgb(252 165 165 / var(--tw-text-opacity, 1))}@media(min-width:640px){.sm\:inline{display:inline}.sm\:max-w-\[425px\]{max-width:425px}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-\[10rem_1fr\]{grid-template-columns:10rem 1fr}.sm\:flex-row{flex-direction:row}.sm\:justify-end{justify-content:flex-end}.sm\:space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(.5rem * var(--tw-space-x-reverse));margin-left:calc(.5rem * calc(1 - var(--tw-space-x-reverse)))}.sm\:rounded-lg{border-radius:var(--radius)}.sm\:text-left{text-align:left}}@media(min-width:768px){.md\:flex{display:flex}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:flex-col{flex-direction:column}}@media(min-width:1024px){.lg\:col-span-2{grid-column:span 2 / span 2}.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))}}.\[\&_tr\:last-child\]\:border-0 tr:last-child{border-width:0px}.\[\&_tr\]\:border-b tr{border-bottom-width:1px}