@dsh-workbench/core 0.2.14 → 0.2.16

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.
Files changed (36) hide show
  1. package/client.js +630 -142
  2. package/dist/client/client.body.js +630 -142
  3. package/dist/client/index.js +3524 -421
  4. package/dist/host/index.js +571 -44
  5. package/dist/types/app/client.d.ts +121 -6
  6. package/dist/types/app/layouts/rightbar/__tests__/board-fact.test.d.ts +1 -0
  7. package/dist/types/app/layouts/rightbar/board-fact.d.ts +5 -0
  8. package/dist/types/app/layouts/sidebar/DebugFooterAction.d.ts +17 -0
  9. package/dist/types/app/layouts/sidebar/ProjectSwitcher.d.ts +2 -1
  10. package/dist/types/app/layouts/sidebar/__tests__/debug-ui.test.d.ts +1 -0
  11. package/dist/types/app/layouts/sidebar/debug-footer.d.ts +4 -0
  12. package/dist/types/app/layouts/sidebar/session-pick.d.ts +2 -1
  13. package/dist/types/modules/panels/__tests__/diy-harness.d.ts +6 -3
  14. package/dist/types/modules/panels/model/diy-browser-act.d.ts +1 -1
  15. package/dist/types/modules/panels/model/diy-browser.d.ts +4 -0
  16. package/dist/types/modules/panels/model/diy-debug-routes.d.ts +2 -0
  17. package/dist/types/modules/panels/model/diy-debug-routes.test.d.ts +1 -0
  18. package/dist/types/modules/panels/model/diy-debug-tools.d.ts +8 -0
  19. package/dist/types/modules/panels/model/diy-debug-tools.test.d.ts +1 -0
  20. package/dist/types/modules/panels/model/diy-look.d.ts +2 -1
  21. package/dist/types/modules/panels/model/diy-page.d.ts +14 -0
  22. package/dist/types/modules/panels/model/diy-scripts.d.ts +2 -1
  23. package/dist/types/modules/panels/model/diy-tools.d.ts +2 -1
  24. package/dist/types/modules/panels/model/handoff.d.ts +1 -0
  25. package/dist/types/modules/panels/unit.d.ts +7 -2
  26. package/dist/types/modules/sessions/index.d.ts +1 -1
  27. package/dist/types/modules/sessions/model/attention.d.ts +7 -0
  28. package/dist/types/shared/__tests__/host-import-barrel.test.d.ts +1 -0
  29. package/dist/types/shared/api/host/__tests__/diy-debug-act.test.d.ts +1 -0
  30. package/dist/types/shared/api/host/__tests__/host-args.test.d.ts +1 -0
  31. package/dist/types/shared/api/host/diy-debug-act.d.ts +31 -0
  32. package/dist/types/shared/api/host/host-args.d.ts +3 -0
  33. package/dist/types/shared/hooks/use-api-resource.d.ts +1 -0
  34. package/dist/types/shared/hooks/use-diy-debug.d.ts +8 -0
  35. package/package.json +2 -2
  36. package/skills/workbench-module-diy/KIT.md +18 -3
@@ -1,4 +1,4 @@
1
- import { Button, Checkbox, CodeBlock, DiffBlock, DisclosureRow, HoverCard, IconCheckCircleFillRegular, IconCheckOutlineRegular, IconChevronDownOutlineRegular, IconCodeOutlineRegular, IconCordisPluginOutlineRegular, IconDownloadOutlineRegular, IconEditOutlineRegular, IconEllipsisOutlineRegular, IconFlatListOutlineRegular, IconFolderCloseRegular, IconFolderOpenRegular, IconInfoOutlineRegular, IconLinkOutlineRegular, IconNewChatOutlineRegular, IconPanelLeftOutlineRegular, IconPinFillRegular, IconPlusOutlineRegular, IconRefreshOutlineRegular, IconRightUpOutlineRegular, IconSearchOutlineRegular, IconSettingsOutlineRegular, IconTrashOutlineRegular, IconWarningOutlineRegular, Menu, Modal, RiskConfirmation, StateDot, Switch, Tag, TextShimmer, Tooltip, useAnchoredPosition, useDismissOnOutsidePointer, writeClipboard } from "@deepseek-ai/dsh-client-ui-primitives";
1
+ import { Button, Checkbox, CodeBlock, DiffBlock, DisclosureRow, HoverCard, IconCheckCircleFillRegular, IconCheckOutlineRegular, IconChevronDownOutlineRegular, IconChevronRightOutlineRegular, IconCodeOutlineRegular, IconCordisPluginOutlineRegular, IconDownloadOutlineRegular, IconEditOutlineRegular, IconEllipsisOutlineRegular, IconFlatListOutlineRegular, IconFolderCloseRegular, IconFolderOpenRegular, IconInfoOutlineRegular, IconLinkOutlineRegular, IconNewChatOutlineRegular, IconPanelLeftOutlineRegular, IconPauseOutlineRegular, IconPinFillRegular, IconPlayOutlineRegular, IconPlusOutlineRegular, IconRefreshOutlineRegular, IconRightUpOutlineRegular, IconSearchOutlineRegular, IconSettingsOutlineRegular, IconStopFillRegular, IconTrashOutlineRegular, IconWarningOutlineRegular, Menu, Modal, RiskConfirmation, StateDot, Switch, Tag, TextShimmer, Tooltip, useAnchoredPosition, useDismissOnOutsidePointer, writeClipboard } from "@deepseek-ai/dsh-client-ui-primitives";
2
2
  //#region \0rolldown/runtime.js
3
3
  var __defProp = Object.defineProperty;
4
4
  var __exportAll = (all, no_symbols) => {
@@ -609,12 +609,15 @@ var EVENTS_PATH = "/workbench/events";
609
609
  var ACTIONS_PREFIX = `${API_PREFIX}/actions`;
610
610
  var PROVISION_PREFIX = `${API_PREFIX}/provision`;
611
611
  var PANEL_STATE_PATH = "panel-state";
612
+ var DIY_DEBUG_PATH = "diy-debug";
613
+ var DIY_DEBUG_ACT_PATH = `${DIY_DEBUG_PATH}/act`;
612
614
  var PANEL_STATE_PREFIX = `${API_PREFIX}/${PANEL_STATE_PATH}`;
613
615
  var OPENCLI_PIN = "1.8.8";
614
616
  var CODING_ISSUES_SERVICE = "workbenchCodingIssues";
615
617
  var PANELS_SERVICE = "workbenchPanels";
616
618
  var UNITS_SERVICE = "workbenchUnits";
617
619
  var PANEL_STATE_SERVICE = "workbenchPanelState";
620
+ var DIY_DEBUG_SERVICE = "workbenchDiyDebug";
618
621
  var OPENCLI_TIMEOUT_MS = 12e4;
619
622
  var WARM_TIMEOUT_MS = 2e4;
620
623
  var INSTALL_TIMEOUT_MS = 3e5;
@@ -1173,30 +1176,8 @@ function SaveBar({ busy, disabled, labels, onCancel, onSave }) {
1173
1176
  }] });
1174
1177
  }
1175
1178
  //#endregion
1176
- //#region ../shared/dist/components/TextField.js
1177
- function TextField({ invalid = false, className, ...rest }) {
1178
- return h("input", {
1179
- ...rest,
1180
- className: className === void 0 ? "wb-textField" : `wb-textField ${className}`,
1181
- "aria-invalid": invalid || void 0
1182
- });
1183
- }
1184
- //#endregion
1185
- //#region ../shared/dist/components/SelectField.js
1186
- var FOOTER_ID = "__wb-select-footer__";
1187
- var EMPTY_ID = "__wb-select-empty__";
1188
- function mergeClass(...parts) {
1189
- return parts.filter((one) => one !== void 0 && one !== "").join(" ");
1190
- }
1191
- function itemOf(option) {
1192
- return {
1193
- id: option.value,
1194
- label: option.label,
1195
- ...option.icon === void 0 ? {} : { icon: option.icon },
1196
- ...option.disabled === true ? { disabled: true } : {}
1197
- };
1198
- }
1199
- function triggerNode(args) {
1179
+ //#region ../shared/dist/components/SelectFieldNodes.js
1180
+ function selectTriggerNode(args) {
1200
1181
  return h("button", {
1201
1182
  type: "button",
1202
1183
  id: args.id,
@@ -1208,9 +1189,9 @@ function triggerNode(args) {
1208
1189
  "aria-label": args.ariaLabel,
1209
1190
  title: args.title,
1210
1191
  onClick: args.onOpen
1211
- }, args.icon === void 0 ? null : h("span", { className: "wb-selectIcon" }, args.icon), h("span", { className: "wb-selectValue" }, args.value), h("span", { className: "wb-selectChevron" }, h(IconChevronDownOutlineRegular, { size: 14 })));
1192
+ }, args.iconOnly ? h("span", { className: "wb-selectIcon" }, args.icon) : h(Fragment, null, args.icon === void 0 ? null : h("span", { className: "wb-selectIcon" }, args.icon), h("span", { className: "wb-selectValue" }, args.value), h("span", { className: "wb-selectChevron" }, h(IconChevronDownOutlineRegular, { size: 14 }))));
1212
1193
  }
1213
- function loadingNode(args) {
1194
+ function selectLoadingNode(args) {
1214
1195
  return h("button", {
1215
1196
  type: "button",
1216
1197
  id: args.id,
@@ -1222,6 +1203,57 @@ function loadingNode(args) {
1222
1203
  title: args.loadingText
1223
1204
  }, h("span", { className: "wb-selectValue" }, h(TextShimmer, { active: true }, args.loadingText ?? "…")), h("span", { className: "wb-selectChevron" }, h(Spinner, { size: 14 })));
1224
1205
  }
1206
+ //#endregion
1207
+ //#region ../shared/dist/components/TextField.js
1208
+ function TextField({ invalid = false, className, ...rest }) {
1209
+ return h("input", {
1210
+ ...rest,
1211
+ className: className === void 0 ? "wb-textField" : `wb-textField ${className}`,
1212
+ "aria-invalid": invalid || void 0
1213
+ });
1214
+ }
1215
+ //#endregion
1216
+ //#region ../shared/dist/components/SelectField.js
1217
+ var FOOTER_ID = "__wb-select-footer__";
1218
+ var EMPTY_ID = "__wb-select-empty__";
1219
+ function mergeClass(...parts) {
1220
+ return parts.filter((one) => one !== void 0 && one !== "").join(" ");
1221
+ }
1222
+ function triggerClassOf(variantClass, iconOnly) {
1223
+ return mergeClass("wb-selectTrigger", variantClass, iconOnly ? "wb-selectIconOnly" : void 0);
1224
+ }
1225
+ function itemOf(option, revealId) {
1226
+ if (!(option.value === revealId)) return {
1227
+ id: option.value,
1228
+ label: option.label,
1229
+ ...option.icon === void 0 ? {} : { icon: option.icon },
1230
+ ...option.disabled === true ? { disabled: true } : {}
1231
+ };
1232
+ const revealed = (node) => h("span", {
1233
+ className: "wb-selectReveal",
1234
+ "data-wb-select-reveal": ""
1235
+ }, node);
1236
+ return {
1237
+ id: option.value,
1238
+ label: option.icon === void 0 ? revealed(option.label) : option.label,
1239
+ ...option.icon === void 0 ? {} : { icon: revealed(option.icon) },
1240
+ ...option.disabled === true ? { disabled: true } : {}
1241
+ };
1242
+ }
1243
+ function revealNode() {
1244
+ const found = document.querySelector("[data-wb-select-reveal]");
1245
+ return found instanceof HTMLElement ? found : null;
1246
+ }
1247
+ function useRevealOnOpen(open, revealId) {
1248
+ useEffect(() => {
1249
+ if (!open || revealId === void 0) return;
1250
+ revealNode()?.scrollIntoView({ block: "nearest" });
1251
+ }, [open, revealId]);
1252
+ }
1253
+ function selectValueNode(current, renderValue, placeholder) {
1254
+ if (current === void 0) return h("span", { className: "wb-selectPlaceholder" }, placeholder ?? "—");
1255
+ return renderValue === void 0 ? current.label : renderValue(current);
1256
+ }
1225
1257
  function searchNode(args) {
1226
1258
  return h("span", {
1227
1259
  ref: args.boxRef,
@@ -1285,7 +1317,7 @@ function stepSelectCursor(shown, cursor, step) {
1285
1317
  if (cursor === null) return step === 1 ? 0 : shown.length - 1;
1286
1318
  return (cursor + step + shown.length) % shown.length;
1287
1319
  }
1288
- function selectEntries(shown, emptyText) {
1320
+ function selectEntries(shown, emptyText, revealId) {
1289
1321
  if (shown.length === 0) return emptyText === void 0 ? [] : [{
1290
1322
  type: "label",
1291
1323
  id: EMPTY_ID,
@@ -1302,7 +1334,7 @@ function selectEntries(shown, emptyText) {
1302
1334
  });
1303
1335
  group = option.group;
1304
1336
  }
1305
- out.push(itemOf(option));
1337
+ out.push(itemOf(option, revealId));
1306
1338
  }
1307
1339
  return out;
1308
1340
  }
@@ -1366,12 +1398,13 @@ function useSelectState(props) {
1366
1398
  };
1367
1399
  }
1368
1400
  function SelectField(props) {
1369
- const { value, options, onChange, label, hint, icon, renderValue, placeholder, search = true, searchLabel, searchPlaceholder, footer, onFooter, disabled = false, invalid = false, loading = false, loadingText, fallback, selection = "fill", variant = "boxed", ariaLabel, title, id, name, className, menuClassName } = props;
1401
+ const { value, options, onChange, label, hint, icon, renderValue, placeholder, search = true, searchLabel, searchPlaceholder, footer, onFooter, disabled = false, invalid = false, loading = false, loadingText, fallback, selection = "fill", variant = "boxed", iconOnly = false, revealId, ariaLabel, title, id, name, className, menuClassName } = props;
1370
1402
  const state = useSelectState(props);
1371
1403
  const current = options.find((option) => option.value === value);
1404
+ useRevealOnOpen(state.open, revealId);
1372
1405
  const variantClass = variant === "ghost" ? "wb-selectGhost" : void 0;
1373
- const triggerClass = mergeClass("wb-selectTrigger", variantClass);
1374
- if (loading) return framed(label, hint, className, loadingNode({
1406
+ const triggerClass = triggerClassOf(variantClass, iconOnly);
1407
+ if (loading) return framed(label, hint, className, selectLoadingNode({
1375
1408
  id,
1376
1409
  className: triggerClass,
1377
1410
  invalid,
@@ -1387,7 +1420,7 @@ function SelectField(props) {
1387
1420
  value: fallback.value,
1388
1421
  onChange: (event) => fallback.onChange(event.currentTarget.value)
1389
1422
  }));
1390
- const trigger = triggerNode({
1423
+ const trigger = selectTriggerNode({
1391
1424
  id,
1392
1425
  className: triggerClass,
1393
1426
  disabled,
@@ -1396,7 +1429,8 @@ function SelectField(props) {
1396
1429
  ariaLabel,
1397
1430
  title,
1398
1431
  icon,
1399
- value: current === void 0 ? h("span", { className: "wb-selectPlaceholder" }, placeholder ?? "—") : renderValue === void 0 ? current.label : renderValue(current),
1432
+ value: selectValueNode(current, renderValue, placeholder),
1433
+ iconOnly,
1400
1434
  onOpen: () => state.setOpen(true)
1401
1435
  });
1402
1436
  const anchor = state.open && search ? searchNode({
@@ -1432,7 +1466,7 @@ function SelectField(props) {
1432
1466
  anchor,
1433
1467
  selection,
1434
1468
  selectedId: selectCursorValue(state.shown, state.cursor) ?? void 0,
1435
- items: selectEntries(state.shown, state.empty),
1469
+ items: selectEntries(state.shown, state.empty, revealId),
1436
1470
  footer: footer === void 0 ? void 0 : [{
1437
1471
  id: FOOTER_ID,
1438
1472
  label: footer.label,
@@ -2097,7 +2131,21 @@ var en = {
2097
2131
  "configSync.unreadable": "Cannot read {path}: {reason}",
2098
2132
  "configSync.noSource": "This machine has no other profile to sync from",
2099
2133
  "configSync.emptyProviders": "The workbench has no model provider yet — sync the llm- rows from some profile, or configure one under Models.",
2100
- "configSync.failed": "The sync did not go through; try again."
2134
+ "configSync.failed": "The sync did not go through; try again.",
2135
+ "debug.status": "Workbench DIY debugging",
2136
+ "debug.status.trouble": "Workbench DIY debugging needs attention",
2137
+ "debug.stalled": "Workbench DIY debugging paused",
2138
+ "debug.act.pause": "Pause debugging",
2139
+ "debug.act.resume": "Resume debugging",
2140
+ "debug.act.stop": "Stop debugging",
2141
+ "debug.act.stop.ask": "Confirm stop",
2142
+ "debug.card.here.title": "Workbench DIY debugging is on",
2143
+ "debug.card.here.note": "Do not switch workspaces or touch the panel",
2144
+ "debug.card.away.title": "Workbench DIY debugging is on",
2145
+ "debug.card.away.note": "Switch to the Workbench DIY workspace",
2146
+ "debug.card.paused.note": "Paused",
2147
+ "debug.card.hidden.note": "Switch to the Workbench panel",
2148
+ "debug.back": "Back to the workshop screen"
2101
2149
  };
2102
2150
  //#endregion
2103
2151
  //#region ../shared/dist/i18n/zh.js
@@ -2508,7 +2556,21 @@ var zh = {
2508
2556
  "configSync.unreadable": "读不到 {path}:{reason}",
2509
2557
  "configSync.noSource": "这台机器上只有工作台这一个 profile,没有可同步的来源",
2510
2558
  "configSync.emptyProviders": "工作台还没有任何模型供应商 —— 去「配置同步」从某个 profile 把 llm- 那几行搬过来,或自己去「模型」里配。",
2511
- "configSync.failed": "同步没成功,再试一次。"
2559
+ "configSync.failed": "同步没成功,再试一次。",
2560
+ "debug.status": "工作台 DIY 开发调试中",
2561
+ "debug.status.trouble": "工作台 DIY 开发调试异常",
2562
+ "debug.stalled": "工作台 DIY 调试暂停",
2563
+ "debug.act.pause": "暂停调试",
2564
+ "debug.act.resume": "继续调试",
2565
+ "debug.act.stop": "结束调试",
2566
+ "debug.act.stop.ask": "确认结束",
2567
+ "debug.card.here.title": "当前工作台 DIY 开发调试中",
2568
+ "debug.card.here.note": "请勿切换工作区和操作面板",
2569
+ "debug.card.away.title": "工作台 DIY 开发调试中",
2570
+ "debug.card.away.note": "请切换到工作台 DIY 工作区",
2571
+ "debug.card.paused.note": "已暂停",
2572
+ "debug.card.hidden.note": "请切换到工作台面板",
2573
+ "debug.back": "回到工坊那一屏"
2512
2574
  };
2513
2575
  //#endregion
2514
2576
  //#region ../shared/dist/i18n/index.js
@@ -2619,6 +2681,129 @@ function revealFirstProblem(root) {
2619
2681
  problem.querySelector(FOCUSABLE_SELECTOR)?.focus?.();
2620
2682
  return true;
2621
2683
  }
2684
+ //#endregion
2685
+ //#region ../shared/dist/lib/board-fact.js
2686
+ function insideWorkshop(root, target) {
2687
+ if (target === root) return true;
2688
+ const base = root.endsWith("/") ? root : `${root}/`;
2689
+ return target.startsWith(base);
2690
+ }
2691
+ function boardFactOf(probe, workshop) {
2692
+ if (!probe.workbench) return "unknown";
2693
+ if (!probe.bar || !probe.open || !probe.drawn) return "hidden";
2694
+ if (probe.board === "" || workshop === null) return "unknown";
2695
+ return insideWorkshop(workshop, probe.board) ? "workshop" : "other";
2696
+ }
2697
+ function boardSituation(probe, workshop) {
2698
+ if (!probe.workbench || workshop === null) return "unknown";
2699
+ if (probe.bar && probe.open && probe.drawn) {
2700
+ if (probe.board === "") return "unknown";
2701
+ return insideWorkshop(workshop, probe.board) ? "ok" : "other-board";
2702
+ }
2703
+ if (probe.where !== "" && !insideWorkshop(workshop, probe.where)) return "off-workspace";
2704
+ return "panel-closed";
2705
+ }
2706
+ //#endregion
2707
+ //#region ../shared/dist/lib/diy-debug.js
2708
+ function parseDebugIntent(value) {
2709
+ return value === "pause" || value === "resume" || value === "stop" ? value : null;
2710
+ }
2711
+ var DEBUG_STALE_MS = 144e5;
2712
+ function alive(state, now) {
2713
+ if (state === null) return null;
2714
+ return now - state.at <= 144e5 ? state : null;
2715
+ }
2716
+ function ownerOf(state, sessionId, now) {
2717
+ const held = alive(state, now);
2718
+ if (held === null) return "none";
2719
+ return held.sessionId === sessionId ? held : "not-owner";
2720
+ }
2721
+ function createDebugStore() {
2722
+ let held = null;
2723
+ const live = (now) => alive(held, now);
2724
+ return {
2725
+ live,
2726
+ begin(pact) {
2727
+ const current = alive(held, pact.now);
2728
+ if (current !== null) return {
2729
+ ok: false,
2730
+ code: current.sessionId === pact.sessionId ? "already-held" : "held-by-other"
2731
+ };
2732
+ const state = {
2733
+ phase: "debugging",
2734
+ sessionId: pact.sessionId,
2735
+ workspace: pact.workspace,
2736
+ board: pact.board,
2737
+ unit: pact.unit,
2738
+ name: pact.name,
2739
+ startedAt: pact.now,
2740
+ at: pact.now
2741
+ };
2742
+ held = state;
2743
+ return {
2744
+ ok: true,
2745
+ state
2746
+ };
2747
+ },
2748
+ pause(sessionId, now) {
2749
+ const found = ownerOf(held, sessionId, now);
2750
+ if (typeof found === "string") return {
2751
+ ok: false,
2752
+ code: found
2753
+ };
2754
+ if (found.phase === "paused") return {
2755
+ ok: false,
2756
+ code: "already-paused"
2757
+ };
2758
+ const state = {
2759
+ ...found,
2760
+ phase: "paused",
2761
+ at: now
2762
+ };
2763
+ held = state;
2764
+ return {
2765
+ ok: true,
2766
+ state
2767
+ };
2768
+ },
2769
+ resume(sessionId, now) {
2770
+ const found = ownerOf(held, sessionId, now);
2771
+ if (typeof found === "string") return {
2772
+ ok: false,
2773
+ code: found
2774
+ };
2775
+ if (found.phase === "debugging") return {
2776
+ ok: false,
2777
+ code: "already-debugging"
2778
+ };
2779
+ const state = {
2780
+ ...found,
2781
+ phase: "debugging",
2782
+ at: now
2783
+ };
2784
+ held = state;
2785
+ return {
2786
+ ok: true,
2787
+ state
2788
+ };
2789
+ },
2790
+ stop(sessionId, now) {
2791
+ const found = ownerOf(held, sessionId, now);
2792
+ if (typeof found === "string") return {
2793
+ ok: false,
2794
+ code: found
2795
+ };
2796
+ held = null;
2797
+ return {
2798
+ ok: true,
2799
+ state: found
2800
+ };
2801
+ }
2802
+ };
2803
+ }
2804
+ function debugOwnerText(state) {
2805
+ return `会话 ${state.sessionId}(自 ${new Date(state.startedAt).toISOString().slice(11, 19)}Z 起在调试 ${state.unit})`;
2806
+ }
2622
2807
  var PANEL_STATE_CRASH_WINDOW_MS = 6e5;
2623
2808
  var PANEL_STATE_MAX_TEXT = 2e3;
2624
2809
  var PHASES = [
@@ -2884,9 +3069,13 @@ var dist_exports = /* @__PURE__ */ __exportAll({
2884
3069
  CenteredState: () => CenteredState,
2885
3070
  ChoiceGroup: () => ChoiceGroup,
2886
3071
  Component: () => Component,
3072
+ DEBUG_STALE_MS: () => DEBUG_STALE_MS,
2887
3073
  DECLARATION_KEYS: () => DECLARATION_KEYS,
2888
3074
  DECLARATION_REQUIRED_KEYS: () => DECLARATION_REQUIRED_KEYS,
2889
3075
  DEFAULT_WORKSPACE_TITLE: () => DEFAULT_WORKSPACE_TITLE,
3076
+ DIY_DEBUG_ACT_PATH: () => DIY_DEBUG_ACT_PATH,
3077
+ DIY_DEBUG_PATH: () => DIY_DEBUG_PATH,
3078
+ DIY_DEBUG_SERVICE: () => DIY_DEBUG_SERVICE,
2890
3079
  EVENTS_PATH: () => EVENTS_PATH,
2891
3080
  EmptyState: () => EmptyState,
2892
3081
  FACT_SCOPE_SUFFIX: () => "*",
@@ -2958,12 +3147,16 @@ var dist_exports = /* @__PURE__ */ __exportAll({
2958
3147
  blockerOfCapability: () => blockerOfCapability,
2959
3148
  blockerOfError: () => blockerOfError,
2960
3149
  blockerPending: () => blockerPending,
3150
+ boardFactOf: () => boardFactOf,
3151
+ boardSituation: () => boardSituation,
2961
3152
  buildMarker: () => buildMarker,
2962
3153
  cardIdOf: () => cardIdOf,
2963
3154
  createContext: () => createContext,
3155
+ createDebugStore: () => createDebugStore,
2964
3156
  createFactChannel: () => createFactChannel,
2965
3157
  createPanelStateStore: () => createPanelStateStore,
2966
3158
  cx: () => cx,
3159
+ debugOwnerText: () => debugOwnerText,
2967
3160
  declarationProblemsOf: () => declarationProblemsOf,
2968
3161
  decodeRef: () => decodeRef,
2969
3162
  defaultSelectFilter: () => defaultSelectFilter,
@@ -2979,6 +3172,7 @@ var dist_exports = /* @__PURE__ */ __exportAll({
2979
3172
  h: () => h,
2980
3173
  hasEnvSupply: () => hasEnvSupply,
2981
3174
  holdBusy: () => holdBusy,
3175
+ insideWorkshop: () => insideWorkshop,
2982
3176
  isFactScope: () => isFactScope,
2983
3177
  longTaskDot: () => longTaskDot,
2984
3178
  longTaskPollMs: () => longTaskPollMs,
@@ -2988,6 +3182,7 @@ var dist_exports = /* @__PURE__ */ __exportAll({
2988
3182
  mergeMessagesSkipping: () => mergeMessagesSkipping,
2989
3183
  parseCardsReport: () => parseCardsReport,
2990
3184
  parseCrashReport: () => parseCrashReport,
3185
+ parseDebugIntent: () => parseDebugIntent,
2991
3186
  parseFactFrame: () => parseFactFrame,
2992
3187
  parseJsonLoose: () => parseJsonLoose,
2993
3188
  parseLocalTimestamp: () => parseLocalTimestamp,
@@ -3143,10 +3338,10 @@ var silentNextProbe = false;
3143
3338
  function markNextProbeSilent() {
3144
3339
  silentNextProbe = true;
3145
3340
  }
3146
- var probe = NO_PROBE;
3341
+ var probe$3 = NO_PROBE;
3147
3342
  var probeListeners = /* @__PURE__ */ new Set();
3148
3343
  function probeValue() {
3149
- return probe;
3344
+ return probe$3;
3150
3345
  }
3151
3346
  function subscribeProbe(listener) {
3152
3347
  probeListeners.add(listener);
@@ -3155,43 +3350,43 @@ function subscribeProbe(listener) {
3155
3350
  };
3156
3351
  }
3157
3352
  function setProbe(next) {
3158
- if (next === probe) return;
3159
- probe = next;
3353
+ if (next === probe$3) return;
3354
+ probe$3 = next;
3160
3355
  for (const listener of [...probeListeners]) listener();
3161
3356
  }
3162
3357
  var CAPABILITY_FACT = "capability";
3163
3358
  var shared = null;
3164
3359
  var current$1 = null;
3165
- var listeners$3 = /* @__PURE__ */ new Set();
3360
+ var listeners$4 = /* @__PURE__ */ new Set();
3166
3361
  function capabilityValue() {
3167
3362
  return current$1;
3168
3363
  }
3169
3364
  function subscribeCapabilities(listener) {
3170
- listeners$3.add(listener);
3365
+ listeners$4.add(listener);
3171
3366
  return () => {
3172
- listeners$3.delete(listener);
3367
+ listeners$4.delete(listener);
3173
3368
  };
3174
3369
  }
3175
3370
  function setCapabilities(next, rechecked = false) {
3176
3371
  if (next === null) setProbe(NO_PROBE);
3177
3372
  else if (rechecked) setProbe({
3178
- ...probe,
3373
+ ...probe$3,
3179
3374
  checkedAt: Date.now()
3180
3375
  });
3181
3376
  if (next === current$1) return;
3182
3377
  current$1 = next;
3183
- for (const listener of [...listeners$3]) listener();
3378
+ for (const listener of [...listeners$4]) listener();
3184
3379
  }
3185
3380
  function beginProbe() {
3186
- if (probe.checking) return;
3381
+ if (probe$3.checking) return;
3187
3382
  setProbe({
3188
- ...probe,
3383
+ ...probe$3,
3189
3384
  checking: true
3190
3385
  });
3191
3386
  }
3192
3387
  function endProbe() {
3193
3388
  setProbe({
3194
- ...probe,
3389
+ ...probe$3,
3195
3390
  checking: false
3196
3391
  });
3197
3392
  }
@@ -3247,91 +3442,2916 @@ function useCapabilities(refreshToken, reloadToken = 0) {
3247
3442
  silent
3248
3443
  });
3249
3444
  }, [
3250
- refreshToken,
3251
- useFactRevision(CAPABILITY_FACT),
3252
- reloadToken
3445
+ refreshToken,
3446
+ useFactRevision(CAPABILITY_FACT),
3447
+ reloadToken
3448
+ ]);
3449
+ return value;
3450
+ }
3451
+ function useCapabilityProbe() {
3452
+ return useSyncExternalStore(subscribeProbe, probeValue);
3453
+ }
3454
+ //#endregion
3455
+ //#region src/shared/hooks/use-capability-gate.ts
3456
+ var use_capability_gate_exports = /* @__PURE__ */ __exportAll({
3457
+ useCapabilityGate: () => useCapabilityGate,
3458
+ useCapabilityMap: () => useCapabilityMap
3459
+ });
3460
+ function useCapabilityGate(unit, refreshToken, options = {}) {
3461
+ const [probeNonce, setProbeNonce] = useState(0);
3462
+ const forceProbe = useCallback(() => setProbeNonce((value) => value + 1), []);
3463
+ const capabilities = useCapabilities(refreshToken + probeNonce);
3464
+ const capability = options.fixture ?? capabilities?.[unit] ?? null;
3465
+ return {
3466
+ capability,
3467
+ gated: gateOf(capability, options.mode ?? "capability").gated,
3468
+ forceProbe
3469
+ };
3470
+ }
3471
+ function useCapabilityMap(refreshToken) {
3472
+ const [probeNonce, setProbeNonce] = useState(0);
3473
+ const [reloadNonce, setReloadNonce] = useState(0);
3474
+ const forceProbe = useCallback(() => setProbeNonce((value) => value + 1), []);
3475
+ const reload = useCallback(() => setReloadNonce((value) => value + 1), []);
3476
+ const probe = useCapabilityProbe();
3477
+ return {
3478
+ capabilities: useCapabilities(refreshToken + probeNonce, reloadNonce),
3479
+ ...probe,
3480
+ forceProbe,
3481
+ reload
3482
+ };
3483
+ }
3484
+ //#endregion
3485
+ //#region src/dev/MockStrip.tsx
3486
+ function MockStrip({ mocks, index, onPick, note, real }) {
3487
+ return /* @__PURE__ */ h("div", { className: "wb-mockStrip" }, /* @__PURE__ */ h("span", { className: "wb-mockNote" }, note ?? "夹具:只切状态,不发请求"), real === void 0 ? null : /* @__PURE__ */ h("button", {
3488
+ type: "button",
3489
+ className: `wb-mockChip${real.active ? " wb-mockChipOn" : ""}`,
3490
+ onClick: real.onPick
3491
+ }, real.label), mocks.map((mock, at) => /* @__PURE__ */ h("button", {
3492
+ key: mock.id,
3493
+ type: "button",
3494
+ className: `wb-mockChip${at === index ? " wb-mockChipOn" : ""}`,
3495
+ onClick: () => onPick(at)
3496
+ }, mock.label)));
3497
+ }
3498
+ //#endregion
3499
+ //#region src/shared/hooks/mock-mode.ts
3500
+ function mockModeOn(search) {
3501
+ return /(?:^|[?&])(?:wbMock|wbMarketMock)=1(?:&|$)/.test(search);
3502
+ }
3503
+ function crashModeOn(search) {
3504
+ return /(?:^|[?&])wbCrash=1(?:&|$)/.test(search);
3505
+ }
3506
+ //#endregion
3507
+ //#region src/shared/hooks/use-fixture-pick.ts
3508
+ function useFixturePick(options) {
3509
+ const controlled = options.selected !== void 0 || options.onSelect !== void 0;
3510
+ const [ownActive, setOwnActive] = useState(options.initial ?? null);
3511
+ const [nonce, setNonce] = useState(0);
3512
+ const [on] = useState(() => mockModeOn(window.location.search));
3513
+ const enabled = options.enabled ?? on;
3514
+ const active = controlled ? options.selected ?? null : ownActive;
3515
+ const pick = useCallback((id) => {
3516
+ if (!controlled) setOwnActive(id);
3517
+ options.onSelect?.(id);
3518
+ setNonce((value) => value + 1);
3519
+ }, [controlled, options]);
3520
+ return {
3521
+ enabled,
3522
+ active,
3523
+ current: options.fixtures.find((fixture) => fixture.id === active),
3524
+ pick,
3525
+ nonce,
3526
+ index: options.fixtures.findIndex((fixture) => fixture.id === active)
3527
+ };
3528
+ }
3529
+ //#endregion
3530
+ //#region src/app/layouts/rightbar/board-mock.ts
3531
+ var REAL = {
3532
+ id: "real",
3533
+ label: "真实",
3534
+ note: "不接管:宿主配置里开着什么就摆什么。",
3535
+ shape: { kind: "real" }
3536
+ };
3537
+ var EMPTY = {
3538
+ id: "empty",
3539
+ label: "空看板",
3540
+ note: "一个模块都没开:内容区那条空态与它的两条出路。",
3541
+ shape: { kind: "empty" },
3542
+ expect: {
3543
+ cards: 0,
3544
+ empty: true
3545
+ }
3546
+ };
3547
+ var UNREAD = {
3548
+ id: "unread",
3549
+ label: "配置还没读到",
3550
+ note: "还没读到配置:内容区说一句\"正在读取面板配置…\",头部 ⟳ 留着(按一下立刻重读)。",
3551
+ shape: { kind: "unread" },
3552
+ expect: {
3553
+ cards: 0,
3554
+ empty: false
3555
+ }
3556
+ };
3557
+ var KIT = {
3558
+ id: "kit",
3559
+ label: "公共组件预览",
3560
+ note: "把 shared 那套哑组件按\"样式 + 交互\"摆一遍(下拉的常规档与无边框档、搜索、分组、禁用、加载、手填退化、卡片头、状态、行、活动流、长任务那一行):不碰配置、不读数据。",
3561
+ shape: { kind: "kit" },
3562
+ expect: {
3563
+ cards: 1,
3564
+ empty: false
3565
+ }
3566
+ };
3567
+ function buildBoardMocks(roster) {
3568
+ return [
3569
+ REAL,
3570
+ KIT,
3571
+ ...!roster.some((manifest) => manifest.card !== null) ? [] : [
3572
+ {
3573
+ id: "one",
3574
+ label: "一张卡",
3575
+ note: "常态:面板上只有一个模块时的样子。",
3576
+ shape: {
3577
+ kind: "copies",
3578
+ count: 1
3579
+ },
3580
+ expect: {
3581
+ cards: 1,
3582
+ empty: false
3583
+ }
3584
+ },
3585
+ {
3586
+ id: "two",
3587
+ label: "两张卡",
3588
+ note: "同一个模块摆两份 —— 量卡片之间的间距与分界(卡片夹具条已收起)。",
3589
+ shape: {
3590
+ kind: "copies",
3591
+ count: 2
3592
+ },
3593
+ expect: {
3594
+ cards: 2,
3595
+ empty: false
3596
+ }
3597
+ },
3598
+ {
3599
+ id: "many",
3600
+ label: "八张卡(要滚)",
3601
+ note: "同一个模块摆八份 —— 量滚动、滚动条与底部留白(卡片夹具条已收起)。",
3602
+ shape: {
3603
+ kind: "copies",
3604
+ count: 8
3605
+ },
3606
+ expect: {
3607
+ cards: 8,
3608
+ empty: false
3609
+ }
3610
+ },
3611
+ {
3612
+ id: "crash",
3613
+ label: "坏卡 + 好卡",
3614
+ note: "一张渲染必炸的卡 + 你装的模块(配 ?wbCrash=1 才摆得出来):要看到坏的那张只剩一句\"这个模块起不来\",别的卡与面板壳都还在。",
3615
+ shape: { kind: "all" },
3616
+ expect: {
3617
+ cards: 1,
3618
+ empty: false
3619
+ }
3620
+ }
3621
+ ],
3622
+ EMPTY,
3623
+ UNREAD
3624
+ ];
3625
+ }
3626
+ var REAL_SHAPE = { kind: "real" };
3627
+ function useBoardMock(roster) {
3628
+ const [on] = useState(() => mockModeOn(window.location.search));
3629
+ const mocks = useMemo(() => on ? buildBoardMocks(roster) : [], [on, roster]);
3630
+ const [index, setIndex] = useState(0);
3631
+ const mock = mocks[index];
3632
+ return {
3633
+ mock,
3634
+ mocks,
3635
+ index,
3636
+ pick: setIndex,
3637
+ shape: mock?.shape ?? REAL_SHAPE
3638
+ };
3639
+ }
3640
+ //#endregion
3641
+ //#region src/app/layouts/rightbar/BoardMockStrip.tsx
3642
+ function BoardMockStrip({ fixtures, show }) {
3643
+ const current = fixtures.mock;
3644
+ if (!show || current === void 0) return null;
3645
+ return /* @__PURE__ */ h(MockStrip, {
3646
+ note: `夹具:只切形状,不碰真实配置;卡片上的数据看卡片夹具 —— ${current.note}`,
3647
+ mocks: fixtures.mocks,
3648
+ index: fixtures.index,
3649
+ onPick: fixtures.pick
3650
+ });
3651
+ }
3652
+ //#endregion
3653
+ //#region src/app/layouts/rightbar/panel-mock.ts
3654
+ function row$3(id, titleKey, shown) {
3655
+ return {
3656
+ id,
3657
+ titleKey,
3658
+ shown,
3659
+ source: "user",
3660
+ hasCard: true
3661
+ };
3662
+ }
3663
+ function noCardRow(id, titleKey) {
3664
+ return {
3665
+ id,
3666
+ titleKey,
3667
+ shown: false,
3668
+ source: "user",
3669
+ hasCard: false
3670
+ };
3671
+ }
3672
+ function plugin(id, pkg, title, shown) {
3673
+ return {
3674
+ id,
3675
+ pkg,
3676
+ title,
3677
+ shown,
3678
+ source: "user"
3679
+ };
3680
+ }
3681
+ var PLUGIN_MOCK = {
3682
+ id: "plugin",
3683
+ label: "opencli 插件行(标出是插件,能开能关)",
3684
+ units: [],
3685
+ plugins: [plugin("plugin:opencli-plugin-cmdb", "opencli-plugin-cmdb", "cmdb", true), plugin("plugin:opencli-plugin-notes", "opencli-plugin-notes", "notes", false)],
3686
+ capabilities: {},
3687
+ expect: { rows: 0 }
3688
+ };
3689
+ function probe$2(unit, status) {
3690
+ return { [unit]: {
3691
+ unit,
3692
+ status,
3693
+ required: [],
3694
+ missing: [],
3695
+ detail: "夹具"
3696
+ } };
3697
+ }
3698
+ function buildPanelMocks(roster) {
3699
+ const found = roster.find((manifest) => manifest.card !== null);
3700
+ if (found === void 0) return [{
3701
+ id: "empty",
3702
+ label: "列表空(都卸了/都关了)",
3703
+ units: [],
3704
+ capabilities: {},
3705
+ expect: { rows: 0 }
3706
+ }, PLUGIN_MOCK];
3707
+ const titleKey = found.card?.titleKey ?? found.id;
3708
+ const id = found.id;
3709
+ const on = row$3(id, titleKey, true);
3710
+ const off = row$3(id, titleKey, false);
3711
+ const twin = row$3(`${id}-b`, titleKey, true);
3712
+ const third = row$3(`${id}-c`, titleKey, false);
3713
+ return [
3714
+ {
3715
+ id: "one",
3716
+ label: "一行:已启用、装好了",
3717
+ units: [on],
3718
+ capabilities: probe$2(id, "ok"),
3719
+ expect: {
3720
+ rows: 1,
3721
+ badge: null,
3722
+ on: true
3723
+ }
3724
+ },
3725
+ {
3726
+ id: "off",
3727
+ label: "已停用(开关关着)",
3728
+ units: [off],
3729
+ capabilities: probe$2(id, "ok"),
3730
+ expect: {
3731
+ rows: 1,
3732
+ badge: null,
3733
+ on: false
3734
+ }
3735
+ },
3736
+ {
3737
+ id: "missing",
3738
+ label: "⚠ 没装好 → 不列(去市场装)",
3739
+ units: [on],
3740
+ capabilities: probe$2(id, "missing-plugin"),
3741
+ expect: { rows: 0 }
3742
+ },
3743
+ {
3744
+ id: "outdated",
3745
+ label: "⚠ 缺命令(也没装好)→ 同样不列",
3746
+ units: [on],
3747
+ capabilities: probe$2(id, "missing-commands"),
3748
+ expect: { rows: 0 }
3749
+ },
3750
+ {
3751
+ id: "unchecked",
3752
+ label: "⚠ 检测不了",
3753
+ units: [on],
3754
+ capabilities: probe$2(id, "unchecked"),
3755
+ expect: {
3756
+ rows: 1,
3757
+ badge: "panels.dep.unchecked",
3758
+ on: true
3759
+ }
3760
+ },
3761
+ {
3762
+ id: "checking",
3763
+ label: "还没探到(没有徽标)",
3764
+ units: [on],
3765
+ capabilities: null,
3766
+ expect: {
3767
+ rows: 1,
3768
+ badge: null,
3769
+ on: true
3770
+ }
3771
+ },
3772
+ {
3773
+ id: "many",
3774
+ label: "三行(顺序 / 停用混着)",
3775
+ units: [
3776
+ on,
3777
+ twin,
3778
+ third
3779
+ ],
3780
+ capabilities: {
3781
+ ...probe$2(id, "ok"),
3782
+ ...probe$2(`${id}-b`, "ok"),
3783
+ ...probe$2(`${id}-c`, "ok")
3784
+ },
3785
+ expect: {
3786
+ rows: 3,
3787
+ badge: null,
3788
+ on: true
3789
+ }
3790
+ },
3791
+ {
3792
+ id: "no-card",
3793
+ label: "没看板的模块(只有基座命令那种):也列出来、带「无看板」标签,开关照常能用,只是不参与排序",
3794
+ units: [on, noCardRow(`${id}-c`, `${titleKey}(无看板)`)],
3795
+ capabilities: {
3796
+ ...probe$2(id, "ok"),
3797
+ ...probe$2(`${id}-c`, "ok")
3798
+ },
3799
+ expect: {
3800
+ rows: 2,
3801
+ badge: null,
3802
+ on: true
3803
+ }
3804
+ },
3805
+ {
3806
+ id: "long",
3807
+ label: "超长模块名",
3808
+ units: [row$3(id, "一个名字特别特别长的模块用来验证省略号会不会把开关挤下去", true)],
3809
+ capabilities: probe$2(id, "ok"),
3810
+ expect: {
3811
+ rows: 1,
3812
+ badge: null
3813
+ }
3814
+ },
3815
+ {
3816
+ id: "hidden",
3817
+ label: "卸载后不显示(未启用 + 没装)",
3818
+ units: [off],
3819
+ capabilities: probe$2(id, "missing-plugin"),
3820
+ expect: { rows: 0 }
3821
+ },
3822
+ {
3823
+ id: "busy",
3824
+ label: "正在改配置(开关禁用)",
3825
+ units: [on, twin],
3826
+ capabilities: {
3827
+ ...probe$2(id, "ok"),
3828
+ ...probe$2(`${id}-b`, "ok")
3829
+ },
3830
+ busy: true,
3831
+ expect: { rows: 2 }
3832
+ },
3833
+ {
3834
+ id: "failed",
3835
+ label: "改配置失败(红字)",
3836
+ units: [on],
3837
+ capabilities: probe$2(id, "ok"),
3838
+ failed: true,
3839
+ expect: { rows: 1 }
3840
+ },
3841
+ {
3842
+ id: "drag",
3843
+ label: "拖动中的落点提示",
3844
+ units: [
3845
+ on,
3846
+ twin,
3847
+ third
3848
+ ],
3849
+ capabilities: {
3850
+ ...probe$2(id, "ok"),
3851
+ ...probe$2(`${id}-b`, "ok"),
3852
+ ...probe$2(`${id}-c`, "ok")
3853
+ },
3854
+ drag: {
3855
+ from: 1,
3856
+ over: 0,
3857
+ at: {
3858
+ x: 1230,
3859
+ y: 300
3860
+ }
3861
+ },
3862
+ expect: {
3863
+ rows: 3,
3864
+ on: true
3865
+ }
3866
+ },
3867
+ {
3868
+ id: "drag-off",
3869
+ label: "拖到未开启的那一行上:落点不亮(松手也不动)",
3870
+ units: [
3871
+ on,
3872
+ twin,
3873
+ third
3874
+ ],
3875
+ capabilities: {
3876
+ ...probe$2(id, "ok"),
3877
+ ...probe$2(`${id}-b`, "ok"),
3878
+ ...probe$2(`${id}-c`, "ok")
3879
+ },
3880
+ drag: {
3881
+ from: 0,
3882
+ over: null,
3883
+ at: {
3884
+ x: 1230,
3885
+ y: 300
3886
+ }
3887
+ },
3888
+ expect: {
3889
+ rows: 3,
3890
+ on: true
3891
+ }
3892
+ },
3893
+ PLUGIN_MOCK
3894
+ ];
3895
+ }
3896
+ //#endregion
3897
+ //#region src/app/layouts/rightbar/market-installed-mock.ts
3898
+ function installedMocks(input) {
3899
+ const { id, found, mine, probe } = input;
3900
+ return [
3901
+ {
3902
+ id: "no-supply",
3903
+ label: "没有环境依赖的模块(供给是基座命令那种):市场里有它这一行",
3904
+ manifests: [found],
3905
+ capabilities: probe(id, "ok"),
3906
+ installed: [{
3907
+ unit: id,
3908
+ pkg: "@dsh-workbench/module-one",
3909
+ installed: "0.1.2"
3910
+ }],
3911
+ expect: {
3912
+ rows: 1,
3913
+ state: "installed",
3914
+ actions: ["uninstall"],
3915
+ installed: 0,
3916
+ shared: 0
3917
+ }
3918
+ },
3919
+ {
3920
+ id: "no-card",
3921
+ label: "没有卡片的模块(只有基座命令那种):市场里有它这一行,有版本、有「更新」",
3922
+ manifests: [{
3923
+ ...found,
3924
+ card: null
3925
+ }],
3926
+ capabilities: probe(id, "ok"),
3927
+ updates: { [id]: {
3928
+ installed: "0.1.2",
3929
+ latest: "0.2.0"
3930
+ } },
3931
+ installed: [{
3932
+ unit: id,
3933
+ pkg: "@dsh-workbench/module-one",
3934
+ installed: "0.1.2"
3935
+ }],
3936
+ expect: {
3937
+ rows: 1,
3938
+ state: "outdated",
3939
+ actions: ["update-bundle", "uninstall"],
3940
+ version: {
3941
+ installed: "0.1.2",
3942
+ latest: "0.2.0"
3943
+ },
3944
+ installed: 0,
3945
+ shared: 0
3946
+ }
3947
+ },
3948
+ {
3949
+ id: "no-env-installed",
3950
+ label: "本机装着、又没有依赖要探(DIY 本地那份那种):写「已安装」,不是「状态未知」",
3951
+ manifests: [{
3952
+ ...found,
3953
+ env: void 0
3954
+ }],
3955
+ capabilities: {},
3956
+ updates: { [id]: { installed: "0.1.2" } },
3957
+ installed: [{
3958
+ unit: id,
3959
+ pkg: "@dsh-workbench/module-one",
3960
+ installed: "0.1.2"
3961
+ }],
3962
+ expect: {
3963
+ rows: 1,
3964
+ state: "installed",
3965
+ actions: ["uninstall"],
3966
+ version: { installed: "0.1.2" },
3967
+ installed: 0
3968
+ }
3969
+ },
3970
+ {
3971
+ id: "local-no-update",
3972
+ label: "本机那份(link: 装的):有「本地」标记、不给「更新」",
3973
+ manifests: [mine],
3974
+ capabilities: probe(id, "ok", { plugins: [{
3975
+ name: "fixture",
3976
+ status: "ok",
3977
+ missing: []
3978
+ }] }),
3979
+ updates: { [id]: {
3980
+ installed: "0.1.0",
3981
+ local: true
3982
+ } },
3983
+ installed: [{
3984
+ unit: id,
3985
+ pkg: "@dsh-workbench/module-one",
3986
+ installed: "0.1.0",
3987
+ local: true
3988
+ }],
3989
+ expect: {
3990
+ rows: 1,
3991
+ state: "installed",
3992
+ actions: ["uninstall"],
3993
+ local: true,
3994
+ version: { installed: "0.1.0" },
3995
+ installed: 0
3996
+ }
3997
+ },
3998
+ {
3999
+ id: "installed-refused",
4000
+ label: "本机装了,但宿主不认它的声明(行上说得出理由)",
4001
+ manifests: [],
4002
+ capabilities: {},
4003
+ installed: [{
4004
+ unit: id,
4005
+ pkg: "@dsh-workbench/module-one",
4006
+ installed: "0.1.2",
4007
+ refused: ["dsh.workbench 缺 apiVersion —— 协议从 v1 起,写 \"apiVersion\": 1"]
4008
+ }],
4009
+ expect: {
4010
+ rows: 0,
4011
+ installed: 1,
4012
+ installedState: "unusable",
4013
+ installedActions: ["remove-bundle"],
4014
+ installedNote: true
4015
+ }
4016
+ },
4017
+ {
4018
+ id: "installed-pending",
4019
+ label: "本机装了、宿主还没加载它(重启一次就会出来)",
4020
+ manifests: [],
4021
+ capabilities: {},
4022
+ installed: [{
4023
+ unit: id,
4024
+ pkg: "@dsh-workbench/module-one",
4025
+ installed: "0.1.2"
4026
+ }],
4027
+ expect: {
4028
+ rows: 0,
4029
+ installed: 1,
4030
+ installedState: "inactive",
4031
+ installedActions: ["remove-bundle"],
4032
+ installedHint: "panels.market.moduleRestartHint"
4033
+ }
4034
+ },
4035
+ {
4036
+ id: "installed-pending-update",
4037
+ label: "本机装了、还没加载 + 源上有新版(给「更新」,也说明要重启)",
4038
+ manifests: [],
4039
+ capabilities: {},
4040
+ installed: [{
4041
+ unit: id,
4042
+ pkg: "@dsh-workbench/module-one",
4043
+ installed: "0.1.0",
4044
+ latest: "0.1.2"
4045
+ }],
4046
+ expect: {
4047
+ rows: 0,
4048
+ installed: 1,
4049
+ installedState: "outdated",
4050
+ installedActions: ["update-bundle", "remove-bundle"],
4051
+ installedHint: "panels.market.moduleRestartHint"
4052
+ }
4053
+ },
4054
+ {
4055
+ id: "installed-confirm",
4056
+ label: "卸载本机模块(还没加载的那种:Modal 确认,标题是包名)",
4057
+ manifests: [],
4058
+ capabilities: {},
4059
+ installed: [{
4060
+ unit: id,
4061
+ pkg: "@dsh-workbench/module-one",
4062
+ installed: "0.1.2"
4063
+ }],
4064
+ confirming: id,
4065
+ expect: {
4066
+ rows: 0,
4067
+ installed: 1,
4068
+ installedState: "inactive",
4069
+ installedActions: ["remove-bundle"]
4070
+ }
4071
+ },
4072
+ {
4073
+ id: "first-paint",
4074
+ label: "刚进页面(检测中:能力与本机清单都还没结论)",
4075
+ manifests: [mine],
4076
+ capabilities: null,
4077
+ installedRead: false,
4078
+ loaded: false,
4079
+ expect: {
4080
+ rows: 1,
4081
+ state: "checking",
4082
+ actions: []
4083
+ }
4084
+ }
4085
+ ];
4086
+ }
4087
+ //#endregion
4088
+ //#region src/app/layouts/rightbar/market-mock.ts
4089
+ function installable(manifest) {
4090
+ return {
4091
+ ...manifest,
4092
+ env: {
4093
+ command: "opencli",
4094
+ plugins: [{
4095
+ name: "fixture",
4096
+ commands: ["x"]
4097
+ }]
4098
+ }
4099
+ };
4100
+ }
4101
+ function withEnvSource(manifest, env) {
4102
+ const [first, ...rest] = manifest.env?.plugins ?? [];
4103
+ if (first === void 0) return manifest;
4104
+ return {
4105
+ ...manifest,
4106
+ env: {
4107
+ ...manifest.env,
4108
+ plugins: [{
4109
+ ...first,
4110
+ installSource: {
4111
+ kind: "local",
4112
+ env
4113
+ }
4114
+ }, ...rest]
4115
+ }
4116
+ };
4117
+ }
4118
+ function withSecondNeed(manifest) {
4119
+ return {
4120
+ ...manifest,
4121
+ env: {
4122
+ ...manifest.env,
4123
+ plugins: [...manifest.env?.plugins ?? [], {
4124
+ name: "fixture-second",
4125
+ commands: ["y"]
4126
+ }]
4127
+ }
4128
+ };
4129
+ }
4130
+ function twin(manifest) {
4131
+ return {
4132
+ ...manifest,
4133
+ id: `${manifest.id}-b`
4134
+ };
4135
+ }
4136
+ function copies(manifest, count) {
4137
+ return Array.from({ length: count }, (_, index) => ({
4138
+ ...manifest,
4139
+ id: `${manifest.id}-${index}`,
4140
+ env: {
4141
+ ...manifest.env,
4142
+ plugins: [{
4143
+ name: `fixture-${index}`,
4144
+ commands: manifest.env?.plugins?.[0]?.commands ?? []
4145
+ }]
4146
+ }
4147
+ }));
4148
+ }
4149
+ function probe$1(unit, status, extra = {}) {
4150
+ return { [unit]: {
4151
+ unit,
4152
+ status,
4153
+ required: ["x"],
4154
+ missing: [],
4155
+ detail: "夹具",
4156
+ ...extra
4157
+ } };
4158
+ }
4159
+ function buildMarketMocks(roster) {
4160
+ const found = roster.find((manifest) => manifest.card !== null);
4161
+ if (found === void 0) return [{
4162
+ id: "empty",
4163
+ label: "市场空态",
4164
+ manifests: [],
4165
+ capabilities: {},
4166
+ expect: { rows: 0 }
4167
+ }];
4168
+ const mine = installable(found);
4169
+ const second = twin(mine);
4170
+ const id = mine.id;
4171
+ const secondId = second.id;
4172
+ return [
4173
+ {
4174
+ id: "installed",
4175
+ label: "已装",
4176
+ manifests: [mine],
4177
+ capabilities: probe$1(id, "ok", { plugins: [{
4178
+ name: "fixture",
4179
+ status: "ok",
4180
+ missing: []
4181
+ }] }),
4182
+ expect: {
4183
+ rows: 1,
4184
+ state: "installed",
4185
+ actions: ["uninstall"],
4186
+ shared: 1,
4187
+ sharedActions: []
4188
+ }
4189
+ },
4190
+ {
4191
+ id: "outdated",
4192
+ label: "要更新",
4193
+ manifests: [mine],
4194
+ capabilities: probe$1(id, "missing-commands", { missing: ["x"] }),
4195
+ expect: {
4196
+ rows: 1,
4197
+ state: "outdated",
4198
+ actions: ["update", "uninstall"],
4199
+ noteKey: "panels.market.needCommands"
4200
+ }
4201
+ },
4202
+ {
4203
+ id: "module-update",
4204
+ label: "模块包有新版(行上给「更新」,装了要重启)",
4205
+ manifests: [mine],
4206
+ capabilities: probe$1(id, "ok", { plugins: [{
4207
+ name: "fixture",
4208
+ status: "ok",
4209
+ missing: []
4210
+ }] }),
4211
+ updates: { [id]: {
4212
+ installed: "0.1.2",
4213
+ latest: "0.2.0"
4214
+ } },
4215
+ expect: {
4216
+ rows: 1,
4217
+ state: "outdated",
4218
+ actions: ["update-bundle", "uninstall"],
4219
+ shared: 1,
4220
+ sharedActions: []
4221
+ }
4222
+ },
4223
+ {
4224
+ id: "outdated-release",
4225
+ label: "源上有新版(模块行不变,共用依赖行给「更新」)",
4226
+ manifests: [mine],
4227
+ capabilities: probe$1(id, "ok", { plugins: [{
4228
+ name: "fixture",
4229
+ status: "outdated",
4230
+ missing: [],
4231
+ release: {
4232
+ installed: "1.0.16",
4233
+ latest: "1.0.17"
4234
+ }
4235
+ }] }),
4236
+ expect: {
4237
+ rows: 1,
4238
+ state: "installed",
4239
+ actions: ["uninstall"],
4240
+ shared: 1,
4241
+ sharedActions: ["update-dependency"]
4242
+ }
4243
+ },
4244
+ {
4245
+ id: "missing",
4246
+ label: "未装(可装)",
4247
+ manifests: [mine],
4248
+ capabilities: probe$1(id, "missing-plugin", {
4249
+ install: "ready",
4250
+ plugins: [{
4251
+ name: "fixture",
4252
+ status: "missing",
4253
+ missing: ["x"],
4254
+ install: "ready"
4255
+ }]
4256
+ }),
4257
+ expect: {
4258
+ rows: 1,
4259
+ state: "missing",
4260
+ actions: ["install"],
4261
+ shared: 1,
4262
+ sharedActions: []
4263
+ }
4264
+ },
4265
+ {
4266
+ id: "missing-env",
4267
+ label: "未装 + 要先设环境变量",
4268
+ manifests: [withEnvSource(mine, "WB_FIXTURE_HOME")],
4269
+ capabilities: probe$1(id, "missing-plugin", { install: "env-missing" }),
4270
+ expect: {
4271
+ rows: 1,
4272
+ state: "missing",
4273
+ actions: []
4274
+ }
4275
+ },
4276
+ {
4277
+ id: "missing-undeclared",
4278
+ label: "未装 + 没声明怎么装",
4279
+ manifests: [mine],
4280
+ capabilities: probe$1(id, "missing-plugin", { install: "not-declared" }),
4281
+ expect: {
4282
+ rows: 1,
4283
+ state: "missing",
4284
+ actions: []
4285
+ }
4286
+ },
4287
+ {
4288
+ id: "unknown",
4289
+ label: "探测失败(状态未知)",
4290
+ manifests: [mine],
4291
+ capabilities: {},
4292
+ expect: {
4293
+ rows: 1,
4294
+ state: "unknown",
4295
+ actions: []
4296
+ }
4297
+ },
4298
+ {
4299
+ id: "checking",
4300
+ label: "检测中",
4301
+ manifests: [mine],
4302
+ capabilities: null,
4303
+ expect: {
4304
+ rows: 1,
4305
+ state: "checking",
4306
+ actions: []
4307
+ }
4308
+ },
4309
+ {
4310
+ id: "shared",
4311
+ label: "两个模块(第二行是复制的)",
4312
+ manifests: [mine, second],
4313
+ capabilities: {
4314
+ ...probe$1(id, "ok"),
4315
+ ...probe$1(secondId, "ok")
4316
+ },
4317
+ expect: {
4318
+ rows: 2,
4319
+ state: "installed",
4320
+ actions: ["uninstall"],
4321
+ shared: 1
4322
+ }
4323
+ },
4324
+ {
4325
+ id: "busy",
4326
+ label: "正在装",
4327
+ manifests: [mine],
4328
+ capabilities: probe$1(id, "missing-plugin", { install: "ready" }),
4329
+ pending: {
4330
+ id,
4331
+ action: "install"
4332
+ },
4333
+ expect: {
4334
+ rows: 1,
4335
+ state: "missing",
4336
+ actions: ["install"]
4337
+ }
4338
+ },
4339
+ {
4340
+ id: "confirm",
4341
+ label: "等确认卸载",
4342
+ manifests: [mine],
4343
+ capabilities: probe$1(id, "ok"),
4344
+ confirming: id,
4345
+ expect: {
4346
+ rows: 1,
4347
+ state: "installed",
4348
+ actions: ["uninstall"]
4349
+ }
4350
+ },
4351
+ {
4352
+ id: "failed",
4353
+ label: "失败(红字贴行)",
4354
+ manifests: [mine],
4355
+ capabilities: probe$1(id, "ok"),
4356
+ failure: {
4357
+ id,
4358
+ message: "没成功:命令失败(退出码 1):夹具里的一条失败原因"
4359
+ },
4360
+ expect: {
4361
+ rows: 1,
4362
+ state: "installed",
4363
+ actions: ["uninstall"]
4364
+ }
4365
+ },
4366
+ {
4367
+ id: "long-title",
4368
+ label: "超长模块名",
4369
+ manifests: [{
4370
+ ...mine,
4371
+ card: {
4372
+ titleKey: "一个名字特别特别长的模块用来验证省略号会不会把按钮挤下去",
4373
+ order: 10
4374
+ }
4375
+ }],
4376
+ capabilities: probe$1(id, "ok"),
4377
+ expect: {
4378
+ rows: 1,
4379
+ state: "installed",
4380
+ actions: ["uninstall"],
4381
+ titleChars: 25
4382
+ }
4383
+ },
4384
+ {
4385
+ id: "long-env",
4386
+ label: "超长环境变量名",
4387
+ manifests: [withEnvSource(mine, "DSH_WORKBENCH_SOMETHING_VERY_LONG_ENV_NAME_FOR_THE_MODULE")],
4388
+ capabilities: probe$1(id, "missing-plugin", { install: "env-missing" }),
4389
+ expect: {
4390
+ rows: 1,
4391
+ state: "missing",
4392
+ actions: []
4393
+ }
4394
+ },
4395
+ {
4396
+ id: "long-error",
4397
+ label: "超长错误信息",
4398
+ manifests: [mine],
4399
+ capabilities: probe$1(id, "ok"),
4400
+ failure: {
4401
+ id,
4402
+ message: "没成功:命令失败(退出码 1):Error: EPERM: operation not permitted, unlink '/Users/someone/.dsh/workbench/opencli/home/.opencli/plugins/example-permission-copy-with-a-very-long-directory-name'"
4403
+ },
4404
+ expect: {
4405
+ rows: 1,
4406
+ state: "installed",
4407
+ actions: ["uninstall"]
4408
+ }
4409
+ },
4410
+ {
4411
+ id: "two-deps",
4412
+ label: "两份依赖(只装缺的)",
4413
+ manifests: [withSecondNeed(mine)],
4414
+ capabilities: probe$1(id, "missing-plugin", {
4415
+ install: "ready",
4416
+ plugins: [{
4417
+ name: "fixture",
4418
+ status: "ok",
4419
+ missing: []
4420
+ }, {
4421
+ name: "fixture-second",
4422
+ status: "missing",
4423
+ missing: ["y"],
4424
+ install: "ready"
4425
+ }]
4426
+ }),
4427
+ expect: {
4428
+ rows: 1,
4429
+ state: "missing",
4430
+ actions: ["install"]
4431
+ }
4432
+ },
4433
+ {
4434
+ id: "many",
4435
+ label: "很多行(要滚)",
4436
+ manifests: [mine, ...copies(mine, 13)],
4437
+ capabilities: Object.fromEntries([id, ...copies(mine, 13).map((item) => item.id)].map((unit) => [unit, probe$1(unit, "ok")[unit]])),
4438
+ expect: {
4439
+ rows: 14,
4440
+ state: "installed",
4441
+ actions: ["uninstall"]
4442
+ }
4443
+ },
4444
+ ...installedMocks({
4445
+ id,
4446
+ found,
4447
+ mine,
4448
+ probe: probe$1
4449
+ }),
4450
+ {
4451
+ id: "shared-many",
4452
+ label: "三个模块(同一份安装)",
4453
+ manifests: [
4454
+ mine,
4455
+ twin(mine),
4456
+ {
4457
+ ...twin(mine),
4458
+ id: `${mine.id}-c`
4459
+ }
4460
+ ],
4461
+ capabilities: {
4462
+ ...probe$1(id, "ok"),
4463
+ ...probe$1(secondId, "ok"),
4464
+ ...probe$1(`${mine.id}-c`, "ok")
4465
+ },
4466
+ expect: {
4467
+ rows: 3,
4468
+ state: "installed",
4469
+ actions: ["uninstall"]
4470
+ }
4471
+ },
4472
+ {
4473
+ id: "plugin-outdated",
4474
+ label: "用户装的 opencli 插件:有新版(给更新 / 卸载)",
4475
+ manifests: [],
4476
+ capabilities: {},
4477
+ plugins: [{
4478
+ pkg: "opencli-plugin-cmdb",
4479
+ name: "cmdb",
4480
+ installed: "1.0.24",
4481
+ latest: "1.0.25"
4482
+ }],
4483
+ expect: {
4484
+ rows: 0,
4485
+ plugins: 1,
4486
+ pluginActions: ["update-plugin", "uninstall-plugin"]
4487
+ }
4488
+ },
4489
+ {
4490
+ id: "plugin-local",
4491
+ label: "本地目录装的 opencli 插件:没有版本源,只给卸载",
4492
+ manifests: [],
4493
+ capabilities: {},
4494
+ plugins: [{
4495
+ pkg: "/Users/me/my-local-plugin",
4496
+ name: "my-local-plugin",
4497
+ local: true
4498
+ }],
4499
+ expect: {
4500
+ rows: 0,
4501
+ plugins: 1,
4502
+ pluginActions: ["uninstall-plugin"],
4503
+ pluginNote: false
4504
+ }
4505
+ },
4506
+ {
4507
+ id: "plugin-alias",
4508
+ label: "插件名 ≠ 包名:行上两个都写出来(更新 / 卸载按包名)",
4509
+ manifests: [],
4510
+ capabilities: {},
4511
+ plugins: [{
4512
+ pkg: "opencli-plugin-cmdb",
4513
+ name: "cmdb",
4514
+ installed: "1.0.24",
4515
+ latest: "1.0.25"
4516
+ }],
4517
+ expect: {
4518
+ rows: 0,
4519
+ plugins: 1,
4520
+ pluginActions: ["update-plugin", "uninstall-plugin"]
4521
+ }
4522
+ },
4523
+ {
4524
+ id: "plugin-broken",
4525
+ label: "装坏了的那一份(目录在但看不出是个插件):行上直说,给卸载与指路",
4526
+ manifests: [],
4527
+ capabilities: {},
4528
+ plugins: [{
4529
+ pkg: "opencli-plugin-cmdb",
4530
+ name: "cmdb",
4531
+ installed: "1.0.24",
4532
+ broken: true
4533
+ }],
4534
+ expect: {
4535
+ rows: 0,
4536
+ plugins: 1,
4537
+ pluginState: "broken",
4538
+ pluginActions: ["uninstall-plugin"],
4539
+ pluginNoteKey: "panels.market.pluginBroken"
4540
+ }
4541
+ },
4542
+ {
4543
+ id: "plugin-kept",
4544
+ label: "卸掉用户装的插件,但还有模块在用:文件先留着(行上给一句为什么)",
4545
+ manifests: [],
4546
+ capabilities: {},
4547
+ plugins: [{
4548
+ pkg: "opencli-plugin-cmdb",
4549
+ name: "cmdb",
4550
+ installed: "1.0.24"
4551
+ }],
4552
+ notice: "文件先留着:cmdb、argocd 还要用它。",
4553
+ expect: {
4554
+ rows: 0,
4555
+ plugins: 1,
4556
+ pluginActions: ["uninstall-plugin"],
4557
+ notice: true
4558
+ }
4559
+ },
4560
+ {
4561
+ id: "workbench-update",
4562
+ label: "工作台有新版(这一行也给「更新」,装完面板自己换上)",
4563
+ manifests: [],
4564
+ capabilities: {},
4565
+ workbench: {
4566
+ pkg: "@dsh-workbench/core",
4567
+ installed: "0.1.18",
4568
+ latest: "0.1.19"
4569
+ },
4570
+ expect: {
4571
+ rows: 0,
4572
+ workbenchState: "outdated",
4573
+ workbenchActions: ["update-workbench"]
4574
+ }
4575
+ },
4576
+ {
4577
+ id: "workbench-current",
4578
+ label: "工作台已经最新(只显示版本,没有按钮)",
4579
+ manifests: [],
4580
+ capabilities: {},
4581
+ workbench: {
4582
+ pkg: "@dsh-workbench/core",
4583
+ installed: "0.1.19"
4584
+ },
4585
+ expect: {
4586
+ rows: 0,
4587
+ workbenchState: "installed",
4588
+ workbenchActions: []
4589
+ }
4590
+ },
4591
+ {
4592
+ id: "workbench-local",
4593
+ label: "工作台是本仓那份(link: 装的:不给更新,行上说清)",
4594
+ manifests: [],
4595
+ capabilities: {},
4596
+ workbench: {
4597
+ pkg: "@dsh-workbench/core",
4598
+ installed: "0.1.18",
4599
+ latest: "0.1.19",
4600
+ local: true
4601
+ },
4602
+ expect: {
4603
+ rows: 0,
4604
+ workbenchState: "installed",
4605
+ workbenchActions: [],
4606
+ workbenchNoteKey: "panels.market.workbenchLocal"
4607
+ }
4608
+ },
4609
+ {
4610
+ id: "workbench-updated",
4611
+ label: "工作台刚更新完(新版已经在盘上:行上就是新版,没有按钮、也不劝人重启)",
4612
+ manifests: [],
4613
+ capabilities: {},
4614
+ workbench: {
4615
+ pkg: "@dsh-workbench/core",
4616
+ installed: "0.1.19"
4617
+ },
4618
+ expect: {
4619
+ rows: 0,
4620
+ workbenchState: "installed",
4621
+ workbenchActions: []
4622
+ }
4623
+ },
4624
+ {
4625
+ id: "workbench-restart-pending",
4626
+ label: "工作台更新完了但这份进程里还是旧的(盘上 0.1.19、跑着的 0.1.18:状态那格是红点「重启后生效」——重启一次 dsh 才真的换上)",
4627
+ manifests: [],
4628
+ capabilities: {},
4629
+ workbench: {
4630
+ pkg: "@dsh-workbench/core",
4631
+ installed: "0.1.19",
4632
+ running: "0.1.18"
4633
+ },
4634
+ expect: {
4635
+ rows: 0,
4636
+ workbenchState: "pending-restart",
4637
+ workbenchActions: []
4638
+ }
4639
+ },
4640
+ {
4641
+ id: "workbench-restart-pending-local",
4642
+ label: "本仓那份(link: 装的)永远等于盘上那份 → 不亮这句、也不劝重启",
4643
+ manifests: [],
4644
+ capabilities: {},
4645
+ workbench: {
4646
+ pkg: "@dsh-workbench/core",
4647
+ installed: "0.1.19",
4648
+ running: "0.1.18",
4649
+ local: true
4650
+ },
4651
+ expect: {
4652
+ rows: 0,
4653
+ workbenchState: "installed",
4654
+ workbenchActions: []
4655
+ }
4656
+ },
4657
+ {
4658
+ id: "empty",
4659
+ label: "市场空态",
4660
+ manifests: [],
4661
+ capabilities: {},
4662
+ expect: {
4663
+ rows: 0,
4664
+ shared: 0
4665
+ }
4666
+ }
4667
+ ];
4668
+ }
4669
+ //#endregion
4670
+ //#region src/app/layouts/market/add-module-mock.ts
4671
+ function change(over) {
4672
+ return {
4673
+ application: "applied",
4674
+ stage: "install",
4675
+ changed: true,
4676
+ target: "@dsh-workbench/module-hello",
4677
+ ...over
4678
+ };
4679
+ }
4680
+ function outcome(over, supply = { state: "installed" }) {
4681
+ return {
4682
+ change: change(over),
4683
+ module: {
4684
+ kind: "module",
4685
+ pkg: "@dsh-workbench/module-hello",
4686
+ unit: "hello",
4687
+ version: "0.1.2"
4688
+ },
4689
+ supply
4690
+ };
4691
+ }
4692
+ function refused(problem, reason = "") {
4693
+ return {
4694
+ id: `refused-${problem}`,
4695
+ label: `预检拒:${problem}`,
4696
+ phase: "idle",
4697
+ spec: "@dsh-workbench/module-nope",
4698
+ problem: {
4699
+ problem,
4700
+ reason
4701
+ }
4702
+ };
4703
+ }
4704
+ var ADD_MODULE_MOCKS = [
4705
+ {
4706
+ id: "empty",
4707
+ label: "刚打开",
4708
+ phase: "idle",
4709
+ spec: ""
4710
+ },
4711
+ {
4712
+ id: "typed",
4713
+ label: "填了包名",
4714
+ phase: "idle",
4715
+ spec: "@dsh-workbench/module-hello"
4716
+ },
4717
+ {
4718
+ id: "guide",
4719
+ label: "展开了示例",
4720
+ phase: "idle",
4721
+ spec: "",
4722
+ guideOpen: true
4723
+ },
4724
+ {
4725
+ id: "inspecting",
4726
+ label: "正在预检",
4727
+ phase: "inspecting",
4728
+ spec: "@dsh-workbench/module-hello"
4729
+ },
4730
+ refused("invalid-spec"),
4731
+ refused("already-installed", "已经在 profile 里:@dsh-workbench/module-hello@0.1.2"),
4732
+ refused("not-found"),
4733
+ refused("not-a-package"),
4734
+ refused("not-a-bundle"),
4735
+ refused("not-a-module-or-plugin", "这个包既不是工作台的模块,也不是 opencli 的插件,装了也用不上"),
4736
+ refused("network", "getaddrinfo ENOTFOUND registry.example.com"),
4737
+ refused("unknown", "pnpm 的返回码是 1"),
4738
+ {
4739
+ id: "preview",
4740
+ label: "预览(可装)",
4741
+ phase: "preview",
4742
+ spec: "@dsh-workbench/module-hello",
4743
+ preview: {
4744
+ kind: "module",
4745
+ name: "@dsh-workbench/module-hello",
4746
+ version: "0.1.2",
4747
+ description: "最小样本模块:一枚「你好」卡片",
4748
+ registry: "registry.npmmirror.com"
4749
+ }
4750
+ },
4751
+ {
4752
+ id: "preview-no-source",
4753
+ label: "预览(问不出源)",
4754
+ phase: "preview",
4755
+ spec: "@dsh-workbench/module-hello",
4756
+ preview: {
4757
+ kind: "module",
4758
+ name: "@dsh-workbench/module-hello",
4759
+ version: "",
4760
+ description: "",
4761
+ registry: ""
4762
+ }
4763
+ },
4764
+ {
4765
+ id: "preview-plugin",
4766
+ label: "预览(opencli 插件)",
4767
+ phase: "preview",
4768
+ spec: "opencli-plugin-grafana",
4769
+ preview: {
4770
+ kind: "plugin",
4771
+ name: "opencli-plugin-grafana",
4772
+ version: "1.0.16",
4773
+ description: "",
4774
+ registry: "registry.npmmirror.com",
4775
+ pluginName: "grafana"
4776
+ }
4777
+ },
4778
+ {
4779
+ id: "installing",
4780
+ label: "正在安装(可取消)",
4781
+ phase: "installing",
4782
+ spec: "@dsh-workbench/module-hello"
4783
+ },
4784
+ {
4785
+ id: "needs-approval",
4786
+ label: "安装脚本待批",
4787
+ phase: "result",
4788
+ spec: "@dsh-workbench/module-hello",
4789
+ outcome: {
4790
+ ...outcome({
4791
+ application: "failed",
4792
+ stage: "install",
4793
+ errorCode: "build-blocked",
4794
+ pendingBuilds: ["esbuild", "sharp"]
4795
+ }),
4796
+ supply: {
4797
+ state: "failed",
4798
+ reason: "装上之前得先允许安装脚本"
4799
+ }
4800
+ }
4801
+ },
4802
+ {
4803
+ id: "failed-registry",
4804
+ label: "失败:源上没有",
4805
+ phase: "result",
4806
+ spec: "@dsh-workbench/module-nope",
4807
+ outcome: outcome({
4808
+ application: "failed",
4809
+ stage: "install",
4810
+ failedAt: "registry",
4811
+ errorCode: "not-found"
4812
+ })
4813
+ },
4814
+ {
4815
+ id: "failed-pnpm",
4816
+ label: "失败:pnpm 执行出错",
4817
+ phase: "result",
4818
+ spec: "@dsh-workbench/module-hello",
4819
+ outcome: outcome({
4820
+ application: "failed",
4821
+ stage: "install",
4822
+ errorCode: "operation-error",
4823
+ errorDetail: "ERR_PNPM_FETCH_404 GET https://registry.example.com/@dsh-workbench%2Fmodule-hello: Not Found"
4824
+ })
4825
+ },
4826
+ {
4827
+ id: "done-applied",
4828
+ label: "装好了(已生效)",
4829
+ phase: "result",
4830
+ spec: "@dsh-workbench/module-hello",
4831
+ outcome: outcome({})
4832
+ },
4833
+ {
4834
+ id: "done-plugin",
4835
+ label: "装好了(opencli 插件)",
4836
+ phase: "result",
4837
+ spec: "opencli-plugin-cmdb",
4838
+ outcome: {
4839
+ change: change({ target: "opencli-plugin-cmdb" }),
4840
+ module: {
4841
+ kind: "unknown",
4842
+ pkg: "opencli-plugin-cmdb"
4843
+ },
4844
+ supply: { state: "no-needs" },
4845
+ plugin: {
4846
+ kind: "opencli-plugin",
4847
+ pkg: "opencli-plugin-cmdb",
4848
+ name: "cmdb"
4849
+ }
4850
+ }
4851
+ },
4852
+ {
4853
+ id: "done-restart",
4854
+ label: "装好了(要重启,并说清是哪种:这一格是「某个已装的包换了目录」)",
4855
+ phase: "result",
4856
+ spec: "@dsh-workbench/module-hello",
4857
+ outcome: outcome({
4858
+ application: "restart-required",
4859
+ restartReason: "package-moved"
4860
+ }, { state: "pending-restart" })
4861
+ },
4862
+ {
4863
+ id: "not-a-module",
4864
+ label: "装进来的不是模块",
4865
+ phase: "result",
4866
+ spec: "some-random-package",
4867
+ outcome: {
4868
+ change: change({ target: "some-random-package" }),
4869
+ module: {
4870
+ kind: "not-module",
4871
+ pkg: "some-random-package"
4872
+ },
4873
+ supply: { state: "not-a-module" }
4874
+ }
4875
+ },
4876
+ {
4877
+ id: "cancelled",
4878
+ label: "已取消",
4879
+ phase: "result",
4880
+ spec: "@dsh-workbench/module-hello",
4881
+ outcome: outcome({
4882
+ application: "cancelled",
4883
+ changed: false
4884
+ }, { state: "no-needs" })
4885
+ },
4886
+ {
4887
+ id: "done-no-needs",
4888
+ label: "装好了(不要额外供给)",
4889
+ phase: "result",
4890
+ spec: "@dsh-workbench/module-plain",
4891
+ outcome: {
4892
+ change: change({ target: "@dsh-workbench/module-plain" }),
4893
+ module: {
4894
+ kind: "module",
4895
+ pkg: "@dsh-workbench/module-plain",
4896
+ unit: "plain",
4897
+ version: "1.0.0"
4898
+ },
4899
+ supply: { state: "no-needs" }
4900
+ }
4901
+ },
4902
+ {
4903
+ id: "removed",
4904
+ label: "移除掉了",
4905
+ phase: "result",
4906
+ spec: "some-random-package",
4907
+ outcome: {
4908
+ change: change({
4909
+ stage: "remove",
4910
+ target: "some-random-package"
4911
+ }),
4912
+ module: {
4913
+ kind: "not-module",
4914
+ pkg: "some-random-package"
4915
+ },
4916
+ supply: { state: "not-a-module" }
4917
+ }
4918
+ }
4919
+ ];
4920
+ var frozen = () => {};
4921
+ function stateOfMock(base, mock) {
4922
+ return {
4923
+ ...base,
4924
+ spec: mock.spec,
4925
+ guideOpen: mock.guideOpen ?? false,
4926
+ phase: mock.phase,
4927
+ choices: base.choices,
4928
+ custom: "",
4929
+ registryOpen: false,
4930
+ problem: mock.problem ?? null,
4931
+ preview: mock.preview ?? null,
4932
+ outcome: mock.outcome ?? null,
4933
+ failure: mock.failure ?? null,
4934
+ builds: mock.outcome?.change.pendingBuilds ?? [],
4935
+ setSpec: frozen,
4936
+ setChoice: frozen,
4937
+ setCustom: frozen,
4938
+ toggleRegistry: frozen,
4939
+ closeRegistry: frozen,
4940
+ toggleGuide: frozen,
4941
+ check: frozen,
4942
+ edit: frozen,
4943
+ install: frozen,
4944
+ cancelInstall: frozen,
4945
+ removeIt: frozen
4946
+ };
4947
+ }
4948
+ //#endregion
4949
+ //#region src/app/layouts/rightbar/registry.ts
4950
+ function createBoardRegistry() {
4951
+ const modules = [];
4952
+ const listeners = /* @__PURE__ */ new Set();
4953
+ let revision = 0;
4954
+ let sorted = [];
4955
+ let index = /* @__PURE__ */ new Map();
4956
+ let steps = /* @__PURE__ */ new Map();
4957
+ function rebuild() {
4958
+ sorted = [...modules].sort((a, b) => a.order - b.order || a.id.localeCompare(b.id));
4959
+ index = new Map(sorted.map((module) => [module.id, module]));
4960
+ const table = /* @__PURE__ */ new Map();
4961
+ for (const module of sorted) for (const kind of Object.keys(module.steps ?? {})) {
4962
+ const owner = table.get(kind);
4963
+ if (owner !== void 0) throw new Error(`看板层名重复:${kind}(${owner.id} 与 ${module.id} 都声明了它)`);
4964
+ table.set(kind, module);
4965
+ }
4966
+ steps = table;
4967
+ }
4968
+ function notify() {
4969
+ revision += 1;
4970
+ for (const listener of listeners) listener();
4971
+ }
4972
+ return {
4973
+ register(module) {
4974
+ if (modules.some((item) => item.id === module.id)) throw new Error(`看板模块 id 重复:${module.id}(id 会进持久化配置,不能撞)`);
4975
+ modules.push(module);
4976
+ try {
4977
+ rebuild();
4978
+ } catch (error) {
4979
+ modules.pop();
4980
+ rebuild();
4981
+ throw error;
4982
+ }
4983
+ notify();
4984
+ return () => {
4985
+ const at = modules.indexOf(module);
4986
+ if (at < 0) return;
4987
+ modules.splice(at, 1);
4988
+ rebuild();
4989
+ notify();
4990
+ };
4991
+ },
4992
+ all: () => sorted,
4993
+ byId: (id) => index.get(id),
4994
+ stepOwner: (kind) => steps.get(kind),
4995
+ subscribe(listener) {
4996
+ listeners.add(listener);
4997
+ return () => listeners.delete(listener);
4998
+ },
4999
+ version: () => revision
5000
+ };
5001
+ }
5002
+ //#endregion
5003
+ //#region src/app/units/registry.ts
5004
+ function toBoardModule(face, manifest) {
5005
+ const View = face.card;
5006
+ if (View === void 0) return void 0;
5007
+ return {
5008
+ id: manifest.id,
5009
+ titleKey: manifest.card?.titleKey ?? manifest.id,
5010
+ order: manifest.card?.order ?? 100,
5011
+ View,
5012
+ ...face.steps === void 0 ? {} : { steps: face.steps }
5013
+ };
5014
+ }
5015
+ function createClientUnitRegistry(options = {}) {
5016
+ const registrations = [];
5017
+ const refusals = [];
5018
+ const listeners = /* @__PURE__ */ new Set();
5019
+ const board = createBoardRegistry();
5020
+ let known = /* @__PURE__ */ new Map();
5021
+ let installableIds = null;
5022
+ let revision = 0;
5023
+ let manifestsCache;
5024
+ function notify() {
5025
+ revision += 1;
5026
+ for (const listener of [...listeners]) try {
5027
+ listener();
5028
+ } catch (error) {
5029
+ console.warn(`[dsh-workbench] 套件注册的订阅者报错(不影响其它订阅者与这次注册):${String(error)}`);
5030
+ }
5031
+ }
5032
+ function warnRefusal(unit, kind, reasons) {
5033
+ refusals.push({
5034
+ unit,
5035
+ kind,
5036
+ reasons
5037
+ });
5038
+ console.warn(`[dsh-workbench] ${unit === "" ? "这个模块" : unit} 的卡片没挂上:${reasons.join(";")}`);
5039
+ }
5040
+ function takeBackRefusal(unit) {
5041
+ for (let at = refusals.length - 1; at >= 0; at -= 1) if (refusals[at]?.unit === unit) refusals.splice(at, 1);
5042
+ }
5043
+ function attach(entry) {
5044
+ const manifest = known.get(entry.unit);
5045
+ if (manifest === void 0) return false;
5046
+ const boardModule = toBoardModule(entry.face, manifest);
5047
+ entry.mounted = {
5048
+ manifest,
5049
+ unmount: boardModule === void 0 ? () => {} : board.register(boardModule)
5050
+ };
5051
+ takeBackRefusal(entry.unit);
5052
+ return true;
5053
+ }
5054
+ function detach(entry) {
5055
+ entry.mounted?.unmount();
5056
+ entry.mounted = null;
5057
+ }
5058
+ return {
5059
+ register(face) {
5060
+ const unit = typeof face?.unit === "string" ? face.unit.trim() : "";
5061
+ if (unit === "") {
5062
+ warnRefusal("", "old-shape", ["registerUnit({ unit, card }) 里的 unit 是空的 —— U1b 之前的旧形状是 registerUnit({ manifest, card });现在清单由外壳从**已装清单**读出来、按 unit 交给浏览器(ADR-0038 §2.2)"]);
5063
+ notify();
5064
+ return () => {};
5065
+ }
5066
+ if (registrations.some((entry) => entry.unit === unit)) throw new Error(`套件 id 重复:${unit}(id 会进持久化配置,不能撞)`);
5067
+ const entry = {
5068
+ face,
5069
+ unit,
5070
+ mounted: null
5071
+ };
5072
+ registrations.push(entry);
5073
+ manifestsCache = void 0;
5074
+ if (!attach(entry)) {
5075
+ warnRefusal(unit, "no-manifest", [`宿主没有担保 unit「${unit}」的清单 —— 这个包要么没装进这份 profile,要么它的 dsh.workbench 没通过校验。卡片先不挂:清单只有一处真相(ADR-0038 §2.2)`]);
5076
+ options.onUnknownUnit?.(unit);
5077
+ }
5078
+ notify();
5079
+ return () => {
5080
+ const at = registrations.indexOf(entry);
5081
+ if (at < 0) return;
5082
+ registrations.splice(at, 1);
5083
+ detach(entry);
5084
+ takeBackRefusal(unit);
5085
+ manifestsCache = void 0;
5086
+ notify();
5087
+ };
5088
+ },
5089
+ all: () => registrations.map((entry) => entry.face),
5090
+ manifests: () => {
5091
+ manifestsCache ??= registrations.flatMap((entry) => entry.mounted === null ? [] : [entry.mounted.manifest]);
5092
+ return manifestsCache;
5093
+ },
5094
+ refusals: () => refusals,
5095
+ installable: () => installableIds,
5096
+ setManifests(manifests, installable) {
5097
+ known = new Map(manifests.map((manifest) => [manifest.id, manifest]));
5098
+ installableIds = installable === void 0 ? null : new Set(installable);
5099
+ let changed = false;
5100
+ for (const entry of registrations) {
5101
+ const next = known.get(entry.unit);
5102
+ if (entry.mounted === null) {
5103
+ if (next !== void 0 && attach(entry)) changed = true;
5104
+ continue;
5105
+ }
5106
+ if (next === void 0) {
5107
+ detach(entry);
5108
+ warnRefusal(entry.unit, "withdrawn", [`宿主不再担保 unit「${entry.unit}」的清单(模块被卸了?)—— 这张卡片先摘下来`]);
5109
+ changed = true;
5110
+ }
5111
+ }
5112
+ if (!changed) return;
5113
+ manifestsCache = void 0;
5114
+ notify();
5115
+ },
5116
+ board,
5117
+ subscribe(listener) {
5118
+ listeners.add(listener);
5119
+ return () => listeners.delete(listener);
5120
+ },
5121
+ version: () => revision
5122
+ };
5123
+ }
5124
+ //#endregion
5125
+ //#region src/app/units/fixture-unit-mock.tsx
5126
+ var FIXTURE_UNIT_ID = "wb-fixture";
5127
+ var CRASH_UNIT_ID = "wb-fixture-crash";
5128
+ var KEY = {
5129
+ cardTitle: `${FIXTURE_UNIT_ID}.cardTitle`,
5130
+ cardMeta: `${FIXTURE_UNIT_ID}.cardMeta`,
5131
+ rowKey: `${FIXTURE_UNIT_ID}.rowKey`,
5132
+ rowValue: `${FIXTURE_UNIT_ID}.rowValue`
5133
+ };
5134
+ var messages = {
5135
+ zh: {
5136
+ [KEY.cardTitle]: "示例模块",
5137
+ [KEY.cardMeta]: "夹具",
5138
+ [KEY.rowKey]: "示例",
5139
+ [KEY.rowValue]: "第 {n} 行"
5140
+ },
5141
+ en: {
5142
+ [KEY.cardTitle]: "Sample module",
5143
+ [KEY.cardMeta]: "Fixture",
5144
+ [KEY.rowKey]: "Sample",
5145
+ [KEY.rowValue]: "Row {n}"
5146
+ }
5147
+ };
5148
+ var manifest = {
5149
+ id: FIXTURE_UNIT_ID,
5150
+ card: {
5151
+ titleKey: KEY.cardTitle,
5152
+ order: 900
5153
+ },
5154
+ tools: [],
5155
+ host: { inject: [] }
5156
+ };
5157
+ function FixtureCard({ t, onRefresh }) {
5158
+ return /* @__PURE__ */ h(Card, {
5159
+ t,
5160
+ title: t(KEY.cardTitle),
5161
+ meta: t(KEY.cardMeta),
5162
+ refreshing: false,
5163
+ onRefresh
5164
+ }, /* @__PURE__ */ h(Rows, null, [
5165
+ 1,
5166
+ 2,
5167
+ 3
5168
+ ].map((n) => /* @__PURE__ */ h(Row, {
5169
+ key: String(n),
5170
+ label: t(KEY.rowKey),
5171
+ value: t(KEY.rowValue, { n: String(n) })
5172
+ }))));
5173
+ }
5174
+ var FIXTURE_FACE = {
5175
+ unit: FIXTURE_UNIT_ID,
5176
+ manifest,
5177
+ messages,
5178
+ card: FixtureCard
5179
+ };
5180
+ var CRASH_KEY = {
5181
+ cardTitle: `${CRASH_UNIT_ID}.cardTitle`,
5182
+ cardMeta: `${CRASH_UNIT_ID}.cardMeta`
5183
+ };
5184
+ var crashMessages = {
5185
+ zh: {
5186
+ [CRASH_KEY.cardTitle]: "崩溃的卡片",
5187
+ [CRASH_KEY.cardMeta]: "夹具:渲染时抛错"
5188
+ },
5189
+ en: {
5190
+ [CRASH_KEY.cardTitle]: "Crashing card",
5191
+ [CRASH_KEY.cardMeta]: "Fixture: throws while rendering"
5192
+ }
5193
+ };
5194
+ var crashManifest = {
5195
+ id: CRASH_UNIT_ID,
5196
+ card: {
5197
+ titleKey: CRASH_KEY.cardTitle,
5198
+ order: 899
5199
+ },
5200
+ tools: [],
5201
+ host: { inject: [] }
5202
+ };
5203
+ function CrashingCard() {
5204
+ throw new Error("夹具:这张卡片按 wbCrash=1 故意渲染失败(守「一张卡片崩溃不带走面板」)");
5205
+ }
5206
+ var CRASH_FACE = {
5207
+ unit: CRASH_UNIT_ID,
5208
+ manifest: crashManifest,
5209
+ messages: crashMessages,
5210
+ card: CrashingCard
5211
+ };
5212
+ var SAMPLE_ROSTER = [manifest];
5213
+ function hasCard(roster) {
5214
+ return roster.some((item) => item.card !== null);
5215
+ }
5216
+ function fixtureRoster(roster) {
5217
+ return hasCard(roster) ? roster : SAMPLE_ROSTER;
5218
+ }
5219
+ function boardModuleOf(face) {
5220
+ const module = toBoardModule(face, face.manifest);
5221
+ return module === void 0 ? [] : [module];
5222
+ }
5223
+ function fixtureSeed(roster, all, crash = false) {
5224
+ const base = hasCard(roster) ? all : boardModuleOf(FIXTURE_FACE);
5225
+ return crash ? [...boardModuleOf(CRASH_FACE), ...base] : base;
5226
+ }
5227
+ var BootGate_module_default = {
5228
+ actions: "_actions_jlw8j_1",
5229
+ progress: "_progress_jlw8j_2",
5230
+ commandRow: "_commandRow_jlw8j_3",
5231
+ bridge: "_bridge_jlw8j_4",
5232
+ raw: "_raw_jlw8j_5",
5233
+ gate: "_gate_jlw8j_9",
5234
+ card: "_card_jlw8j_20",
5235
+ title: "_title_jlw8j_35",
5236
+ hint: "_hint_jlw8j_43",
5237
+ steps: "_steps_jlw8j_50",
5238
+ step: "_step_jlw8j_50",
5239
+ mark: "_mark_jlw8j_77",
5240
+ label: "_label_jlw8j_102",
5241
+ detail: "_detail_jlw8j_106",
5242
+ elapsed: "_elapsed_jlw8j_124",
5243
+ error: "_error_jlw8j_132",
5244
+ copy: "_copy_jlw8j_158",
5245
+ command: "_command_jlw8j_3",
5246
+ buttons: "_buttons_jlw8j_191",
5247
+ mockSlot: "_mockSlot_jlw8j_198",
5248
+ button: "_button_jlw8j_191",
5249
+ fixTitle: "_fixTitle_jlw8j_249",
5250
+ rawSummary: "_rawSummary_jlw8j_282",
5251
+ bridgeLines: "_bridgeLines_jlw8j_292",
5252
+ bridgeLine: "_bridgeLine_jlw8j_292",
5253
+ link: "_link_jlw8j_309",
5254
+ loading: "_loading_jlw8j_323",
5255
+ loadingMotion: "_loadingMotion_jlw8j_332",
5256
+ "wb-spin": "_wb-spin_jlw8j_1",
5257
+ loadingTrack: "_loadingTrack_jlw8j_337",
5258
+ loadingArc: "_loadingArc_jlw8j_338",
5259
+ "wb-dash": "_wb-dash_jlw8j_1"
5260
+ };
5261
+ //#endregion
5262
+ //#region src/app/layouts/env-gate/gate-mock.ts
5263
+ var INSTALL_COMMAND = "npm i --prefix '/Users/you/.dsh/workbench/opencli/toolchain' @jackwener/opencli@1.8.8";
5264
+ var EXTENSION_REPORT = [
5265
+ "[OK] Daemon: running on port 19825 (v1.8.8)",
5266
+ "[MISSING] Extension: not connected",
5267
+ "[OK] Connectivity: connected in 0.0s",
5268
+ "",
5269
+ "Issues:",
5270
+ " • Daemon is running but the Chrome/Chromium extension is not connected.",
5271
+ "If the extension is already installed, try: opencli daemon restart",
5272
+ "If the extension is not installed:",
5273
+ " 1. Download from https://github.com/jackwener/opencli/releases",
5274
+ " 2. Open chrome://extensions/ → Enable Developer Mode",
5275
+ " 3. Click \"Load unpacked\" → select the extension folder"
5276
+ ].join("\n");
5277
+ var DAEMON_REPORT = [
5278
+ "[MISSING] Daemon: not running",
5279
+ "[MISSING] Extension: not connected",
5280
+ "[FAIL] Connectivity: failed (daemon not reachable)",
5281
+ "",
5282
+ "Issues:",
5283
+ " • Daemon is not running. It should start automatically when you run an opencli browser command.",
5284
+ " • Daemon is running but the Chrome/Chromium extension is not connected.",
5285
+ "If the extension is already installed, try: opencli daemon restart"
5286
+ ].join("\n");
5287
+ var PROFILE_REPORT = [
5288
+ "[OK] Daemon: running on port 19825 (v1.8.8)",
5289
+ "[MISSING] Extension: not connected",
5290
+ "[FAIL] Connectivity: failed (profile-required)",
5291
+ "",
5292
+ "Issues:",
5293
+ " • Multiple Chrome profiles are connected to the daemon, but no default profile was selected.",
5294
+ " Run opencli profile list, then opencli profile use <name>, or pass --profile <name>."
5295
+ ].join("\n");
5296
+ var AT = 1790574156506;
5297
+ function mock(id, label, note, snapshot, expect) {
5298
+ return {
5299
+ id,
5300
+ label,
5301
+ note,
5302
+ snapshot: {
5303
+ ...snapshot,
5304
+ at: AT
5305
+ },
5306
+ expect
5307
+ };
5308
+ }
5309
+ var BRIDGE_PENDING = {
5310
+ id: "bridge",
5311
+ status: "pending"
5312
+ };
5313
+ var GATE_MOCKS = [
5314
+ mock("boot", "刚立起来", "还没拿到体检结果的那一帧:只有标题 + 一句\"正在检测运行环境…\",一行步骤都还没有。", {
5315
+ phase: "idle",
5316
+ steps: []
5317
+ }, {
5318
+ hint: "checking",
5319
+ command: false
5320
+ }),
5321
+ mock("checking", "检测中", "第一步在跑(转圈 + 它正在执行的命令),第二步还没轮到(短横)。", {
5322
+ phase: "checking",
5323
+ steps: [{
5324
+ id: "opencli",
5325
+ status: "running",
5326
+ action: "opencli --version"
5327
+ }, BRIDGE_PENDING]
5328
+ }, {
5329
+ hint: "checking",
5330
+ command: false
5331
+ }),
5332
+ mock("installing", "安装中(npm 在跑)", "缺 opencli:正在装。右边会**数秒**(静止的圆点看不出在干活)。", {
5333
+ phase: "installing",
5334
+ steps: [{
5335
+ id: "opencli",
5336
+ status: "running",
5337
+ action: INSTALL_COMMAND,
5338
+ command: INSTALL_COMMAND
5339
+ }, BRIDGE_PENDING]
5340
+ }, {
5341
+ hint: "installing",
5342
+ command: false
5343
+ }),
5344
+ mock("ready", "都就绪(真机到这就放行)", "两步都过。这一帧之后 gate 立刻撤掉 —— 钉住它只是为了看一眼这两行长什么样。", {
5345
+ phase: "ready",
5346
+ steps: [{
5347
+ id: "opencli",
5348
+ status: "ok",
5349
+ detail: "1.8.8"
5350
+ }, {
5351
+ id: "bridge",
5352
+ status: "ok",
5353
+ detail: "Everything looks good!"
5354
+ }]
5355
+ }, {
5356
+ hint: "checking",
5357
+ command: false
5358
+ }),
5359
+ mock("warn-extension", "浏览器通道:扩展没连上", "daemon 在跑、扩展没连上(最常见):行尾说\"没连上\",下面给「去应用商店装扩展」+ `daemon restart`,原文折叠当证据。", {
5360
+ phase: "ready",
5361
+ steps: [{
5362
+ id: "opencli",
5363
+ status: "ok",
5364
+ detail: "1.8.8"
5365
+ }, {
5366
+ id: "bridge",
5367
+ status: "warn",
5368
+ detail: EXTENSION_REPORT,
5369
+ command: "opencli daemon restart"
5370
+ }],
5371
+ bridgeIssues: ["extension"]
5372
+ }, {
5373
+ hint: "checking",
5374
+ command: false,
5375
+ bridgeIssues: ["extension"]
5376
+ }),
5377
+ mock("warn-daemon", "浏览器通道:服务没起来", "daemon 没起来(扩展跟着也连不上):两条人话都摆出来,命令给 `daemon restart`。", {
5378
+ phase: "ready",
5379
+ steps: [{
5380
+ id: "opencli",
5381
+ status: "ok",
5382
+ detail: "1.8.8"
5383
+ }, {
5384
+ id: "bridge",
5385
+ status: "warn",
5386
+ detail: DAEMON_REPORT,
5387
+ command: "opencli daemon restart"
5388
+ }],
5389
+ bridgeIssues: ["daemon", "extension"]
5390
+ }, {
5391
+ hint: "checking",
5392
+ command: false,
5393
+ bridgeIssues: ["daemon", "extension"]
5394
+ }),
5395
+ mock("warn-profile", "浏览器通道:没选默认 profile", "连了多个浏览器 profile 但没选默认:只说\"选哪个\"(重启服务解决不了它),命令给 `profile list`。", {
5396
+ phase: "ready",
5397
+ steps: [{
5398
+ id: "opencli",
5399
+ status: "ok",
5400
+ detail: "1.8.8"
5401
+ }, {
5402
+ id: "bridge",
5403
+ status: "warn",
5404
+ detail: PROFILE_REPORT,
5405
+ command: "opencli profile list"
5406
+ }],
5407
+ bridgeIssues: ["profile"]
5408
+ }, {
5409
+ hint: "checking",
5410
+ command: false,
5411
+ bridgeIssues: ["profile"]
5412
+ }),
5413
+ mock("failed-permission", "装不上:权限不足", "失败态:为什么需要它 → 确切命令(可复制)→ 照做能解决的一句人话(EACCES → 换目录 / sudo)。", {
5414
+ phase: "failed",
5415
+ steps: [{
5416
+ id: "opencli",
5417
+ status: "failed",
5418
+ detail: "npm ERR! code EACCES",
5419
+ command: INSTALL_COMMAND
5420
+ }, BRIDGE_PENDING],
5421
+ error: "npm ERR! code EACCES\nnpm ERR! syscall mkdir\nnpm ERR! path /usr/local/lib/node_modules",
5422
+ failure: "permission",
5423
+ guidance: "install"
5424
+ }, {
5425
+ hint: "failed",
5426
+ guidance: "install",
5427
+ command: true
5428
+ }),
5429
+ mock("failed-network", "装不上:网络不通", "同一档失败,但人话换成\"查代理\"那条(EAI_AGAIN / ENOTFOUND)。", {
5430
+ phase: "failed",
5431
+ steps: [{
5432
+ id: "opencli",
5433
+ status: "failed",
5434
+ detail: "npm ERR! code EAI_AGAIN",
5435
+ command: INSTALL_COMMAND
5436
+ }, BRIDGE_PENDING],
5437
+ error: "npm ERR! code EAI_AGAIN\nnpm ERR! network request to https://registry.npmjs.org failed",
5438
+ failure: "network",
5439
+ guidance: "install"
5440
+ }, {
5441
+ hint: "failed",
5442
+ guidance: "install",
5443
+ command: true
5444
+ }),
5445
+ mock("failed-unknown", "装不上:认不出的错", "认不出失败种类时**不编**建议:只给命令与原文(多一句假建议比少一句更糟)。", {
5446
+ phase: "failed",
5447
+ steps: [{
5448
+ id: "opencli",
5449
+ status: "failed",
5450
+ detail: "something went wrong",
5451
+ command: INSTALL_COMMAND
5452
+ }, BRIDGE_PENDING],
5453
+ error: "something went wrong",
5454
+ failure: "unknown",
5455
+ guidance: "install"
5456
+ }, {
5457
+ hint: "failed",
5458
+ guidance: "install",
5459
+ command: true
5460
+ }),
5461
+ mock("failed-path", "装了但还找不到", "装完了 `--version` 还是不行:**不再让用户装一遍**(PATH / 新终端的事),所以不给命令。", {
5462
+ phase: "failed",
5463
+ steps: [{
5464
+ id: "opencli",
5465
+ status: "failed",
5466
+ detail: "zsh: command not found: opencli",
5467
+ command: INSTALL_COMMAND
5468
+ }, BRIDGE_PENDING],
5469
+ error: "zsh: command not found: opencli",
5470
+ failure: "missing",
5471
+ guidance: "path"
5472
+ }, {
5473
+ hint: "failed",
5474
+ guidance: "path",
5475
+ command: false
5476
+ }),
5477
+ mock("failed-shell", "执行缝坏了", "连 shell 都调不动:装也不可能成功。没有\"正在执行的动作\"、也没有命令 —— 该做的是重启宿主。", {
5478
+ phase: "failed",
5479
+ steps: [{
5480
+ id: "opencli",
5481
+ status: "failed",
5482
+ detail: "Error: spawn /bin/sh ENOENT"
5483
+ }, BRIDGE_PENDING],
5484
+ error: "Error: spawn /bin/sh ENOENT",
5485
+ failure: "unknown",
5486
+ guidance: "shell"
5487
+ }, {
5488
+ hint: "failed",
5489
+ guidance: "shell",
5490
+ command: false
5491
+ })
5492
+ ];
5493
+ function el$1(tag, className, text) {
5494
+ const node = document.createElement(tag);
5495
+ node.className = className;
5496
+ if (text !== void 0) node.textContent = text;
5497
+ return node;
5498
+ }
5499
+ function mountGateMockStrip(options) {
5500
+ const strip = el$1("div", `wb-mockStrip ${BootGate_module_default.mockSlot}`);
5501
+ const note = el$1("span", "wb-mockNote");
5502
+ const chips = [];
5503
+ const paint = (active) => {
5504
+ note.textContent = `夹具:钉住启动页的状态,不轮询、不放行 —— ${active?.note ?? "不接管:按真机走(就绪就放行)。"}`;
5505
+ chips.forEach((chip) => {
5506
+ chip.className = `wb-mockChip${chip.dataset.mock === active?.id ? " wb-mockChipOn" : ""}`;
5507
+ });
5508
+ };
5509
+ const pick = (active) => {
5510
+ paint(active);
5511
+ options.onPick(active === null ? null : active.snapshot);
5512
+ };
5513
+ const real = el$1("button", "wb-mockChip", "真实");
5514
+ real.setAttribute("type", "button");
5515
+ real.dataset.mock = "";
5516
+ real.addEventListener("click", () => pick(null));
5517
+ strip.append(note, real);
5518
+ chips.push(real);
5519
+ for (const item of GATE_MOCKS) {
5520
+ const chip = el$1("button", "wb-mockChip", item.label);
5521
+ chip.setAttribute("type", "button");
5522
+ chip.dataset.mock = item.id;
5523
+ chip.addEventListener("click", () => pick(item));
5524
+ strip.append(chip);
5525
+ chips.push(chip);
5526
+ }
5527
+ pick(GATE_MOCKS[0] ?? null);
5528
+ return strip;
5529
+ }
5530
+ var kit_preview_module_default = {
5531
+ gallery: "_gallery_cagso_1",
5532
+ section: "_section_cagso_7",
5533
+ heading: "_heading_cagso_19",
5534
+ headingText: "_headingText_cagso_27",
5535
+ title: "_title_cagso_34",
5536
+ note: "_note_cagso_42",
5537
+ toggle: "_toggle_cagso_49",
5538
+ body: "_body_cagso_70",
5539
+ nav: "_nav_cagso_81",
5540
+ navLink: "_navLink_cagso_89",
5541
+ cells: "_cells_cagso_115",
5542
+ cell: "_cell_cagso_115",
5543
+ cellLabel: "_cellLabel_cagso_129",
5544
+ example: "_example_cagso_135",
5545
+ span: "_span_cagso_147",
5546
+ stack: "_stack_cagso_151",
5547
+ inline: "_inline_cagso_157",
5548
+ panel: "_panel_cagso_164",
5549
+ narrowActions: "_narrowActions_cagso_171",
5550
+ bound: "_bound_cagso_175"
5551
+ };
5552
+ //#endregion
5553
+ //#region src/app/layouts/rightbar/kit-preview-controls.tsx
5554
+ var ENV_OPTIONS = [
5555
+ {
5556
+ value: "prod",
5557
+ label: "生产环境"
5558
+ },
5559
+ {
5560
+ value: "stage",
5561
+ label: "预发环境"
5562
+ },
5563
+ {
5564
+ value: "dev",
5565
+ label: "开发环境"
5566
+ }
5567
+ ];
5568
+ var CLOUD_OPTIONS = [
5569
+ {
5570
+ value: "ali-prod",
5571
+ label: "生产集群",
5572
+ group: "阿里云",
5573
+ searchText: "aliyun 生产 prod"
5574
+ },
5575
+ {
5576
+ value: "ali-stage",
5577
+ label: "预发集群",
5578
+ group: "阿里云",
5579
+ searchText: "aliyun 预发 stage"
5580
+ },
5581
+ {
5582
+ value: "tencent-prod",
5583
+ label: "生产集群",
5584
+ group: "腾讯云",
5585
+ searchText: "tencent 生产 prod"
5586
+ },
5587
+ {
5588
+ value: "tencent-dev",
5589
+ label: "开发集群",
5590
+ group: "腾讯云",
5591
+ disabled: true,
5592
+ searchText: "tencent 开发 dev"
5593
+ }
5594
+ ];
5595
+ var CHOICES = [
5596
+ {
5597
+ value: "small",
5598
+ label: "小"
5599
+ },
5600
+ {
5601
+ value: "medium",
5602
+ label: "中"
5603
+ },
5604
+ {
5605
+ value: "large",
5606
+ label: "大"
5607
+ }
5608
+ ];
5609
+ var LONG_CHOICES = [
5610
+ {
5611
+ value: "cn-north-prod",
5612
+ label: "华北二 · 生产集群(候选名字故意很长,看它不再被裁成一行)",
5613
+ description: "线上流量都从这里走;改动前先确认发布窗口"
5614
+ },
5615
+ {
5616
+ value: "cn-south-stage",
5617
+ label: "华南一 · 预发集群",
5618
+ description: "灰度验证用,数据每周一清"
5619
+ },
5620
+ {
5621
+ value: "cn-east-dev",
5622
+ label: "华东 · 开发集群"
5623
+ }
5624
+ ];
5625
+ function TextFieldDemo() {
5626
+ const [text, setText] = useState("");
5627
+ return /* @__PURE__ */ h("div", { className: kit_preview_module_default.stack }, /* @__PURE__ */ h(Field, {
5628
+ label: "名字",
5629
+ hint: "随手敲点字,看描边与焦点环"
5630
+ }, /* @__PURE__ */ h(TextField, {
5631
+ value: text,
5632
+ placeholder: "例如:生产",
5633
+ onChange: (event) => setText(event.currentTarget.value)
5634
+ })), /* @__PURE__ */ h(TextField, {
5635
+ invalid: true,
5636
+ value: "这份填错了",
5637
+ onChange: () => {}
5638
+ }), /* @__PURE__ */ h(TextField, {
5639
+ value: "禁用的一格",
5640
+ disabled: true,
5641
+ onChange: () => {}
5642
+ }));
5643
+ }
5644
+ function SelectDemo({ variant }) {
5645
+ const [value, setValue] = useState("stage");
5646
+ return /* @__PURE__ */ h(SelectField, {
5647
+ value,
5648
+ options: ENV_OPTIONS,
5649
+ onChange: setValue,
5650
+ ...variant === void 0 ? {} : { variant },
5651
+ label: variant === "ghost" ? void 0 : "环境",
5652
+ hint: variant === "ghost" ? void 0 : "展开后锚点换成搜索框,↑↓ 走游标"
5653
+ });
5654
+ }
5655
+ function SelectRichDemo() {
5656
+ const [value, setValue] = useState("ali-prod");
5657
+ const [added, setAdded] = useState(0);
5658
+ return /* @__PURE__ */ h(SelectField, {
5659
+ value,
5660
+ options: CLOUD_OPTIONS,
5661
+ onChange: setValue,
5662
+ label: "集群",
5663
+ hint: added === 0 ? "试试点页脚那颗「新建集群…」" : `页脚接过 ${added} 次`,
5664
+ searchLabel: "搜集群",
5665
+ searchPlaceholder: "搜名字或别名…",
5666
+ emptyText: (query) => `没有匹配「${query}」的集群`,
5667
+ footer: {
5668
+ label: "新建集群…",
5669
+ icon: /* @__PURE__ */ h(IconPlusOutlineRegular, { size: 14 })
5670
+ },
5671
+ onFooter: () => setAdded((count) => count + 1)
5672
+ });
5673
+ }
5674
+ function SelectStateDemo() {
5675
+ const [manual, setManual] = useState("手填的环境名");
5676
+ return /* @__PURE__ */ h("div", { className: kit_preview_module_default.stack }, /* @__PURE__ */ h(SelectField, {
5677
+ value: "prod",
5678
+ options: ENV_OPTIONS,
5679
+ onChange: () => {},
5680
+ disabled: true,
5681
+ label: "禁用"
5682
+ }), /* @__PURE__ */ h(SelectField, {
5683
+ value: "",
5684
+ options: [],
5685
+ onChange: () => {},
5686
+ loading: true,
5687
+ loadingText: "正在读环境…",
5688
+ label: "加载中"
5689
+ }), /* @__PURE__ */ h(SelectField, {
5690
+ value: "",
5691
+ options: [],
5692
+ onChange: () => {},
5693
+ fallback: {
5694
+ value: manual,
5695
+ onChange: setManual
5696
+ },
5697
+ label: "名单读不到 → 退化成手填"
5698
+ }));
5699
+ }
5700
+ function AppearanceDemo() {
5701
+ const [value, setValue] = useState("medium");
5702
+ return /* @__PURE__ */ h("div", { className: kit_preview_module_default.stack }, /* @__PURE__ */ h(SelectField, {
5703
+ value,
5704
+ options: CHOICES,
5705
+ onChange: setValue,
5706
+ variant: "ghost",
5707
+ icon: /* @__PURE__ */ h(IconChevronDownOutlineRegular, { size: 16 }),
5708
+ ariaLabel: "尺寸",
5709
+ title: "无边框变体:图标 + 当前值 + 箭头"
5710
+ }), /* @__PURE__ */ h(SelectField, {
5711
+ value,
5712
+ options: CHOICES,
5713
+ onChange: setValue,
5714
+ selection: "check",
5715
+ label: "selection=check(打勾那一种)"
5716
+ }));
5717
+ }
5718
+ function ChoiceDemo() {
5719
+ const [single, setSingle] = useState("medium");
5720
+ const [many, setMany] = useState(["small", "large"]);
5721
+ const [long, setLong] = useState("cn-north-prod");
5722
+ return /* @__PURE__ */ h("div", { className: kit_preview_module_default.stack }, /* @__PURE__ */ h(ChoiceGroup, {
5723
+ label: "尺寸",
5724
+ name: "kit-size",
5725
+ options: CHOICES,
5726
+ value: single,
5727
+ onChange: setSingle
5728
+ }), /* @__PURE__ */ h(ChoiceGroup, {
5729
+ label: "多选",
5730
+ name: "kit-many",
5731
+ options: CHOICES,
5732
+ multi: true,
5733
+ values: many,
5734
+ onChange: setMany
5735
+ }), /* @__PURE__ */ h(ChoiceGroup, {
5736
+ label: "禁用",
5737
+ name: "kit-off",
5738
+ options: CHOICES,
5739
+ value: "small",
5740
+ onChange: () => {},
5741
+ disabled: true
5742
+ }), /* @__PURE__ */ h(ChoiceGroup, {
5743
+ label: "无边框档",
5744
+ name: "kit-ghost",
5745
+ options: CHOICES,
5746
+ variant: "ghost",
5747
+ value: single,
5748
+ onChange: setSingle
5749
+ }), /* @__PURE__ */ h(ChoiceGroup, {
5750
+ label: "加载中",
5751
+ name: "kit-loading",
5752
+ options: [],
5753
+ loading: true,
5754
+ loadingText: "正在读环境…",
5755
+ value: "",
5756
+ onChange: () => {}
5757
+ }), /* @__PURE__ */ h(ChoiceGroup, {
5758
+ label: "没得选",
5759
+ name: "kit-empty",
5760
+ options: [],
5761
+ emptyText: "这个工作区还没绑定环境",
5762
+ value: "",
5763
+ onChange: () => {}
5764
+ }), /* @__PURE__ */ h(ChoiceGroup, {
5765
+ label: "长候选 + description",
5766
+ name: "kit-long",
5767
+ options: LONG_CHOICES,
5768
+ value: long,
5769
+ onChange: setLong
5770
+ }));
5771
+ }
5772
+ function FormActionsDemo() {
5773
+ const [busy, setBusy] = useState(false);
5774
+ return /* @__PURE__ */ h("div", { className: kit_preview_module_default.stack }, /* @__PURE__ */ h(FormActions, { actions: [{
5775
+ key: "retry",
5776
+ label: "重试",
5777
+ onClick: () => {}
5778
+ }, {
5779
+ key: "confirm",
5780
+ label: "确认",
5781
+ kind: "primary",
5782
+ onClick: () => {}
5783
+ }] }), /* @__PURE__ */ h(FormActions, { actions: [
5784
+ {
5785
+ key: "cancel",
5786
+ label: "取消",
5787
+ onClick: () => {}
5788
+ },
5789
+ {
5790
+ key: "remove",
5791
+ label: "删除",
5792
+ kind: "danger",
5793
+ onClick: () => {}
5794
+ },
5795
+ {
5796
+ key: "save",
5797
+ label: "保存",
5798
+ kind: "primary",
5799
+ onClick: () => {}
5800
+ }
5801
+ ] }), /* @__PURE__ */ h(FormActions, { actions: [{
5802
+ key: "later",
5803
+ label: "稍后",
5804
+ onClick: () => {},
5805
+ disabled: true
5806
+ }, {
5807
+ key: "sync",
5808
+ label: busy ? "同步中…" : "同步",
5809
+ kind: "primary",
5810
+ onClick: () => setBusy((on) => !on),
5811
+ busy
5812
+ }] }), /* @__PURE__ */ h("div", { className: kit_preview_module_default.narrowActions }, /* @__PURE__ */ h(FormActions, { actions: [
5813
+ {
5814
+ key: "cancel",
5815
+ label: "取消",
5816
+ onClick: () => {}
5817
+ },
5818
+ {
5819
+ key: "delete",
5820
+ label: "删除环境",
5821
+ kind: "danger",
5822
+ onClick: () => {}
5823
+ },
5824
+ {
5825
+ key: "save",
5826
+ label: "保存",
5827
+ kind: "primary",
5828
+ onClick: () => {}
5829
+ }
5830
+ ] })));
5831
+ }
5832
+ function SaveBarDemo() {
5833
+ const [busy, setBusy] = useState(false);
5834
+ return /* @__PURE__ */ h(SaveBar, {
5835
+ busy,
5836
+ labels: {
5837
+ cancel: "取消",
5838
+ save: "保存",
5839
+ saving: "保存中…"
5840
+ },
5841
+ onCancel: () => setBusy(false),
5842
+ onSave: () => setBusy(true)
5843
+ });
5844
+ }
5845
+ function LinkDemo() {
5846
+ return /* @__PURE__ */ h("div", { className: kit_preview_module_default.inline }, /* @__PURE__ */ h(Link, {
5847
+ href: "https://example.com/report",
5848
+ title: "外部链接:新窗口打开"
5849
+ }, "外部报告"), /* @__PURE__ */ h(Link, {
5850
+ href: "#kit-preview",
5851
+ external: false
5852
+ }, "站内锚点"));
5853
+ }
5854
+ //#endregion
5855
+ //#region src/app/layouts/rightbar/kit-preview-hash.ts
5856
+ function fragmentOf(hash) {
5857
+ if (!hash.startsWith("#")) return "";
5858
+ try {
5859
+ return decodeURIComponent(hash.slice(1));
5860
+ } catch {
5861
+ return "";
5862
+ }
5863
+ }
5864
+ function hashTargetsSection(anchor, hash) {
5865
+ return anchor !== "" && fragmentOf(hash) === anchor;
5866
+ }
5867
+ //#endregion
5868
+ //#region src/app/layouts/rightbar/kit-preview-frame.tsx
5869
+ var KitNavContext = createContext(null);
5870
+ function anchorOf(title) {
5871
+ return `kit-${title.toLowerCase().replace(/[^\p{L}\p{N}]+/gu, "-").replace(/^-+|-+$/g, "")}`;
5872
+ }
5873
+ function KitNavProvider({ children }) {
5874
+ const [entries, setEntries] = useState([]);
5875
+ const add = useCallback((entry) => {
5876
+ setEntries((list) => list.some((one) => one.id === entry.id) ? list : [...list, entry]);
5877
+ }, []);
5878
+ const remove = useCallback((id) => {
5879
+ setEntries((list) => list.filter((one) => one.id !== id));
5880
+ }, []);
5881
+ const registry = useMemo(() => ({
5882
+ entries,
5883
+ add,
5884
+ remove
5885
+ }), [
5886
+ entries,
5887
+ add,
5888
+ remove
5889
+ ]);
5890
+ return /* @__PURE__ */ h(KitNavContext.Provider, { value: registry }, children);
5891
+ }
5892
+ function KitNav() {
5893
+ const entries = useContext(KitNavContext)?.entries ?? [];
5894
+ if (entries.length === 0) return null;
5895
+ return /* @__PURE__ */ h("nav", {
5896
+ className: kit_preview_module_default.nav,
5897
+ "aria-label": "这一卡里的各节"
5898
+ }, entries.map((entry) => /* @__PURE__ */ h("a", {
5899
+ key: entry.id,
5900
+ className: kit_preview_module_default.navLink,
5901
+ href: `#${entry.id}`
5902
+ }, entry.title)));
5903
+ }
5904
+ function Section({ title, note, children }) {
5905
+ const [open, setOpen] = useState(true);
5906
+ const registry = useContext(KitNavContext);
5907
+ const anchor = anchorOf(title);
5908
+ const bodyId = `${anchor}-body`;
5909
+ const add = registry?.add;
5910
+ const remove = registry?.remove;
5911
+ useEffect(() => {
5912
+ if (add === void 0 || remove === void 0) return void 0;
5913
+ add({
5914
+ id: anchor,
5915
+ title
5916
+ });
5917
+ return () => remove(anchor);
5918
+ }, [
5919
+ add,
5920
+ remove,
5921
+ anchor,
5922
+ title
3253
5923
  ]);
3254
- return value;
5924
+ useEffect(() => {
5925
+ const sync = () => {
5926
+ if (hashTargetsSection(anchor, window.location.hash)) setOpen(true);
5927
+ };
5928
+ sync();
5929
+ window.addEventListener("hashchange", sync);
5930
+ return () => window.removeEventListener("hashchange", sync);
5931
+ }, [anchor]);
5932
+ return /* @__PURE__ */ h("section", {
5933
+ className: kit_preview_module_default.section,
5934
+ id: anchor
5935
+ }, /* @__PURE__ */ h("div", { className: kit_preview_module_default.heading }, /* @__PURE__ */ h("div", { className: kit_preview_module_default.headingText }, /* @__PURE__ */ h("h3", { className: kit_preview_module_default.title }, title), note === void 0 ? null : /* @__PURE__ */ h("p", { className: kit_preview_module_default.note }, note)), /* @__PURE__ */ h(Button, {
5936
+ type: "button",
5937
+ size: "sm",
5938
+ variant: "ghost",
5939
+ className: kit_preview_module_default.toggle,
5940
+ "aria-label": `${open ? "收起" : "展开"}:${title}`,
5941
+ "aria-expanded": open,
5942
+ "aria-controls": bodyId,
5943
+ icon: /* @__PURE__ */ h(IconChevronRightOutlineRegular, { size: 14 }),
5944
+ onClick: () => setOpen((on) => !on)
5945
+ })), /* @__PURE__ */ h("div", {
5946
+ className: kit_preview_module_default.body,
5947
+ id: bodyId,
5948
+ hidden: !open
5949
+ }, children));
5950
+ }
5951
+ function Grid({ children }) {
5952
+ return /* @__PURE__ */ h("div", { className: kit_preview_module_default.cells }, children);
5953
+ }
5954
+ function Cell({ label, wide, children }) {
5955
+ return /* @__PURE__ */ h("div", { className: wide === true ? `${kit_preview_module_default.cell} ${kit_preview_module_default.span}` : kit_preview_module_default.cell }, /* @__PURE__ */ h("span", { className: kit_preview_module_default.cellLabel }, label), /* @__PURE__ */ h("div", { className: kit_preview_module_default.example }, children));
5956
+ }
5957
+ //#endregion
5958
+ //#region src/app/layouts/rightbar/kit-preview-rows.tsx
5959
+ function RowsSection() {
5960
+ return /* @__PURE__ */ h(Section, {
5961
+ title: "行与分组",
5962
+ note: "Rows / Row 是键值行;Stack 只管间距;SettingsSection 是设置页那一节"
5963
+ }, /* @__PURE__ */ h(Grid, null, /* @__PURE__ */ h(Cell, { label: "Rows + Row" }, /* @__PURE__ */ h(Rows, null, /* @__PURE__ */ h(Row, {
5964
+ label: "环境",
5965
+ value: "生产"
5966
+ }), /* @__PURE__ */ h(Row, {
5967
+ label: "集群",
5968
+ value: "ali-prod"
5969
+ }), /* @__PURE__ */ h(Row, {
5970
+ label: "指纹",
5971
+ value: "a1b2c3d4"
5972
+ }))), /* @__PURE__ */ h(Cell, { label: "Stack(只管间距)" }, /* @__PURE__ */ h(Stack, null, /* @__PURE__ */ h(Note, null, "第一行说明:默认 muted。"), /* @__PURE__ */ h(Note, { tone: "problem" }, "第二行是个问题:tone=problem。"))), /* @__PURE__ */ h(Cell, {
5973
+ label: "SettingsSection(设置页那一节)",
5974
+ wide: true
5975
+ }, /* @__PURE__ */ h("div", { className: kit_preview_module_default.bound }, /* @__PURE__ */ h(SettingsSection, {
5976
+ label: "面板",
5977
+ title: "显示"
5978
+ }, /* @__PURE__ */ h(Rows, null, /* @__PURE__ */ h(Row, {
5979
+ label: "每页条数",
5980
+ value: "20"
5981
+ }), /* @__PURE__ */ h(Row, {
5982
+ label: "自动刷新",
5983
+ value: "开"
5984
+ })))))));
5985
+ }
5986
+ function FormSection() {
5987
+ return /* @__PURE__ */ h(Section, {
5988
+ title: "表单的行",
5989
+ note: "FormRows / FormRow:标签左列 + 控件(stacked 才是上下堆叠);控件仍由调用点给 —— 这一层没有 DSL"
5990
+ }, /* @__PURE__ */ h(Grid, null, /* @__PURE__ */ h(Cell, {
5991
+ label: "FormRow(标签在左,默认)",
5992
+ wide: true
5993
+ }, /* @__PURE__ */ h("div", { className: kit_preview_module_default.bound }, /* @__PURE__ */ h(FormRows, null, /* @__PURE__ */ h(FormRow, {
5994
+ label: "环境",
5995
+ hint: "只列非生产"
5996
+ }, /* @__PURE__ */ h(SelectField, {
5997
+ options: [{
5998
+ value: "test",
5999
+ label: "测试环境"
6000
+ }, {
6001
+ value: "stage",
6002
+ label: "预发"
6003
+ }],
6004
+ value: "test",
6005
+ onChange: () => {}
6006
+ })), /* @__PURE__ */ h(FormRow, { label: "发布分支" }, /* @__PURE__ */ h(TextField, {
6007
+ value: "bgkj-test-auth",
6008
+ onChange: () => {}
6009
+ }))))), /* @__PURE__ */ h(Cell, {
6010
+ label: "长标签不折行(同一组共用一个标签列;组标题通栏)",
6011
+ wide: true
6012
+ }, /* @__PURE__ */ h("div", { className: kit_preview_module_default.bound }, /* @__PURE__ */ h(FormRows, null, /* @__PURE__ */ h("p", { className: kit_preview_module_default.note }, "身份"), /* @__PURE__ */ h(FormRow, { label: "Application 名" }, /* @__PURE__ */ h(TextField, {
6013
+ value: "bgkj-test-auth",
6014
+ onChange: () => {}
6015
+ })), /* @__PURE__ */ h(FormRow, { label: "环境" }, /* @__PURE__ */ h(SelectField, {
6016
+ options: [{
6017
+ value: "test",
6018
+ label: "测试环境"
6019
+ }],
6020
+ value: "test",
6021
+ onChange: () => {}
6022
+ }))))), /* @__PURE__ */ h(Cell, { label: "stacked(上下堆叠)+ 禁用那一档" }, /* @__PURE__ */ h("div", { className: kit_preview_module_default.bound }, /* @__PURE__ */ h(FormRows, null, /* @__PURE__ */ h(FormRow, {
6023
+ label: "项目",
6024
+ layout: "stacked"
6025
+ }, /* @__PURE__ */ h(TextField, {
6026
+ value: "中台-组织权限域",
6027
+ onChange: () => {}
6028
+ })), /* @__PURE__ */ h(FormRow, {
6029
+ label: "服务",
6030
+ hint: "禁用时标签会压暗"
6031
+ }, /* @__PURE__ */ h(SelectField, {
6032
+ options: [{
6033
+ value: "web",
6034
+ label: "前端服务"
6035
+ }],
6036
+ value: "web",
6037
+ onChange: () => {},
6038
+ disabled: true
6039
+ }))))), /* @__PURE__ */ h(Cell, {
6040
+ label: "出错那一档(problem 顶掉 hint,控件给 invalid)",
6041
+ wide: true
6042
+ }, /* @__PURE__ */ h("div", { className: kit_preview_module_default.bound }, /* @__PURE__ */ h(FormRows, null, /* @__PURE__ */ h(FormRow, {
6043
+ label: "环境",
6044
+ problem: "生产环境不在可发布范围内"
6045
+ }, /* @__PURE__ */ h(SelectField, {
6046
+ options: [{
6047
+ value: "prod",
6048
+ label: "生产环境"
6049
+ }],
6050
+ value: "prod",
6051
+ onChange: () => {},
6052
+ invalid: true
6053
+ })), /* @__PURE__ */ h(FormRow, {
6054
+ label: "发布分支",
6055
+ problem: "这个分支上还没有最近的构建"
6056
+ }, /* @__PURE__ */ h(TextField, {
6057
+ value: "release/2.13",
6058
+ invalid: true,
6059
+ onChange: () => {}
6060
+ })))))));
6061
+ }
6062
+ function ActivitySection() {
6063
+ return /* @__PURE__ */ h(Section, {
6064
+ title: "活动流",
6065
+ note: "ActivityBlock / ActivityLine / ActivityAction:一行一个动作,右边是时间与按钮"
6066
+ }, /* @__PURE__ */ h("div", { className: kit_preview_module_default.panel }, /* @__PURE__ */ h(ActivityBlock, { head: "今天的动作" }, /* @__PURE__ */ h(ActivityLine, {
6067
+ dot: /* @__PURE__ */ h(StateDot, {
6068
+ state: "done",
6069
+ size: 10
6070
+ }),
6071
+ text: "读了构建列表",
6072
+ at: "2 分钟前"
6073
+ }), /* @__PURE__ */ h(ActivityLine, {
6074
+ dot: /* @__PURE__ */ h(StateDot, {
6075
+ state: "ongoing",
6076
+ size: 10
6077
+ }),
6078
+ text: "正在发布",
6079
+ at: "刚刚",
6080
+ actions: /* @__PURE__ */ h(ActivityAction, {
6081
+ label: "看日志",
6082
+ icon: /* @__PURE__ */ h(IconCodeOutlineRegular, { size: 14 }),
6083
+ onClick: () => {}
6084
+ })
6085
+ }), /* @__PURE__ */ h(ActivityLine, {
6086
+ dot: /* @__PURE__ */ h(StateDot, {
6087
+ state: "error",
6088
+ size: 10
6089
+ }),
6090
+ text: "发布失败",
6091
+ at: "1 小时前",
6092
+ actions: /* @__PURE__ */ h(ActivityAction, {
6093
+ label: "重试",
6094
+ hint: "失败的那次再跑一遍",
6095
+ icon: /* @__PURE__ */ h(IconRefreshOutlineRegular, { size: 14 }),
6096
+ failed: true,
6097
+ onClick: () => {}
6098
+ })
6099
+ }))));
3255
6100
  }
3256
- function useCapabilityProbe() {
3257
- return useSyncExternalStore(subscribeProbe, probeValue);
6101
+ function LongTaskSection() {
6102
+ return /* @__PURE__ */ h(Section, {
6103
+ title: "长任务那一行",
6104
+ note: "四种状态:跑着 / 要登录 / 好了 / 失败(带步骤与原文)"
6105
+ }, /* @__PURE__ */ h("div", { className: kit_preview_module_default.stack }, /* @__PURE__ */ h(LongTaskRow, {
6106
+ status: "running",
6107
+ headline: "正在发布(2/3)",
6108
+ stepsTitle: "步骤",
6109
+ steps: [
6110
+ "拉代码",
6111
+ "构建",
6112
+ "发布"
6113
+ ]
6114
+ }), /* @__PURE__ */ h(LongTaskRow, {
6115
+ status: "needs-login",
6116
+ headline: "要登录腾讯云",
6117
+ problem: "凭证过期了"
6118
+ }), /* @__PURE__ */ h(LongTaskRow, {
6119
+ status: "ok",
6120
+ headline: "发布完成",
6121
+ rawTitle: "原文",
6122
+ raw: "ok · 12.4s",
6123
+ copyLabel: "复制",
6124
+ copiedLabel: "复制好了",
6125
+ links: [{
6126
+ href: "https://example.com/log",
6127
+ text: "日志"
6128
+ }]
6129
+ }), /* @__PURE__ */ h(LongTaskRow, {
6130
+ status: "failed",
6131
+ headline: "发布失败",
6132
+ problem: "站点回的是 HTTP 403"
6133
+ })));
6134
+ }
6135
+ function IconSection() {
6136
+ return /* @__PURE__ */ h(Section, {
6137
+ title: "外壳自己的图标",
6138
+ note: "dsh 那一套 Icon*Regular 直接从原语拿,这几个是外壳自己画的"
6139
+ }, /* @__PURE__ */ h(Grid, null, [
6140
+ {
6141
+ label: "IconBrandMark",
6142
+ node: /* @__PURE__ */ h(IconBrandMark, { size: 20 })
6143
+ },
6144
+ {
6145
+ label: "IconModuleMark",
6146
+ node: /* @__PURE__ */ h(IconModuleMark, { size: 20 })
6147
+ },
6148
+ {
6149
+ label: "IconModules",
6150
+ node: /* @__PURE__ */ h(IconModules, { size: 16 })
6151
+ },
6152
+ {
6153
+ label: "IconPanelScreen",
6154
+ node: /* @__PURE__ */ h(IconPanelScreen, { size: 16 })
6155
+ },
6156
+ {
6157
+ label: "IconOpencli",
6158
+ node: /* @__PURE__ */ h(IconOpencli, { size: 16 })
6159
+ },
6160
+ {
6161
+ label: "IconNpm",
6162
+ node: /* @__PURE__ */ h(IconNpm, { size: 16 })
6163
+ }
6164
+ ].map((one) => /* @__PURE__ */ h(Cell, {
6165
+ key: one.label,
6166
+ label: one.label
6167
+ }, /* @__PURE__ */ h("span", { className: kit_preview_module_default.panel }, one.node)))));
6168
+ }
6169
+ function StripSection() {
6170
+ const [index, setIndex] = useState(0);
6171
+ return /* @__PURE__ */ h(Section, {
6172
+ title: "夹具条",
6173
+ note: "MockStrip:只在 ?wbMock=1 下出现的那条,自己也可以摆出来"
6174
+ }, /* @__PURE__ */ h(MockStrip, {
6175
+ note: "这是夹具条本身:点一下就换一个形状",
6176
+ index,
6177
+ onPick: setIndex,
6178
+ mocks: [
6179
+ {
6180
+ id: "one",
6181
+ label: "一张卡"
6182
+ },
6183
+ {
6184
+ id: "two",
6185
+ label: "两张卡"
6186
+ },
6187
+ {
6188
+ id: "eight",
6189
+ label: "八张卡"
6190
+ }
6191
+ ]
6192
+ }));
3258
6193
  }
3259
6194
  //#endregion
3260
- //#region src/shared/hooks/use-capability-gate.ts
3261
- var use_capability_gate_exports = /* @__PURE__ */ __exportAll({
3262
- useCapabilityGate: () => useCapabilityGate,
3263
- useCapabilityMap: () => useCapabilityMap
3264
- });
3265
- function useCapabilityGate(unit, refreshToken, options = {}) {
3266
- const [probeNonce, setProbeNonce] = useState(0);
3267
- const forceProbe = useCallback(() => setProbeNonce((value) => value + 1), []);
3268
- const capabilities = useCapabilities(refreshToken + probeNonce);
3269
- const capability = options.fixture ?? capabilities?.[unit] ?? null;
6195
+ //#region src/app/layouts/rightbar/kit-preview.tsx
6196
+ function SelectSection() {
6197
+ return /* @__PURE__ */ h(Section, {
6198
+ title: "下拉选择 SelectField",
6199
+ note: "默认是常规下拉框;无边框那档要显式给 variant=ghost。展开后锚点换成搜索框,↑↓ 走游标、Enter 选中、Esc / 外点关掉"
6200
+ }, /* @__PURE__ */ h(Grid, null, /* @__PURE__ */ h(Cell, { label: "常规档(默认,带 label / hint)" }, /* @__PURE__ */ h(SelectDemo, null)), /* @__PURE__ */ h(Cell, { label: "variant=ghost(左栏工作区那一种)" }, /* @__PURE__ */ h(SelectDemo, { variant: "ghost" })), /* @__PURE__ */ h(Cell, { label: "搜索 + 分组 + 禁用项 + 页脚动作" }, /* @__PURE__ */ h(SelectRichDemo, null)), /* @__PURE__ */ h(Cell, { label: "禁用 / 加载中 / 名单读不到时退化成手填" }, /* @__PURE__ */ h(SelectStateDemo, null)), /* @__PURE__ */ h(Cell, {
6201
+ label: "图标 + 当前值(无边框)与 selection=check",
6202
+ wide: true
6203
+ }, /* @__PURE__ */ h(AppearanceDemo, null))));
6204
+ }
6205
+ function FormsSection() {
6206
+ return /* @__PURE__ */ h(Section, {
6207
+ title: "输入与本机选择",
6208
+ note: "TextField 的三个态、ChoiceGroup 的单选 / 多选 / 禁用 / 无边框档 / 加载中 / 没得选 / 长候选带说明、FormActions(主操作在右、窄容器换行)、SaveBar、Link"
6209
+ }, /* @__PURE__ */ h(Grid, null, /* @__PURE__ */ h(Cell, { label: "TextField(正常 / invalid / 禁用)" }, /* @__PURE__ */ h(TextFieldDemo, null)), /* @__PURE__ */ h(Cell, { label: "ChoiceGroup(单选 / 多选 / 禁用 / ghost / loading / empty / description)" }, /* @__PURE__ */ h(ChoiceDemo, null)), /* @__PURE__ */ h(Cell, {
6210
+ label: "FormActions(普通两动作 / 带 danger / busy+disabled / 窄容器换行后 primary 仍在右下角)",
6211
+ wide: true
6212
+ }, /* @__PURE__ */ h(FormActionsDemo, null)), /* @__PURE__ */ h(Cell, { label: "SaveBar(点保存看它转起来)" }, /* @__PURE__ */ h(SaveBarDemo, null)), /* @__PURE__ */ h(Cell, { label: "Link(外链与站内)" }, /* @__PURE__ */ h(LinkDemo, null))));
6213
+ }
6214
+ function CardSection({ t }) {
6215
+ return /* @__PURE__ */ h(Section, {
6216
+ title: "卡片与卡头",
6217
+ note: "模块卡片自己渲染 Card;外壳只在外层套 CardAnchor(display: contents)与 CardBoundary(崩了才看得见)"
6218
+ }, /* @__PURE__ */ h(Grid, null, /* @__PURE__ */ h(Cell, {
6219
+ label: "Card(整张卡)",
6220
+ wide: true
6221
+ }, /* @__PURE__ */ h("div", { className: kit_preview_module_default.bound }, /* @__PURE__ */ h(Card, {
6222
+ t,
6223
+ title: "示例卡片",
6224
+ meta: "夹具",
6225
+ refreshing: false,
6226
+ onRefresh: () => {}
6227
+ }, /* @__PURE__ */ h(Note, null, "卡身里放什么都行:这张预览卡自己就是个例子。")))), /* @__PURE__ */ h(Cell, {
6228
+ label: "CardHead(带齿轮与平台跳转)",
6229
+ wide: true
6230
+ }, /* @__PURE__ */ h("div", { className: kit_preview_module_default.bound }, /* @__PURE__ */ h(CardHead, {
6231
+ t,
6232
+ title: "卡头",
6233
+ meta: "3 分钟前",
6234
+ refreshing: false,
6235
+ onRefresh: () => {},
6236
+ gear: "面板设置",
6237
+ gearOpen: true,
6238
+ onToggleGear: () => {},
6239
+ platform: "打开平台",
6240
+ platformTitle: "去平台上看看",
6241
+ platformHref: "https://example.com/panel"
6242
+ })))));
6243
+ }
6244
+ function StateSection() {
6245
+ return /* @__PURE__ */ h(Section, {
6246
+ title: "状态与提示",
6247
+ note: "Note / StateBlock / CenteredState / EmptyState / SkeletonRows:卡里那几种“没东西可看”的说法"
6248
+ }, /* @__PURE__ */ h(Grid, null, /* @__PURE__ */ h(Cell, { label: "Note(muted 与 problem)" }, /* @__PURE__ */ h(Note, null, "这句是说明。"), /* @__PURE__ */ h(Note, { tone: "problem" }, "这句是问题。")), /* @__PURE__ */ h(Cell, { label: "StateBlock(点 + 标题 + 提示 + 动作)" }, /* @__PURE__ */ h(StateBlock, {
6249
+ dot: /* @__PURE__ */ h(StateDot, {
6250
+ state: "ongoing",
6251
+ size: 10
6252
+ }),
6253
+ title: "正在读",
6254
+ hint: "读回来之前这一块先这么说",
6255
+ resolving: "还剩 3 秒"
6256
+ }, /* @__PURE__ */ h(SkeletonRows, { rows: 3 }))), /* @__PURE__ */ h(Cell, { label: "CenteredState(大图标 / 紧凑)" }, /* @__PURE__ */ h(CenteredState, {
6257
+ icon: /* @__PURE__ */ h(IconPanelScreen, { size: 32 }),
6258
+ title: "这块还没接上",
6259
+ hint: "接上之后这里会有数据",
6260
+ action: /* @__PURE__ */ h(Note, null, "动作用 Note 或 Button 都行")
6261
+ }), /* @__PURE__ */ h(CenteredState, {
6262
+ compact: true,
6263
+ icon: /* @__PURE__ */ h(IconModules, { size: 20 }),
6264
+ title: "紧凑的那一档"
6265
+ })), /* @__PURE__ */ h(Cell, { label: "EmptyState 与 SkeletonRows" }, /* @__PURE__ */ h(EmptyState, {
6266
+ text: "一条都还没有",
6267
+ icon: /* @__PURE__ */ h(IconBrandMark, { size: 20 })
6268
+ }), /* @__PURE__ */ h(SkeletonRows, { rows: 2 }))));
6269
+ }
6270
+ function KitPreview({ t }) {
6271
+ return /* @__PURE__ */ h(Card, {
6272
+ t,
6273
+ title: "公共组件预览",
6274
+ meta: "夹具 · 只在 ?wbMock=1 下摆出来",
6275
+ refreshing: false,
6276
+ onRefresh: () => {}
6277
+ }, /* @__PURE__ */ h(KitNavProvider, null, /* @__PURE__ */ h("div", { className: kit_preview_module_default.gallery }, /* @__PURE__ */ h(Note, null, "这里把 ", /* @__PURE__ */ h("code", null, "@dsh-workbench/shared"), " 里那套哑组件按“样式 + 交互”摆了一遍:能点的都点得动, 能搜的都能搜。没摆的是要真实数据的那些(ApprovalDetail 要一份会话快照、CardBoundary 要一张会炸的卡 —— 那个走 ?wbCrash=1)。"), /* @__PURE__ */ h(KitNav, null), /* @__PURE__ */ h(SelectSection, null), /* @__PURE__ */ h(FormsSection, null), /* @__PURE__ */ h(RowsSection, null), /* @__PURE__ */ h(FormSection, null), /* @__PURE__ */ h(CardSection, { t }), /* @__PURE__ */ h(StateSection, null), /* @__PURE__ */ h(ActivitySection, null), /* @__PURE__ */ h(LongTaskSection, null), /* @__PURE__ */ h(IconSection, null), /* @__PURE__ */ h(StripSection, null))));
6278
+ }
6279
+ var KIT_PREVIEW_MODULE = {
6280
+ id: "wb-kit-preview",
6281
+ titleKey: "组件预览",
6282
+ order: 999,
6283
+ View: KitPreview
6284
+ };
6285
+ //#endregion
6286
+ //#region src/dev/surface.ts
6287
+ var rosterOf = (manifests) => fixtureRoster(manifests);
6288
+ function mocksOf(site, manifests) {
6289
+ if (site === "panel") return buildPanelMocks(rosterOf(manifests));
6290
+ if (site === "market") return buildMarketMocks(rosterOf(manifests));
6291
+ return ADD_MODULE_MOCKS;
6292
+ }
6293
+ function useBoard(input) {
6294
+ const fixtures = useBoardMock(rosterOf(input.manifests));
6295
+ const crash = crashModeOn(input.search);
3270
6296
  return {
3271
- capability,
3272
- gated: gateOf(capability, options.mode ?? "capability").gated,
3273
- forceProbe
6297
+ shape: fixtures.shape,
6298
+ seed: fixtureSeed(input.manifests, input.all, crash),
6299
+ strip: (show) => h(BoardMockStrip, {
6300
+ fixtures,
6301
+ show
6302
+ }),
6303
+ mode: mockModeOn(input.search) || crash
3274
6304
  };
3275
6305
  }
3276
- function useCapabilityMap(refreshToken) {
3277
- const [probeNonce, setProbeNonce] = useState(0);
3278
- const [reloadNonce, setReloadNonce] = useState(0);
3279
- const forceProbe = useCallback(() => setProbeNonce((value) => value + 1), []);
3280
- const reload = useCallback(() => setReloadNonce((value) => value + 1), []);
3281
- const probe = useCapabilityProbe();
6306
+ function useStrips(site, manifests) {
6307
+ const mocks = useMemo(() => mocksOf(site, manifests), [site, manifests]);
6308
+ const pick = useFixturePick({
6309
+ fixtures: mocks,
6310
+ initial: mocks[0]?.id ?? null
6311
+ });
3282
6312
  return {
3283
- capabilities: useCapabilities(refreshToken + probeNonce, reloadNonce),
3284
- ...probe,
3285
- forceProbe,
3286
- reload
6313
+ pick,
6314
+ current: pick.enabled ? pick.current : void 0,
6315
+ enabled: pick.enabled,
6316
+ strip: pick.enabled ? h(MockStrip, {
6317
+ mocks,
6318
+ index: pick.index,
6319
+ onPick: (at) => pick.pick(mocks[at]?.id ?? null)
6320
+ }) : null
3287
6321
  };
3288
6322
  }
3289
- //#endregion
3290
- //#region src/dev/surface.stub.ts
3291
- var noop = () => void 0;
6323
+ function gateStrip(options) {
6324
+ return mountGateMockStrip(options);
6325
+ }
6326
+ function addModuleState(base, mock) {
6327
+ return stateOfMock(base, mock);
6328
+ }
3292
6329
  var devSurface = {
3293
- on: () => false,
3294
- crash: () => false,
3295
- useBoard: ({ all }) => ({
3296
- shape: { kind: "real" },
3297
- seed: all,
3298
- strip: () => null,
3299
- mode: false
3300
- }),
3301
- useStrips: () => ({
3302
- pick: {
3303
- enabled: false,
3304
- active: null,
3305
- current: void 0,
3306
- nonce: 0,
3307
- index: 0,
3308
- pick: noop
3309
- },
3310
- current: void 0,
3311
- enabled: false,
3312
- strip: null
3313
- }),
3314
- addModuleState: (base) => base,
3315
- gateStrip: () => null,
3316
- kitModule: null
6330
+ on: (search) => mockModeOn(search),
6331
+ crash: (search) => crashModeOn(search),
6332
+ useBoard,
6333
+ useStrips,
6334
+ addModuleState,
6335
+ gateStrip,
6336
+ kitModule: KIT_PREVIEW_MODULE
3317
6337
  };
3318
6338
  //#endregion
3319
6339
  //#region src/app/layouts/panel-hint.ts
3320
6340
  var hints = /* @__PURE__ */ new Map();
3321
- var listeners$2 = /* @__PURE__ */ new Set();
6341
+ var listeners$3 = /* @__PURE__ */ new Set();
3322
6342
  function publishPanelHint(id, hint) {
3323
6343
  if ((hints.get(id)?.labelKey ?? null) === (hint?.labelKey ?? null)) return;
3324
6344
  if (hint === null) hints.delete(id);
3325
6345
  else hints.set(id, hint);
3326
- for (const listener of [...listeners$2]) listener();
6346
+ for (const listener of [...listeners$3]) listener();
3327
6347
  }
3328
6348
  function panelHintOf(id) {
3329
6349
  return id === null ? null : hints.get(id) ?? null;
3330
6350
  }
3331
6351
  function subscribePanelHints(listener) {
3332
- listeners$2.add(listener);
6352
+ listeners$3.add(listener);
3333
6353
  return () => {
3334
- listeners$2.delete(listener);
6354
+ listeners$3.delete(listener);
3335
6355
  };
3336
6356
  }
3337
6357
  function usePanelHint(id) {
@@ -4970,6 +7990,26 @@ function attentionOfSession(summary, statusById, sessions) {
4970
7990
  if (node.running || node.runningSubagentCount > 0) return "ongoing";
4971
7991
  if (node.completed) return "done";
4972
7992
  }
7993
+ function attentionSessionIdOf(input) {
7994
+ const workspace = input.workspace;
7995
+ if (workspace === null) return null;
7996
+ let best;
7997
+ let bestRank = -1;
7998
+ for (const summary of sessionRows(workspace.sessionIds, input.sessions, input.archivedIds)) {
7999
+ const ofSession = attentionOfSession(summary, input.statusById, input.sessions);
8000
+ if (ofSession === void 0 || ofSession === "ongoing") continue;
8001
+ const rank = RANK[ofSession];
8002
+ if (best === void 0 || rank > bestRank || rank === bestRank && isLater(summary, best)) {
8003
+ best = summary;
8004
+ bestRank = rank;
8005
+ }
8006
+ }
8007
+ return best?.id ?? null;
8008
+ }
8009
+ function isLater(left, right) {
8010
+ if (left.updatedAt !== right.updatedAt) return left.updatedAt > right.updatedAt;
8011
+ return left.id < right.id;
8012
+ }
4973
8013
  function attentionOf(input) {
4974
8014
  const byWorkspace = /* @__PURE__ */ new Map();
4975
8015
  let elsewhere = null;
@@ -4994,17 +8034,17 @@ function attentionOf(input) {
4994
8034
  }
4995
8035
  }
4996
8036
  if (severity === void 0) continue;
4997
- const own = {
8037
+ byWorkspace.set(workspace.workspaceId, {
4998
8038
  severity,
4999
8039
  count
5000
- };
5001
- byWorkspace.set(workspace.workspaceId, own);
5002
- overall = merge(overall, own);
5003
- if (workspace.workspaceId === input.currentWorkspaceId || tagged === void 0) continue;
5004
- elsewhere = merge(elsewhere, {
8040
+ });
8041
+ if (tagged === void 0) continue;
8042
+ const own = {
5005
8043
  severity: tagged,
5006
8044
  count: taggedCount
5007
- });
8045
+ };
8046
+ overall = merge(overall, own);
8047
+ if (workspace.workspaceId !== input.currentWorkspaceId) elsewhere = merge(elsewhere, own);
5008
8048
  }
5009
8049
  return {
5010
8050
  byWorkspace,
@@ -5029,21 +8069,21 @@ function attentionWordLabel(attention, t) {
5029
8069
  }
5030
8070
  //#endregion
5031
8071
  //#region src/app/layouts/project-selection.ts
5032
- var listeners$1 = /* @__PURE__ */ new Set();
8072
+ var listeners$2 = /* @__PURE__ */ new Set();
5033
8073
  function selectedProjectId() {
5034
8074
  const stored = readText(STORAGE_KEY_PROJECT);
5035
8075
  return stored === "" ? null : stored;
5036
8076
  }
5037
8077
  function selectProject(workspaceId) {
5038
8078
  writeText(STORAGE_KEY_PROJECT, workspaceId);
5039
- for (const listener of [...listeners$1]) try {
8079
+ for (const listener of [...listeners$2]) try {
5040
8080
  listener();
5041
8081
  } catch {}
5042
8082
  }
5043
8083
  function subscribeProject(listener) {
5044
- listeners$1.add(listener);
8084
+ listeners$2.add(listener);
5045
8085
  return () => {
5046
- listeners$1.delete(listener);
8086
+ listeners$2.delete(listener);
5047
8087
  };
5048
8088
  }
5049
8089
  //#endregion
@@ -5129,7 +8169,7 @@ var state = {
5129
8169
  read: false,
5130
8170
  checkedAt: null
5131
8171
  };
5132
- var listeners = /* @__PURE__ */ new Set();
8172
+ var listeners$1 = /* @__PURE__ */ new Set();
5133
8173
  var inFlight = null;
5134
8174
  var readSeq = 0;
5135
8175
  var newestForceSeq = -1;
@@ -5137,14 +8177,14 @@ function moduleVersionsValue() {
5137
8177
  return state;
5138
8178
  }
5139
8179
  function subscribeModuleVersions(listener) {
5140
- listeners.add(listener);
8180
+ listeners$1.add(listener);
5141
8181
  return () => {
5142
- listeners.delete(listener);
8182
+ listeners$1.delete(listener);
5143
8183
  };
5144
8184
  }
5145
8185
  function publish(next) {
5146
8186
  state = next;
5147
- for (const listener of [...listeners]) listener();
8187
+ for (const listener of [...listeners$1]) listener();
5148
8188
  }
5149
8189
  function runModuleVersionsRead(force = false) {
5150
8190
  if (inFlight !== null && inFlight.force === force) return inFlight.promise;
@@ -5894,9 +8934,17 @@ function registerMarketPanel(ctx, units) {
5894
8934
  }, MarketPanel));
5895
8935
  }
5896
8936
  //#endregion
5897
- //#region src/shared/api/config-sync.ts
5898
- var CONFIG_SYNC_ROUTE = "config-sync";
5899
- var CONFIG_SYNC_RESOURCE = "configSync";
8937
+ //#region src/shared/api/diy.ts
8938
+ var DIY_PRESET_ID = "workbench-diy";
8939
+ var WORKSHOP_RELATIVE = "workbench/diy";
8940
+ var WORKSHOP_TITLE = "工作台DIY";
8941
+ var WORKSHOP_PAST_TITLES = ["DIY 工坊", "工作台自带 · DIY 模块住这儿"];
8942
+ function isWorkshopPath(path) {
8943
+ return path.replace(/\\/g, "/").replace(/\/+$/, "").endsWith(`/${WORKSHOP_RELATIVE}`);
8944
+ }
8945
+ function diyStartOptions(workspaceId, workshopId) {
8946
+ return workshopId !== void 0 && workshopId === workspaceId ? { agentPreset: DIY_PRESET_ID } : void 0;
8947
+ }
5900
8948
  //#endregion
5901
8949
  //#region src/shared/hooks/panel-state-report.ts
5902
8950
  var FLUSH_MS = 400;
@@ -6019,7 +9067,7 @@ function useApiResource(route, query, refreshToken, options = {}) {
6019
9067
  ...prev.at === void 0 ? {} : { at: prev.at }
6020
9068
  } : { phase: "loading" });
6021
9069
  const flight = requestResource(route, queryRef.current, key);
6022
- const owner = unitOfRoute(route);
9070
+ const owner = options.report === false ? null : unitOfRoute(route);
6023
9071
  if (owner !== null) reportPanelRead({
6024
9072
  unit: owner,
6025
9073
  route,
@@ -6084,10 +9132,201 @@ function useApiResource(route, query, refreshToken, options = {}) {
6084
9132
  refreshToken,
6085
9133
  factRev,
6086
9134
  enabled,
6087
- options.fact
9135
+ options.fact,
9136
+ options.report
6088
9137
  ]);
6089
9138
  return state;
6090
9139
  }
9140
+ //#endregion
9141
+ //#region src/shared/hooks/use-diy-debug.ts
9142
+ var DIY_DEBUG_ROUTE = "panels/diy-debug";
9143
+ var DIY_DEBUG_FACT = "diy-debug";
9144
+ function useDiyDebugState() {
9145
+ const read = useApiResource(DIY_DEBUG_ROUTE, {}, 0, {
9146
+ fact: DIY_DEBUG_FACT,
9147
+ report: false
9148
+ });
9149
+ if (read.value === void 0) return null;
9150
+ return read.value.state ?? null;
9151
+ }
9152
+ function useDiyDebugAct() {
9153
+ return useHostWrite({
9154
+ channel: "diy-debug",
9155
+ resource: "act",
9156
+ networkText: "网络不通,动作没发出去"
9157
+ });
9158
+ }
9159
+ //#endregion
9160
+ //#region src/app/layouts/rightbar/board-fact.ts
9161
+ var BOARD_PROBE_UNKNOWN = {
9162
+ workbench: true,
9163
+ where: "",
9164
+ bar: false,
9165
+ board: "",
9166
+ open: false,
9167
+ drawn: false
9168
+ };
9169
+ var probe = BOARD_PROBE_UNKNOWN;
9170
+ var listeners = /* @__PURE__ */ new Set();
9171
+ function boardProbe() {
9172
+ return probe;
9173
+ }
9174
+ function same(left, right) {
9175
+ return left.workbench === right.workbench && left.where === right.where && left.bar === right.bar && left.board === right.board && left.open === right.open && left.drawn === right.drawn;
9176
+ }
9177
+ function publishBoardProbe(next) {
9178
+ if (same(next, probe)) return;
9179
+ probe = next;
9180
+ for (const listener of [...listeners]) try {
9181
+ listener();
9182
+ } catch {}
9183
+ }
9184
+ function subscribeBoardProbe(listener) {
9185
+ listeners.add(listener);
9186
+ return () => {
9187
+ listeners.delete(listener);
9188
+ };
9189
+ }
9190
+ var DebugFooterAction_module_default = {
9191
+ slot: "_slot_1og2k_1",
9192
+ action: "_action_1og2k_12",
9193
+ live: "_live_1og2k_31",
9194
+ paused: "_paused_1og2k_35",
9195
+ trouble: "_trouble_1og2k_39",
9196
+ pulse: "_pulse_1og2k_43",
9197
+ "wb-debug-breathe": "_wb-debug-breathe_1og2k_1",
9198
+ entry: "_entry_1og2k_64",
9199
+ entryInner: "_entryInner_1og2k_71",
9200
+ acts: "_acts_1og2k_78",
9201
+ act: "_act_1og2k_12",
9202
+ actStop: "_actStop_1og2k_110",
9203
+ actArmed: "_actArmed_1og2k_115",
9204
+ actLabel: "_actLabel_1og2k_125",
9205
+ entryLine: "_entryLine_1og2k_131",
9206
+ actionRail: "_actionRail_1og2k_138",
9207
+ card: "_card_1og2k_150",
9208
+ cardTitle: "_cardTitle_1og2k_156",
9209
+ cardNote: "_cardNote_1og2k_162"
9210
+ };
9211
+ //#endregion
9212
+ //#region src/app/layouts/sidebar/DebugFooterAction.tsx
9213
+ function debugFooterView(state, t, trouble = "none") {
9214
+ const shown = state.phase === "paused" ? "none" : trouble;
9215
+ const label = shown !== "none" ? t("debug.status.trouble") : state.phase === "paused" ? t("debug.stalled") : t("debug.status");
9216
+ const noteOf = (kind) => kind === "panel" ? t("debug.card.hidden.note") : t("debug.card.away.note");
9217
+ if (state.phase === "paused") return {
9218
+ label,
9219
+ title: label,
9220
+ note: t("debug.card.paused.note"),
9221
+ trouble: "none",
9222
+ stalled: true
9223
+ };
9224
+ if (shown !== "none") return {
9225
+ label,
9226
+ title: label,
9227
+ note: noteOf(shown),
9228
+ trouble: shown,
9229
+ stalled: false
9230
+ };
9231
+ return {
9232
+ label,
9233
+ title: t("debug.card.here.title"),
9234
+ note: t("debug.card.here.note"),
9235
+ trouble: "none",
9236
+ stalled: false
9237
+ };
9238
+ }
9239
+ var EMPTY_WORKSPACES = {
9240
+ items: [],
9241
+ archivedSessionIds: [],
9242
+ pinnedSessionIds: []
9243
+ };
9244
+ var EMPTY_SESSIONS = {
9245
+ byId: {},
9246
+ projectionsBySession: {}
9247
+ };
9248
+ function DebugFooterAction({ wide, t, useWorkspaces, useSessions }) {
9249
+ const state = useDiyDebugState();
9250
+ const act = useDiyDebugAct();
9251
+ const probe = useSyncExternalStore(subscribeBoardProbe, boardProbe);
9252
+ const workspaces = useWorkspaces?.((snapshot) => snapshot) ?? EMPTY_WORKSPACES;
9253
+ const here = useBoardWorkspace(workspaces, useSessions?.((snapshot) => snapshot) ?? EMPTY_SESSIONS);
9254
+ const workshop = workspaces.items.find((item) => isWorkshopPath(item.path));
9255
+ const [armed, setArmed] = useState(false);
9256
+ if (state === null) return null;
9257
+ const workshopPath = workshop?.path ?? null;
9258
+ const situation = boardSituation({
9259
+ ...probe,
9260
+ where: here.path ?? ""
9261
+ }, workshopPath);
9262
+ const view = debugFooterView(state, t, situation === "off-workspace" || situation === "other-board" ? "workspace" : situation === "panel-closed" ? "panel" : "none");
9263
+ const dot = /* @__PURE__ */ h(StateDot, {
9264
+ state: view.trouble !== "none" ? "error" : view.stalled ? "warning" : "done",
9265
+ className: view.trouble === "none" && !view.stalled ? DebugFooterAction_module_default.pulse : void 0
9266
+ });
9267
+ const tone = view.trouble !== "none" ? DebugFooterAction_module_default.trouble : view.stalled ? DebugFooterAction_module_default.paused : DebugFooterAction_module_default.live;
9268
+ const press = (intent) => (event) => {
9269
+ event.stopPropagation();
9270
+ act.send({ intent });
9271
+ };
9272
+ const onStop = (event) => {
9273
+ event.stopPropagation();
9274
+ if (!armed) {
9275
+ setArmed(true);
9276
+ return;
9277
+ }
9278
+ setArmed(false);
9279
+ act.send({ intent: "stop" });
9280
+ };
9281
+ const acts = /* @__PURE__ */ h("span", { className: DebugFooterAction_module_default.acts }, view.stalled ? /* @__PURE__ */ h("button", {
9282
+ type: "button",
9283
+ className: DebugFooterAction_module_default.act,
9284
+ "aria-label": t("debug.act.resume"),
9285
+ onClick: press("resume")
9286
+ }, /* @__PURE__ */ h(IconPlayOutlineRegular, { size: 12 })) : /* @__PURE__ */ h("button", {
9287
+ type: "button",
9288
+ className: DebugFooterAction_module_default.act,
9289
+ "aria-label": t("debug.act.pause"),
9290
+ onClick: press("pause")
9291
+ }, /* @__PURE__ */ h(IconPauseOutlineRegular, { size: 12 })), /* @__PURE__ */ h("button", {
9292
+ type: "button",
9293
+ className: cx(DebugFooterAction_module_default.act, DebugFooterAction_module_default.actStop, armed ? DebugFooterAction_module_default.actArmed : void 0),
9294
+ "data-act-state": armed ? "armed" : "idle",
9295
+ "aria-label": armed ? t("debug.act.stop.ask") : t("debug.act.stop"),
9296
+ onClick: onStop,
9297
+ onBlur: () => setArmed(false)
9298
+ }, /* @__PURE__ */ h(IconStopFillRegular, { size: 12 }), armed ? /* @__PURE__ */ h("span", { className: DebugFooterAction_module_default.actLabel }, t("debug.act.stop.ask")) : null));
9299
+ const status = /* @__PURE__ */ h("span", { className: DebugFooterAction_module_default.entryInner }, dot, wide === true ? /* @__PURE__ */ h("span", { className: DebugFooterAction_module_default.entryLine }, view.label) : null);
9300
+ const row = /* @__PURE__ */ h("div", { className: cx(DebugFooterAction_module_default.action, wide === true ? void 0 : DebugFooterAction_module_default.actionRail, tone) }, /* @__PURE__ */ h("span", {
9301
+ className: DebugFooterAction_module_default.entry,
9302
+ role: "status",
9303
+ "aria-label": `${view.label},${view.note}`
9304
+ }, wide === true ? /* @__PURE__ */ h(Tip, {
9305
+ label: view.note,
9306
+ side: "top"
9307
+ }, status) : status), wide === true ? acts : null);
9308
+ if (wide === true) return /* @__PURE__ */ h("span", { className: DebugFooterAction_module_default.slot }, row);
9309
+ return /* @__PURE__ */ h("span", { className: DebugFooterAction_module_default.slot }, /* @__PURE__ */ h(HoverCard, {
9310
+ anchor: row,
9311
+ content: /* @__PURE__ */ h("div", { className: DebugFooterAction_module_default.card }, /* @__PURE__ */ h("div", { className: DebugFooterAction_module_default.cardTitle }, view.title), /* @__PURE__ */ h("div", { className: DebugFooterAction_module_default.cardNote }, view.note), acts),
9312
+ openDelayMs: 200
9313
+ }));
9314
+ }
9315
+ //#endregion
9316
+ //#region src/app/layouts/sidebar/debug-footer.tsx
9317
+ var DEBUG_FOOTER_ID = "workbench-debug";
9318
+ function registerDebugFooter(ctx) {
9319
+ ctx.slots.inject("sidebar.footer.action", () => ctx.slots.register({
9320
+ name: "sidebar.footer.action",
9321
+ id: DEBUG_FOOTER_ID,
9322
+ order: 10,
9323
+ locale: LOCALE_NS
9324
+ }, DebugFooterAction));
9325
+ }
9326
+ //#endregion
9327
+ //#region src/shared/api/config-sync.ts
9328
+ var CONFIG_SYNC_ROUTE = "config-sync";
9329
+ var CONFIG_SYNC_RESOURCE = "configSync";
6091
9330
  var ConfigSyncSection_module_default = {
6092
9331
  body: "_body_lw2ph_1",
6093
9332
  lead: "_lead_lw2ph_7",
@@ -6326,208 +9565,20 @@ function ConfigSyncSection({ t }) {
6326
9565
  onToggle: toggle
6327
9566
  }) : null, rows.length > 0 ? /* @__PURE__ */ h("div", { className: ConfigSyncSection_module_default.foot }, /* @__PURE__ */ h(Button, {
6328
9567
  variant: "primary",
6329
- size: "md",
6330
- icon: /* @__PURE__ */ h(IconRefreshOutlineRegular, {
6331
- size: 16,
6332
- "aria-hidden": "true"
6333
- }),
6334
- disabled: chosen.length === 0 || busy.busy,
6335
- onClick: apply
6336
- }, chosen.length === 0 ? t("configSync.applyNone") : busy.busy ? t("configSync.applying") : t("configSync.apply", { count: chosen.length }))) : null) : null));
6337
- }
6338
- //#endregion
6339
- //#region src/shared/api/diy.ts
6340
- var DIY_PRESET_ID = "workbench-diy";
6341
- var WORKSHOP_RELATIVE = "workbench/diy";
6342
- var WORKSHOP_TITLE = "工作台DIY";
6343
- var WORKSHOP_PAST_TITLES = ["DIY 工坊", "工作台自带 · DIY 模块住这儿"];
6344
- function isWorkshopPath(path) {
6345
- return path.replace(/\\/g, "/").replace(/\/+$/, "").endsWith(`/${WORKSHOP_RELATIVE}`);
6346
- }
6347
- function diyStartOptions(workspaceId, workshopId) {
6348
- return workshopId !== void 0 && workshopId === workspaceId ? { agentPreset: DIY_PRESET_ID } : void 0;
6349
- }
6350
- //#endregion
6351
- //#region src/app/units/index.ts
6352
- var CLIENT_UNITS = [];
6353
- function assembleClientUnits(registry) {
6354
- for (const face of CLIENT_UNITS) registry.register(face);
6355
- }
6356
- //#endregion
6357
- //#region src/app/layouts/rightbar/registry.ts
6358
- function createBoardRegistry() {
6359
- const modules = [];
6360
- const listeners = /* @__PURE__ */ new Set();
6361
- let revision = 0;
6362
- let sorted = [];
6363
- let index = /* @__PURE__ */ new Map();
6364
- let steps = /* @__PURE__ */ new Map();
6365
- function rebuild() {
6366
- sorted = [...modules].sort((a, b) => a.order - b.order || a.id.localeCompare(b.id));
6367
- index = new Map(sorted.map((module) => [module.id, module]));
6368
- const table = /* @__PURE__ */ new Map();
6369
- for (const module of sorted) for (const kind of Object.keys(module.steps ?? {})) {
6370
- const owner = table.get(kind);
6371
- if (owner !== void 0) throw new Error(`看板层名重复:${kind}(${owner.id} 与 ${module.id} 都声明了它)`);
6372
- table.set(kind, module);
6373
- }
6374
- steps = table;
6375
- }
6376
- function notify() {
6377
- revision += 1;
6378
- for (const listener of listeners) listener();
6379
- }
6380
- return {
6381
- register(module) {
6382
- if (modules.some((item) => item.id === module.id)) throw new Error(`看板模块 id 重复:${module.id}(id 会进持久化配置,不能撞)`);
6383
- modules.push(module);
6384
- try {
6385
- rebuild();
6386
- } catch (error) {
6387
- modules.pop();
6388
- rebuild();
6389
- throw error;
6390
- }
6391
- notify();
6392
- return () => {
6393
- const at = modules.indexOf(module);
6394
- if (at < 0) return;
6395
- modules.splice(at, 1);
6396
- rebuild();
6397
- notify();
6398
- };
6399
- },
6400
- all: () => sorted,
6401
- byId: (id) => index.get(id),
6402
- stepOwner: (kind) => steps.get(kind),
6403
- subscribe(listener) {
6404
- listeners.add(listener);
6405
- return () => listeners.delete(listener);
6406
- },
6407
- version: () => revision
6408
- };
9568
+ size: "md",
9569
+ icon: /* @__PURE__ */ h(IconRefreshOutlineRegular, {
9570
+ size: 16,
9571
+ "aria-hidden": "true"
9572
+ }),
9573
+ disabled: chosen.length === 0 || busy.busy,
9574
+ onClick: apply
9575
+ }, chosen.length === 0 ? t("configSync.applyNone") : busy.busy ? t("configSync.applying") : t("configSync.apply", { count: chosen.length }))) : null) : null));
6409
9576
  }
6410
9577
  //#endregion
6411
- //#region src/app/units/registry.ts
6412
- function toBoardModule(face, manifest) {
6413
- const View = face.card;
6414
- if (View === void 0) return void 0;
6415
- return {
6416
- id: manifest.id,
6417
- titleKey: manifest.card?.titleKey ?? manifest.id,
6418
- order: manifest.card?.order ?? 100,
6419
- View,
6420
- ...face.steps === void 0 ? {} : { steps: face.steps }
6421
- };
6422
- }
6423
- function createClientUnitRegistry(options = {}) {
6424
- const registrations = [];
6425
- const refusals = [];
6426
- const listeners = /* @__PURE__ */ new Set();
6427
- const board = createBoardRegistry();
6428
- let known = /* @__PURE__ */ new Map();
6429
- let installableIds = null;
6430
- let revision = 0;
6431
- let manifestsCache;
6432
- function notify() {
6433
- revision += 1;
6434
- for (const listener of [...listeners]) try {
6435
- listener();
6436
- } catch (error) {
6437
- console.warn(`[dsh-workbench] 套件注册的订阅者报错(不影响其它订阅者与这次注册):${String(error)}`);
6438
- }
6439
- }
6440
- function warnRefusal(unit, kind, reasons) {
6441
- refusals.push({
6442
- unit,
6443
- kind,
6444
- reasons
6445
- });
6446
- console.warn(`[dsh-workbench] ${unit === "" ? "这个模块" : unit} 的卡片没挂上:${reasons.join(";")}`);
6447
- }
6448
- function takeBackRefusal(unit) {
6449
- for (let at = refusals.length - 1; at >= 0; at -= 1) if (refusals[at]?.unit === unit) refusals.splice(at, 1);
6450
- }
6451
- function attach(entry) {
6452
- const manifest = known.get(entry.unit);
6453
- if (manifest === void 0) return false;
6454
- const boardModule = toBoardModule(entry.face, manifest);
6455
- entry.mounted = {
6456
- manifest,
6457
- unmount: boardModule === void 0 ? () => {} : board.register(boardModule)
6458
- };
6459
- takeBackRefusal(entry.unit);
6460
- return true;
6461
- }
6462
- function detach(entry) {
6463
- entry.mounted?.unmount();
6464
- entry.mounted = null;
6465
- }
6466
- return {
6467
- register(face) {
6468
- const unit = typeof face?.unit === "string" ? face.unit.trim() : "";
6469
- if (unit === "") {
6470
- warnRefusal("", "old-shape", ["registerUnit({ unit, card }) 里的 unit 是空的 —— U1b 之前的旧形状是 registerUnit({ manifest, card });现在清单由外壳从**已装清单**读出来、按 unit 交给浏览器(ADR-0038 §2.2)"]);
6471
- notify();
6472
- return () => {};
6473
- }
6474
- if (registrations.some((entry) => entry.unit === unit)) throw new Error(`套件 id 重复:${unit}(id 会进持久化配置,不能撞)`);
6475
- const entry = {
6476
- face,
6477
- unit,
6478
- mounted: null
6479
- };
6480
- registrations.push(entry);
6481
- manifestsCache = void 0;
6482
- if (!attach(entry)) {
6483
- warnRefusal(unit, "no-manifest", [`宿主没有担保 unit「${unit}」的清单 —— 这个包要么没装进这份 profile,要么它的 dsh.workbench 没通过校验。卡片先不挂:清单只有一处真相(ADR-0038 §2.2)`]);
6484
- options.onUnknownUnit?.(unit);
6485
- }
6486
- notify();
6487
- return () => {
6488
- const at = registrations.indexOf(entry);
6489
- if (at < 0) return;
6490
- registrations.splice(at, 1);
6491
- detach(entry);
6492
- takeBackRefusal(unit);
6493
- manifestsCache = void 0;
6494
- notify();
6495
- };
6496
- },
6497
- all: () => registrations.map((entry) => entry.face),
6498
- manifests: () => {
6499
- manifestsCache ??= registrations.flatMap((entry) => entry.mounted === null ? [] : [entry.mounted.manifest]);
6500
- return manifestsCache;
6501
- },
6502
- refusals: () => refusals,
6503
- installable: () => installableIds,
6504
- setManifests(manifests, installable) {
6505
- known = new Map(manifests.map((manifest) => [manifest.id, manifest]));
6506
- installableIds = installable === void 0 ? null : new Set(installable);
6507
- let changed = false;
6508
- for (const entry of registrations) {
6509
- const next = known.get(entry.unit);
6510
- if (entry.mounted === null) {
6511
- if (next !== void 0 && attach(entry)) changed = true;
6512
- continue;
6513
- }
6514
- if (next === void 0) {
6515
- detach(entry);
6516
- warnRefusal(entry.unit, "withdrawn", [`宿主不再担保 unit「${entry.unit}」的清单(模块被卸了?)—— 这张卡片先摘下来`]);
6517
- changed = true;
6518
- }
6519
- }
6520
- if (!changed) return;
6521
- manifestsCache = void 0;
6522
- notify();
6523
- },
6524
- board,
6525
- subscribe(listener) {
6526
- listeners.add(listener);
6527
- return () => listeners.delete(listener);
6528
- },
6529
- version: () => revision
6530
- };
9578
+ //#region src/app/units/index.ts
9579
+ var CLIENT_UNITS = [];
9580
+ function assembleClientUnits(registry) {
9581
+ for (const face of CLIENT_UNITS) registry.register(face);
6531
9582
  }
6532
9583
  //#endregion
6533
9584
  //#region src/shared/api/unit-manifests.ts
@@ -6564,40 +9615,6 @@ function createUnitManifestLoader(options = {}) {
6564
9615
  load(registry);
6565
9616
  };
6566
9617
  }
6567
- var BootGate_module_default = {
6568
- actions: "_actions_jlw8j_1",
6569
- progress: "_progress_jlw8j_2",
6570
- commandRow: "_commandRow_jlw8j_3",
6571
- bridge: "_bridge_jlw8j_4",
6572
- raw: "_raw_jlw8j_5",
6573
- gate: "_gate_jlw8j_9",
6574
- card: "_card_jlw8j_20",
6575
- title: "_title_jlw8j_35",
6576
- hint: "_hint_jlw8j_43",
6577
- steps: "_steps_jlw8j_50",
6578
- step: "_step_jlw8j_50",
6579
- mark: "_mark_jlw8j_77",
6580
- label: "_label_jlw8j_102",
6581
- detail: "_detail_jlw8j_106",
6582
- elapsed: "_elapsed_jlw8j_124",
6583
- error: "_error_jlw8j_132",
6584
- copy: "_copy_jlw8j_158",
6585
- command: "_command_jlw8j_3",
6586
- buttons: "_buttons_jlw8j_191",
6587
- mockSlot: "_mockSlot_jlw8j_198",
6588
- button: "_button_jlw8j_191",
6589
- fixTitle: "_fixTitle_jlw8j_249",
6590
- rawSummary: "_rawSummary_jlw8j_282",
6591
- bridgeLines: "_bridgeLines_jlw8j_292",
6592
- bridgeLine: "_bridgeLine_jlw8j_292",
6593
- link: "_link_jlw8j_309",
6594
- loading: "_loading_jlw8j_323",
6595
- loadingMotion: "_loadingMotion_jlw8j_332",
6596
- "wb-spin": "_wb-spin_jlw8j_1",
6597
- loadingTrack: "_loadingTrack_jlw8j_337",
6598
- loadingArc: "_loadingArc_jlw8j_338",
6599
- "wb-dash": "_wb-dash_jlw8j_1"
6600
- };
6601
9618
  //#endregion
6602
9619
  //#region src/app/layouts/env-gate/gate-text.ts
6603
9620
  function failedStepText(guidance, t) {
@@ -7950,22 +10967,12 @@ function BoardContent({ top, plan, world, board, twoColumns, panelToken, onPanel
7950
10967
  }))))))));
7951
10968
  }
7952
10969
  function Rightbar(props) {
7953
- const units = props.units;
7954
- useSyncExternalStore(useCallback((listener) => units.subscribe(listener), [units]), useCallback(() => units.version(), [units]));
7955
- const modules = units.board;
7956
- const manifests = units.manifests();
7957
- const titleKeyOf = (kind) => modules.stepOwner(kind)?.steps?.[kind]?.titleKey;
7958
- const state = props.useRightbar((snapshot) => snapshot);
7959
- const sessions = props.useSessions((snapshot) => snapshot);
7960
- const workspaces = props.useWorkspaces((snapshot) => snapshot);
7961
- const [panelToken, setPanelToken] = useState(0);
7962
- const refreshPanel = useCallback(() => setPanelToken((value) => value + 1), []);
7963
- const { capabilities } = useCapabilityMap(panelToken);
7964
- const board = useBoardWorkspace(workspaces, sessions);
10970
+ const { modules, manifests, titleKeyOf, state, sessions, workspaces, panelToken, refreshPanel, capabilities, board } = useRightbarWiring(props);
7965
10971
  const boardWorkspace = board.path;
7966
10972
  const panelBoard = useEnabledUnits(panelToken, boardWorkspace);
7967
10973
  const enabledUnits = panelBoard?.units ?? null;
7968
10974
  const [modulesOpen, setModulesOpen] = useState(false);
10975
+ const asideRef = useRef(null);
7969
10976
  const devBoard = devSurface.useBoard({
7970
10977
  manifests,
7971
10978
  all: modules.all(),
@@ -8004,6 +11011,36 @@ function Rightbar(props) {
8004
11011
  const summary = aggregateSummaries(plan.modules.map((entry) => summaries[entry.module.id]).filter((item) => item !== void 0));
8005
11012
  const feedEnabled = plan.modules.length > 0 || plan.reading;
8006
11013
  const shown = state.expanded;
11014
+ useLayoutEffect(() => {
11015
+ const el = asideRef.current;
11016
+ const drawnNow = () => {
11017
+ if (el === null) return false;
11018
+ const style = getComputedStyle(el);
11019
+ const box = el.getBoundingClientRect();
11020
+ return style.visibility !== "hidden" && style.display !== "none" && box.width > 0 && box.height > 0;
11021
+ };
11022
+ const publish = () => {
11023
+ publishBoardProbe({
11024
+ workbench: true,
11025
+ where: boardWorkspace ?? "",
11026
+ bar: true,
11027
+ board: fixtureMode ? "" : boardWorkspace ?? "",
11028
+ open: shown,
11029
+ drawn: drawnNow()
11030
+ });
11031
+ };
11032
+ publish();
11033
+ const observer = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(publish);
11034
+ if (observer !== null && el !== null) observer.observe(el);
11035
+ return () => {
11036
+ observer?.disconnect();
11037
+ publishBoardProbe(BOARD_PROBE_UNKNOWN);
11038
+ };
11039
+ }, [
11040
+ boardWorkspace,
11041
+ fixtureMode,
11042
+ shown
11043
+ ]);
8007
11044
  const presentation = rightbarPresentation({
8008
11045
  shown,
8009
11046
  viewportWidth: props.viewportWidth,
@@ -8029,10 +11066,13 @@ function Rightbar(props) {
8029
11066
  const navigate = (step) => props.openPanel(step);
8030
11067
  const openMarket = () => props.openMarket();
8031
11068
  return /* @__PURE__ */ h("aside", {
11069
+ ref: asideRef,
8032
11070
  className: `wb-rightbar ${Rightbar_module_default.panel}`,
8033
11071
  style: { width: panelWidth },
8034
11072
  "data-open": shown ? "" : void 0,
8035
11073
  "data-fullscreen": fullscreen ? "" : void 0,
11074
+ "data-wb-board": fixtureMode ? void 0 : boardWorkspace ?? void 0,
11075
+ "data-wb-open": fixtureMode || !shown ? void 0 : "",
8036
11076
  "aria-label": props.t("rightbar.label")
8037
11077
  }, /* @__PURE__ */ h(PanelHeader, {
8038
11078
  t: props.t,
@@ -8068,6 +11108,36 @@ function Rightbar(props) {
8068
11108
  t: props.t
8069
11109
  })));
8070
11110
  }
11111
+ function useRightbarWiring(props) {
11112
+ const units = props.units;
11113
+ const subscribeUnits = useCallback((listener) => units.subscribe(listener), [units]);
11114
+ const unitsRevision = useCallback(() => units.version(), [units]);
11115
+ useSyncExternalStore(subscribeUnits, unitsRevision);
11116
+ const modules = units.board;
11117
+ const manifests = units.manifests();
11118
+ const titleKeyOf = (kind) => modules.stepOwner(kind)?.steps?.[kind]?.titleKey;
11119
+ const state = props.useRightbar((snapshot) => snapshot);
11120
+ const sessions = props.useSessions((snapshot) => snapshot);
11121
+ const workspaces = props.useWorkspaces((snapshot) => snapshot);
11122
+ const [panelToken, setPanelToken] = useState(0);
11123
+ const refreshPanel = useCallback(() => setPanelToken((value) => value + 1), []);
11124
+ const { capabilities } = useCapabilityMap(panelToken);
11125
+ return {
11126
+ units,
11127
+ subscribeUnits,
11128
+ unitsRevision,
11129
+ modules,
11130
+ manifests,
11131
+ titleKeyOf,
11132
+ state,
11133
+ sessions,
11134
+ workspaces,
11135
+ panelToken,
11136
+ refreshPanel,
11137
+ capabilities,
11138
+ board: useBoardWorkspace(workspaces, sessions)
11139
+ };
11140
+ }
8071
11141
  //#endregion
8072
11142
  //#region src/shared/api/context-chips.ts
8073
11143
  var context_chips_exports = /* @__PURE__ */ __exportAll({
@@ -8177,9 +11247,15 @@ function installWorkbenchStyles(css, doc = document) {
8177
11247
  //#endregion
8178
11248
  //#region src/app/layouts/sidebar/session-pick.ts
8179
11249
  function openPickedProject(input) {
8180
- const first = firstSessionIdOf(input.items.find((item) => item.workspaceId === input.workspaceId) ?? null, input.sessions, input.archivedIds);
8181
- if (first === null) input.startSession(input.workspaceId);
8182
- else input.openSession(first);
11250
+ const target = input.items.find((item) => item.workspaceId === input.workspaceId) ?? null;
11251
+ const picked = attentionSessionIdOf({
11252
+ workspace: target,
11253
+ sessions: input.sessions,
11254
+ statusById: input.statusById,
11255
+ archivedIds: input.archivedIds
11256
+ }) ?? firstSessionIdOf(target, input.sessions, input.archivedIds);
11257
+ if (picked === null) input.startSession(input.workspaceId);
11258
+ else input.openSession(picked);
8183
11259
  }
8184
11260
  function firstSessionIdOf(workspace, sessions, archivedIds) {
8185
11261
  if (workspace === null) return null;
@@ -8206,25 +11282,6 @@ function openNewSession(input) {
8206
11282
  if (blank === null) input.startSession(input.workspace.workspaceId);
8207
11283
  else input.openSession(blank);
8208
11284
  }
8209
- var WorkspaceAttentionDot_module_default = {
8210
- dot: "_dot_moid1_1",
8211
- overlay: "_overlay_moid1_8"
8212
- };
8213
- //#endregion
8214
- //#region src/app/layouts/sidebar/WorkspaceAttentionDot.tsx
8215
- function WorkspaceAttentionDot({ attention, t, variant = "inline", tip = false }) {
8216
- if (attention === null) return null;
8217
- const label = attentionLabel(attention, t);
8218
- const dot = /* @__PURE__ */ h("span", {
8219
- className: variant === "overlay" ? cx(WorkspaceAttentionDot_module_default.dot, WorkspaceAttentionDot_module_default.overlay) : WorkspaceAttentionDot_module_default.dot,
8220
- role: "img",
8221
- "aria-label": label
8222
- }, /* @__PURE__ */ h(StateDot, {
8223
- state: attention.severity,
8224
- size: variant === "overlay" ? 10 : void 0
8225
- }));
8226
- return tip ? /* @__PURE__ */ h(Tip, { label }, dot) : dot;
8227
- }
8228
11285
  //#endregion
8229
11286
  //#region src/app/layouts/sidebar/SidebarHeader.tsx
8230
11287
  function SidebarHeader(props) {
@@ -8241,12 +11298,7 @@ function SidebarHeader(props) {
8241
11298
  }, !wide ? /* @__PURE__ */ h("span", {
8242
11299
  className: "wb-railMark",
8243
11300
  "aria-hidden": "true"
8244
- }, renderSlot("sidebar.brand.mark", { size: 24 }, { fallback: /* @__PURE__ */ h(IconBrandMark, { size: 24 }) })) : null, /* @__PURE__ */ h("span", { className: "wb-panelIcon" }, /* @__PURE__ */ h(IconPanelLeftOutlineRegular, { size: wide ? 16 : 18 })), !wide ? renderSlot("sidebar.toggle.badge", { attention }, { fallback: /* @__PURE__ */ h(WorkspaceAttentionDot, {
8245
- attention,
8246
- t,
8247
- variant: "overlay",
8248
- tip: true
8249
- }) }) : null));
11301
+ }, renderSlot("sidebar.brand.mark", { size: 24 }, { fallback: /* @__PURE__ */ h(IconBrandMark, { size: 24 }) })) : null, /* @__PURE__ */ h("span", { className: "wb-panelIcon" }, /* @__PURE__ */ h(IconPanelLeftOutlineRegular, { size: wide ? 16 : 18 })), !wide ? renderSlot("sidebar.toggle.badge", { attention }) : null));
8250
11302
  }
8251
11303
  //#endregion
8252
11304
  //#region src/app/layouts/sidebar/WorkspaceSection.tsx
@@ -8321,17 +11373,38 @@ function PanelRow({ id, label, active, wide, onSelect, fallbackGlyph, renderEntr
8321
11373
  }, t(hint.labelKey))));
8322
11374
  }
8323
11375
  var ProjectSwitcher_module_default = {
8324
- root: "_root_1ubj2_1",
8325
- glyph: "_glyph_1ubj2_7",
8326
- glyphActive: "_glyphActive_1ubj2_17",
8327
- triggerName: "_triggerName_1ubj2_21",
8328
- dir: "_dir_1ubj2_32",
8329
- name: "_name_1ubj2_40",
8330
- row: "_row_1ubj2_53",
8331
- trailing: "_trailing_1ubj2_61",
8332
- rowAction: "_rowAction_1ubj2_71",
8333
- current: "_current_1ubj2_84"
11376
+ root: "_root_1cmz0_1",
11377
+ rail: "_rail_1cmz0_7",
11378
+ glyphBox: "_glyphBox_1cmz0_11",
11379
+ glyph: "_glyph_1cmz0_11",
11380
+ glyphActive: "_glyphActive_1cmz0_30",
11381
+ triggerName: "_triggerName_1cmz0_34",
11382
+ dir: "_dir_1cmz0_45",
11383
+ name: "_name_1cmz0_53",
11384
+ row: "_row_1cmz0_66",
11385
+ trailing: "_trailing_1cmz0_74",
11386
+ rowAction: "_rowAction_1cmz0_84",
11387
+ current: "_current_1cmz0_97"
8334
11388
  };
11389
+ var WorkspaceAttentionDot_module_default = {
11390
+ dot: "_dot_sosf1_1",
11391
+ overlay: "_overlay_sosf1_8"
11392
+ };
11393
+ //#endregion
11394
+ //#region src/app/layouts/sidebar/WorkspaceAttentionDot.tsx
11395
+ function WorkspaceAttentionDot({ attention, t, variant = "inline", tip = false }) {
11396
+ if (attention === null) return null;
11397
+ const label = attentionLabel(attention, t);
11398
+ const dot = /* @__PURE__ */ h("span", {
11399
+ className: variant === "overlay" ? cx(WorkspaceAttentionDot_module_default.dot, WorkspaceAttentionDot_module_default.overlay) : WorkspaceAttentionDot_module_default.dot,
11400
+ role: "img",
11401
+ "aria-label": label
11402
+ }, /* @__PURE__ */ h(StateDot, {
11403
+ state: attention.severity,
11404
+ size: variant === "overlay" ? 9 : void 0
11405
+ }));
11406
+ return tip ? /* @__PURE__ */ h(Tip, { label }, dot) : dot;
11407
+ }
8335
11408
  var WorkspaceAttentionTag_module_default = { tag: "_tag_g9dg8_1" };
8336
11409
  //#endregion
8337
11410
  //#region src/app/layouts/sidebar/WorkspaceAttentionTag.tsx
@@ -8541,7 +11614,7 @@ function workspaceOptions(options) {
8541
11614
  }
8542
11615
  //#endregion
8543
11616
  //#region src/app/layouts/sidebar/ProjectSwitcher.tsx
8544
- function ProjectSwitcher({ items, current, attention, onPick, onAdd, onRename, t }) {
11617
+ function ProjectSwitcher({ items, current, attention, compact = false, onPick, onAdd, onRename, t }) {
8545
11618
  const [open, setOpen] = useState(false);
8546
11619
  const [hoverId, setHoverId] = useState(null);
8547
11620
  const [naming, setNaming] = useState(null);
@@ -8570,6 +11643,7 @@ function ProjectSwitcher({ items, current, attention, onPick, onAdd, onRename, t
8570
11643
  t,
8571
11644
  attention.byWorkspace
8572
11645
  ]);
11646
+ const revealId = useMemo(() => options.find((option) => attention.byWorkspace.has(option.value))?.value, [options, attention.byWorkspace]);
8573
11647
  const valueNodes = useMemo(() => {
8574
11648
  const out = /* @__PURE__ */ new Map();
8575
11649
  for (const workspace of items) {
@@ -8578,21 +11652,31 @@ function ProjectSwitcher({ items, current, attention, onPick, onAdd, onRename, t
8578
11652
  }
8579
11653
  return out;
8580
11654
  }, [items]);
8581
- return /* @__PURE__ */ h("div", { className: ProjectSwitcher_module_default.root }, /* @__PURE__ */ h(SelectField, {
11655
+ return /* @__PURE__ */ h("div", { className: cx(ProjectSwitcher_module_default.root, compact && ProjectSwitcher_module_default.rail) }, /* @__PURE__ */ h(SelectField, {
8582
11656
  value: currentId,
8583
11657
  options,
8584
11658
  onChange: onPick,
8585
11659
  open,
8586
11660
  onOpenChange: setOpen,
8587
- icon: /* @__PURE__ */ h("span", { className: cx(ProjectSwitcher_module_default.glyph, ProjectSwitcher_module_default.glyphActive) }, /* @__PURE__ */ h(IconFolderCloseRegular, { size: 16 })),
8588
- renderValue: (option) => /* @__PURE__ */ h(Fragment, null, option === void 0 ? t("project.none") : valueNodes.get(option.value) ?? option.label, /* @__PURE__ */ h(WorkspaceAttentionTag, {
11661
+ icon: /* @__PURE__ */ h(Tip, {
11662
+ label: current?.path ?? "",
11663
+ disabled: current === null
11664
+ }, /* @__PURE__ */ h("span", { className: ProjectSwitcher_module_default.glyphBox }, /* @__PURE__ */ h("span", { className: cx(ProjectSwitcher_module_default.glyph, ProjectSwitcher_module_default.glyphActive) }, /* @__PURE__ */ h(IconFolderCloseRegular, { size: 16 }), compact ? /* @__PURE__ */ h(WorkspaceAttentionDot, {
11665
+ attention: attention.overall,
11666
+ t,
11667
+ variant: "overlay",
11668
+ tip: true
11669
+ }) : null))),
11670
+ renderValue: compact ? void 0 : (option) => /* @__PURE__ */ h(Fragment, null, option === void 0 ? t("project.none") : valueNodes.get(option.value) ?? option.label, /* @__PURE__ */ h(WorkspaceAttentionTag, {
8589
11671
  attention: attention.elsewhere,
8590
11672
  t
8591
11673
  })),
8592
11674
  placeholder: t("project.none"),
8593
11675
  variant: "ghost",
11676
+ iconOnly: compact,
11677
+ search: !compact,
11678
+ revealId,
8594
11679
  ariaLabel: t("project.label"),
8595
- title: current?.path ?? void 0,
8596
11680
  searchLabel: t("project.search.label"),
8597
11681
  searchPlaceholder: t("project.search.placeholder"),
8598
11682
  emptyText: (query) => t("project.search.empty", { query: query.trim() }),
@@ -8837,6 +11921,11 @@ function Sidebar(props) {
8837
11921
  const activePanelId = usePanelInfo((state) => state.activePanelId);
8838
11922
  const sessions = props.useSessions((state) => state);
8839
11923
  const statusById = props.useSessionStatus((state) => state);
11924
+ const board = useBoardWorkspace({
11925
+ items,
11926
+ archivedSessionIds: archived,
11927
+ pinnedSessionIds: pinnedIds
11928
+ }, sessions);
8840
11929
  const [storedId, setStoredId] = useState(() => selectedProjectId());
8841
11930
  const [panelEntries, setPanelEntries] = useState(() => props.listPanels());
8842
11931
  const [creating, setCreating] = useState(false);
@@ -8859,6 +11948,7 @@ function Sidebar(props) {
8859
11948
  workspaceId,
8860
11949
  items,
8861
11950
  sessions,
11951
+ statusById,
8862
11952
  archivedIds: archivedSet,
8863
11953
  openSession,
8864
11954
  startSession
@@ -8874,7 +11964,10 @@ function Sidebar(props) {
8874
11964
  });
8875
11965
  };
8876
11966
  const wide = !collapsed;
8877
- return /* @__PURE__ */ h("div", { className: cx("wb-root", collapsed && "wb-collapsed") }, /* @__PURE__ */ h(SidebarHeader, {
11967
+ return /* @__PURE__ */ h("div", {
11968
+ className: cx("wb-root", collapsed && "wb-collapsed"),
11969
+ "data-wb-where": board.path ?? void 0
11970
+ }, /* @__PURE__ */ h(SidebarHeader, {
8878
11971
  collapsed,
8879
11972
  wide,
8880
11973
  attention: attention.overall,
@@ -8908,7 +12001,16 @@ function Sidebar(props) {
8908
12001
  }), creating ? /* @__PURE__ */ h("p", {
8909
12002
  className: "wb-workspaceBusy",
8910
12003
  role: "status"
8911
- }, /* @__PURE__ */ h(Spinner, { size: 12 }), t("project.add.busy")) : null, createFailed ? /* @__PURE__ */ h("p", { className: "wb-workspaceError" }, t("project.add.failed")) : null) : null, /* @__PURE__ */ h(WorkspaceSection, {
12004
+ }, /* @__PURE__ */ h(Spinner, { size: 12 }), t("project.add.busy")) : null, createFailed ? /* @__PURE__ */ h("p", { className: "wb-workspaceError" }, t("project.add.failed")) : null) : /* @__PURE__ */ h(ProjectSwitcher, {
12005
+ items,
12006
+ current,
12007
+ attention,
12008
+ compact: true,
12009
+ onPick: pickProject,
12010
+ onAdd: addProject,
12011
+ onRename: props.renameWorkspace,
12012
+ t
12013
+ }), /* @__PURE__ */ h(WorkspaceSection, {
8912
12014
  t,
8913
12015
  wide,
8914
12016
  onNewSession: () => {
@@ -9207,7 +12309,7 @@ function messagesOf(units) {
9207
12309
  ...face.messages === void 0 ? {} : { messages: face.messages }
9208
12310
  }));
9209
12311
  }
9210
- var COMPONENT_CSS_MARKER = "\n.wb-activityBlock {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-6);\n padding-top: var(--wb-len-10);\n border-top: 0.5px solid var(--dsw-alias-border-l2);\n}\n\n.wb-activityBlock:first-child {\n padding-top: 0;\n border-top: none;\n}\n\n.wb-activityBlockHead {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--wb-len-8);\n}\n\n.wb-activityLine {\n display: flex;\n align-items: center;\n gap: var(--wb-len-6);\n margin: 0;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-secondary);\n}\n\n.wb-activityLineText {\n flex: none;\n min-width: 0;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n overflow-wrap: anywhere;\n white-space: pre-wrap;\n max-height: var(--wb-len-72);\n overflow-y: auto;\n}\n\n.wb-activityLineAt {\n flex: none;\n margin-left: auto;\n font-size: var(--wb-font-10);\n line-height: var(--wb-line-16);\n font-variant-numeric: tabular-nums;\n color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-activityLine > .wb-activityLineAt,\n.wb-activityLine > .wb-activityLineActions {\n margin-left: auto;\n}\n\n.wb-activityLine > .wb-activityLineAt + .wb-activityLineActions {\n margin-left: 0;\n}\n\n.wb-activityLineActions {\n flex: none;\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-6);\n}\n\n.wb-activityActionFailed {\n color: var(--dsw-alias-state-error-primary);\n}\n\n.wb-note {\n margin: 0;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-tertiary);\n}\n.wb-problem {\n margin: 0;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-state-error-primary);\n overflow-wrap: anywhere;\n}\n\n.wb-approvalCommand {\n max-width: 100%;\n}\n.wb-approvalPlan {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-6);\n}\n.wb-approvalHint {\n margin: 0;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-secondary);\n}\n.wb-approvalRows {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-2);\n margin: 0;\n}\n.wb-approvalRow {\n display: flex;\n align-items: baseline;\n gap: var(--wb-len-8);\n}\n.wb-approvalLabel {\n flex: none;\n width: var(--wb-len-56);\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-tertiary);\n}\n.wb-approvalValue {\n margin: 0;\n font-size: var(--dsw-font-xs-13-font-size);\n line-height: var(--wb-line-18);\n font-weight: 500;\n color: var(--dsw-alias-label-primary);\n overflow-wrap: anywhere;\n}\n.wb-approvalWarn {\n color: var(--dsw-alias-label-secondary);\n}\n\n.wb-cardHead {\n display: flex;\n align-items: center;\n gap: var(--wb-len-6);\n flex: none;\n padding: var(--wb-len-8) var(--wb-len-10) var(--wb-len-8) var(--wb-card-gutter);\n border-bottom: 0.5px solid var(--dsw-alias-border-l2);\n background: var(--dsw-alias-bg-layer-2);\n}\n\n.wb-cardTitle {\n margin: 0;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n font-weight: 600;\n color: var(--dsw-alias-label-secondary);\n}\n\n.wb-cardMeta {\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-label-tertiary);\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.wb-cardMeta::before {\n content: '\\00b7';\n margin-right: var(--wb-len-6);\n color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-cardOpen {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n margin-left: auto;\n flex: none;\n width: var(--wb-len-22);\n height: var(--wb-len-22);\n padding: var(--wb-len-4);\n border-radius: var(--wb-radius-6);\n color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-cardOpen ~ .wb-cardRefresh {\n margin-left: 0;\n}\n\n.wb-cardOpen:hover {\n color: var(--dsw-alias-label-primary);\n}\n\n.wb-cardRefresh {\n margin-left: auto;\n flex: none;\n width: var(--wb-len-22);\n height: var(--wb-len-22);\n padding: var(--wb-len-4);\n border-radius: var(--wb-radius-6);\n color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-cardRefresh:hover:not(:disabled) {\n color: var(--dsw-alias-label-primary);\n}\n\n.wb-cardRefresh:disabled {\n cursor: default;\n opacity: 1;\n}\n\n.wb-cardGear {\n flex: none;\n width: var(--wb-len-22);\n height: var(--wb-len-22);\n padding: var(--wb-len-3);\n border-radius: var(--wb-radius-6);\n color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-cardGear:hover:not(:disabled) {\n color: var(--dsw-alias-label-primary);\n}\n\n.wb-card {\n border: 0.5px solid var(--dsw-alias-border-l3);\n border-radius: var(--dsw-radius-xl);\n background: var(--dsw-alias-bg-layer-1);\n overflow: hidden;\n display: flex;\n flex-direction: column;\n flex: none;\n}\n.wb-cardBody {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-12);\n padding: var(--wb-len-12) var(--wb-card-gutter);\n font-size: var(--dsw-font-xxs-12-font-size);\n}\n.wb-cardBleed {\n margin-inline: calc(-1 * var(--wb-card-gutter));\n}\n._anchor_yq4s2_1 {\n display: contents;\n}\n\n.wb-spinner {\n display: inline-flex;\n align-items: center;\n flex: none;\n}\n\n.wb-choiceMenu {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-2);\n background: transparent;\n}\n\n.wb-choiceMenu[data-variant='boxed'] {\n padding: var(--wb-len-4);\n border: 0.5px solid var(--dsw-alias-border-l3);\n border-radius: var(--dsw-radius-md);\n}\n\n.wb-choiceOption {\n position: relative;\n display: flex;\n align-items: center;\n gap: var(--wb-len-6);\n min-height: var(--wb-len-28);\n padding: var(--wb-len-4) var(--wb-len-8);\n border-radius: var(--dsw-radius-md);\n cursor: pointer;\n font-size: var(--dsw-font-xs-13-font-size);\n line-height: var(--wb-line-20);\n color: var(--dsw-alias-label-primary);\n}\n\n.wb-choiceOptionOn {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.wb-checkbox {\n position: absolute;\n width: var(--wb-len-16);\n height: var(--wb-len-16);\n margin: 0;\n opacity: 0;\n pointer-events: none;\n}\n\n.wb-checkboxBox {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n flex: none;\n width: var(--wb-len-16);\n height: var(--wb-len-16);\n border: 1px solid var(--dsw-alias-border-l3);\n border-radius: var(--dsw-radius-xs);\n corner-shape: round;\n color: var(--dsw-alias-label-primary-foreground);\n transition:\n background-color var(--wb-dur-0-12) ease, border-color var(--wb-dur-0-12) ease;\n}\n\n.wb-choiceOption:hover .wb-checkboxBox {\n border-color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-checkbox:checked + .wb-checkboxBox {\n border-color: var(--dsw-alias-brand-primary);\n background: var(--dsw-alias-brand-primary);\n}\n\n.wb-checkbox:disabled + .wb-checkboxBox {\n cursor: default;\n}\n\n.wb-checkbox:focus-visible + .wb-checkboxBox {\n outline: var(--dsw-focus-ring-width, var(--wb-len-2)) solid\n var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));\n outline-offset: 2px;\n}\n\n.wb-choiceOption:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.wb-choiceOption:has(:disabled) {\n cursor: default;\n opacity: 0.5;\n}\n\n.wb-choiceOption:has(:disabled),\n.wb-choiceOption:has(:disabled):hover {\n background: transparent;\n}\n\n.wb-choiceLabel {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n.wb-choiceLabelText {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.wb-choiceLabel:has(.wb-choiceDescription) .wb-choiceLabelText {\n overflow: visible;\n white-space: normal;\n overflow-wrap: anywhere;\n}\n\n.wb-choiceDescription {\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-tertiary);\n overflow-wrap: anywhere;\n}\n\n.wb-choiceLoading {\n display: flex;\n align-items: center;\n gap: var(--wb-len-6);\n min-height: var(--wb-len-28);\n padding: var(--wb-len-4) var(--wb-len-8);\n font-size: var(--dsw-font-xs-13-font-size);\n line-height: var(--wb-line-20);\n color: var(--dsw-alias-label-secondary);\n}\n\n.wb-choiceLoadingText {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.wb-choiceEmpty {\n display: flex;\n align-items: center;\n min-height: var(--wb-len-28);\n padding: var(--wb-len-4) var(--wb-len-8);\n font-size: var(--dsw-font-xs-13-font-size);\n line-height: var(--wb-line-20);\n color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-radio {\n appearance: none;\n -webkit-appearance: none;\n flex: none;\n box-sizing: border-box;\n width: var(--wb-len-12);\n height: var(--wb-len-12);\n margin: 0;\n border: 1px solid var(--dsw-alias-border-l3);\n border-radius: 50%;\n corner-shape: round;\n background-color: transparent;\n cursor: pointer;\n transition:\n background-color var(--wb-dur-0-12) ease, border-color var(--wb-dur-0-12) ease;\n}\n\n.wb-radio:not(:checked):hover {\n border-color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-radio:checked {\n border-color: var(--dsw-alias-brand-primary);\n background-image: radial-gradient(\n circle at center,\n var(--dsw-alias-brand-primary) 0 3px,\n transparent 3px\n );\n}\n\n.wb-radio:disabled {\n cursor: default;\n}\n\n.wb-radio:focus-visible {\n outline: var(--dsw-focus-ring-width, var(--wb-len-2)) solid var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));\n outline-offset: 2px;\n}.wb-field {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-6);\n font-size: var(--dsw-font-xs-13-font-size);\n}\n\n.wb-fieldLabel {\n color: var(--dsw-alias-label-secondary);\n}\n\n.wb-fieldHint {\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-field:has(:disabled) .wb-fieldLabel {\n opacity: 0.4;\n}\n.wb-formActions {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: flex-end;\n gap: var(--wb-len-8);\n}\n\n.wb-formActionDanger {\n color: var(--dsw-alias-state-error-primary);\n border-color: color-mix(in srgb, var(--dsw-alias-state-error-primary) 30%, transparent);\n --dsw-alias-interactive-bg-hover: color-mix(in srgb, var(--dsw-alias-state-error-primary) 8%, transparent);\n}\n.wb-formRows {\n display: grid;\n grid-template-columns: minmax(72px, max-content) minmax(0, 1fr);\n column-gap: var(--wb-len-8);\n row-gap: var(--wb-len-12);\n}\n\n.wb-formRows > :not(.wb-formRow) {\n grid-column: 1 / -1;\n}\n\n.wb-formRow {\n display: grid;\n grid-column: 1 / -1;\n grid-template-columns: minmax(72px, max-content) minmax(0, 1fr);\n align-items: center;\n column-gap: var(--wb-len-8);\n row-gap: var(--wb-len-8);\n}\n\n.wb-formRows > .wb-formRow {\n grid-template-columns: subgrid;\n}\n\n.wb-formRow[data-layout='stacked'] {\n grid-template-columns: minmax(0, 1fr);\n align-items: stretch;\n gap: var(--wb-len-6);\n}\n\n.wb-formLabel {\n min-width: 0;\n font-size: var(--dsw-font-xs-13-font-size);\n color: var(--dsw-alias-label-secondary);\n overflow-wrap: anywhere;\n white-space: nowrap;\n}\n\n.wb-formRow[data-layout='stacked'] .wb-formLabel {\n white-space: normal;\n}\n\n.wb-formControl {\n display: flex;\n align-items: center;\n min-width: 0;\n}\n\n.wb-formHint {\n grid-column: 2;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-formProblem {\n grid-column: 2;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-state-error-primary);\n}\n\n.wb-formRow:has(.wb-formProblem) .wb-formLabel {\n color: var(--dsw-alias-state-error-primary);\n}\n\n.wb-formRow:has(:disabled) .wb-formLabel {\n opacity: 0.4;\n}\n:where(.wb-link) {\n margin-left: var(--wb-len-2);\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-2);\n font: inherit;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-primary);\n text-decoration: none;\n white-space: nowrap;\n vertical-align: baseline;\n}\n\n:where(.wb-link:hover) {\n text-decoration: underline;\n}\n\n:where(.wb-link:focus-visible) {\n outline: var(--dsw-focus-ring-width) solid var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));\n outline-offset: -2px;\n}\n\n.wb-longTask {\n padding-top: var(--wb-len-12);\n border-top: 0.5px solid var(--dsw-alias-border-l2);\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-2);\n}\n\n.wb-longTaskHead {\n display: flex;\n align-items: center;\n gap: var(--wb-len-6);\n margin: 0;\n}\n\n.wb-longTaskLink {\n flex: none;\n}\n\n.wb-longTaskHeadline {\n margin: 0;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n color: var(--dsw-alias-label-secondary);\n}\n\n.wb-longTaskProblem {\n margin: 0;\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-state-error-primary);\n overflow-wrap: anywhere;\n}\n\n.wb-longTaskDump {\n margin: var(--wb-len-2) 0 0;\n font-size: var(--dsw-font-xxxs-11-font-size);\n color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-longTaskDump pre {\n margin: var(--wb-len-4) 0 0;\n max-height: var(--wb-len-220);\n overflow: auto;\n}\n.wb-centered.wb-centeredCompact {\n flex: none;\n min-height: 0;\n gap: var(--wb-len-8);\n padding: var(--wb-len-20) var(--wb-len-16);\n}\n\n.wb-centered.wb-centeredCompact .wb-centeredHero {\n margin-bottom: var(--wb-len-4);\n}\n\n.wb-skeleton {\n display: flex;\n flex-direction: column;\n}\n\n.wb-skeletonRow {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-8);\n padding: var(--wb-len-8);\n border-radius: var(--dsw-radius-md);\n}\n\n.wb-skeletonRow + .wb-skeletonRow::before {\n content: '';\n align-self: stretch;\n height: var(--wb-len-0-5);\n margin: 0 var(--wb-len-8) var(--wb-len-neg-0-5);\n background: var(--dsw-alias-border-l2);\n}\n\n.wb-skeletonBar {\n display: block;\n height: var(--wb-len-13);\n border-radius: var(--dsw-radius-xs);\n background: var(--dsw-alias-bg-skeleton);\n animation: wb-skeleton-pulse var(--wb-dur-1-4) var(--ds-ease-in-out) infinite;\n}\n\n.wb-skeletonBarTitle {\n width: 62%;\n}\n\n.wb-skeletonBarMeta {\n width: 32%;\n height: var(--wb-len-10);\n}\n\n.wb-skeletonRow:nth-child(2n) .wb-skeletonBarTitle {\n width: 74%;\n}\n\n.wb-skeletonRow:nth-child(3n) .wb-skeletonBarTitle {\n width: 52%;\n}\n\n@keyframes wb-skeleton-pulse {\n 50% {\n opacity: 0.45;\n }\n}\n\n.wb-centered {\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n gap: var(--wb-len-14);\n flex: 1;\n min-height: var(--wb-len-240);\n padding: 0 var(--wb-len-24) var(--wb-len-24);\n text-align: center;\n}\n\n.wb-centeredHero {\n display: flex;\n margin-bottom: var(--wb-len-16);\n color: var(--dsw-alias-label-dimmed);\n}\n\n.wb-centeredTitle {\n font-size: var(--dsw-font-s-14-font-size);\n line-height: var(--wb-line-22);\n color: var(--dsw-alias-label-primary);\n}\n\n.wb-centeredHint {\n max-width: var(--wb-len-300);\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-centeredDetail {\n max-width: var(--wb-len-320);\n font-family: var(--ds-font-family-code, monospace);\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-label-dimmed);\n word-break: break-all;\n}\n\n.wb-centeredAction {\n display: flex;\n justify-content: center;\n gap: var(--wb-len-8);\n margin-top: var(--wb-len-2);\n}\n@media (prefers-reduced-motion: reduce) {\n .wb-skeletonBar {\n animation: none;\n }}\n\n.wb-row:has(> [data-wb-dot]) {\n grid-template-columns: 84px minmax(0, 1fr);\n}\n.wb-rows {\n display: flex;\n flex-direction: column;\n}\n.wb-row {\n display: grid;\n grid-template-columns: 56px minmax(0, 1fr);\n align-items: baseline;\n gap: var(--wb-len-8);\n padding: var(--wb-len-4) 0;\n}\n.wb-row + .wb-row {\n border-top: 0.5px solid var(--dsw-alias-border-l2);\n}\n.wb-rowKey {\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-label-tertiary);\n}\n.wb-rowValue {\n min-width: 0;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-primary);\n overflow-wrap: anywhere;\n}\n.wb-textField {\n box-sizing: border-box;\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: var(--dsw-radius-md);\n background: var(--dsw-alias-bg-layer-3);\n font: var(--dsw-font-xs-13);\n color: var(--dsw-alias-label-primary);\n outline: none;\n}\n\n.wb-textField:focus {\n border-color: var(--dsw-alias-state-business-primary);\n box-shadow: inset 0 0 0 0.5px var(--dsw-alias-state-business-primary);\n}\n\n.wb-textField:disabled {\n cursor: not-allowed;\n opacity: 0.4;\n}\n\n.wb-textField[aria-invalid='true'] {\n border-color: var(--dsw-alias-state-error-primary);\n}\n\n.wb-textField[aria-invalid='true']:focus {\n box-shadow: inset 0 0 0 0.5px var(--dsw-alias-state-error-primary);\n}\n\n:where(.wb-textField) {\n min-height: var(--wb-len-28);\n padding: var(--wb-len-4) var(--wb-len-10);\n}\n:where(.wb-selectTrigger) {\n box-sizing: border-box;\n display: flex;\n align-items: center;\n gap: var(--wb-len-8);\n width: 100%;\n min-height: var(--wb-len-28);\n padding: var(--wb-len-4) var(--wb-len-10);\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: var(--dsw-radius-md);\n background: var(--dsw-alias-bg-layer-3);\n font: var(--dsw-font-xs-13);\n color: var(--dsw-alias-label-primary);\n text-align: left;\n cursor: pointer;\n}\n\n.wb-selectTrigger:focus-visible {\n outline: none;\n border-color: var(--dsw-alias-state-business-primary);\n box-shadow: inset 0 0 0 0.5px var(--dsw-alias-state-business-primary);\n}\n\n.wb-selectTrigger[aria-invalid='true'] {\n border-color: var(--dsw-alias-state-error-primary);\n}\n\n.wb-selectTrigger[aria-invalid='true']:focus-visible {\n box-shadow: inset 0 0 0 0.5px var(--dsw-alias-state-error-primary);\n}\n\n.wb-selectTrigger:disabled {\n cursor: not-allowed;\n opacity: 0.4;\n}\n\n.wb-selectLoading:disabled {\n cursor: default;\n opacity: 1;\n}\n\n.wb-selectGhost {\n gap: var(--wb-gap-xs);\n min-height: 0;\n height: var(--wb-len-34);\n padding: 0 var(--wb-len-8);\n border: none;\n background: transparent;\n font-size: var(--wb-font-row);\n}\n\n.wb-selectGhost:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.wb-selectGhost:focus-visible {\n outline: var(--dsw-focus-ring-width) solid\n var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));\n outline-offset: -2px;\n border-color: transparent;\n box-shadow: none;\n}\n\n.wb-selectAnchor {\n display: block;\n width: 100%;\n}\n\n.wb-selectIcon {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--wb-len-16);\n height: var(--wb-len-20);\n color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-selectValue {\n flex: 1;\n min-width: 0;\n display: flex;\n align-items: baseline;\n gap: var(--wb-len-6);\n line-height: var(--wb-line-20);\n overflow: hidden;\n}\n\n.wb-selectPlaceholder {\n color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-selectChevron {\n flex: none;\n display: inline-flex;\n color: var(--dsw-alias-label-caption);\n}\n\n.wb-selectMenu {\n min-width: var(--wb-len-240);\n max-width: var(--wb-len-360);\n max-height: min(var(--wb-len-320), calc(100vh - var(--wb-len-24)));\n}\n\n:where(.wb-selectSearch) {\n box-sizing: border-box;\n display: flex;\n align-items: center;\n gap: var(--wb-len-8);\n width: 100%;\n min-height: var(--wb-len-28);\n padding: var(--wb-len-4) var(--wb-len-10);\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: var(--dsw-radius-md);\n background: var(--dsw-alias-bg-layer-3);\n}\n\n.wb-selectSearch:focus-within {\n border-color: var(--dsw-alias-state-business-primary);\n box-shadow: inset 0 0 0 0.5px var(--dsw-alias-state-business-primary);\n}\n\n.wb-selectSearch.wb-selectGhost {\n gap: var(--wb-gap-xs);\n min-height: 0;\n height: var(--wb-len-34);\n padding: 0 var(--wb-len-8);\n border: 0.5px solid var(--dsw-alias-border-l3);\n background: var(--dsw-alias-bg-layer-2);\n}\n\n.wb-selectSearch.wb-selectGhost:focus-within {\n border-color: var(--dsw-alias-state-business-primary);\n box-shadow: none;\n}\n\n.wb-selectSearchIcon {\n flex: none;\n display: inline-flex;\n color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-textField.wb-selectSearchInput {\n flex: 1;\n min-width: 0;\n min-height: 0;\n padding: 0;\n border: none;\n background: transparent;\n}\n\n.wb-textField.wb-selectSearchInput:focus {\n box-shadow: none;\n}\n\n.wb-selectFallback {\n width: 100%;\n}\n\n.wb-selectHint {\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-tertiary);\n}\n\nsection.wb-settings {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-12);\n padding: var(--wb-len-12) var(--wb-len-16);\n border: 0;\n border-radius: var(--dsw-radius-md);\n background: var(--dsw-alias-settings-card-fill);\n}\n.wb-settingsHead {\n display: flex;\n align-items: center;\n gap: var(--wb-len-8);\n}\n.wb-settings .wb-settingsTitle {\n flex: 1 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: var(--dsw-font-s-strong-14-font-size);\n line-height: var(--wb-line-24);\n font-weight: 500;\n color: var(--dsw-alias-label-primary);\n}\n\n.wb-stack {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-10);\n min-height: 0;\n}\n\n.wb-stateBlock {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-6);\n}\n.wb-stateBlockTitle {\n margin: 0;\n display: flex;\n align-items: center;\n gap: var(--wb-len-6);\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-primary);\n}\n.wb-stateBlockHint {\n margin: 0;\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-label-tertiary);\n}\n.wb-stateBlockActions {\n display: flex;\n align-items: center;\n gap: var(--wb-len-8);\n margin-top: var(--wb-len-2);\n}\n.wb-stateBlockResolving {\n display: flex;\n align-items: center;\n gap: var(--wb-len-8);\n margin: 0;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-secondary);\n}\n._marketList_csyus_1 {\n list-style: none;\n margin: 0;\n padding: var(--wb-len-6);\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-2);\n}\n\n._marketRow_csyus_10 {\n display: grid;\n grid-template-columns: auto minmax(0, 1fr) auto;\n align-items: center;\n column-gap: var(--wb-len-14);\n row-gap: var(--wb-len-4);\n padding: var(--wb-len-8);\n border-radius: var(--dsw-radius-lg);\n}\n\n._marketIcon_csyus_20 {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--wb-len-40);\n height: var(--wb-len-40);\n border: 0.5px solid var(--dsw-alias-border-l3);\n border-radius: var(--dsw-radius-md);\n color: var(--dsw-alias-label-secondary);\n}\n\n._marketMain_csyus_32 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-4);\n min-width: 0;\n}\n\n._marketName_csyus_39 {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font: var(--dsw-font-base-strong-16);\n color: var(--dsw-alias-label-primary);\n}\n\n._marketDesc_csyus_48 {\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-6);\n min-width: 0;\n overflow: hidden;\n white-space: nowrap;\n font: var(--dsw-font-s-14);\n color: var(--dsw-alias-label-secondary);\n}\n\n._marketUsedBy_csyus_59 {\n margin-left: var(--wb-len-8);\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-label-tertiary);\n opacity: 0.75;\n}\n\n._marketUsedBy_csyus_59::before {\n content: '·';\n margin-right: var(--wb-len-6);\n opacity: 0.8;\n}\n\n._marketName_csyus_39 ._marketVersion_csyus_73 {\n margin-left: var(--wb-len-6);\n font-size: var(--dsw-font-xxs-12-font-size);\n font-weight: 400;\n line-height: var(--wb-line-18);\n}\n\n._marketVersion_csyus_73 {\n font-variant-numeric: tabular-nums;\n color: var(--dsw-alias-label-caption);\n}\n\n._marketVersion_csyus_73::before {\n content: '';\n display: inline-block;\n width: var(--wb-len-1);\n height: var(--wb-len-10);\n margin: 0 var(--wb-len-8) 0 var(--wb-len-2);\n vertical-align: -1px;\n background: var(--dsw-alias-border-l2);\n}\n\n._marketLocalTag_csyus_95 {\n margin-left: var(--wb-len-8);\n padding: 0 var(--wb-len-6);\n border: var(--wb-len-1) solid var(--dsw-alias-border-l2);\n border-radius: var(--dsw-radius-sm);\n font-size: var(--dsw-font-xxs-12-font-size);\n font-weight: 400;\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-caption);\n}\n\n._marketEnd_csyus_106 {\n flex: none;\n display: flex;\n align-items: center;\n gap: var(--wb-len-10);\n}\n\n._marketSwitchSeat_csyus_113 {\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-10);\n}\n\n._marketSwitchSeat_csyus_113::before {\n content: '';\n width: 0;\n height: var(--wb-len-14);\n border-left: 0.5px solid var(--dsw-alias-border-l3);\n}\n\n._marketActions_csyus_126 {\n flex: none;\n display: flex;\n gap: var(--wb-len-6);\n}\n\n._marketUpdateAction_csyus_132 {\n color: var(--dsw-alias-state-warn-primary);\n border-color: color-mix(in srgb, var(--dsw-alias-state-warn-primary) 30%, transparent);\n --dsw-alias-interactive-bg-hover: color-mix(in srgb, var(--dsw-alias-state-warn-primary) 8%, transparent);\n}\n\n._marketSelfDivider_csyus_138 {\n height: 0;\n border-top: 0.5px solid var(--dsw-alias-border-l3);\n}\n\n._marketSection_csyus_143 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-8);\n min-width: 0;\n}\n\n._marketSectionHead_csyus_150 {\n display: flex;\n align-items: baseline;\n gap: var(--wb-len-8);\n}\n\n._marketSectionIcon_csyus_156 {\n display: inline-flex;\n align-items: center;\n align-self: center;\n color: var(--dsw-alias-label-caption);\n}\n\n._marketSectionTitle_csyus_163 {\n margin: 0;\n font: var(--dsw-font-base-strong-16);\n color: var(--dsw-alias-label-primary);\n}\n\n._marketSectionCount_csyus_169 {\n font: var(--dsw-font-s-14);\n font-variant-numeric: tabular-nums;\n color: var(--dsw-alias-label-caption);\n}\n\n\n._marketProgress_csyus_176 {\n flex: none;\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-8);\n min-height: var(--wb-len-32);\n font: var(--dsw-font-s-14);\n color: var(--dsw-alias-label-secondary);\n}\n\n._marketNote_csyus_186 {\n grid-column: 2 / -1;\n font: var(--dsw-font-s-14);\n color: var(--dsw-alias-state-warn-primary);\n overflow-wrap: anywhere;\n}\n\n._marketNotePlain_csyus_193 {\n grid-column: 2 / -1;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-caption);\n overflow-wrap: anywhere;\n}\n\n._marketFailure_csyus_201 {\n grid-column: 2 / -1;\n font: var(--dsw-font-s-14);\n color: var(--dsw-alias-state-error-primary);\n overflow-wrap: anywhere;\n}\n\n._marketEmpty_csyus_208 {\n padding: var(--wb-len-18) var(--wb-len-16);\n text-align: center;\n}\n\n._marketPage_csyus_213 {\n box-sizing: border-box;\n height: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--wb-len-32);\n padding: 0 clamp(var(--wb-len-24), 4vw, var(--wb-len-48)) var(--wb-len-48);\n overflow-x: hidden;\n overflow-y: auto;\n color: var(--dsw-alias-label-primary);\n}\n\n._marketPage_csyus_213 > * {\n width: 100%;\n max-width: var(--wb-len-960);\n}\n\n._marketPageHead_csyus_231 {\n box-sizing: border-box;\n display: flex;\n align-items: flex-start;\n gap: var(--wb-len-16);\n padding-top: var(--wb-len-28);\n}\n\n._marketPageTitle_csyus_239 {\n margin: 0;\n font: var(--dsw-font-l-20);\n}\n\n._marketPageIntro_csyus_244 {\n margin: var(--wb-len-4) 0 0;\n font: var(--dsw-font-xs-13);\n color: var(--dsw-alias-label-secondary);\n}\n\n._marketPageTools_csyus_250 {\n flex: none;\n align-self: center;\n margin-left: auto;\n display: flex;\n align-items: center;\n gap: var(--wb-len-16);\n}\n\n._marketIconButton_csyus_259 {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--wb-len-28);\n height: var(--wb-len-28);\n padding: 0;\n border: 0;\n border-radius: var(--dsw-radius-sm);\n background: transparent;\n color: var(--dsw-alias-label-caption);\n cursor: pointer;\n}\n\n._marketIconButton_csyus_259:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-secondary);\n}\n\n._marketIconButton_csyus_259:disabled {\n cursor: default;\n opacity: 0.5;\n}\n\n._marketIconWrap_csyus_284 {\n display: inline-flex;\n}\n\n._marketIconButtonSpinning_csyus_288 svg {\n animation: _wb-spin_csyus_1 var(--wb-dur-0-9) linear infinite;\n}\n\n._marketAddButton_csyus_292 {\n height: var(--wb-len-32);\n padding: 0 var(--wb-len-12);\n font-size: var(--dsw-font-xs-13-font-size);\n line-height: var(--wb-line-20);\n border-radius: var(--dsw-radius-md);\n}\n\n._marketEmpty_csyus_208 {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--wb-len-8);\n padding: var(--wb-len-64) var(--wb-len-16);\n text-align: center;\n}\n\n._marketChecking_csyus_309 {\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-6);\n font: var(--dsw-font-s-14);\n color: var(--dsw-alias-label-secondary);\n}\n\n._marketEmptyTitle_csyus_317 {\n font: var(--dsw-font-base-strong-16);\n color: var(--dsw-alias-label-primary);\n}\n\n@keyframes _wb-spin_csyus_1 {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n}\n._foot_1ud1j_1 {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: var(--wb-len-8);\n padding: var(--wb-len-8) var(--wb-len-14) var(--wb-len-10);\n border-top: 0.5px solid var(--dsw-alias-border-l2);\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-label-tertiary);\n}\n\n._footText_1ud1j_13 {\n flex: 1;\n min-width: 0;\n}\n\n._footTextMd_1ud1j_18 {\n flex: 1;\n min-width: 0;\n font: var(--dsw-font-s-14);\n color: var(--dsw-alias-label-secondary);\n}\n._wide_1lv8f_1 {\n justify-content: center;\n width: 100%;\n height: var(--wb-len-40);\n border-radius: var(--dsw-radius-md);\n}\n\n._dialog_1lv8f_8 {\n width: min(var(--wb-len-560), 100%);\n max-height: min(var(--wb-len-800), 100%);\n}\n\n._content_1lv8f_13 {\n min-height: 0;\n overflow: auto;\n}\n\n._stack_1lv8f_18 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-12);\n min-width: 0;\n}\n\n._body_1lv8f_25 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-12);\n min-width: 0;\n}\n\n._field_1lv8f_32 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-6);\n font-size: var(--dsw-font-xs-13-font-size);\n}\n\n._input_1lv8f_39 {\n width: 100%;\n height: var(--wb-len-40);\n padding: 0 var(--wb-len-14);\n}\n\n._registryField_1lv8f_45 {\n height: var(--wb-len-32);\n margin-left: var(--wb-len-26);\n padding: 0 var(--wb-len-10);\n}\n\n._options_1lv8f_51 {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n gap: var(--wb-len-8) var(--wb-len-12);\n}\n\n._guideToggle_1lv8f_59 {\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-4);\n align-self: flex-start;\n margin-top: var(--wb-len-4);\n padding: 0;\n border: 0;\n background: transparent;\n font: var(--dsw-font-xs-13);\n color: var(--dsw-alias-label-secondary);\n cursor: pointer;\n}\n\n._guideToggle_1lv8f_59:hover {\n color: var(--dsw-alias-label-primary);\n}\n\n._guideToggle_1lv8f_59 svg,\n._registryToggle_1lv8f_78 svg {\n transition: transform var(--wb-dur-0-12) ease;\n}\n\n._guideToggle_1lv8f_59[aria-expanded='true'] svg,\n._registryToggle_1lv8f_78[aria-expanded='true'] svg {\n transform: rotate(180deg);\n}\n\n._registryWrap_1lv8f_87 {\n position: relative;\n flex: none;\n}\n\n._registryToggle_1lv8f_78 {\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-6);\n height: var(--wb-len-26);\n padding: 0 var(--wb-len-8) 0 var(--wb-len-10);\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: var(--dsw-radius-sm);\n background: var(--dsw-alias-bg-layer-2);\n font: inherit;\n font-size: var(--wb-font-12-5);\n color: var(--dsw-alias-label-secondary);\n cursor: pointer;\n}\n\n._registryToggle_1lv8f_78:hover:not(:disabled) {\n color: var(--dsw-alias-label-primary);\n}\n\n._registryToggle_1lv8f_78:disabled {\n cursor: default;\n opacity: 0.6;\n}\n\n._registryToggle_1lv8f_78[aria-expanded='true'] {\n border-color: var(--dsw-alias-border-l3);\n background: var(--dsw-alias-bg-layer-3);\n}\n\n._registryChosen_1lv8f_121 {\n color: var(--dsw-alias-label-primary);\n font-weight: 500;\n}\n\n._registry_1lv8f_45 {\n position: fixed;\n z-index: var(--wb-z-1100);\n box-sizing: border-box;\n width: min(var(--wb-len-440), 100vw - var(--wb-len-24));\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-4);\n margin: 0;\n padding: var(--wb-len-8) var(--wb-len-10) var(--wb-len-12);\n border: 0;\n border-radius: var(--dsw-radius-lg);\n background: var(--dsw-alias-bg-layer-2);\n --dsw-elevation-stroke-color: var(--dsw-alias-border-l3);\n box-shadow: var(--dsw-elevation-prominent);\n}\n\n._registryOption_1lv8f_143 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-4);\n padding: var(--wb-len-8) var(--wb-len-10);\n border: 0.5px solid transparent;\n border-radius: var(--dsw-radius-lg);\n cursor: pointer;\n}\n\nlabel._registryOption_1lv8f_143 {\n flex-direction: row;\n align-items: flex-start;\n gap: var(--wb-len-10);\n}\n\n._registryPick_1lv8f_159 {\n display: flex;\n align-items: flex-start;\n gap: var(--wb-len-10);\n cursor: pointer;\n}\n\n._registryOption_1lv8f_143[data-checked='true'] {\n border-color: color-mix(in srgb, var(--dsw-alias-brand-primary) 40%, transparent);\n background: var(--dsw-alias-bg-layer-2);\n}\n\n._registryOption_1lv8f_143 input[type='radio'] {\n flex: none;\n width: var(--wb-len-16);\n height: var(--wb-len-16);\n margin: var(--wb-len-2) 0 0;\n accent-color: var(--dsw-alias-brand-primary);\n}\n\n._registryTitle_1lv8f_179 {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wb-len-8);\n font: var(--dsw-font-xs-13);\n line-height: var(--wb-line-20);\n color: var(--dsw-alias-label-primary);\n}\n\n._registryHint_1lv8f_189 {\n margin-left: var(--wb-len-26);\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-tertiary);\n overflow-wrap: anywhere;\n}\n\n._inputError_1lv8f_197 {\n margin: var(--wb-len-neg-4) 0 0 var(--wb-len-26);\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-state-error-primary);\n}\n\n._guide_1lv8f_59 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-10);\n padding: var(--wb-len-8) var(--wb-len-14) var(--wb-len-14);\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: var(--dsw-radius-lg);\n background: var(--dsw-alias-bg-layer-1);\n}\n\n._guideList_1lv8f_214 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-2);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n._guideItem_1lv8f_223 {\n display: flex;\n align-items: flex-start;\n gap: var(--wb-len-10);\n padding: var(--wb-len-8) 0;\n}\n\n._guideIndex_1lv8f_230 {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--wb-len-20);\n height: var(--wb-len-20);\n border-radius: var(--wb-radius-pill);\n corner-shape: round;\n background: var(--dsw-alias-bg-module-platform);\n font: var(--dsw-font-xs-13);\n color: var(--dsw-alias-label-secondary);\n}\n\n._guideMain_1lv8f_244 {\n display: flex;\n flex-direction: column;\n flex: 1;\n gap: 0;\n min-width: 0;\n}\n\n._guideTitle_1lv8f_252 {\n font: var(--dsw-font-s-14);\n font-weight: 500;\n color: var(--dsw-alias-label-primary);\n}\n\n._guideHint_1lv8f_258 {\n margin: 0;\n font: var(--dsw-font-xs-13);\n color: var(--dsw-alias-label-caption);\n}\n\n._guideExample_1lv8f_264 {\n font: var(--dsw-font-xs-13);\n color: var(--dsw-alias-label-secondary);\n overflow-wrap: anywhere;\n}\n\n._guideExample_1lv8f_264 code {\n font-family: var(--dsw-font-mono, monospace);\n}\n\n._guideExampleLabel_1lv8f_274 {\n color: var(--dsw-alias-label-caption);\n}\n\n._footer_1lv8f_278 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-20);\n width: 100%;\n}\n\n._hero_1lv8f_285 {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--wb-len-10);\n padding: var(--wb-len-8) 0 var(--wb-len-4);\n text-align: center;\n}\n\n._heroIcon_1lv8f_294 {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--wb-len-44);\n height: var(--wb-len-44);\n color: var(--dsw-alias-label-secondary);\n}\n\n._heroIcon_1lv8f_294[data-state='done'] {\n color: var(--dsw-alias-state-success-secondary);\n}\n\n._heroIcon_1lv8f_294[data-state='error'] {\n color: var(--dsw-alias-state-warn-label);\n}\n\n._pendingTitle_1lv8f_311 {\n margin: 0;\n font-size: var(--dsw-font-s-14-font-size);\n line-height: var(--wb-line-22);\n font-weight: 500;\n color: var(--dsw-alias-label-secondary);\n}\n\n._wizardTitle_1lv8f_319 {\n margin: 0;\n font-size: var(--wb-font-18);\n line-height: var(--wb-len-26);\n font-weight: 600;\n}\n\n._subject_1lv8f_326 {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--wb-len-6);\n padding: var(--wb-len-16);\n border: 0.5px solid var(--dsw-alias-border-l3);\n border-radius: var(--dsw-radius-lg);\n text-align: center;\n}\n\n._subjectName_1lv8f_337 {\n margin: 0;\n font: var(--dsw-font-base-strong-16);\n overflow-wrap: anywhere;\n}\n\n._subjectMeta_1lv8f_343,\n._subjectDesc_1lv8f_344 {\n margin: 0;\n font: var(--dsw-font-xs-13);\n color: var(--dsw-alias-label-secondary);\n overflow-wrap: anywhere;\n}\n\n._result_1lv8f_351,\n._resultWarn_1lv8f_352 {\n margin: 0;\n padding: var(--wb-len-8) var(--wb-len-12);\n border-radius: var(--dsw-radius-md);\n background: color-mix(in srgb, var(--dsw-alias-state-success-primary) 10%, transparent);\n font: var(--dsw-font-s-14);\n color: var(--dsw-alias-label-primary);\n}\n\n._resultWarn_1lv8f_352 {\n background: color-mix(in srgb, var(--dsw-alias-state-warn-primary) 12%, transparent);\n}\n\n._resultMeta_1lv8f_365 {\n margin: 0;\n padding: 0 var(--wb-len-12);\n font: var(--dsw-font-xs-13);\n color: var(--dsw-alias-label-secondary);\n overflow-wrap: anywhere;\n}\n\n._approval_1lv8f_373 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-8);\n padding: var(--wb-len-12) var(--wb-len-14);\n border: 0.5px solid var(--dsw-alias-state-warn-primary);\n border-radius: var(--dsw-radius-lg);\n background: color-mix(in srgb, var(--dsw-alias-state-warn-primary) 8%, transparent);\n}\n\n._approvalTitle_1lv8f_383 {\n margin: 0;\n font: var(--dsw-font-s-14);\n font-weight: 600;\n color: var(--dsw-alias-label-primary);\n}\n\n._approvalText_1lv8f_390 {\n margin: 0;\n font: var(--dsw-font-xs-13);\n color: var(--dsw-alias-label-secondary);\n}\n\n._approvalCaution_1lv8f_396 {\n margin: 0;\n font: var(--dsw-font-xs-13);\n font-weight: 600;\n color: var(--dsw-alias-state-warn-primary);\n}\n\n._note_1lv8f_403 {\n margin: 0;\n font: var(--dsw-font-s-14);\n color: var(--dsw-alias-label-secondary);\n overflow-wrap: anywhere;\n}\n\n._noteWarn_1lv8f_410 {\n color: var(--dsw-alias-state-warn-primary);\n}\n\n._noteError_1lv8f_414 {\n color: var(--dsw-alias-state-error-primary);\n}\n\n._problem_1lv8f_418 {\n margin: 0;\n font: var(--dsw-font-xs-13);\n color: var(--dsw-alias-state-error-primary);\n overflow-wrap: anywhere;\n}\n\n._detailLabel_1lv8f_425 {\n margin: 0;\n font: var(--dsw-font-xs-13);\n color: var(--dsw-alias-label-caption);\n}\n\n._detail_1lv8f_425 {\n margin: 0;\n padding: var(--wb-len-8) var(--wb-len-10);\n border: 0.5px solid var(--dsw-alias-border-l1);\n border-radius: var(--dsw-radius-sm);\n background: var(--dsw-alias-bg-layer-3);\n font-family: var(--dsw-font-mono, monospace);\n font-size: var(--dsw-font-xs-13-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-secondary);\n overflow-wrap: anywhere;\n white-space: pre-wrap;\n}\n._note_1enlz_1 {\n display: flex;\n align-items: flex-start;\n gap: var(--wb-len-8);\n margin: 0;\n padding: var(--wb-len-10) var(--wb-len-12);\n border-radius: var(--dsw-radius-md);\n background: var(--dsw-alias-state-warn-tertiary);\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-secondary);\n}\n\n._note_1enlz_1 > svg {\n flex: none;\n margin-top: var(--wb-len-2);\n color: var(--dsw-alias-state-warn-primary);\n}\n._body_lw2ph_1 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-12);\n}\n\n._lead_lw2ph_7 {\n margin: 0;\n font-size: var(--dsw-font-xs-13-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-secondary);\n}\n\n._sources_lw2ph_14 {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wb-len-8);\n}\n\n._sourcesLabel_lw2ph_21 {\n font-size: var(--dsw-font-xxs-12-font-size);\n color: var(--dsw-alias-label-secondary);\n}\n\nbutton._sourceOn_lw2ph_26 {\n border-color: var(--dsw-alias-brand-primary);\n}\n._sourceCount_lw2ph_29 {\n margin-left: var(--wb-len-4);\n font-variant-numeric: tabular-nums;\n font-size: var(--dsw-font-xxs-12-font-size);\n color: var(--dsw-alias-label-tertiary);\n}\n\n._reading_lw2ph_36 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-4);\n}\n\n._status_lw2ph_42 {\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-6);\n margin: 0;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-tertiary);\n}\n\n._failure_lw2ph_52 {\n display: grid;\n grid-template-columns: minmax(0, 1fr) auto;\n column-gap: var(--wb-len-10);\n row-gap: var(--wb-len-2);\n color: var(--dsw-alias-state-error-primary);\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n}\n\n._failureTitle_lw2ph_62 {\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-6);\n min-width: 0;\n}\n\n._failureHint_lw2ph_69 {\n grid-column: 1;\n color: var(--dsw-alias-label-tertiary);\n}\n\n._failureAction_lw2ph_74 {\n grid-column: 2;\n grid-row: 1;\n justify-self: end;\n}\n\n._rows_lw2ph_80 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-8);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n._row_lw2ph_80 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-6);\n padding: var(--wb-len-12) var(--wb-len-14);\n border: 0.5px solid var(--dsw-alias-settings-card-stroke);\n border-radius: var(--dsw-radius-xl);\n background: var(--dsw-alias-settings-card-fill);\n}\n\n._head_lw2ph_99 {\n display: flex;\n align-items: center;\n gap: var(--wb-len-8);\n min-width: 0;\n}\n\n._pick_lw2ph_106 {\n flex: 0 1 auto;\n min-width: 0;\n font-size: var(--dsw-font-xs-13-font-size);\n}\n\n._pick_lw2ph_106 > span {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n._code_lw2ph_118 {\n --dsl-code-block-background: var(--dsw-alias-bg-layer-1);\n margin: 0;\n}\n\n._missing_lw2ph_123,\n._conflict_lw2ph_124 {\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-state-warn-primary);\n}\n\n._foot_lw2ph_130 {\n display: flex;\n justify-content: flex-end;\n}\n._actions_jlw8j_1[hidden],\n._progress_jlw8j_2[hidden],\n._commandRow_jlw8j_3[hidden],\n._bridge_jlw8j_4[hidden],\n._raw_jlw8j_5[hidden] {\n display: none;\n}\n\n._gate_jlw8j_9 {\n position: fixed;\n inset: 0;\n z-index: var(--wb-z-top);\n display: flex;\n align-items: center;\n justify-content: center;\n padding: var(--wb-len-24);\n background: var(--dsw-alias-bg-base);\n}\n\n._card_jlw8j_20 {\n width: 100%;\n max-width: var(--wb-len-420);\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--wb-len-16);\n text-align: center;\n}\n\n._card_jlw8j_20:has(._actions_jlw8j_1:not([hidden])),\n._card_jlw8j_20:has(._bridge_jlw8j_4:not([hidden])) {\n max-width: var(--wb-len-520);\n}\n\n._title_jlw8j_35 {\n margin: 0;\n font-size: var(--dsw-font-base-16-font-size);\n line-height: var(--wb-line-24);\n font-weight: 600;\n color: var(--dsw-alias-label-primary);\n}\n\n._hint_jlw8j_43 {\n margin: 0;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-tertiary);\n}\n\n._steps_jlw8j_50 {\n list-style: none;\n margin: var(--wb-len-6) 0 0;\n padding: 0;\n width: 100%;\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-2);\n text-align: left;\n}\n\n._step_jlw8j_50 {\n display: flex;\n align-items: center;\n gap: var(--wb-len-8);\n padding: var(--wb-len-6) var(--wb-len-10);\n border-radius: var(--dsw-radius-sm);\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-secondary);\n background: var(--dsw-alias-bg-layer-1);\n}\n\n._step_jlw8j_50[data-status='running'] {\n color: var(--dsw-alias-label-primary);\n}\n\n._mark_jlw8j_77 {\n flex: none;\n display: flex;\n align-items: center;\n justify-content: center;\n width: var(--wb-len-14);\n height: var(--wb-len-14);\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-tertiary);\n font-variant-numeric: tabular-nums;\n}\n\n._step_jlw8j_50[data-status='ok'] ._mark_jlw8j_77 {\n color: var(--dsw-alias-state-success-primary);\n}\n\n._step_jlw8j_50[data-status='warn'] ._mark_jlw8j_77 {\n color: var(--dsw-alias-state-warn-primary);\n}\n\n._step_jlw8j_50[data-status='failed'] ._mark_jlw8j_77 {\n color: var(--dsw-alias-state-error-primary);\n}\n\n._label_jlw8j_102 {\n flex: none;\n}\n\n._detail_jlw8j_106 {\n margin-left: auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: var(--dsw-alias-label-tertiary);\n}\n\n._progress_jlw8j_2 {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: var(--wb-len-8);\n margin-top: var(--wb-len-4);\n max-width: 100%;\n}\n\n._elapsed_jlw8j_124 {\n flex: none;\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-label-tertiary);\n font-variant-numeric: tabular-nums;\n}\n\n._error_jlw8j_132 {\n margin: 0;\n padding: var(--wb-len-8) var(--wb-len-10);\n max-height: var(--wb-len-120);\n overflow: auto;\n border-radius: var(--dsw-radius-sm);\n background: var(--dsw-alias-bg-layer-1);\n font-family: var(--ds-font-family-code, monospace);\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n white-space: pre-wrap;\n word-break: break-all;\n text-align: left;\n color: var(--dsw-alias-label-tertiary);\n}\n\n._commandRow_jlw8j_3 {\n display: flex;\n align-items: center;\n gap: var(--wb-len-4);\n margin: 0 0 var(--wb-len-8);\n padding-right: var(--wb-len-4);\n border-radius: var(--dsw-radius-sm);\n background: var(--dsw-alias-bg-layer-2);\n}\n\n._copy_jlw8j_158 {\n flex: none;\n display: flex;\n align-items: center;\n justify-content: center;\n width: var(--wb-len-24);\n height: var(--wb-len-24);\n padding: 0;\n border: none;\n border-radius: var(--wb-radius-6);\n background: transparent;\n color: var(--dsw-alias-label-tertiary);\n cursor: pointer;\n}\n\n._copy_jlw8j_158:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-primary);\n}\n\n._command_jlw8j_3 {\n flex: 1;\n min-width: 0;\n padding: var(--wb-len-8) var(--wb-len-10);\n border-radius: var(--dsw-radius-sm);\n background: transparent;\n font-family: var(--ds-font-family-code, monospace);\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n overflow-wrap: anywhere;\n color: var(--dsw-alias-label-primary);\n}\n\n._buttons_jlw8j_191 {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: var(--wb-len-12);\n}\n\n._mockSlot_jlw8j_198 {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n justify-content: center;\n background: var(--dsw-alias-bg-base);\n}\n\n._button_jlw8j_191 {\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n height: var(--wb-len-28);\n padding: 0 var(--wb-len-10);\n border: 0.5px solid var(--dsw-alias-border-l3);\n border-radius: var(--dsw-radius-sm);\n background: transparent;\n font: inherit;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-primary);\n cursor: pointer;\n}\n\n._button_jlw8j_191:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n._button_jlw8j_191:disabled {\n cursor: not-allowed;\n opacity: 0.4;\n}\n\n._actions_jlw8j_1,\n._bridge_jlw8j_4 {\n box-sizing: border-box;\n width: 100%;\n display: flex;\n flex-direction: column;\n align-items: stretch;\n gap: var(--wb-len-10);\n margin-top: var(--wb-len-4);\n padding: var(--wb-len-14) var(--wb-len-16);\n border: 0.5px solid var(--dsw-alias-border-l2);\n border-radius: var(--wb-radius-14);\n background: var(--dsw-alias-bg-layer-1);\n text-align: left;\n}\n\n._fixTitle_jlw8j_249 {\n margin: 0;\n font-size: var(--dsw-font-xs-13-font-size);\n line-height: var(--wb-line-20);\n font-weight: 600;\n color: var(--dsw-alias-label-primary);\n}\n\n._actions_jlw8j_1 ._hint_jlw8j_43,\n._bridge_jlw8j_4 ._hint_jlw8j_43 {\n margin: 0;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-19);\n color: var(--dsw-alias-label-secondary);\n}\n\n._actions_jlw8j_1 ._commandRow_jlw8j_3,\n._bridge_jlw8j_4 ._commandRow_jlw8j_3 {\n margin: 0;\n}\n\n._actions_jlw8j_1 ._buttons_jlw8j_191,\n._bridge_jlw8j_4 ._buttons_jlw8j_191 {\n justify-content: flex-start;\n}\n\n._raw_jlw8j_5 {\n margin: 0;\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-label-tertiary);\n}\n\n._rawSummary_jlw8j_282 {\n cursor: pointer;\n color: var(--dsw-alias-label-tertiary);\n}\n\n._actions_jlw8j_1 ._error_jlw8j_132,\n._bridge_jlw8j_4 ._error_jlw8j_132 {\n margin-top: var(--wb-len-6);\n}\n\n._bridgeLines_jlw8j_292 {\n margin: 0;\n padding-left: var(--wb-len-18);\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-8);\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-19);\n color: var(--dsw-alias-label-secondary);\n}\n\n._bridgeLine_jlw8j_292 a {\n display: block;\n margin-top: var(--wb-len-4);\n width: fit-content;\n}\n\n._link_jlw8j_309 {\n color: var(--dsw-alias-label-primary);\n text-decoration: none;\n}\n\n._link_jlw8j_309::after {\n content: '↗';\n margin-left: var(--wb-len-2);\n}\n\n._link_jlw8j_309:hover {\n text-decoration: underline;\n}\n\n._loading_jlw8j_323 {\n flex: none;\n color: var(--dsw-alias-label-tertiary);\n}\n\n._loading_jlw8j_323[hidden] {\n display: none;\n}\n\n._loadingMotion_jlw8j_332 {\n transform-origin: center;\n animation: _wb-spin_jlw8j_1 var(--wb-dur-1-5) linear infinite;\n}\n\n._loadingTrack_jlw8j_337,\n._loadingArc_jlw8j_338 {\n fill: none;\n stroke: currentColor;\n stroke-width: 2;\n stroke-linecap: round;\n}\n\n._loadingTrack_jlw8j_337 {\n opacity: 0.25;\n}\n\n._loadingArc_jlw8j_338 {\n stroke-dasharray: 12 150;\n animation: _wb-dash_jlw8j_1 var(--wb-dur-1-5) ease-in-out infinite;\n}\n\n@keyframes _wb-spin_jlw8j_1 {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n}\n\n@keyframes _wb-dash_jlw8j_1 {\n 0% {\n stroke-dasharray: 12 150;\n stroke-dashoffset: 0;\n }\n 50% {\n stroke-dasharray: 24 150;\n stroke-dashoffset: -6;\n }\n to {\n stroke-dasharray: 12 150;\n stroke-dashoffset: 0;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n ._loadingMotion_jlw8j_332,\n ._loadingArc_jlw8j_338 {\n animation: none;\n }\n}\n._group_1hxis_1 {\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-2);\n}\n\n._button_1hxis_7 {\n flex: none;\n width: var(--wb-len-28);\n height: var(--wb-len-28);\n padding: 0;\n color: var(--dsw-alias-label-secondary);\n}\n\n._button_1hxis_7:hover:not(:disabled) {\n color: var(--dsw-alias-label-primary);\n}\n\n._active_1hxis_19 {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n._icon_1hxis_23 {\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n._icon_1hxis_23 svg {\n display: block;\n width: var(--wb-len-15);\n height: var(--wb-len-15);\n}\n\n._mirror_1hxis_35 {\n transform: scaleX(-1);\n}\n._stripTabs_1dqp4_1 {\n display: flex;\n align-items: center;\n gap: var(--wb-len-4);\n min-width: 0;\n overflow: hidden;\n}\n\n._tab_1dqp4_9 {\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-6);\n flex: none;\n height: var(--wb-len-28);\n padding: 0 var(--wb-len-10);\n border: 0;\n border-radius: var(--dsw-radius-sm);\n background: none;\n font: inherit;\n font-size: var(--dsw-font-xs-13-font-size);\n line-height: var(--wb-line-16);\n max-width: 100%;\n}\n\n._tabActive_1dqp4_25 {\n color: var(--dsw-alias-label-primary);\n}\n\n._tabQuiet_1dqp4_29 {\n color: var(--dsw-alias-label-tertiary);\n cursor: pointer;\n}\n\n._tabQuiet_1dqp4_29:hover {\n color: var(--dsw-alias-label-primary);\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n._tabTitle_1dqp4_39 {\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-6);\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n._sep_1dqp4_49 {\n flex: none;\n color: var(--dsw-alias-label-dimmed);\n}\n._trigger_15ptp_1 {\n display: flex;\n align-items: center;\n}\n\n._pop_15ptp_6 {\n position: absolute;\n top: calc(var(--wb-len-38) + var(--wb-len-8));\n right: var(--wb-len-6);\n z-index: var(--wb-z-30);\n width: min(var(--wb-len-360), calc(100% - var(--wb-len-12)));\n max-width: calc(100vw - var(--wb-len-48));\n border: 0.5px solid var(--dsw-alias-border-l2);\n border-radius: var(--wb-radius-14);\n background: var(--dsw-alias-bg-layer-2);\n box-shadow: var(--dsw-shadow-lv3);\n overflow: hidden;\n}\n\n._head_15ptp_20 {\n display: flex;\n align-items: center;\n gap: var(--wb-len-8);\n padding: var(--wb-len-10) var(--wb-len-12) var(--wb-len-9) var(--wb-len-14);\n border-bottom: 0.5px solid var(--dsw-alias-border-l2);\n}\n\n._title_15ptp_28 {\n flex: 1;\n font-size: var(--dsw-font-xs-13-font-size);\n line-height: var(--wb-line-20);\n font-weight: 600;\n color: var(--dsw-alias-label-primary);\n}\n\n._rowControls_15ptp_36 {\n flex: none;\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-8);\n}\n\n._reset_15ptp_43 {\n flex: none;\n padding: var(--wb-len-3) var(--wb-len-8);\n border: none;\n border-radius: var(--wb-radius-6);\n background: transparent;\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-label-tertiary);\n cursor: pointer;\n}\n\n._reset_15ptp_43:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-primary);\n}\n\n._reset_15ptp_43:disabled {\n cursor: default;\n opacity: 0.5;\n}\n\n._list_15ptp_65 {\n list-style: none;\n margin: 0;\n padding: var(--wb-len-6);\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-2);\n}\n\n._row_15ptp_36 {\n position: relative;\n display: grid;\n grid-template-columns: 12px minmax(0, 1fr) auto;\n align-items: center;\n gap: var(--wb-len-8);\n padding: var(--wb-len-7) var(--wb-len-8);\n border-radius: var(--dsw-radius-sm);\n cursor: default;\n}\n\n._rowDragging_15ptp_85 {\n cursor: grabbing;\n}\n\n._rowBlocked_15ptp_89 {\n cursor: not-allowed;\n}\n\n._listDragging_15ptp_93 ._rowControls_15ptp_36 {\n pointer-events: none;\n}\n\n._row_15ptp_36:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n._rowOff_15ptp_101 {\n opacity: 0.55;\n}\n\n._rowOff_15ptp_101:hover {\n opacity: 1;\n}\n\n._rowOver_15ptp_109::before {\n content: '';\n position: absolute;\n top: var(--wb-len-neg-3);\n left: var(--wb-len-8);\n right: var(--wb-len-8);\n height: var(--wb-len-2);\n background: var(--dsw-alias-brand-primary);\n}\n\n._ghost_15ptp_119 {\n position: fixed;\n z-index: var(--wb-z-40);\n pointer-events: none;\n padding: var(--wb-len-4) var(--wb-len-10);\n border: 0.5px solid var(--dsw-alias-border-l3);\n border-radius: var(--dsw-radius-sm);\n background: var(--dsw-alias-bg-layer-1);\n box-shadow: var(--wb-static-shadow-ghost);\n font-size: var(--dsw-font-xs-13-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-primary);\n white-space: nowrap;\n}\n\n._grip_15ptp_134 {\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n text-align: center;\n color: var(--dsw-alias-label-tertiary);\n user-select: none;\n cursor: grab;\n touch-action: none;\n}\n\n._gripDragging_15ptp_144 {\n cursor: grabbing;\n}\n\n._gripBlocked_15ptp_148 {\n cursor: not-allowed;\n}\n\n._label_15ptp_152 {\n display: flex;\n align-items: center;\n gap: var(--wb-len-6);\n min-width: 0;\n}\n\n._name_15ptp_159 {\n min-width: 0;\n flex: 0 1 auto;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: var(--dsw-font-xs-13-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-primary);\n}\n\n._error_15ptp_170 {\n margin: 0;\n padding: 0 var(--wb-len-14) var(--wb-len-10);\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-state-error-primary);\n}\n\n._dep_15ptp_178 {\n flex: none;\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-label-tertiary);\n white-space: nowrap;\n}\n\n._group_15ptp_186 {\n padding-top: var(--wb-len-6);\n border-top: 0.5px solid var(--dsw-alias-border-l2);\n}\n\n._groupTitle_15ptp_191 {\n margin: 0;\n padding: var(--wb-len-2) var(--wb-len-8) 0 var(--wb-len-14);\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n font-weight: 400;\n color: var(--dsw-alias-label-tertiary);\n}\n._panel_135e7_1 {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n z-index: var(--wb-z-10);\n visibility: hidden;\n}\n\n._panel_135e7_1[data-fullscreen] {\n z-index: var(--wb-z-40);\n}\n\n._panel_135e7_1[data-open] {\n visibility: visible;\n}\n\n._columns_135e7_18 {\n display: grid;\n grid-template-columns: minmax(0, 1fr);\n align-items: start;\n gap: var(--wb-len-12);\n}\n\n._columns_135e7_18[data-two] {\n grid-template-columns: repeat(2, minmax(0, 1fr));\n}\n\n._column_135e7_18 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-12);\n min-width: 0;\n}\n._dot_moid1_1 {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n\n._overlay_moid1_8 {\n position: absolute;\n inset-block-start: var(--wb-len-neg-2);\n inset-inline-end: var(--wb-len-neg-2);\n}\n._root_1ubj2_1 {\n position: relative;\n flex: none;\n margin: 0 var(--wb-len-2) var(--wb-len-4);\n}\n\n._glyph_1ubj2_7 {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--wb-len-16);\n height: var(--wb-len-20);\n color: var(--dsw-alias-label-tertiary);\n}\n\n._glyphActive_1ubj2_17 {\n color: var(--dsw-alias-state-business-primary);\n}\n\n._triggerName_1ubj2_21 {\n flex: 1;\n min-width: 0;\n display: flex;\n align-items: baseline;\n gap: var(--wb-len-6);\n font-size: var(--wb-font-row);\n line-height: var(--wb-line-20);\n overflow: hidden;\n}\n\n._dir_1ubj2_32 {\n flex: 0 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n._name_1ubj2_40 {\n flex: 0 1 auto;\n max-width: 50%;\n font-size: var(--dsw-font-xxs-12-font-size);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n._triggerName_1ubj2_21 ._name_1ubj2_40 {\n color: var(--dsw-alias-label-tertiary);\n}\n\n._row_1ubj2_53 {\n display: flex;\n align-items: center;\n gap: var(--wb-len-6);\n width: 100%;\n min-width: 0;\n}\n\n._trailing_1ubj2_61 {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--wb-len-20);\n height: var(--wb-len-20);\n margin-inline-start: auto;\n}\n\n._trailing_1ubj2_61 ._rowAction_1ubj2_71 {\n width: var(--wb-len-20);\n min-width: var(--wb-len-20);\n height: var(--wb-len-20);\n min-height: var(--wb-len-20);\n padding: 0;\n border-radius: var(--dsw-radius-sm);\n}\n\n._row_1ubj2_53 ._name_1ubj2_40 {\n color: var(--dsw-alias-label-tertiary);\n}\n\n._current_1ubj2_84 {\n flex: none;\n display: inline-flex;\n align-items: center;\n color: var(--dsw-alias-label-primary);\n}\n._tag_g9dg8_1 {\n flex: none;\n margin-inline-start: auto;\n}\n._dialog_1vye5_1 {\n width: min(var(--wb-len-420), 100%);\n}\n\n._stack_1vye5_5 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-8);\n min-width: 0;\n}\n\n._input_1vye5_12 {\n width: 100%;\n height: var(--wb-len-40);\n padding: 0 var(--wb-len-12);\n}\n\n._meta_1vye5_18 {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--wb-len-12);\n min-width: 0;\n}\n._blocker_1oaj0_1 {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--wb-len-6);\n padding: var(--wb-len-20) var(--wb-len-16);\n text-align: center;\n}\n\n._icon_1oaj0_10 {\n display: flex;\n color: var(--dsw-alias-label-tertiary);\n}\n\n._title_1oaj0_15 {\n margin: var(--wb-len-2) 0 0;\n font-size: var(--dsw-font-s-14-font-size);\n line-height: var(--wb-line-22);\n font-weight: 600;\n color: var(--dsw-alias-label-primary);\n}\n\n._hint_1oaj0_23 {\n margin: 0;\n max-width: var(--wb-len-42em);\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-tertiary);\n text-wrap: pretty;\n}\n\n._blocker_1oaj0_1._blockerInline_1oaj0_32 {\n align-items: flex-start;\n gap: var(--wb-len-6);\n padding: var(--wb-len-4) 0 var(--wb-len-2);\n text-align: left;\n}\n\n._blocker_1oaj0_1._blockerInline_1oaj0_32 ._title_1oaj0_15 {\n font-size: var(--dsw-font-xs-13-font-size);\n line-height: var(--wb-line-20);\n}\n\n._blocker_1oaj0_1._blockerInline_1oaj0_32 ._hint_1oaj0_23 {\n max-width: 100%;\n}\n\n._blocker_1oaj0_1._blockerInline_1oaj0_32 ._actions_1oaj0_48 {\n margin-top: var(--wb-len-8);\n}\n\n._blocker_1oaj0_1._blockerInline_1oaj0_32 ._raw_1oaj0_52 {\n margin-top: var(--wb-len-4);\n max-width: 100%;\n}\n\n._actions_1oaj0_48 {\n display: flex;\n align-items: center;\n gap: var(--wb-len-10);\n margin-top: var(--wb-len-6);\n}\n\n._raw_1oaj0_52 {\n margin-top: var(--wb-len-10);\n width: 100%;\n max-width: var(--wb-len-360);\n text-align: left;\n}\n\n._notice_1oaj0_71 {\n display: grid;\n grid-template-columns: minmax(0, 1fr) auto;\n align-items: start;\n column-gap: var(--wb-len-10);\n margin: 0 0 var(--wb-len-10);\n padding: var(--wb-len-10) var(--wb-len-12);\n border: 0.5px solid var(--dsw-alias-border-l2);\n border-left: 2px solid var(--dsw-alias-border-l3);\n border-radius: var(--dsw-radius-sm);\n background: var(--dsw-alias-bg-layer-1);\n}\n\n._notice_1oaj0_71._noticeFlat_1oaj0_84 {\n margin: 0;\n padding: 0;\n border: 0;\n background: transparent;\n}\n\n._noticeText_1oaj0_91 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-3);\n min-width: 0;\n}\n\n._noticeTitle_1oaj0_98 {\n font-size: var(--wb-font-12-5);\n line-height: var(--wb-line-18);\n font-weight: 600;\n color: var(--dsw-alias-label-primary);\n}\n\n._noticeHint_1oaj0_105 {\n font-size: var(--wb-font-11-5);\n line-height: var(--wb-line-17);\n color: var(--dsw-alias-label-tertiary);\n overflow-wrap: anywhere;\n}\n\n._noticeActions_1oaj0_112 {\n display: flex;\n align-items: center;\n gap: var(--wb-len-6);\n margin-top: var(--wb-len-neg-2);\n}\n\n._failure_1oaj0_119 {\n margin: var(--wb-len-8) 0 0;\n font-size: var(--wb-font-11-5);\n line-height: var(--wb-line-17);\n color: var(--dsw-alias-state-error-primary);\n overflow-wrap: anywhere;\n}\n\n._failureDetail_1oaj0_127 {\n display: block;\n margin-top: var(--wb-len-2);\n color: var(--dsw-alias-label-tertiary);\n white-space: pre-wrap;\n}\n\n._inlineAction_1oaj0_134 {\n padding: 0;\n border: none;\n background: transparent;\n cursor: pointer;\n}\n\n._inlineAction_1oaj0_134:disabled {\n opacity: 0.6;\n cursor: default;\n}\n\n._rawText_1oaj0_146 {\n margin: var(--wb-len-6) 0 0;\n max-width: 100%;\n}\n/*$vite$:1*/";
12312
+ var COMPONENT_CSS_MARKER = "\n.wb-activityBlock {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-6);\n padding-top: var(--wb-len-10);\n border-top: 0.5px solid var(--dsw-alias-border-l2);\n}\n\n.wb-activityBlock:first-child {\n padding-top: 0;\n border-top: none;\n}\n\n.wb-activityBlockHead {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--wb-len-8);\n}\n\n.wb-activityLine {\n display: flex;\n align-items: center;\n gap: var(--wb-len-6);\n margin: 0;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-secondary);\n}\n\n.wb-activityLineText {\n flex: none;\n min-width: 0;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n overflow-wrap: anywhere;\n white-space: pre-wrap;\n max-height: var(--wb-len-72);\n overflow-y: auto;\n}\n\n.wb-activityLineAt {\n flex: none;\n margin-left: auto;\n font-size: var(--wb-font-10);\n line-height: var(--wb-line-16);\n font-variant-numeric: tabular-nums;\n color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-activityLine > .wb-activityLineAt,\n.wb-activityLine > .wb-activityLineActions {\n margin-left: auto;\n}\n\n.wb-activityLine > .wb-activityLineAt + .wb-activityLineActions {\n margin-left: 0;\n}\n\n.wb-activityLineActions {\n flex: none;\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-6);\n}\n\n.wb-activityActionFailed {\n color: var(--dsw-alias-state-error-primary);\n}\n\n.wb-note {\n margin: 0;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-tertiary);\n}\n.wb-problem {\n margin: 0;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-state-error-primary);\n overflow-wrap: anywhere;\n}\n\n.wb-approvalCommand {\n max-width: 100%;\n}\n.wb-approvalPlan {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-6);\n}\n.wb-approvalHint {\n margin: 0;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-secondary);\n}\n.wb-approvalRows {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-2);\n margin: 0;\n}\n.wb-approvalRow {\n display: flex;\n align-items: baseline;\n gap: var(--wb-len-8);\n}\n.wb-approvalLabel {\n flex: none;\n width: var(--wb-len-56);\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-tertiary);\n}\n.wb-approvalValue {\n margin: 0;\n font-size: var(--dsw-font-xs-13-font-size);\n line-height: var(--wb-line-18);\n font-weight: 500;\n color: var(--dsw-alias-label-primary);\n overflow-wrap: anywhere;\n}\n.wb-approvalWarn {\n color: var(--dsw-alias-label-secondary);\n}\n\n.wb-cardHead {\n display: flex;\n align-items: center;\n gap: var(--wb-len-6);\n flex: none;\n padding: var(--wb-len-8) var(--wb-len-10) var(--wb-len-8) var(--wb-card-gutter);\n border-bottom: 0.5px solid var(--dsw-alias-border-l2);\n background: var(--dsw-alias-bg-layer-2);\n}\n\n.wb-cardTitle {\n margin: 0;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n font-weight: 600;\n color: var(--dsw-alias-label-secondary);\n}\n\n.wb-cardMeta {\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-label-tertiary);\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.wb-cardMeta::before {\n content: '\\00b7';\n margin-right: var(--wb-len-6);\n color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-cardOpen {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n margin-left: auto;\n flex: none;\n width: var(--wb-len-22);\n height: var(--wb-len-22);\n padding: var(--wb-len-4);\n border-radius: var(--wb-radius-6);\n color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-cardOpen ~ .wb-cardRefresh {\n margin-left: 0;\n}\n\n.wb-cardOpen:hover {\n color: var(--dsw-alias-label-primary);\n}\n\n.wb-cardRefresh {\n margin-left: auto;\n flex: none;\n width: var(--wb-len-22);\n height: var(--wb-len-22);\n padding: var(--wb-len-4);\n border-radius: var(--wb-radius-6);\n color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-cardRefresh:hover:not(:disabled) {\n color: var(--dsw-alias-label-primary);\n}\n\n.wb-cardRefresh:disabled {\n cursor: default;\n opacity: 1;\n}\n\n.wb-cardGear {\n flex: none;\n width: var(--wb-len-22);\n height: var(--wb-len-22);\n padding: var(--wb-len-3);\n border-radius: var(--wb-radius-6);\n color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-cardGear:hover:not(:disabled) {\n color: var(--dsw-alias-label-primary);\n}\n\n.wb-card {\n border: 0.5px solid var(--dsw-alias-border-l3);\n border-radius: var(--dsw-radius-xl);\n background: var(--dsw-alias-bg-layer-1);\n overflow: hidden;\n display: flex;\n flex-direction: column;\n flex: none;\n}\n.wb-cardBody {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-12);\n padding: var(--wb-len-12) var(--wb-card-gutter);\n font-size: var(--dsw-font-xxs-12-font-size);\n}\n.wb-cardBleed {\n margin-inline: calc(-1 * var(--wb-card-gutter));\n}\n._anchor_yq4s2_1 {\n display: contents;\n}\n\n.wb-spinner {\n display: inline-flex;\n align-items: center;\n flex: none;\n}\n\n.wb-choiceMenu {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-2);\n background: transparent;\n}\n\n.wb-choiceMenu[data-variant='boxed'] {\n padding: var(--wb-len-4);\n border: 0.5px solid var(--dsw-alias-border-l3);\n border-radius: var(--dsw-radius-md);\n}\n\n.wb-choiceOption {\n position: relative;\n display: flex;\n align-items: center;\n gap: var(--wb-len-6);\n min-height: var(--wb-len-28);\n padding: var(--wb-len-4) var(--wb-len-8);\n border-radius: var(--dsw-radius-md);\n cursor: pointer;\n font-size: var(--dsw-font-xs-13-font-size);\n line-height: var(--wb-line-20);\n color: var(--dsw-alias-label-primary);\n}\n\n.wb-choiceOptionOn {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.wb-checkbox {\n position: absolute;\n width: var(--wb-len-16);\n height: var(--wb-len-16);\n margin: 0;\n opacity: 0;\n pointer-events: none;\n}\n\n.wb-checkboxBox {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n flex: none;\n width: var(--wb-len-16);\n height: var(--wb-len-16);\n border: 1px solid var(--dsw-alias-border-l3);\n border-radius: var(--dsw-radius-xs);\n corner-shape: round;\n color: var(--dsw-alias-label-primary-foreground);\n transition:\n background-color var(--wb-dur-0-12) ease, border-color var(--wb-dur-0-12) ease;\n}\n\n.wb-choiceOption:hover .wb-checkboxBox {\n border-color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-checkbox:checked + .wb-checkboxBox {\n border-color: var(--dsw-alias-brand-primary);\n background: var(--dsw-alias-brand-primary);\n}\n\n.wb-checkbox:disabled + .wb-checkboxBox {\n cursor: default;\n}\n\n.wb-checkbox:focus-visible + .wb-checkboxBox {\n outline: var(--dsw-focus-ring-width, var(--wb-len-2)) solid\n var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));\n outline-offset: 2px;\n}\n\n.wb-choiceOption:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.wb-choiceOption:has(:disabled) {\n cursor: default;\n opacity: 0.5;\n}\n\n.wb-choiceOption:has(:disabled),\n.wb-choiceOption:has(:disabled):hover {\n background: transparent;\n}\n\n.wb-choiceLabel {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n.wb-choiceLabelText {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.wb-choiceLabel:has(.wb-choiceDescription) .wb-choiceLabelText {\n overflow: visible;\n white-space: normal;\n overflow-wrap: anywhere;\n}\n\n.wb-choiceDescription {\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-tertiary);\n overflow-wrap: anywhere;\n}\n\n.wb-choiceLoading {\n display: flex;\n align-items: center;\n gap: var(--wb-len-6);\n min-height: var(--wb-len-28);\n padding: var(--wb-len-4) var(--wb-len-8);\n font-size: var(--dsw-font-xs-13-font-size);\n line-height: var(--wb-line-20);\n color: var(--dsw-alias-label-secondary);\n}\n\n.wb-choiceLoadingText {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.wb-choiceEmpty {\n display: flex;\n align-items: center;\n min-height: var(--wb-len-28);\n padding: var(--wb-len-4) var(--wb-len-8);\n font-size: var(--dsw-font-xs-13-font-size);\n line-height: var(--wb-line-20);\n color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-radio {\n appearance: none;\n -webkit-appearance: none;\n flex: none;\n box-sizing: border-box;\n width: var(--wb-len-12);\n height: var(--wb-len-12);\n margin: 0;\n border: 1px solid var(--dsw-alias-border-l3);\n border-radius: 50%;\n corner-shape: round;\n background-color: transparent;\n cursor: pointer;\n transition:\n background-color var(--wb-dur-0-12) ease, border-color var(--wb-dur-0-12) ease;\n}\n\n.wb-radio:not(:checked):hover {\n border-color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-radio:checked {\n border-color: var(--dsw-alias-brand-primary);\n background-image: radial-gradient(\n circle at center,\n var(--dsw-alias-brand-primary) 0 3px,\n transparent 3px\n );\n}\n\n.wb-radio:disabled {\n cursor: default;\n}\n\n.wb-radio:focus-visible {\n outline: var(--dsw-focus-ring-width, var(--wb-len-2)) solid var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));\n outline-offset: 2px;\n}.wb-field {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-6);\n font-size: var(--dsw-font-xs-13-font-size);\n}\n\n.wb-fieldLabel {\n color: var(--dsw-alias-label-secondary);\n}\n\n.wb-fieldHint {\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-field:has(:disabled) .wb-fieldLabel {\n opacity: 0.4;\n}\n.wb-formActions {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: flex-end;\n gap: var(--wb-len-8);\n}\n\n.wb-formActionDanger {\n color: var(--dsw-alias-state-error-primary);\n border-color: color-mix(in srgb, var(--dsw-alias-state-error-primary) 30%, transparent);\n --dsw-alias-interactive-bg-hover: color-mix(in srgb, var(--dsw-alias-state-error-primary) 8%, transparent);\n}\n.wb-formRows {\n display: grid;\n grid-template-columns: minmax(72px, max-content) minmax(0, 1fr);\n column-gap: var(--wb-len-8);\n row-gap: var(--wb-len-12);\n}\n\n.wb-formRows > :not(.wb-formRow) {\n grid-column: 1 / -1;\n}\n\n.wb-formRow {\n display: grid;\n grid-column: 1 / -1;\n grid-template-columns: minmax(72px, max-content) minmax(0, 1fr);\n align-items: center;\n column-gap: var(--wb-len-8);\n row-gap: var(--wb-len-8);\n}\n\n.wb-formRow[data-layout='stacked'] {\n grid-template-columns: minmax(0, 1fr);\n align-items: stretch;\n gap: var(--wb-len-6);\n}\n\n.wb-formLabel {\n min-width: 0;\n font-size: var(--dsw-font-xs-13-font-size);\n color: var(--dsw-alias-label-secondary);\n overflow-wrap: anywhere;\n white-space: nowrap;\n}\n\n.wb-formRow[data-layout='stacked'] .wb-formLabel {\n white-space: normal;\n}\n\n.wb-formControl {\n display: flex;\n align-items: center;\n min-width: 0;\n}\n\n.wb-formHint {\n grid-column: 2;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-formProblem {\n grid-column: 2;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-state-error-primary);\n}\n\n.wb-formRow:has(.wb-formProblem) .wb-formLabel {\n color: var(--dsw-alias-state-error-primary);\n}\n\n.wb-formRow:has(:disabled) .wb-formLabel {\n opacity: 0.4;\n}\n\n.wb-formRows > .wb-formRow {\n grid-template-columns: subgrid;\n}\n\n@supports not (grid-template-columns: subgrid) {\n .wb-formRows > .wb-formRow {\n grid-template-columns: minmax(72px, max-content) minmax(0, 1fr);\n }\n}\n:where(.wb-link) {\n margin-left: var(--wb-len-2);\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-2);\n font: inherit;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-primary);\n text-decoration: none;\n white-space: nowrap;\n vertical-align: baseline;\n}\n\n:where(.wb-link:hover) {\n text-decoration: underline;\n}\n\n:where(.wb-link:focus-visible) {\n outline: var(--dsw-focus-ring-width) solid var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));\n outline-offset: -2px;\n}\n\n.wb-longTask {\n padding-top: var(--wb-len-12);\n border-top: 0.5px solid var(--dsw-alias-border-l2);\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-2);\n}\n\n.wb-longTaskHead {\n display: flex;\n align-items: center;\n gap: var(--wb-len-6);\n margin: 0;\n}\n\n.wb-longTaskLink {\n flex: none;\n}\n\n.wb-longTaskHeadline {\n margin: 0;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n color: var(--dsw-alias-label-secondary);\n}\n\n.wb-longTaskProblem {\n margin: 0;\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-state-error-primary);\n overflow-wrap: anywhere;\n}\n\n.wb-longTaskDump {\n margin: var(--wb-len-2) 0 0;\n font-size: var(--dsw-font-xxxs-11-font-size);\n color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-longTaskDump pre {\n margin: var(--wb-len-4) 0 0;\n max-height: var(--wb-len-220);\n overflow: auto;\n}\n.wb-centered.wb-centeredCompact {\n flex: none;\n min-height: 0;\n gap: var(--wb-len-8);\n padding: var(--wb-len-20) var(--wb-len-16);\n}\n\n.wb-centered.wb-centeredCompact .wb-centeredHero {\n margin-bottom: var(--wb-len-4);\n}\n\n.wb-skeleton {\n display: flex;\n flex-direction: column;\n}\n\n.wb-skeletonRow {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-8);\n padding: var(--wb-len-8);\n border-radius: var(--dsw-radius-md);\n}\n\n.wb-skeletonRow + .wb-skeletonRow::before {\n content: '';\n align-self: stretch;\n height: var(--wb-len-0-5);\n margin: 0 var(--wb-len-8) var(--wb-len-neg-0-5);\n background: var(--dsw-alias-border-l2);\n}\n\n.wb-skeletonBar {\n display: block;\n height: var(--wb-len-13);\n border-radius: var(--dsw-radius-xs);\n background: var(--dsw-alias-bg-skeleton);\n animation: wb-skeleton-pulse var(--wb-dur-1-4) var(--ds-ease-in-out) infinite;\n}\n\n.wb-skeletonBarTitle {\n width: 62%;\n}\n\n.wb-skeletonBarMeta {\n width: 32%;\n height: var(--wb-len-10);\n}\n\n.wb-skeletonRow:nth-child(2n) .wb-skeletonBarTitle {\n width: 74%;\n}\n\n.wb-skeletonRow:nth-child(3n) .wb-skeletonBarTitle {\n width: 52%;\n}\n\n@keyframes wb-skeleton-pulse {\n 50% {\n opacity: 0.45;\n }\n}\n\n.wb-centered {\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n gap: var(--wb-len-14);\n flex: 1;\n min-height: var(--wb-len-240);\n padding: 0 var(--wb-len-24) var(--wb-len-24);\n text-align: center;\n}\n\n.wb-centeredHero {\n display: flex;\n margin-bottom: var(--wb-len-16);\n color: var(--dsw-alias-label-dimmed);\n}\n\n.wb-centeredTitle {\n font-size: var(--dsw-font-s-14-font-size);\n line-height: var(--wb-line-22);\n color: var(--dsw-alias-label-primary);\n}\n\n.wb-centeredHint {\n max-width: var(--wb-len-300);\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-centeredDetail {\n max-width: var(--wb-len-320);\n font-family: var(--ds-font-family-code, monospace);\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-label-dimmed);\n word-break: break-all;\n}\n\n.wb-centeredAction {\n display: flex;\n justify-content: center;\n gap: var(--wb-len-8);\n margin-top: var(--wb-len-2);\n}\n@media (prefers-reduced-motion: reduce) {\n .wb-skeletonBar {\n animation: none;\n }}\n.wb-rows {\n display: flex;\n flex-direction: column;\n}\n.wb-row {\n display: grid;\n grid-template-columns: minmax(72px, max-content) minmax(0, 1fr);\n align-items: baseline;\n gap: var(--wb-len-8);\n padding: var(--wb-len-4) 0;\n}\n.wb-row + .wb-row {\n border-top: 0.5px solid var(--dsw-alias-border-l2);\n}\n.wb-rowKey {\n white-space: nowrap;\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-label-tertiary);\n}\n.wb-rowValue {\n min-width: 0;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-primary);\n overflow-wrap: anywhere;\n}\n\n.wb-rows > .wb-row {\n grid-template-columns: subgrid;\n}\n\n@supports not (grid-template-columns: subgrid) {\n .wb-rows > .wb-row {\n grid-template-columns: minmax(72px, max-content) minmax(0, 1fr);\n }\n}\n.wb-textField {\n box-sizing: border-box;\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: var(--dsw-radius-md);\n background: var(--dsw-alias-bg-layer-3);\n font: var(--dsw-font-xs-13);\n color: var(--dsw-alias-label-primary);\n outline: none;\n}\n\n.wb-textField:focus {\n border-color: var(--dsw-alias-state-business-primary);\n box-shadow: inset 0 0 0 0.5px var(--dsw-alias-state-business-primary);\n}\n\n.wb-textField:disabled {\n cursor: not-allowed;\n opacity: 0.4;\n}\n\n.wb-textField[aria-invalid='true'] {\n border-color: var(--dsw-alias-state-error-primary);\n}\n\n.wb-textField[aria-invalid='true']:focus {\n box-shadow: inset 0 0 0 0.5px var(--dsw-alias-state-error-primary);\n}\n\n:where(.wb-textField) {\n min-height: var(--wb-len-28);\n padding: var(--wb-len-4) var(--wb-len-10);\n}\n:where(.wb-selectTrigger) {\n box-sizing: border-box;\n display: flex;\n align-items: center;\n gap: var(--wb-len-8);\n width: 100%;\n min-height: var(--wb-len-28);\n padding: var(--wb-len-4) var(--wb-len-10);\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: var(--dsw-radius-md);\n background: var(--dsw-alias-bg-layer-3);\n font: var(--dsw-font-xs-13);\n color: var(--dsw-alias-label-primary);\n text-align: left;\n cursor: pointer;\n}\n\n.wb-selectTrigger:focus-visible {\n outline: none;\n border-color: var(--dsw-alias-state-business-primary);\n box-shadow: inset 0 0 0 0.5px var(--dsw-alias-state-business-primary);\n}\n\n.wb-selectTrigger[aria-invalid='true'] {\n border-color: var(--dsw-alias-state-error-primary);\n}\n\n.wb-selectTrigger[aria-invalid='true']:focus-visible {\n box-shadow: inset 0 0 0 0.5px var(--dsw-alias-state-error-primary);\n}\n\n.wb-selectTrigger:disabled {\n cursor: not-allowed;\n opacity: 0.4;\n}\n\n.wb-selectLoading:disabled {\n cursor: default;\n opacity: 1;\n}\n\n.wb-selectGhost {\n gap: var(--wb-gap-xs);\n min-height: 0;\n height: var(--wb-len-34);\n padding: 0 var(--wb-len-8);\n border: none;\n background: transparent;\n font-size: var(--wb-font-row);\n}\n\n.wb-selectGhost:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.wb-selectGhost:focus-visible {\n outline: var(--dsw-focus-ring-width) solid\n var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));\n outline-offset: -2px;\n border-color: transparent;\n box-shadow: none;\n}\n\n.wb-selectIconOnly {\n width: var(--wb-len-36);\n height: var(--wb-len-36);\n min-height: 0;\n gap: 0;\n padding: 0;\n justify-content: center;\n}\n\n.wb-selectReveal {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n\n.wb-selectIconOnly .wb-selectIcon {\n width: 100%;\n height: 100%;\n}\n\n.wb-selectAnchor {\n display: block;\n width: 100%;\n}\n\n.wb-selectIcon {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--wb-len-16);\n height: var(--wb-len-20);\n color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-selectValue {\n flex: 1;\n min-width: 0;\n display: flex;\n align-items: baseline;\n gap: var(--wb-len-6);\n line-height: var(--wb-line-20);\n overflow: hidden;\n}\n\n.wb-selectPlaceholder {\n color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-selectChevron {\n flex: none;\n display: inline-flex;\n color: var(--dsw-alias-label-caption);\n}\n\n.wb-selectMenu {\n min-width: var(--wb-len-240);\n max-width: var(--wb-len-360);\n max-height: min(var(--wb-len-320), calc(100vh - var(--wb-len-24)));\n}\n\n:where(.wb-selectSearch) {\n box-sizing: border-box;\n display: flex;\n align-items: center;\n gap: var(--wb-len-8);\n width: 100%;\n min-height: var(--wb-len-28);\n padding: var(--wb-len-4) var(--wb-len-10);\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: var(--dsw-radius-md);\n background: var(--dsw-alias-bg-layer-3);\n}\n\n.wb-selectSearch:focus-within {\n border-color: var(--dsw-alias-state-business-primary);\n box-shadow: inset 0 0 0 0.5px var(--dsw-alias-state-business-primary);\n}\n\n.wb-selectSearch.wb-selectGhost {\n gap: var(--wb-gap-xs);\n min-height: 0;\n height: var(--wb-len-34);\n padding: 0 var(--wb-len-8);\n border: 0.5px solid var(--dsw-alias-border-l3);\n background: var(--dsw-alias-bg-layer-2);\n}\n\n.wb-selectSearch.wb-selectGhost:focus-within {\n border-color: var(--dsw-alias-state-business-primary);\n box-shadow: none;\n}\n\n.wb-selectSearchIcon {\n flex: none;\n display: inline-flex;\n color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-textField.wb-selectSearchInput {\n flex: 1;\n min-width: 0;\n min-height: 0;\n padding: 0;\n border: none;\n background: transparent;\n}\n\n.wb-textField.wb-selectSearchInput:focus {\n box-shadow: none;\n}\n\n.wb-selectFallback {\n width: 100%;\n}\n\n.wb-selectHint {\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-tertiary);\n}\n\nsection.wb-settings {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-12);\n padding: var(--wb-len-12) var(--wb-len-16);\n border: 0;\n border-radius: var(--dsw-radius-md);\n background: var(--dsw-alias-settings-card-fill);\n}\n.wb-settingsHead {\n display: flex;\n align-items: center;\n gap: var(--wb-len-8);\n}\n.wb-settings .wb-settingsTitle {\n flex: 1 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: var(--dsw-font-s-strong-14-font-size);\n line-height: var(--wb-line-24);\n font-weight: 500;\n color: var(--dsw-alias-label-primary);\n}\n\n.wb-stack {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-10);\n min-height: 0;\n}\n\n.wb-stateBlock {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-6);\n}\n.wb-stateBlockTitle {\n margin: 0;\n display: flex;\n align-items: center;\n gap: var(--wb-len-6);\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-primary);\n}\n.wb-stateBlockHint {\n margin: 0;\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-label-tertiary);\n}\n.wb-stateBlockActions {\n display: flex;\n align-items: center;\n gap: var(--wb-len-8);\n margin-top: var(--wb-len-2);\n}\n.wb-stateBlockResolving {\n display: flex;\n align-items: center;\n gap: var(--wb-len-8);\n margin: 0;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-secondary);\n}\n\n.wb-mockStrip {\n display: flex;\n flex-wrap: wrap;\n gap: var(--wb-len-4);\n padding: var(--wb-len-8) var(--wb-len-12);\n border-bottom: 0.5px solid var(--dsw-alias-border-l2);\n flex: none;\n}\n\n.wb-mockNote {\n flex: 1 0 100%;\n font-size: var(--wb-font-10);\n line-height: var(--wb-line-14);\n color: var(--dsw-alias-label-tertiary);\n}\n\n.wb-mockChip {\n flex: none;\n padding: var(--wb-len-2) var(--wb-len-7);\n border: 0.5px solid var(--dsw-alias-border-l2);\n border-radius: var(--wb-radius-pill);\n corner-shape: round;\n background: transparent;\n font-size: var(--wb-font-10);\n line-height: var(--wb-line-14);\n color: var(--dsw-alias-label-secondary);\n cursor: pointer;\n}\n\n.wb-mockChip:hover {\n color: var(--dsw-alias-label-primary);\n}\n\n.wb-mockChipOn {\n border-color: transparent;\n background: var(--dsw-alias-brand-primary);\n color: var(--dsw-alias-label-primary-foreground);\n}\n\n.wb-mockChipOn:hover {\n border-color: transparent;\n background: var(--dsw-alias-brand-primary);\n color: var(--dsw-alias-label-primary-foreground);\n}\n\n.wb-panelBody.wb-panelMany .wb-mockStrip {\n display: none;\n}\n._actions_jlw8j_1[hidden],\n._progress_jlw8j_2[hidden],\n._commandRow_jlw8j_3[hidden],\n._bridge_jlw8j_4[hidden],\n._raw_jlw8j_5[hidden] {\n display: none;\n}\n\n._gate_jlw8j_9 {\n position: fixed;\n inset: 0;\n z-index: var(--wb-z-top);\n display: flex;\n align-items: center;\n justify-content: center;\n padding: var(--wb-len-24);\n background: var(--dsw-alias-bg-base);\n}\n\n._card_jlw8j_20 {\n width: 100%;\n max-width: var(--wb-len-420);\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--wb-len-16);\n text-align: center;\n}\n\n._card_jlw8j_20:has(._actions_jlw8j_1:not([hidden])),\n._card_jlw8j_20:has(._bridge_jlw8j_4:not([hidden])) {\n max-width: var(--wb-len-520);\n}\n\n._title_jlw8j_35 {\n margin: 0;\n font-size: var(--dsw-font-base-16-font-size);\n line-height: var(--wb-line-24);\n font-weight: 600;\n color: var(--dsw-alias-label-primary);\n}\n\n._hint_jlw8j_43 {\n margin: 0;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-tertiary);\n}\n\n._steps_jlw8j_50 {\n list-style: none;\n margin: var(--wb-len-6) 0 0;\n padding: 0;\n width: 100%;\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-2);\n text-align: left;\n}\n\n._step_jlw8j_50 {\n display: flex;\n align-items: center;\n gap: var(--wb-len-8);\n padding: var(--wb-len-6) var(--wb-len-10);\n border-radius: var(--dsw-radius-sm);\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-secondary);\n background: var(--dsw-alias-bg-layer-1);\n}\n\n._step_jlw8j_50[data-status='running'] {\n color: var(--dsw-alias-label-primary);\n}\n\n._mark_jlw8j_77 {\n flex: none;\n display: flex;\n align-items: center;\n justify-content: center;\n width: var(--wb-len-14);\n height: var(--wb-len-14);\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-tertiary);\n font-variant-numeric: tabular-nums;\n}\n\n._step_jlw8j_50[data-status='ok'] ._mark_jlw8j_77 {\n color: var(--dsw-alias-state-success-primary);\n}\n\n._step_jlw8j_50[data-status='warn'] ._mark_jlw8j_77 {\n color: var(--dsw-alias-state-warn-primary);\n}\n\n._step_jlw8j_50[data-status='failed'] ._mark_jlw8j_77 {\n color: var(--dsw-alias-state-error-primary);\n}\n\n._label_jlw8j_102 {\n flex: none;\n}\n\n._detail_jlw8j_106 {\n margin-left: auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: var(--dsw-alias-label-tertiary);\n}\n\n._progress_jlw8j_2 {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: var(--wb-len-8);\n margin-top: var(--wb-len-4);\n max-width: 100%;\n}\n\n._elapsed_jlw8j_124 {\n flex: none;\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-label-tertiary);\n font-variant-numeric: tabular-nums;\n}\n\n._error_jlw8j_132 {\n margin: 0;\n padding: var(--wb-len-8) var(--wb-len-10);\n max-height: var(--wb-len-120);\n overflow: auto;\n border-radius: var(--dsw-radius-sm);\n background: var(--dsw-alias-bg-layer-1);\n font-family: var(--ds-font-family-code, monospace);\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n white-space: pre-wrap;\n word-break: break-all;\n text-align: left;\n color: var(--dsw-alias-label-tertiary);\n}\n\n._commandRow_jlw8j_3 {\n display: flex;\n align-items: center;\n gap: var(--wb-len-4);\n margin: 0 0 var(--wb-len-8);\n padding-right: var(--wb-len-4);\n border-radius: var(--dsw-radius-sm);\n background: var(--dsw-alias-bg-layer-2);\n}\n\n._copy_jlw8j_158 {\n flex: none;\n display: flex;\n align-items: center;\n justify-content: center;\n width: var(--wb-len-24);\n height: var(--wb-len-24);\n padding: 0;\n border: none;\n border-radius: var(--wb-radius-6);\n background: transparent;\n color: var(--dsw-alias-label-tertiary);\n cursor: pointer;\n}\n\n._copy_jlw8j_158:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-primary);\n}\n\n._command_jlw8j_3 {\n flex: 1;\n min-width: 0;\n padding: var(--wb-len-8) var(--wb-len-10);\n border-radius: var(--dsw-radius-sm);\n background: transparent;\n font-family: var(--ds-font-family-code, monospace);\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n overflow-wrap: anywhere;\n color: var(--dsw-alias-label-primary);\n}\n\n._buttons_jlw8j_191 {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: var(--wb-len-12);\n}\n\n._mockSlot_jlw8j_198 {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n justify-content: center;\n background: var(--dsw-alias-bg-base);\n}\n\n._button_jlw8j_191 {\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n height: var(--wb-len-28);\n padding: 0 var(--wb-len-10);\n border: 0.5px solid var(--dsw-alias-border-l3);\n border-radius: var(--dsw-radius-sm);\n background: transparent;\n font: inherit;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-primary);\n cursor: pointer;\n}\n\n._button_jlw8j_191:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n._button_jlw8j_191:disabled {\n cursor: not-allowed;\n opacity: 0.4;\n}\n\n._actions_jlw8j_1,\n._bridge_jlw8j_4 {\n box-sizing: border-box;\n width: 100%;\n display: flex;\n flex-direction: column;\n align-items: stretch;\n gap: var(--wb-len-10);\n margin-top: var(--wb-len-4);\n padding: var(--wb-len-14) var(--wb-len-16);\n border: 0.5px solid var(--dsw-alias-border-l2);\n border-radius: var(--wb-radius-14);\n background: var(--dsw-alias-bg-layer-1);\n text-align: left;\n}\n\n._fixTitle_jlw8j_249 {\n margin: 0;\n font-size: var(--dsw-font-xs-13-font-size);\n line-height: var(--wb-line-20);\n font-weight: 600;\n color: var(--dsw-alias-label-primary);\n}\n\n._actions_jlw8j_1 ._hint_jlw8j_43,\n._bridge_jlw8j_4 ._hint_jlw8j_43 {\n margin: 0;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-19);\n color: var(--dsw-alias-label-secondary);\n}\n\n._actions_jlw8j_1 ._commandRow_jlw8j_3,\n._bridge_jlw8j_4 ._commandRow_jlw8j_3 {\n margin: 0;\n}\n\n._actions_jlw8j_1 ._buttons_jlw8j_191,\n._bridge_jlw8j_4 ._buttons_jlw8j_191 {\n justify-content: flex-start;\n}\n\n._raw_jlw8j_5 {\n margin: 0;\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-label-tertiary);\n}\n\n._rawSummary_jlw8j_282 {\n cursor: pointer;\n color: var(--dsw-alias-label-tertiary);\n}\n\n._actions_jlw8j_1 ._error_jlw8j_132,\n._bridge_jlw8j_4 ._error_jlw8j_132 {\n margin-top: var(--wb-len-6);\n}\n\n._bridgeLines_jlw8j_292 {\n margin: 0;\n padding-left: var(--wb-len-18);\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-8);\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-19);\n color: var(--dsw-alias-label-secondary);\n}\n\n._bridgeLine_jlw8j_292 a {\n display: block;\n margin-top: var(--wb-len-4);\n width: fit-content;\n}\n\n._link_jlw8j_309 {\n color: var(--dsw-alias-label-primary);\n text-decoration: none;\n}\n\n._link_jlw8j_309::after {\n content: '↗';\n margin-left: var(--wb-len-2);\n}\n\n._link_jlw8j_309:hover {\n text-decoration: underline;\n}\n\n._loading_jlw8j_323 {\n flex: none;\n color: var(--dsw-alias-label-tertiary);\n}\n\n._loading_jlw8j_323[hidden] {\n display: none;\n}\n\n._loadingMotion_jlw8j_332 {\n transform-origin: center;\n animation: _wb-spin_jlw8j_1 var(--wb-dur-1-5) linear infinite;\n}\n\n._loadingTrack_jlw8j_337,\n._loadingArc_jlw8j_338 {\n fill: none;\n stroke: currentColor;\n stroke-width: 2;\n stroke-linecap: round;\n}\n\n._loadingTrack_jlw8j_337 {\n opacity: 0.25;\n}\n\n._loadingArc_jlw8j_338 {\n stroke-dasharray: 12 150;\n animation: _wb-dash_jlw8j_1 var(--wb-dur-1-5) ease-in-out infinite;\n}\n\n@keyframes _wb-spin_jlw8j_1 {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n}\n\n@keyframes _wb-dash_jlw8j_1 {\n 0% {\n stroke-dasharray: 12 150;\n stroke-dashoffset: 0;\n }\n 50% {\n stroke-dasharray: 24 150;\n stroke-dashoffset: -6;\n }\n to {\n stroke-dasharray: 12 150;\n stroke-dashoffset: 0;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n ._loadingMotion_jlw8j_332,\n ._loadingArc_jlw8j_338 {\n animation: none;\n }\n}\n._gallery_cagso_1 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-16);\n}\n\n._section_cagso_7 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-10);\n scroll-margin-top: var(--wb-len-12);\n}\n\n._section_cagso_7 + ._section_cagso_7 {\n padding-top: var(--wb-len-16);\n border-top: var(--wb-len-0-5) solid var(--dsw-alias-border-l3);\n}\n\n._heading_cagso_19 {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: var(--wb-len-8);\n min-width: 0;\n}\n\n._headingText_cagso_27 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-2);\n min-width: 0;\n}\n\n._title_cagso_34 {\n margin: 0;\n font-size: var(--dsw-font-xs-13-font-size);\n line-height: var(--wb-line-18);\n font-weight: 600;\n color: var(--dsw-alias-label-primary);\n}\n\n._note_cagso_42 {\n margin: 0;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-tertiary);\n}\n\n._toggle_cagso_49 {\n flex: none;\n width: var(--wb-len-22);\n height: var(--wb-len-22);\n padding: var(--wb-len-3);\n border-radius: var(--wb-radius-6);\n color: var(--dsw-alias-label-tertiary);\n}\n\n._toggle_cagso_49:hover:not(:disabled) {\n color: var(--dsw-alias-label-primary);\n}\n\n._toggle_cagso_49 svg {\n transition: transform var(--wb-dur-0-12) ease;\n}\n\n._toggle_cagso_49[aria-expanded='true'] svg {\n transform: rotate(90deg);\n}\n\n._body_cagso_70 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-10);\n min-width: 0;\n}\n\n._body_cagso_70[hidden] {\n display: none;\n}\n\n._nav_cagso_81 {\n display: flex;\n flex-wrap: wrap;\n gap: var(--wb-len-6);\n padding-bottom: var(--wb-len-12);\n border-bottom: var(--wb-len-0-5) solid var(--dsw-alias-border-l3);\n}\n\n._navLink_cagso_89 {\n display: inline-flex;\n align-items: center;\n box-sizing: border-box;\n padding: var(--wb-len-2) var(--wb-len-8);\n border: var(--wb-len-0-5) solid var(--dsw-alias-border-l3);\n border-radius: var(--wb-radius-pill);\n corner-shape: round;\n background: var(--dsw-alias-bg-layer-2);\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-secondary);\n text-decoration: none;\n}\n\n._navLink_cagso_89:hover {\n border-color: var(--dsw-alias-border-l4);\n color: var(--dsw-alias-label-primary);\n}\n\n._navLink_cagso_89:focus-visible {\n outline: var(--dsw-focus-ring-width) solid\n var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));\n outline-offset: var(--wb-len-neg-2);\n}\n\n._cells_cagso_115 {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(var(--wb-len-220), 1fr));\n gap: var(--wb-len-12);\n align-items: start;\n}\n\n._cell_cagso_115 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-6);\n min-width: 0;\n}\n\n._cellLabel_cagso_129 {\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-caption);\n}\n\n._example_cagso_135 {\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-8);\n min-width: 0;\n max-width: var(--wb-len-360);\n padding: var(--wb-len-10) var(--wb-len-12);\n border-radius: var(--dsw-radius-sm);\n background: var(--dsw-alias-bg-layer-2);\n}\n\n._span_cagso_147 {\n grid-column: 1 / -1;\n}\n\n._stack_cagso_151 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-8);\n}\n\n._inline_cagso_157 {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wb-len-8);\n}\n\n._panel_cagso_164 {\n padding: var(--wb-len-12);\n border: 0.5px solid var(--dsw-alias-border-l3);\n border-radius: var(--dsw-radius-md);\n background: var(--dsw-alias-bg-layer-2);\n}\n\n._narrowActions_cagso_171 {\n max-width: var(--wb-len-132);\n}\n\n._bound_cagso_175 {\n max-width: var(--wb-len-360);\n}\n._marketList_csyus_1 {\n list-style: none;\n margin: 0;\n padding: var(--wb-len-6);\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-2);\n}\n\n._marketRow_csyus_10 {\n display: grid;\n grid-template-columns: auto minmax(0, 1fr) auto;\n align-items: center;\n column-gap: var(--wb-len-14);\n row-gap: var(--wb-len-4);\n padding: var(--wb-len-8);\n border-radius: var(--dsw-radius-lg);\n}\n\n._marketIcon_csyus_20 {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--wb-len-40);\n height: var(--wb-len-40);\n border: 0.5px solid var(--dsw-alias-border-l3);\n border-radius: var(--dsw-radius-md);\n color: var(--dsw-alias-label-secondary);\n}\n\n._marketMain_csyus_32 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-4);\n min-width: 0;\n}\n\n._marketName_csyus_39 {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font: var(--dsw-font-base-strong-16);\n color: var(--dsw-alias-label-primary);\n}\n\n._marketDesc_csyus_48 {\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-6);\n min-width: 0;\n overflow: hidden;\n white-space: nowrap;\n font: var(--dsw-font-s-14);\n color: var(--dsw-alias-label-secondary);\n}\n\n._marketUsedBy_csyus_59 {\n margin-left: var(--wb-len-8);\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-label-tertiary);\n opacity: 0.75;\n}\n\n._marketUsedBy_csyus_59::before {\n content: '·';\n margin-right: var(--wb-len-6);\n opacity: 0.8;\n}\n\n._marketName_csyus_39 ._marketVersion_csyus_73 {\n margin-left: var(--wb-len-6);\n font-size: var(--dsw-font-xxs-12-font-size);\n font-weight: 400;\n line-height: var(--wb-line-18);\n}\n\n._marketVersion_csyus_73 {\n font-variant-numeric: tabular-nums;\n color: var(--dsw-alias-label-caption);\n}\n\n._marketVersion_csyus_73::before {\n content: '';\n display: inline-block;\n width: var(--wb-len-1);\n height: var(--wb-len-10);\n margin: 0 var(--wb-len-8) 0 var(--wb-len-2);\n vertical-align: -1px;\n background: var(--dsw-alias-border-l2);\n}\n\n._marketLocalTag_csyus_95 {\n margin-left: var(--wb-len-8);\n padding: 0 var(--wb-len-6);\n border: var(--wb-len-1) solid var(--dsw-alias-border-l2);\n border-radius: var(--dsw-radius-sm);\n font-size: var(--dsw-font-xxs-12-font-size);\n font-weight: 400;\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-caption);\n}\n\n._marketEnd_csyus_106 {\n flex: none;\n display: flex;\n align-items: center;\n gap: var(--wb-len-10);\n}\n\n._marketSwitchSeat_csyus_113 {\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-10);\n}\n\n._marketSwitchSeat_csyus_113::before {\n content: '';\n width: 0;\n height: var(--wb-len-14);\n border-left: 0.5px solid var(--dsw-alias-border-l3);\n}\n\n._marketActions_csyus_126 {\n flex: none;\n display: flex;\n gap: var(--wb-len-6);\n}\n\n._marketUpdateAction_csyus_132 {\n color: var(--dsw-alias-state-warn-primary);\n border-color: color-mix(in srgb, var(--dsw-alias-state-warn-primary) 30%, transparent);\n --dsw-alias-interactive-bg-hover: color-mix(in srgb, var(--dsw-alias-state-warn-primary) 8%, transparent);\n}\n\n._marketSelfDivider_csyus_138 {\n height: 0;\n border-top: 0.5px solid var(--dsw-alias-border-l3);\n}\n\n._marketSection_csyus_143 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-8);\n min-width: 0;\n}\n\n._marketSectionHead_csyus_150 {\n display: flex;\n align-items: baseline;\n gap: var(--wb-len-8);\n}\n\n._marketSectionIcon_csyus_156 {\n display: inline-flex;\n align-items: center;\n align-self: center;\n color: var(--dsw-alias-label-caption);\n}\n\n._marketSectionTitle_csyus_163 {\n margin: 0;\n font: var(--dsw-font-base-strong-16);\n color: var(--dsw-alias-label-primary);\n}\n\n._marketSectionCount_csyus_169 {\n font: var(--dsw-font-s-14);\n font-variant-numeric: tabular-nums;\n color: var(--dsw-alias-label-caption);\n}\n\n\n._marketProgress_csyus_176 {\n flex: none;\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-8);\n min-height: var(--wb-len-32);\n font: var(--dsw-font-s-14);\n color: var(--dsw-alias-label-secondary);\n}\n\n._marketNote_csyus_186 {\n grid-column: 2 / -1;\n font: var(--dsw-font-s-14);\n color: var(--dsw-alias-state-warn-primary);\n overflow-wrap: anywhere;\n}\n\n._marketNotePlain_csyus_193 {\n grid-column: 2 / -1;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-caption);\n overflow-wrap: anywhere;\n}\n\n._marketFailure_csyus_201 {\n grid-column: 2 / -1;\n font: var(--dsw-font-s-14);\n color: var(--dsw-alias-state-error-primary);\n overflow-wrap: anywhere;\n}\n\n._marketEmpty_csyus_208 {\n padding: var(--wb-len-18) var(--wb-len-16);\n text-align: center;\n}\n\n._marketPage_csyus_213 {\n box-sizing: border-box;\n height: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--wb-len-32);\n padding: 0 clamp(var(--wb-len-24), 4vw, var(--wb-len-48)) var(--wb-len-48);\n overflow-x: hidden;\n overflow-y: auto;\n color: var(--dsw-alias-label-primary);\n}\n\n._marketPage_csyus_213 > * {\n width: 100%;\n max-width: var(--wb-len-960);\n}\n\n._marketPageHead_csyus_231 {\n box-sizing: border-box;\n display: flex;\n align-items: flex-start;\n gap: var(--wb-len-16);\n padding-top: var(--wb-len-28);\n}\n\n._marketPageTitle_csyus_239 {\n margin: 0;\n font: var(--dsw-font-l-20);\n}\n\n._marketPageIntro_csyus_244 {\n margin: var(--wb-len-4) 0 0;\n font: var(--dsw-font-xs-13);\n color: var(--dsw-alias-label-secondary);\n}\n\n._marketPageTools_csyus_250 {\n flex: none;\n align-self: center;\n margin-left: auto;\n display: flex;\n align-items: center;\n gap: var(--wb-len-16);\n}\n\n._marketIconButton_csyus_259 {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--wb-len-28);\n height: var(--wb-len-28);\n padding: 0;\n border: 0;\n border-radius: var(--dsw-radius-sm);\n background: transparent;\n color: var(--dsw-alias-label-caption);\n cursor: pointer;\n}\n\n._marketIconButton_csyus_259:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-secondary);\n}\n\n._marketIconButton_csyus_259:disabled {\n cursor: default;\n opacity: 0.5;\n}\n\n._marketIconWrap_csyus_284 {\n display: inline-flex;\n}\n\n._marketIconButtonSpinning_csyus_288 svg {\n animation: _wb-spin_csyus_1 var(--wb-dur-0-9) linear infinite;\n}\n\n._marketAddButton_csyus_292 {\n height: var(--wb-len-32);\n padding: 0 var(--wb-len-12);\n font-size: var(--dsw-font-xs-13-font-size);\n line-height: var(--wb-line-20);\n border-radius: var(--dsw-radius-md);\n}\n\n._marketEmpty_csyus_208 {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--wb-len-8);\n padding: var(--wb-len-64) var(--wb-len-16);\n text-align: center;\n}\n\n._marketChecking_csyus_309 {\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-6);\n font: var(--dsw-font-s-14);\n color: var(--dsw-alias-label-secondary);\n}\n\n._marketEmptyTitle_csyus_317 {\n font: var(--dsw-font-base-strong-16);\n color: var(--dsw-alias-label-primary);\n}\n\n@keyframes _wb-spin_csyus_1 {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n}\n._foot_1ud1j_1 {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: var(--wb-len-8);\n padding: var(--wb-len-8) var(--wb-len-14) var(--wb-len-10);\n border-top: 0.5px solid var(--dsw-alias-border-l2);\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-label-tertiary);\n}\n\n._footText_1ud1j_13 {\n flex: 1;\n min-width: 0;\n}\n\n._footTextMd_1ud1j_18 {\n flex: 1;\n min-width: 0;\n font: var(--dsw-font-s-14);\n color: var(--dsw-alias-label-secondary);\n}\n._wide_1lv8f_1 {\n justify-content: center;\n width: 100%;\n height: var(--wb-len-40);\n border-radius: var(--dsw-radius-md);\n}\n\n._dialog_1lv8f_8 {\n width: min(var(--wb-len-560), 100%);\n max-height: min(var(--wb-len-800), 100%);\n}\n\n._content_1lv8f_13 {\n min-height: 0;\n overflow: auto;\n}\n\n._stack_1lv8f_18 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-12);\n min-width: 0;\n}\n\n._body_1lv8f_25 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-12);\n min-width: 0;\n}\n\n._field_1lv8f_32 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-6);\n font-size: var(--dsw-font-xs-13-font-size);\n}\n\n._input_1lv8f_39 {\n width: 100%;\n height: var(--wb-len-40);\n padding: 0 var(--wb-len-14);\n}\n\n._registryField_1lv8f_45 {\n height: var(--wb-len-32);\n margin-left: var(--wb-len-26);\n padding: 0 var(--wb-len-10);\n}\n\n._options_1lv8f_51 {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n gap: var(--wb-len-8) var(--wb-len-12);\n}\n\n._guideToggle_1lv8f_59 {\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-4);\n align-self: flex-start;\n margin-top: var(--wb-len-4);\n padding: 0;\n border: 0;\n background: transparent;\n font: var(--dsw-font-xs-13);\n color: var(--dsw-alias-label-secondary);\n cursor: pointer;\n}\n\n._guideToggle_1lv8f_59:hover {\n color: var(--dsw-alias-label-primary);\n}\n\n._guideToggle_1lv8f_59 svg,\n._registryToggle_1lv8f_78 svg {\n transition: transform var(--wb-dur-0-12) ease;\n}\n\n._guideToggle_1lv8f_59[aria-expanded='true'] svg,\n._registryToggle_1lv8f_78[aria-expanded='true'] svg {\n transform: rotate(180deg);\n}\n\n._registryWrap_1lv8f_87 {\n position: relative;\n flex: none;\n}\n\n._registryToggle_1lv8f_78 {\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-6);\n height: var(--wb-len-26);\n padding: 0 var(--wb-len-8) 0 var(--wb-len-10);\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: var(--dsw-radius-sm);\n background: var(--dsw-alias-bg-layer-2);\n font: inherit;\n font-size: var(--wb-font-12-5);\n color: var(--dsw-alias-label-secondary);\n cursor: pointer;\n}\n\n._registryToggle_1lv8f_78:hover:not(:disabled) {\n color: var(--dsw-alias-label-primary);\n}\n\n._registryToggle_1lv8f_78:disabled {\n cursor: default;\n opacity: 0.6;\n}\n\n._registryToggle_1lv8f_78[aria-expanded='true'] {\n border-color: var(--dsw-alias-border-l3);\n background: var(--dsw-alias-bg-layer-3);\n}\n\n._registryChosen_1lv8f_121 {\n color: var(--dsw-alias-label-primary);\n font-weight: 500;\n}\n\n._registry_1lv8f_45 {\n position: fixed;\n z-index: var(--wb-z-1100);\n box-sizing: border-box;\n width: min(var(--wb-len-440), 100vw - var(--wb-len-24));\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-4);\n margin: 0;\n padding: var(--wb-len-8) var(--wb-len-10) var(--wb-len-12);\n border: 0;\n border-radius: var(--dsw-radius-lg);\n background: var(--dsw-alias-bg-layer-2);\n --dsw-elevation-stroke-color: var(--dsw-alias-border-l3);\n box-shadow: var(--dsw-elevation-prominent);\n}\n\n._registryOption_1lv8f_143 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-4);\n padding: var(--wb-len-8) var(--wb-len-10);\n border: 0.5px solid transparent;\n border-radius: var(--dsw-radius-lg);\n cursor: pointer;\n}\n\nlabel._registryOption_1lv8f_143 {\n flex-direction: row;\n align-items: flex-start;\n gap: var(--wb-len-10);\n}\n\n._registryPick_1lv8f_159 {\n display: flex;\n align-items: flex-start;\n gap: var(--wb-len-10);\n cursor: pointer;\n}\n\n._registryOption_1lv8f_143[data-checked='true'] {\n border-color: color-mix(in srgb, var(--dsw-alias-brand-primary) 40%, transparent);\n background: var(--dsw-alias-bg-layer-2);\n}\n\n._registryOption_1lv8f_143 input[type='radio'] {\n flex: none;\n width: var(--wb-len-16);\n height: var(--wb-len-16);\n margin: var(--wb-len-2) 0 0;\n accent-color: var(--dsw-alias-brand-primary);\n}\n\n._registryTitle_1lv8f_179 {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wb-len-8);\n font: var(--dsw-font-xs-13);\n line-height: var(--wb-line-20);\n color: var(--dsw-alias-label-primary);\n}\n\n._registryHint_1lv8f_189 {\n margin-left: var(--wb-len-26);\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-tertiary);\n overflow-wrap: anywhere;\n}\n\n._inputError_1lv8f_197 {\n margin: var(--wb-len-neg-4) 0 0 var(--wb-len-26);\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-state-error-primary);\n}\n\n._guide_1lv8f_59 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-10);\n padding: var(--wb-len-8) var(--wb-len-14) var(--wb-len-14);\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: var(--dsw-radius-lg);\n background: var(--dsw-alias-bg-layer-1);\n}\n\n._guideList_1lv8f_214 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-2);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n._guideItem_1lv8f_223 {\n display: flex;\n align-items: flex-start;\n gap: var(--wb-len-10);\n padding: var(--wb-len-8) 0;\n}\n\n._guideIndex_1lv8f_230 {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--wb-len-20);\n height: var(--wb-len-20);\n border-radius: var(--wb-radius-pill);\n corner-shape: round;\n background: var(--dsw-alias-bg-module-platform);\n font: var(--dsw-font-xs-13);\n color: var(--dsw-alias-label-secondary);\n}\n\n._guideMain_1lv8f_244 {\n display: flex;\n flex-direction: column;\n flex: 1;\n gap: 0;\n min-width: 0;\n}\n\n._guideTitle_1lv8f_252 {\n font: var(--dsw-font-s-14);\n font-weight: 500;\n color: var(--dsw-alias-label-primary);\n}\n\n._guideHint_1lv8f_258 {\n margin: 0;\n font: var(--dsw-font-xs-13);\n color: var(--dsw-alias-label-caption);\n}\n\n._guideExample_1lv8f_264 {\n font: var(--dsw-font-xs-13);\n color: var(--dsw-alias-label-secondary);\n overflow-wrap: anywhere;\n}\n\n._guideExample_1lv8f_264 code {\n font-family: var(--dsw-font-mono, monospace);\n}\n\n._guideExampleLabel_1lv8f_274 {\n color: var(--dsw-alias-label-caption);\n}\n\n._footer_1lv8f_278 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-20);\n width: 100%;\n}\n\n._hero_1lv8f_285 {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--wb-len-10);\n padding: var(--wb-len-8) 0 var(--wb-len-4);\n text-align: center;\n}\n\n._heroIcon_1lv8f_294 {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--wb-len-44);\n height: var(--wb-len-44);\n color: var(--dsw-alias-label-secondary);\n}\n\n._heroIcon_1lv8f_294[data-state='done'] {\n color: var(--dsw-alias-state-success-secondary);\n}\n\n._heroIcon_1lv8f_294[data-state='error'] {\n color: var(--dsw-alias-state-warn-label);\n}\n\n._pendingTitle_1lv8f_311 {\n margin: 0;\n font-size: var(--dsw-font-s-14-font-size);\n line-height: var(--wb-line-22);\n font-weight: 500;\n color: var(--dsw-alias-label-secondary);\n}\n\n._wizardTitle_1lv8f_319 {\n margin: 0;\n font-size: var(--wb-font-18);\n line-height: var(--wb-len-26);\n font-weight: 600;\n}\n\n._subject_1lv8f_326 {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--wb-len-6);\n padding: var(--wb-len-16);\n border: 0.5px solid var(--dsw-alias-border-l3);\n border-radius: var(--dsw-radius-lg);\n text-align: center;\n}\n\n._subjectName_1lv8f_337 {\n margin: 0;\n font: var(--dsw-font-base-strong-16);\n overflow-wrap: anywhere;\n}\n\n._subjectMeta_1lv8f_343,\n._subjectDesc_1lv8f_344 {\n margin: 0;\n font: var(--dsw-font-xs-13);\n color: var(--dsw-alias-label-secondary);\n overflow-wrap: anywhere;\n}\n\n._result_1lv8f_351,\n._resultWarn_1lv8f_352 {\n margin: 0;\n padding: var(--wb-len-8) var(--wb-len-12);\n border-radius: var(--dsw-radius-md);\n background: color-mix(in srgb, var(--dsw-alias-state-success-primary) 10%, transparent);\n font: var(--dsw-font-s-14);\n color: var(--dsw-alias-label-primary);\n}\n\n._resultWarn_1lv8f_352 {\n background: color-mix(in srgb, var(--dsw-alias-state-warn-primary) 12%, transparent);\n}\n\n._resultMeta_1lv8f_365 {\n margin: 0;\n padding: 0 var(--wb-len-12);\n font: var(--dsw-font-xs-13);\n color: var(--dsw-alias-label-secondary);\n overflow-wrap: anywhere;\n}\n\n._approval_1lv8f_373 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-8);\n padding: var(--wb-len-12) var(--wb-len-14);\n border: 0.5px solid var(--dsw-alias-state-warn-primary);\n border-radius: var(--dsw-radius-lg);\n background: color-mix(in srgb, var(--dsw-alias-state-warn-primary) 8%, transparent);\n}\n\n._approvalTitle_1lv8f_383 {\n margin: 0;\n font: var(--dsw-font-s-14);\n font-weight: 600;\n color: var(--dsw-alias-label-primary);\n}\n\n._approvalText_1lv8f_390 {\n margin: 0;\n font: var(--dsw-font-xs-13);\n color: var(--dsw-alias-label-secondary);\n}\n\n._approvalCaution_1lv8f_396 {\n margin: 0;\n font: var(--dsw-font-xs-13);\n font-weight: 600;\n color: var(--dsw-alias-state-warn-primary);\n}\n\n._note_1lv8f_403 {\n margin: 0;\n font: var(--dsw-font-s-14);\n color: var(--dsw-alias-label-secondary);\n overflow-wrap: anywhere;\n}\n\n._noteWarn_1lv8f_410 {\n color: var(--dsw-alias-state-warn-primary);\n}\n\n._noteError_1lv8f_414 {\n color: var(--dsw-alias-state-error-primary);\n}\n\n._problem_1lv8f_418 {\n margin: 0;\n font: var(--dsw-font-xs-13);\n color: var(--dsw-alias-state-error-primary);\n overflow-wrap: anywhere;\n}\n\n._detailLabel_1lv8f_425 {\n margin: 0;\n font: var(--dsw-font-xs-13);\n color: var(--dsw-alias-label-caption);\n}\n\n._detail_1lv8f_425 {\n margin: 0;\n padding: var(--wb-len-8) var(--wb-len-10);\n border: 0.5px solid var(--dsw-alias-border-l1);\n border-radius: var(--dsw-radius-sm);\n background: var(--dsw-alias-bg-layer-3);\n font-family: var(--dsw-font-mono, monospace);\n font-size: var(--dsw-font-xs-13-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-secondary);\n overflow-wrap: anywhere;\n white-space: pre-wrap;\n}\n._note_1enlz_1 {\n display: flex;\n align-items: flex-start;\n gap: var(--wb-len-8);\n margin: 0;\n padding: var(--wb-len-10) var(--wb-len-12);\n border-radius: var(--dsw-radius-md);\n background: var(--dsw-alias-state-warn-tertiary);\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-secondary);\n}\n\n._note_1enlz_1 > svg {\n flex: none;\n margin-top: var(--wb-len-2);\n color: var(--dsw-alias-state-warn-primary);\n}\n._slot_1og2k_1 {\n display: flex;\n flex: 1 1 0;\n min-width: 0;\n}\n\n._slot_1og2k_1 > * {\n flex: 1 1 0;\n min-width: 0;\n}\n\n._action_1og2k_12 {\n box-sizing: border-box;\n display: flex;\n align-items: center;\n justify-content: flex-start;\n flex: 1 1 0;\n width: 100%;\n min-width: 0;\n min-height: var(--wb-len-36);\n margin: 0 var(--wb-len-2);\n padding: var(--wb-len-7) var(--wb-len-8);\n border-radius: var(--dsw-radius-md);\n cursor: default;\n overflow: hidden;\n gap: var(--wb-len-4);\n font-size: var(--dsw-font-xs-13-font-size);\n line-height: var(--wb-line-18);\n}\n\n._live_1og2k_31 {\n color: var(--dsw-alias-state-success-primary);\n}\n\n._paused_1og2k_35 {\n color: var(--dsw-alias-state-warn-primary);\n}\n\n._trouble_1og2k_39 {\n color: var(--dsw-alias-state-error-primary);\n}\n\n._pulse_1og2k_43 {\n animation: _wb-debug-breathe_1og2k_1 var(--wb-dur-1-5) var(--ds-ease-in-out, ease-in-out) infinite;\n}\n\n@keyframes _wb-debug-breathe_1og2k_1 {\n 0%,\n 100% {\n opacity: 1;\n }\n\n 50% {\n opacity: 0.35;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n ._pulse_1og2k_43 {\n animation: none;\n }\n}\n\n._entry_1og2k_64 {\n display: flex;\n align-items: center;\n flex: 1 1 auto;\n min-width: 0;\n}\n\n._entryInner_1og2k_71 {\n display: flex;\n align-items: center;\n gap: var(--wb-len-6);\n min-width: 0;\n}\n\n._acts_1og2k_78 {\n display: flex;\n align-items: center;\n gap: var(--wb-len-2);\n flex: none;\n}\n\n._act_1og2k_12 {\n appearance: none;\n border: 0;\n background: transparent;\n color: var(--dsw-alias-label-secondary);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--wb-len-22);\n height: var(--wb-len-22);\n padding: 0;\n border-radius: var(--dsw-radius-sm, var(--wb-len-6));\n flex: none;\n cursor: pointer;\n}\n\n._act_1og2k_12:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n._act_1og2k_12:focus-visible {\n outline: var(--dsw-focus-ring-width) solid var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));\n outline-offset: -2px;\n}\n\n._actStop_1og2k_110:hover,\n._actStop_1og2k_110:focus-visible {\n color: var(--dsw-alias-state-error-primary);\n}\n\n._actArmed_1og2k_115,\n._actArmed_1og2k_115:hover,\n._actArmed_1og2k_115:focus-visible {\n background: color-mix(in srgb, var(--dsw-alias-state-error-primary) 12%, transparent);\n width: auto;\n color: var(--dsw-alias-state-error-primary);\n gap: var(--wb-len-4);\n padding: 0 var(--wb-len-7);\n}\n\n._actLabel_1og2k_125 {\n white-space: nowrap;\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-18);\n}\n\n._entryLine_1og2k_131 {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n._actionRail_1og2k_138 {\n justify-content: center;\n flex: none;\n width: var(--wb-len-36);\n min-width: var(--wb-len-36);\n height: var(--wb-len-36);\n margin: 0;\n padding: 0;\n corner-shape: round;\n border-radius: 50%;\n}\n\n._card_1og2k_150 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-4);\n}\n\n._cardTitle_1og2k_156 {\n color: var(--dsw-alias-label-primary);\n font-size: var(--dsw-font-s-14-font-size);\n line-height: var(--wb-line-20);\n}\n\n._cardNote_1og2k_162 {\n color: var(--dsw-alias-label-secondary);\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n}\n._body_lw2ph_1 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-12);\n}\n\n._lead_lw2ph_7 {\n margin: 0;\n font-size: var(--dsw-font-xs-13-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-secondary);\n}\n\n._sources_lw2ph_14 {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wb-len-8);\n}\n\n._sourcesLabel_lw2ph_21 {\n font-size: var(--dsw-font-xxs-12-font-size);\n color: var(--dsw-alias-label-secondary);\n}\n\nbutton._sourceOn_lw2ph_26 {\n border-color: var(--dsw-alias-brand-primary);\n}\n._sourceCount_lw2ph_29 {\n margin-left: var(--wb-len-4);\n font-variant-numeric: tabular-nums;\n font-size: var(--dsw-font-xxs-12-font-size);\n color: var(--dsw-alias-label-tertiary);\n}\n\n._reading_lw2ph_36 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-4);\n}\n\n._status_lw2ph_42 {\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-6);\n margin: 0;\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-tertiary);\n}\n\n._failure_lw2ph_52 {\n display: grid;\n grid-template-columns: minmax(0, 1fr) auto;\n column-gap: var(--wb-len-10);\n row-gap: var(--wb-len-2);\n color: var(--dsw-alias-state-error-primary);\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n}\n\n._failureTitle_lw2ph_62 {\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-6);\n min-width: 0;\n}\n\n._failureHint_lw2ph_69 {\n grid-column: 1;\n color: var(--dsw-alias-label-tertiary);\n}\n\n._failureAction_lw2ph_74 {\n grid-column: 2;\n grid-row: 1;\n justify-self: end;\n}\n\n._rows_lw2ph_80 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-8);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n._row_lw2ph_80 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-6);\n padding: var(--wb-len-12) var(--wb-len-14);\n border: 0.5px solid var(--dsw-alias-settings-card-stroke);\n border-radius: var(--dsw-radius-xl);\n background: var(--dsw-alias-settings-card-fill);\n}\n\n._head_lw2ph_99 {\n display: flex;\n align-items: center;\n gap: var(--wb-len-8);\n min-width: 0;\n}\n\n._pick_lw2ph_106 {\n flex: 0 1 auto;\n min-width: 0;\n font-size: var(--dsw-font-xs-13-font-size);\n}\n\n._pick_lw2ph_106 > span {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n._code_lw2ph_118 {\n --dsl-code-block-background: var(--dsw-alias-bg-layer-1);\n margin: 0;\n}\n\n._missing_lw2ph_123,\n._conflict_lw2ph_124 {\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-state-warn-primary);\n}\n\n._foot_lw2ph_130 {\n display: flex;\n justify-content: flex-end;\n}\n._group_1hxis_1 {\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-2);\n}\n\n._button_1hxis_7 {\n flex: none;\n width: var(--wb-len-28);\n height: var(--wb-len-28);\n padding: 0;\n color: var(--dsw-alias-label-secondary);\n}\n\n._button_1hxis_7:hover:not(:disabled) {\n color: var(--dsw-alias-label-primary);\n}\n\n._active_1hxis_19 {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n._icon_1hxis_23 {\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n._icon_1hxis_23 svg {\n display: block;\n width: var(--wb-len-15);\n height: var(--wb-len-15);\n}\n\n._mirror_1hxis_35 {\n transform: scaleX(-1);\n}\n._stripTabs_1dqp4_1 {\n display: flex;\n align-items: center;\n gap: var(--wb-len-4);\n min-width: 0;\n overflow: hidden;\n}\n\n._tab_1dqp4_9 {\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-6);\n flex: none;\n height: var(--wb-len-28);\n padding: 0 var(--wb-len-10);\n border: 0;\n border-radius: var(--dsw-radius-sm);\n background: none;\n font: inherit;\n font-size: var(--dsw-font-xs-13-font-size);\n line-height: var(--wb-line-16);\n max-width: 100%;\n}\n\n._tabActive_1dqp4_25 {\n color: var(--dsw-alias-label-primary);\n}\n\n._tabQuiet_1dqp4_29 {\n color: var(--dsw-alias-label-tertiary);\n cursor: pointer;\n}\n\n._tabQuiet_1dqp4_29:hover {\n color: var(--dsw-alias-label-primary);\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n._tabTitle_1dqp4_39 {\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-6);\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n._sep_1dqp4_49 {\n flex: none;\n color: var(--dsw-alias-label-dimmed);\n}\n._trigger_15ptp_1 {\n display: flex;\n align-items: center;\n}\n\n._pop_15ptp_6 {\n position: absolute;\n top: calc(var(--wb-len-38) + var(--wb-len-8));\n right: var(--wb-len-6);\n z-index: var(--wb-z-30);\n width: min(var(--wb-len-360), calc(100% - var(--wb-len-12)));\n max-width: calc(100vw - var(--wb-len-48));\n border: 0.5px solid var(--dsw-alias-border-l2);\n border-radius: var(--wb-radius-14);\n background: var(--dsw-alias-bg-layer-2);\n box-shadow: var(--dsw-shadow-lv3);\n overflow: hidden;\n}\n\n._head_15ptp_20 {\n display: flex;\n align-items: center;\n gap: var(--wb-len-8);\n padding: var(--wb-len-10) var(--wb-len-12) var(--wb-len-9) var(--wb-len-14);\n border-bottom: 0.5px solid var(--dsw-alias-border-l2);\n}\n\n._title_15ptp_28 {\n flex: 1;\n font-size: var(--dsw-font-xs-13-font-size);\n line-height: var(--wb-line-20);\n font-weight: 600;\n color: var(--dsw-alias-label-primary);\n}\n\n._rowControls_15ptp_36 {\n flex: none;\n display: inline-flex;\n align-items: center;\n gap: var(--wb-len-8);\n}\n\n._reset_15ptp_43 {\n flex: none;\n padding: var(--wb-len-3) var(--wb-len-8);\n border: none;\n border-radius: var(--wb-radius-6);\n background: transparent;\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-label-tertiary);\n cursor: pointer;\n}\n\n._reset_15ptp_43:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-primary);\n}\n\n._reset_15ptp_43:disabled {\n cursor: default;\n opacity: 0.5;\n}\n\n._list_15ptp_65 {\n list-style: none;\n margin: 0;\n padding: var(--wb-len-6);\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-2);\n}\n\n._row_15ptp_36 {\n position: relative;\n display: grid;\n grid-template-columns: 12px minmax(0, 1fr) auto;\n align-items: center;\n gap: var(--wb-len-8);\n padding: var(--wb-len-7) var(--wb-len-8);\n border-radius: var(--dsw-radius-sm);\n cursor: default;\n}\n\n._rowDragging_15ptp_85 {\n cursor: grabbing;\n}\n\n._rowBlocked_15ptp_89 {\n cursor: not-allowed;\n}\n\n._listDragging_15ptp_93 ._rowControls_15ptp_36 {\n pointer-events: none;\n}\n\n._row_15ptp_36:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n._rowOff_15ptp_101 {\n opacity: 0.55;\n}\n\n._rowOff_15ptp_101:hover {\n opacity: 1;\n}\n\n._rowOver_15ptp_109::before {\n content: '';\n position: absolute;\n top: var(--wb-len-neg-3);\n left: var(--wb-len-8);\n right: var(--wb-len-8);\n height: var(--wb-len-2);\n background: var(--dsw-alias-brand-primary);\n}\n\n._ghost_15ptp_119 {\n position: fixed;\n z-index: var(--wb-z-40);\n pointer-events: none;\n padding: var(--wb-len-4) var(--wb-len-10);\n border: 0.5px solid var(--dsw-alias-border-l3);\n border-radius: var(--dsw-radius-sm);\n background: var(--dsw-alias-bg-layer-1);\n box-shadow: var(--wb-static-shadow-ghost);\n font-size: var(--dsw-font-xs-13-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-primary);\n white-space: nowrap;\n}\n\n._grip_15ptp_134 {\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n text-align: center;\n color: var(--dsw-alias-label-tertiary);\n user-select: none;\n cursor: grab;\n touch-action: none;\n}\n\n._gripDragging_15ptp_144 {\n cursor: grabbing;\n}\n\n._gripBlocked_15ptp_148 {\n cursor: not-allowed;\n}\n\n._label_15ptp_152 {\n display: flex;\n align-items: center;\n gap: var(--wb-len-6);\n min-width: 0;\n}\n\n._name_15ptp_159 {\n min-width: 0;\n flex: 0 1 auto;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: var(--dsw-font-xs-13-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-primary);\n}\n\n._error_15ptp_170 {\n margin: 0;\n padding: 0 var(--wb-len-14) var(--wb-len-10);\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-state-error-primary);\n}\n\n._dep_15ptp_178 {\n flex: none;\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n color: var(--dsw-alias-label-tertiary);\n white-space: nowrap;\n}\n\n._group_15ptp_186 {\n padding-top: var(--wb-len-6);\n border-top: 0.5px solid var(--dsw-alias-border-l2);\n}\n\n._groupTitle_15ptp_191 {\n margin: 0;\n padding: var(--wb-len-2) var(--wb-len-8) 0 var(--wb-len-14);\n font-size: var(--dsw-font-xxxs-11-font-size);\n line-height: var(--wb-line-16);\n font-weight: 400;\n color: var(--dsw-alias-label-tertiary);\n}\n._panel_135e7_1 {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n z-index: var(--wb-z-10);\n visibility: hidden;\n}\n\n._panel_135e7_1[data-fullscreen] {\n z-index: var(--wb-z-40);\n}\n\n._panel_135e7_1[data-open] {\n visibility: visible;\n}\n\n._columns_135e7_18 {\n display: grid;\n grid-template-columns: minmax(0, 1fr);\n align-items: start;\n gap: var(--wb-len-12);\n}\n\n._columns_135e7_18[data-two] {\n grid-template-columns: repeat(2, minmax(0, 1fr));\n}\n\n._column_135e7_18 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-12);\n min-width: 0;\n}\n._root_1cmz0_1 {\n position: relative;\n flex: none;\n margin: 0 var(--wb-len-2) var(--wb-len-4);\n}\n\n._rail_1cmz0_7 {\n margin: 0 0 var(--wb-len-4);\n}\n\n._glyphBox_1cmz0_11 {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n}\n\n._glyph_1cmz0_11 {\n position: relative;\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--wb-len-16);\n height: var(--wb-len-20);\n color: var(--dsw-alias-label-tertiary);\n}\n\n._glyphActive_1cmz0_30 {\n color: var(--dsw-alias-state-business-primary);\n}\n\n._triggerName_1cmz0_34 {\n flex: 1;\n min-width: 0;\n display: flex;\n align-items: baseline;\n gap: var(--wb-len-6);\n font-size: var(--wb-font-row);\n line-height: var(--wb-line-20);\n overflow: hidden;\n}\n\n._dir_1cmz0_45 {\n flex: 0 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n._name_1cmz0_53 {\n flex: 0 1 auto;\n max-width: 50%;\n font-size: var(--dsw-font-xxs-12-font-size);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n._triggerName_1cmz0_34 ._name_1cmz0_53 {\n color: var(--dsw-alias-label-tertiary);\n}\n\n._row_1cmz0_66 {\n display: flex;\n align-items: center;\n gap: var(--wb-len-6);\n width: 100%;\n min-width: 0;\n}\n\n._trailing_1cmz0_74 {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--wb-len-20);\n height: var(--wb-len-20);\n margin-inline-start: auto;\n}\n\n._trailing_1cmz0_74 ._rowAction_1cmz0_84 {\n width: var(--wb-len-20);\n min-width: var(--wb-len-20);\n height: var(--wb-len-20);\n min-height: var(--wb-len-20);\n padding: 0;\n border-radius: var(--dsw-radius-sm);\n}\n\n._row_1cmz0_66 ._name_1cmz0_53 {\n color: var(--dsw-alias-label-tertiary);\n}\n\n._current_1cmz0_97 {\n flex: none;\n display: inline-flex;\n align-items: center;\n color: var(--dsw-alias-label-primary);\n}\n._dot_sosf1_1 {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n\n._overlay_sosf1_8 {\n position: absolute;\n inset-block-start: var(--wb-len-neg-3);\n inset-inline-end: var(--wb-len-neg-3);\n}\n._tag_g9dg8_1 {\n flex: none;\n margin-inline-start: auto;\n}\n._dialog_1vye5_1 {\n width: min(var(--wb-len-420), 100%);\n}\n\n._stack_1vye5_5 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-8);\n min-width: 0;\n}\n\n._input_1vye5_12 {\n width: 100%;\n height: var(--wb-len-40);\n padding: 0 var(--wb-len-12);\n}\n\n._meta_1vye5_18 {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--wb-len-12);\n min-width: 0;\n}\n._blocker_1oaj0_1 {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--wb-len-6);\n padding: var(--wb-len-20) var(--wb-len-16);\n text-align: center;\n}\n\n._icon_1oaj0_10 {\n display: flex;\n color: var(--dsw-alias-label-tertiary);\n}\n\n._title_1oaj0_15 {\n margin: var(--wb-len-2) 0 0;\n font-size: var(--dsw-font-s-14-font-size);\n line-height: var(--wb-line-22);\n font-weight: 600;\n color: var(--dsw-alias-label-primary);\n}\n\n._hint_1oaj0_23 {\n margin: 0;\n max-width: var(--wb-len-42em);\n font-size: var(--dsw-font-xxs-12-font-size);\n line-height: var(--wb-line-18);\n color: var(--dsw-alias-label-tertiary);\n text-wrap: pretty;\n}\n\n._blocker_1oaj0_1._blockerInline_1oaj0_32 {\n align-items: flex-start;\n gap: var(--wb-len-6);\n padding: var(--wb-len-4) 0 var(--wb-len-2);\n text-align: left;\n}\n\n._blocker_1oaj0_1._blockerInline_1oaj0_32 ._title_1oaj0_15 {\n font-size: var(--dsw-font-xs-13-font-size);\n line-height: var(--wb-line-20);\n}\n\n._blocker_1oaj0_1._blockerInline_1oaj0_32 ._hint_1oaj0_23 {\n max-width: 100%;\n}\n\n._blocker_1oaj0_1._blockerInline_1oaj0_32 ._actions_1oaj0_48 {\n margin-top: var(--wb-len-8);\n}\n\n._blocker_1oaj0_1._blockerInline_1oaj0_32 ._raw_1oaj0_52 {\n margin-top: var(--wb-len-4);\n max-width: 100%;\n}\n\n._actions_1oaj0_48 {\n display: flex;\n align-items: center;\n gap: var(--wb-len-10);\n margin-top: var(--wb-len-6);\n}\n\n._raw_1oaj0_52 {\n margin-top: var(--wb-len-10);\n width: 100%;\n max-width: var(--wb-len-360);\n text-align: left;\n}\n\n._notice_1oaj0_71 {\n display: grid;\n grid-template-columns: minmax(0, 1fr) auto;\n align-items: start;\n column-gap: var(--wb-len-10);\n margin: 0 0 var(--wb-len-10);\n padding: var(--wb-len-10) var(--wb-len-12);\n border: 0.5px solid var(--dsw-alias-border-l2);\n border-left: 2px solid var(--dsw-alias-border-l3);\n border-radius: var(--dsw-radius-sm);\n background: var(--dsw-alias-bg-layer-1);\n}\n\n._notice_1oaj0_71._noticeFlat_1oaj0_84 {\n margin: 0;\n padding: 0;\n border: 0;\n background: transparent;\n}\n\n._noticeText_1oaj0_91 {\n display: flex;\n flex-direction: column;\n gap: var(--wb-len-3);\n min-width: 0;\n}\n\n._noticeTitle_1oaj0_98 {\n font-size: var(--wb-font-12-5);\n line-height: var(--wb-line-18);\n font-weight: 600;\n color: var(--dsw-alias-label-primary);\n}\n\n._noticeHint_1oaj0_105 {\n font-size: var(--wb-font-11-5);\n line-height: var(--wb-line-17);\n color: var(--dsw-alias-label-tertiary);\n overflow-wrap: anywhere;\n}\n\n._noticeActions_1oaj0_112 {\n display: flex;\n align-items: center;\n gap: var(--wb-len-6);\n margin-top: var(--wb-len-neg-2);\n}\n\n._failure_1oaj0_119 {\n margin: var(--wb-len-8) 0 0;\n font-size: var(--wb-font-11-5);\n line-height: var(--wb-line-17);\n color: var(--dsw-alias-state-error-primary);\n overflow-wrap: anywhere;\n}\n\n._failureDetail_1oaj0_127 {\n display: block;\n margin-top: var(--wb-len-2);\n color: var(--dsw-alias-label-tertiary);\n white-space: pre-wrap;\n}\n\n._inlineAction_1oaj0_134 {\n padding: 0;\n border: none;\n background: transparent;\n cursor: pointer;\n}\n\n._inlineAction_1oaj0_134:disabled {\n opacity: 0.6;\n cursor: default;\n}\n\n._rawText_1oaj0_146 {\n margin: var(--wb-len-6) 0 0;\n max-width: 100%;\n}\n/*$vite$:1*/";
9211
12313
  function workbenchCss() {
9212
12314
  return `${tokens_default}\n${palette_default}\n${scale_default}\n${sidebar_default}\n${sidebar_app_default}\n${rightbar_default}\n${chrome_default}\n${board_default}\n${motion_default}\n${COMPONENT_CSS_MARKER}`;
9213
12315
  }
@@ -9396,6 +12498,7 @@ function mount(ctx) {
9396
12498
  })
9397
12499
  }, Sidebar));
9398
12500
  registerMarketPanel(ctx, units);
12501
+ registerDebugFooter(ctx);
9399
12502
  registerConfigSyncSection(ctx);
9400
12503
  ctx.effect(() => {
9401
12504
  const workshop = workshopWorkspace();