@flytedan/flytebot-design-system 0.51.3 → 0.51.4

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.js CHANGED
@@ -1123,7 +1123,60 @@ function LoadingRegion({
1123
1123
  }
1124
1124
 
1125
1125
  // src/components/loading/JobTray.tsx
1126
+ import * as React10 from "react";
1127
+
1128
+ // src/kits/cornerStack.tsx
1126
1129
  import * as React9 from "react";
1130
+ import { createPortal as createPortal4 } from "react-dom";
1131
+ var SLOTS = ["jobs", "toasts"];
1132
+ var references = /* @__PURE__ */ new Map();
1133
+ var host = null;
1134
+ var slotElements = /* @__PURE__ */ new Map();
1135
+ function createHost() {
1136
+ const stack = document.createElement("div");
1137
+ stack.className = "fd-corner-stack";
1138
+ stack.style.zIndex = String(OVERLAY_CEILING);
1139
+ for (const slot of SLOTS) {
1140
+ const element = document.createElement("div");
1141
+ element.className = "fd-corner-stack-slot";
1142
+ element.dataset.cornerStackSlot = slot;
1143
+ stack.appendChild(element);
1144
+ slotElements.set(slot, element);
1145
+ }
1146
+ document.body.appendChild(stack);
1147
+ return stack;
1148
+ }
1149
+ function acquire(slot) {
1150
+ host ??= createHost();
1151
+ references.set(slot, (references.get(slot) ?? 0) + 1);
1152
+ return slotElements.get(slot);
1153
+ }
1154
+ function release(slot) {
1155
+ const remaining = (references.get(slot) ?? 1) - 1;
1156
+ if (remaining > 0) references.set(slot, remaining);
1157
+ else references.delete(slot);
1158
+ if (references.size === 0 && host) {
1159
+ host.remove();
1160
+ host = null;
1161
+ slotElements.clear();
1162
+ }
1163
+ }
1164
+ var useSlotEffect = typeof document === "undefined" ? React9.useEffect : React9.useLayoutEffect;
1165
+ function useCornerStackSlot(slot) {
1166
+ const [element, setElement] = React9.useState(null);
1167
+ useSlotEffect(() => {
1168
+ setElement(acquire(slot));
1169
+ return () => {
1170
+ release(slot);
1171
+ setElement(null);
1172
+ };
1173
+ }, [slot]);
1174
+ return element;
1175
+ }
1176
+ function CornerStackPortal({ slot, children }) {
1177
+ const element = useCornerStackSlot(slot);
1178
+ return element ? createPortal4(children, element) : null;
1179
+ }
1127
1180
 
1128
1181
  // src/components/loading/ProgressBar.tsx
1129
1182
  import { jsx as jsx14, jsxs as jsxs10 } from "react/jsx-runtime";
@@ -1167,9 +1220,9 @@ function announcementFor(job) {
1167
1220
  return title + ": in progress";
1168
1221
  }
1169
1222
  function JobTray({ jobs: jobs2, onDismiss, className = "" }) {
1170
- const [announcement, setAnnouncement] = React9.useState("");
1171
- const prevStatuses = React9.useRef({});
1172
- React9.useEffect(() => {
1223
+ const [announcement, setAnnouncement] = React10.useState("");
1224
+ const prevStatuses = React10.useRef({});
1225
+ React10.useEffect(() => {
1173
1226
  let next = "";
1174
1227
  for (const job of jobs2) {
1175
1228
  if (prevStatuses.current[job.id] !== job.status) {
@@ -1182,10 +1235,10 @@ function JobTray({ jobs: jobs2, onDismiss, className = "" }) {
1182
1235
  if (next) setAnnouncement(next);
1183
1236
  }, [jobs2]);
1184
1237
  if (jobs2.length === 0) return null;
1185
- return /* @__PURE__ */ jsxs11("div", { className: ["fd-job-tray", className].filter(Boolean).join(" "), children: [
1238
+ return /* @__PURE__ */ jsx15(CornerStackPortal, { slot: "jobs", children: /* @__PURE__ */ jsxs11("div", { className: ["fd-job-tray", className].filter(Boolean).join(" "), children: [
1186
1239
  /* @__PURE__ */ jsx15("span", { className: "fd-sr", role: "status", "aria-live": "polite", children: announcement }),
1187
1240
  jobs2.map((job) => /* @__PURE__ */ jsx15(JobCard, { job, onDismiss }, job.id))
1188
- ] });
1241
+ ] }) });
1189
1242
  }
1190
1243
  function JobCard({ job, onDismiss }) {
1191
1244
  const title = textOf(job.title) || "Job";
@@ -1220,7 +1273,7 @@ function JobCard({ job, onDismiss }) {
1220
1273
  }
1221
1274
 
1222
1275
  // src/components/loading/PhasedProgress.tsx
1223
- import * as React10 from "react";
1276
+ import * as React11 from "react";
1224
1277
  import { jsx as jsx16, jsxs as jsxs12 } from "react/jsx-runtime";
1225
1278
  var ICON = {
1226
1279
  pending: "ph-circle",
@@ -1233,9 +1286,9 @@ function textOf2(node) {
1233
1286
  return "";
1234
1287
  }
1235
1288
  function PhasedProgress({ phases, summary, className = "" }) {
1236
- const [announcement, setAnnouncement] = React10.useState("");
1237
- const prevStatuses = React10.useRef({});
1238
- React10.useEffect(() => {
1289
+ const [announcement, setAnnouncement] = React11.useState("");
1290
+ const prevStatuses = React11.useRef({});
1291
+ React11.useEffect(() => {
1239
1292
  let next = "";
1240
1293
  for (const phase of phases) {
1241
1294
  if (prevStatuses.current[phase.id] !== phase.status) {
@@ -1305,12 +1358,12 @@ function Spinner({ size = "md", label = "Loading", className = "", style, ...res
1305
1358
  }
1306
1359
 
1307
1360
  // src/components/navigation/SidebarNav.tsx
1308
- import * as React11 from "react";
1361
+ import * as React12 from "react";
1309
1362
  import { jsx as jsx19, jsxs as jsxs13 } from "react/jsx-runtime";
1310
1363
  function Tip({ label, children }) {
1311
1364
  return /* @__PURE__ */ jsx19("span", { title: label, style: { display: "inline-flex", flex: "none" }, children });
1312
1365
  }
1313
- var SidebarNav = React11.forwardRef(function SidebarNav2({ brand, groups = [], current: current2, onNavigate, footer, open: open2 = false, className = "", ...rest }, ref) {
1366
+ var SidebarNav = React12.forwardRef(function SidebarNav2({ brand, groups = [], current: current2, onNavigate, footer, open: open2 = false, className = "", ...rest }, ref) {
1314
1367
  return /* @__PURE__ */ jsxs13(
1315
1368
  "nav",
1316
1369
  {
@@ -1349,13 +1402,13 @@ var SidebarNav = React11.forwardRef(function SidebarNav2({ brand, groups = [], c
1349
1402
  });
1350
1403
 
1351
1404
  // src/components/navigation/Topbar.tsx
1352
- import * as React12 from "react";
1405
+ import * as React13 from "react";
1353
1406
  import { Fragment as Fragment4, jsx as jsx20, jsxs as jsxs14 } from "react/jsx-runtime";
1354
1407
  function useIsNarrow(breakpoint) {
1355
- const [narrow, setNarrow] = React12.useState(
1408
+ const [narrow, setNarrow] = React13.useState(
1356
1409
  () => typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia(`(max-width: ${breakpoint}px)`).matches
1357
1410
  );
1358
- React12.useEffect(() => {
1411
+ React13.useEffect(() => {
1359
1412
  if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
1360
1413
  const mq = window.matchMedia(`(max-width: ${breakpoint}px)`);
1361
1414
  const apply = () => setNarrow(mq.matches);
@@ -1376,11 +1429,11 @@ function Topbar({
1376
1429
  ...rest
1377
1430
  }) {
1378
1431
  const narrow = useIsNarrow(overflowBreakpoint);
1379
- const [moreOpen, setMoreOpen] = React12.useState(false);
1380
- const moreRef = React12.useRef(null);
1432
+ const [moreOpen, setMoreOpen] = React13.useState(false);
1433
+ const moreRef = React13.useRef(null);
1381
1434
  return /* @__PURE__ */ jsxs14("header", { className: ["fd-topbar", narrow ? "is-narrow" : "", className].filter(Boolean).join(" "), ...rest, children: [
1382
1435
  onMenu ? /* @__PURE__ */ jsx20("button", { type: "button", className: "fd-btn-icon", "aria-label": "Menu", onClick: onMenu, children: /* @__PURE__ */ jsx20("i", { className: "ph ph-list" }) }) : null,
1383
- /* @__PURE__ */ jsx20("nav", { className: "fd-crumb", "aria-label": "Breadcrumb", children: crumbs.map((c, i) => /* @__PURE__ */ jsxs14(React12.Fragment, { children: [
1436
+ /* @__PURE__ */ jsx20("nav", { className: "fd-crumb", "aria-label": "Breadcrumb", children: crumbs.map((c, i) => /* @__PURE__ */ jsxs14(React13.Fragment, { children: [
1384
1437
  i > 0 ? /* @__PURE__ */ jsx20("i", { className: "ph ph-caret-right", style: { fontSize: 11, opacity: 0.6 }, "aria-hidden": "true" }) : null,
1385
1438
  i === crumbs.length - 1 ? (
1386
1439
  // MP-141: the current crumb mixes a static route label with (usually) a
@@ -1433,25 +1486,25 @@ function Topbar({
1433
1486
  }
1434
1487
 
1435
1488
  // src/kits/useResponsiveRail.ts
1436
- import * as React13 from "react";
1489
+ import * as React14 from "react";
1437
1490
  function matchesBreakpoint(breakpoint) {
1438
1491
  return typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia(`(max-width: ${breakpoint}px)`).matches;
1439
1492
  }
1440
1493
  function useResponsiveRail(options = {}) {
1441
1494
  const { breakpoint = 1024, initialOpen = true, onPersist } = options;
1442
- const navRef = React13.useRef(null);
1443
- const [overlay, setOverlay] = React13.useState(() => matchesBreakpoint(breakpoint));
1444
- const [open2, setOpenRaw] = React13.useState(() => matchesBreakpoint(breakpoint) ? false : initialOpen);
1445
- const setOpen = React13.useCallback(
1495
+ const navRef = React14.useRef(null);
1496
+ const [overlay, setOverlay] = React14.useState(() => matchesBreakpoint(breakpoint));
1497
+ const [open2, setOpenRaw] = React14.useState(() => matchesBreakpoint(breakpoint) ? false : initialOpen);
1498
+ const setOpen = React14.useCallback(
1446
1499
  (value) => {
1447
1500
  setOpenRaw(value);
1448
1501
  if (!matchesBreakpoint(breakpoint)) onPersist?.(value);
1449
1502
  },
1450
1503
  [breakpoint, onPersist]
1451
1504
  );
1452
- const toggle = React13.useCallback(() => setOpen(!open2), [open2, setOpen]);
1453
- const close2 = React13.useCallback(() => setOpenRaw(false), []);
1454
- React13.useEffect(() => {
1505
+ const toggle = React14.useCallback(() => setOpen(!open2), [open2, setOpen]);
1506
+ const close2 = React14.useCallback(() => setOpenRaw(false), []);
1507
+ React14.useEffect(() => {
1455
1508
  if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
1456
1509
  const mq = window.matchMedia(`(max-width: ${breakpoint}px)`);
1457
1510
  const handler = (e) => {
@@ -1462,7 +1515,7 @@ function useResponsiveRail(options = {}) {
1462
1515
  return () => mq.removeEventListener("change", handler);
1463
1516
  }, [breakpoint]);
1464
1517
  const layer = useStackedLayer({ active: overlay && open2, containerRef: navRef, trap: true, onEscape: close2 });
1465
- React13.useEffect(() => {
1518
+ React14.useEffect(() => {
1466
1519
  if (!overlay || !open2) return;
1467
1520
  const previousOverflow = document.body.style.overflow;
1468
1521
  document.body.style.overflow = "hidden";
@@ -1820,15 +1873,15 @@ function Toast({ title, children, tone = "success", onUndo, onDismiss, className
1820
1873
  }
1821
1874
 
1822
1875
  // src/components/feedback/ToastProvider.tsx
1823
- import * as React14 from "react";
1876
+ import * as React15 from "react";
1824
1877
  import { jsx as jsx32, jsxs as jsxs25 } from "react/jsx-runtime";
1825
1878
  var DEFAULT_TOAST_DURATION_MS = 5e3;
1826
- var ToastContext = React14.createContext(null);
1879
+ var ToastContext = React15.createContext(null);
1827
1880
  function ToastProvider({ children }) {
1828
- const [items, setItems] = React14.useState([]);
1829
- const timers = React14.useRef(/* @__PURE__ */ new Map());
1830
- const nextId = React14.useRef(1);
1831
- const dismiss = React14.useCallback((id) => {
1881
+ const [items, setItems] = React15.useState([]);
1882
+ const timers = React15.useRef(/* @__PURE__ */ new Map());
1883
+ const nextId = React15.useRef(1);
1884
+ const dismiss = React15.useCallback((id) => {
1832
1885
  setItems((current2) => current2.filter((item) => item.id !== id));
1833
1886
  const timer = timers.current.get(id);
1834
1887
  if (timer !== void 0) {
@@ -1836,7 +1889,7 @@ function ToastProvider({ children }) {
1836
1889
  timers.current.delete(id);
1837
1890
  }
1838
1891
  }, []);
1839
- const show = React14.useCallback(
1892
+ const show = React15.useCallback(
1840
1893
  (title, options = {}) => {
1841
1894
  const { tone = "success", duration = DEFAULT_TOAST_DURATION_MS } = options;
1842
1895
  const id = nextId.current++;
@@ -1845,38 +1898,38 @@ function ToastProvider({ children }) {
1845
1898
  },
1846
1899
  [dismiss]
1847
1900
  );
1848
- React14.useEffect(() => {
1901
+ React15.useEffect(() => {
1849
1902
  const pending = timers.current;
1850
1903
  return () => {
1851
1904
  pending.forEach(clearTimeout);
1852
1905
  pending.clear();
1853
1906
  };
1854
1907
  }, []);
1855
- const api = React14.useMemo(() => ({ show }), [show]);
1908
+ const api = React15.useMemo(() => ({ show }), [show]);
1856
1909
  return /* @__PURE__ */ jsxs25(ToastContext.Provider, { value: api, children: [
1857
1910
  children,
1858
- /* @__PURE__ */ jsx32("div", { className: "fd-toast-region", "aria-live": "polite", style: { zIndex: OVERLAY_CEILING }, children: items.map((item) => /* @__PURE__ */ jsx32(Toast, { title: item.title, tone: item.tone, onDismiss: () => dismiss(item.id) }, item.id)) })
1911
+ /* @__PURE__ */ jsx32(CornerStackPortal, { slot: "toasts", children: /* @__PURE__ */ jsx32("div", { className: "fd-toast-region", "aria-live": "polite", children: items.map((item) => /* @__PURE__ */ jsx32(Toast, { title: item.title, tone: item.tone, onDismiss: () => dismiss(item.id) }, item.id)) }) })
1859
1912
  ] });
1860
1913
  }
1861
1914
  function useToast() {
1862
- const api = React14.useContext(ToastContext);
1915
+ const api = React15.useContext(ToastContext);
1863
1916
  if (!api) throw new Error("useToast must be used inside a <ToastProvider>");
1864
1917
  return api;
1865
1918
  }
1866
1919
 
1867
1920
  // src/components/feedback/Tooltip.tsx
1868
- import * as React15 from "react";
1921
+ import * as React16 from "react";
1869
1922
  import { jsx as jsx33, jsxs as jsxs26 } from "react/jsx-runtime";
1870
1923
  var CLOSE_DELAY_MS = 120;
1871
1924
  function Tooltip({ label, placement = "top", children, className = "" }) {
1872
- const anchorRef = React15.useRef(null);
1873
- const bubbleRef = React15.useRef(null);
1874
- const [reason, setReason] = React15.useState(null);
1875
- const closeTimer = React15.useRef(null);
1876
- const id = React15.useId();
1925
+ const anchorRef = React16.useRef(null);
1926
+ const bubbleRef = React16.useRef(null);
1927
+ const [reason, setReason] = React16.useState(null);
1928
+ const closeTimer = React16.useRef(null);
1929
+ const id = React16.useId();
1877
1930
  const descId = id + "-desc";
1878
1931
  const open2 = reason != null;
1879
- const cancelClose = React15.useCallback(() => {
1932
+ const cancelClose = React16.useCallback(() => {
1880
1933
  if (closeTimer.current) {
1881
1934
  clearTimeout(closeTimer.current);
1882
1935
  closeTimer.current = null;
@@ -1886,7 +1939,7 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
1886
1939
  cancelClose();
1887
1940
  setReason(why);
1888
1941
  };
1889
- const hide = React15.useCallback(() => {
1942
+ const hide = React16.useCallback(() => {
1890
1943
  cancelClose();
1891
1944
  setReason(null);
1892
1945
  }, [cancelClose]);
@@ -1901,7 +1954,7 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
1901
1954
  setReason((r) => r === "hover" ? null : r);
1902
1955
  }, CLOSE_DELAY_MS);
1903
1956
  };
1904
- React15.useEffect(() => cancelClose, [cancelClose]);
1957
+ React16.useEffect(() => cancelClose, [cancelClose]);
1905
1958
  const pos = usePopoverPosition(open2, anchorRef, {
1906
1959
  placement: placement === "bottom" ? "bottom-center" : "top-center",
1907
1960
  offset: 8,
@@ -1912,7 +1965,7 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
1912
1965
  });
1913
1966
  const layer = useStackedLayer({ active: open2, containerRef: bubbleRef, onEscape: hide, returnFocus: false });
1914
1967
  const zIndex = useLayerZIndex(layer);
1915
- React15.useEffect(() => {
1968
+ React16.useEffect(() => {
1916
1969
  if (!open2) return;
1917
1970
  const away = (e) => {
1918
1971
  const t = e.target;
@@ -1933,7 +1986,7 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
1933
1986
  }
1934
1987
  if (keyboard) show("focus");
1935
1988
  };
1936
- const described = React15.isValidElement(children) ? React15.cloneElement(children, {
1989
+ const described = React16.isValidElement(children) ? React16.cloneElement(children, {
1937
1990
  "aria-describedby": [children.props["aria-describedby"], descId].filter(Boolean).join(" ")
1938
1991
  }) : children;
1939
1992
  return /* @__PURE__ */ jsxs26(
@@ -1941,7 +1994,7 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
1941
1994
  {
1942
1995
  ref: anchorRef,
1943
1996
  className: "fd-tooltip-anchor",
1944
- "aria-describedby": React15.isValidElement(children) ? void 0 : descId,
1997
+ "aria-describedby": React16.isValidElement(children) ? void 0 : descId,
1945
1998
  onPointerEnter: (e) => {
1946
1999
  if (isMouse(e)) hover();
1947
2000
  },
@@ -1985,16 +2038,16 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
1985
2038
  }
1986
2039
 
1987
2040
  // src/components/data/AnimNum.tsx
1988
- import * as React16 from "react";
2041
+ import * as React17 from "react";
1989
2042
  import { Fragment as Fragment6, jsx as jsx34 } from "react/jsx-runtime";
1990
2043
  function shouldSkipEasing() {
1991
2044
  if (typeof document !== "undefined" && document.hidden) return true;
1992
2045
  return window.matchMedia?.("(prefers-reduced-motion: reduce)").matches ?? false;
1993
2046
  }
1994
2047
  function AnimNum({ value, format, duration = 550 }) {
1995
- const [display, setDisplay] = React16.useState(value);
1996
- const prev = React16.useRef(value);
1997
- React16.useEffect(() => {
2048
+ const [display, setDisplay] = React17.useState(value);
2049
+ const prev = React17.useRef(value);
2050
+ React17.useEffect(() => {
1998
2051
  const from = prev.current;
1999
2052
  const to = value;
2000
2053
  prev.current = to;
@@ -2022,14 +2075,14 @@ function AnimNum({ value, format, duration = 550 }) {
2022
2075
  }
2023
2076
 
2024
2077
  // src/components/data/TrendChart.tsx
2025
- import * as React19 from "react";
2078
+ import * as React20 from "react";
2026
2079
 
2027
2080
  // src/components/useMeasuredWidth.ts
2028
- import * as React17 from "react";
2081
+ import * as React18 from "react";
2029
2082
  function useMeasuredWidth(fallback) {
2030
- const [element, setElement] = React17.useState(null);
2031
- const [width, setWidth] = React17.useState(fallback);
2032
- React17.useLayoutEffect(() => {
2083
+ const [element, setElement] = React18.useState(null);
2084
+ const [width, setWidth] = React18.useState(fallback);
2085
+ React18.useLayoutEffect(() => {
2033
2086
  if (!element || typeof ResizeObserver === "undefined") return;
2034
2087
  const measure = () => {
2035
2088
  const measured = Math.round(element.getBoundingClientRect().width);
@@ -2044,7 +2097,7 @@ function useMeasuredWidth(fallback) {
2044
2097
  }
2045
2098
 
2046
2099
  // src/components/data/SegmentedMeter.tsx
2047
- import * as React18 from "react";
2100
+ import * as React19 from "react";
2048
2101
 
2049
2102
  // src/kits/files.ts
2050
2103
  function formatBytes(n) {
@@ -2249,7 +2302,7 @@ function SegmentedMeter({
2249
2302
  const pct = safeTotal ? Math.min(100, Math.round(used / safeTotal * 100)) : 0;
2250
2303
  const w = (v) => safeTotal ? Math.max(0, Math.min(100, Number(v) / safeTotal * 100)) : 0;
2251
2304
  const fill = (s, i) => s.color || (s.variant ? VARIANT_FILL[s.variant] : void 0) || CHART[i % CHART.length];
2252
- const generatedId = React18.useId();
2305
+ const generatedId = React19.useId();
2253
2306
  const uid2 = id || generatedId;
2254
2307
  return /* @__PURE__ */ jsxs27("div", { className: ["fd-segmeter", className].filter(Boolean).join(" "), onClick, children: [
2255
2308
  label || showTotal ? /* @__PURE__ */ jsxs27("div", { className: "fd-segmeter-head", children: [
@@ -2400,8 +2453,8 @@ function TrendChart({
2400
2453
  onRetry,
2401
2454
  className = ""
2402
2455
  }) {
2403
- const [activeId, setActiveId] = React19.useState(null);
2404
- const [pointTip, setPointTip] = React19.useState(null);
2456
+ const [activeId, setActiveId] = React20.useState(null);
2457
+ const [pointTip, setPointTip] = React20.useState(null);
2405
2458
  const isEmpty = state === "ready" && (!categories.length || !series.length || series.every((s) => !s.values.length));
2406
2459
  const effectiveState = isEmpty ? "empty" : state;
2407
2460
  const [plotRef, VBW] = useMeasuredWidth(INITIAL_WIDTH);
@@ -2515,7 +2568,7 @@ function TrendChart({
2515
2568
  }
2516
2569
 
2517
2570
  // src/components/data/DonutChart.tsx
2518
- import * as React20 from "react";
2571
+ import * as React21 from "react";
2519
2572
  import { jsx as jsx38, jsxs as jsxs30 } from "react/jsx-runtime";
2520
2573
  function DonutChart({
2521
2574
  segments,
@@ -2530,7 +2583,7 @@ function DonutChart({
2530
2583
  onRetry,
2531
2584
  className = ""
2532
2585
  }) {
2533
- const [activeId, setActiveId] = React20.useState(null);
2586
+ const [activeId, setActiveId] = React21.useState(null);
2534
2587
  const items = segments.filter((s) => Number(s.value) > 0);
2535
2588
  const total = items.reduce((n, s) => n + Number(s.value), 0);
2536
2589
  const isEmpty = state === "ready" && (!items.length || total <= 0);
@@ -2622,7 +2675,7 @@ function DonutChart({
2622
2675
  }
2623
2676
 
2624
2677
  // src/components/data/BarList.tsx
2625
- import * as React21 from "react";
2678
+ import * as React22 from "react";
2626
2679
  import { jsx as jsx39, jsxs as jsxs31 } from "react/jsx-runtime";
2627
2680
  function BarList({
2628
2681
  rows,
@@ -2637,7 +2690,7 @@ function BarList({
2637
2690
  onRetry,
2638
2691
  className = ""
2639
2692
  }) {
2640
- const ordered = React21.useMemo(() => {
2693
+ const ordered = React22.useMemo(() => {
2641
2694
  const list = sort ? [...rows].sort((a, b) => Number(b.value) - Number(a.value)) : rows;
2642
2695
  return maxRows ? list.slice(0, maxRows) : list;
2643
2696
  }, [rows, sort, maxRows]);
@@ -2779,7 +2832,7 @@ function FunnelChart({
2779
2832
  }
2780
2833
 
2781
2834
  // src/components/data/Clamp.tsx
2782
- import * as React22 from "react";
2835
+ import * as React23 from "react";
2783
2836
  import { jsx as jsx41, jsxs as jsxs33 } from "react/jsx-runtime";
2784
2837
  function Clamp({
2785
2838
  children,
@@ -2791,16 +2844,16 @@ function Clamp({
2791
2844
  onToggle,
2792
2845
  className = ""
2793
2846
  }) {
2794
- const [open2, setOpen] = React22.useState(false);
2795
- const [overflows, setOverflows] = React22.useState(false);
2796
- const bodyRef = React22.useRef(null);
2797
- const charClamped = React22.useMemo(() => {
2847
+ const [open2, setOpen] = React23.useState(false);
2848
+ const [overflows, setOverflows] = React23.useState(false);
2849
+ const bodyRef = React23.useRef(null);
2850
+ const charClamped = React23.useMemo(() => {
2798
2851
  if (open2 || !maxChars || typeof text !== "string" || text.length <= maxChars) return null;
2799
2852
  const cut = text.slice(0, maxChars);
2800
2853
  const at = cut.lastIndexOf(" ");
2801
2854
  return (at > maxChars * 0.6 ? cut.slice(0, at) : cut).trimEnd() + "\u2026";
2802
2855
  }, [text, maxChars, open2]);
2803
- React22.useLayoutEffect(() => {
2856
+ React23.useLayoutEffect(() => {
2804
2857
  const node = bodyRef.current;
2805
2858
  if (maxChars || !node || !maxHeight) return;
2806
2859
  const measure = () => {
@@ -2939,16 +2992,16 @@ function DataTable({
2939
2992
  }
2940
2993
 
2941
2994
  // src/components/data/FilterBar.tsx
2942
- import * as React28 from "react";
2995
+ import * as React29 from "react";
2943
2996
 
2944
2997
  // src/components/forms/NumberInput.tsx
2945
- import * as React25 from "react";
2998
+ import * as React26 from "react";
2946
2999
 
2947
3000
  // src/components/forms/field.tsx
2948
- import * as React23 from "react";
3001
+ import * as React24 from "react";
2949
3002
  import { jsx as jsx44, jsxs as jsxs36 } from "react/jsx-runtime";
2950
3003
  function useFieldId(id) {
2951
- const generated = React23.useId();
3004
+ const generated = React24.useId();
2952
3005
  return id || generated;
2953
3006
  }
2954
3007
  function FieldLabel({ htmlFor, id, required = false, onClick, children }) {
@@ -2967,10 +3020,10 @@ function HiddenFieldLabel({ id, children }) {
2967
3020
  }
2968
3021
 
2969
3022
  // src/components/useLatest.ts
2970
- import * as React24 from "react";
3023
+ import * as React25 from "react";
2971
3024
  function useLatest(value) {
2972
- const ref = React24.useRef(value);
2973
- React24.useInsertionEffect(() => {
3025
+ const ref = React25.useRef(value);
3026
+ React25.useInsertionEffect(() => {
2974
3027
  ref.current = value;
2975
3028
  });
2976
3029
  return ref;
@@ -3053,20 +3106,20 @@ function NumberInput({
3053
3106
  const n = typeof v === "number" ? v : parseNumberText(v);
3054
3107
  return n == null || Number.isNaN(n) ? null : n;
3055
3108
  };
3056
- const [text, setText] = React25.useState(() => toText(value));
3057
- const [editing, setEditing] = React25.useState(false);
3109
+ const [text, setText] = React26.useState(() => toText(value));
3110
+ const [editing, setEditing] = React26.useState(false);
3058
3111
  const parsed = parseNumberText(text);
3059
3112
  const invalidMessage = parsed == null ? null : Number.isNaN(parsed) ? "Enter a number" : integer && !Number.isInteger(parsed) ? "Enter a whole number" : parsed < lo ? "Must be \u2265 " + lo : parsed > hi ? "Must be \u2264 " + hi : null;
3060
3113
  const valid = invalidMessage == null;
3061
- const committedRef = React25.useRef(toNumber(value));
3114
+ const committedRef = React26.useRef(toNumber(value));
3062
3115
  const onChangeRef = useLatest(onChange);
3063
3116
  const onValidityChangeRef = useLatest(onValidityChange);
3064
- const focusedRef = React25.useRef(false);
3065
- React25.useEffect(() => {
3117
+ const focusedRef = React26.useRef(false);
3118
+ React26.useEffect(() => {
3066
3119
  committedRef.current = toNumber(value);
3067
3120
  if (!focusedRef.current) setText(toText(value));
3068
3121
  }, [value]);
3069
- React25.useLayoutEffect(() => {
3122
+ React26.useLayoutEffect(() => {
3070
3123
  onValidityChangeRef.current?.(valid);
3071
3124
  }, [valid, onValidityChangeRef]);
3072
3125
  const fire = (n) => {
@@ -3082,26 +3135,26 @@ function NumberInput({
3082
3135
  return true;
3083
3136
  };
3084
3137
  const bumpRef = useLatest(bump);
3085
- const holdTimer = React25.useRef(null);
3086
- const release = () => {
3138
+ const holdTimer = React26.useRef(null);
3139
+ const release2 = () => {
3087
3140
  if (holdTimer.current) clearTimeout(holdTimer.current);
3088
3141
  holdTimer.current = null;
3089
3142
  };
3090
3143
  const hold = (direction) => {
3091
- release();
3144
+ release2();
3092
3145
  bump(direction, step);
3093
3146
  let repeats = 0;
3094
3147
  const tick = () => {
3095
3148
  repeats++;
3096
3149
  if (!bumpRef.current(direction, repeats > HOLD_BIG_AFTER ? big : step)) {
3097
- release();
3150
+ release2();
3098
3151
  return;
3099
3152
  }
3100
3153
  holdTimer.current = setTimeout(tick, holdInterval(repeats));
3101
3154
  };
3102
3155
  holdTimer.current = setTimeout(tick, HOLD_DELAY_MS);
3103
3156
  };
3104
- React25.useEffect(() => () => {
3157
+ React26.useEffect(() => () => {
3105
3158
  if (holdTimer.current) clearTimeout(holdTimer.current);
3106
3159
  }, []);
3107
3160
  const current2 = committedRef.current;
@@ -3167,9 +3220,9 @@ function NumberInput({
3167
3220
  "aria-label": stepperName("Decrease"),
3168
3221
  disabled: disabled || noRange || current2 != null && current2 <= lo,
3169
3222
  onPointerDown: () => hold(-1),
3170
- onPointerUp: release,
3171
- onPointerLeave: release,
3172
- onPointerCancel: release,
3223
+ onPointerUp: release2,
3224
+ onPointerLeave: release2,
3225
+ onPointerCancel: release2,
3173
3226
  onClick: (e) => {
3174
3227
  if (e.detail === 0) bump(-1, step);
3175
3228
  },
@@ -3184,9 +3237,9 @@ function NumberInput({
3184
3237
  "aria-label": stepperName("Increase"),
3185
3238
  disabled: disabled || noRange || current2 != null && current2 >= hi,
3186
3239
  onPointerDown: () => hold(1),
3187
- onPointerUp: release,
3188
- onPointerLeave: release,
3189
- onPointerCancel: release,
3240
+ onPointerUp: release2,
3241
+ onPointerLeave: release2,
3242
+ onPointerCancel: release2,
3190
3243
  onClick: (e) => {
3191
3244
  if (e.detail === 0) bump(1, step);
3192
3245
  },
@@ -3204,7 +3257,7 @@ function NumberInput({
3204
3257
  }
3205
3258
 
3206
3259
  // src/components/forms/DatePicker.tsx
3207
- import * as React26 from "react";
3260
+ import * as React27 from "react";
3208
3261
  import { jsx as jsx46, jsxs as jsxs38 } from "react/jsx-runtime";
3209
3262
  var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
3210
3263
  var DOW = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
@@ -3237,10 +3290,10 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
3237
3290
  const today = /* @__PURE__ */ new Date();
3238
3291
  const sel = range ? value || {} : { start: value, end: value };
3239
3292
  const anchor = parse(sel.start) || parse(initialMonth) || today;
3240
- const [vy, setVy] = React26.useState(anchor.getFullYear());
3241
- const [vm, setVm] = React26.useState(anchor.getMonth());
3242
- const [mode2, setMode] = React26.useState("days");
3243
- const [hover, setHover] = React26.useState(null);
3293
+ const [vy, setVy] = React27.useState(anchor.getFullYear());
3294
+ const [vm, setVm] = React27.useState(anchor.getMonth());
3295
+ const [mode2, setMode] = React27.useState("days");
3296
+ const [hover, setHover] = React27.useState(null);
3244
3297
  const s = parse(sel.start), e = parse(sel.end);
3245
3298
  const hoverEnd = range && s && !e && hover ? parse(hover) : null;
3246
3299
  const inRange = (d) => {
@@ -3251,12 +3304,12 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
3251
3304
  const isEnd = (d) => !!e && iso(d) === iso(e);
3252
3305
  const isEdge = (d) => isStart(d) || isEnd(d);
3253
3306
  const nextY = vm === 11 ? vy + 1 : vy, nextM = (vm + 1) % 12;
3254
- const [activeDate, setActiveDate] = React26.useState(() => {
3307
+ const [activeDate, setActiveDate] = React27.useState(() => {
3255
3308
  if (s) return s;
3256
3309
  if (sameMonth(today, anchor.getFullYear(), anchor.getMonth())) return today;
3257
3310
  return new Date(anchor.getFullYear(), anchor.getMonth(), 1);
3258
3311
  });
3259
- const calRef = React26.useRef(null);
3312
+ const calRef = React27.useRef(null);
3260
3313
  const pageToShow = (y, m) => {
3261
3314
  const idx = y * 12 + m, firstIdx = vy * 12 + vm, secondIdx = firstIdx + 1;
3262
3315
  if (idx === firstIdx || months > 1 && idx === secondIdx) return;
@@ -3273,7 +3326,7 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
3273
3326
  setActiveDate(next);
3274
3327
  pageToShow(next.getFullYear(), next.getMonth());
3275
3328
  };
3276
- React26.useEffect(() => {
3329
+ React27.useEffect(() => {
3277
3330
  const el = calRef.current?.querySelector('[data-iso="' + iso(activeDate) + '"]');
3278
3331
  if (el) el.focus({ preventScroll: true });
3279
3332
  }, [activeDate, vy, vm]);
@@ -3466,9 +3519,9 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
3466
3519
  }
3467
3520
  function DatePicker({ label, help, error, required = false, disabled = false, range = false, value, onChange, placeholder, id, className = "", style, "aria-label": hiddenLabel, ...rest }) {
3468
3521
  const { fieldId, labelId, ariaLabelledBy } = useTriggerLabelling(label, id, hiddenLabel);
3469
- const [open2, setOpen] = React26.useState(false);
3470
- const rootRef = React26.useRef(null);
3471
- const boxRef = React26.useRef(null);
3522
+ const [open2, setOpen] = React27.useState(false);
3523
+ const rootRef = React27.useRef(null);
3524
+ const boxRef = React27.useRef(null);
3472
3525
  const display = range ? value && value.start ? fmt(value.start) + (value.end ? " \u2192 " + fmt(value.end) : " \u2192 \u2026") : "" : fmt(value);
3473
3526
  const toggle = () => {
3474
3527
  if (!disabled) setOpen(!open2);
@@ -3557,9 +3610,9 @@ function Textarea({ label, help, error, required = false, rows = 4, disabled = f
3557
3610
  }
3558
3611
 
3559
3612
  // src/components/forms/listbox.ts
3560
- import * as React27 from "react";
3613
+ import * as React28 from "react";
3561
3614
  function useListboxNav({ count, onSelect }) {
3562
- const [active, setActive] = React27.useState(-1);
3615
+ const [active, setActive] = React28.useState(-1);
3563
3616
  return {
3564
3617
  active,
3565
3618
  setActive,
@@ -3572,7 +3625,7 @@ function useListboxNav({ count, onSelect }) {
3572
3625
  };
3573
3626
  }
3574
3627
  function useListboxScrollIntoView(active, listRef, enabled) {
3575
- React27.useEffect(() => {
3628
+ React28.useEffect(() => {
3576
3629
  if (!enabled || active < 0 || !listRef.current) return;
3577
3630
  const list = listRef.current;
3578
3631
  const el = list.querySelector('[data-i="' + active + '"]');
@@ -3785,13 +3838,13 @@ function MultiSelectPanel({
3785
3838
  onClose
3786
3839
  }) {
3787
3840
  const allowedOps = operatorsFor(field);
3788
- const [draftOperator, setDraftOperator] = React28.useState(value?.operator ?? allowedOps[0]);
3841
+ const [draftOperator, setDraftOperator] = React29.useState(value?.operator ?? allowedOps[0]);
3789
3842
  const operator = allowedOps.length === 1 ? allowedOps[0] : value?.operator ?? draftOperator;
3790
3843
  const selected = value?.values ?? [];
3791
3844
  const selectedRef = useLatest(selected);
3792
3845
  const operatorRef = useLatest(operator);
3793
- const mountedRef = React28.useRef(true);
3794
- React28.useEffect(() => {
3846
+ const mountedRef = React29.useRef(true);
3847
+ React29.useEffect(() => {
3795
3848
  mountedRef.current = true;
3796
3849
  return () => {
3797
3850
  mountedRef.current = false;
@@ -3805,20 +3858,20 @@ function MultiSelectPanel({
3805
3858
  if (selectedRef.current.length > 0) commit(selectedRef.current, op);
3806
3859
  else setDraftOperator(op);
3807
3860
  };
3808
- const [mode2, setMode] = React28.useState("search");
3809
- const [query, setQuery] = React28.useState("");
3810
- const [asyncState, setAsyncState] = React28.useState(
3861
+ const [mode2, setMode] = React29.useState("search");
3862
+ const [query, setQuery] = React29.useState("");
3863
+ const [asyncState, setAsyncState] = React29.useState(
3811
3864
  { options: null, loading: !!field.loadOptions, error: false }
3812
3865
  );
3813
- const [retryTick, setRetryTick] = React28.useState(0);
3814
- const inputRef = React28.useRef(null);
3815
- const listRef = React28.useRef(null);
3816
- const listId = React28.useId();
3866
+ const [retryTick, setRetryTick] = React29.useState(0);
3867
+ const inputRef = React29.useRef(null);
3868
+ const listRef = React29.useRef(null);
3869
+ const listId = React29.useId();
3817
3870
  const loadOptionsRef = useLatest(field.loadOptions);
3818
- React28.useEffect(() => {
3871
+ React29.useEffect(() => {
3819
3872
  inputRef.current?.focus();
3820
3873
  }, []);
3821
- React28.useEffect(() => {
3874
+ React29.useEffect(() => {
3822
3875
  const load = loadOptionsRef.current;
3823
3876
  if (!load) return;
3824
3877
  const controller = new AbortController();
@@ -3851,17 +3904,17 @@ function MultiSelectPanel({
3851
3904
  };
3852
3905
  const nav = useListboxNav({ count: options.length, onSelect: (i) => toggle(options[i]) });
3853
3906
  useListboxScrollIntoView(nav.active, listRef, hasListbox);
3854
- React28.useEffect(() => {
3907
+ React29.useEffect(() => {
3855
3908
  nav.setActive(0);
3856
3909
  }, [query, options.length]);
3857
3910
  const activeId = hasListbox && options[nav.active] ? listId + "-opt-" + nav.active : void 0;
3858
3911
  const liveMessage = showLoading ? "Loading\u2026" : showError ? "Couldn't load options." : options.length === 0 ? "No matches" : atLimit ? "Limit reached: at most " + field.maxValues + " values" : "";
3859
- const [pasteText, setPasteText] = React28.useState("");
3860
- const [pasteLoading, setPasteLoading] = React28.useState(false);
3861
- const [unmatchedTokens, setUnmatchedTokens] = React28.useState([]);
3862
- const [pasteError, setPasteError] = React28.useState(null);
3863
- const pasteWrapRef = React28.useRef(null);
3864
- React28.useEffect(() => {
3912
+ const [pasteText, setPasteText] = React29.useState("");
3913
+ const [pasteLoading, setPasteLoading] = React29.useState(false);
3914
+ const [unmatchedTokens, setUnmatchedTokens] = React29.useState([]);
3915
+ const [pasteError, setPasteError] = React29.useState(null);
3916
+ const pasteWrapRef = React29.useRef(null);
3917
+ React29.useEffect(() => {
3865
3918
  if (mode2 === "paste") pasteWrapRef.current?.querySelector("textarea")?.focus();
3866
3919
  }, [mode2]);
3867
3920
  const doResolve = () => {
@@ -4034,8 +4087,8 @@ function MultiSelectPanel({
4034
4087
  );
4035
4088
  }
4036
4089
  function useTextValidity(onFlip) {
4037
- const invalidRef = React28.useRef(/* @__PURE__ */ new Set());
4038
- const [, rerender] = React28.useReducer((n) => n + 1, 0);
4090
+ const invalidRef = React29.useRef(/* @__PURE__ */ new Set());
4091
+ const [, rerender] = React29.useReducer((n) => n + 1, 0);
4039
4092
  const onFlipRef = useLatest(onFlip);
4040
4093
  const record = (name, valid) => {
4041
4094
  const invalid = invalidRef.current;
@@ -4078,15 +4131,15 @@ function sameValue(a, b) {
4078
4131
  return true;
4079
4132
  }
4080
4133
  function useReseedFromProps(value, applies, reseed) {
4081
- const seen = React28.useRef(value);
4082
- React28.useLayoutEffect(() => {
4134
+ const seen = React29.useRef(value);
4135
+ React29.useLayoutEffect(() => {
4083
4136
  if (seen.current === value) return;
4084
4137
  seen.current = value;
4085
4138
  if (!sameValue(value, applies())) reseed(value);
4086
4139
  }, [value, applies, reseed]);
4087
4140
  }
4088
4141
  function usePreserveFocusAcrossRemount(seed, fields) {
4089
- const pendingName = React28.useRef(null);
4142
+ const pendingName = React29.useRef(null);
4090
4143
  const fieldsRef = useLatest(fields);
4091
4144
  const capture = () => {
4092
4145
  const active = document.activeElement;
@@ -4099,7 +4152,7 @@ function usePreserveFocusAcrossRemount(seed, fields) {
4099
4152
  }
4100
4153
  }
4101
4154
  };
4102
- React28.useLayoutEffect(() => {
4155
+ React29.useLayoutEffect(() => {
4103
4156
  const name = pendingName.current;
4104
4157
  if (!name) return;
4105
4158
  pendingName.current = null;
@@ -4115,14 +4168,14 @@ function RangePanel({
4115
4168
  onCommit,
4116
4169
  onClose
4117
4170
  }) {
4118
- const [draft, setDraft] = React28.useState(() => rangeDraft(value));
4119
- const [seed, setSeed] = React28.useState(0);
4120
- const minId = React28.useId();
4121
- const maxId = React28.useId();
4122
- const minWrapRef = React28.useRef(null);
4123
- const maxWrapRef = React28.useRef(null);
4171
+ const [draft, setDraft] = React29.useState(() => rangeDraft(value));
4172
+ const [seed, setSeed] = React29.useState(0);
4173
+ const minId = React29.useId();
4174
+ const maxId = React29.useId();
4175
+ const minWrapRef = React29.useRef(null);
4176
+ const maxWrapRef = React29.useRef(null);
4124
4177
  const preserveFocus = usePreserveFocusAcrossRemount(seed, { min: minWrapRef, max: maxWrapRef });
4125
- const draftRef = React28.useRef(draft);
4178
+ const draftRef = React29.useRef(draft);
4126
4179
  const shown = () => {
4127
4180
  const { min, max } = draftRef.current;
4128
4181
  return applicable(field, min == null && max == null ? void 0 : { min, max }, validity.allValid());
@@ -4214,15 +4267,15 @@ function DatePanel({
4214
4267
  onClose
4215
4268
  }) {
4216
4269
  const maxDays = effectiveMaxDays(field);
4217
- const [initial] = React28.useState(() => dateDraft(field, value));
4218
- const [kind, setKind] = React28.useState(initial.kind);
4219
- const [daysDraft, setDaysDraft] = React28.useState(initial.days);
4220
- const daysRef = React28.useRef(daysDraft);
4221
- const daysConfirmed = React28.useRef(value?.kind === "withinDays");
4222
- const [between, setBetween] = React28.useState(initial.between);
4223
- const [seed, setSeed] = React28.useState(0);
4224
- const daysId = React28.useId();
4225
- const daysWrapRef = React28.useRef(null);
4270
+ const [initial] = React29.useState(() => dateDraft(field, value));
4271
+ const [kind, setKind] = React29.useState(initial.kind);
4272
+ const [daysDraft, setDaysDraft] = React29.useState(initial.days);
4273
+ const daysRef = React29.useRef(daysDraft);
4274
+ const daysConfirmed = React29.useRef(value?.kind === "withinDays");
4275
+ const [between, setBetween] = React29.useState(initial.between);
4276
+ const [seed, setSeed] = React29.useState(0);
4277
+ const daysId = React29.useId();
4278
+ const daysWrapRef = React29.useRef(null);
4226
4279
  const preserveFocus = usePreserveFocusAcrossRemount(seed, { days: daysWrapRef });
4227
4280
  const shownWithinDays = () => {
4228
4281
  const days = daysRef.current;
@@ -4334,11 +4387,11 @@ function DatePanel({
4334
4387
  );
4335
4388
  }
4336
4389
  function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align = "left", actions, onClearAll, showActiveCount = false, className = "", ...rest }) {
4337
- const [panel, setPanel] = React28.useState(null);
4338
- const editAnchorRef = React28.useRef(null);
4339
- const addAnchorRef = React28.useRef(null);
4340
- const textInputRef = React28.useRef(null);
4341
- const optionsRef = React28.useRef(null);
4390
+ const [panel, setPanel] = React29.useState(null);
4391
+ const editAnchorRef = React29.useRef(null);
4392
+ const addAnchorRef = React29.useRef(null);
4393
+ const textInputRef = React29.useRef(null);
4394
+ const optionsRef = React29.useRef(null);
4342
4395
  if (process.env.NODE_ENV !== "production") {
4343
4396
  for (const f of fields) assertValidFieldDefinition(f);
4344
4397
  }
@@ -4361,7 +4414,7 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
4361
4414
  const editingField = panel && panel.kind === "edit" ? fields.find((f) => f.key === panel.key) : void 0;
4362
4415
  const startEditing = (key) => setPanel({ kind: "edit", key });
4363
4416
  const closeEditing = () => setPanel(null);
4364
- React28.useEffect(() => {
4417
+ React29.useEffect(() => {
4365
4418
  if (!panel || panel.kind !== "edit") return;
4366
4419
  if (editingField?.type === "text") {
4367
4420
  textInputRef.current?.focus();
@@ -4591,10 +4644,10 @@ function StatTile({ label, value, sub, delta, invert = false, loading = false, c
4591
4644
  }
4592
4645
 
4593
4646
  // src/components/data/CodeBlock.tsx
4594
- import * as React30 from "react";
4647
+ import * as React31 from "react";
4595
4648
 
4596
4649
  // src/kits/clipboard.ts
4597
- import * as React29 from "react";
4650
+ import * as React30 from "react";
4598
4651
  var COPIED_FEEDBACK_MS = 1600;
4599
4652
  function copyThroughSelection(text) {
4600
4653
  const previouslyFocused = document.activeElement instanceof HTMLElement ? document.activeElement : null;
@@ -4624,17 +4677,17 @@ async function copyToClipboard(text) {
4624
4677
  return copyThroughSelection(text);
4625
4678
  }
4626
4679
  function useCopyToClipboard() {
4627
- const [copied, setCopied] = React29.useState(false);
4628
- const timer = React29.useRef(null);
4629
- const mounted = React29.useRef(true);
4630
- React29.useEffect(() => {
4680
+ const [copied, setCopied] = React30.useState(false);
4681
+ const timer = React30.useRef(null);
4682
+ const mounted = React30.useRef(true);
4683
+ React30.useEffect(() => {
4631
4684
  mounted.current = true;
4632
4685
  return () => {
4633
4686
  mounted.current = false;
4634
4687
  if (timer.current) clearTimeout(timer.current);
4635
4688
  };
4636
4689
  }, []);
4637
- const copy = React29.useCallback(async (text) => {
4690
+ const copy = React30.useCallback(async (text) => {
4638
4691
  const ok = await copyToClipboard(text);
4639
4692
  if (ok && mounted.current) {
4640
4693
  setCopied(true);
@@ -4802,7 +4855,7 @@ function tokenize(src, lang) {
4802
4855
  return out;
4803
4856
  }
4804
4857
  function Highlighted({ code, lang }) {
4805
- const toks = React30.useMemo(() => tokenize(code, lang), [code, lang]);
4858
+ const toks = React31.useMemo(() => tokenize(code, lang), [code, lang]);
4806
4859
  return /* @__PURE__ */ jsx51(Fragment7, { children: toks.map((tk, i) => tk.c ? /* @__PURE__ */ jsx51("span", { className: "tok-" + tk.c, children: tk.t }, i) : tk.t) });
4807
4860
  }
4808
4861
  function CodeBlock({
@@ -4816,8 +4869,8 @@ function CodeBlock({
4816
4869
  actions,
4817
4870
  className = ""
4818
4871
  }) {
4819
- const [wrap, setWrap] = React30.useState(!!wrapDefault);
4820
- const [open2, setOpen] = React30.useState(false);
4872
+ const [wrap, setWrap] = React31.useState(!!wrapDefault);
4873
+ const [open2, setOpen] = React31.useState(false);
4821
4874
  const [copied, copy] = useCopyToClipboard();
4822
4875
  const body = String(code).replace(/\n$/, "");
4823
4876
  const lines = body.split("\n");
@@ -4846,7 +4899,7 @@ function CodeBlock({
4846
4899
  ] });
4847
4900
  }
4848
4901
  function DiffBlock({ diff = "", filename, collapseAfter = 34, className = "" }) {
4849
- const [open2, setOpen] = React30.useState(false);
4902
+ const [open2, setOpen] = React31.useState(false);
4850
4903
  const [copied, copy] = useCopyToClipboard();
4851
4904
  const raw = String(diff).replace(/\n$/, "");
4852
4905
  const all = raw.split("\n").map((line) => {
@@ -4892,7 +4945,7 @@ function DiffBlock({ diff = "", filename, collapseAfter = 34, className = "" })
4892
4945
  }
4893
4946
 
4894
4947
  // src/components/data/Markdown.tsx
4895
- import * as React31 from "react";
4948
+ import * as React32 from "react";
4896
4949
  import { jsx as jsx52, jsxs as jsxs44 } from "react/jsx-runtime";
4897
4950
  var SAFE = /^(?:https?:|mailto:|tel:|#|\/|\.{1,2}\/)/i;
4898
4951
  var safeHref = (h) => SAFE.test(String(h || "").trim()) ? String(h).trim() : null;
@@ -4931,7 +4984,7 @@ function inlineNodes(src, ctx, keyBase) {
4931
4984
  const href = safeHref(g(2));
4932
4985
  out.push(href ? /* @__PURE__ */ jsx52("a", { href, title: g(3) || void 0, target: /^https?:/i.test(href) ? "_blank" : void 0, rel: "noopener noreferrer", onClick: ctx.onLinkClick, children: inlineNodes(g(1), ctx, key()) }, key()) : /* @__PURE__ */ jsx52("span", { children: g(1) }, key()));
4933
4986
  } else if (kind === "cite") {
4934
- out.push(ctx.renderCitation ? /* @__PURE__ */ jsx52(React31.Fragment, { children: ctx.renderCitation(g(1)) }, key()) : /* @__PURE__ */ jsx52("sup", { className: "fd-md-cite", children: g(1) }, key()));
4987
+ out.push(ctx.renderCitation ? /* @__PURE__ */ jsx52(React32.Fragment, { children: ctx.renderCitation(g(1)) }, key()) : /* @__PURE__ */ jsx52("sup", { className: "fd-md-cite", children: g(1) }, key()));
4935
4988
  } else if (kind === "strongem") out.push(/* @__PURE__ */ jsx52("strong", { children: /* @__PURE__ */ jsx52("em", { children: inlineNodes(g(1), ctx, key()) }) }, key()));
4936
4989
  else if (kind === "strong") out.push(/* @__PURE__ */ jsx52("strong", { children: inlineNodes(g(1) || g(2), ctx, key()) }, key()));
4937
4990
  else if (kind === "em") out.push(/* @__PURE__ */ jsx52("em", { children: inlineNodes(g(1) || g(2), ctx, key()) }, key()));
@@ -5096,7 +5149,7 @@ function Markdown({
5096
5149
  onLinkClick
5097
5150
  }) {
5098
5151
  const ctx = { allowImages, headingOffset, renderCitation, onLinkClick, codeProps };
5099
- const blocks = React31.useMemo(() => parseBlocks(source), [source]);
5152
+ const blocks = React32.useMemo(() => parseBlocks(source), [source]);
5100
5153
  return /* @__PURE__ */ jsx52("div", { className: ["fd-md", className].filter(Boolean).join(" "), children: renderBlocks(blocks, ctx, "b") });
5101
5154
  }
5102
5155
  function MarkdownInline({ source = "", className = "", onLinkClick }) {
@@ -5210,7 +5263,7 @@ function Pagination({
5210
5263
  }
5211
5264
 
5212
5265
  // src/components/data/RelativeTime.tsx
5213
- import * as React32 from "react";
5266
+ import * as React33 from "react";
5214
5267
  import { jsxs as jsxs47 } from "react/jsx-runtime";
5215
5268
  var MIN = 6e4;
5216
5269
  var HOUR = 36e5;
@@ -5262,9 +5315,9 @@ function formatDuration(ms) {
5262
5315
  return h + "h" + (m % 60 ? " " + m % 60 + "m" : "");
5263
5316
  }
5264
5317
  function RelativeTime({ value, prefix, className = "", refresh: refresh2 = true, ...rest }) {
5265
- const [, force] = React32.useState(0);
5318
+ const [, force] = React33.useState(0);
5266
5319
  const t = value instanceof Date ? value.getTime() : Date.parse(value);
5267
- React32.useEffect(() => {
5320
+ React33.useEffect(() => {
5268
5321
  if (!refresh2 || !t || isNaN(t)) return;
5269
5322
  const abs = Math.abs(t - Date.now());
5270
5323
  if (abs > DAY) return;
@@ -5280,7 +5333,7 @@ function RelativeTime({ value, prefix, className = "", refresh: refresh2 = true,
5280
5333
  }
5281
5334
 
5282
5335
  // src/components/data/ScoreMeter.tsx
5283
- import * as React33 from "react";
5336
+ import * as React34 from "react";
5284
5337
  import { jsx as jsx55, jsxs as jsxs48 } from "react/jsx-runtime";
5285
5338
  function ScoreMeter({
5286
5339
  score,
@@ -5295,10 +5348,10 @@ function ScoreMeter({
5295
5348
  breakdownWidth = 280,
5296
5349
  className = ""
5297
5350
  }) {
5298
- const [open2, setOpen] = React33.useState(false);
5299
- const ref = React33.useRef(null);
5351
+ const [open2, setOpen] = React34.useState(false);
5352
+ const ref = React34.useRef(null);
5300
5353
  const value = Math.max(0, Math.min(100, Math.round(Number(score) || 0)));
5301
- const body = /* @__PURE__ */ jsxs48(React33.Fragment, { children: [
5354
+ const body = /* @__PURE__ */ jsxs48(React34.Fragment, { children: [
5302
5355
  /* @__PURE__ */ jsx55("span", { className: "fd-scoremeter-rail", style: { width }, "aria-hidden": "true", children: /* @__PURE__ */ jsx55(SegmentedMeter, { total: 100, segments, height, showTotal: false, showPercent: false, legend: false }) }),
5303
5356
  showScore ? /* @__PURE__ */ jsx55("span", { className: "fd-scoremeter-value fd-tabular", "aria-hidden": "true", children: value }) : null
5304
5357
  ] });
@@ -5317,7 +5370,7 @@ function ScoreMeter({
5317
5370
  }
5318
5371
  );
5319
5372
  }
5320
- return /* @__PURE__ */ jsxs48(React33.Fragment, { children: [
5373
+ return /* @__PURE__ */ jsxs48(React34.Fragment, { children: [
5321
5374
  /* @__PURE__ */ jsx55(
5322
5375
  "button",
5323
5376
  {
@@ -5348,14 +5401,14 @@ function ScoreMeter({
5348
5401
  }
5349
5402
 
5350
5403
  // src/components/actions/inlinePanel.tsx
5351
- import * as React34 from "react";
5404
+ import * as React35 from "react";
5352
5405
  import { jsx as jsx56 } from "react/jsx-runtime";
5353
5406
  function useInlinePanel() {
5354
- const [open2, setOpen] = React34.useState(false);
5355
- const ref = React34.useRef(null);
5407
+ const [open2, setOpen] = React35.useState(false);
5408
+ const ref = React35.useRef(null);
5356
5409
  const layer = useStackedLayer({ active: open2, containerRef: ref, onEscape: () => setOpen(false) });
5357
5410
  const zIndex = useLayerZIndex(layer);
5358
- React34.useEffect(() => {
5411
+ React35.useEffect(() => {
5359
5412
  if (!open2) return;
5360
5413
  const away = (e) => {
5361
5414
  if (ref.current && !ref.current.contains(e.target)) setOpen(false);
@@ -5421,7 +5474,7 @@ function SortMenu({ fields = [], sort, onSort, align = "right", size = "md", cla
5421
5474
  }
5422
5475
 
5423
5476
  // src/components/data/StepList.tsx
5424
- import * as React35 from "react";
5477
+ import * as React36 from "react";
5425
5478
  import { jsx as jsx58, jsxs as jsxs50 } from "react/jsx-runtime";
5426
5479
  var KIND_ICON = { tool: "wrench", search: "magnifying-glass", read: "file-text", write: "pencil-simple", reasoning: "brain", run: "terminal", fetch: "cloud-arrow-down" };
5427
5480
  function StepList({
@@ -5434,9 +5487,9 @@ function StepList({
5434
5487
  dense = false,
5435
5488
  className = ""
5436
5489
  }) {
5437
- const [openState, setOpenState] = React35.useState(defaultOpen);
5490
+ const [openState, setOpenState] = React36.useState(defaultOpen);
5438
5491
  const open2 = openProp == null ? openState : openProp;
5439
- const [expanded, setExpanded] = React35.useState({});
5492
+ const [expanded, setExpanded] = React36.useState({});
5440
5493
  if (!steps.length) return null;
5441
5494
  const running = steps.some((s) => s.status === "running");
5442
5495
  const failed = steps.filter((s) => s.status === "error").length;
@@ -5494,7 +5547,7 @@ function StepList({
5494
5547
  }
5495
5548
 
5496
5549
  // src/components/data/VirtualList.tsx
5497
- import * as React36 from "react";
5550
+ import * as React37 from "react";
5498
5551
  import { jsx as jsx59, jsxs as jsxs51 } from "react/jsx-runtime";
5499
5552
  var VIRTUAL_LIST_BUFFER_ROWS = 20;
5500
5553
  var VIRTUAL_LIST_ROW_GAP = 6;
@@ -5546,35 +5599,35 @@ function VirtualList({
5546
5599
  className = "",
5547
5600
  style
5548
5601
  }) {
5549
- const [scrollTop, setScrollTop] = React36.useState(0);
5550
- const loaded = React36.useMemo(
5602
+ const [scrollTop, setScrollTop] = React37.useState(0);
5603
+ const loaded = React37.useMemo(
5551
5604
  () => ({ firstItemIndex, count: items.length }),
5552
5605
  [firstItemIndex, items.length]
5553
5606
  );
5554
5607
  const total = Math.max(totalCount == null ? 0 : totalCount, firstItemIndex + items.length);
5555
5608
  const bandKey = firstItemIndex + ":" + items.length;
5556
- const win = React36.useMemo(
5609
+ const win = React37.useMemo(
5557
5610
  () => computeVirtualWindow({ scrollTop, viewportHeight: height, itemHeight, itemCount: total, loaded }),
5558
5611
  [scrollTop, height, itemHeight, total, loaded]
5559
5612
  );
5560
- const need = React36.useMemo(() => computeNeedMore(win, loaded), [win, loaded]);
5613
+ const need = React37.useMemo(() => computeNeedMore(win, loaded), [win, loaded]);
5561
5614
  const wantStart = need.start && hasMore?.start !== false;
5562
5615
  const wantEnd = need.end && hasMore?.end !== false;
5563
5616
  const bucket2 = Math.floor(win.visibleStart / VIRTUAL_LIST_BUFFER_ROWS);
5564
5617
  const askKey = bandKey + "@" + bucket2;
5565
- const asked = React36.useRef({ start: null, end: null });
5566
- React36.useEffect(() => {
5618
+ const asked = React37.useRef({ start: null, end: null });
5619
+ React37.useEffect(() => {
5567
5620
  if (loading || !wantStart || asked.current.start === askKey) return;
5568
5621
  asked.current.start = askKey;
5569
5622
  onNeedMore("start", win);
5570
5623
  }, [wantStart, loading, askKey, onNeedMore, win]);
5571
- React36.useEffect(() => {
5624
+ React37.useEffect(() => {
5572
5625
  if (loading || !wantEnd || asked.current.end === askKey) return;
5573
5626
  asked.current.end = askKey;
5574
5627
  onNeedMore("end", win);
5575
5628
  }, [wantEnd, loading, askKey, onNeedMore, win]);
5576
- const lastKeysRef = React36.useRef(null);
5577
- const newKeys = React36.useMemo(() => {
5629
+ const lastKeysRef = React37.useRef(null);
5630
+ const newKeys = React37.useMemo(() => {
5578
5631
  const prev = lastKeysRef.current;
5579
5632
  if (!prev) return /* @__PURE__ */ new Set();
5580
5633
  const fresh = /* @__PURE__ */ new Set();
@@ -5584,7 +5637,7 @@ function VirtualList({
5584
5637
  }
5585
5638
  return fresh;
5586
5639
  }, [items]);
5587
- React36.useEffect(() => {
5640
+ React37.useEffect(() => {
5588
5641
  lastKeysRef.current = new Set(items.map(keyOf));
5589
5642
  }, [items]);
5590
5643
  const gapStyle = { "--fd-vlist-gap": rowGap + "px" };
@@ -5629,7 +5682,7 @@ function VirtualList({
5629
5682
  }
5630
5683
 
5631
5684
  // src/components/data/EntityRow.tsx
5632
- import * as React37 from "react";
5685
+ import * as React38 from "react";
5633
5686
  import { jsx as jsx60, jsxs as jsxs52 } from "react/jsx-runtime";
5634
5687
  var ENTITY_ROW_METRIC_WIDTH = 74;
5635
5688
  var METRIC_TONE_COLOR = {
@@ -5642,7 +5695,7 @@ function EntityRowMetrics({ metrics, className = "", style }) {
5642
5695
  const key = m.id || m.label || i;
5643
5696
  const className2 = ["fd-erow-metric", m.tone && m.tone !== "default" ? "is-" + m.tone : "", m.tooltip != null ? "is-described" : ""].filter(Boolean).join(" ");
5644
5697
  const tone = { color: METRIC_TONE_COLOR[m.tone || "default"] };
5645
- const content = /* @__PURE__ */ jsxs52(React37.Fragment, { children: [
5698
+ const content = /* @__PURE__ */ jsxs52(React38.Fragment, { children: [
5646
5699
  m.icon ? /* @__PURE__ */ jsx60("i", { className: "ph ph-" + m.icon, "aria-hidden": "true" }) : null,
5647
5700
  /* @__PURE__ */ jsx60("span", { className: "fd-erow-metric-value fd-tabular", children: m.value }),
5648
5701
  /* @__PURE__ */ jsx60("span", { className: "fd-sr", children: " " + m.label })
@@ -5734,8 +5787,8 @@ function EntityRow({
5734
5787
  }
5735
5788
 
5736
5789
  // src/components/data/TransferList.tsx
5737
- import * as React38 from "react";
5738
- import { createPortal as createPortal4 } from "react-dom";
5790
+ import * as React39 from "react";
5791
+ import { createPortal as createPortal5 } from "react-dom";
5739
5792
 
5740
5793
  // src/components/forms/Input.tsx
5741
5794
  import { jsx as jsx61, jsxs as jsxs53 } from "react/jsx-runtime";
@@ -5840,12 +5893,12 @@ function TransferList({
5840
5893
  listHeight = 440,
5841
5894
  className = ""
5842
5895
  }) {
5843
- const [drag, setDrag] = React38.useState(null);
5844
- const [dragOverSide, setDragOverSide] = React38.useState(null);
5845
- const dragRef = React38.useRef(null);
5846
- const armedRef = React38.useRef(null);
5847
- const sideRefs = React38.useRef({ left: null, right: null });
5848
- const hitTestSide = React38.useCallback((x, y) => {
5896
+ const [drag, setDrag] = React39.useState(null);
5897
+ const [dragOverSide, setDragOverSide] = React39.useState(null);
5898
+ const dragRef = React39.useRef(null);
5899
+ const armedRef = React39.useRef(null);
5900
+ const sideRefs = React39.useRef({ left: null, right: null });
5901
+ const hitTestSide = React39.useCallback((x, y) => {
5849
5902
  for (const side of ["left", "right"]) {
5850
5903
  const el = sideRefs.current[side];
5851
5904
  if (!el) continue;
@@ -5854,7 +5907,7 @@ function TransferList({
5854
5907
  }
5855
5908
  return null;
5856
5909
  }, []);
5857
- const findItem = React38.useCallback(
5910
+ const findItem = React39.useCallback(
5858
5911
  (side, key) => (side === "left" ? left.items : right.items).find((it) => keyOf(it) === key),
5859
5912
  [left.items, right.items, keyOf]
5860
5913
  );
@@ -5876,7 +5929,7 @@ function TransferList({
5876
5929
  height: rect.height
5877
5930
  };
5878
5931
  };
5879
- React38.useEffect(() => {
5932
+ React39.useEffect(() => {
5880
5933
  const onMovePointer = (e) => {
5881
5934
  const armed = armedRef.current;
5882
5935
  if (!armed || e.pointerId !== armed.pointerId) return;
@@ -5929,7 +5982,7 @@ function TransferList({
5929
5982
  window.removeEventListener("pointercancel", endDrag);
5930
5983
  };
5931
5984
  }, [hitTestSide, findItem, onMove]);
5932
- React38.useEffect(() => {
5985
+ React39.useEffect(() => {
5933
5986
  if (!drag || typeof document === "undefined") return;
5934
5987
  const prev = document.body.style.userSelect;
5935
5988
  document.body.style.userSelect = "none";
@@ -6012,7 +6065,7 @@ function TransferList({
6012
6065
  renderSide("left", left, "right"),
6013
6066
  renderSide("right", right, "left")
6014
6067
  ] }),
6015
- drag ? createPortal4(
6068
+ drag ? createPortal5(
6016
6069
  /* @__PURE__ */ jsx63(
6017
6070
  "div",
6018
6071
  {
@@ -6037,11 +6090,11 @@ function TransferList({
6037
6090
  }
6038
6091
 
6039
6092
  // src/components/forms/Checkbox.tsx
6040
- import * as React39 from "react";
6093
+ import * as React40 from "react";
6041
6094
  import { jsx as jsx64, jsxs as jsxs55 } from "react/jsx-runtime";
6042
6095
  function Checkbox({ label, description, card = false, indeterminate = false, className = "", ...rest }) {
6043
- const ref = React39.useRef(null);
6044
- React39.useEffect(() => {
6096
+ const ref = React40.useRef(null);
6097
+ React40.useEffect(() => {
6045
6098
  if (ref.current) ref.current.indeterminate = indeterminate;
6046
6099
  }, [indeterminate]);
6047
6100
  return /* @__PURE__ */ jsxs55("label", { className: ["fd-choice", card ? "fd-choice-card" : "", className].filter(Boolean).join(" "), children: [
@@ -6085,7 +6138,7 @@ function Switch({ label, description, className = "", ...rest }) {
6085
6138
  }
6086
6139
 
6087
6140
  // src/components/forms/Select.tsx
6088
- import * as React40 from "react";
6141
+ import * as React41 from "react";
6089
6142
  import { jsx as jsx67, jsxs as jsxs58 } from "react/jsx-runtime";
6090
6143
  var norm = (o) => typeof o === "string" ? { value: o, label: o } : o;
6091
6144
  function Select({
@@ -6113,12 +6166,12 @@ function Select({
6113
6166
  const isOn = (v) => multiple ? vals.includes(v) : v === value;
6114
6167
  const hasSearch = searchable === void 0 ? opts.length > 8 : searchable;
6115
6168
  const { fieldId, labelId, ariaLabelledBy } = useTriggerLabelling(label, id, hiddenLabel);
6116
- const [open2, setOpen] = React40.useState(false);
6117
- const [q, setQ] = React40.useState("");
6118
- const rootRef = React40.useRef(null);
6119
- const boxRef = React40.useRef(null);
6120
- const listRef = React40.useRef(null);
6121
- const typeBuf = React40.useRef({ s: "", t: 0 });
6169
+ const [open2, setOpen] = React41.useState(false);
6170
+ const [q, setQ] = React41.useState("");
6171
+ const rootRef = React41.useRef(null);
6172
+ const boxRef = React41.useRef(null);
6173
+ const listRef = React41.useRef(null);
6174
+ const typeBuf = React41.useRef({ s: "", t: 0 });
6122
6175
  const selected = multiple ? null : opts.find((o) => o.value === value);
6123
6176
  const chosen = multiple ? opts.filter((o) => vals.includes(o.value)) : [];
6124
6177
  const boxText = multiple ? chosen.length === 0 ? placeholder : chosen.length === 1 ? chosen[0].label : summary ? summary(chosen.map((o) => o.value)) : chosen.length + " selected" : selected ? selected.label : placeholder;
@@ -6254,7 +6307,7 @@ function Select({
6254
6307
  ),
6255
6308
  q ? /* @__PURE__ */ jsx67("span", { className: "fd-body-sm fd-muted", children: visible.length }) : null
6256
6309
  ] }) : void 0,
6257
- footer: multiple ? /* @__PURE__ */ jsxs58(React40.Fragment, { children: [
6310
+ footer: multiple ? /* @__PURE__ */ jsxs58(React41.Fragment, { children: [
6258
6311
  /* @__PURE__ */ jsx67(
6259
6312
  "button",
6260
6313
  {
@@ -6285,7 +6338,7 @@ function Select({
6285
6338
  'Nothing matches "',
6286
6339
  q,
6287
6340
  '".'
6288
- ] }) : groups.map((grp) => /* @__PURE__ */ jsxs58(React40.Fragment, { children: [
6341
+ ] }) : groups.map((grp) => /* @__PURE__ */ jsxs58(React41.Fragment, { children: [
6289
6342
  grp.g ? /* @__PURE__ */ jsx67("div", { className: "fd-pop-group", children: grp.g }) : null,
6290
6343
  grp.items.map(({ o, i }) => /* @__PURE__ */ jsxs58(
6291
6344
  "button",
@@ -6322,7 +6375,7 @@ function Select({
6322
6375
  }
6323
6376
 
6324
6377
  // src/components/forms/TimePicker.tsx
6325
- import * as React41 from "react";
6378
+ import * as React42 from "react";
6326
6379
  import { jsx as jsx68, jsxs as jsxs59 } from "react/jsx-runtime";
6327
6380
  var pad = (n) => String(n).padStart(2, "0");
6328
6381
  function ClockFace({ value = "09:00", onChange }) {
@@ -6331,9 +6384,9 @@ function ClockFace({ value = "09:00", onChange }) {
6331
6384
  if (isNaN(m)) m = 0;
6332
6385
  const pm = h24 >= 12;
6333
6386
  const h12 = h24 % 12 === 0 ? 12 : h24 % 12;
6334
- const [mode2, setMode] = React41.useState("h");
6335
- const faceRef = React41.useRef(null);
6336
- const dragging = React41.useRef(false);
6387
+ const [mode2, setMode] = React42.useState("h");
6388
+ const faceRef = React42.useRef(null);
6389
+ const dragging = React42.useRef(false);
6337
6390
  const set = (h, mm, isPm) => onChange((isPm ? h % 12 + 12 : h % 12) + ":" + pad(mm));
6338
6391
  const R = 108, NR = 80;
6339
6392
  const nums = mode2 === "h" ? Array.from({ length: 12 }, (_, i) => i + 1) : Array.from({ length: 12 }, (_, i) => i * 5);
@@ -6406,9 +6459,9 @@ function ClockFace({ value = "09:00", onChange }) {
6406
6459
  }
6407
6460
  function TimePicker({ label, help, error, required = false, disabled = false, value = "", onChange, placeholder = "Pick a time", id, className = "", style }) {
6408
6461
  const { fieldId, labelId, ariaLabelledBy } = useTriggerLabelling(label, id);
6409
- const [open2, setOpen] = React41.useState(false);
6410
- const rootRef = React41.useRef(null);
6411
- const boxRef = React41.useRef(null);
6462
+ const [open2, setOpen] = React42.useState(false);
6463
+ const rootRef = React42.useRef(null);
6464
+ const boxRef = React42.useRef(null);
6412
6465
  const disp = () => {
6413
6466
  if (!value) return "";
6414
6467
  const [h, m] = value.split(":").map(Number);
@@ -6451,7 +6504,7 @@ function TimePicker({ label, help, error, required = false, disabled = false, va
6451
6504
  offset: 6,
6452
6505
  width: 262,
6453
6506
  role: "presentation",
6454
- footer: /* @__PURE__ */ jsxs59(React41.Fragment, { children: [
6507
+ footer: /* @__PURE__ */ jsxs59(React42.Fragment, { children: [
6455
6508
  /* @__PURE__ */ jsx68(
6456
6509
  "button",
6457
6510
  {
@@ -6479,7 +6532,7 @@ function TimePicker({ label, help, error, required = false, disabled = false, va
6479
6532
  }
6480
6533
 
6481
6534
  // src/components/forms/Slider.tsx
6482
- import * as React42 from "react";
6535
+ import * as React43 from "react";
6483
6536
  import { jsx as jsx69, jsxs as jsxs60 } from "react/jsx-runtime";
6484
6537
  function Slider({
6485
6538
  label,
@@ -6497,7 +6550,7 @@ function Slider({
6497
6550
  ...rest
6498
6551
  }) {
6499
6552
  const fieldId = useFieldId(id);
6500
- const [dragging, setDragging] = React42.useState(false);
6553
+ const [dragging, setDragging] = React43.useState(false);
6501
6554
  const v = value === void 0 ? min : Number(value);
6502
6555
  const pct = max === min ? 0 : (v - min) / (max - min) * 100;
6503
6556
  return /* @__PURE__ */ jsxs60("div", { className: ["fd-field", className].filter(Boolean).join(" "), children: [
@@ -6531,7 +6584,7 @@ function Slider({
6531
6584
  }
6532
6585
 
6533
6586
  // src/components/forms/RangeSlider.tsx
6534
- import * as React43 from "react";
6587
+ import * as React44 from "react";
6535
6588
  import { jsx as jsx70, jsxs as jsxs61 } from "react/jsx-runtime";
6536
6589
  function RangeSlider({
6537
6590
  label,
@@ -6551,9 +6604,9 @@ function RangeSlider({
6551
6604
  }) {
6552
6605
  const fmt2 = format || ((v) => String(v));
6553
6606
  const [a, b] = value || [min, max];
6554
- const [drag, setDrag] = React43.useState(null);
6555
- const [focus, setFocus] = React43.useState(null);
6556
- const railRef = React43.useRef(null);
6607
+ const [drag, setDrag] = React44.useState(null);
6608
+ const [focus, setFocus] = React44.useState(null);
6609
+ const railRef = React44.useRef(null);
6557
6610
  const pct = (v) => max === min ? 0 : (v - min) / (max - min) * 100;
6558
6611
  const clampPair = (i, v) => {
6559
6612
  v = Math.min(max, Math.max(min, Math.round(v / step) * step));
@@ -6568,7 +6621,7 @@ function RangeSlider({
6568
6621
  const r = railRef.current.getBoundingClientRect();
6569
6622
  return min + Math.min(1, Math.max(0, (e.clientX - r.left) / r.width)) * (max - min);
6570
6623
  };
6571
- React43.useEffect(() => {
6624
+ React44.useEffect(() => {
6572
6625
  if (drag === null) return;
6573
6626
  const mv = (e) => onChange && onChange(clampPair(drag, fromEvent(e)));
6574
6627
  const upH = () => setDrag(null);
@@ -6649,7 +6702,7 @@ function RangeSlider({
6649
6702
  /* @__PURE__ */ jsxs61("div", { className: "fd-range" + (hasLabels ? " has-labels" : ""), onPointerDown: onRailDown, children: [
6650
6703
  /* @__PURE__ */ jsx70("span", { className: "fd-range-rail", ref: railRef }),
6651
6704
  /* @__PURE__ */ jsx70("span", { className: "fd-range-fill", style: { left: pct(a) + "%", width: pct(b) - pct(a) + "%" } }),
6652
- marks.map((m) => /* @__PURE__ */ jsxs61(React43.Fragment, { children: [
6705
+ marks.map((m) => /* @__PURE__ */ jsxs61(React44.Fragment, { children: [
6653
6706
  /* @__PURE__ */ jsx70("span", { className: "fd-range-mark" + (m.value >= a && m.value <= b ? " is-in" : ""), style: { left: pct(m.value) + "%" } }),
6654
6707
  m.label ? /* @__PURE__ */ jsx70("span", { className: "fd-range-mark-label", style: { left: pct(m.value) + "%" }, children: m.label }) : null
6655
6708
  ] }, m.value)),
@@ -6678,7 +6731,7 @@ function RangeSlider({
6678
6731
  }
6679
6732
 
6680
6733
  // src/components/forms/Dropzone.tsx
6681
- import * as React44 from "react";
6734
+ import * as React45 from "react";
6682
6735
  import { jsx as jsx71, jsxs as jsxs62 } from "react/jsx-runtime";
6683
6736
  function Dropzone({
6684
6737
  onFiles,
@@ -6693,8 +6746,8 @@ function Dropzone({
6693
6746
  className = "",
6694
6747
  style
6695
6748
  }) {
6696
- const [over, setOver] = React44.useState(false);
6697
- const depth = React44.useRef(0);
6749
+ const [over, setOver] = React45.useState(false);
6750
+ const depth = React45.useRef(0);
6698
6751
  const has = (e) => {
6699
6752
  const dt = e.dataTransfer;
6700
6753
  if (!dt) return false;
@@ -6756,8 +6809,8 @@ function FilePickButton({
6756
6809
  className = "",
6757
6810
  children
6758
6811
  }) {
6759
- const ref = React44.useRef(null);
6760
- return /* @__PURE__ */ jsxs62(React44.Fragment, { children: [
6812
+ const ref = React45.useRef(null);
6813
+ return /* @__PURE__ */ jsxs62(React45.Fragment, { children: [
6761
6814
  /* @__PURE__ */ jsx71(
6762
6815
  "button",
6763
6816
  {
@@ -6790,10 +6843,10 @@ function FilePickButton({
6790
6843
  }
6791
6844
  function useStagedFiles(upload, opts) {
6792
6845
  const o = opts || {};
6793
- const [items, setItems] = React44.useState([]);
6794
- const controllers = React44.useRef({});
6846
+ const [items, setItems] = React45.useState([]);
6847
+ const controllers = React45.useRef({});
6795
6848
  const patch = (id, next) => setItems((list) => list.map((f) => f.id === id ? Object.assign({}, f, next) : f));
6796
- const run = React44.useCallback((att) => {
6849
+ const run = React45.useCallback((att) => {
6797
6850
  if (!upload) return;
6798
6851
  const ac = typeof AbortController !== "undefined" ? new AbortController() : null;
6799
6852
  controllers.current[att.id] = ac;
@@ -6810,14 +6863,14 @@ function useStagedFiles(upload, opts) {
6810
6863
  delete controllers.current[att.id];
6811
6864
  });
6812
6865
  }, [upload]);
6813
- const add = React44.useCallback((files) => {
6866
+ const add = React45.useCallback((files) => {
6814
6867
  if (!upload) return [];
6815
6868
  const atts = Array.from(files).map((f) => toAttachment(f));
6816
6869
  setItems((list) => list.concat(atts));
6817
6870
  atts.forEach(run);
6818
6871
  return atts;
6819
6872
  }, [upload, run]);
6820
- const remove = React44.useCallback((att) => {
6873
+ const remove = React45.useCallback((att) => {
6821
6874
  const ac = controllers.current[att.id];
6822
6875
  if (ac) {
6823
6876
  try {
@@ -6828,10 +6881,10 @@ function useStagedFiles(upload, opts) {
6828
6881
  }
6829
6882
  setItems((list) => list.filter((f) => f.id !== att.id));
6830
6883
  }, []);
6831
- const retry = React44.useCallback((att) => {
6884
+ const retry = React45.useCallback((att) => {
6832
6885
  run(att);
6833
6886
  }, [run]);
6834
- const clear = React44.useCallback(() => {
6887
+ const clear = React45.useCallback(() => {
6835
6888
  Object.values(controllers.current).forEach((ac) => {
6836
6889
  try {
6837
6890
  ac && ac.abort();
@@ -6955,7 +7008,7 @@ function FileGrid({ files = [], onOpen, onRemove, onRetry, tiles = true, maxHeig
6955
7008
  }
6956
7009
 
6957
7010
  // src/components/forms/MarkdownEditor.tsx
6958
- import * as React45 from "react";
7011
+ import * as React46 from "react";
6959
7012
  import { jsx as jsx73, jsxs as jsxs64 } from "react/jsx-runtime";
6960
7013
  var isMac = typeof navigator !== "undefined" && /Mac|iPhone|iPad/.test(navigator.platform || navigator.userAgent || "");
6961
7014
  var INLINE_RE = /(\*\*\*[^*\n]+\*\*\*|\*\*[^*\n]+\*\*|__[^_\n]+__|~~[^~\n]+~~|`[^`\n]+`|\*[^*\s][^*\n]*\*|(?<![A-Za-z0-9_])_[^_\s][^_\n]*_|\[[^\]\n]*\]\([^)\s\n]*\)|https?:\/\/\S+)/g;
@@ -7169,7 +7222,7 @@ function syncDom(root, value) {
7169
7222
  while (root.children.length > lines.length) root.removeChild(root.lastChild);
7170
7223
  }
7171
7224
  var LIST_CONT = RE_LI;
7172
- var MarkdownEditor = React45.forwardRef(function MarkdownEditor2({
7225
+ var MarkdownEditor = React46.forwardRef(function MarkdownEditor2({
7173
7226
  value = "",
7174
7227
  onChange,
7175
7228
  onSubmit,
@@ -7188,10 +7241,10 @@ var MarkdownEditor = React45.forwardRef(function MarkdownEditor2({
7188
7241
  className = "",
7189
7242
  id
7190
7243
  }, ref) {
7191
- const boxRef = React45.useRef(null);
7192
- const composing = React45.useRef(false);
7193
- const pendingCaret = React45.useRef(null);
7194
- React45.useLayoutEffect(() => {
7244
+ const boxRef = React46.useRef(null);
7245
+ const composing = React46.useRef(false);
7246
+ const pendingCaret = React46.useRef(null);
7247
+ React46.useLayoutEffect(() => {
7195
7248
  const root = boxRef.current;
7196
7249
  if (!root || composing.current) return;
7197
7250
  const active = document.activeElement === root || root.contains(document.activeElement);
@@ -7200,7 +7253,7 @@ var MarkdownEditor = React45.forwardRef(function MarkdownEditor2({
7200
7253
  pendingCaret.current = null;
7201
7254
  if (active && caret != null) placeCaret(root, caret);
7202
7255
  }, [value]);
7203
- React45.useEffect(() => {
7256
+ React46.useEffect(() => {
7204
7257
  if (autoFocus && boxRef.current) boxRef.current.focus();
7205
7258
  }, [autoFocus]);
7206
7259
  const caretNow = () => {
@@ -7267,8 +7320,8 @@ var MarkdownEditor = React45.forwardRef(function MarkdownEditor2({
7267
7320
  api.replaceRange(from, to, next, from + next.length);
7268
7321
  }
7269
7322
  };
7270
- React45.useImperativeHandle(ref, () => api);
7271
- const caretAtKeydown = React45.useRef(-1);
7323
+ React46.useImperativeHandle(ref, () => api);
7324
+ const caretAtKeydown = React46.useRef(-1);
7272
7325
  function detect(text, caret) {
7273
7326
  if (!onTrigger) return;
7274
7327
  const upto = text.slice(0, caret);
@@ -7421,7 +7474,7 @@ var MarkdownEditor = React45.forwardRef(function MarkdownEditor2({
7421
7474
  });
7422
7475
 
7423
7476
  // src/components/forms/CodeEditor.tsx
7424
- import * as React46 from "react";
7477
+ import * as React47 from "react";
7425
7478
  import { EditorView, keymap, lineNumbers, placeholder as cmPlaceholder, drawSelection, Decoration } from "@codemirror/view";
7426
7479
  import { EditorState, StateEffect, StateField, Compartment } from "@codemirror/state";
7427
7480
  import { defaultKeymap, history, historyKeymap, indentMore, indentLess } from "@codemirror/commands";
@@ -7525,16 +7578,16 @@ function CodeEditor({
7525
7578
  const fieldId = useFieldId(id);
7526
7579
  const descId = fieldId + "-desc";
7527
7580
  const liveId = fieldId + "-live";
7528
- const hostRef = React46.useRef(null);
7529
- const viewRef = React46.useRef(null);
7530
- const valueRef = React46.useRef(value);
7531
- const onChangeRef = React46.useRef(onChange);
7581
+ const hostRef = React47.useRef(null);
7582
+ const viewRef = React47.useRef(null);
7583
+ const valueRef = React47.useRef(value);
7584
+ const onChangeRef = React47.useRef(onChange);
7532
7585
  onChangeRef.current = onChange;
7533
- const editableCompartment = React46.useRef(new Compartment()).current;
7534
- const attributesCompartment = React46.useRef(new Compartment()).current;
7535
- const errorRef = React46.useRef(error);
7586
+ const editableCompartment = React47.useRef(new Compartment()).current;
7587
+ const attributesCompartment = React47.useRef(new Compartment()).current;
7588
+ const errorRef = React47.useRef(error);
7536
7589
  errorRef.current = error;
7537
- const diagnosticsCountRef = React46.useRef(diagnostics.length);
7590
+ const diagnosticsCountRef = React47.useRef(diagnostics.length);
7538
7591
  diagnosticsCountRef.current = diagnostics.length;
7539
7592
  function contentAttributes() {
7540
7593
  return {
@@ -7544,9 +7597,9 @@ function CodeEditor({
7544
7597
  ...label ? { "aria-label": label } : {}
7545
7598
  };
7546
7599
  }
7547
- React46.useEffect(() => {
7548
- const host = hostRef.current;
7549
- if (!host) return;
7600
+ React47.useEffect(() => {
7601
+ const host2 = hostRef.current;
7602
+ if (!host2) return;
7550
7603
  const updateListener = EditorView.updateListener.of((update) => {
7551
7604
  if (!update.docChanged) return;
7552
7605
  const next = update.state.doc.toString();
@@ -7578,7 +7631,7 @@ function CodeEditor({
7578
7631
  attributesCompartment.of(EditorView.contentAttributes.of(contentAttributes()))
7579
7632
  ]
7580
7633
  });
7581
- const view = new EditorView({ state, parent: host });
7634
+ const view = new EditorView({ state, parent: host2 });
7582
7635
  viewRef.current = view;
7583
7636
  if (autoFocus) view.focus();
7584
7637
  return () => {
@@ -7586,7 +7639,7 @@ function CodeEditor({
7586
7639
  viewRef.current = null;
7587
7640
  };
7588
7641
  }, []);
7589
- React46.useEffect(() => {
7642
+ React47.useEffect(() => {
7590
7643
  const view = viewRef.current;
7591
7644
  if (!view) return;
7592
7645
  const current2 = view.state.doc.toString();
@@ -7595,12 +7648,12 @@ function CodeEditor({
7595
7648
  }
7596
7649
  valueRef.current = value;
7597
7650
  }, [value]);
7598
- React46.useEffect(() => {
7651
+ React47.useEffect(() => {
7599
7652
  const view = viewRef.current;
7600
7653
  if (!view) return;
7601
7654
  view.dispatch({ effects: editableCompartment.reconfigure(EditorView.editable.of(!disabled)) });
7602
7655
  }, [disabled, editableCompartment]);
7603
- React46.useEffect(() => {
7656
+ React47.useEffect(() => {
7604
7657
  const view = viewRef.current;
7605
7658
  if (!view) return;
7606
7659
  view.dispatch({
@@ -7658,16 +7711,16 @@ function CodeEditor({
7658
7711
  }
7659
7712
 
7660
7713
  // src/components/platform/AccountMenu.tsx
7661
- import * as React48 from "react";
7714
+ import * as React49 from "react";
7662
7715
 
7663
7716
  // src/kits/sessionContext.tsx
7664
- import * as React47 from "react";
7665
- var SessionContext = React47.createContext(null);
7717
+ import * as React48 from "react";
7718
+ var SessionContext = React48.createContext(null);
7666
7719
  function SessionProvider({ value, children }) {
7667
- return React47.createElement(SessionContext.Provider, { value }, children);
7720
+ return React48.createElement(SessionContext.Provider, { value }, children);
7668
7721
  }
7669
7722
  function useSessionContext() {
7670
- const ctx = React47.useContext(SessionContext);
7723
+ const ctx = React48.useContext(SessionContext);
7671
7724
  if (!ctx) {
7672
7725
  throw new Error(
7673
7726
  "useSessionContext() was called outside a <SessionProvider>. Wrap your app root in <SessionProvider value={...}> with your real session, or \u2014 in the docs site or a demo \u2014 in <DemoSessionProvider>, before rendering AccountMenu, Gate, ProfilePage or AppSwitcher."
@@ -7707,11 +7760,11 @@ function AccountMenu({
7707
7760
  ...rest
7708
7761
  }) {
7709
7762
  const { user, roles, can: can2, signOut: ctxSignOut, demo, pending } = useSessionContext();
7710
- const [open2, setOpen] = React48.useState(false);
7711
- const [switching, setSwitching] = React48.useState(false);
7712
- const [signingOut, setSigningOut] = React48.useState(false);
7713
- const [signOutError, setSignOutError] = React48.useState(null);
7714
- const ref = React48.useRef(null);
7763
+ const [open2, setOpen] = React49.useState(false);
7764
+ const [switching, setSwitching] = React49.useState(false);
7765
+ const [signingOut, setSigningOut] = React49.useState(false);
7766
+ const [signOutError, setSignOutError] = React49.useState(null);
7767
+ const ref = React49.useRef(null);
7715
7768
  const visibleLinks = links.filter((l) => !l.perm || !pending && can2(l.perm));
7716
7769
  const visibleGroups = groups.map((g) => ({ label: g.label, links: g.links.filter((l) => !l.perm || !pending && can2(l.perm)) })).filter((g) => g.links.length);
7717
7770
  const closeMenu = () => {
@@ -7836,13 +7889,13 @@ function AccountMenu({
7836
7889
  }
7837
7890
 
7838
7891
  // src/components/platform/AppSwitcher.tsx
7839
- import * as React49 from "react";
7892
+ import * as React50 from "react";
7840
7893
  import { jsx as jsx76, jsxs as jsxs67 } from "react/jsx-runtime";
7841
7894
  function AppSwitcher({ apps: appsProp, onNavigate, className = "" }) {
7842
7895
  const { apps: contextApps } = useSessionContext();
7843
7896
  const apps = appsProp ?? contextApps ?? [];
7844
- const [open2, setOpen] = React49.useState(false);
7845
- const anchorRef = React49.useRef(null);
7897
+ const [open2, setOpen] = React50.useState(false);
7898
+ const anchorRef = React50.useRef(null);
7846
7899
  if (!apps.length) return null;
7847
7900
  const items = apps.map((app) => ({
7848
7901
  id: app.key,
@@ -7856,7 +7909,7 @@ function AppSwitcher({ apps: appsProp, onNavigate, className = "" }) {
7856
7909
  window.location.href = app.url;
7857
7910
  }
7858
7911
  }));
7859
- return /* @__PURE__ */ jsxs67(React49.Fragment, { children: [
7912
+ return /* @__PURE__ */ jsxs67(React50.Fragment, { children: [
7860
7913
  /* @__PURE__ */ jsx76("span", { ref: anchorRef, className: ["fd-appswitch-anchor", className].filter(Boolean).join(" "), style: { display: "inline-flex" }, children: /* @__PURE__ */ jsx76(
7861
7914
  IconButton,
7862
7915
  {
@@ -7885,10 +7938,10 @@ function AppSwitcher({ apps: appsProp, onNavigate, className = "" }) {
7885
7938
  }
7886
7939
 
7887
7940
  // src/components/platform/AppearanceMenu.tsx
7888
- import * as React51 from "react";
7941
+ import * as React52 from "react";
7889
7942
 
7890
7943
  // src/kits/appearance.ts
7891
- import * as React50 from "react";
7944
+ import * as React51 from "react";
7892
7945
  var DEFAULT_STORAGE_KEY = "fd-appearance";
7893
7946
  var DEFAULT_PREFS = {
7894
7947
  theme: "system",
@@ -7983,11 +8036,11 @@ function applyPrefs(prefs, root = document.documentElement) {
7983
8036
  else root.removeAttribute("data-motion");
7984
8037
  }
7985
8038
  function useAppearancePrefs(store) {
7986
- const prefs = React50.useSyncExternalStore(store.subscribe, store.getSnapshot);
7987
- React50.useEffect(() => {
8039
+ const prefs = React51.useSyncExternalStore(store.subscribe, store.getSnapshot);
8040
+ React51.useEffect(() => {
7988
8041
  applyPrefs(prefs);
7989
8042
  }, [prefs]);
7990
- React50.useEffect(() => {
8043
+ React51.useEffect(() => {
7991
8044
  if (prefs.theme !== "system" || typeof window === "undefined" || typeof window.matchMedia !== "function") {
7992
8045
  return;
7993
8046
  }
@@ -7996,7 +8049,7 @@ function useAppearancePrefs(store) {
7996
8049
  mq.addEventListener("change", onChange);
7997
8050
  return () => mq.removeEventListener("change", onChange);
7998
8051
  }, [prefs]);
7999
- const update = React50.useCallback(
8052
+ const update = React51.useCallback(
8000
8053
  (patch) => {
8001
8054
  store.write({ ...store.getSnapshot(), ...patch });
8002
8055
  },
@@ -8019,15 +8072,15 @@ var TEXT_SCALE_OPTIONS = [
8019
8072
  { value: "xl", label: "XL" }
8020
8073
  ];
8021
8074
  function AppearanceMenu({ className = "", store: storeProp, storageKey, storage, defaults }) {
8022
- const store = React51.useMemo(
8075
+ const store = React52.useMemo(
8023
8076
  () => storeProp ?? createLocalStorageAppearanceStore({ storageKey, storage, defaults }),
8024
8077
  [storeProp, storageKey, storage, defaults]
8025
8078
  );
8026
8079
  const [prefs, update] = useAppearancePrefs(store);
8027
- const [open2, setOpen] = React51.useState(false);
8028
- const anchorRef = React51.useRef(null);
8080
+ const [open2, setOpen] = React52.useState(false);
8081
+ const anchorRef = React52.useRef(null);
8029
8082
  const patch = (p) => update(p);
8030
- return /* @__PURE__ */ jsxs68(React51.Fragment, { children: [
8083
+ return /* @__PURE__ */ jsxs68(React52.Fragment, { children: [
8031
8084
  /* @__PURE__ */ jsx77("span", { ref: anchorRef, className: ["fd-appearance-anchor", className].filter(Boolean).join(" "), style: { display: "inline-flex" }, children: /* @__PURE__ */ jsx77(
8032
8085
  IconButton,
8033
8086
  {
@@ -8096,14 +8149,14 @@ function AppearanceMenu({ className = "", store: storeProp, storageKey, storage,
8096
8149
  }
8097
8150
 
8098
8151
  // src/components/platform/ApiSpecBrowser.tsx
8099
- import * as React52 from "react";
8152
+ import * as React53 from "react";
8100
8153
  import { jsx as jsx78, jsxs as jsxs69 } from "react/jsx-runtime";
8101
8154
  var METHOD_TONE = { GET: "success", POST: "info", PATCH: "warning", PUT: "warning", DELETE: "danger" };
8102
8155
  function Json({ obj }) {
8103
8156
  return /* @__PURE__ */ jsx78("pre", { className: "fd-json", children: JSON.stringify(obj, null, 2) });
8104
8157
  }
8105
8158
  function Endpoint({ s, onRequest }) {
8106
- const [tried, setTried] = React52.useState(null);
8159
+ const [tried, setTried] = React53.useState(null);
8107
8160
  const run = async () => {
8108
8161
  setTried("busy");
8109
8162
  const t0 = (window.performance || Date).now();
@@ -8176,10 +8229,10 @@ function ApiSpecBrowser({
8176
8229
  className = "",
8177
8230
  ...rest
8178
8231
  }) {
8179
- const [q, setQ] = React52.useState("");
8180
- const [method, setMethod] = React52.useState(null);
8181
- const [mod, setMod] = React52.useState(null);
8182
- const [listOnly, setListOnly] = React52.useState(false);
8232
+ const [q, setQ] = React53.useState("");
8233
+ const [method, setMethod] = React53.useState(null);
8234
+ const [mod, setMod] = React53.useState(null);
8235
+ const [listOnly, setListOnly] = React53.useState(false);
8183
8236
  const activeModule = modules && modules.find((m) => m.id === mod);
8184
8237
  const hits = spec.filter((s) => (!method || s.method === method) && (!listOnly || s.isList) && (!activeModule || activeModule.endpoints.indexOf(s.id) >= 0) && (!q || (s.path + " " + s.title + " " + s.purpose + " " + (s.usedBy || []).join(" ")).toLowerCase().includes(q.toLowerCase())));
8185
8238
  const effGroups = groups && groups.length ? groups : [["All endpoints", spec.map((s) => s.id)]];
@@ -8258,7 +8311,7 @@ function ApiSpecBrowser({
8258
8311
  }
8259
8312
 
8260
8313
  // src/components/platform/ProfilePage.tsx
8261
- import * as React53 from "react";
8314
+ import * as React54 from "react";
8262
8315
  import { jsx as jsx79, jsxs as jsxs70 } from "react/jsx-runtime";
8263
8316
  function fieldInitialValue(field, user) {
8264
8317
  if (field.value) return field.value(user);
@@ -8294,21 +8347,21 @@ function ProfilePage({
8294
8347
  }) {
8295
8348
  const { user: sessionUser, roles, permissions, saveProfile: saveProfile2 } = useSessionContext();
8296
8349
  const user = userProp || sessionUser;
8297
- const initialFieldValues = React53.useMemo(() => {
8350
+ const initialFieldValues = React54.useMemo(() => {
8298
8351
  const values2 = {};
8299
8352
  for (const field of fields) values2[field.key] = fieldInitialValue(field, user);
8300
8353
  return values2;
8301
8354
  }, [user.id, fields]);
8302
- const initialNotify = React53.useMemo(() => {
8355
+ const initialNotify = React54.useMemo(() => {
8303
8356
  const values2 = {};
8304
8357
  for (const n of notifications) values2[n.key] = !!user.notify?.[n.key];
8305
8358
  return values2;
8306
8359
  }, [user.id, notifications]);
8307
- const [values, setValues] = React53.useState(initialFieldValues);
8308
- const [notify, setNotify] = React53.useState(initialNotify);
8309
- const [saving, setSaving] = React53.useState(false);
8310
- const [saved, setSaved] = React53.useState(false);
8311
- const [prevUserId, setPrevUserId] = React53.useState(user.id);
8360
+ const [values, setValues] = React54.useState(initialFieldValues);
8361
+ const [notify, setNotify] = React54.useState(initialNotify);
8362
+ const [saving, setSaving] = React54.useState(false);
8363
+ const [saved, setSaved] = React54.useState(false);
8364
+ const [prevUserId, setPrevUserId] = React54.useState(user.id);
8312
8365
  if (user.id !== prevUserId) {
8313
8366
  setPrevUserId(user.id);
8314
8367
  setValues(initialFieldValues);
@@ -8496,11 +8549,11 @@ function ProfilePage({
8496
8549
  }
8497
8550
 
8498
8551
  // src/components/platform/SignInPage.tsx
8499
- import * as React54 from "react";
8552
+ import * as React55 from "react";
8500
8553
  import { Fragment as Fragment19, jsx as jsx80, jsxs as jsxs71 } from "react/jsx-runtime";
8501
8554
  function SignInPage({ productName, onSignIn, continueAs, error }) {
8502
- const [signingIn, setSigningIn] = React54.useState(false);
8503
- const [resuming, setResuming] = React54.useState(false);
8555
+ const [signingIn, setSigningIn] = React55.useState(false);
8556
+ const [resuming, setResuming] = React55.useState(false);
8504
8557
  function handleSignIn() {
8505
8558
  setSigningIn(true);
8506
8559
  onSignIn();
@@ -8689,10 +8742,10 @@ function GoogleGlyph() {
8689
8742
  }
8690
8743
 
8691
8744
  // src/components/platform/RoadmapTimeline.tsx
8692
- import * as React57 from "react";
8745
+ import * as React58 from "react";
8693
8746
 
8694
8747
  // src/kits/session.ts
8695
- import * as React55 from "react";
8748
+ import * as React56 from "react";
8696
8749
  var PERMISSION_CATALOG = [
8697
8750
  { group: "Plans", items: [
8698
8751
  { key: "plan.view", label: "View plans", detail: "Read any plan in the workspace." },
@@ -10259,8 +10312,8 @@ function roadmap(overrides) {
10259
10312
  };
10260
10313
  }
10261
10314
  function useSession() {
10262
- const [s, setS] = React55.useState(getSession);
10263
- React55.useEffect(() => subscribe(setS), []);
10315
+ const [s, setS] = React56.useState(getSession);
10316
+ React56.useEffect(() => subscribe(setS), []);
10264
10317
  return s;
10265
10318
  }
10266
10319
  var SessionKit = {
@@ -10293,7 +10346,7 @@ var SessionKit = {
10293
10346
  };
10294
10347
  function DemoSessionProvider({ children }) {
10295
10348
  const session = useSession();
10296
- const value = React55.useMemo(
10349
+ const value = React56.useMemo(
10297
10350
  () => ({
10298
10351
  user: session.user,
10299
10352
  roles: session.roles,
@@ -10309,11 +10362,11 @@ function DemoSessionProvider({ children }) {
10309
10362
  }),
10310
10363
  [session]
10311
10364
  );
10312
- return React55.createElement(SessionProvider, { value }, children);
10365
+ return React56.createElement(SessionProvider, { value }, children);
10313
10366
  }
10314
10367
 
10315
10368
  // src/kits/runtime.ts
10316
- import * as React56 from "react";
10369
+ import * as React57 from "react";
10317
10370
  var WIRED_ENDPOINTS = [
10318
10371
  // Nothing yet. Every id below would come from a real service:
10319
10372
  // "plan.get", "placements.list", …
@@ -10484,8 +10537,8 @@ var RuntimeKit = {
10484
10537
  };
10485
10538
  RuntimeKit.declare(FEATURE_NEEDS);
10486
10539
  function useRuntimeMode() {
10487
- const [m, setM] = React56.useState(RuntimeKit.getMode());
10488
- React56.useEffect(() => RuntimeKit.subscribe(setM), []);
10540
+ const [m, setM] = React57.useState(RuntimeKit.getMode());
10541
+ React57.useEffect(() => RuntimeKit.subscribe(setM), []);
10489
10542
  return m;
10490
10543
  }
10491
10544
  function useFeatureStatus(key) {
@@ -10568,12 +10621,12 @@ function RoadmapCard({ item, byKey, onOpenFlag }) {
10568
10621
  }
10569
10622
  function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
10570
10623
  const session = SessionKit.useSession();
10571
- const [project, setProject] = React57.useState("");
10572
- const [q, setQ] = React57.useState("");
10573
- const scrollRef = React57.useRef(null);
10574
- const nowRef = React57.useRef(null);
10575
- const rm = React57.useMemo(() => SessionKit.roadmap({ isComplete: RuntimeKit.isComplete }), [session]);
10576
- const byKey = React57.useMemo(() => {
10624
+ const [project, setProject] = React58.useState("");
10625
+ const [q, setQ] = React58.useState("");
10626
+ const scrollRef = React58.useRef(null);
10627
+ const nowRef = React58.useRef(null);
10628
+ const rm = React58.useMemo(() => SessionKit.roadmap({ isComplete: RuntimeKit.isComplete }), [session]);
10629
+ const byKey = React58.useMemo(() => {
10577
10630
  const m = {};
10578
10631
  rm.items.forEach((i) => {
10579
10632
  m[i.key] = i;
@@ -10582,7 +10635,7 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
10582
10635
  }, [rm]);
10583
10636
  const items = rm.items.filter((i) => (!project || i.project === project) && (!q || (i.label + " " + i.description + " " + (i.backend || "") + " " + i.key).toLowerCase().includes(q.toLowerCase())));
10584
10637
  const projects = [...new Set(rm.items.map((i) => i.project))];
10585
- React57.useEffect(() => {
10638
+ React58.useEffect(() => {
10586
10639
  let raf1 = 0, raf2 = 0;
10587
10640
  const place = () => {
10588
10641
  const box = scrollRef.current, mark = nowRef.current;
@@ -10656,7 +10709,7 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
10656
10709
  lastPhase = item.phase;
10657
10710
  const inPhase = items.filter((i) => i.phase === item.phase).length;
10658
10711
  const isBoundary = n === firstPending;
10659
- return /* @__PURE__ */ jsxs72(React57.Fragment, { children: [
10712
+ return /* @__PURE__ */ jsxs72(React58.Fragment, { children: [
10660
10713
  showPhase ? /* @__PURE__ */ jsxs72("div", { className: "fd-rm-era", children: [
10661
10714
  /* @__PURE__ */ jsxs72("span", { className: "fd-row", style: { gap: 8, flexWrap: "wrap", alignItems: "baseline" }, children: [
10662
10715
  /* @__PURE__ */ jsx81("span", { style: { fontWeight: 700 }, children: item.phase === 0 ? "Shipped" : "Phase " + item.phase + " \u2014 " + item.phaseName }),
@@ -10700,8 +10753,8 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
10700
10753
  }
10701
10754
 
10702
10755
  // src/components/platform/ComingSoon.tsx
10703
- import * as React58 from "react";
10704
- import { createPortal as createPortal5 } from "react-dom";
10756
+ import * as React59 from "react";
10757
+ import { createPortal as createPortal6 } from "react-dom";
10705
10758
  import { Fragment as Fragment21, jsx as jsx82, jsxs as jsxs73 } from "react/jsx-runtime";
10706
10759
  var BYPASS_STORE = "fd.soon.bypass.v1";
10707
10760
  function readBypassed() {
@@ -10718,8 +10771,8 @@ function writeBypassed(list) {
10718
10771
  }
10719
10772
  }
10720
10773
  function useBypass(key) {
10721
- const [on, setOn] = React58.useState(() => !!key && readBypassed().indexOf(key) >= 0);
10722
- React58.useEffect(() => {
10774
+ const [on, setOn] = React59.useState(() => !!key && readBypassed().indexOf(key) >= 0);
10775
+ React59.useEffect(() => {
10723
10776
  setOn(!!key && readBypassed().indexOf(key) >= 0);
10724
10777
  }, [key]);
10725
10778
  const set = (next) => {
@@ -10766,9 +10819,9 @@ function SoonCard({ label, detail, backend, eta, effort, onRoadmap, allowed, onB
10766
10819
  ] });
10767
10820
  }
10768
10821
  function useHoverCard(open2) {
10769
- const anchor = React58.useRef(null);
10770
- const [pos, setPos] = React58.useState(null);
10771
- React58.useLayoutEffect(() => {
10822
+ const anchor = React59.useRef(null);
10823
+ const [pos, setPos] = React59.useState(null);
10824
+ React59.useLayoutEffect(() => {
10772
10825
  if (!open2 || !anchor.current) {
10773
10826
  setPos(null);
10774
10827
  return;
@@ -10895,12 +10948,12 @@ function ComingSoon({
10895
10948
  ] });
10896
10949
  }
10897
10950
  function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, onBypass, blur, tip, className, rest, children }) {
10898
- const [open2, setOpen] = React58.useState(false);
10951
+ const [open2, setOpen] = React59.useState(false);
10899
10952
  const [anchor, pos] = useHoverCard(open2);
10900
- const hoverCardRef = React58.useRef(null);
10953
+ const hoverCardRef = React59.useRef(null);
10901
10954
  const hoverLayer = useStackedLayer({ active: open2, containerRef: hoverCardRef, returnFocus: false });
10902
10955
  const zIndex = useLayerZIndex(hoverLayer);
10903
- const close2 = React58.useRef(null);
10956
+ const close2 = React59.useRef(null);
10904
10957
  const show = () => {
10905
10958
  if (close2.current) {
10906
10959
  clearTimeout(close2.current);
@@ -10916,7 +10969,7 @@ function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, o
10916
10969
  setOpen(false);
10917
10970
  }, 140);
10918
10971
  };
10919
- React58.useEffect(() => () => {
10972
+ React59.useEffect(() => () => {
10920
10973
  if (close2.current) clearTimeout(close2.current);
10921
10974
  }, []);
10922
10975
  return /* @__PURE__ */ jsxs73(
@@ -10945,7 +10998,7 @@ function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, o
10945
10998
  children: /* @__PURE__ */ jsx82("i", { className: "ph ph-traffic-cone", "aria-hidden": "true" })
10946
10999
  }
10947
11000
  ),
10948
- open2 && pos ? createPortal5(
11001
+ open2 && pos ? createPortal6(
10949
11002
  /* @__PURE__ */ jsx82(
10950
11003
  "div",
10951
11004
  {
@@ -11368,7 +11421,7 @@ function SaturationDistribution({ campuses = [], floorBand, floorScore, onSelect
11368
11421
  }
11369
11422
 
11370
11423
  // src/components/planner/MixGap.tsx
11371
- import * as React59 from "react";
11424
+ import * as React60 from "react";
11372
11425
  import { Fragment as Fragment23, jsx as jsx87, jsxs as jsxs78 } from "react/jsx-runtime";
11373
11426
  var MIX_GAP_LAYOUT = {
11374
11427
  trackHeight: 30,
@@ -11383,7 +11436,7 @@ function mixGapOffset(value, max) {
11383
11436
  }
11384
11437
  function MixGap({ rows = [], loading = false, className = "" }) {
11385
11438
  const max = Math.max(1, ...rows.flatMap((r) => [r.target, r.realized]));
11386
- const [hover, setHover] = React59.useState(null);
11439
+ const [hover, setHover] = React60.useState(null);
11387
11440
  const toneOf = (gap) => gap >= -1 ? "ok" : gap >= -4 ? "warn" : "danger";
11388
11441
  const TONE = { ok: "var(--ok-solid)", warn: "var(--warn-solid)", danger: "var(--danger-solid)" };
11389
11442
  const { trackHeight, barHeight, targetWidth, labelGap } = MIX_GAP_LAYOUT;
@@ -11526,7 +11579,7 @@ function ChannelContribution({
11526
11579
  }
11527
11580
 
11528
11581
  // src/components/planner/BudgetReallocator.tsx
11529
- import * as React60 from "react";
11582
+ import * as React61 from "react";
11530
11583
  import { Fragment as Fragment24, jsx as jsx89, jsxs as jsxs80 } from "react/jsx-runtime";
11531
11584
  var bandFor = (crp) => crp >= 200 ? "dominant" : crp >= 100 ? "strong" : crp >= 50 ? "adequate" : "weak";
11532
11585
  function BudgetReallocator({
@@ -11542,8 +11595,8 @@ function BudgetReallocator({
11542
11595
  onCancel,
11543
11596
  className = ""
11544
11597
  }) {
11545
- const [draft, setDraft] = React60.useState(spend);
11546
- React60.useEffect(() => setDraft(spend), [spend]);
11598
+ const [draft, setDraft] = React61.useState(spend);
11599
+ React61.useEffect(() => setDraft(spend), [spend]);
11547
11600
  const dirty = draft !== spend;
11548
11601
  const nextCrp = scoreFor ? scoreFor(draft) : crp;
11549
11602
  const nextBand = bandFor(nextCrp);
@@ -11558,10 +11611,10 @@ function BudgetReallocator({
11558
11611
  setDraft(spend);
11559
11612
  if (onCancel) onCancel();
11560
11613
  };
11561
- const trackRef = React60.useRef(null);
11562
- const chipRef = React60.useRef(null);
11563
- const [chipLeft, setChipLeft] = React60.useState(null);
11564
- React60.useLayoutEffect(() => {
11614
+ const trackRef = React61.useRef(null);
11615
+ const chipRef = React61.useRef(null);
11616
+ const [chipLeft, setChipLeft] = React61.useState(null);
11617
+ React61.useLayoutEffect(() => {
11565
11618
  const track = trackRef.current;
11566
11619
  if (!dirty || !track) {
11567
11620
  setChipLeft(null);
@@ -11749,7 +11802,7 @@ function ImportanceTag({ level, showLabel = true, size = "sm", className = "", d
11749
11802
  }
11750
11803
 
11751
11804
  // src/components/planner/PreferenceMeter.tsx
11752
- import * as React61 from "react";
11805
+ import * as React62 from "react";
11753
11806
  import { jsx as jsx92, jsxs as jsxs83 } from "react/jsx-runtime";
11754
11807
  function preferenceScore(criteria) {
11755
11808
  const earned = criteria.reduce((n, c) => n + (Number(c.earned) || 0), 0);
@@ -11779,7 +11832,7 @@ function PreferenceMeter({
11779
11832
  className = ""
11780
11833
  }) {
11781
11834
  const value = score == null ? preferenceScore(criteria) : score;
11782
- const segments = React61.useMemo(() => preferenceSegments(criteria), [criteria]);
11835
+ const segments = React62.useMemo(() => preferenceSegments(criteria), [criteria]);
11783
11836
  return /* @__PURE__ */ jsx92(
11784
11837
  ScoreMeter,
11785
11838
  {
@@ -11818,10 +11871,10 @@ function PreferenceMeter({
11818
11871
  }
11819
11872
 
11820
11873
  // src/components/chat/AgentChatPanel.tsx
11821
- import * as React67 from "react";
11874
+ import * as React68 from "react";
11822
11875
 
11823
11876
  // src/components/chat/chatEngine.ts
11824
- import * as React62 from "react";
11877
+ import * as React63 from "react";
11825
11878
  var CHAT_UNAVAILABLE = "chat_unavailable";
11826
11879
  var JOB_PENDING = ["queued", "running"];
11827
11880
  var JOB_SUCCESS = ["completed", "recovered"];
@@ -11875,22 +11928,22 @@ function useChatEngine(opts) {
11875
11928
  onClear,
11876
11929
  onFeedback
11877
11930
  } = opts || {};
11878
- const [status, setStatus] = React62.useState("idle");
11879
- const [threadId, setThreadId] = React62.useState(null);
11880
- const [messages, setMessages] = React62.useState([]);
11881
- const [queue, setQueue] = React62.useState([]);
11882
- const [fatal, setFatal] = React62.useState(null);
11883
- const [busy, setBusy] = React62.useState(false);
11884
- const [turnStartedAt, setTurnStartedAt] = React62.useState(null);
11885
- const listRef = React62.useRef([]);
11886
- const queueRef = React62.useRef([]);
11887
- const busyRef = React62.useRef(false);
11888
- const stoppedRef = React62.useRef(false);
11889
- const abortRef = React62.useRef(null);
11890
- const serverCount = React62.useRef(0);
11891
- const threadRef = React62.useRef(null);
11892
- const mounted = React62.useRef(true);
11893
- React62.useEffect(() => {
11931
+ const [status, setStatus] = React63.useState("idle");
11932
+ const [threadId, setThreadId] = React63.useState(null);
11933
+ const [messages, setMessages] = React63.useState([]);
11934
+ const [queue, setQueue] = React63.useState([]);
11935
+ const [fatal, setFatal] = React63.useState(null);
11936
+ const [busy, setBusy] = React63.useState(false);
11937
+ const [turnStartedAt, setTurnStartedAt] = React63.useState(null);
11938
+ const listRef = React63.useRef([]);
11939
+ const queueRef = React63.useRef([]);
11940
+ const busyRef = React63.useRef(false);
11941
+ const stoppedRef = React63.useRef(false);
11942
+ const abortRef = React63.useRef(null);
11943
+ const serverCount = React63.useRef(0);
11944
+ const threadRef = React63.useRef(null);
11945
+ const mounted = React63.useRef(true);
11946
+ React63.useEffect(() => {
11894
11947
  mounted.current = true;
11895
11948
  return () => {
11896
11949
  mounted.current = false;
@@ -11912,14 +11965,14 @@ function useChatEngine(opts) {
11912
11965
  }
11913
11966
  return false;
11914
11967
  };
11915
- const loadThread = React62.useCallback(async (id) => {
11968
+ const loadThread = React63.useCallback(async (id) => {
11916
11969
  const data = await apiAdapter.getThread(id);
11917
11970
  const list = [...data && data.messages || []];
11918
11971
  serverCount.current = list.length;
11919
11972
  commit(list);
11920
11973
  return list;
11921
11974
  }, [apiAdapter]);
11922
- React62.useEffect(() => {
11975
+ React63.useEffect(() => {
11923
11976
  if (!apiAdapter) {
11924
11977
  setStatus("idle");
11925
11978
  setFatal(null);
@@ -12132,7 +12185,7 @@ function useChatEngine(opts) {
12132
12185
  await dispatchTurn(turn);
12133
12186
  }
12134
12187
  }
12135
- const send = React62.useCallback((text, attachments) => {
12188
+ const send = React63.useCallback((text, attachments) => {
12136
12189
  const body = (text || "").trim();
12137
12190
  if (!body && !(attachments && attachments.length)) return;
12138
12191
  if (status === "disconnected") return;
@@ -12142,7 +12195,7 @@ function useChatEngine(opts) {
12142
12195
  stoppedRef.current = false;
12143
12196
  drain();
12144
12197
  }, [status]);
12145
- const stop = React62.useCallback(() => {
12198
+ const stop = React63.useCallback(() => {
12146
12199
  stoppedRef.current = true;
12147
12200
  const ac = abortRef.current;
12148
12201
  if (ac) {
@@ -12161,11 +12214,11 @@ function useChatEngine(opts) {
12161
12214
  store.del(STORAGE_PREFIX + threadRef.current);
12162
12215
  }
12163
12216
  }, [apiAdapter]);
12164
- const removeQueued = React62.useCallback((id) => {
12217
+ const removeQueued = React63.useCallback((id) => {
12165
12218
  queueRef.current = queueRef.current.filter((t) => t.id !== id);
12166
12219
  setQueue(queueRef.current.slice());
12167
12220
  }, []);
12168
- const retry = React62.useCallback(() => {
12221
+ const retry = React63.useCallback(() => {
12169
12222
  const list = listRef.current;
12170
12223
  let at = -1;
12171
12224
  for (let i = list.length - 1; i >= 0; i--) if (list[i].role === "user") {
@@ -12181,19 +12234,19 @@ function useChatEngine(opts) {
12181
12234
  setQueue(queueRef.current.slice());
12182
12235
  drain();
12183
12236
  }, []);
12184
- const clear = React62.useCallback(() => {
12237
+ const clear = React63.useCallback(() => {
12185
12238
  commit([]);
12186
12239
  serverCount.current = 0;
12187
12240
  queueRef.current = [];
12188
12241
  setQueue([]);
12189
12242
  onClear && onClear();
12190
12243
  }, [onClear]);
12191
- const setFeedback = React62.useCallback((id, value) => {
12244
+ const setFeedback = React63.useCallback((id, value) => {
12192
12245
  patch(id, (m) => ({ feedback: m.feedback === value ? null : value }));
12193
12246
  const msg = listRef.current.find((m) => m.id === id);
12194
12247
  onFeedback && onFeedback({ message: msg, feedback: msg ? msg.feedback : value });
12195
12248
  }, [onFeedback]);
12196
- const reload = React62.useCallback(async () => {
12249
+ const reload = React63.useCallback(async () => {
12197
12250
  if (!threadRef.current) return;
12198
12251
  setStatus("loading");
12199
12252
  try {
@@ -12231,10 +12284,10 @@ var ChatKit = {
12231
12284
  };
12232
12285
 
12233
12286
  // src/components/chat/ChatTranscript.tsx
12234
- import * as React64 from "react";
12287
+ import * as React65 from "react";
12235
12288
 
12236
12289
  // src/components/chat/ChatTurn.tsx
12237
- import * as React63 from "react";
12290
+ import * as React64 from "react";
12238
12291
  import { jsx as jsx93, jsxs as jsxs84 } from "react/jsx-runtime";
12239
12292
  function JsonView({ value }) {
12240
12293
  let text;
@@ -12271,7 +12324,7 @@ function PacketCard({ packet, schema, render, onApply, applied }) {
12271
12324
  ] });
12272
12325
  }
12273
12326
  function ThinkingBlock({ text, durationMs, streaming, defaultOpen = false }) {
12274
- const [open2, setOpen] = React63.useState(defaultOpen);
12327
+ const [open2, setOpen] = React64.useState(defaultOpen);
12275
12328
  if (!text) return null;
12276
12329
  return /* @__PURE__ */ jsxs84("div", { className: "fdc-think" + (open2 ? " is-open" : ""), children: [
12277
12330
  /* @__PURE__ */ jsxs84("button", { type: "button", className: "fdc-think-head", onClick: () => setOpen((v) => !v), "aria-expanded": open2, children: [
@@ -12288,7 +12341,7 @@ function ThinkingBlock({ text, durationMs, streaming, defaultOpen = false }) {
12288
12341
  ] });
12289
12342
  }
12290
12343
  function Citations({ items = [], onOpen }) {
12291
- const [open2, setOpen] = React63.useState(false);
12344
+ const [open2, setOpen] = React64.useState(false);
12292
12345
  if (!items.length) return null;
12293
12346
  return /* @__PURE__ */ jsxs84("div", { className: "fdc-cites", children: [
12294
12347
  /* @__PURE__ */ jsxs84("button", { type: "button", className: "fdc-cites-head", onClick: () => setOpen((v) => !v), "aria-expanded": open2, children: [
@@ -12314,7 +12367,7 @@ function clampText(text, max) {
12314
12367
  return (at > max * 0.6 ? cut.slice(0, at) : cut).trimEnd() + "\u2026";
12315
12368
  }
12316
12369
  function MessageBody({ message: m, ctx }) {
12317
- const [expanded, setExpanded] = React63.useState(false);
12370
+ const [expanded, setExpanded] = React64.useState(false);
12318
12371
  const isUser = m.role === "user";
12319
12372
  const raw = m.text || "";
12320
12373
  const clamped = !expanded && !m.streaming ? clampText(raw, ctx.maxVisibleChars) : null;
@@ -12394,7 +12447,7 @@ function RunActions({ group, ctx }) {
12394
12447
  ] }),
12395
12448
  isAssistant && ctx.onRetry ? /* @__PURE__ */ jsx93("button", { type: "button", className: "fdc-act", onClick: ctx.onRetry, "aria-label": "Retry this turn", children: /* @__PURE__ */ jsx93("i", { className: "ph ph-arrow-clockwise", "aria-hidden": "true" }) }) : null,
12396
12449
  group.role === "user" && ctx.onEdit ? /* @__PURE__ */ jsx93("button", { type: "button", className: "fdc-act", onClick: () => ctx.onEdit(last), "aria-label": "Edit and resend", children: /* @__PURE__ */ jsx93("i", { className: "ph ph-pencil-simple", "aria-hidden": "true" }) }) : null,
12397
- isAssistant && ctx.onFeedback ? /* @__PURE__ */ jsxs84(React63.Fragment, { children: [
12450
+ isAssistant && ctx.onFeedback ? /* @__PURE__ */ jsxs84(React64.Fragment, { children: [
12398
12451
  /* @__PURE__ */ jsx93("button", { type: "button", className: "fdc-act" + (fb === "up" ? " is-on" : ""), onClick: () => ctx.onFeedback(last.id, "up"), "aria-pressed": fb === "up", "aria-label": "Good response", children: /* @__PURE__ */ jsx93("i", { className: "ph ph-thumbs-up", "aria-hidden": "true" }) }),
12399
12452
  /* @__PURE__ */ jsx93("button", { type: "button", className: "fdc-act" + (fb === "down" ? " is-on" : ""), onClick: () => ctx.onFeedback(last.id, "down"), "aria-pressed": fb === "down", "aria-label": "Bad response", children: /* @__PURE__ */ jsx93("i", { className: "ph ph-thumbs-down", "aria-hidden": "true" }) })
12400
12453
  ] }) : null,
@@ -12489,10 +12542,10 @@ function ChatTranscript({
12489
12542
  renderEmpty,
12490
12543
  className = ""
12491
12544
  }) {
12492
- const scroller = React64.useRef(null);
12493
- const stick = React64.useRef(true);
12494
- const [pill, setPill] = React64.useState(0);
12495
- const seen = React64.useRef(0);
12545
+ const scroller = React65.useRef(null);
12546
+ const stick = React65.useRef(true);
12547
+ const [pill, setPill] = React65.useState(0);
12548
+ const seen = React65.useRef(0);
12496
12549
  const toBottom = (smooth) => {
12497
12550
  const el = scroller.current;
12498
12551
  if (!el) return;
@@ -12511,7 +12564,7 @@ function ChatTranscript({
12511
12564
  seen.current = messages.length;
12512
12565
  }
12513
12566
  };
12514
- React64.useLayoutEffect(() => {
12567
+ React65.useLayoutEffect(() => {
12515
12568
  const el = scroller.current;
12516
12569
  if (!el) return;
12517
12570
  if (stick.current) {
@@ -12519,7 +12572,7 @@ function ChatTranscript({
12519
12572
  seen.current = messages.length;
12520
12573
  } else setPill(Math.max(0, messages.length - seen.current));
12521
12574
  }, [messages]);
12522
- React64.useEffect(() => {
12575
+ React65.useEffect(() => {
12523
12576
  const el = scroller.current;
12524
12577
  const inner = el && el.firstChild;
12525
12578
  if (!el || !inner || typeof ResizeObserver === "undefined") return;
@@ -12529,7 +12582,7 @@ function ChatTranscript({
12529
12582
  ro.observe(inner);
12530
12583
  return () => ro.disconnect();
12531
12584
  }, []);
12532
- const groups = React64.useMemo(() => groupMessages(messages), [messages]);
12585
+ const groups = React65.useMemo(() => groupMessages(messages), [messages]);
12533
12586
  const empty = !messages.length && status === "ready";
12534
12587
  return /* @__PURE__ */ jsxs85("div", { className: ["fdc-scroll", className].filter(Boolean).join(" "), ref: scroller, onScroll, children: [
12535
12588
  /* @__PURE__ */ jsxs85("div", { className: "fdc-log", role: "log", "aria-label": "Conversation", children: [
@@ -12553,7 +12606,7 @@ function ChatTranscript({
12553
12606
  const prev = groups[i - 1];
12554
12607
  const k = dayKey(g.messages[0].timestamp);
12555
12608
  const showDay = !!k && (!prev || dayKey(prev.messages[0].timestamp) !== k);
12556
- return /* @__PURE__ */ jsxs85(React64.Fragment, { children: [
12609
+ return /* @__PURE__ */ jsxs85(React65.Fragment, { children: [
12557
12610
  showDay ? /* @__PURE__ */ jsx94("div", { className: "fdc-day", children: /* @__PURE__ */ jsx94("span", { children: dayLabel(k) }) }) : null,
12558
12611
  /* @__PURE__ */ jsx94(ChatTurn, { group: g, ctx })
12559
12612
  ] }, g.key || i);
@@ -12570,7 +12623,7 @@ function ChatTranscript({
12570
12623
  var TranscriptKit = { groupMessages };
12571
12624
 
12572
12625
  // src/components/chat/ChatComposer.tsx
12573
- import * as React65 from "react";
12626
+ import * as React66 from "react";
12574
12627
  import { jsx as jsx95, jsxs as jsxs86 } from "react/jsx-runtime";
12575
12628
  function ChatComposer({
12576
12629
  onSubmit,
@@ -12598,17 +12651,17 @@ function ChatComposer({
12598
12651
  onReject,
12599
12652
  onOpenAttachment
12600
12653
  }) {
12601
- const [text, setText] = React65.useState(draft || "");
12602
- const [trigger, setTrigger] = React65.useState(null);
12603
- const [mentionItems, setMentionItems] = React65.useState([]);
12604
- const [listening, setListening] = React65.useState(false);
12605
- const [notice, setNotice] = React65.useState(null);
12606
- const editor = React65.useRef(null);
12607
- const wrap = React65.useRef(null);
12608
- const stopVoice = React65.useRef(null);
12654
+ const [text, setText] = React66.useState(draft || "");
12655
+ const [trigger, setTrigger] = React66.useState(null);
12656
+ const [mentionItems, setMentionItems] = React66.useState([]);
12657
+ const [listening, setListening] = React66.useState(false);
12658
+ const [notice, setNotice] = React66.useState(null);
12659
+ const editor = React66.useRef(null);
12660
+ const wrap = React66.useRef(null);
12661
+ const stopVoice = React66.useRef(null);
12609
12662
  const staged = useStagedFiles(fileUploadHandler, { onError: () => {
12610
12663
  } });
12611
- React65.useEffect(() => {
12664
+ React66.useEffect(() => {
12612
12665
  if (draft != null && draft !== text) setText(draft);
12613
12666
  }, [draft]);
12614
12667
  const change = (v) => {
@@ -12644,7 +12697,7 @@ function ChatComposer({
12644
12697
  e.preventDefault();
12645
12698
  staged.add(found.files);
12646
12699
  };
12647
- React65.useEffect(() => {
12700
+ React66.useEffect(() => {
12648
12701
  if (!trigger || trigger.type !== "mention" || !mentionSources) {
12649
12702
  setMentionItems([]);
12650
12703
  return;
@@ -12662,7 +12715,7 @@ function ChatComposer({
12662
12715
  const q = (trigger.query || "").toLowerCase();
12663
12716
  setMentionItems(mentionSources.filter((m) => !q || (m.label + " " + (m.description || "")).toLowerCase().includes(q)));
12664
12717
  }, [trigger, mentionSources]);
12665
- const slashItems = React65.useMemo(() => {
12718
+ const slashItems = React66.useMemo(() => {
12666
12719
  if (!trigger || trigger.type !== "slash" || !slashCommands) return [];
12667
12720
  const q = (trigger.query || "").toLowerCase();
12668
12721
  return slashCommands.filter((c) => !q || (c.id + " " + c.label + " " + (c.description || "")).toLowerCase().includes(q));
@@ -12832,12 +12885,12 @@ function ChatComposer({
12832
12885
  }
12833
12886
 
12834
12887
  // src/components/chat/ChatSessionBar.tsx
12835
- import * as React66 from "react";
12888
+ import * as React67 from "react";
12836
12889
  import { jsx as jsx96, jsxs as jsxs87 } from "react/jsx-runtime";
12837
12890
  var compact2 = meterFormats.compact;
12838
12891
  function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extras }) {
12839
- const [open2, setOpen] = React66.useState(false);
12840
- const anchor = React66.useRef(null);
12892
+ const [open2, setOpen] = React67.useState(false);
12893
+ const anchor = React67.useRef(null);
12841
12894
  const stats = sessionStats || null;
12842
12895
  const cu = contextUsage || null;
12843
12896
  const limits = usageLimits || null;
@@ -12852,7 +12905,7 @@ function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extr
12852
12905
  if (stats && stats.runningTasks) bits.push(stats.runningTasks + " running task" + (stats.runningTasks === 1 ? "" : "s"));
12853
12906
  if (cu) bits.push(pct + "% context");
12854
12907
  const expandable = !!(cu || limits);
12855
- return /* @__PURE__ */ jsxs87(React66.Fragment, { children: [
12908
+ return /* @__PURE__ */ jsxs87(React67.Fragment, { children: [
12856
12909
  /* @__PURE__ */ jsxs87("div", { className: "fdc-bar", children: [
12857
12910
  /* @__PURE__ */ jsxs87(
12858
12911
  "button",
@@ -12993,7 +13046,7 @@ function ModelControls({
12993
13046
  ] })
12994
13047
  });
12995
13048
  }
12996
- return /* @__PURE__ */ jsxs87(React66.Fragment, { children: [
13049
+ return /* @__PURE__ */ jsxs87(React67.Fragment, { children: [
12997
13050
  /* @__PURE__ */ jsx96(
12998
13051
  MenuButton,
12999
13052
  {
@@ -13110,11 +13163,11 @@ function AgentChatPanel({
13110
13163
  onFeedback,
13111
13164
  onEditMessage
13112
13165
  }) {
13113
- const [panelWidth, setPanelWidth] = React67.useState(width);
13114
- const [applied, setApplied] = React67.useState({});
13115
- const [draft, setDraft] = React67.useState("");
13116
- const dragging = React67.useRef(null);
13117
- React67.useEffect(() => setPanelWidth(width), [width]);
13166
+ const [panelWidth, setPanelWidth] = React68.useState(width);
13167
+ const [applied, setApplied] = React68.useState({});
13168
+ const [draft, setDraft] = React68.useState("");
13169
+ const dragging = React68.useRef(null);
13170
+ React68.useEffect(() => setPanelWidth(width), [width]);
13118
13171
  const engine = useChatEngine({
13119
13172
  contextType,
13120
13173
  contextId,
@@ -13318,7 +13371,7 @@ function AgentChatPanel({
13318
13371
  }
13319
13372
 
13320
13373
  // src/components/files/FileViewer.tsx
13321
- import * as React68 from "react";
13374
+ import * as React69 from "react";
13322
13375
  import { jsx as jsx98, jsxs as jsxs89 } from "react/jsx-runtime";
13323
13376
  function previewKindOf(file) {
13324
13377
  const mime = (file.mime || "").toLowerCase();
@@ -13375,13 +13428,13 @@ function parseDelimited(text, delimiter) {
13375
13428
  return rows;
13376
13429
  }
13377
13430
  function usePreview(file, kind, resolveUrl) {
13378
- const [state, setState] = React68.useState({ status: "loading" });
13379
- const [attempt, setAttempt] = React68.useState(0);
13380
- const resolveRef = React68.useRef(resolveUrl);
13381
- React68.useEffect(() => {
13431
+ const [state, setState] = React69.useState({ status: "loading" });
13432
+ const [attempt, setAttempt] = React69.useState(0);
13433
+ const resolveRef = React69.useRef(resolveUrl);
13434
+ React69.useEffect(() => {
13382
13435
  resolveRef.current = resolveUrl;
13383
13436
  }, [resolveUrl]);
13384
- React68.useEffect(() => {
13437
+ React69.useEffect(() => {
13385
13438
  if (kind === "none") {
13386
13439
  setState({ status: "ready" });
13387
13440
  return;
@@ -13411,7 +13464,7 @@ function usePreview(file, kind, resolveUrl) {
13411
13464
  if (ac) ac.abort();
13412
13465
  };
13413
13466
  }, [file.id, kind, attempt]);
13414
- return { ...state, retry: React68.useCallback(() => setAttempt((a) => a + 1), []) };
13467
+ return { ...state, retry: React69.useCallback(() => setAttempt((a) => a + 1), []) };
13415
13468
  }
13416
13469
  function PreviewBody({ file, kind, state }) {
13417
13470
  if (kind === "image") return /* @__PURE__ */ jsx98("img", { className: "fd-fv-image", src: state.url, alt: file.name || "Preview" });
@@ -13456,13 +13509,13 @@ function PreviewBody({ file, kind, state }) {
13456
13509
  ] });
13457
13510
  }
13458
13511
  function FileViewer({ file, resolveUrl, sidePanel, sidePanelLabel = "Details", onClose, actions, className = "" }) {
13459
- const kind = React68.useMemo(() => previewKindOf(file), [file]);
13512
+ const kind = React69.useMemo(() => previewKindOf(file), [file]);
13460
13513
  const preview = usePreview(file, kind, resolveUrl);
13461
- const [tab, setTab] = React68.useState("preview");
13462
- const [downloading, setDownloading] = React68.useState(false);
13463
- const [downloadError, setDownloadError] = React68.useState(null);
13514
+ const [tab, setTab] = React69.useState("preview");
13515
+ const [downloading, setDownloading] = React69.useState(false);
13516
+ const [downloadError, setDownloadError] = React69.useState(null);
13464
13517
  const hasSide = sidePanel != null;
13465
- React68.useEffect(() => {
13518
+ React69.useEffect(() => {
13466
13519
  setTab("preview");
13467
13520
  }, [file.id]);
13468
13521
  const download = () => {
@@ -13529,7 +13582,7 @@ function FileViewer({ file, resolveUrl, sidePanel, sidePanelLabel = "Details", o
13529
13582
  }
13530
13583
 
13531
13584
  // src/components/files/FileBrowser.tsx
13532
- import * as React69 from "react";
13585
+ import * as React70 from "react";
13533
13586
  import { Fragment as Fragment28, jsx as jsx99, jsxs as jsxs90 } from "react/jsx-runtime";
13534
13587
  function childrenOf(folders, parentId) {
13535
13588
  return folders.filter((f) => f.parentId === parentId).sort((a, b) => a.name.localeCompare(b.name));
@@ -13639,8 +13692,8 @@ function FolderPickerMenu({
13639
13692
  ] });
13640
13693
  }
13641
13694
  function RowShell({ icon, name, meta, onOpen, draggableId, isDropTarget, onDropPayload, actions, className = "" }) {
13642
- const [over, setOver] = React69.useState(false);
13643
- const dragCounter = React69.useRef(0);
13695
+ const [over, setOver] = React70.useState(false);
13696
+ const dragCounter = React70.useRef(0);
13644
13697
  const dropHandlers = isDropTarget ? {
13645
13698
  onDragEnter: (e) => {
13646
13699
  if (!hasInternalPayload(e)) return;
@@ -13688,8 +13741,8 @@ function RowShell({ icon, name, meta, onOpen, draggableId, isDropTarget, onDropP
13688
13741
  }
13689
13742
  function TreeNode({ folder, depth, folders, currentFolderId, onNavigate, onMoveInto, canMove }) {
13690
13743
  const kids = childrenOf(folders, folder.id);
13691
- const [expanded, setExpanded] = React69.useState(() => currentFolderId != null && isSelfOrDescendant(folders, folder.id, currentFolderId));
13692
- React69.useEffect(() => {
13744
+ const [expanded, setExpanded] = React70.useState(() => currentFolderId != null && isSelfOrDescendant(folders, folder.id, currentFolderId));
13745
+ React70.useEffect(() => {
13693
13746
  if (currentFolderId != null && isSelfOrDescendant(folders, folder.id, currentFolderId)) setExpanded(true);
13694
13747
  }, [currentFolderId, folder.id, folders]);
13695
13748
  const isCurrent = folder.id === currentFolderId;
@@ -13755,15 +13808,15 @@ function FileBrowser({
13755
13808
  const canUpload = perm.canUpload !== false && !!onUpload;
13756
13809
  const canRemoveFile = perm.canRemoveFile !== false && !!onRemoveFile;
13757
13810
  const canDeleteFolder = perm.canDeleteFolder !== false && !!onDeleteFolder;
13758
- const [createOpen, setCreateOpen] = React69.useState(false);
13759
- const [createName, setCreateName] = React69.useState("");
13760
- const [renameTarget, setRenameTarget] = React69.useState(null);
13761
- const [renameValue, setRenameValue] = React69.useState("");
13762
- const [deleteTarget, setDeleteTarget] = React69.useState(null);
13763
- const uploadInputRef = React69.useRef(null);
13764
- const crumbFolders = React69.useMemo(() => ancestorsOf(folders, currentFolderId), [folders, currentFolderId]);
13765
- const subfolders = React69.useMemo(() => childrenOf(folders, currentFolderId), [folders, currentFolderId]);
13766
- const currentFiles = React69.useMemo(
13811
+ const [createOpen, setCreateOpen] = React70.useState(false);
13812
+ const [createName, setCreateName] = React70.useState("");
13813
+ const [renameTarget, setRenameTarget] = React70.useState(null);
13814
+ const [renameValue, setRenameValue] = React70.useState("");
13815
+ const [deleteTarget, setDeleteTarget] = React70.useState(null);
13816
+ const uploadInputRef = React70.useRef(null);
13817
+ const crumbFolders = React70.useMemo(() => ancestorsOf(folders, currentFolderId), [folders, currentFolderId]);
13818
+ const subfolders = React70.useMemo(() => childrenOf(folders, currentFolderId), [folders, currentFolderId]);
13819
+ const currentFiles = React70.useMemo(
13767
13820
  () => files.filter((f) => f.folderId === currentFolderId).sort((a, b) => a.name.localeCompare(b.name)),
13768
13821
  [files, currentFolderId]
13769
13822
  );
@@ -13995,8 +14048,8 @@ function BreadcrumbCrumb({
13995
14048
  isDropTarget,
13996
14049
  onDropPayload
13997
14050
  }) {
13998
- const [over, setOver] = React69.useState(false);
13999
- const dragCounter = React69.useRef(0);
14051
+ const [over, setOver] = React70.useState(false);
14052
+ const dragCounter = React70.useRef(0);
14000
14053
  const dropHandlers = isDropTarget ? {
14001
14054
  onDragEnter: (e) => {
14002
14055
  if (!hasInternalPayload(e)) return;
@@ -14025,7 +14078,7 @@ function BreadcrumbCrumb({
14025
14078
  }
14026
14079
 
14027
14080
  // src/kits/query.ts
14028
- import * as React70 from "react";
14081
+ import * as React71 from "react";
14029
14082
  var isMultiSelectShaped = (v) => !!v && typeof v === "object" && Array.isArray(v.values);
14030
14083
  var isRangeShaped = (v) => !!v && typeof v === "object" && ("min" in v || "max" in v);
14031
14084
  var isDateShaped = (v) => !!v && typeof v === "object" && "kind" in v;
@@ -14080,22 +14133,22 @@ function compare(a, b, dir) {
14080
14133
  var API = null;
14081
14134
  var PREFS = null;
14082
14135
  function useServerTable({ endpoint, params, defaults, deps, prefsKey }) {
14083
- const [query, setQuery] = React70.useState(() => {
14136
+ const [query, setQuery] = React71.useState(() => {
14084
14137
  const store = PREFS || window.PlannerPrefs;
14085
14138
  const saved = prefsKey && store ? store.getTable(prefsKey) : {};
14086
14139
  return { ...DEFAULTS, ...defaults || {}, ...saved.pageSize ? { pageSize: saved.pageSize } : {}, ...saved.sort ? { sort: saved.sort, dir: saved.dir || "desc" } : {} };
14087
14140
  });
14088
- const savePref = React70.useCallback((patch2) => {
14141
+ const savePref = React71.useCallback((patch2) => {
14089
14142
  const store = PREFS || window.PlannerPrefs;
14090
14143
  if (prefsKey && store) store.setTable(prefsKey, patch2);
14091
14144
  }, [prefsKey]);
14092
- const [res, setRes] = React70.useState(null);
14093
- const [loading, setLoading] = React70.useState(true);
14094
- const seq2 = React70.useRef(0);
14145
+ const [res, setRes] = React71.useState(null);
14146
+ const [loading, setLoading] = React71.useState(true);
14147
+ const seq2 = React71.useRef(0);
14095
14148
  const depKey = (deps || []).join("|");
14096
14149
  const paramKey = JSON.stringify(params || {});
14097
14150
  const queryKey = JSON.stringify(query);
14098
- React70.useEffect(() => {
14151
+ React71.useEffect(() => {
14099
14152
  const id = ++seq2.current;
14100
14153
  setLoading(true);
14101
14154
  const t = setTimeout(() => {
@@ -14414,12 +14467,12 @@ function createVersionStore(initialState, options) {
14414
14467
  }
14415
14468
 
14416
14469
  // src/kits/documentTitle.ts
14417
- import * as React71 from "react";
14470
+ import * as React72 from "react";
14418
14471
  function formatDocumentTitle(routeTitle, appName) {
14419
14472
  return [routeTitle, appName, "Flytedesk"].filter((part) => !!part && part.length > 0).join(" \xB7 ");
14420
14473
  }
14421
14474
  function useDocumentTitle(routeTitle, appName) {
14422
- React71.useEffect(() => {
14475
+ React72.useEffect(() => {
14423
14476
  if (typeof document === "undefined") return;
14424
14477
  document.title = formatDocumentTitle(routeTitle, appName);
14425
14478
  }, [routeTitle, appName]);
@@ -14465,6 +14518,7 @@ export {
14465
14518
  CodeEditor,
14466
14519
  Collapsible,
14467
14520
  ComingSoon,
14521
+ CornerStackPortal,
14468
14522
  CsiBadge,
14469
14523
  CsiHero,
14470
14524
  CsiMeter,
@@ -14633,6 +14687,7 @@ export {
14633
14687
  useAppearancePrefs,
14634
14688
  useChatEngine,
14635
14689
  useCopyToClipboard,
14690
+ useCornerStackSlot,
14636
14691
  useDocumentTitle,
14637
14692
  useFeatureStatus,
14638
14693
  useLayerZIndex,