@camstack/ui-library 0.1.26 → 0.1.27

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/dist/index.cjs CHANGED
@@ -78,6 +78,7 @@ __export(src_exports, {
78
78
  ProviderBadge: () => ProviderBadge,
79
79
  ScrollArea: () => ScrollArea,
80
80
  Select: () => Select,
81
+ SemanticBadge: () => SemanticBadge,
81
82
  Separator: () => Separator,
82
83
  Sidebar: () => Sidebar,
83
84
  SidebarItem: () => SidebarItem,
@@ -94,6 +95,7 @@ __export(src_exports, {
94
95
  Tooltip: () => Tooltip,
95
96
  TooltipContent: () => TooltipContent,
96
97
  TooltipTrigger: () => TooltipTrigger,
98
+ VersionBadge: () => VersionBadge,
97
99
  cn: () => cn,
98
100
  createTheme: () => createTheme,
99
101
  darkColors: () => darkColors,
@@ -1348,8 +1350,30 @@ function ProviderBadge({
1348
1350
  ] });
1349
1351
  }
1350
1352
 
1351
- // src/composites/form-field.tsx
1353
+ // src/composites/version-badge.tsx
1352
1354
  var import_jsx_runtime22 = require("react/jsx-runtime");
1355
+ var VARIANT_STYLES = {
1356
+ success: "bg-emerald-400 text-emerald-950",
1357
+ warning: "bg-amber-400 text-amber-950",
1358
+ danger: "bg-red-400 text-red-950",
1359
+ info: "bg-blue-400 text-blue-950",
1360
+ neutral: "bg-foreground-subtle/20 text-foreground"
1361
+ };
1362
+ function SemanticBadge({ children, variant = "neutral", mono, className }) {
1363
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: cn(
1364
+ "inline-flex items-center rounded-md px-2 py-0.5 text-[11px] font-bold leading-tight",
1365
+ mono && "font-mono",
1366
+ VARIANT_STYLES[variant],
1367
+ className
1368
+ ), children });
1369
+ }
1370
+ function VersionBadge({ version, preRelease, className }) {
1371
+ const isPreRelease = preRelease ?? /-(alpha|beta|rc|dev|canary|next)/i.test(version);
1372
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(SemanticBadge, { variant: isPreRelease ? "warning" : "success", mono: true, className, children: version });
1373
+ }
1374
+
1375
+ // src/composites/form-field.tsx
1376
+ var import_jsx_runtime23 = require("react/jsx-runtime");
1353
1377
  function FormField({
1354
1378
  label,
1355
1379
  description,
@@ -1360,7 +1384,7 @@ function FormField({
1360
1384
  className
1361
1385
  }) {
1362
1386
  const isHorizontal = orientation === "horizontal";
1363
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
1387
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
1364
1388
  "div",
1365
1389
  {
1366
1390
  className: cn(
@@ -1369,34 +1393,34 @@ function FormField({
1369
1393
  className
1370
1394
  ),
1371
1395
  children: [
1372
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: cn(isHorizontal ? "flex-1" : ""), children: [
1373
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(Label, { children: [
1396
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: cn(isHorizontal ? "flex-1" : ""), children: [
1397
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(Label, { children: [
1374
1398
  label,
1375
- required && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "text-danger ml-0.5", children: "*" })
1399
+ required && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-danger ml-0.5", children: "*" })
1376
1400
  ] }),
1377
- description && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "text-foreground-subtle text-xs mt-0.5", children: description })
1401
+ description && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-foreground-subtle text-xs mt-0.5", children: description })
1378
1402
  ] }),
1379
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: cn(isHorizontal ? "shrink-0" : ""), children }),
1380
- error && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "text-danger text-xs", children: error })
1403
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: cn(isHorizontal ? "shrink-0" : ""), children }),
1404
+ error && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-danger text-xs", children: error })
1381
1405
  ]
1382
1406
  }
1383
1407
  );
1384
1408
  }
1385
1409
 
1386
1410
  // src/composites/page-header.tsx
1387
- var import_jsx_runtime23 = require("react/jsx-runtime");
1411
+ var import_jsx_runtime24 = require("react/jsx-runtime");
1388
1412
  function PageHeader({ title, subtitle, actions, className }) {
1389
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: cn("flex items-center justify-between mb-3", className), children: [
1390
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { children: [
1391
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h1", { className: "text-sm font-semibold text-foreground", children: title }),
1392
- subtitle && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-foreground-subtle text-xs", children: subtitle })
1413
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: cn("flex items-center justify-between mb-3", className), children: [
1414
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { children: [
1415
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("h1", { className: "text-sm font-semibold text-foreground", children: title }),
1416
+ subtitle && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-foreground-subtle text-xs", children: subtitle })
1393
1417
  ] }),
1394
- actions && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex items-center gap-2", children: actions })
1418
+ actions && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "flex items-center gap-2", children: actions })
1395
1419
  ] });
1396
1420
  }
1397
1421
 
1398
1422
  // src/composites/empty-state.tsx
1399
- var import_jsx_runtime24 = require("react/jsx-runtime");
1423
+ var import_jsx_runtime25 = require("react/jsx-runtime");
1400
1424
  function EmptyState({
1401
1425
  icon: Icon,
1402
1426
  title,
@@ -1404,18 +1428,18 @@ function EmptyState({
1404
1428
  action,
1405
1429
  className
1406
1430
  }) {
1407
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: cn("flex flex-col items-center justify-center gap-3 py-12", className), children: [
1408
- Icon && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Icon, { className: "h-12 w-12 text-foreground-subtle", "aria-hidden": "true" }),
1409
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-col items-center gap-1 text-center", children: [
1410
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-foreground-muted text-sm font-medium", children: title }),
1411
- description && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-foreground-subtle text-xs max-w-xs", children: description })
1431
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: cn("flex flex-col items-center justify-center gap-3 py-12", className), children: [
1432
+ Icon && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Icon, { className: "h-12 w-12 text-foreground-subtle", "aria-hidden": "true" }),
1433
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex flex-col items-center gap-1 text-center", children: [
1434
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "text-foreground-muted text-sm font-medium", children: title }),
1435
+ description && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "text-foreground-subtle text-xs max-w-xs", children: description })
1412
1436
  ] }),
1413
- action && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "mt-1", children: action })
1437
+ action && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "mt-1", children: action })
1414
1438
  ] });
1415
1439
  }
1416
1440
 
1417
1441
  // src/composites/confirm-dialog.tsx
1418
- var import_jsx_runtime25 = require("react/jsx-runtime");
1442
+ var import_jsx_runtime26 = require("react/jsx-runtime");
1419
1443
  function ConfirmDialog({
1420
1444
  title,
1421
1445
  message,
@@ -1427,14 +1451,14 @@ function ConfirmDialog({
1427
1451
  open,
1428
1452
  onOpenChange
1429
1453
  }) {
1430
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Dialog, { open, onOpenChange, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(DialogContent, { children: [
1431
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(DialogHeader, { children: [
1432
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(DialogTitle, { children: title }),
1433
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(DialogDescription, { children: message })
1454
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Dialog, { open, onOpenChange, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(DialogContent, { children: [
1455
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(DialogHeader, { children: [
1456
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(DialogTitle, { children: title }),
1457
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(DialogDescription, { children: message })
1434
1458
  ] }),
1435
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(DialogFooter, { children: [
1436
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Button, { variant: "ghost", onClick: onCancel, children: cancelLabel }),
1437
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
1459
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(DialogFooter, { children: [
1460
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Button, { variant: "ghost", onClick: onCancel, children: cancelLabel }),
1461
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
1438
1462
  Button,
1439
1463
  {
1440
1464
  variant: variant === "danger" ? "danger" : "primary",
@@ -1448,12 +1472,12 @@ function ConfirmDialog({
1448
1472
 
1449
1473
  // src/composites/stat-card.tsx
1450
1474
  var import_lucide_react5 = require("lucide-react");
1451
- var import_jsx_runtime26 = require("react/jsx-runtime");
1475
+ var import_jsx_runtime27 = require("react/jsx-runtime");
1452
1476
  function StatCard({ value, label, trend, className }) {
1453
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(Card, { className: cn("flex flex-col gap-1", className), children: [
1454
- /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex items-baseline gap-2", children: [
1455
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "text-2xl font-semibold text-foreground", children: value }),
1456
- trend && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
1477
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(Card, { className: cn("flex flex-col gap-1", className), children: [
1478
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex items-baseline gap-2", children: [
1479
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "text-2xl font-semibold text-foreground", children: value }),
1480
+ trend && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
1457
1481
  "span",
1458
1482
  {
1459
1483
  className: cn(
@@ -1461,27 +1485,27 @@ function StatCard({ value, label, trend, className }) {
1461
1485
  trend.direction === "up" ? "text-success" : "text-danger"
1462
1486
  ),
1463
1487
  children: [
1464
- trend.direction === "up" ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react5.TrendingUp, { className: "h-3 w-3" }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react5.TrendingDown, { className: "h-3 w-3" }),
1488
+ trend.direction === "up" ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react5.TrendingUp, { className: "h-3 w-3" }) : /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react5.TrendingDown, { className: "h-3 w-3" }),
1465
1489
  trend.value,
1466
1490
  "%"
1467
1491
  ]
1468
1492
  }
1469
1493
  )
1470
1494
  ] }),
1471
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "text-xs text-foreground-muted", children: label })
1495
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "text-xs text-foreground-muted", children: label })
1472
1496
  ] });
1473
1497
  }
1474
1498
 
1475
1499
  // src/composites/key-value-list.tsx
1476
- var import_jsx_runtime27 = require("react/jsx-runtime");
1500
+ var import_jsx_runtime28 = require("react/jsx-runtime");
1477
1501
  function KeyValueList({ items, className }) {
1478
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("dl", { className: cn("flex flex-col", className), children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
1502
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("dl", { className: cn("flex flex-col", className), children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
1479
1503
  "div",
1480
1504
  {
1481
1505
  className: "flex items-center h-7",
1482
1506
  children: [
1483
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("dt", { className: "text-foreground-subtle text-xs w-1/3 shrink-0", children: item.key }),
1484
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("dd", { className: "text-foreground text-xs", children: item.value })
1507
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("dt", { className: "text-foreground-subtle text-xs w-1/3 shrink-0", children: item.key }),
1508
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("dd", { className: "text-foreground text-xs", children: item.value })
1485
1509
  ]
1486
1510
  },
1487
1511
  item.key
@@ -1491,7 +1515,7 @@ function KeyValueList({ items, className }) {
1491
1515
  // src/composites/code-block.tsx
1492
1516
  var import_react21 = require("react");
1493
1517
  var import_lucide_react6 = require("lucide-react");
1494
- var import_jsx_runtime28 = require("react/jsx-runtime");
1518
+ var import_jsx_runtime29 = require("react/jsx-runtime");
1495
1519
  function CodeBlock({ children, maxHeight = 300, className }) {
1496
1520
  const [copied, setCopied] = (0, import_react21.useState)(false);
1497
1521
  const handleCopy = (0, import_react21.useCallback)(() => {
@@ -1500,9 +1524,9 @@ function CodeBlock({ children, maxHeight = 300, className }) {
1500
1524
  setTimeout(() => setCopied(false), 2e3);
1501
1525
  });
1502
1526
  }, [children]);
1503
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: cn("relative group", className), children: [
1504
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(ScrollArea, { style: { maxHeight }, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("pre", { className: "font-mono text-xs bg-surface p-3 rounded-md border border-border-subtle", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("code", { children }) }) }),
1505
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "absolute top-2 right-2 opacity-0 group-hover:opacity-100 transition-opacity", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
1527
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: cn("relative group", className), children: [
1528
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(ScrollArea, { style: { maxHeight }, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("pre", { className: "font-mono text-xs bg-surface p-3 rounded-md border border-border-subtle", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("code", { children }) }) }),
1529
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "absolute top-2 right-2 opacity-0 group-hover:opacity-100 transition-opacity", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
1506
1530
  IconButton,
1507
1531
  {
1508
1532
  icon: copied ? import_lucide_react6.Check : import_lucide_react6.Copy,
@@ -1517,27 +1541,27 @@ function CodeBlock({ children, maxHeight = 300, className }) {
1517
1541
 
1518
1542
  // src/composites/filter-bar.tsx
1519
1543
  var import_lucide_react7 = require("lucide-react");
1520
- var import_jsx_runtime29 = require("react/jsx-runtime");
1544
+ var import_jsx_runtime30 = require("react/jsx-runtime");
1521
1545
  function FilterBar({ filters, values, onChange, className }) {
1522
1546
  const handleChange = (key, value) => {
1523
1547
  onChange({ ...values, [key]: value });
1524
1548
  };
1525
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: cn("flex items-center gap-2 flex-wrap", className), children: filters.map((filter) => {
1549
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: cn("flex items-center gap-2 flex-wrap", className), children: filters.map((filter) => {
1526
1550
  switch (filter.type) {
1527
1551
  case "search":
1528
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
1552
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
1529
1553
  Input,
1530
1554
  {
1531
1555
  placeholder: filter.placeholder ?? "Search...",
1532
1556
  value: values[filter.key] ?? "",
1533
1557
  onChange: (e) => handleChange(filter.key, e.target.value),
1534
- leftSlot: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react7.Search, { className: "h-3 w-3 text-foreground-subtle" }),
1558
+ leftSlot: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_lucide_react7.Search, { className: "h-3 w-3 text-foreground-subtle" }),
1535
1559
  className: "w-48"
1536
1560
  },
1537
1561
  filter.key
1538
1562
  );
1539
1563
  case "select":
1540
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
1564
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
1541
1565
  Select,
1542
1566
  {
1543
1567
  options: filter.options,
@@ -1548,10 +1572,10 @@ function FilterBar({ filters, values, onChange, className }) {
1548
1572
  filter.key
1549
1573
  );
1550
1574
  case "badge-toggle":
1551
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "flex items-center gap-1", children: filter.options.map((option) => {
1575
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "flex items-center gap-1", children: filter.options.map((option) => {
1552
1576
  const currentValue = values[filter.key];
1553
1577
  const isActive = currentValue === option.value;
1554
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
1578
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
1555
1579
  "button",
1556
1580
  {
1557
1581
  type: "button",
@@ -1559,7 +1583,7 @@ function FilterBar({ filters, values, onChange, className }) {
1559
1583
  filter.key,
1560
1584
  isActive ? void 0 : option.value
1561
1585
  ),
1562
- children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
1586
+ children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
1563
1587
  Badge,
1564
1588
  {
1565
1589
  variant: isActive ? "info" : "default",
@@ -1578,7 +1602,7 @@ function FilterBar({ filters, values, onChange, className }) {
1578
1602
  }
1579
1603
 
1580
1604
  // src/composites/app-shell/sidebar-item.tsx
1581
- var import_jsx_runtime30 = require("react/jsx-runtime");
1605
+ var import_jsx_runtime31 = require("react/jsx-runtime");
1582
1606
  function SidebarItem({
1583
1607
  label,
1584
1608
  icon: Icon,
@@ -1587,7 +1611,7 @@ function SidebarItem({
1587
1611
  active = false,
1588
1612
  className
1589
1613
  }) {
1590
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
1614
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
1591
1615
  "a",
1592
1616
  {
1593
1617
  href,
@@ -1597,18 +1621,18 @@ function SidebarItem({
1597
1621
  className
1598
1622
  ),
1599
1623
  children: [
1600
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(Icon, { className: "h-3.5 w-3.5 shrink-0" }),
1601
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "truncate flex-1", children: label }),
1602
- badge !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(Badge, { className: "ml-auto text-[10px] px-1.5 py-0", children: badge })
1624
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Icon, { className: "h-3.5 w-3.5 shrink-0" }),
1625
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "truncate flex-1", children: label }),
1626
+ badge !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Badge, { className: "ml-auto text-[10px] px-1.5 py-0", children: badge })
1603
1627
  ]
1604
1628
  }
1605
1629
  );
1606
1630
  }
1607
1631
 
1608
1632
  // src/composites/app-shell/sidebar.tsx
1609
- var import_jsx_runtime31 = require("react/jsx-runtime");
1633
+ var import_jsx_runtime32 = require("react/jsx-runtime");
1610
1634
  function Sidebar({ logo, sections, footer, className }) {
1611
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
1635
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
1612
1636
  "nav",
1613
1637
  {
1614
1638
  className: cn(
@@ -1616,14 +1640,14 @@ function Sidebar({ logo, sections, footer, className }) {
1616
1640
  className
1617
1641
  ),
1618
1642
  children: [
1619
- logo && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "px-3 py-2 shrink-0", children: logo }),
1620
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "flex-1 overflow-auto px-1 py-1", children: sections.map((section, sectionIndex) => /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: cn(sectionIndex > 0 ? "mt-3" : ""), children: [
1621
- section.label && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "text-[10px] text-foreground-disabled uppercase tracking-wider px-2 mb-1 block", children: section.label }),
1622
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "flex flex-col gap-0.5", children: section.items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(SidebarItem, { ...item }, item.href)) })
1643
+ logo && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "px-3 py-2 shrink-0", children: logo }),
1644
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "flex-1 overflow-auto px-1 py-1", children: sections.map((section, sectionIndex) => /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: cn(sectionIndex > 0 ? "mt-3" : ""), children: [
1645
+ section.label && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "text-[10px] text-foreground-disabled uppercase tracking-wider px-2 mb-1 block", children: section.label }),
1646
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "flex flex-col gap-0.5", children: section.items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(SidebarItem, { ...item }, item.href)) })
1623
1647
  ] }, sectionIndex)) }),
1624
- footer && footer.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "shrink-0 px-1 pb-1", children: [
1625
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Separator, { className: "mb-1" }),
1626
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "flex flex-col gap-0.5", children: footer.map((item) => /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(SidebarItem, { ...item }, item.href)) })
1648
+ footer && footer.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "shrink-0 px-1 pb-1", children: [
1649
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Separator, { className: "mb-1" }),
1650
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "flex flex-col gap-0.5", children: footer.map((item) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(SidebarItem, { ...item }, item.href)) })
1627
1651
  ] })
1628
1652
  ]
1629
1653
  }
@@ -1632,29 +1656,29 @@ function Sidebar({ logo, sections, footer, className }) {
1632
1656
 
1633
1657
  // src/composites/app-shell/app-shell.tsx
1634
1658
  var import_lucide_react8 = require("lucide-react");
1635
- var import_jsx_runtime32 = require("react/jsx-runtime");
1659
+ var import_jsx_runtime33 = require("react/jsx-runtime");
1636
1660
  function AppShell({ sidebar, header, children, className }) {
1637
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: cn("flex h-screen", className), children: [
1638
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Sidebar, { ...sidebar }),
1639
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex flex-1 flex-col min-w-0", children: [
1640
- header && /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("header", { className: "flex items-center h-10 border-b border-border px-4 shrink-0", children: [
1641
- header.breadcrumbs && header.breadcrumbs.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("nav", { className: "flex items-center gap-1 text-xs flex-1 min-w-0", children: header.breadcrumbs.map((crumb, index) => {
1661
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: cn("flex h-screen", className), children: [
1662
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Sidebar, { ...sidebar }),
1663
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "flex flex-1 flex-col min-w-0", children: [
1664
+ header && /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("header", { className: "flex items-center h-10 border-b border-border px-4 shrink-0", children: [
1665
+ header.breadcrumbs && header.breadcrumbs.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("nav", { className: "flex items-center gap-1 text-xs flex-1 min-w-0", children: header.breadcrumbs.map((crumb, index) => {
1642
1666
  const isLast = index === header.breadcrumbs.length - 1;
1643
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("span", { className: "flex items-center gap-1", children: [
1644
- index > 0 && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_lucide_react8.ChevronRight, { className: "h-3 w-3 text-foreground-subtle shrink-0" }),
1645
- crumb.href && !isLast ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
1667
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("span", { className: "flex items-center gap-1", children: [
1668
+ index > 0 && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_lucide_react8.ChevronRight, { className: "h-3 w-3 text-foreground-subtle shrink-0" }),
1669
+ crumb.href && !isLast ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
1646
1670
  "a",
1647
1671
  {
1648
1672
  href: crumb.href,
1649
1673
  className: "text-foreground-subtle hover:text-foreground transition-colors truncate",
1650
1674
  children: crumb.label
1651
1675
  }
1652
- ) : /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "text-foreground truncate", children: crumb.label })
1676
+ ) : /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "text-foreground truncate", children: crumb.label })
1653
1677
  ] }, index);
1654
1678
  }) }),
1655
- header.actions && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "flex items-center gap-2 ml-auto shrink-0", children: header.actions })
1679
+ header.actions && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "flex items-center gap-2 ml-auto shrink-0", children: header.actions })
1656
1680
  ] }),
1657
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("main", { className: "flex-1 overflow-auto p-4", children })
1681
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("main", { className: "flex-1 overflow-auto p-4", children })
1658
1682
  ] })
1659
1683
  ] });
1660
1684
  }
@@ -1665,20 +1689,20 @@ var import_react_table = require("@tanstack/react-table");
1665
1689
 
1666
1690
  // src/composites/data-table/data-table-header.tsx
1667
1691
  var import_lucide_react9 = require("lucide-react");
1668
- var import_jsx_runtime33 = require("react/jsx-runtime");
1692
+ var import_jsx_runtime34 = require("react/jsx-runtime");
1669
1693
  function DataTableHeader({
1670
1694
  headerGroups,
1671
1695
  onSortingChange,
1672
1696
  stickyHeader,
1673
1697
  flexRender: render
1674
1698
  }) {
1675
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
1699
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
1676
1700
  "thead",
1677
1701
  {
1678
1702
  className: cn(
1679
1703
  stickyHeader && "sticky top-0 z-10 bg-background"
1680
1704
  ),
1681
- children: headerGroups.map((headerGroup) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("tr", { className: "h-6", children: headerGroup.headers.map((header) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
1705
+ children: headerGroups.map((headerGroup) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("tr", { className: "h-6", children: headerGroup.headers.map((header) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
1682
1706
  HeaderCell,
1683
1707
  {
1684
1708
  header,
@@ -1693,7 +1717,7 @@ function DataTableHeader({
1693
1717
  function HeaderCell({ header, sortable, flexRender: render }) {
1694
1718
  const sorted = header.column.getIsSorted();
1695
1719
  const SortIcon = sorted === "asc" ? import_lucide_react9.ArrowUp : sorted === "desc" ? import_lucide_react9.ArrowDown : import_lucide_react9.ArrowUpDown;
1696
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
1720
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
1697
1721
  "th",
1698
1722
  {
1699
1723
  className: cn(
@@ -1701,9 +1725,9 @@ function HeaderCell({ header, sortable, flexRender: render }) {
1701
1725
  sortable && "cursor-pointer select-none"
1702
1726
  ),
1703
1727
  onClick: sortable ? header.column.getToggleSortingHandler() : void 0,
1704
- children: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("span", { className: "inline-flex items-center gap-1", children: [
1728
+ children: /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("span", { className: "inline-flex items-center gap-1", children: [
1705
1729
  header.isPlaceholder ? null : render(header.column.columnDef.header, header.getContext()),
1706
- sortable && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(SortIcon, { className: "h-3 w-3" })
1730
+ sortable && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(SortIcon, { className: "h-3 w-3" })
1707
1731
  ] })
1708
1732
  }
1709
1733
  );
@@ -1711,7 +1735,7 @@ function HeaderCell({ header, sortable, flexRender: render }) {
1711
1735
 
1712
1736
  // src/composites/data-table/data-table-row.tsx
1713
1737
  var import_lucide_react10 = require("lucide-react");
1714
- var import_jsx_runtime34 = require("react/jsx-runtime");
1738
+ var import_jsx_runtime35 = require("react/jsx-runtime");
1715
1739
  function DataTableRow({
1716
1740
  row,
1717
1741
  onRowClick,
@@ -1719,7 +1743,7 @@ function DataTableRow({
1719
1743
  flexRender: render
1720
1744
  }) {
1721
1745
  const actions = rowActions ? rowActions(row.original) : [];
1722
- return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
1746
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
1723
1747
  "tr",
1724
1748
  {
1725
1749
  className: cn(
@@ -1729,17 +1753,17 @@ function DataTableRow({
1729
1753
  ),
1730
1754
  onClick: onRowClick ? () => onRowClick(row.original) : void 0,
1731
1755
  children: [
1732
- row.getVisibleCells().map((cell) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(DataTableCell, { cell, flexRender: render }, cell.id)),
1733
- actions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("td", { className: "px-2 py-1.5 w-8", children: /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(Dropdown, { children: [
1734
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
1756
+ row.getVisibleCells().map((cell) => /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(DataTableCell, { cell, flexRender: render }, cell.id)),
1757
+ actions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("td", { className: "px-2 py-1.5 w-8", children: /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(Dropdown, { children: [
1758
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
1735
1759
  DropdownTrigger,
1736
1760
  {
1737
1761
  className: "p-0.5 rounded hover:bg-surface-hover",
1738
1762
  onClick: (e) => e.stopPropagation(),
1739
- children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_lucide_react10.MoreHorizontal, { className: "h-3.5 w-3.5 text-foreground-muted" })
1763
+ children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_lucide_react10.MoreHorizontal, { className: "h-3.5 w-3.5 text-foreground-muted" })
1740
1764
  }
1741
1765
  ),
1742
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(DropdownContent, { className: "right-0 left-auto", children: actions.map((action) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
1766
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(DropdownContent, { className: "right-0 left-auto", children: actions.map((action) => /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
1743
1767
  DropdownItem,
1744
1768
  {
1745
1769
  icon: action.icon,
@@ -1758,12 +1782,12 @@ function DataTableRow({
1758
1782
  );
1759
1783
  }
1760
1784
  function DataTableCell({ cell, flexRender: render }) {
1761
- return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("td", { className: "px-2 py-1.5 text-xs text-foreground", children: render(cell.column.columnDef.cell, cell.getContext()) });
1785
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("td", { className: "px-2 py-1.5 text-xs text-foreground", children: render(cell.column.columnDef.cell, cell.getContext()) });
1762
1786
  }
1763
1787
 
1764
1788
  // src/composites/data-table/data-table-pagination.tsx
1765
1789
  var import_lucide_react11 = require("lucide-react");
1766
- var import_jsx_runtime35 = require("react/jsx-runtime");
1790
+ var import_jsx_runtime36 = require("react/jsx-runtime");
1767
1791
  var PAGE_SIZE_OPTIONS = [
1768
1792
  { value: "10", label: "10" },
1769
1793
  { value: "25", label: "25" },
@@ -1778,10 +1802,10 @@ function DataTablePagination({
1778
1802
  }) {
1779
1803
  const totalPages = Math.max(1, Math.ceil(total / pageSize));
1780
1804
  const currentPage = page + 1;
1781
- return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "flex items-center justify-between px-2 py-2 text-xs text-foreground-muted", children: [
1782
- /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "flex items-center gap-2", children: [
1783
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { children: "Rows per page" }),
1784
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "w-16", children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
1805
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "flex items-center justify-between px-2 py-2 text-xs text-foreground-muted", children: [
1806
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "flex items-center gap-2", children: [
1807
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { children: "Rows per page" }),
1808
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "w-16", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
1785
1809
  Select,
1786
1810
  {
1787
1811
  options: PAGE_SIZE_OPTIONS,
@@ -1793,14 +1817,14 @@ function DataTablePagination({
1793
1817
  }
1794
1818
  ) })
1795
1819
  ] }),
1796
- /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "flex items-center gap-2", children: [
1797
- /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("span", { children: [
1820
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "flex items-center gap-2", children: [
1821
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("span", { children: [
1798
1822
  "Page ",
1799
1823
  currentPage,
1800
1824
  " of ",
1801
1825
  totalPages
1802
1826
  ] }),
1803
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
1827
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
1804
1828
  IconButton,
1805
1829
  {
1806
1830
  icon: import_lucide_react11.ChevronLeft,
@@ -1811,7 +1835,7 @@ function DataTablePagination({
1811
1835
  onClick: () => onPaginationChange?.({ pageIndex: page - 1, pageSize })
1812
1836
  }
1813
1837
  ),
1814
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
1838
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
1815
1839
  IconButton,
1816
1840
  {
1817
1841
  icon: import_lucide_react11.ChevronRight,
@@ -1827,7 +1851,7 @@ function DataTablePagination({
1827
1851
  }
1828
1852
 
1829
1853
  // src/composites/data-table/data-table.tsx
1830
- var import_jsx_runtime36 = require("react/jsx-runtime");
1854
+ var import_jsx_runtime37 = require("react/jsx-runtime");
1831
1855
  function DataTable({
1832
1856
  data,
1833
1857
  columns: userColumns,
@@ -1850,7 +1874,7 @@ function DataTable({
1850
1874
  if (!selectable) return userColumns;
1851
1875
  const selectColumn = {
1852
1876
  id: "__select",
1853
- header: ({ table: table2 }) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
1877
+ header: ({ table: table2 }) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
1854
1878
  Checkbox,
1855
1879
  {
1856
1880
  checked: table2.getIsAllPageRowsSelected(),
@@ -1858,7 +1882,7 @@ function DataTable({
1858
1882
  "aria-label": "Select all"
1859
1883
  }
1860
1884
  ),
1861
- cell: ({ row }) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
1885
+ cell: ({ row }) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
1862
1886
  Checkbox,
1863
1887
  {
1864
1888
  checked: row.getIsSelected(),
@@ -1896,9 +1920,9 @@ function DataTable({
1896
1920
  pageCount: pagination ? Math.ceil(pagination.total / pagination.pageSize) : void 0
1897
1921
  });
1898
1922
  const hasActions = !!rowActions;
1899
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: cn("overflow-auto", className), children: [
1900
- /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("table", { className: "w-full border-collapse", children: [
1901
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
1923
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: cn("overflow-auto", className), children: [
1924
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("table", { className: "w-full border-collapse", children: [
1925
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
1902
1926
  DataTableHeader,
1903
1927
  {
1904
1928
  headerGroups: table.getHeaderGroups(),
@@ -1907,14 +1931,14 @@ function DataTable({
1907
1931
  flexRender: import_react_table.flexRender
1908
1932
  }
1909
1933
  ),
1910
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("tbody", { children: loading ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(LoadingRows, { colSpan: columns.length + (hasActions ? 1 : 0), compact }) : table.getRowModel().rows.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
1934
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("tbody", { children: loading ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(LoadingRows, { colSpan: columns.length + (hasActions ? 1 : 0), compact }) : table.getRowModel().rows.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
1911
1935
  "td",
1912
1936
  {
1913
1937
  colSpan: columns.length + (hasActions ? 1 : 0),
1914
1938
  className: "text-center py-8 text-xs text-foreground-muted",
1915
1939
  children: emptyState ?? "No data"
1916
1940
  }
1917
- ) }) : table.getRowModel().rows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
1941
+ ) }) : table.getRowModel().rows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
1918
1942
  DataTableRow,
1919
1943
  {
1920
1944
  row,
@@ -1925,7 +1949,7 @@ function DataTable({
1925
1949
  row.id
1926
1950
  )) })
1927
1951
  ] }),
1928
- pagination && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
1952
+ pagination && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
1929
1953
  DataTablePagination,
1930
1954
  {
1931
1955
  page: pagination.page,
@@ -1937,11 +1961,11 @@ function DataTable({
1937
1961
  ] });
1938
1962
  }
1939
1963
  function LoadingRows({ colSpan, compact }) {
1940
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_jsx_runtime36.Fragment, { children: Array.from({ length: 5 }).map((_, rowIdx) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("tr", { className: compact ? "h-7" : "h-9", children: Array.from({ length: colSpan }).map((_2, colIdx) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("td", { className: "px-2 py-1.5", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Skeleton, { className: "h-3 w-full" }) }, colIdx)) }, rowIdx)) });
1964
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_jsx_runtime37.Fragment, { children: Array.from({ length: 5 }).map((_, rowIdx) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("tr", { className: compact ? "h-7" : "h-9", children: Array.from({ length: colSpan }).map((_2, colIdx) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("td", { className: "px-2 py-1.5", children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(Skeleton, { className: "h-3 w-full" }) }, colIdx)) }, rowIdx)) });
1941
1965
  }
1942
1966
 
1943
1967
  // src/composites/device-card.tsx
1944
- var import_jsx_runtime37 = require("react/jsx-runtime");
1968
+ var import_jsx_runtime38 = require("react/jsx-runtime");
1945
1969
  var STATUS_COLORS = {
1946
1970
  online: "bg-success",
1947
1971
  offline: "bg-danger",
@@ -1960,7 +1984,7 @@ function DeviceCard({
1960
1984
  className
1961
1985
  }) {
1962
1986
  const isOffline = status === "offline";
1963
- return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
1987
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
1964
1988
  "div",
1965
1989
  {
1966
1990
  onClick,
@@ -1972,18 +1996,18 @@ function DeviceCard({
1972
1996
  className
1973
1997
  ),
1974
1998
  children: [
1975
- /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "flex items-center justify-between mb-2", children: [
1976
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "text-sm font-medium truncate", children: title }),
1977
- status && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: cn("h-2 w-2 rounded-full shrink-0", STATUS_COLORS[status]) })
1999
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "flex items-center justify-between mb-2", children: [
2000
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "text-sm font-medium truncate", children: title }),
2001
+ status && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: cn("h-2 w-2 rounded-full shrink-0", STATUS_COLORS[status]) })
1978
2002
  ] }),
1979
- subtitle && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "text-[11px] text-foreground-muted", children: subtitle }),
1980
- badges && badges.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "flex flex-wrap gap-1 mt-2", children: badges.map((badge, i) => {
2003
+ subtitle && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "text-[11px] text-foreground-muted", children: subtitle }),
2004
+ badges && badges.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "flex flex-wrap gap-1 mt-2", children: badges.map((badge, i) => {
1981
2005
  const cls = cn(
1982
2006
  "rounded px-1.5 py-0.5 text-[10px] flex items-center gap-0.5",
1983
2007
  selected ? "bg-primary/20" : "bg-surface-hover",
1984
2008
  badge.onClick && "hover:opacity-80 transition-opacity cursor-pointer"
1985
2009
  );
1986
- return badge.onClick ? /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
2010
+ return badge.onClick ? /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
1987
2011
  "button",
1988
2012
  {
1989
2013
  onClick: (e) => {
@@ -1997,12 +2021,12 @@ function DeviceCard({
1997
2021
  ]
1998
2022
  },
1999
2023
  i
2000
- ) : /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("span", { className: cls, children: [
2024
+ ) : /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("span", { className: cls, children: [
2001
2025
  badge.icon,
2002
2026
  badge.label
2003
2027
  ] }, i);
2004
2028
  }) }),
2005
- !isOffline && actions && actions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "flex items-center gap-0.5 mt-2 -mb-1", children: actions.map((action, i) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
2029
+ !isOffline && actions && actions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "flex items-center gap-0.5 mt-2 -mb-1", children: actions.map((action, i) => /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
2006
2030
  "button",
2007
2031
  {
2008
2032
  onClick: (e) => {
@@ -2016,21 +2040,21 @@ function DeviceCard({
2016
2040
  },
2017
2041
  i
2018
2042
  )) }),
2019
- isOffline && offlineAction && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "mt-2", onClick: (e) => e.stopPropagation(), children: offlineAction })
2043
+ isOffline && offlineAction && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "mt-2", onClick: (e) => e.stopPropagation(), children: offlineAction })
2020
2044
  ]
2021
2045
  }
2022
2046
  );
2023
2047
  }
2024
2048
 
2025
2049
  // src/composites/device-grid.tsx
2026
- var import_jsx_runtime38 = require("react/jsx-runtime");
2050
+ var import_jsx_runtime39 = require("react/jsx-runtime");
2027
2051
  function DeviceGrid({
2028
2052
  children,
2029
2053
  minCardWidth = 220,
2030
2054
  gap = 3,
2031
2055
  className
2032
2056
  }) {
2033
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
2057
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
2034
2058
  "div",
2035
2059
  {
2036
2060
  className: cn(
@@ -2050,7 +2074,7 @@ function DeviceGrid({
2050
2074
  // src/composites/pipeline-step.tsx
2051
2075
  var import_react23 = require("react");
2052
2076
  var import_lucide_react12 = require("lucide-react");
2053
- var import_jsx_runtime39 = require("react/jsx-runtime");
2077
+ var import_jsx_runtime40 = require("react/jsx-runtime");
2054
2078
  var ADDON_COLORS = {
2055
2079
  "object-detection": "border-l-blue-500",
2056
2080
  "motion-detection": "border-l-amber-500",
@@ -2149,7 +2173,7 @@ function PipelineStep({
2149
2173
  if (e.target.closest(".step-config")) return;
2150
2174
  setExpanded((v) => !v);
2151
2175
  }
2152
- return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "space-y-2", children: /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
2176
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "space-y-2", children: /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
2153
2177
  "div",
2154
2178
  {
2155
2179
  className: cn(
@@ -2158,18 +2182,18 @@ function PipelineStep({
2158
2182
  !step.enabled && "opacity-[0.45]"
2159
2183
  ),
2160
2184
  children: [
2161
- /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "flex items-center gap-2.5 px-3 py-2.5 cursor-pointer select-none", onClick: handleClick, children: [
2162
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "text-foreground-subtle", children: expanded ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_lucide_react12.ChevronDown, { className: "h-4 w-4" }) : /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_lucide_react12.ChevronRight, { className: "h-4 w-4" }) }),
2163
- /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "flex-1 min-w-0", children: [
2164
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "text-[10px] uppercase tracking-wider font-medium text-foreground-subtle/60 block leading-none", children: step.slot }),
2165
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "text-sm font-semibold text-foreground truncate block leading-tight", children: step.addonName }),
2166
- /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "flex items-center gap-1 mt-0.5 flex-wrap", children: [
2167
- step.inputClasses.map((c) => /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "text-[9px] uppercase font-semibold tracking-wide px-1.5 py-0.5 rounded bg-blue-500/12 text-blue-400", children: c }, c)),
2168
- step.inputClasses.length > 0 && step.outputClasses.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "text-foreground-subtle/40 text-[10px]", children: "\u2192" }),
2169
- step.outputClasses.map((c) => /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "text-[9px] uppercase font-semibold tracking-wide px-1.5 py-0.5 rounded bg-green-500/12 text-green-400", children: c }, c))
2185
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "flex items-center gap-2.5 px-3 py-2.5 cursor-pointer select-none", onClick: handleClick, children: [
2186
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "text-foreground-subtle", children: expanded ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_lucide_react12.ChevronDown, { className: "h-4 w-4" }) : /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_lucide_react12.ChevronRight, { className: "h-4 w-4" }) }),
2187
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "flex-1 min-w-0", children: [
2188
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "text-[10px] uppercase tracking-wider font-medium text-foreground-subtle/60 block leading-none", children: step.slot }),
2189
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "text-sm font-semibold text-foreground truncate block leading-tight", children: step.addonName }),
2190
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "flex items-center gap-1 mt-0.5 flex-wrap", children: [
2191
+ step.inputClasses.map((c) => /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "text-[9px] uppercase font-semibold tracking-wide px-1.5 py-0.5 rounded bg-blue-500/12 text-blue-400", children: c }, c)),
2192
+ step.inputClasses.length > 0 && step.outputClasses.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "text-foreground-subtle/40 text-[10px]", children: "\u2192" }),
2193
+ step.outputClasses.map((c) => /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "text-[9px] uppercase font-semibold tracking-wide px-1.5 py-0.5 rounded bg-green-500/12 text-green-400", children: c }, c))
2170
2194
  ] })
2171
2195
  ] }),
2172
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
2196
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
2173
2197
  "button",
2174
2198
  {
2175
2199
  onClick: (e) => {
@@ -2180,16 +2204,16 @@ function PipelineStep({
2180
2204
  "relative inline-flex h-6 w-11 shrink-0 items-center rounded-full transition-colors",
2181
2205
  step.enabled ? "bg-success" : "bg-foreground-subtle/30"
2182
2206
  ),
2183
- children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: cn(
2207
+ children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: cn(
2184
2208
  "inline-block h-4 w-4 rounded-full bg-white shadow transition-transform",
2185
2209
  step.enabled ? "translate-x-6" : "translate-x-1"
2186
2210
  ) })
2187
2211
  }
2188
2212
  )
2189
2213
  ] }),
2190
- expanded && /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "step-config border-t border-border bg-background px-4 py-4 space-y-3", children: [
2191
- /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "grid grid-cols-2 gap-3", children: [
2192
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
2214
+ expanded && /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "step-config border-t border-border bg-background px-4 py-4 space-y-3", children: [
2215
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "grid grid-cols-2 gap-3", children: [
2216
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
2193
2217
  ConfigSelect,
2194
2218
  {
2195
2219
  label: "Agent",
@@ -2199,7 +2223,7 @@ function PipelineStep({
2199
2223
  onChange: (v) => onChange({ ...step, agentId: v })
2200
2224
  }
2201
2225
  ),
2202
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
2226
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
2203
2227
  ConfigSelect,
2204
2228
  {
2205
2229
  label: "Runtime",
@@ -2209,7 +2233,7 @@ function PipelineStep({
2209
2233
  onChange: (v) => onChange({ ...step, runtime: v })
2210
2234
  }
2211
2235
  ),
2212
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
2236
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
2213
2237
  ConfigSelect,
2214
2238
  {
2215
2239
  label: "Backend",
@@ -2219,7 +2243,7 @@ function PipelineStep({
2219
2243
  onChange: (v) => onChange({ ...step, backend: v })
2220
2244
  }
2221
2245
  ),
2222
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
2246
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
2223
2247
  ConfigSelect,
2224
2248
  {
2225
2249
  label: "Model",
@@ -2230,15 +2254,15 @@ function PipelineStep({
2230
2254
  }
2231
2255
  )
2232
2256
  ] }),
2233
- /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { children: [
2234
- /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "flex items-center justify-between mb-1", children: [
2235
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "text-[10px] font-medium text-foreground-subtle uppercase tracking-wide", children: "Confidence" }),
2236
- /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("span", { className: "text-xs font-medium text-foreground tabular-nums", children: [
2257
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { children: [
2258
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "flex items-center justify-between mb-1", children: [
2259
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "text-[10px] font-medium text-foreground-subtle uppercase tracking-wide", children: "Confidence" }),
2260
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("span", { className: "text-xs font-medium text-foreground tabular-nums", children: [
2237
2261
  (step.confidence * 100).toFixed(0),
2238
2262
  "%"
2239
2263
  ] })
2240
2264
  ] }),
2241
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
2265
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
2242
2266
  "input",
2243
2267
  {
2244
2268
  type: "range",
@@ -2258,9 +2282,9 @@ function PipelineStep({
2258
2282
  ) });
2259
2283
  }
2260
2284
  function ConfigSelect({ label, value, options, disabled, onChange }) {
2261
- return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { children: [
2262
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("label", { className: "block text-[10px] font-medium text-foreground-subtle uppercase tracking-wide mb-1.5", children: label }),
2263
- /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
2285
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { children: [
2286
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("label", { className: "block text-[10px] font-medium text-foreground-subtle uppercase tracking-wide mb-1.5", children: label }),
2287
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
2264
2288
  "select",
2265
2289
  {
2266
2290
  value,
@@ -2268,8 +2292,8 @@ function ConfigSelect({ label, value, options, disabled, onChange }) {
2268
2292
  disabled,
2269
2293
  className: "w-full rounded-lg border border-border bg-surface px-3 py-2 text-xs text-foreground focus:outline-none focus:border-primary/50",
2270
2294
  children: [
2271
- options.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("option", { value, children: value || "default" }),
2272
- options.map((o) => /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("option", { value: o.value, disabled: o.disabled, children: o.label }, o.value))
2295
+ options.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("option", { value, children: value || "default" }),
2296
+ options.map((o) => /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("option", { value: o.value, disabled: o.disabled, children: o.label }, o.value))
2273
2297
  ]
2274
2298
  }
2275
2299
  )
@@ -2278,29 +2302,29 @@ function ConfigSelect({ label, value, options, disabled, onChange }) {
2278
2302
 
2279
2303
  // src/composites/pipeline-runtime-selector.tsx
2280
2304
  var import_lucide_react13 = require("lucide-react");
2281
- var import_jsx_runtime40 = require("react/jsx-runtime");
2305
+ var import_jsx_runtime41 = require("react/jsx-runtime");
2282
2306
  function PipelineRuntimeSelector({ options, value, onChange }) {
2283
- return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "flex flex-wrap gap-2", children: options.map((opt) => {
2307
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "flex flex-wrap gap-2", children: options.map((opt) => {
2284
2308
  const active = opt.id === value;
2285
- return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
2309
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
2286
2310
  "button",
2287
2311
  {
2288
2312
  onClick: () => opt.available && onChange(opt.id),
2289
2313
  disabled: !opt.available,
2290
2314
  className: `flex items-center gap-2 rounded-lg border px-3 py-2 text-xs font-medium transition-all ${active ? "border-primary/40 bg-primary/10 text-primary" : opt.available ? "border-border bg-surface text-foreground-subtle hover:bg-surface-hover hover:text-foreground" : "border-border/40 bg-surface/40 text-foreground-subtle/40 cursor-not-allowed"}`,
2291
2315
  children: [
2292
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_lucide_react13.Cpu, { className: "h-3.5 w-3.5 shrink-0" }),
2316
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_lucide_react13.Cpu, { className: "h-3.5 w-3.5 shrink-0" }),
2293
2317
  opt.label,
2294
- opt.isBest && /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("span", { className: "inline-flex items-center gap-0.5 rounded-full bg-amber-500/15 px-1.5 py-0.5 text-[10px] font-semibold text-amber-400", children: [
2295
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_lucide_react13.Star, { className: "h-2.5 w-2.5" }),
2318
+ opt.isBest && /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("span", { className: "inline-flex items-center gap-0.5 rounded-full bg-amber-500/15 px-1.5 py-0.5 text-[10px] font-semibold text-amber-400", children: [
2319
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_lucide_react13.Star, { className: "h-2.5 w-2.5" }),
2296
2320
  "Best"
2297
2321
  ] }),
2298
- opt.platformScore != null && /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("span", { className: "text-[10px] text-foreground-subtle/60", children: [
2322
+ opt.platformScore != null && /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("span", { className: "text-[10px] text-foreground-subtle/60", children: [
2299
2323
  "(",
2300
2324
  opt.platformScore,
2301
2325
  ")"
2302
2326
  ] }),
2303
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
2327
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
2304
2328
  "span",
2305
2329
  {
2306
2330
  className: `h-1.5 w-1.5 rounded-full ${opt.available ? "bg-success" : "bg-danger"}`
@@ -2347,7 +2371,7 @@ function validateTemplate(steps, schema) {
2347
2371
  }
2348
2372
 
2349
2373
  // src/composites/pipeline-builder.tsx
2350
- var import_jsx_runtime41 = require("react/jsx-runtime");
2374
+ var import_jsx_runtime42 = require("react/jsx-runtime");
2351
2375
  function buildSchemaMap(schema) {
2352
2376
  const map = /* @__PURE__ */ new Map();
2353
2377
  for (const slot of schema.slots) {
@@ -2376,20 +2400,20 @@ function createDefaultStep(addon, fallbackRuntime, fallbackBackend) {
2376
2400
  };
2377
2401
  }
2378
2402
  function PlaceholderStep({ addon, onClick }) {
2379
- return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
2403
+ return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
2380
2404
  "button",
2381
2405
  {
2382
2406
  type: "button",
2383
2407
  onClick,
2384
2408
  className: "w-full rounded-xl border-2 border-dashed border-border/60 px-4 py-3 text-left transition-all hover:border-primary/30 hover:bg-surface/60 group",
2385
- children: /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "flex items-center gap-3", children: [
2386
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_lucide_react14.PlusCircle, { className: "h-[18px] w-[18px] text-foreground-subtle/30 group-hover:text-primary/60 shrink-0" }),
2387
- /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "flex-1 min-w-0", children: [
2388
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "text-[13px] font-medium text-foreground-subtle/50 group-hover:text-foreground-subtle block truncate", children: addon.name }),
2389
- /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "flex items-center gap-1 mt-0.5 flex-wrap", children: [
2390
- addon.inputClasses.map((c) => /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "text-[9px] uppercase font-semibold tracking-wide px-1.5 py-0.5 rounded bg-blue-500/8 text-blue-400/50", children: c }, c)),
2391
- addon.inputClasses.length > 0 && addon.outputClasses.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "text-foreground-subtle/25 text-[10px]", children: "\u2192" }),
2392
- addon.outputClasses.map((c) => /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "text-[9px] uppercase font-semibold tracking-wide px-1.5 py-0.5 rounded bg-green-500/8 text-green-400/50", children: c }, c))
2409
+ children: /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "flex items-center gap-3", children: [
2410
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_lucide_react14.PlusCircle, { className: "h-[18px] w-[18px] text-foreground-subtle/30 group-hover:text-primary/60 shrink-0" }),
2411
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "flex-1 min-w-0", children: [
2412
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "text-[13px] font-medium text-foreground-subtle/50 group-hover:text-foreground-subtle block truncate", children: addon.name }),
2413
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "flex items-center gap-1 mt-0.5 flex-wrap", children: [
2414
+ addon.inputClasses.map((c) => /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "text-[9px] uppercase font-semibold tracking-wide px-1.5 py-0.5 rounded bg-blue-500/8 text-blue-400/50", children: c }, c)),
2415
+ addon.inputClasses.length > 0 && addon.outputClasses.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "text-foreground-subtle/25 text-[10px]", children: "\u2192" }),
2416
+ addon.outputClasses.map((c) => /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "text-[9px] uppercase font-semibold tracking-wide px-1.5 py-0.5 rounded bg-green-500/8 text-green-400/50", children: c }, c))
2393
2417
  ] })
2394
2418
  ] })
2395
2419
  ] })
@@ -2501,8 +2525,8 @@ function PipelineBuilder({
2501
2525
  }
2502
2526
  function renderStep(step) {
2503
2527
  const childPlaceholders = getChildPlaceholders(step);
2504
- return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "space-y-1.5", children: [
2505
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
2528
+ return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "space-y-1.5", children: [
2529
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
2506
2530
  PipelineStep,
2507
2531
  {
2508
2532
  step,
@@ -2514,12 +2538,12 @@ function PipelineBuilder({
2514
2538
  readOnly
2515
2539
  }
2516
2540
  ),
2517
- (step.children.length > 0 || childPlaceholders.length > 0) && /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "ml-6 pl-4 border-l-2 border-dashed border-border/40 space-y-1.5", children: [
2518
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "text-[10px] font-semibold uppercase tracking-widest text-foreground-subtle/40", children: "Slot: Cropper / Classifier" }),
2541
+ (step.children.length > 0 || childPlaceholders.length > 0) && /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "ml-6 pl-4 border-l-2 border-dashed border-border/40 space-y-1.5", children: [
2542
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "text-[10px] font-semibold uppercase tracking-widest text-foreground-subtle/40", children: "Slot: Cropper / Classifier" }),
2519
2543
  step.children.map((child) => {
2520
2544
  const childChildPlaceholders = getChildPlaceholders(child);
2521
- return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "space-y-1.5", children: [
2522
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
2545
+ return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "space-y-1.5", children: [
2546
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
2523
2547
  PipelineStep,
2524
2548
  {
2525
2549
  step: child,
@@ -2542,9 +2566,9 @@ function PipelineBuilder({
2542
2566
  readOnly
2543
2567
  }
2544
2568
  ),
2545
- (child.children.length > 0 || childChildPlaceholders.length > 0) && /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "ml-6 pl-4 border-l-2 border-dashed border-border/30 space-y-1.5", children: [
2546
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "text-[10px] font-semibold uppercase tracking-widest text-foreground-subtle/30", children: "Slot: Recognizer" }),
2547
- child.children.map((grandchild) => /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
2569
+ (child.children.length > 0 || childChildPlaceholders.length > 0) && /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "ml-6 pl-4 border-l-2 border-dashed border-border/30 space-y-1.5", children: [
2570
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "text-[10px] font-semibold uppercase tracking-widest text-foreground-subtle/30", children: "Slot: Recognizer" }),
2571
+ child.children.map((grandchild) => /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
2548
2572
  PipelineStep,
2549
2573
  {
2550
2574
  step: grandchild,
@@ -2572,7 +2596,7 @@ function PipelineBuilder({
2572
2596
  },
2573
2597
  grandchild.addonId
2574
2598
  )),
2575
- !readOnly && childChildPlaceholders.map((addon) => /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
2599
+ !readOnly && childChildPlaceholders.map((addon) => /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
2576
2600
  PlaceholderStep,
2577
2601
  {
2578
2602
  addon,
@@ -2591,7 +2615,7 @@ function PipelineBuilder({
2591
2615
  ] })
2592
2616
  ] }, child.addonId);
2593
2617
  }),
2594
- !readOnly && childPlaceholders.map((addon) => /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
2618
+ !readOnly && childPlaceholders.map((addon) => /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
2595
2619
  PlaceholderStep,
2596
2620
  {
2597
2621
  addon,
@@ -2603,22 +2627,22 @@ function PipelineBuilder({
2603
2627
  ] }, step.addonId);
2604
2628
  }
2605
2629
  const rootSlots = schema.slots.filter((s) => s.parentSlot === null).sort((a, b) => a.priority - b.priority);
2606
- return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "space-y-4", children: [
2607
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "rounded-xl border border-border bg-surface p-3", children: /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "flex items-center gap-2", children: [
2608
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "relative flex-1 min-w-0", children: /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
2630
+ return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "space-y-4", children: [
2631
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: "rounded-xl border border-border bg-surface p-3", children: /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "flex items-center gap-2", children: [
2632
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: "relative flex-1 min-w-0", children: /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
2609
2633
  "select",
2610
2634
  {
2611
2635
  value: selectedTemplateId ?? "",
2612
2636
  onChange: handleSelectTemplate,
2613
2637
  className: "w-full rounded-lg border border-border bg-background px-3 py-2 text-sm text-foreground focus:outline-none focus:border-primary/50",
2614
2638
  children: [
2615
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("option", { value: "", children: "No template" }),
2616
- templates.map((t) => /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("option", { value: t.id, children: t.name }, t.id))
2639
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("option", { value: "", children: "No template" }),
2640
+ templates.map((t) => /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("option", { value: t.id, children: t.name }, t.id))
2617
2641
  ]
2618
2642
  }
2619
2643
  ) }),
2620
- dirty && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "h-1.5 w-1.5 rounded-full bg-amber-500 shrink-0" }),
2621
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
2644
+ dirty && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "h-1.5 w-1.5 rounded-full bg-amber-500 shrink-0" }),
2645
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
2622
2646
  "button",
2623
2647
  {
2624
2648
  onClick: handleSave,
@@ -2628,10 +2652,10 @@ function PipelineBuilder({
2628
2652
  "p-2 rounded-lg border border-border transition-colors",
2629
2653
  selectedTemplateId && !readOnly ? "text-foreground-subtle hover:bg-surface-hover" : "text-foreground-subtle/30 cursor-not-allowed"
2630
2654
  ),
2631
- children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_lucide_react14.Save, { className: "h-4 w-4" })
2655
+ children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_lucide_react14.Save, { className: "h-4 w-4" })
2632
2656
  }
2633
2657
  ),
2634
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
2658
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
2635
2659
  "button",
2636
2660
  {
2637
2661
  onClick: handleSaveAs,
@@ -2641,10 +2665,10 @@ function PipelineBuilder({
2641
2665
  "p-2 rounded-lg border border-border transition-colors",
2642
2666
  !readOnly ? "text-foreground-subtle hover:bg-surface-hover" : "text-foreground-subtle/30 cursor-not-allowed"
2643
2667
  ),
2644
- children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_lucide_react14.CopyPlus, { className: "h-4 w-4" })
2668
+ children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_lucide_react14.CopyPlus, { className: "h-4 w-4" })
2645
2669
  }
2646
2670
  ),
2647
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
2671
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
2648
2672
  "button",
2649
2673
  {
2650
2674
  onClick: handleDelete,
@@ -2654,16 +2678,16 @@ function PipelineBuilder({
2654
2678
  "p-2 rounded-lg border border-border transition-colors",
2655
2679
  selectedTemplateId && !readOnly ? "text-foreground-subtle hover:text-danger" : "text-foreground-subtle/30 cursor-not-allowed"
2656
2680
  ),
2657
- children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_lucide_react14.Trash2, { className: "h-4 w-4" })
2681
+ children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_lucide_react14.Trash2, { className: "h-4 w-4" })
2658
2682
  }
2659
2683
  )
2660
2684
  ] }) }),
2661
- warnings.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "rounded-lg border border-amber-500/30 bg-amber-500/5 p-3 text-xs text-amber-400 space-y-1", children: [
2662
- /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "flex items-center justify-between", children: [
2663
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "font-medium", children: "Template loaded with warnings:" }),
2664
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("button", { onClick: () => setWarnings([]), className: "text-amber-400/60 hover:text-amber-400", children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_lucide_react14.X, { className: "h-3.5 w-3.5" }) })
2685
+ warnings.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "rounded-lg border border-amber-500/30 bg-amber-500/5 p-3 text-xs text-amber-400 space-y-1", children: [
2686
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "flex items-center justify-between", children: [
2687
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "font-medium", children: "Template loaded with warnings:" }),
2688
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("button", { onClick: () => setWarnings([]), className: "text-amber-400/60 hover:text-amber-400", children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_lucide_react14.X, { className: "h-3.5 w-3.5" }) })
2665
2689
  ] }),
2666
- warnings.map((w, i) => /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { children: [
2690
+ warnings.map((w, i) => /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { children: [
2667
2691
  "\u2022 ",
2668
2692
  w
2669
2693
  ] }, i))
@@ -2671,13 +2695,13 @@ function PipelineBuilder({
2671
2695
  rootSlots.map((slot) => {
2672
2696
  const slotSteps = steps.filter((s) => s.slot === slot.id && !excluded.has(s.addonId));
2673
2697
  const missingRootAddons = slot.addons.filter((a) => !existingIds.has(a.id) && !excluded.has(a.id));
2674
- return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "space-y-2", children: [
2675
- /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("span", { className: "text-[10px] font-semibold uppercase tracking-widest text-foreground-subtle/50", children: [
2698
+ return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "space-y-2", children: [
2699
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("span", { className: "text-[10px] font-semibold uppercase tracking-widest text-foreground-subtle/50", children: [
2676
2700
  "Slot: ",
2677
2701
  slot.label
2678
2702
  ] }),
2679
2703
  slotSteps.map((step) => renderStep(step)),
2680
- !readOnly && missingRootAddons.map((addon) => /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(PlaceholderStep, { addon, onClick: () => {
2704
+ !readOnly && missingRootAddons.map((addon) => /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(PlaceholderStep, { addon, onClick: () => {
2681
2705
  onChange([...steps, createDefaultStep(addon, defaultRuntime, defaultBackend)]);
2682
2706
  } }, addon.id))
2683
2707
  ] }, slot.id);
@@ -2758,7 +2782,7 @@ function getClassColor(className, customColors) {
2758
2782
 
2759
2783
  // src/composites/detection-canvas.tsx
2760
2784
  var import_react25 = require("react");
2761
- var import_jsx_runtime42 = require("react/jsx-runtime");
2785
+ var import_jsx_runtime43 = require("react/jsx-runtime");
2762
2786
  var DEFAULT_CLASS_COLORS = CLASS_COLORS;
2763
2787
  function DetectionCanvas({
2764
2788
  src,
@@ -2778,7 +2802,7 @@ function DetectionCanvas({
2778
2802
  }
2779
2803
  const ratio = aspectRatio ?? (imageWidth && imageHeight ? `${imageWidth}/${imageHeight}` : "16/9");
2780
2804
  const filteredDetections = detections.filter((d) => d.confidence >= minConfidence);
2781
- return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
2805
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
2782
2806
  "div",
2783
2807
  {
2784
2808
  className: cn(
@@ -2786,10 +2810,10 @@ function DetectionCanvas({
2786
2810
  className
2787
2811
  ),
2788
2812
  style: { aspectRatio: ratio },
2789
- children: src ? /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_jsx_runtime42.Fragment, { children: [
2790
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("img", { src, className: "absolute inset-0 w-full h-full object-fill", alt: "" }),
2813
+ children: src ? /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(import_jsx_runtime43.Fragment, { children: [
2814
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("img", { src, className: "absolute inset-0 w-full h-full object-fill", alt: "" }),
2791
2815
  filteredDetections.map(
2792
- (d, i) => d.mask && d.maskWidth && d.maskHeight ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
2816
+ (d, i) => d.mask && d.maskWidth && d.maskHeight ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
2793
2817
  MaskOverlay,
2794
2818
  {
2795
2819
  mask: d.mask,
@@ -2803,7 +2827,7 @@ function DetectionCanvas({
2803
2827
  `mask-${i}`
2804
2828
  ) : null
2805
2829
  ),
2806
- filteredDetections.map((d, i) => /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
2830
+ filteredDetections.map((d, i) => /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
2807
2831
  BoundingBox,
2808
2832
  {
2809
2833
  detection: d,
@@ -2823,7 +2847,7 @@ function DetectionCanvas({
2823
2847
  const ph = py2 - py1;
2824
2848
  if (pw > 0 && ph > 0 && cw * ch / (pw * ph) > 0.8) return false;
2825
2849
  return true;
2826
- }).map((child, j) => /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
2850
+ }).map((child, j) => /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
2827
2851
  ChildBoundingBox,
2828
2852
  {
2829
2853
  child,
@@ -2836,7 +2860,7 @@ function DetectionCanvas({
2836
2860
  },
2837
2861
  `det-${i}`
2838
2862
  ))
2839
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: "w-full h-full flex items-center justify-center text-foreground-subtle text-sm", children: placeholder ?? "No image loaded" })
2863
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "w-full h-full flex items-center justify-center text-foreground-subtle text-sm", children: placeholder ?? "No image loaded" })
2840
2864
  }
2841
2865
  );
2842
2866
  }
@@ -2855,13 +2879,13 @@ function BoundingBox({
2855
2879
  const topPct = y1 / imageHeight * 100;
2856
2880
  const containerRef = (0, import_react25.useRef)(null);
2857
2881
  const showBelow = topPct < labelHeightPx / imageHeight * 100 * 1.5;
2858
- const labelsElement = /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
2882
+ const labelsElement = /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
2859
2883
  "div",
2860
2884
  {
2861
2885
  className: `absolute left-0 flex flex-col items-start gap-px ${showBelow ? "" : ""}`,
2862
2886
  style: showBelow ? { top: "100%", marginTop: "2px" } : { bottom: "100%", marginBottom: "2px" },
2863
2887
  children: [
2864
- /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
2888
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
2865
2889
  "span",
2866
2890
  {
2867
2891
  className: "text-[10px] px-1 rounded-sm whitespace-nowrap text-white",
@@ -2872,7 +2896,7 @@ function BoundingBox({
2872
2896
  ]
2873
2897
  }
2874
2898
  ),
2875
- detection.labelsData?.map((l, k) => /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
2899
+ detection.labelsData?.map((l, k) => /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
2876
2900
  "span",
2877
2901
  {
2878
2902
  className: "text-[9px] font-semibold px-1 rounded-sm whitespace-nowrap text-white",
@@ -2889,7 +2913,7 @@ function BoundingBox({
2889
2913
  ]
2890
2914
  }
2891
2915
  );
2892
- return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
2916
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
2893
2917
  "div",
2894
2918
  {
2895
2919
  ref: containerRef,
@@ -2948,7 +2972,7 @@ function MaskOverlay({
2948
2972
  ctx.putImageData(imageData, 0, 0);
2949
2973
  }, [mask, maskWidth, maskHeight, color]);
2950
2974
  const [x1, y1, x2, y2] = bbox;
2951
- return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
2975
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
2952
2976
  "canvas",
2953
2977
  {
2954
2978
  ref: canvasRef,
@@ -2974,7 +2998,7 @@ function ChildBoundingBox({
2974
2998
  const pw = px2 - px1;
2975
2999
  const ph = py2 - py1;
2976
3000
  if (pw <= 0 || ph <= 0) return null;
2977
- return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
3001
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
2978
3002
  "div",
2979
3003
  {
2980
3004
  className: "absolute rounded-sm",
@@ -2991,13 +3015,13 @@ function ChildBoundingBox({
2991
3015
  const labelCount = 1 + (child.labelsData?.length ?? 0);
2992
3016
  const relTop = (cy1 - py1) / ph * 100;
2993
3017
  const showBelow = relTop < labelCount * 6;
2994
- return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
3018
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
2995
3019
  "div",
2996
3020
  {
2997
3021
  className: "absolute left-0 flex flex-col items-start gap-px",
2998
3022
  style: showBelow ? { top: "100%", marginTop: "1px" } : { bottom: "100%", marginBottom: "1px" },
2999
3023
  children: [
3000
- /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
3024
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
3001
3025
  "span",
3002
3026
  {
3003
3027
  className: "text-[9px] px-0.5 rounded-sm whitespace-nowrap text-white",
@@ -3008,7 +3032,7 @@ function ChildBoundingBox({
3008
3032
  ]
3009
3033
  }
3010
3034
  ),
3011
- child.labelsData?.map((l, k) => /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
3035
+ child.labelsData?.map((l, k) => /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
3012
3036
  "span",
3013
3037
  {
3014
3038
  className: "text-[8px] font-semibold px-0.5 rounded-sm whitespace-nowrap text-white",
@@ -3031,7 +3055,7 @@ function ChildBoundingBox({
3031
3055
  }
3032
3056
 
3033
3057
  // src/composites/detection-result-tree.tsx
3034
- var import_jsx_runtime43 = require("react/jsx-runtime");
3058
+ var import_jsx_runtime44 = require("react/jsx-runtime");
3035
3059
  function DetectionResultTree({
3036
3060
  detections,
3037
3061
  classColors,
@@ -3041,15 +3065,15 @@ function DetectionResultTree({
3041
3065
  }) {
3042
3066
  const colors = classColors;
3043
3067
  if (detections.length === 0) {
3044
- return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "text-sm text-foreground-subtle italic text-center py-4", children: "No detections" });
3068
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "text-sm text-foreground-subtle italic text-center py-4", children: "No detections" });
3045
3069
  }
3046
- return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className, children: [
3047
- /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "text-xs font-medium text-foreground-subtle uppercase tracking-wide mb-2", children: [
3070
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className, children: [
3071
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "text-xs font-medium text-foreground-subtle uppercase tracking-wide mb-2", children: [
3048
3072
  "Detections (",
3049
3073
  detections.length,
3050
3074
  ")"
3051
3075
  ] }),
3052
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "space-y-2", children: detections.map((d, i) => /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
3076
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "space-y-2", children: detections.map((d, i) => /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
3053
3077
  DetectionNode,
3054
3078
  {
3055
3079
  detection: d,
@@ -3071,10 +3095,10 @@ function DetectionNode({
3071
3095
  }) {
3072
3096
  const color = getClassColor(detection.className, colors);
3073
3097
  const isVisible = !hiddenKeys?.has(path);
3074
- return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: `rounded-md border border-border bg-surface p-3 space-y-1 ${isVisible ? "" : "opacity-40"}`, children: [
3075
- /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "flex justify-between items-center", children: [
3076
- /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "flex items-center gap-2", children: [
3077
- onToggleVisibility && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
3098
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: `rounded-md border border-border bg-surface p-3 space-y-1 ${isVisible ? "" : "opacity-40"}`, children: [
3099
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex justify-between items-center", children: [
3100
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex items-center gap-2", children: [
3101
+ onToggleVisibility && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
3078
3102
  "input",
3079
3103
  {
3080
3104
  type: "checkbox",
@@ -3083,45 +3107,45 @@ function DetectionNode({
3083
3107
  className: "h-3.5 w-3.5 rounded border-border accent-primary cursor-pointer shrink-0"
3084
3108
  }
3085
3109
  ),
3086
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
3110
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
3087
3111
  "span",
3088
3112
  {
3089
3113
  className: "h-2.5 w-2.5 rounded-full shrink-0",
3090
3114
  style: { backgroundColor: color }
3091
3115
  }
3092
3116
  ),
3093
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "text-sm font-medium text-foreground", children: detection.className }),
3094
- detection.mask && detection.maskWidth && detection.maskHeight && /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("span", { className: "text-[9px] font-mono px-1 py-0.5 rounded bg-primary/10 text-primary", children: [
3117
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "text-sm font-medium text-foreground", children: detection.className }),
3118
+ detection.mask && detection.maskWidth && detection.maskHeight && /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("span", { className: "text-[9px] font-mono px-1 py-0.5 rounded bg-primary/10 text-primary", children: [
3095
3119
  "mask ",
3096
3120
  detection.maskWidth,
3097
3121
  "x",
3098
3122
  detection.maskHeight
3099
3123
  ] })
3100
3124
  ] }),
3101
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(ConfidenceBadge, { confidence: detection.confidence })
3125
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(ConfidenceBadge, { confidence: detection.confidence })
3102
3126
  ] }),
3103
- /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "text-[10px] text-foreground-subtle font-mono", children: [
3127
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "text-[10px] text-foreground-subtle font-mono", children: [
3104
3128
  "bbox: [",
3105
3129
  detection.bbox.map((v) => Math.round(v)).join(", "),
3106
3130
  "]"
3107
3131
  ] }),
3108
- detection.labelsData && detection.labelsData.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "flex flex-wrap gap-1 mt-1", children: detection.labelsData.map((l, k) => /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
3132
+ detection.labelsData && detection.labelsData.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "flex flex-wrap gap-1 mt-1", children: detection.labelsData.map((l, k) => /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
3109
3133
  "span",
3110
3134
  {
3111
3135
  className: "inline-flex items-center gap-1 text-[10px] font-medium px-1.5 py-0.5 rounded-full",
3112
3136
  style: { backgroundColor: getClassColor(l.addonId ?? l.label, colors) + "20", color: getClassColor(l.addonId ?? l.label, colors) },
3113
3137
  children: [
3114
3138
  l.label,
3115
- /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("span", { className: "opacity-60", children: [
3139
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("span", { className: "opacity-60", children: [
3116
3140
  (l.score * 100).toFixed(0),
3117
3141
  "%"
3118
3142
  ] }),
3119
- l.addonId && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "opacity-40 text-[8px]", children: l.addonId })
3143
+ l.addonId && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "opacity-40 text-[8px]", children: l.addonId })
3120
3144
  ]
3121
3145
  },
3122
3146
  k
3123
3147
  )) }),
3124
- detection.children && detection.children.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
3148
+ detection.children && detection.children.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
3125
3149
  ChildrenTree,
3126
3150
  {
3127
3151
  children: detection.children,
@@ -3140,13 +3164,13 @@ function ChildrenTree({
3140
3164
  hiddenKeys,
3141
3165
  onToggleVisibility
3142
3166
  }) {
3143
- return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "ml-4 mt-1.5 space-y-1.5 border-l-2 border-border pl-3", children: children.map((child, j) => {
3167
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "ml-4 mt-1.5 space-y-1.5 border-l-2 border-border pl-3", children: children.map((child, j) => {
3144
3168
  const childPath = `${parentPath}.${j}`;
3145
3169
  const childColor = getClassColor(child.className, colors);
3146
3170
  const isVisible = !hiddenKeys?.has(childPath);
3147
- return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: `text-xs space-y-0.5 ${isVisible ? "" : "opacity-40"}`, children: [
3148
- /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "flex items-center gap-1.5", children: [
3149
- onToggleVisibility && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
3171
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: `text-xs space-y-0.5 ${isVisible ? "" : "opacity-40"}`, children: [
3172
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex items-center gap-1.5", children: [
3173
+ onToggleVisibility && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
3150
3174
  "input",
3151
3175
  {
3152
3176
  type: "checkbox",
@@ -3155,26 +3179,26 @@ function ChildrenTree({
3155
3179
  className: "h-3 w-3 rounded border-border accent-primary cursor-pointer shrink-0"
3156
3180
  }
3157
3181
  ),
3158
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
3182
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
3159
3183
  "span",
3160
3184
  {
3161
3185
  className: "h-1.5 w-1.5 rounded-full shrink-0",
3162
3186
  style: { backgroundColor: childColor }
3163
3187
  }
3164
3188
  ),
3165
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "font-medium", style: { color: childColor }, children: child.className }),
3166
- /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("span", { className: "text-foreground-subtle", children: [
3189
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "font-medium", style: { color: childColor }, children: child.className }),
3190
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("span", { className: "text-foreground-subtle", children: [
3167
3191
  (child.confidence * 100).toFixed(0),
3168
3192
  "%"
3169
3193
  ] }),
3170
- child.mask && child.maskWidth && child.maskHeight && /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("span", { className: "text-[9px] font-mono px-1 py-0.5 rounded bg-primary/10 text-primary", children: [
3194
+ child.mask && child.maskWidth && child.maskHeight && /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("span", { className: "text-[9px] font-mono px-1 py-0.5 rounded bg-primary/10 text-primary", children: [
3171
3195
  "mask ",
3172
3196
  child.maskWidth,
3173
3197
  "x",
3174
3198
  child.maskHeight
3175
3199
  ] })
3176
3200
  ] }),
3177
- child.labelsData && child.labelsData.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "flex flex-wrap gap-1 ml-5 mt-0.5", children: child.labelsData.map((l, k) => /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
3201
+ child.labelsData && child.labelsData.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "flex flex-wrap gap-1 ml-5 mt-0.5", children: child.labelsData.map((l, k) => /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
3178
3202
  "span",
3179
3203
  {
3180
3204
  className: "inline-flex items-center gap-0.5 text-[9px] font-medium px-1 py-0.5 rounded-full",
@@ -3182,7 +3206,7 @@ function ChildrenTree({
3182
3206
  children: [
3183
3207
  l.label,
3184
3208
  " ",
3185
- /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("span", { className: "opacity-60", children: [
3209
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("span", { className: "opacity-60", children: [
3186
3210
  (l.score * 100).toFixed(0),
3187
3211
  "%"
3188
3212
  ] })
@@ -3190,7 +3214,7 @@ function ChildrenTree({
3190
3214
  },
3191
3215
  k
3192
3216
  )) }),
3193
- child.children && child.children.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
3217
+ child.children && child.children.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
3194
3218
  ChildrenTree,
3195
3219
  {
3196
3220
  children: child.children,
@@ -3205,30 +3229,30 @@ function ChildrenTree({
3205
3229
  }
3206
3230
  function ConfidenceBadge({ confidence }) {
3207
3231
  const level = confidence >= 0.8 ? "bg-success/10 text-success" : confidence >= 0.5 ? "bg-warning/10 text-warning" : "bg-danger/10 text-danger";
3208
- return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("span", { className: `text-xs font-medium px-2 py-0.5 rounded-full ${level}`, children: [
3232
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("span", { className: `text-xs font-medium px-2 py-0.5 rounded-full ${level}`, children: [
3209
3233
  (confidence * 100).toFixed(1),
3210
3234
  "%"
3211
3235
  ] });
3212
3236
  }
3213
3237
 
3214
3238
  // src/composites/step-timings.tsx
3215
- var import_jsx_runtime44 = require("react/jsx-runtime");
3239
+ var import_jsx_runtime45 = require("react/jsx-runtime");
3216
3240
  function StepTimings({ timings, totalMs, className }) {
3217
3241
  const entries = Object.entries(timings);
3218
3242
  if (entries.length === 0 && totalMs === void 0) return null;
3219
- return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: `rounded-lg border border-border bg-surface p-3 space-y-2 ${className ?? ""}`, children: [
3220
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "text-xs font-medium text-foreground-subtle uppercase tracking-wide", children: "Timings" }),
3221
- /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "space-y-1 text-xs", children: [
3222
- entries.map(([step, ms]) => /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex justify-between", children: [
3223
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "text-foreground-subtle", children: step }),
3224
- /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("span", { className: "font-mono text-foreground", children: [
3243
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: `rounded-lg border border-border bg-surface p-3 space-y-2 ${className ?? ""}`, children: [
3244
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "text-xs font-medium text-foreground-subtle uppercase tracking-wide", children: "Timings" }),
3245
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "space-y-1 text-xs", children: [
3246
+ entries.map(([step, ms]) => /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "flex justify-between", children: [
3247
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "text-foreground-subtle", children: step }),
3248
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("span", { className: "font-mono text-foreground", children: [
3225
3249
  ms.toFixed(1),
3226
3250
  "ms"
3227
3251
  ] })
3228
3252
  ] }, step)),
3229
- totalMs !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex justify-between pt-1 border-t border-border font-medium text-foreground", children: [
3230
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { children: "Total" }),
3231
- /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("span", { className: "font-mono", children: [
3253
+ totalMs !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "flex justify-between pt-1 border-t border-border font-medium text-foreground", children: [
3254
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { children: "Total" }),
3255
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("span", { className: "font-mono", children: [
3232
3256
  totalMs.toFixed(1),
3233
3257
  "ms"
3234
3258
  ] })
@@ -3238,7 +3262,7 @@ function StepTimings({ timings, totalMs, className }) {
3238
3262
  }
3239
3263
 
3240
3264
  // src/composites/image-selector.tsx
3241
- var import_jsx_runtime45 = require("react/jsx-runtime");
3265
+ var import_jsx_runtime46 = require("react/jsx-runtime");
3242
3266
  function ImageSelector({
3243
3267
  images,
3244
3268
  selectedFilename,
@@ -3264,8 +3288,8 @@ function ImageSelector({
3264
3288
  };
3265
3289
  input.click();
3266
3290
  };
3267
- return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: `flex flex-wrap items-center gap-2 ${className ?? ""}`, children: [
3268
- images.map((img) => /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
3291
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: `flex flex-wrap items-center gap-2 ${className ?? ""}`, children: [
3292
+ images.map((img) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
3269
3293
  "button",
3270
3294
  {
3271
3295
  onClick: () => onSelect(img.filename),
@@ -3274,7 +3298,7 @@ function ImageSelector({
3274
3298
  },
3275
3299
  img.filename
3276
3300
  )),
3277
- /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
3301
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
3278
3302
  "button",
3279
3303
  {
3280
3304
  onClick: handleUploadClick,
@@ -3282,12 +3306,12 @@ function ImageSelector({
3282
3306
  children: "Upload..."
3283
3307
  }
3284
3308
  ),
3285
- uploadedName && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "text-xs text-foreground-subtle", children: uploadedName })
3309
+ uploadedName && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "text-xs text-foreground-subtle", children: uploadedName })
3286
3310
  ] });
3287
3311
  }
3288
3312
 
3289
3313
  // src/composites/inference-config-selector.tsx
3290
- var import_jsx_runtime46 = require("react/jsx-runtime");
3314
+ var import_jsx_runtime47 = require("react/jsx-runtime");
3291
3315
  var SELECT_CLASS = "w-full px-3 py-2 text-sm rounded-md border border-border bg-surface text-foreground focus:outline-none focus:ring-2 focus:ring-primary/50";
3292
3316
  function InferenceConfigSelector({
3293
3317
  runtime,
@@ -3307,16 +3331,16 @@ function InferenceConfigSelector({
3307
3331
  showAgent = false
3308
3332
  }) {
3309
3333
  const containerClass = layout === "grid" ? "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4" : layout === "horizontal" ? "flex flex-wrap items-end gap-4" : "space-y-3";
3310
- return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: `${containerClass} ${className ?? ""}`, children: [
3311
- showAgent && agents.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("label", { className: "space-y-1", children: [
3312
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "text-xs font-medium text-foreground-subtle", children: "Agent" }),
3313
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
3334
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: `${containerClass} ${className ?? ""}`, children: [
3335
+ showAgent && agents.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("label", { className: "space-y-1", children: [
3336
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "text-xs font-medium text-foreground-subtle", children: "Agent" }),
3337
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
3314
3338
  "select",
3315
3339
  {
3316
3340
  value: agentId,
3317
3341
  onChange: (e) => onAgentChange?.(e.target.value),
3318
3342
  className: SELECT_CLASS,
3319
- children: agents.map((a) => /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("option", { value: a.id, children: [
3343
+ children: agents.map((a) => /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("option", { value: a.id, children: [
3320
3344
  a.name,
3321
3345
  " (",
3322
3346
  a.status,
@@ -3325,45 +3349,45 @@ function InferenceConfigSelector({
3325
3349
  }
3326
3350
  )
3327
3351
  ] }),
3328
- /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("label", { className: "space-y-1", children: [
3329
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "text-xs font-medium text-foreground-subtle", children: "Runtime" }),
3330
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
3352
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("label", { className: "space-y-1", children: [
3353
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "text-xs font-medium text-foreground-subtle", children: "Runtime" }),
3354
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
3331
3355
  "select",
3332
3356
  {
3333
3357
  value: runtime,
3334
3358
  onChange: (e) => onRuntimeChange(e.target.value),
3335
3359
  className: SELECT_CLASS,
3336
- children: runtimes.map((r) => /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("option", { value: r.value, disabled: !r.available, children: [
3360
+ children: runtimes.map((r) => /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("option", { value: r.value, disabled: !r.available, children: [
3337
3361
  r.label,
3338
3362
  !r.available ? " (unavailable)" : ""
3339
3363
  ] }, r.value))
3340
3364
  }
3341
3365
  )
3342
3366
  ] }),
3343
- /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("label", { className: "space-y-1", children: [
3344
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "text-xs font-medium text-foreground-subtle", children: "Backend" }),
3345
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
3367
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("label", { className: "space-y-1", children: [
3368
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "text-xs font-medium text-foreground-subtle", children: "Backend" }),
3369
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
3346
3370
  "select",
3347
3371
  {
3348
3372
  value: backend,
3349
3373
  onChange: (e) => onBackendChange(e.target.value),
3350
3374
  className: SELECT_CLASS,
3351
- children: backends.map((b) => /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("option", { value: b.id, disabled: !b.available, children: [
3375
+ children: backends.map((b) => /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("option", { value: b.id, disabled: !b.available, children: [
3352
3376
  b.label,
3353
3377
  !b.available ? " (unavailable)" : ""
3354
3378
  ] }, b.id))
3355
3379
  }
3356
3380
  )
3357
3381
  ] }),
3358
- /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("label", { className: "space-y-1", children: [
3359
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "text-xs font-medium text-foreground-subtle", children: "Model" }),
3360
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
3382
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("label", { className: "space-y-1", children: [
3383
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "text-xs font-medium text-foreground-subtle", children: "Model" }),
3384
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
3361
3385
  "select",
3362
3386
  {
3363
3387
  value: modelId,
3364
3388
  onChange: (e) => onModelChange(e.target.value),
3365
3389
  className: SELECT_CLASS,
3366
- children: models.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("option", { value: "", children: "No compatible models" }) : models.map((m) => /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("option", { value: m.id, children: [
3390
+ children: models.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("option", { value: "", children: "No compatible models" }) : models.map((m) => /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("option", { value: m.id, children: [
3367
3391
  m.name,
3368
3392
  m.downloaded ? " \u2713" : ""
3369
3393
  ] }, m.id))
@@ -3384,9 +3408,9 @@ var import_superjson = __toESM(require("superjson"), 1);
3384
3408
 
3385
3409
  // src/composites/login-form.tsx
3386
3410
  var import_react26 = require("react");
3387
- var import_jsx_runtime47 = require("react/jsx-runtime");
3411
+ var import_jsx_runtime48 = require("react/jsx-runtime");
3388
3412
  function EyeIcon({ className }) {
3389
- return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
3413
+ return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(
3390
3414
  "svg",
3391
3415
  {
3392
3416
  xmlns: "http://www.w3.org/2000/svg",
@@ -3398,14 +3422,14 @@ function EyeIcon({ className }) {
3398
3422
  strokeLinejoin: "round",
3399
3423
  className,
3400
3424
  children: [
3401
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("path", { d: "M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0" }),
3402
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("circle", { cx: "12", cy: "12", r: "3" })
3425
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("path", { d: "M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0" }),
3426
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("circle", { cx: "12", cy: "12", r: "3" })
3403
3427
  ]
3404
3428
  }
3405
3429
  );
3406
3430
  }
3407
3431
  function EyeOffIcon({ className }) {
3408
- return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
3432
+ return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(
3409
3433
  "svg",
3410
3434
  {
3411
3435
  xmlns: "http://www.w3.org/2000/svg",
@@ -3417,16 +3441,16 @@ function EyeOffIcon({ className }) {
3417
3441
  strokeLinejoin: "round",
3418
3442
  className,
3419
3443
  children: [
3420
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("path", { d: "M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49" }),
3421
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("path", { d: "M14.084 14.158a3 3 0 0 1-4.242-4.242" }),
3422
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("path", { d: "M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143" }),
3423
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("path", { d: "m2 2 20 20" })
3444
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("path", { d: "M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49" }),
3445
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("path", { d: "M14.084 14.158a3 3 0 0 1-4.242-4.242" }),
3446
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("path", { d: "M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143" }),
3447
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("path", { d: "m2 2 20 20" })
3424
3448
  ]
3425
3449
  }
3426
3450
  );
3427
3451
  }
3428
3452
  function SpinnerIcon({ className }) {
3429
- return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
3453
+ return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
3430
3454
  "svg",
3431
3455
  {
3432
3456
  xmlns: "http://www.w3.org/2000/svg",
@@ -3437,7 +3461,7 @@ function SpinnerIcon({ className }) {
3437
3461
  strokeLinecap: "round",
3438
3462
  strokeLinejoin: "round",
3439
3463
  className,
3440
- children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" })
3464
+ children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" })
3441
3465
  }
3442
3466
  );
3443
3467
  }
@@ -3468,26 +3492,26 @@ function LoginForm({
3468
3492
  setSubmitting(false);
3469
3493
  }
3470
3494
  };
3471
- return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
3495
+ return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
3472
3496
  "div",
3473
3497
  {
3474
3498
  className: cn(
3475
3499
  "flex min-h-screen items-center justify-center bg-background p-4",
3476
3500
  className
3477
3501
  ),
3478
- children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "w-full max-w-sm", children: [
3479
- logoSrc && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "flex justify-center mb-8", children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("img", { src: logoSrc, alt: "Logo", className: "h-12" }) }),
3480
- serverUrl && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("p", { className: "mb-4 text-center text-xs text-foreground-subtle truncate", children: serverUrl }),
3481
- /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
3502
+ children: /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "w-full max-w-sm", children: [
3503
+ logoSrc && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "flex justify-center mb-8", children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("img", { src: logoSrc, alt: "Logo", className: "h-12" }) }),
3504
+ serverUrl && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("p", { className: "mb-4 text-center text-xs text-foreground-subtle truncate", children: serverUrl }),
3505
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(
3482
3506
  "form",
3483
3507
  {
3484
3508
  onSubmit: handleSubmit,
3485
3509
  className: "space-y-4 rounded-xl border border-border bg-surface p-6 shadow-xl shadow-black/10",
3486
3510
  children: [
3487
- error && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "rounded-md bg-danger/10 border border-danger/20 px-3 py-2 text-xs text-danger", children: error }),
3488
- /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "space-y-1.5", children: [
3489
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("label", { className: "text-xs font-medium text-foreground-subtle", children: "Username" }),
3490
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
3511
+ error && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "rounded-md bg-danger/10 border border-danger/20 px-3 py-2 text-xs text-danger", children: error }),
3512
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "space-y-1.5", children: [
3513
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("label", { className: "text-xs font-medium text-foreground-subtle", children: "Username" }),
3514
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
3491
3515
  "input",
3492
3516
  {
3493
3517
  type: "text",
@@ -3499,10 +3523,10 @@ function LoginForm({
3499
3523
  }
3500
3524
  )
3501
3525
  ] }),
3502
- /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "space-y-1.5", children: [
3503
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("label", { className: "text-xs font-medium text-foreground-subtle", children: "Password" }),
3504
- /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "relative", children: [
3505
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
3526
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "space-y-1.5", children: [
3527
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("label", { className: "text-xs font-medium text-foreground-subtle", children: "Password" }),
3528
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "relative", children: [
3529
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
3506
3530
  "input",
3507
3531
  {
3508
3532
  type: showPassword ? "text" : "password",
@@ -3513,26 +3537,26 @@ function LoginForm({
3513
3537
  className: "w-full rounded-lg border border-border bg-background px-3 py-2.5 pr-10 text-sm text-foreground placeholder:text-foreground-subtle focus:outline-none focus:ring-2 focus:ring-primary/50 focus:border-primary"
3514
3538
  }
3515
3539
  ),
3516
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
3540
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
3517
3541
  "button",
3518
3542
  {
3519
3543
  type: "button",
3520
3544
  onClick: () => setShowPassword((prev) => !prev),
3521
3545
  className: "absolute right-2.5 top-1/2 -translate-y-1/2 text-foreground-subtle hover:text-foreground",
3522
3546
  tabIndex: -1,
3523
- children: showPassword ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(EyeOffIcon, { className: "h-4 w-4" }) : /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(EyeIcon, { className: "h-4 w-4" })
3547
+ children: showPassword ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(EyeOffIcon, { className: "h-4 w-4" }) : /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(EyeIcon, { className: "h-4 w-4" })
3524
3548
  }
3525
3549
  )
3526
3550
  ] })
3527
3551
  ] }),
3528
- /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
3552
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(
3529
3553
  "button",
3530
3554
  {
3531
3555
  type: "submit",
3532
3556
  disabled: submitting,
3533
3557
  className: "w-full rounded-lg bg-primary px-4 py-2.5 text-sm font-semibold text-primary-foreground hover:bg-primary/90 disabled:opacity-50 disabled:cursor-not-allowed transition-colors flex items-center justify-center gap-2",
3534
3558
  children: [
3535
- submitting && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(SpinnerIcon, { className: "h-4 w-4 animate-spin" }),
3559
+ submitting && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(SpinnerIcon, { className: "h-4 w-4 animate-spin" }),
3536
3560
  submitting ? "Logging in..." : "Log in"
3537
3561
  ]
3538
3562
  }
@@ -3546,7 +3570,7 @@ function LoginForm({
3546
3570
  }
3547
3571
 
3548
3572
  // src/composites/dev-shell.tsx
3549
- var import_jsx_runtime48 = require("react/jsx-runtime");
3573
+ var import_jsx_runtime49 = require("react/jsx-runtime");
3550
3574
  var STORAGE_KEY = "camstack_dev_token";
3551
3575
  var DevShellContext = (0, import_react27.createContext)(null);
3552
3576
  function useDevShell() {
@@ -3561,7 +3585,7 @@ function getStoredToken() {
3561
3585
  return localStorage.getItem(STORAGE_KEY);
3562
3586
  }
3563
3587
  function SunIcon({ className }) {
3564
- return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(
3588
+ return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
3565
3589
  "svg",
3566
3590
  {
3567
3591
  xmlns: "http://www.w3.org/2000/svg",
@@ -3573,21 +3597,21 @@ function SunIcon({ className }) {
3573
3597
  strokeLinejoin: "round",
3574
3598
  className,
3575
3599
  children: [
3576
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("circle", { cx: "12", cy: "12", r: "4" }),
3577
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("path", { d: "M12 2v2" }),
3578
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("path", { d: "M12 20v2" }),
3579
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("path", { d: "m4.93 4.93 1.41 1.41" }),
3580
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("path", { d: "m17.66 17.66 1.41 1.41" }),
3581
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("path", { d: "M2 12h2" }),
3582
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("path", { d: "M20 12h2" }),
3583
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("path", { d: "m6.34 17.66-1.41 1.41" }),
3584
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("path", { d: "m19.07 4.93-1.41 1.41" })
3600
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("circle", { cx: "12", cy: "12", r: "4" }),
3601
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("path", { d: "M12 2v2" }),
3602
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("path", { d: "M12 20v2" }),
3603
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("path", { d: "m4.93 4.93 1.41 1.41" }),
3604
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("path", { d: "m17.66 17.66 1.41 1.41" }),
3605
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("path", { d: "M2 12h2" }),
3606
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("path", { d: "M20 12h2" }),
3607
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("path", { d: "m6.34 17.66-1.41 1.41" }),
3608
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("path", { d: "m19.07 4.93-1.41 1.41" })
3585
3609
  ]
3586
3610
  }
3587
3611
  );
3588
3612
  }
3589
3613
  function MoonIcon({ className }) {
3590
- return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
3614
+ return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
3591
3615
  "svg",
3592
3616
  {
3593
3617
  xmlns: "http://www.w3.org/2000/svg",
@@ -3598,7 +3622,7 @@ function MoonIcon({ className }) {
3598
3622
  strokeLinecap: "round",
3599
3623
  strokeLinejoin: "round",
3600
3624
  className,
3601
- children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("path", { d: "M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z" })
3625
+ children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("path", { d: "M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z" })
3602
3626
  }
3603
3627
  );
3604
3628
  }
@@ -3637,15 +3661,15 @@ function DevShellInner({
3637
3661
  () => ({ trpc, token, logout: onLogout }),
3638
3662
  [trpc, token, onLogout]
3639
3663
  );
3640
- return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(DevShellContext.Provider, { value: contextValue, children: /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "min-h-screen bg-background text-foreground", children: [
3641
- /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "flex items-center justify-between border-b border-border bg-surface px-4 py-2", children: [
3642
- /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "flex items-center gap-2", children: [
3643
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "rounded bg-warning/20 px-2 py-0.5 text-xs font-bold text-warning", children: "DEV MODE" }),
3644
- title && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "text-sm font-medium text-foreground", children: title }),
3645
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "text-xs text-foreground-subtle", children: serverUrl })
3664
+ return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(DevShellContext.Provider, { value: contextValue, children: /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "min-h-screen bg-background text-foreground", children: [
3665
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "flex items-center justify-between border-b border-border bg-surface px-4 py-2", children: [
3666
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "flex items-center gap-2", children: [
3667
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "rounded bg-warning/20 px-2 py-0.5 text-xs font-bold text-warning", children: "DEV MODE" }),
3668
+ title && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "text-sm font-medium text-foreground", children: title }),
3669
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "text-xs text-foreground-subtle", children: serverUrl })
3646
3670
  ] }),
3647
- /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "flex items-center gap-2", children: [
3648
- /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(
3671
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "flex items-center gap-2", children: [
3672
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
3649
3673
  "button",
3650
3674
  {
3651
3675
  type: "button",
@@ -3653,12 +3677,12 @@ function DevShellInner({
3653
3677
  className: "flex items-center gap-1.5 rounded-md px-2 py-1 text-xs font-medium text-foreground-subtle hover:text-foreground hover:bg-surface-hover transition-colors",
3654
3678
  title: `Theme: ${theme.mode}`,
3655
3679
  children: [
3656
- theme.resolvedMode === "dark" ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(SunIcon, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(MoonIcon, { className: "h-3.5 w-3.5" }),
3680
+ theme.resolvedMode === "dark" ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(SunIcon, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(MoonIcon, { className: "h-3.5 w-3.5" }),
3657
3681
  theme.mode === "dark" ? "Dark" : theme.mode === "light" ? "Light" : "System"
3658
3682
  ]
3659
3683
  }
3660
3684
  ),
3661
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
3685
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
3662
3686
  "button",
3663
3687
  {
3664
3688
  type: "button",
@@ -3669,7 +3693,7 @@ function DevShellInner({
3669
3693
  )
3670
3694
  ] })
3671
3695
  ] }),
3672
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "p-4", children: children({ trpc, theme }) })
3696
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "p-4", children: children({ trpc, theme }) })
3673
3697
  ] }) });
3674
3698
  }
3675
3699
  function DevShell({
@@ -3700,9 +3724,9 @@ function DevShell({
3700
3724
  setToken(null);
3701
3725
  }, []);
3702
3726
  if (!token) {
3703
- return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ThemeProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(LoginForm, { onLogin: handleLogin, serverUrl }) });
3727
+ return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(ThemeProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(LoginForm, { onLogin: handleLogin, serverUrl }) });
3704
3728
  }
3705
- return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ThemeProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
3729
+ return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(ThemeProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
3706
3730
  DevShellInner,
3707
3731
  {
3708
3732
  serverUrl,
@@ -3790,6 +3814,7 @@ function mountAddonPage(PageComponent, options = {}) {
3790
3814
  ProviderBadge,
3791
3815
  ScrollArea,
3792
3816
  Select,
3817
+ SemanticBadge,
3793
3818
  Separator,
3794
3819
  Sidebar,
3795
3820
  SidebarItem,
@@ -3806,6 +3831,7 @@ function mountAddonPage(PageComponent, options = {}) {
3806
3831
  Tooltip,
3807
3832
  TooltipContent,
3808
3833
  TooltipTrigger,
3834
+ VersionBadge,
3809
3835
  cn,
3810
3836
  createTheme,
3811
3837
  darkColors,