@almadar/ui 6.4.0 → 6.6.0

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 (46) hide show
  1. package/dist/{EntityBindingContext-0Evn_LcT.d.cts → EntityBindingContext-Bn3ePJQC.d.cts} +1 -1
  2. package/dist/{EntityBindingContext-0Evn_LcT.d.ts → EntityBindingContext-Bn3ePJQC.d.ts} +1 -1
  3. package/dist/{GameAudioProvider-B48iXwz3.d.ts → GameAudioProvider-Ctceau1s.d.ts} +6 -18
  4. package/dist/{GameAudioProvider-CQAdPreB.d.cts → GameAudioProvider-Dk_Y3LN3.d.cts} +6 -18
  5. package/dist/avl/index.cjs +2755 -1532
  6. package/dist/avl/index.js +1710 -487
  7. package/dist/{avl-schema-parser-dvJKXn-o.d.ts → avl-schema-parser-DncJLEn9.d.ts} +18 -0
  8. package/dist/{avl-schema-parser-Bt4NzAam.d.cts → avl-schema-parser-FQ1474v8.d.cts} +18 -0
  9. package/dist/{cn-DJSBBm5W.d.cts → cn-CCjFspAo.d.cts} +25 -1
  10. package/dist/{cn-BbhJq_nr.d.ts → cn-sgpqpN0U.d.ts} +25 -1
  11. package/dist/components/index.cjs +2518 -1692
  12. package/dist/components/index.d.cts +178 -25
  13. package/dist/components/index.d.ts +178 -25
  14. package/dist/components/index.js +1500 -677
  15. package/dist/context/index.cjs +10 -13
  16. package/dist/context/index.js +10 -13
  17. package/dist/hooks/index.cjs +63 -13
  18. package/dist/hooks/index.d.cts +2 -2
  19. package/dist/hooks/index.d.ts +2 -2
  20. package/dist/hooks/index.js +64 -15
  21. package/dist/lib/drawable/three/index.cjs +126 -13
  22. package/dist/lib/drawable/three/index.d.cts +2 -2
  23. package/dist/lib/drawable/three/index.d.ts +2 -2
  24. package/dist/lib/drawable/three/index.js +127 -14
  25. package/dist/lib/index.cjs +180 -0
  26. package/dist/lib/index.d.cts +1 -1
  27. package/dist/lib/index.d.ts +1 -1
  28. package/dist/lib/index.js +178 -1
  29. package/dist/locales/index.cjs +6 -3
  30. package/dist/locales/index.js +6 -3
  31. package/dist/providers/index.cjs +2346 -1399
  32. package/dist/providers/index.d.cts +2 -2
  33. package/dist/providers/index.d.ts +2 -2
  34. package/dist/providers/index.js +1389 -442
  35. package/dist/runtime/index.cjs +2892 -1356
  36. package/dist/runtime/index.d.cts +78 -6
  37. package/dist/runtime/index.d.ts +78 -6
  38. package/dist/runtime/index.js +1974 -441
  39. package/dist/{useEventBus-CQWyAWpK.d.ts → useKeyboardRouter-D84cNWmA.d.ts} +31 -1
  40. package/dist/{useEventBus-Ckr4wqW3.d.cts → useKeyboardRouter-DQEE_9mq.d.cts} +31 -1
  41. package/locales/ar.json +2 -1
  42. package/locales/en.json +2 -1
  43. package/locales/sl.json +2 -1
  44. package/package.json +4 -4
  45. package/themes/comic.css +437 -0
  46. package/themes/index.css +1 -0
package/dist/avl/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
- import * as React95 from 'react';
3
- import React95__default, { createContext, useState, useMemo, useRef, useEffect, useContext, useCallback, Suspense, useLayoutEffect, Profiler, useReducer, useSyncExternalStore, lazy, useId } from 'react';
2
+ import * as React96 from 'react';
3
+ import React96__default, { createContext, useState, useEffect, useMemo, useRef, useContext, useCallback, Suspense, useLayoutEffect, Profiler, useReducer, useSyncExternalStore, lazy, useId } from 'react';
4
4
  import { getAllPages, matchPathAmong, CurrentPagePathProvider, NavStackProvider, OrbitalProvider, EventBusContext, useTraitScopeChain, useNavStack, ServerBridgeProvider, VerificationProvider, EntitySchemaProvider, OrbitalThemeProvider, useServerBridge, EntityBindingContext, useEntitySchema, RenderSlotProvider, useEntitySchemaOptional, useEntityBindingSnapshot, TraitScopeProvider, useTraitScope, useCurrentPagePath, useRenderSlot, useGameAudioContextOptional } from '@almadar/ui/providers';
5
5
  import { createLogger, setNamespaceLevel, isLogLevelEnabled } from '@almadar/logger';
6
6
  import ELK from 'elkjs/lib/elk.bundled.js';
@@ -3301,7 +3301,7 @@ var init_Typography = __esm({
3301
3301
  if (format !== void 0 && format !== "none" && (typeof body === "string" || typeof body === "number" || body instanceof Date)) {
3302
3302
  body = formatValue(body, format);
3303
3303
  }
3304
- return React95__default.createElement(
3304
+ return React96__default.createElement(
3305
3305
  Component,
3306
3306
  {
3307
3307
  id,
@@ -3647,7 +3647,7 @@ var init_Box = __esm({
3647
3647
  fixed: "fixed",
3648
3648
  sticky: "sticky"
3649
3649
  };
3650
- Box = React95__default.forwardRef(
3650
+ Box = React96__default.forwardRef(
3651
3651
  ({
3652
3652
  padding,
3653
3653
  paddingX,
@@ -3712,7 +3712,7 @@ var init_Box = __esm({
3712
3712
  onPointerDown?.(e);
3713
3713
  }, [hoverEvent, tapReveal, triggerProps, onPointerDown]);
3714
3714
  const isClickable = action || onClick;
3715
- return React95__default.createElement(
3715
+ return React96__default.createElement(
3716
3716
  Component,
3717
3717
  {
3718
3718
  ref,
@@ -3808,7 +3808,7 @@ var init_Stack = __esm({
3808
3808
  };
3809
3809
  const isHorizontal = direction === "horizontal";
3810
3810
  const directionClass = responsive && isHorizontal ? reverse ? "flex-col-reverse md:flex-row-reverse" : "flex-col md:flex-row" : isHorizontal ? reverse ? "flex-row-reverse" : "flex-row" : reverse ? "flex-col-reverse" : "flex-col";
3811
- return React95__default.createElement(
3811
+ return React96__default.createElement(
3812
3812
  Component,
3813
3813
  {
3814
3814
  className: cn(
@@ -4300,7 +4300,7 @@ var init_MiniStateMachine = __esm({
4300
4300
  const x = 2 + i * (NODE_W + GAP + ARROW_W + GAP);
4301
4301
  const tc = transitionCounts[s.name] ?? 0;
4302
4302
  const role = getStateRole(s.name, s.isInitial ?? void 0, s.isTerminal ?? void 0, tc, maxTC);
4303
- return /* @__PURE__ */ jsxs(React95__default.Fragment, { children: [
4303
+ return /* @__PURE__ */ jsxs(React96__default.Fragment, { children: [
4304
4304
  /* @__PURE__ */ jsx(
4305
4305
  AvlState,
4306
4306
  {
@@ -4583,7 +4583,7 @@ function resolveMarkerExpression(expression, entity, config, state) {
4583
4583
  function isPlainObject(value) {
4584
4584
  if (value === null || value === void 0 || typeof value !== "object") return false;
4585
4585
  if (Array.isArray(value)) return false;
4586
- if (React95__default.isValidElement(value)) return false;
4586
+ if (React96__default.isValidElement(value)) return false;
4587
4587
  if (value instanceof Date) return false;
4588
4588
  if (typeof value === "function") return false;
4589
4589
  return true;
@@ -4592,7 +4592,7 @@ function isEvaluatorResolvedData(value) {
4592
4592
  return evaluatorResolvedData.has(value);
4593
4593
  }
4594
4594
  function brandResolved(value) {
4595
- if (value !== null && typeof value === "object" && !React95__default.isValidElement(value) && !(value instanceof Date)) {
4595
+ if (value !== null && typeof value === "object" && !React96__default.isValidElement(value) && !(value instanceof Date)) {
4596
4596
  resolvedMarkerFree.add(value);
4597
4597
  }
4598
4598
  }
@@ -4625,7 +4625,7 @@ function walkValue(value, scopeTrait, entity, config, state) {
4625
4625
  }
4626
4626
  const resolved = resolveMarkerExpression(value.expression, entity, config, state);
4627
4627
  markerResolutionCache.set(value, { entity, config, state, resolved });
4628
- if (resolved !== null && typeof resolved === "object" && !React95__default.isValidElement(resolved) && !(resolved instanceof Date)) {
4628
+ if (resolved !== null && typeof resolved === "object" && !React96__default.isValidElement(resolved) && !(resolved instanceof Date)) {
4629
4629
  resolvedMarkerFree.add(resolved);
4630
4630
  evaluatorResolvedData.add(resolved);
4631
4631
  }
@@ -4876,7 +4876,7 @@ var init_Icon = __esm({
4876
4876
  const effectiveName = typeof icon === "string" && icon !== "" ? icon : name;
4877
4877
  const effectiveStrokeWidth = strokeWidth != null && strokeWidth > 0 ? strokeWidth : void 0;
4878
4878
  const family = useIconFamily();
4879
- const RenderedComponent = React95__default.useMemo(() => {
4879
+ const RenderedComponent = React96__default.useMemo(() => {
4880
4880
  if (directIcon) return null;
4881
4881
  return effectiveName ? resolveIconForFamily(effectiveName) : null;
4882
4882
  }, [directIcon, effectiveName, family]);
@@ -5005,7 +5005,7 @@ var init_atlasSlice = __esm({
5005
5005
  }
5006
5006
  });
5007
5007
  function useAtlasSliceDataUrl(asset) {
5008
- const [, bump] = React95.useReducer((x) => x + 1, 0);
5008
+ const [, bump] = React96.useReducer((x) => x + 1, 0);
5009
5009
  if (!isAtlasAsset(asset)) return void 0;
5010
5010
  const key = `${asset.atlas}#${asset.sprite}`;
5011
5011
  const cached = sliceDataUrlCache.get(key);
@@ -5068,13 +5068,13 @@ function AtlasImage({
5068
5068
  style,
5069
5069
  "aria-hidden": ariaHidden
5070
5070
  }) {
5071
- const [, bump] = React95.useReducer((x) => x + 1, 0);
5072
- const canvasRef = React95.useRef(null);
5071
+ const [, bump] = React96.useReducer((x) => x + 1, 0);
5072
+ const canvasRef = React96.useRef(null);
5073
5073
  const sliced = isAtlasAsset(asset);
5074
5074
  const atlas = sliced ? getAtlas(asset.atlas, bump) : void 0;
5075
5075
  const img = sliced && asset?.url ? getSheetImage(asset.url, bump) : null;
5076
5076
  const rect = sliced && atlas ? subRectFor(atlas, asset.sprite) : null;
5077
- React95.useEffect(() => {
5077
+ React96.useEffect(() => {
5078
5078
  const canvas = canvasRef.current;
5079
5079
  if (!canvas || !img || !rect) return;
5080
5080
  canvas.width = rect.sw;
@@ -5150,7 +5150,7 @@ function resolveIconProp(value, sizeClass) {
5150
5150
  const IconComp = value;
5151
5151
  return /* @__PURE__ */ jsx(IconComp, { className: sizeClass });
5152
5152
  }
5153
- if (React95__default.isValidElement(value)) {
5153
+ if (React96__default.isValidElement(value)) {
5154
5154
  return value;
5155
5155
  }
5156
5156
  if (typeof value === "object" && value !== null && isIconLike(value)) {
@@ -5227,7 +5227,7 @@ var init_Button = __esm({
5227
5227
  md: "h-icon-default w-icon-default",
5228
5228
  lg: "h-icon-default w-icon-default"
5229
5229
  };
5230
- Button = React95__default.forwardRef(
5230
+ Button = React96__default.forwardRef(
5231
5231
  ({
5232
5232
  className,
5233
5233
  variant = "primary",
@@ -5297,7 +5297,7 @@ var Dialog;
5297
5297
  var init_Dialog = __esm({
5298
5298
  "components/core/atoms/Dialog.tsx"() {
5299
5299
  init_cn();
5300
- Dialog = React95__default.forwardRef(
5300
+ Dialog = React96__default.forwardRef(
5301
5301
  ({
5302
5302
  role = "dialog",
5303
5303
  "aria-modal": ariaModal = true,
@@ -5859,7 +5859,7 @@ var init_Badge = __esm({
5859
5859
  md: "px-2.5 py-1 text-sm",
5860
5860
  lg: "px-3 py-1.5 text-base"
5861
5861
  };
5862
- Badge = React95__default.forwardRef(
5862
+ Badge = React96__default.forwardRef(
5863
5863
  ({ className, variant = "default", size = "sm", amount, label, icon, iconAsset, children, onRemove, removeLabel, ...props }, ref) => {
5864
5864
  const iconSizes3 = {
5865
5865
  sm: "h-icon-default w-icon-default",
@@ -6209,7 +6209,7 @@ var init_SvgFlow = __esm({
6209
6209
  width = 100,
6210
6210
  height = 100
6211
6211
  }) => {
6212
- const markerId = React95__default.useMemo(() => {
6212
+ const markerId = React96__default.useMemo(() => {
6213
6213
  flowIdCounter += 1;
6214
6214
  return `almadar-flow-arrow-${flowIdCounter}`;
6215
6215
  }, []);
@@ -6802,7 +6802,7 @@ var init_SvgRing = __esm({
6802
6802
  width = 100,
6803
6803
  height = 100
6804
6804
  }) => {
6805
- const gradientId = React95__default.useMemo(() => {
6805
+ const gradientId = React96__default.useMemo(() => {
6806
6806
  ringIdCounter += 1;
6807
6807
  return `almadar-ring-glow-${ringIdCounter}`;
6808
6808
  }, []);
@@ -6983,7 +6983,7 @@ var init_Input = __esm({
6983
6983
  init_cn();
6984
6984
  init_Icon();
6985
6985
  init_useEventBus();
6986
- Input = React95__default.forwardRef(
6986
+ Input = React96__default.forwardRef(
6987
6987
  ({
6988
6988
  className,
6989
6989
  inputType,
@@ -7007,9 +7007,9 @@ var init_Input = __esm({
7007
7007
  const eventBus = useEventBus();
7008
7008
  const type = inputType || htmlType || "text";
7009
7009
  const isDeclarative = typeof onChange === "string";
7010
- const [localValue, setLocalValue] = React95__default.useState(value);
7011
- const pendingEchoRef = React95__default.useRef(/* @__PURE__ */ new Set());
7012
- React95__default.useEffect(() => {
7010
+ const [localValue, setLocalValue] = React96__default.useState(value);
7011
+ const pendingEchoRef = React96__default.useRef(/* @__PURE__ */ new Set());
7012
+ React96__default.useEffect(() => {
7013
7013
  if (!isDeclarative) return;
7014
7014
  const incoming = value == null ? "" : String(value);
7015
7015
  if (pendingEchoRef.current.has(incoming)) {
@@ -7176,7 +7176,7 @@ var Label;
7176
7176
  var init_Label = __esm({
7177
7177
  "components/core/atoms/Label.tsx"() {
7178
7178
  init_cn();
7179
- Label = React95__default.forwardRef(
7179
+ Label = React96__default.forwardRef(
7180
7180
  ({ className, required, children, ...props }, ref) => {
7181
7181
  return /* @__PURE__ */ jsxs(
7182
7182
  "label",
@@ -7203,7 +7203,7 @@ var init_Textarea = __esm({
7203
7203
  "components/core/atoms/Textarea.tsx"() {
7204
7204
  init_cn();
7205
7205
  init_useEventBus();
7206
- Textarea = React95__default.forwardRef(
7206
+ Textarea = React96__default.forwardRef(
7207
7207
  ({ className, error, onChange, ...props }, ref) => {
7208
7208
  const eventBus = useEventBus();
7209
7209
  const handleChange = (e) => {
@@ -7453,7 +7453,7 @@ var init_Select = __esm({
7453
7453
  init_cn();
7454
7454
  init_Icon();
7455
7455
  init_useEventBus();
7456
- Select = React95__default.forwardRef(
7456
+ Select = React96__default.forwardRef(
7457
7457
  (props, _ref) => {
7458
7458
  const { multiple, searchable, clearable } = props;
7459
7459
  if (multiple || searchable || clearable) {
@@ -7470,7 +7470,7 @@ var init_Checkbox = __esm({
7470
7470
  "components/core/atoms/Checkbox.tsx"() {
7471
7471
  init_cn();
7472
7472
  init_useEventBus();
7473
- Checkbox = React95__default.forwardRef(
7473
+ Checkbox = React96__default.forwardRef(
7474
7474
  ({ className, label, id, onChange, ...props }, ref) => {
7475
7475
  const inputId = id || `checkbox-${Math.random().toString(36).substr(2, 9)}`;
7476
7476
  const eventBus = useEventBus();
@@ -7524,7 +7524,7 @@ var init_Spinner = __esm({
7524
7524
  md: "h-6 w-6",
7525
7525
  lg: "h-8 w-8"
7526
7526
  };
7527
- Spinner = React95__default.forwardRef(
7527
+ Spinner = React96__default.forwardRef(
7528
7528
  ({ className, size = "md", overlay, ...props }, ref) => {
7529
7529
  if (overlay) {
7530
7530
  return /* @__PURE__ */ jsx(
@@ -7614,7 +7614,7 @@ var init_Card = __esm({
7614
7614
  chip: "shadow-none rounded-pill border-[length:var(--border-width)] border-border",
7615
7615
  "tile-image-first": "p-0 overflow-hidden"
7616
7616
  };
7617
- Card = React95__default.forwardRef(
7617
+ Card = React96__default.forwardRef(
7618
7618
  ({
7619
7619
  className,
7620
7620
  variant = "bordered",
@@ -7663,9 +7663,9 @@ var init_Card = __esm({
7663
7663
  }
7664
7664
  );
7665
7665
  Card.displayName = "Card";
7666
- CardHeader = React95__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("mb-4", className), ...props }));
7666
+ CardHeader = React96__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("mb-4", className), ...props }));
7667
7667
  CardHeader.displayName = "CardHeader";
7668
- CardTitle = React95__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
7668
+ CardTitle = React96__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
7669
7669
  "h3",
7670
7670
  {
7671
7671
  ref,
@@ -7678,11 +7678,11 @@ var init_Card = __esm({
7678
7678
  }
7679
7679
  ));
7680
7680
  CardTitle.displayName = "CardTitle";
7681
- CardContent = React95__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("", className), ...props }));
7681
+ CardContent = React96__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("", className), ...props }));
7682
7682
  CardContent.displayName = "CardContent";
7683
7683
  CardBody = CardContent;
7684
7684
  CardBody.displayName = "CardBody";
7685
- CardFooter = React95__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
7685
+ CardFooter = React96__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
7686
7686
  "div",
7687
7687
  {
7688
7688
  ref,
@@ -7769,7 +7769,7 @@ var init_FilterPill = __esm({
7769
7769
  md: "w-3.5 h-3.5",
7770
7770
  lg: "w-4 h-4"
7771
7771
  };
7772
- FilterPill = React95__default.forwardRef(
7772
+ FilterPill = React96__default.forwardRef(
7773
7773
  ({
7774
7774
  className,
7775
7775
  variant = "default",
@@ -7898,8 +7898,8 @@ var init_Avatar = __esm({
7898
7898
  actionPayload
7899
7899
  }) => {
7900
7900
  const eventBus = useEventBus();
7901
- const [imgFailed, setImgFailed] = React95__default.useState(false);
7902
- React95__default.useEffect(() => {
7901
+ const [imgFailed, setImgFailed] = React96__default.useState(false);
7902
+ React96__default.useEffect(() => {
7903
7903
  setImgFailed(false);
7904
7904
  }, [src]);
7905
7905
  const initials = providedInitials ?? (name ? generateInitials(name) : void 0);
@@ -8012,7 +8012,7 @@ var init_Center = __esm({
8012
8012
  as: Component = "div"
8013
8013
  }) => {
8014
8014
  const mergedStyle = minHeight ? { minHeight, ...style } : style;
8015
- return React95__default.createElement(Component, {
8015
+ return React96__default.createElement(Component, {
8016
8016
  className: cn(
8017
8017
  inline ? "inline-flex" : "flex",
8018
8018
  horizontal && "justify-center",
@@ -8280,7 +8280,7 @@ var init_Radio = __esm({
8280
8280
  md: "w-2.5 h-2.5",
8281
8281
  lg: "w-3 h-3"
8282
8282
  };
8283
- Radio = React95__default.forwardRef(
8283
+ Radio = React96__default.forwardRef(
8284
8284
  ({
8285
8285
  label,
8286
8286
  helperText,
@@ -8297,12 +8297,12 @@ var init_Radio = __esm({
8297
8297
  onChange,
8298
8298
  ...props
8299
8299
  }, ref) => {
8300
- const reactId = React95__default.useId();
8300
+ const reactId = React96__default.useId();
8301
8301
  const baseId = id || `radio-${reactId}`;
8302
8302
  const hasError = !!error;
8303
8303
  const eventBus = useEventBus();
8304
- const [selected, setSelected] = React95__default.useState(value);
8305
- React95__default.useEffect(() => {
8304
+ const [selected, setSelected] = React96__default.useState(value);
8305
+ React96__default.useEffect(() => {
8306
8306
  if (value !== void 0) setSelected(value);
8307
8307
  }, [value]);
8308
8308
  const pick = (next, e) => {
@@ -8484,7 +8484,7 @@ var init_Switch = __esm({
8484
8484
  "components/core/atoms/Switch.tsx"() {
8485
8485
  "use client";
8486
8486
  init_cn();
8487
- Switch = React95.forwardRef(
8487
+ Switch = React96.forwardRef(
8488
8488
  ({
8489
8489
  checked,
8490
8490
  defaultChecked = false,
@@ -8495,10 +8495,10 @@ var init_Switch = __esm({
8495
8495
  name,
8496
8496
  className
8497
8497
  }, ref) => {
8498
- const [isChecked, setIsChecked] = React95.useState(
8498
+ const [isChecked, setIsChecked] = React96.useState(
8499
8499
  checked !== void 0 ? checked : defaultChecked
8500
8500
  );
8501
- React95.useEffect(() => {
8501
+ React96.useEffect(() => {
8502
8502
  if (checked !== void 0) {
8503
8503
  setIsChecked(checked);
8504
8504
  }
@@ -8776,7 +8776,7 @@ var Aside;
8776
8776
  var init_Aside = __esm({
8777
8777
  "components/core/atoms/Aside.tsx"() {
8778
8778
  init_cn();
8779
- Aside = React95__default.forwardRef(
8779
+ Aside = React96__default.forwardRef(
8780
8780
  ({ className, children, ...rest }, ref) => /* @__PURE__ */ jsx("aside", { ref, className: cn(className), ...rest, children })
8781
8781
  );
8782
8782
  Aside.displayName = "Aside";
@@ -8855,9 +8855,9 @@ var init_LawReferenceTooltip = __esm({
8855
8855
  className
8856
8856
  }) => {
8857
8857
  const { t } = useTranslate();
8858
- const [isVisible, setIsVisible] = React95__default.useState(false);
8859
- const timeoutRef = React95__default.useRef(null);
8860
- const triggerRef = React95__default.useRef(null);
8858
+ const [isVisible, setIsVisible] = React96__default.useState(false);
8859
+ const timeoutRef = React96__default.useRef(null);
8860
+ const triggerRef = React96__default.useRef(null);
8861
8861
  const handleMouseEnter = () => {
8862
8862
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
8863
8863
  timeoutRef.current = setTimeout(() => setIsVisible(true), 200);
@@ -8868,7 +8868,7 @@ var init_LawReferenceTooltip = __esm({
8868
8868
  };
8869
8869
  const { revealed, triggerProps } = useTapReveal({ refs: [triggerRef] });
8870
8870
  const open = isVisible || revealed;
8871
- React95__default.useEffect(() => {
8871
+ React96__default.useEffect(() => {
8872
8872
  return () => {
8873
8873
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
8874
8874
  };
@@ -9078,7 +9078,7 @@ var init_StatusDot = __esm({
9078
9078
  md: "w-2.5 h-2.5",
9079
9079
  lg: "w-3 h-3"
9080
9080
  };
9081
- StatusDot = React95__default.forwardRef(
9081
+ StatusDot = React96__default.forwardRef(
9082
9082
  ({ className, status = "offline", pulse = false, size = "md", label, ...props }, ref) => {
9083
9083
  return /* @__PURE__ */ jsx(
9084
9084
  "span",
@@ -9132,7 +9132,7 @@ var init_TrendIndicator = __esm({
9132
9132
  down: "trending-down",
9133
9133
  flat: "arrow-right"
9134
9134
  };
9135
- TrendIndicator = React95__default.forwardRef(
9135
+ TrendIndicator = React96__default.forwardRef(
9136
9136
  ({
9137
9137
  className,
9138
9138
  value,
@@ -9201,7 +9201,7 @@ var init_RangeSlider = __esm({
9201
9201
  md: "w-4 h-4",
9202
9202
  lg: "w-5 h-5"
9203
9203
  };
9204
- RangeSlider = React95__default.forwardRef(
9204
+ RangeSlider = React96__default.forwardRef(
9205
9205
  ({
9206
9206
  className,
9207
9207
  min = 0,
@@ -9858,7 +9858,7 @@ var init_ContentSection = __esm({
9858
9858
  md: "py-16",
9859
9859
  lg: "py-24"
9860
9860
  };
9861
- ContentSection = React95__default.forwardRef(
9861
+ ContentSection = React96__default.forwardRef(
9862
9862
  ({ children, background = "default", padding = "lg", id, className }, ref) => {
9863
9863
  return /* @__PURE__ */ jsx(
9864
9864
  Box,
@@ -10392,7 +10392,7 @@ var init_AnimatedReveal = __esm({
10392
10392
  "scale-up": { opacity: 1, transform: "scale(1) translateY(0)" },
10393
10393
  "none": {}
10394
10394
  };
10395
- AnimatedReveal = React95__default.forwardRef(
10395
+ AnimatedReveal = React96__default.forwardRef(
10396
10396
  ({
10397
10397
  trigger = "scroll",
10398
10398
  animation = "fade-up",
@@ -10552,7 +10552,7 @@ var init_AnimatedGraphic = __esm({
10552
10552
  "components/marketing/atoms/AnimatedGraphic.tsx"() {
10553
10553
  "use client";
10554
10554
  init_cn();
10555
- AnimatedGraphic = React95__default.forwardRef(
10555
+ AnimatedGraphic = React96__default.forwardRef(
10556
10556
  ({
10557
10557
  src,
10558
10558
  svgContent,
@@ -10575,7 +10575,7 @@ var init_AnimatedGraphic = __esm({
10575
10575
  const fetchedSvg = useFetchedSvg(svgContent ? void 0 : src);
10576
10576
  const resolvedSvg = svgContent ?? fetchedSvg;
10577
10577
  const prevAnimateRef = useRef(animate);
10578
- const setRef = React95__default.useCallback(
10578
+ const setRef = React96__default.useCallback(
10579
10579
  (node) => {
10580
10580
  containerRef.current = node;
10581
10581
  if (typeof ref === "function") ref(node);
@@ -11327,9 +11327,9 @@ function ControlButton({
11327
11327
  className
11328
11328
  }) {
11329
11329
  const eventBus = useEventBus();
11330
- const [isPressed, setIsPressed] = React95.useState(false);
11330
+ const [isPressed, setIsPressed] = React96.useState(false);
11331
11331
  const actualPressed = pressed ?? isPressed;
11332
- const handlePointerDown = React95.useCallback(
11332
+ const handlePointerDown = React96.useCallback(
11333
11333
  (e) => {
11334
11334
  e.preventDefault();
11335
11335
  if (disabled) return;
@@ -11339,7 +11339,7 @@ function ControlButton({
11339
11339
  },
11340
11340
  [disabled, pressEvent, eventBus, onPress]
11341
11341
  );
11342
- const handlePointerUp = React95.useCallback(
11342
+ const handlePointerUp = React96.useCallback(
11343
11343
  (e) => {
11344
11344
  e.preventDefault();
11345
11345
  if (disabled) return;
@@ -11349,7 +11349,7 @@ function ControlButton({
11349
11349
  },
11350
11350
  [disabled, releaseEvent, eventBus, onRelease]
11351
11351
  );
11352
- const handlePointerLeave = React95.useCallback(
11352
+ const handlePointerLeave = React96.useCallback(
11353
11353
  (e) => {
11354
11354
  if (isPressed) {
11355
11355
  setIsPressed(false);
@@ -11608,18 +11608,18 @@ function ControlGrid({
11608
11608
  className
11609
11609
  }) {
11610
11610
  const eventBus = useEventBus();
11611
- const [active, setActive] = React95.useState(/* @__PURE__ */ new Set());
11612
- const [coarse, setCoarse] = React95.useState(
11611
+ const [active, setActive] = React96.useState(/* @__PURE__ */ new Set());
11612
+ const [coarse, setCoarse] = React96.useState(
11613
11613
  () => typeof window !== "undefined" && window.matchMedia("(pointer: coarse)").matches
11614
11614
  );
11615
- React95.useEffect(() => {
11615
+ React96.useEffect(() => {
11616
11616
  if (visibility !== "auto" || typeof window === "undefined") return;
11617
11617
  const mq = window.matchMedia("(pointer: coarse)");
11618
11618
  const onChange = (e) => setCoarse(e.matches);
11619
11619
  mq.addEventListener("change", onChange);
11620
11620
  return () => mq.removeEventListener("change", onChange);
11621
11621
  }, [visibility]);
11622
- const handlePress = React95.useCallback(
11622
+ const handlePress = React96.useCallback(
11623
11623
  (id) => {
11624
11624
  setActive((prev) => new Set(prev).add(id));
11625
11625
  if (actionEvent) eventBus.emit(`UI:${actionEvent}`, { id, pressed: true });
@@ -11633,7 +11633,7 @@ function ControlGrid({
11633
11633
  },
11634
11634
  [kind, actionEvent, directionEvent, directionEvents, eventBus, onAction, onDirection]
11635
11635
  );
11636
- const handleRelease = React95.useCallback(
11636
+ const handleRelease = React96.useCallback(
11637
11637
  (id) => {
11638
11638
  setActive((prev) => {
11639
11639
  const next = new Set(prev);
@@ -11996,7 +11996,7 @@ function GameMenu({
11996
11996
  }) {
11997
11997
  const resolvedOptions = (options?.length ? options : void 0) ?? (menuItems?.length ? menuItems : void 0) ?? DEFAULT_MENU_OPTIONS;
11998
11998
  const eventBus = useEventBus();
11999
- const handleOptionClick = React95.useCallback(
11999
+ const handleOptionClick = React96.useCallback(
12000
12000
  (option) => {
12001
12001
  if (option.event) {
12002
12002
  eventBus.emit(`UI:${option.event}`, { option });
@@ -12232,7 +12232,7 @@ function StateGraph({
12232
12232
  }) {
12233
12233
  const eventBus = useEventBus();
12234
12234
  const nodes = states ?? [];
12235
- const positions = React95.useMemo(() => layoutStates(nodes, width, height), [nodes, width, height]);
12235
+ const positions = React96.useMemo(() => layoutStates(nodes, width, height), [nodes, width, height]);
12236
12236
  return /* @__PURE__ */ jsxs(
12237
12237
  Box,
12238
12238
  {
@@ -12303,8 +12303,8 @@ function MiniMap({
12303
12303
  tileAssets,
12304
12304
  unitAssets
12305
12305
  }) {
12306
- const canvasRef = React95.useRef(null);
12307
- const imgCacheRef = React95.useRef(/* @__PURE__ */ new Map());
12306
+ const canvasRef = React96.useRef(null);
12307
+ const imgCacheRef = React96.useRef(/* @__PURE__ */ new Map());
12308
12308
  function loadImg(url) {
12309
12309
  const cached = imgCacheRef.current.get(url);
12310
12310
  if (cached) return cached.complete ? cached : null;
@@ -12320,7 +12320,7 @@ function MiniMap({
12320
12320
  imgCacheRef.current.set(url, img);
12321
12321
  return null;
12322
12322
  }
12323
- React95.useEffect(() => {
12323
+ React96.useEffect(() => {
12324
12324
  const canvas = canvasRef.current;
12325
12325
  if (!canvas) return;
12326
12326
  const ctx = canvas.getContext("2d");
@@ -13711,7 +13711,7 @@ function collectDrawnItems(nodes) {
13711
13711
  for (const n of nodes) {
13712
13712
  switch (n.type) {
13713
13713
  case "draw-sprite":
13714
- if (isValidScenePos(n.position)) out.push({ pos: n.position, id: n.id, anchor: n.anchor, width: n.width, height: n.height });
13714
+ if (isValidScenePos(n.position)) out.push({ pos: n.position, id: n.id, anchor: n.anchor, width: n.width, height: n.height, rotation: n.rotation });
13715
13715
  break;
13716
13716
  case "draw-shape":
13717
13717
  case "draw-text":
@@ -13721,7 +13721,7 @@ function collectDrawnItems(nodes) {
13721
13721
  break;
13722
13722
  case "draw-sprite-layer":
13723
13723
  for (const it of n.items) {
13724
- if (isValidScenePos(it.position)) out.push({ pos: it.position, id: it.id, anchor: it.anchor, width: it.width, height: it.height });
13724
+ if (isValidScenePos(it.position)) out.push({ pos: it.position, id: it.id, anchor: it.anchor, width: it.width, height: it.height, rotation: it.rotation });
13725
13725
  }
13726
13726
  break;
13727
13727
  case "draw-shape-layer":
@@ -13741,15 +13741,39 @@ function buildHitIndex(items) {
13741
13741
  }
13742
13742
  return m;
13743
13743
  }
13744
+ function withPreviewPosition(nodes, id, pos) {
13745
+ return nodes.map((n) => {
13746
+ if (n.type === "draw-sprite-layer" || n.type === "draw-shape-layer" || n.type === "draw-text-layer") {
13747
+ if (!n.items.some((it) => it.id === id)) return n;
13748
+ return { ...n, items: n.items.map((it) => it.id === id ? { ...it, position: pos } : it) };
13749
+ }
13750
+ if (n.type === "draw-group") {
13751
+ if (!Array.isArray(n.items)) return n;
13752
+ return { ...n, items: withPreviewPosition(n.items, id, pos) };
13753
+ }
13754
+ if (n.id === id && "position" in n) {
13755
+ return { ...n, position: pos };
13756
+ }
13757
+ return n;
13758
+ });
13759
+ }
13744
13760
  function hitTestSprites(items, projector, point) {
13745
13761
  for (let i = items.length - 1; i >= 0; i--) {
13746
13762
  const it = items[i];
13747
13763
  if (it.id === void 0) continue;
13748
13764
  const r2 = spriteRect(projector, { position: it.pos, anchor: it.anchor, width: it.width, height: it.height });
13749
- if (point.x >= r2.x && point.x <= r2.x + r2.w && point.y >= r2.y && point.y <= r2.y + r2.h) return it.id;
13765
+ const test = it.rotation ? rotatePoint(point, { x: r2.x + r2.w / 2, y: r2.y + r2.h / 2 }, -it.rotation) : point;
13766
+ if (test.x >= r2.x && test.x <= r2.x + r2.w && test.y >= r2.y && test.y <= r2.y + r2.h) return it.id;
13750
13767
  }
13751
13768
  return void 0;
13752
13769
  }
13770
+ function rotatePoint(p, center, radians) {
13771
+ const cos = Math.cos(radians);
13772
+ const sin = Math.sin(radians);
13773
+ const dx = p.x - center.x;
13774
+ const dy = p.y - center.y;
13775
+ return { x: center.x + dx * cos - dy * sin, y: center.y + dx * sin + dy * cos };
13776
+ }
13753
13777
  var init_hitTest = __esm({
13754
13778
  "lib/drawable/hitTest.ts"() {
13755
13779
  init_contract();
@@ -13758,6 +13782,41 @@ var init_hitTest = __esm({
13758
13782
  function normalizeBackdrop(bg) {
13759
13783
  return typeof bg === "string" ? { url: bg, role: "decoration", category: "background" } : bg;
13760
13784
  }
13785
+ function selectionOverlayNodes(projector, item) {
13786
+ const r2 = spriteRect(projector, { position: item.pos, anchor: item.anchor, width: item.width, height: item.height });
13787
+ const tw = projector.tileWidth;
13788
+ const cellTopLeft = projector.anchorPoint(item.pos, "top-left");
13789
+ const offsetX = (r2.x - cellTopLeft.x) / tw;
13790
+ const offsetY = (r2.y - cellTopLeft.y) / tw;
13791
+ const width = r2.w / tw;
13792
+ const height = r2.h / tw;
13793
+ const handle = EDIT_HANDLE_SIZE_PX / tw;
13794
+ const ring = {
13795
+ type: "draw-shape",
13796
+ shape: "rect",
13797
+ position: item.pos,
13798
+ anchor: "top-left",
13799
+ offsetX,
13800
+ offsetY,
13801
+ width,
13802
+ height,
13803
+ stroke: EDIT_SELECTION_COLOR,
13804
+ strokeWidth: 2,
13805
+ fill: "none"
13806
+ };
13807
+ const handles = EDIT_SELECTION_CORNERS.map(([cx, cy]) => ({
13808
+ type: "draw-shape",
13809
+ shape: "rect",
13810
+ position: item.pos,
13811
+ anchor: "top-left",
13812
+ offsetX: offsetX + cx * width - handle / 2,
13813
+ offsetY: offsetY + cy * height - handle / 2,
13814
+ width: handle,
13815
+ height: handle,
13816
+ fill: EDIT_SELECTION_COLOR
13817
+ }));
13818
+ return [ring, ...handles];
13819
+ }
13761
13820
  function Canvas2D({
13762
13821
  className,
13763
13822
  isLoading = false,
@@ -13771,6 +13830,12 @@ function Canvas2D({
13771
13830
  tileLeaveEvent,
13772
13831
  keyMap,
13773
13832
  keyUpMap,
13833
+ editable = false,
13834
+ selectedId = null,
13835
+ onSelect,
13836
+ onMove,
13837
+ selectEvent,
13838
+ moveEvent,
13774
13839
  camera = "pan-zoom",
13775
13840
  scale = 0.4,
13776
13841
  tileWidth,
@@ -13787,7 +13852,7 @@ function Canvas2D({
13787
13852
  const registerChildDrawable = useCallback((node) => {
13788
13853
  childDrawablesRef.current.push(node);
13789
13854
  }, []);
13790
- const hasJsxChildren = React95.Children.count(children) > 0;
13855
+ const hasJsxChildren = React96.Children.count(children) > 0;
13791
13856
  function isDrawableLayer(node) {
13792
13857
  return node.type === "draw-sprite-layer" || node.type === "draw-shape-layer" || node.type === "draw-text-layer";
13793
13858
  }
@@ -14028,10 +14093,22 @@ function Canvas2D({
14028
14093
  painter.scale(cam.zoom, cam.zoom);
14029
14094
  painter.translate(-viewportSize.width / 2 - cam.x, -viewportSize.height / 2 - cam.y);
14030
14095
  const dctx = { projector, time: timeMs, invalidate: bumpAtlas };
14031
- for (const node of drawables) paintDrawable(painter, node, dctx);
14096
+ let paintNodes = drawables;
14097
+ if (editable) {
14098
+ const drag = editDragRef.current;
14099
+ if (drag && drag.moved) {
14100
+ paintNodes = withPreviewPosition(paintNodes, drag.id, { x: drag.previewX, y: drag.previewY });
14101
+ }
14102
+ const selectedItem = selectedId != null ? drawnItems.find((it) => it.id === selectedId) : void 0;
14103
+ if (selectedItem) {
14104
+ const overlaySource = drag && drag.moved && drag.id === selectedId ? { ...selectedItem, pos: { x: drag.previewX, y: drag.previewY } } : selectedItem;
14105
+ paintNodes = [...paintNodes, ...selectionOverlayNodes(projector, overlaySource)];
14106
+ }
14107
+ }
14108
+ for (const node of paintNodes) paintDrawable(painter, node, dctx);
14032
14109
  painter.restore();
14033
- scheduleAnimation(drawables);
14034
- }, [viewportSize, backgroundImage, bgColor, drawables, projector, cameraRef, bumpAtlas, getImage, cameraPos, defaultGridFocus, camera, dragDistance]);
14110
+ scheduleAnimation(paintNodes);
14111
+ }, [viewportSize, backgroundImage, bgColor, drawables, projector, cameraRef, bumpAtlas, getImage, cameraPos, defaultGridFocus, camera, dragDistance, editable, selectedId, drawnItems]);
14035
14112
  useEffect(() => {
14036
14113
  drawTimeRef.current = draw;
14037
14114
  }, [draw]);
@@ -14076,23 +14153,83 @@ function Canvas2D({
14076
14153
  };
14077
14154
  }, [camera, followTarget, lerpToTarget, draw]);
14078
14155
  const singlePointerActiveRef = useRef(false);
14156
+ const editDragRef = useRef(null);
14157
+ const pointerToScene = useCallback((clientX, clientY) => {
14158
+ const canvas = canvasRef.current;
14159
+ if (!canvas) return { x: 0, y: 0 };
14160
+ const world = screenToWorld(clientX, clientY, canvas, viewportSize);
14161
+ const adjustedX = world.x - scaledTileWidth / 2;
14162
+ const adjustedY = squareGrid ? world.y - scaledTileWidth / 2 : world.y - scaledDiamondTopY - scaledFloorHeight / 2;
14163
+ return unproject(adjustedX, adjustedY);
14164
+ }, [screenToWorld, viewportSize, scaledTileWidth, squareGrid, scaledDiamondTopY, scaledFloorHeight, unproject]);
14079
14165
  const handleCanvasPointerDown = useCallback((e) => {
14080
14166
  singlePointerActiveRef.current = true;
14167
+ if (editable) {
14168
+ if (!canvasRef.current) return;
14169
+ const world = screenToWorld(e.clientX, e.clientY, canvasRef.current, viewportSize);
14170
+ const hitId = hitTestSprites(drawnItems, projector, world);
14171
+ if (hitId === void 0) return;
14172
+ const item = [...drawnItems].reverse().find((it) => it.id === hitId);
14173
+ if (!item) return;
14174
+ editDragRef.current = {
14175
+ id: hitId,
14176
+ pointerId: e.pointerId,
14177
+ startClientX: e.clientX,
14178
+ startClientY: e.clientY,
14179
+ startSceneX: item.pos.x,
14180
+ startSceneY: item.pos.y,
14181
+ moved: false,
14182
+ previewX: item.pos.x,
14183
+ previewY: item.pos.y
14184
+ };
14185
+ return;
14186
+ }
14081
14187
  if (enableCamera) handlePointerDown(e);
14082
- }, [enableCamera, handlePointerDown]);
14188
+ }, [editable, screenToWorld, viewportSize, drawnItems, projector, enableCamera, handlePointerDown]);
14083
14189
  const handleCanvasPointerMove = useCallback((e) => {
14190
+ if (editable) {
14191
+ const drag = editDragRef.current;
14192
+ if (!drag || drag.pointerId !== e.pointerId) return;
14193
+ const dxPx = e.clientX - drag.startClientX;
14194
+ const dyPx = e.clientY - drag.startClientY;
14195
+ if (!drag.moved && Math.abs(dxPx) + Math.abs(dyPx) <= 5) return;
14196
+ drag.moved = true;
14197
+ const nowScene = pointerToScene(e.clientX, e.clientY);
14198
+ const startScene = pointerToScene(drag.startClientX, drag.startClientY);
14199
+ drag.previewX = drag.startSceneX + (nowScene.x - startScene.x);
14200
+ drag.previewY = drag.startSceneY + (nowScene.y - startScene.y);
14201
+ draw();
14202
+ return;
14203
+ }
14084
14204
  if (enableCamera) handlePointerMove(e, () => draw());
14085
- }, [enableCamera, handlePointerMove, draw]);
14205
+ }, [editable, pointerToScene, draw, enableCamera, handlePointerMove]);
14086
14206
  const handleCanvasHover = useCallback((e) => {
14087
14207
  if (singlePointerActiveRef.current) return;
14088
14208
  if (!tileHoverEvent || !canvasRef.current) return;
14089
- const world = screenToWorld(e.clientX, e.clientY, canvasRef.current, viewportSize);
14090
- const adjustedX = world.x - scaledTileWidth / 2;
14091
- const adjustedY = squareGrid ? world.y - scaledTileWidth / 2 : world.y - scaledDiamondTopY - scaledFloorHeight / 2;
14092
- const isoPos = unproject(adjustedX, adjustedY);
14209
+ const isoPos = pointerToScene(e.clientX, e.clientY);
14093
14210
  eventBus.emit(`UI:${tileHoverEvent}`, { x: isoPos.x, y: isoPos.y });
14094
- }, [screenToWorld, viewportSize, scaledTileWidth, squareGrid, scaledDiamondTopY, scaledFloorHeight, unproject, tileHoverEvent, eventBus]);
14211
+ }, [pointerToScene, tileHoverEvent, eventBus]);
14095
14212
  const handleCanvasPointerUp = useCallback((e) => {
14213
+ if (editable) {
14214
+ singlePointerActiveRef.current = false;
14215
+ const drag = editDragRef.current;
14216
+ if (drag && drag.pointerId === e.pointerId) {
14217
+ editDragRef.current = null;
14218
+ if (drag.moved) {
14219
+ onMove?.(drag.id, drag.previewX, drag.previewY);
14220
+ if (moveEvent) eventBus.emit(`UI:${moveEvent}`, { id: drag.id, x: drag.previewX, y: drag.previewY });
14221
+ draw();
14222
+ return;
14223
+ }
14224
+ const next = selectedId === drag.id ? null : drag.id;
14225
+ onSelect?.(next);
14226
+ if (selectEvent) eventBus.emit(`UI:${selectEvent}`, { id: next });
14227
+ return;
14228
+ }
14229
+ onSelect?.(null);
14230
+ if (selectEvent) eventBus.emit(`UI:${selectEvent}`, { id: null });
14231
+ return;
14232
+ }
14096
14233
  singlePointerActiveRef.current = false;
14097
14234
  if (enableCamera) handlePointerUp();
14098
14235
  if (dragDistance() > 5) return;
@@ -14103,16 +14240,14 @@ function Canvas2D({
14103
14240
  eventBus.emit(`UI:${unitClickEvent}`, { unitId: spriteHit });
14104
14241
  return;
14105
14242
  }
14106
- const adjustedX = world.x - scaledTileWidth / 2;
14107
- const adjustedY = squareGrid ? world.y - scaledTileWidth / 2 : world.y - scaledDiamondTopY - scaledFloorHeight / 2;
14108
- const isoPos = unproject(adjustedX, adjustedY);
14243
+ const isoPos = pointerToScene(e.clientX, e.clientY);
14109
14244
  const hitId = hitIndex.get(`${isoPos.x},${isoPos.y}`);
14110
14245
  if (hitId !== void 0 && unitClickEvent) {
14111
14246
  eventBus.emit(`UI:${unitClickEvent}`, { unitId: hitId });
14112
14247
  } else if (tileClickEvent) {
14113
14248
  eventBus.emit(`UI:${tileClickEvent}`, { x: isoPos.x, y: isoPos.y });
14114
14249
  }
14115
- }, [enableCamera, handlePointerUp, dragDistance, screenToWorld, viewportSize, scaledTileWidth, squareGrid, scaledDiamondTopY, scaledFloorHeight, unproject, hitIndex, drawnItems, projector, tileClickEvent, unitClickEvent, eventBus]);
14250
+ }, [editable, selectedId, onMove, moveEvent, onSelect, selectEvent, eventBus, draw, enableCamera, handlePointerUp, dragDistance, screenToWorld, viewportSize, drawnItems, projector, tileClickEvent, unitClickEvent, hitIndex, pointerToScene]);
14116
14251
  const handleCanvasPointerLeave = useCallback(() => {
14117
14252
  handleMouseLeave();
14118
14253
  if (tileLeaveEvent) eventBus.emit(`UI:${tileLeaveEvent}`, {});
@@ -14131,7 +14266,7 @@ function Canvas2D({
14131
14266
  }, [enableCamera, handlePointerUp]);
14132
14267
  const gestureHandlers = useCanvasGestures({
14133
14268
  canvasRef,
14134
- enabled: enableCamera || !!tileHoverEvent || !!tileClickEvent || !!unitClickEvent,
14269
+ enabled: enableCamera || !!tileHoverEvent || !!tileClickEvent || !!unitClickEvent || editable,
14135
14270
  onPointerDown: handleCanvasPointerDown,
14136
14271
  onPointerMove: handleCanvasPointerMove,
14137
14272
  onPointerUp: handleCanvasPointerUp,
@@ -14263,7 +14398,7 @@ function Canvas2D({
14263
14398
  }
14264
14399
  ) });
14265
14400
  }
14266
- var canvas2DLog;
14401
+ var canvas2DLog, EDIT_SELECTION_COLOR, EDIT_HANDLE_SIZE_PX, EDIT_SELECTION_CORNERS;
14267
14402
  var init_Canvas2D = __esm({
14268
14403
  "components/game/molecules/Canvas2D.tsx"() {
14269
14404
  "use client";
@@ -14288,8 +14423,12 @@ var init_Canvas2D = __esm({
14288
14423
  init_DrawGroup();
14289
14424
  init_registry();
14290
14425
  init_hitTest();
14426
+ init_contract();
14291
14427
  init_isometric();
14292
14428
  canvas2DLog = createLogger("almadar:ui:game-canvas");
14429
+ EDIT_SELECTION_COLOR = "#3b82f6";
14430
+ EDIT_HANDLE_SIZE_PX = 8;
14431
+ EDIT_SELECTION_CORNERS = [[0, 0], [1, 0], [0, 1], [1, 1]];
14293
14432
  Canvas2D.displayName = "Canvas2D";
14294
14433
  }
14295
14434
  });
@@ -14331,6 +14470,12 @@ function Canvas({
14331
14470
  featureClickEvent,
14332
14471
  keyMap,
14333
14472
  keyUpMap,
14473
+ editable,
14474
+ selectedId,
14475
+ onSelect,
14476
+ onMove,
14477
+ selectEvent,
14478
+ moveEvent,
14334
14479
  children
14335
14480
  }) {
14336
14481
  canvasLog.debug("Canvas render", { mode, drawablesCount: drawables?.length, projection, camera: camera ? JSON.stringify(camera) : void 0 });
@@ -14345,7 +14490,7 @@ function Canvas({
14345
14490
  if (mode !== "3d") return;
14346
14491
  const next = childDrawablesRef.current;
14347
14492
  canvasLog.debug("children:adopt", { registered: next.length, adopted: childDrawables.length });
14348
- if (next.length === 0 && React95.Children.count(children) > 0) return;
14493
+ if (next.length === 0 && React96.Children.count(children) > 0) return;
14349
14494
  setChildDrawables(
14350
14495
  (prev) => prev.length === next.length && JSON.stringify(prev) === JSON.stringify(next) ? prev : [...next]
14351
14496
  );
@@ -14383,7 +14528,7 @@ function Canvas({
14383
14528
  };
14384
14529
  return /* @__PURE__ */ jsxs(Fragment, { children: [
14385
14530
  /* @__PURE__ */ jsx(Suspense, { fallback: null, children: /* @__PURE__ */ jsx(Canvas3DHost, { ...props3d }) }),
14386
- React95.Children.count(children) > 0 && /* @__PURE__ */ jsx(DrawableRegistryContext.Provider, { value: registerChildDrawable, children: /* @__PURE__ */ jsx("div", { "aria-hidden": "true", style: { position: "absolute", width: 0, height: 0, overflow: "hidden" }, children }) })
14531
+ React96.Children.count(children) > 0 && /* @__PURE__ */ jsx(DrawableRegistryContext.Provider, { value: registerChildDrawable, children: /* @__PURE__ */ jsx("div", { "aria-hidden": "true", style: { position: "absolute", width: 0, height: 0, overflow: "hidden" }, children }) })
14387
14532
  ] });
14388
14533
  }
14389
14534
  return /* @__PURE__ */ jsx(
@@ -14408,6 +14553,12 @@ function Canvas({
14408
14553
  tileLeaveEvent,
14409
14554
  keyMap,
14410
14555
  keyUpMap,
14556
+ editable,
14557
+ selectedId,
14558
+ onSelect,
14559
+ onMove,
14560
+ selectEvent,
14561
+ moveEvent,
14411
14562
  ...children !== void 0 ? { children } : {}
14412
14563
  }
14413
14564
  );
@@ -14429,15 +14580,19 @@ function GameAudioToggle({
14429
14580
  size = "sm",
14430
14581
  className,
14431
14582
  onAsset,
14432
- offAsset
14583
+ offAsset,
14584
+ toggleEvent
14433
14585
  }) {
14434
14586
  const ctx = useGameAudioContextOptional();
14435
14587
  const [localMuted, setLocalMuted] = useState(false);
14436
14588
  const muted = ctx ? ctx.muted : localMuted;
14437
14589
  const setMuted = ctx ? ctx.setMuted : setLocalMuted;
14590
+ const eventBus = useEventBus();
14438
14591
  const handleToggle = useCallback(() => {
14439
- setMuted(!muted);
14440
- }, [muted, setMuted]);
14592
+ const next = !muted;
14593
+ setMuted(next);
14594
+ if (toggleEvent) eventBus.emit(`UI:${toggleEvent}`, { muted: next });
14595
+ }, [muted, setMuted, toggleEvent, eventBus]);
14441
14596
  const activeAsset = muted ? offAsset : onAsset;
14442
14597
  return /* @__PURE__ */ jsx(
14443
14598
  Button,
@@ -14456,10 +14611,319 @@ var init_GameAudioToggle = __esm({
14456
14611
  "use client";
14457
14612
  init_atoms();
14458
14613
  init_cn();
14614
+ init_useEventBus();
14459
14615
  init_GameIcon();
14460
14616
  GameAudioToggle.displayName = "GameAudioToggle";
14461
14617
  }
14462
14618
  });
14619
+ function pickPath(entry) {
14620
+ if (Array.isArray(entry.path)) {
14621
+ return entry.path[Math.floor(Math.random() * entry.path.length)];
14622
+ }
14623
+ return entry.path;
14624
+ }
14625
+ function useGameAudio({
14626
+ manifest,
14627
+ baseUrl = "",
14628
+ initialMuted = false,
14629
+ initialVolume = 1
14630
+ }) {
14631
+ const [muted, setMutedState] = useState(initialMuted);
14632
+ const [masterVolume, setMasterVolumeState] = useState(initialVolume);
14633
+ const mutedRef = useRef(muted);
14634
+ const volumeRef = useRef(masterVolume);
14635
+ const manifestRef = useRef(manifest);
14636
+ mutedRef.current = muted;
14637
+ volumeRef.current = masterVolume;
14638
+ manifestRef.current = manifest;
14639
+ const poolsRef = useRef(/* @__PURE__ */ new Map());
14640
+ const getOrCreateElement = useCallback((key) => {
14641
+ const entry = manifestRef.current[key];
14642
+ if (!entry) return null;
14643
+ let pool = poolsRef.current.get(key);
14644
+ if (!pool) {
14645
+ pool = [];
14646
+ poolsRef.current.set(key, pool);
14647
+ }
14648
+ const maxSize = entry.poolSize ?? 1;
14649
+ for (const audio of pool) {
14650
+ if (audio.paused && (audio.ended || audio.currentTime === 0)) {
14651
+ return audio;
14652
+ }
14653
+ }
14654
+ if (pool.length < maxSize) {
14655
+ const src = baseUrl + pickPath(entry);
14656
+ const audio = new Audio(src);
14657
+ audio.loop = entry.loop ?? false;
14658
+ pool.push(audio);
14659
+ return audio;
14660
+ }
14661
+ if (!entry.loop) {
14662
+ let oldest = pool[0];
14663
+ for (const audio of pool) {
14664
+ if (audio.currentTime > oldest.currentTime) {
14665
+ oldest = audio;
14666
+ }
14667
+ }
14668
+ oldest.pause();
14669
+ oldest.currentTime = 0;
14670
+ return oldest;
14671
+ }
14672
+ return null;
14673
+ }, [baseUrl]);
14674
+ const play = useCallback((key) => {
14675
+ if (mutedRef.current) return;
14676
+ const entry = manifestRef.current[key];
14677
+ if (!entry) return;
14678
+ const audio = getOrCreateElement(key);
14679
+ if (!audio) return;
14680
+ audio.volume = Math.min(1, (entry.volume ?? 1) * volumeRef.current);
14681
+ if (!entry.loop) {
14682
+ audio.currentTime = 0;
14683
+ }
14684
+ const promise = audio.play();
14685
+ if (promise) {
14686
+ promise.catch(() => {
14687
+ });
14688
+ }
14689
+ }, [getOrCreateElement]);
14690
+ const stop = useCallback((key) => {
14691
+ const pool = poolsRef.current.get(key);
14692
+ if (!pool) return;
14693
+ for (const audio of pool) {
14694
+ audio.pause();
14695
+ audio.currentTime = 0;
14696
+ }
14697
+ }, []);
14698
+ const currentMusicKeyRef = useRef(null);
14699
+ const currentMusicElRef = useRef(null);
14700
+ const musicFadeRef = useRef(null);
14701
+ const pendingMusicKeyRef = useRef(null);
14702
+ const clearMusicFade = useCallback(() => {
14703
+ if (musicFadeRef.current) {
14704
+ clearInterval(musicFadeRef.current);
14705
+ musicFadeRef.current = null;
14706
+ }
14707
+ }, []);
14708
+ const playMusic = useCallback((key) => {
14709
+ if (key === currentMusicKeyRef.current) return;
14710
+ pendingMusicKeyRef.current = key;
14711
+ const entry = manifestRef.current[key];
14712
+ if (!entry) return;
14713
+ const fadeDurationMs = entry.crossfadeDurationMs ?? 1500;
14714
+ const stepMs = 50;
14715
+ const totalSteps = Math.max(1, fadeDurationMs / stepMs);
14716
+ const targetVolume = Math.min(1, (entry.volume ?? 1) * volumeRef.current);
14717
+ clearMusicFade();
14718
+ const src = baseUrl + (Array.isArray(entry.path) ? entry.path[0] : entry.path);
14719
+ const incoming = new Audio(src);
14720
+ incoming.loop = true;
14721
+ incoming.volume = 0;
14722
+ const outgoing = currentMusicElRef.current;
14723
+ const outgoingStartVol = outgoing?.volume ?? 0;
14724
+ currentMusicKeyRef.current = key;
14725
+ currentMusicElRef.current = incoming;
14726
+ if (!mutedRef.current) {
14727
+ incoming.play().catch(() => {
14728
+ currentMusicKeyRef.current = null;
14729
+ currentMusicElRef.current = outgoing;
14730
+ });
14731
+ }
14732
+ let step = 0;
14733
+ musicFadeRef.current = setInterval(() => {
14734
+ step++;
14735
+ const progress = Math.min(step / totalSteps, 1);
14736
+ incoming.volume = Math.min(1, targetVolume * progress);
14737
+ if (outgoing) {
14738
+ outgoing.volume = Math.max(0, outgoingStartVol * (1 - progress));
14739
+ }
14740
+ if (progress >= 1) {
14741
+ clearMusicFade();
14742
+ if (outgoing) {
14743
+ outgoing.pause();
14744
+ outgoing.src = "";
14745
+ }
14746
+ }
14747
+ }, stepMs);
14748
+ }, [baseUrl, clearMusicFade]);
14749
+ const stopMusic = useCallback((fadeDurationMs = 1e3) => {
14750
+ const outgoing = currentMusicElRef.current;
14751
+ if (!outgoing) return;
14752
+ currentMusicKeyRef.current = null;
14753
+ currentMusicElRef.current = null;
14754
+ pendingMusicKeyRef.current = null;
14755
+ clearMusicFade();
14756
+ const startVolume = outgoing.volume;
14757
+ const stepMs = 50;
14758
+ const totalSteps = Math.max(1, fadeDurationMs / stepMs);
14759
+ let step = 0;
14760
+ musicFadeRef.current = setInterval(() => {
14761
+ step++;
14762
+ const progress = step / totalSteps;
14763
+ outgoing.volume = Math.max(0, startVolume * (1 - progress));
14764
+ if (progress >= 1) {
14765
+ clearMusicFade();
14766
+ outgoing.pause();
14767
+ outgoing.src = "";
14768
+ }
14769
+ }, stepMs);
14770
+ }, [clearMusicFade]);
14771
+ const stopAll = useCallback(() => {
14772
+ for (const pool of poolsRef.current.values()) {
14773
+ for (const audio of pool) {
14774
+ audio.pause();
14775
+ audio.currentTime = 0;
14776
+ }
14777
+ }
14778
+ stopMusic(0);
14779
+ }, [stopMusic]);
14780
+ const setMuted = useCallback((value) => {
14781
+ setMutedState(value);
14782
+ if (value) {
14783
+ for (const [key, pool] of poolsRef.current.entries()) {
14784
+ if (manifestRef.current[key]?.loop) {
14785
+ for (const audio of pool) {
14786
+ if (!audio.paused) audio.pause();
14787
+ }
14788
+ }
14789
+ }
14790
+ currentMusicElRef.current?.pause();
14791
+ } else {
14792
+ for (const [key, pool] of poolsRef.current.entries()) {
14793
+ const entry = manifestRef.current[key];
14794
+ if (entry?.loop && entry?.autostart) {
14795
+ for (const audio of pool) {
14796
+ if (audio.paused) audio.play().catch(() => {
14797
+ });
14798
+ }
14799
+ }
14800
+ }
14801
+ const musicEl = currentMusicElRef.current;
14802
+ if (musicEl) {
14803
+ musicEl.play().catch(() => {
14804
+ });
14805
+ }
14806
+ }
14807
+ }, []);
14808
+ const setMasterVolume = useCallback((volume) => {
14809
+ const clamped = Math.max(0, Math.min(1, volume));
14810
+ setMasterVolumeState(clamped);
14811
+ for (const [key, pool] of poolsRef.current.entries()) {
14812
+ const entryVol = manifestRef.current[key]?.volume ?? 1;
14813
+ for (const audio of pool) {
14814
+ audio.volume = Math.min(1, entryVol * clamped);
14815
+ }
14816
+ }
14817
+ if (!musicFadeRef.current && currentMusicElRef.current) {
14818
+ const key = currentMusicKeyRef.current;
14819
+ const entryVol = key ? manifestRef.current[key]?.volume ?? 1 : 1;
14820
+ currentMusicElRef.current.volume = Math.min(1, entryVol * clamped);
14821
+ }
14822
+ }, []);
14823
+ const unlockedRef = useRef(false);
14824
+ useEffect(() => {
14825
+ const autoKeys = Object.keys(manifest).filter((k) => manifest[k].autostart);
14826
+ const hasPendingMusic = () => pendingMusicKeyRef.current !== null;
14827
+ const hasAutoStart = autoKeys.length > 0;
14828
+ if (!hasAutoStart && !hasPendingMusic()) return;
14829
+ const unlock = () => {
14830
+ if (unlockedRef.current) return;
14831
+ unlockedRef.current = true;
14832
+ if (!mutedRef.current) {
14833
+ for (const key of autoKeys) {
14834
+ play(key);
14835
+ }
14836
+ const pending = pendingMusicKeyRef.current;
14837
+ if (pending && pending !== currentMusicKeyRef.current) {
14838
+ playMusic(pending);
14839
+ }
14840
+ }
14841
+ };
14842
+ document.addEventListener("click", unlock, { once: true });
14843
+ document.addEventListener("keydown", unlock, { once: true });
14844
+ document.addEventListener("touchstart", unlock, { once: true });
14845
+ return () => {
14846
+ document.removeEventListener("click", unlock);
14847
+ document.removeEventListener("keydown", unlock);
14848
+ document.removeEventListener("touchstart", unlock);
14849
+ };
14850
+ }, [manifest, play, playMusic]);
14851
+ useEffect(() => {
14852
+ return () => {
14853
+ clearMusicFade();
14854
+ for (const pool of poolsRef.current.values()) {
14855
+ for (const audio of pool) {
14856
+ audio.pause();
14857
+ audio.src = "";
14858
+ }
14859
+ }
14860
+ poolsRef.current.clear();
14861
+ if (currentMusicElRef.current) {
14862
+ currentMusicElRef.current.pause();
14863
+ currentMusicElRef.current.src = "";
14864
+ currentMusicElRef.current = null;
14865
+ }
14866
+ };
14867
+ }, [clearMusicFade]);
14868
+ return {
14869
+ play,
14870
+ stop,
14871
+ stopAll,
14872
+ playMusic,
14873
+ stopMusic,
14874
+ muted,
14875
+ setMuted,
14876
+ masterVolume,
14877
+ setMasterVolume
14878
+ };
14879
+ }
14880
+ var init_useGameAudio = __esm({
14881
+ "hooks/useGameAudio.ts"() {
14882
+ "use client";
14883
+ useGameAudio.displayName = "useGameAudio";
14884
+ }
14885
+ });
14886
+ function GameAudioCue({
14887
+ cue,
14888
+ cueSeq,
14889
+ music,
14890
+ muted,
14891
+ volume,
14892
+ manifest,
14893
+ baseUrl
14894
+ }) {
14895
+ const { play, playMusic, stopMusic, setMuted, setMasterVolume } = useGameAudio({
14896
+ manifest,
14897
+ baseUrl,
14898
+ initialMuted: muted,
14899
+ initialVolume: volume
14900
+ });
14901
+ const prevCueSeqRef = useRef(cueSeq);
14902
+ useEffect(() => {
14903
+ if (cue && cueSeq !== void 0 && cueSeq !== prevCueSeqRef.current) {
14904
+ play(cue);
14905
+ }
14906
+ prevCueSeqRef.current = cueSeq;
14907
+ }, [cue, cueSeq, play]);
14908
+ useEffect(() => {
14909
+ if (music) playMusic(music);
14910
+ else stopMusic();
14911
+ }, [music, playMusic, stopMusic]);
14912
+ useEffect(() => {
14913
+ if (muted !== void 0) setMuted(muted);
14914
+ }, [muted, setMuted]);
14915
+ useEffect(() => {
14916
+ if (volume !== void 0) setMasterVolume(volume);
14917
+ }, [volume, setMasterVolume]);
14918
+ return null;
14919
+ }
14920
+ var init_GameAudioCue = __esm({
14921
+ "components/game/atoms/GameAudioCue.tsx"() {
14922
+ "use client";
14923
+ init_useGameAudio();
14924
+ GameAudioCue.displayName = "GameAudioCue";
14925
+ }
14926
+ });
14463
14927
  function isKnownState(s) {
14464
14928
  return s in DEFAULT_STATE_STYLES;
14465
14929
  }
@@ -14541,7 +15005,7 @@ function LinearView({
14541
15005
  /* @__PURE__ */ jsx(HStack, { className: "flex-wrap items-center", gap: "xs", children: trait.states.map((state, i) => {
14542
15006
  const isDone = i < currentIdx;
14543
15007
  const isCurrent = i === currentIdx;
14544
- return /* @__PURE__ */ jsxs(React95__default.Fragment, { children: [
15008
+ return /* @__PURE__ */ jsxs(React96__default.Fragment, { children: [
14545
15009
  i > 0 && /* @__PURE__ */ jsx(
14546
15010
  Typography,
14547
15011
  {
@@ -15076,7 +15540,7 @@ function SequenceBar({
15076
15540
  else onSlotRemove?.(index);
15077
15541
  }, [emit, slotRemoveEvent, onSlotRemove, playing]);
15078
15542
  const paddedSlots = Array.from({ length: maxSlots }, (_, i) => slots[i]);
15079
- return /* @__PURE__ */ jsx(HStack, { className: cn("items-center", className), gap: "sm", children: paddedSlots.map((slot, i) => /* @__PURE__ */ jsxs(React95__default.Fragment, { children: [
15543
+ return /* @__PURE__ */ jsx(HStack, { className: cn("items-center", className), gap: "sm", children: paddedSlots.map((slot, i) => /* @__PURE__ */ jsxs(React96__default.Fragment, { children: [
15080
15544
  i > 0 && /* @__PURE__ */ jsx(
15081
15545
  Typography,
15082
15546
  {
@@ -15158,15 +15622,18 @@ var init_StateJsonView = __esm({
15158
15622
  StateJsonView.displayName = "StateJsonView";
15159
15623
  }
15160
15624
  });
15161
- var GAME_FONTS, GameShell;
15162
- var init_GameShell = __esm({
15163
- "components/game/templates/GameShell.tsx"() {
15164
- init_cn();
15165
- init_Box();
15166
- init_Card();
15167
- init_Typography();
15168
- init_AtlasImage();
15169
- GAME_FONTS = {
15625
+
15626
+ // lib/gameFonts.ts
15627
+ function resolveGameFontFamily(input) {
15628
+ if (!input) return void 0;
15629
+ const resolved = GAME_FONT_KEYS[input];
15630
+ if (resolved) return `'${resolved}', ui-sans-serif, system-ui, sans-serif`;
15631
+ return input;
15632
+ }
15633
+ var GAME_FONT_KEYS;
15634
+ var init_gameFonts = __esm({
15635
+ "lib/gameFonts.ts"() {
15636
+ GAME_FONT_KEYS = {
15170
15637
  fredoka: "Fredoka",
15171
15638
  future: "Kenney Future",
15172
15639
  "future-narrow": "Kenney Future Narrow",
@@ -15174,6 +15641,17 @@ var init_GameShell = __esm({
15174
15641
  blocks: "Kenney Blocks",
15175
15642
  mini: "Kenney Mini"
15176
15643
  };
15644
+ }
15645
+ });
15646
+ var GameShell;
15647
+ var init_GameShell = __esm({
15648
+ "components/game/templates/GameShell.tsx"() {
15649
+ init_cn();
15650
+ init_gameFonts();
15651
+ init_Box();
15652
+ init_Card();
15653
+ init_Typography();
15654
+ init_AtlasImage();
15177
15655
  GameShell = ({
15178
15656
  appName = "Game",
15179
15657
  hud,
@@ -15187,7 +15665,7 @@ var init_GameShell = __esm({
15187
15665
  fontFamily,
15188
15666
  "data-theme": dataTheme
15189
15667
  }) => {
15190
- const font = fontFamily ? GAME_FONTS[fontFamily] ?? fontFamily : void 0;
15668
+ const displayFont = resolveGameFontFamily(fontFamily);
15191
15669
  return /* @__PURE__ */ jsxs(
15192
15670
  Box,
15193
15671
  {
@@ -15206,7 +15684,7 @@ var init_GameShell = __esm({
15206
15684
  // passed — an always-on inline stamp would shadow the orbital's
15207
15685
  // inline-theme font-family-display token (inline style beats the
15208
15686
  // theme provider's vars for the whole shell subtree).
15209
- ...font ? { "--font-family-display": `'${font}', ui-sans-serif, system-ui, sans-serif` } : {}
15687
+ ...displayFont ? { "--font-family-display": displayFont } : {}
15210
15688
  },
15211
15689
  children: [
15212
15690
  backgroundAsset && /* @__PURE__ */ jsx(
@@ -15417,14 +15895,15 @@ function drawArrowHead(ctx, x1, y1, x2, y2, size) {
15417
15895
  ctx.closePath();
15418
15896
  ctx.fill();
15419
15897
  }
15420
- function drawShape(ctx, shape, width, height, allShapes) {
15898
+ function drawShape(ctx, shape, width, height, allShapes, fontFamily) {
15421
15899
  ctx.save();
15422
15900
  const opacity = shape.opacity ?? 1;
15423
15901
  ctx.globalAlpha = opacity;
15424
15902
  const stroke = resolveColor2(shape.color, ctx, "#333333");
15425
15903
  const fill = shape.fill ? resolveColor2(shape.fill, ctx, "#cccccc") : void 0;
15426
15904
  ctx.lineWidth = shape.lineWidth ?? 2;
15427
- if (shape.dash) ctx.setLineDash([...DASH_PATTERNS[shape.dash]]);
15905
+ const dashPattern = shape.dash ? DASH_PATTERNS[shape.dash] : void 0;
15906
+ if (dashPattern) ctx.setLineDash([...dashPattern]);
15428
15907
  switch (shape.type) {
15429
15908
  case "grid": {
15430
15909
  const step = shape.step ?? 40;
@@ -15546,7 +16025,7 @@ function drawShape(ctx, shape, width, height, allShapes) {
15546
16025
  case "text": {
15547
16026
  if (shape.x == null || shape.y == null || !shape.text) break;
15548
16027
  ctx.fillStyle = stroke;
15549
- ctx.font = `${shape.fontSize ?? 14}px ${themeBodyFont(ctx.canvas)}`;
16028
+ ctx.font = `${shape.fontSize ?? 14}px ${shape.fontFamily ?? fontFamily ?? themeBodyFont(ctx.canvas)}`;
15550
16029
  ctx.textAlign = shape.align ?? "left";
15551
16030
  ctx.textBaseline = "middle";
15552
16031
  ctx.fillText(shape.text, shape.x, shape.y);
@@ -15588,7 +16067,7 @@ function drawShape(ctx, shape, width, height, allShapes) {
15588
16067
  }
15589
16068
  ctx.restore();
15590
16069
  }
15591
- function readoutShapes(readouts, width) {
16070
+ function readoutShapes(readouts, width, fontFamily) {
15592
16071
  const out = [];
15593
16072
  const chipH = 18;
15594
16073
  const gap = 6;
@@ -15612,13 +16091,14 @@ function readoutShapes(readouts, width) {
15612
16091
  text,
15613
16092
  color: "#ffffff",
15614
16093
  fontSize: 10,
15615
- align: "center"
16094
+ align: "center",
16095
+ fontFamily
15616
16096
  });
15617
16097
  rightEdge = chipX - gap;
15618
16098
  }
15619
16099
  return out;
15620
16100
  }
15621
- function traceShapes(panel, k, width, height) {
16101
+ function traceShapes(panel, k, width, height, fontFamily) {
15622
16102
  const w = panel.width ?? Math.round(width * 0.32);
15623
16103
  const h = panel.height ?? Math.round(height * 0.28);
15624
16104
  const x = panel.x ?? width - w - 8;
@@ -15672,14 +16152,14 @@ function traceShapes(panel, k, width, height) {
15672
16152
  out.push({ type: "circle", x: last.x, y: last.y, radius: 2, color, fill: color });
15673
16153
  }
15674
16154
  if (series.label) {
15675
- out.push({ type: "text", x: x + 6, y: y + 10 + 11 * j, text: series.label, color, fontSize: 9 });
16155
+ out.push({ type: "text", x: x + 6, y: y + 10 + 11 * j, text: series.label, color, fontSize: 9, fontFamily });
15676
16156
  }
15677
16157
  });
15678
16158
  if (panel.yLabel) {
15679
- out.push({ type: "text", x: x + w - 6, y: y + 10, text: panel.yLabel, color: "#6b7280", fontSize: 9, align: "right" });
16159
+ out.push({ type: "text", x: x + w - 6, y: y + 10, text: panel.yLabel, color: "#6b7280", fontSize: 9, align: "right", fontFamily });
15680
16160
  }
15681
16161
  if (panel.xLabel) {
15682
- out.push({ type: "text", x: x + w - 6, y: y + h - 6, text: panel.xLabel, color: "#6b7280", fontSize: 9, align: "right" });
16162
+ out.push({ type: "text", x: x + w - 6, y: y + h - 6, text: panel.xLabel, color: "#6b7280", fontSize: 9, align: "right", fontFamily });
15683
16163
  }
15684
16164
  return out;
15685
16165
  }
@@ -15702,13 +16182,14 @@ var init_LearningCanvas = __esm({
15702
16182
  init_useEventBus();
15703
16183
  init_webPainter2d();
15704
16184
  init_paintDispatch();
15705
- DASH_PATTERNS = { dashed: [6, 4], dotted: [2, 3] };
16185
+ DASH_PATTERNS = { solid: [], dashed: [6, 4], dotted: [2, 3] };
15706
16186
  TRACE_SERIES_COLORS = ["#2563eb", "#dc2626", "#16a34a", "#f59e0b"];
15707
16187
  LearningCanvas = ({
15708
16188
  className,
15709
16189
  width = 600,
15710
16190
  height = 400,
15711
16191
  backgroundColor,
16192
+ fontFamily,
15712
16193
  shapes = [],
15713
16194
  drawables,
15714
16195
  projector,
@@ -15744,10 +16225,10 @@ var init_LearningCanvas = __esm({
15744
16225
  }, [shapes]);
15745
16226
  const derivedShapes = useMemo(() => {
15746
16227
  if (!traces?.length && !readouts?.length) return shapes;
15747
- const traceOut = (traces ?? []).flatMap((panel, k) => traceShapes(panel, k, width, height));
15748
- const readoutOut = readouts?.length ? readoutShapes(readouts, width) : [];
16228
+ const traceOut = (traces ?? []).flatMap((panel, k) => traceShapes(panel, k, width, height, fontFamily));
16229
+ const readoutOut = readouts?.length ? readoutShapes(readouts, width, fontFamily) : [];
15749
16230
  return [...shapes, ...traceOut, ...readoutOut];
15750
- }, [shapes, traces, readouts, width, height]);
16231
+ }, [shapes, traces, readouts, width, height, fontFamily]);
15751
16232
  const draw = useCallback(() => {
15752
16233
  const _perfT = perfStart("learningcanvas:paint");
15753
16234
  const canvas = canvasRef.current;
@@ -15766,15 +16247,15 @@ var init_LearningCanvas = __esm({
15766
16247
  ctx.fillRect(0, 0, width, height);
15767
16248
  }
15768
16249
  for (const shape of derivedShapes) {
15769
- if (shape.type !== "text") drawShape(ctx, shape, width, height, derivedShapes);
16250
+ if (shape.type !== "text") drawShape(ctx, shape, width, height, derivedShapes, fontFamily);
15770
16251
  }
15771
16252
  for (const shape of derivedShapes) {
15772
- if (shape.type === "text") drawShape(ctx, shape, width, height, derivedShapes);
16253
+ if (shape.type === "text") drawShape(ctx, shape, width, height, derivedShapes, fontFamily);
15773
16254
  }
15774
16255
  if (drawables?.length && projector) {
15775
16256
  const painter = createWebPainter(ctx, invalidateRef.current);
15776
16257
  const timeMs = needsAnim && typeof performance !== "undefined" ? performance.now() : 0;
15777
- const dctx = { projector, time: timeMs, invalidate: invalidateRef.current, fontFamily: themeBodyFont(canvas) };
16258
+ const dctx = { projector, time: timeMs, invalidate: invalidateRef.current, fontFamily: fontFamily || themeBodyFont(canvas) };
15778
16259
  for (const node of drawables) {
15779
16260
  paintDrawable(painter, node, dctx);
15780
16261
  }
@@ -15936,7 +16417,7 @@ var init_ErrorBoundary = __esm({
15936
16417
  }
15937
16418
  );
15938
16419
  };
15939
- ErrorBoundary = class extends React95__default.Component {
16420
+ ErrorBoundary = class extends React96__default.Component {
15940
16421
  constructor(props) {
15941
16422
  super(props);
15942
16423
  __publicField(this, "reset", () => {
@@ -16205,7 +16686,7 @@ var init_Container = __esm({
16205
16686
  as: Component = "div"
16206
16687
  }) => {
16207
16688
  const resolvedSize = maxWidth ?? size ?? "lg";
16208
- return React95__default.createElement(
16689
+ return React96__default.createElement(
16209
16690
  Component,
16210
16691
  {
16211
16692
  className: cn(
@@ -19546,6 +20027,250 @@ var init_EmptyState = __esm({
19546
20027
  EmptyState.displayName = "EmptyState";
19547
20028
  }
19548
20029
  });
20030
+
20031
+ // lib/editorMotions.ts
20032
+ function clamp(value, min, max) {
20033
+ return Math.max(min, Math.min(max, value));
20034
+ }
20035
+ function computeLines(text) {
20036
+ const lines = [];
20037
+ let start = 0;
20038
+ for (let i = 0; i <= text.length; i++) {
20039
+ if (i === text.length || text[i] === "\n") {
20040
+ lines.push({ start, end: i });
20041
+ start = i + 1;
20042
+ }
20043
+ }
20044
+ return lines;
20045
+ }
20046
+ function lineIndexAt(lines, pos) {
20047
+ for (let i = 0; i < lines.length; i++) {
20048
+ if (pos <= lines[i].end) return i;
20049
+ }
20050
+ return lines.length - 1;
20051
+ }
20052
+ function findWords(text) {
20053
+ const words = [];
20054
+ const re = /\w+|\S+/g;
20055
+ let m;
20056
+ while ((m = re.exec(text)) !== null) {
20057
+ words.push({ start: m.index, end: m.index + m[0].length });
20058
+ }
20059
+ return words;
20060
+ }
20061
+ function nextWordStart(text, pos) {
20062
+ for (const w of findWords(text)) {
20063
+ if (w.start > pos) return w.start;
20064
+ }
20065
+ return text.length;
20066
+ }
20067
+ function prevWordStart(text, pos) {
20068
+ let result = 0;
20069
+ for (const w of findWords(text)) {
20070
+ if (w.start < pos) result = w.start;
20071
+ else break;
20072
+ }
20073
+ return result;
20074
+ }
20075
+ function nextWordEnd(text, pos) {
20076
+ for (const w of findWords(text)) {
20077
+ const lastChar = w.end - 1;
20078
+ if (lastChar > pos) return lastChar;
20079
+ }
20080
+ return text.length > 0 ? text.length - 1 : 0;
20081
+ }
20082
+ function firstNonBlank(text, line) {
20083
+ let i = line.start;
20084
+ while (i < line.end && (text[i] === " " || text[i] === " ")) i++;
20085
+ return i;
20086
+ }
20087
+ function nextParagraphBoundary(lines, fromLineIdx, textLength) {
20088
+ for (let i = fromLineIdx + 1; i < lines.length; i++) {
20089
+ if (lines[i].start === lines[i].end) return lines[i].start;
20090
+ }
20091
+ return textLength;
20092
+ }
20093
+ function prevParagraphBoundary(lines, fromLineIdx) {
20094
+ for (let i = fromLineIdx - 1; i >= 0; i--) {
20095
+ if (lines[i].start === lines[i].end) return lines[i].start;
20096
+ }
20097
+ return 0;
20098
+ }
20099
+ function applyMotion(text, caret, motion, count) {
20100
+ const n = Math.max(1, count);
20101
+ const lines = computeLines(text);
20102
+ const lineIdx = lineIndexAt(lines, caret);
20103
+ const line = lines[lineIdx];
20104
+ switch (motion) {
20105
+ case "left":
20106
+ return clamp(caret - n, line.start, line.end);
20107
+ case "right":
20108
+ return clamp(caret + n, line.start, line.end);
20109
+ case "up": {
20110
+ const col = caret - line.start;
20111
+ const targetIdx = clamp(lineIdx - n, 0, lines.length - 1);
20112
+ const target = lines[targetIdx];
20113
+ return clamp(target.start + col, target.start, target.end);
20114
+ }
20115
+ case "down": {
20116
+ const col = caret - line.start;
20117
+ const targetIdx = clamp(lineIdx + n, 0, lines.length - 1);
20118
+ const target = lines[targetIdx];
20119
+ return clamp(target.start + col, target.start, target.end);
20120
+ }
20121
+ case "word-forward": {
20122
+ let pos = caret;
20123
+ for (let i = 0; i < n; i++) pos = nextWordStart(text, pos);
20124
+ return pos;
20125
+ }
20126
+ case "word-back": {
20127
+ let pos = caret;
20128
+ for (let i = 0; i < n; i++) pos = prevWordStart(text, pos);
20129
+ return pos;
20130
+ }
20131
+ case "word-end": {
20132
+ let pos = caret;
20133
+ for (let i = 0; i < n; i++) pos = nextWordEnd(text, pos);
20134
+ return pos;
20135
+ }
20136
+ case "line-start":
20137
+ return line.start;
20138
+ case "line-end":
20139
+ return line.end > line.start ? line.end - 1 : line.start;
20140
+ case "first-nonblank":
20141
+ return firstNonBlank(text, line);
20142
+ case "doc-start":
20143
+ return 0;
20144
+ case "doc-end":
20145
+ return text.length;
20146
+ case "paragraph-forward": {
20147
+ let pos = caret;
20148
+ for (let i = 0; i < n; i++) {
20149
+ pos = nextParagraphBoundary(lines, lineIndexAt(lines, pos), text.length);
20150
+ }
20151
+ return pos;
20152
+ }
20153
+ case "paragraph-back": {
20154
+ let pos = caret;
20155
+ for (let i = 0; i < n; i++) {
20156
+ pos = prevParagraphBoundary(lines, lineIndexAt(lines, pos));
20157
+ }
20158
+ return pos;
20159
+ }
20160
+ case "line":
20161
+ case "selection":
20162
+ return caret;
20163
+ default: {
20164
+ const _exhaustive = motion;
20165
+ return _exhaustive;
20166
+ }
20167
+ }
20168
+ }
20169
+ function motionRange(text, caret, motion, count, selection) {
20170
+ if (motion === "selection") {
20171
+ if (!selection) return [caret, caret];
20172
+ return [Math.min(selection[0], selection[1]), Math.max(selection[0], selection[1])];
20173
+ }
20174
+ const lines = computeLines(text);
20175
+ if (motion === "line") {
20176
+ const n = Math.max(1, count);
20177
+ const startIdx = lineIndexAt(lines, caret);
20178
+ const endIdx = clamp(startIdx + n - 1, 0, lines.length - 1);
20179
+ const start2 = lines[startIdx].start;
20180
+ const rawEnd = lines[endIdx].end;
20181
+ const end2 = rawEnd < text.length ? rawEnd + 1 : rawEnd;
20182
+ return [start2, end2];
20183
+ }
20184
+ const newCaret = applyMotion(text, caret, motion, count);
20185
+ let start = Math.min(caret, newCaret);
20186
+ let end = Math.max(caret, newCaret);
20187
+ if (motion === "word-end" || motion === "line-end") {
20188
+ end = Math.min(Math.max(start, newCaret) + 1, text.length);
20189
+ } else if (motion === "word-forward" && newCaret > caret) {
20190
+ const startLine = lineIndexAt(lines, caret);
20191
+ const endLine = lineIndexAt(lines, newCaret);
20192
+ if (endLine !== startLine) {
20193
+ end = lines[startLine].end;
20194
+ }
20195
+ }
20196
+ return [start, end];
20197
+ }
20198
+ function applyOperator(text, range, operator, register) {
20199
+ const start = clamp(range[0], 0, text.length);
20200
+ const end = clamp(range[1], start, text.length);
20201
+ const removed = text.slice(start, end);
20202
+ if (operator === "yank") {
20203
+ return { text, caret: start, register: removed };
20204
+ }
20205
+ return { text: text.slice(0, start) + text.slice(end), caret: start, register: removed };
20206
+ }
20207
+ var init_editorMotions = __esm({
20208
+ "lib/editorMotions.ts"() {
20209
+ }
20210
+ });
20211
+ function isMotionPayload(payload) {
20212
+ return !!payload && typeof payload.editorId === "string" && typeof payload.motion === "string" && typeof payload.count === "number";
20213
+ }
20214
+ function isOperatePayload(payload) {
20215
+ return !!payload && typeof payload.editorId === "string" && typeof payload.operator === "string" && typeof payload.motion === "string" && typeof payload.count === "number";
20216
+ }
20217
+ function isInsertTextPayload(payload) {
20218
+ return !!payload && typeof payload.editorId === "string" && typeof payload.text === "string";
20219
+ }
20220
+ function isSetModePayload(payload) {
20221
+ return !!payload && typeof payload.editorId === "string" && typeof payload.mode === "string" && typeof payload.caret === "string";
20222
+ }
20223
+ function useEditorCapabilities(args) {
20224
+ const [caretMode, setCaretMode] = useState("bar");
20225
+ const registerRef = useRef("");
20226
+ useEventListener(`UI:${args.events.onMotion}`, (evt) => {
20227
+ if (!args.editorId || !isMotionPayload(evt.payload) || evt.payload.editorId !== args.editorId) return;
20228
+ const ta = args.textareaRef.current;
20229
+ if (!ta) return;
20230
+ const { motion, count } = evt.payload;
20231
+ const newCaret = applyMotion(ta.value, ta.selectionStart, motion, count);
20232
+ if (ta.selectionStart !== ta.selectionEnd) {
20233
+ ta.setSelectionRange(ta.selectionStart, newCaret);
20234
+ } else {
20235
+ ta.setSelectionRange(newCaret, newCaret);
20236
+ }
20237
+ });
20238
+ useEventListener(`UI:${args.events.onOperate}`, (evt) => {
20239
+ if (!args.editorId || !isOperatePayload(evt.payload) || evt.payload.editorId !== args.editorId) return;
20240
+ const ta = args.textareaRef.current;
20241
+ if (!ta) return;
20242
+ const { operator, motion, count } = evt.payload;
20243
+ const selection = motion === "selection" ? [ta.selectionStart, ta.selectionEnd] : void 0;
20244
+ const range = motionRange(ta.value, ta.selectionStart, motion, count, selection);
20245
+ const result = applyOperator(ta.value, range, operator, registerRef.current);
20246
+ registerRef.current = result.register;
20247
+ if (operator === "yank") {
20248
+ ta.setSelectionRange(range[0], range[0]);
20249
+ } else {
20250
+ ta.setRangeText("", range[0], range[1], "end");
20251
+ }
20252
+ args.applyChange(ta.value);
20253
+ });
20254
+ useEventListener(`UI:${args.events.onInsertText}`, (evt) => {
20255
+ if (!args.editorId || !isInsertTextPayload(evt.payload) || evt.payload.editorId !== args.editorId) return;
20256
+ const ta = args.textareaRef.current;
20257
+ if (!ta) return;
20258
+ ta.setRangeText(evt.payload.text, ta.selectionStart, ta.selectionEnd, "end");
20259
+ args.applyChange(ta.value);
20260
+ });
20261
+ useEventListener(`UI:${args.events.onSetMode}`, (evt) => {
20262
+ if (!args.editorId || !isSetModePayload(evt.payload) || evt.payload.editorId !== args.editorId) return;
20263
+ setCaretMode(evt.payload.caret);
20264
+ });
20265
+ return { caretMode };
20266
+ }
20267
+ var init_useEditorCapabilities = __esm({
20268
+ "components/core/molecules/markdown/useEditorCapabilities.ts"() {
20269
+ "use client";
20270
+ init_useEventBus();
20271
+ init_editorMotions();
20272
+ }
20273
+ });
19549
20274
  function isLanguageRegistered(lang) {
19550
20275
  return CODE_LANGUAGE_SET.has(lang) || dynamicallyLoaded.has(lang);
19551
20276
  }
@@ -19631,7 +20356,36 @@ function useLanguageReady(language) {
19631
20356
  }, [language]);
19632
20357
  return ready;
19633
20358
  }
19634
- var dynamicallyLoaded, codeLanguageLoader, orbStyleOverrides, orbStyle, loloStyleOverrides, loloStyle, log4, CODE_LANGUAGES, CODE_LANGUAGE_SET, DIFF_STYLES, DIFF_STYLE_FALLBACK, LINE_PROPS_FN, HIDDEN_LINE_NUMBERS, CodeBlock;
20359
+ function resolveHighlightStyle(lang) {
20360
+ if (lang === "orb") return orbStyle;
20361
+ if (lang === "lolo") return loloStyle;
20362
+ return dark;
20363
+ }
20364
+ function plainCodeColorOf(style) {
20365
+ return style['code[class*="language-"]']?.color ?? "#d4d4d4";
20366
+ }
20367
+ function buildLineProps(errorLines, extraClassName) {
20368
+ return (lineNumber) => {
20369
+ const base = {
20370
+ "data-line": String(lineNumber - 1),
20371
+ ...extraClassName ? { className: extraClassName } : {}
20372
+ };
20373
+ const severity = errorLines?.get(lineNumber);
20374
+ if (!severity) return base;
20375
+ return {
20376
+ ...base,
20377
+ style: {
20378
+ display: "block",
20379
+ backgroundColor: severity === "error" ? "rgba(248, 113, 113, 0.18)" : "rgba(251, 191, 36, 0.18)",
20380
+ // amber-400 @ 18%
20381
+ borderLeft: `3px solid ${severity === "error" ? "#ef4444" : "#f59e0b"}`,
20382
+ paddingLeft: "0.5rem",
20383
+ marginLeft: "-0.5rem"
20384
+ }
20385
+ };
20386
+ };
20387
+ }
20388
+ var dynamicallyLoaded, codeLanguageLoader, orbStyleOverrides, orbStyle, loloStyleOverrides, loloStyle, log4, CODE_LANGUAGES, CODE_LANGUAGE_SET, DIFF_STYLES, DIFF_STYLE_FALLBACK, LINE_PROPS_FN, HIDDEN_LINE_NUMBERS, HIGHLIGHT_CAPACITY_BYTES, MONO_FONT_FAMILY, VIEWER_LINE_NUMBER_STYLE, CodeBlock;
19635
20389
  var init_CodeBlock = __esm({
19636
20390
  "components/core/molecules/markdown/CodeBlock.tsx"() {
19637
20391
  init_cn();
@@ -19647,6 +20401,7 @@ var init_CodeBlock = __esm({
19647
20401
  init_Textarea();
19648
20402
  init_Icon();
19649
20403
  init_useEventBus();
20404
+ init_useEditorCapabilities();
19650
20405
  SyntaxHighlighter.registerLanguage("json", langJson);
19651
20406
  SyntaxHighlighter.registerLanguage("javascript", langJavascript);
19652
20407
  SyntaxHighlighter.registerLanguage("js", langJavascript);
@@ -19864,7 +20619,17 @@ var init_CodeBlock = __esm({
19864
20619
  DIFF_STYLE_FALLBACK = { bg: "", prefix: " ", text: "text-foreground" };
19865
20620
  LINE_PROPS_FN = (n) => ({ "data-line": String(n - 1) });
19866
20621
  HIDDEN_LINE_NUMBERS = { display: "none" };
19867
- CodeBlock = React95__default.memo(
20622
+ HIGHLIGHT_CAPACITY_BYTES = 512 * 1024;
20623
+ MONO_FONT_FAMILY = 'ui-monospace, SFMono-Regular, Menlo, Monaco, "Cascadia Mono", "Courier New", monospace';
20624
+ VIEWER_LINE_NUMBER_STYLE = {
20625
+ minWidth: "2.5em",
20626
+ paddingRight: "1rem",
20627
+ textAlign: "right",
20628
+ userSelect: "none",
20629
+ opacity: 0.5,
20630
+ fontVariantNumeric: "tabular-nums"
20631
+ };
20632
+ CodeBlock = React96__default.memo(
19868
20633
  ({
19869
20634
  code: rawCode,
19870
20635
  language = "text",
@@ -19888,13 +20653,39 @@ var init_CodeBlock = __esm({
19888
20653
  actions,
19889
20654
  isLoading = false,
19890
20655
  error,
19891
- showCopy
20656
+ showCopy,
20657
+ // editor capability surface — P1 wires these
20658
+ editorId,
20659
+ onEditorFocus = "EDITOR_FOCUS",
20660
+ onEditorBlur = "EDITOR_BLUR",
20661
+ onMotion = "MOTION",
20662
+ onOperate = "OPERATE",
20663
+ onInsertText = "INSERT_TEXT",
20664
+ onSetMode = "SET_MODE",
20665
+ motions = [
20666
+ "left",
20667
+ "right",
20668
+ "up",
20669
+ "down",
20670
+ "word-forward",
20671
+ "word-back",
20672
+ "word-end",
20673
+ "line-start",
20674
+ "line-end",
20675
+ "first-nonblank",
20676
+ "doc-start",
20677
+ "doc-end",
20678
+ "paragraph-forward",
20679
+ "paragraph-back",
20680
+ "line",
20681
+ "selection"
20682
+ ],
20683
+ operators = ["delete", "yank", "change"]
19892
20684
  }) => {
19893
20685
  const code = typeof rawCode === "string" ? rawCode : String(rawCode ?? "");
19894
- const isOrb = language === "orb";
19895
- const isLolo = language === "lolo";
19896
- const activeStyle = isOrb ? orbStyle : isLolo ? loloStyle : dark;
19897
- const languageReady = useLanguageReady(language);
20686
+ const activeStyle = resolveHighlightStyle(language);
20687
+ const overCapacity = code.length > HIGHLIGHT_CAPACITY_BYTES;
20688
+ const plainCodeColor = plainCodeColorOf(activeStyle);
19898
20689
  const eventBus = useEventBus();
19899
20690
  const { t } = useTranslate();
19900
20691
  const scrollRef = useRef(null);
@@ -19906,6 +20697,9 @@ var init_CodeBlock = __esm({
19906
20697
  const activeFile = files?.[activeFileIndex];
19907
20698
  const activeCode = activeFile?.code ?? code;
19908
20699
  const activeLanguage = activeFile?.language ?? language;
20700
+ const languageReady = useLanguageReady(activeLanguage);
20701
+ const viewerStyle = resolveHighlightStyle(activeLanguage);
20702
+ const viewerPlainCodeColor = plainCodeColorOf(viewerStyle);
19909
20703
  const diffLines = useMemo(() => {
19910
20704
  if (propDiff) return propDiff;
19911
20705
  if (mode === "diff" && oldValue !== void 0 && newValue !== void 0) {
@@ -19935,33 +20729,33 @@ var init_CodeBlock = __esm({
19935
20729
  ov.scrollLeft = ta.scrollLeft;
19936
20730
  }
19937
20731
  }, []);
19938
- const errorLineProps = useMemo(() => {
19939
- if (!errorLines || errorLines.size === 0) {
19940
- return LINE_PROPS_FN;
19941
- }
19942
- return (lineNumber) => {
19943
- const severity = errorLines.get(lineNumber);
19944
- if (!severity) {
19945
- return { "data-line": String(lineNumber - 1) };
19946
- }
19947
- return {
19948
- "data-line": String(lineNumber - 1),
19949
- style: {
19950
- display: "block",
19951
- backgroundColor: severity === "error" ? "rgba(248, 113, 113, 0.18)" : "rgba(251, 191, 36, 0.18)",
19952
- // amber-400 @ 18%
19953
- borderLeft: `3px solid ${severity === "error" ? "#ef4444" : "#f59e0b"}`,
19954
- paddingLeft: "0.5rem",
19955
- marginLeft: "-0.5rem"
19956
- }
19957
- };
19958
- };
19959
- }, [errorLines]);
20732
+ const handleEditableChange = useCallback((v) => {
20733
+ lastPropCodeRef.current = v;
20734
+ setEditableValue(v);
20735
+ onChange?.(v);
20736
+ }, [onChange]);
20737
+ const { caretMode } = useEditorCapabilities({
20738
+ editorId: editable ? editorId : void 0,
20739
+ textareaRef: editableTextareaRef,
20740
+ events: { onMotion, onOperate, onInsertText, onSetMode },
20741
+ applyChange: handleEditableChange
20742
+ });
20743
+ const [caretIndex, setCaretIndex] = useState(0);
20744
+ const caretRowCol = useMemo(() => {
20745
+ const before = editableValue.slice(0, Math.min(caretIndex, editableValue.length));
20746
+ const lines = before.split("\n");
20747
+ return { row: lines.length - 1, col: lines[lines.length - 1].length };
20748
+ }, [editableValue, caretIndex]);
20749
+ const errorLineProps = useMemo(() => buildLineProps(errorLines), [errorLines]);
20750
+ const viewerLineProps = useMemo(
20751
+ () => buildLineProps(errorLines, "px-4 py-0.5 hover:bg-muted/50"),
20752
+ [errorLines]
20753
+ );
19960
20754
  const isFoldable = foldableProp ?? true;
19961
20755
  const [collapsed, setCollapsed] = useState(() => /* @__PURE__ */ new Set());
19962
20756
  const foldRegions = useMemo(
19963
- () => isFoldable ? computeFoldRegions(code) : [],
19964
- [code, isFoldable]
20757
+ () => isFoldable && !overCapacity ? computeFoldRegions(code) : [],
20758
+ [code, isFoldable, overCapacity]
19965
20759
  );
19966
20760
  const foldStartMap = useMemo(() => {
19967
20761
  const m = /* @__PURE__ */ new Map();
@@ -19995,8 +20789,67 @@ var init_CodeBlock = __esm({
19995
20789
  useEffect(() => {
19996
20790
  setCollapsed(/* @__PURE__ */ new Set());
19997
20791
  }, [code]);
20792
+ const editableOverCapacity = editableValue.length > HIGHLIGHT_CAPACITY_BYTES;
20793
+ const editableHighlightedElement = useMemo(
20794
+ () => editableOverCapacity ? /* @__PURE__ */ jsx(
20795
+ "div",
20796
+ {
20797
+ style: {
20798
+ padding: "1rem",
20799
+ margin: 0,
20800
+ whiteSpace: "pre",
20801
+ minWidth: "100%",
20802
+ color: plainCodeColor,
20803
+ fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, "Cascadia Mono", "Courier New", monospace',
20804
+ fontSize: "13px",
20805
+ lineHeight: "1.5"
20806
+ },
20807
+ children: editableValue || " "
20808
+ }
20809
+ ) : /* @__PURE__ */ jsx(
20810
+ SyntaxHighlighter,
20811
+ {
20812
+ PreTag: "div",
20813
+ language,
20814
+ style: activeStyle,
20815
+ wrapLines: errorLines && errorLines.size > 0,
20816
+ lineProps: errorLineProps,
20817
+ customStyle: {
20818
+ backgroundColor: "transparent",
20819
+ borderRadius: 0,
20820
+ padding: "1rem",
20821
+ margin: 0,
20822
+ whiteSpace: "pre",
20823
+ minWidth: "100%",
20824
+ fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, "Cascadia Mono", "Courier New", monospace',
20825
+ fontSize: "13px",
20826
+ lineHeight: "1.5"
20827
+ },
20828
+ codeTagProps: {
20829
+ style: {
20830
+ fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, "Cascadia Mono", "Courier New", monospace',
20831
+ fontSize: "13px",
20832
+ lineHeight: "1.5"
20833
+ }
20834
+ },
20835
+ children: editableValue || " "
20836
+ }
20837
+ ),
20838
+ [editableValue, editableOverCapacity, plainCodeColor, language, activeStyle, errorLines, errorLineProps, languageReady]
20839
+ );
19998
20840
  const highlightedElement = useMemo(
19999
- () => /* @__PURE__ */ jsx(
20841
+ () => overCapacity ? /* @__PURE__ */ jsx(
20842
+ "div",
20843
+ {
20844
+ style: {
20845
+ margin: 0,
20846
+ whiteSpace: "pre",
20847
+ minWidth: "100%",
20848
+ color: plainCodeColor
20849
+ },
20850
+ children: code
20851
+ }
20852
+ ) : /* @__PURE__ */ jsx(
20000
20853
  SyntaxHighlighter,
20001
20854
  {
20002
20855
  PreTag: "div",
@@ -20018,8 +20871,112 @@ var init_CodeBlock = __esm({
20018
20871
  children: code
20019
20872
  }
20020
20873
  ),
20021
- [code, language, activeStyle, languageReady]
20874
+ [code, overCapacity, plainCodeColor, language, activeStyle, languageReady]
20875
+ );
20876
+ const viewerOverCapacity = activeCode.length > HIGHLIGHT_CAPACITY_BYTES;
20877
+ const viewerHighlightedElement = useMemo(
20878
+ () => viewerOverCapacity ? /* @__PURE__ */ jsx(
20879
+ "div",
20880
+ {
20881
+ className: "px-4 py-0.5",
20882
+ style: {
20883
+ margin: 0,
20884
+ whiteSpace: wrap ? "pre-wrap" : "pre",
20885
+ wordBreak: wrap ? "break-all" : "normal",
20886
+ color: viewerPlainCodeColor,
20887
+ fontFamily: MONO_FONT_FAMILY,
20888
+ fontSize: "12px",
20889
+ lineHeight: "1.6"
20890
+ },
20891
+ children: activeCode
20892
+ }
20893
+ ) : /* @__PURE__ */ jsx(
20894
+ SyntaxHighlighter,
20895
+ {
20896
+ PreTag: "div",
20897
+ language: activeLanguage,
20898
+ style: viewerStyle,
20899
+ wrapLines: true,
20900
+ wrapLongLines: wrap,
20901
+ showLineNumbers,
20902
+ lineNumberStyle: VIEWER_LINE_NUMBER_STYLE,
20903
+ lineProps: viewerLineProps,
20904
+ customStyle: {
20905
+ backgroundColor: "transparent",
20906
+ borderRadius: 0,
20907
+ padding: "0.25rem 0",
20908
+ margin: 0,
20909
+ whiteSpace: wrap ? "pre-wrap" : "pre",
20910
+ wordBreak: wrap ? "break-all" : "normal",
20911
+ fontFamily: MONO_FONT_FAMILY,
20912
+ fontSize: "12px",
20913
+ lineHeight: "1.6"
20914
+ },
20915
+ codeTagProps: { style: { fontFamily: MONO_FONT_FAMILY, fontSize: "12px", lineHeight: "1.6" } },
20916
+ children: activeCode
20917
+ }
20918
+ ),
20919
+ [activeCode, viewerOverCapacity, viewerPlainCodeColor, activeLanguage, viewerStyle, wrap, showLineNumbers, viewerLineProps, languageReady]
20920
+ );
20921
+ const diffOverCapacity = useMemo(
20922
+ () => !!diffLines && diffLines.reduce((n, l) => n + l.content.length + 1, 0) > HIGHLIGHT_CAPACITY_BYTES,
20923
+ [diffLines]
20022
20924
  );
20925
+ const diffRowElements = useMemo(() => {
20926
+ if (!diffLines) return null;
20927
+ return diffLines.map((line, idx) => {
20928
+ const style = DIFF_STYLES[line.type] ?? DIFF_STYLE_FALLBACK;
20929
+ return /* @__PURE__ */ jsxs(HStack, { gap: "none", align: "start", className: cn(style.bg, "px-4 py-0.5"), children: [
20930
+ showLineNumbers && /* @__PURE__ */ jsx(
20931
+ Typography,
20932
+ {
20933
+ variant: "caption",
20934
+ color: "secondary",
20935
+ className: "w-8 text-right mr-3 select-none tabular-nums flex-shrink-0",
20936
+ children: line.lineNumber ?? ""
20937
+ }
20938
+ ),
20939
+ /* @__PURE__ */ jsxs(
20940
+ Typography,
20941
+ {
20942
+ variant: "caption",
20943
+ className: cn("font-mono flex-1 min-w-0", style.text, wrap ? "whitespace-pre-wrap break-all" : "whitespace-pre"),
20944
+ children: [
20945
+ /* @__PURE__ */ jsx(Box, { as: "span", className: "select-none opacity-50 mr-2", children: style.prefix }),
20946
+ diffOverCapacity ? line.content || " " : /* @__PURE__ */ jsx(
20947
+ SyntaxHighlighter,
20948
+ {
20949
+ PreTag: "span",
20950
+ CodeTag: "span",
20951
+ language: activeLanguage,
20952
+ style: viewerStyle,
20953
+ customStyle: {
20954
+ display: "inline",
20955
+ background: "transparent",
20956
+ padding: 0,
20957
+ margin: 0,
20958
+ whiteSpace: wrap ? "pre-wrap" : "pre",
20959
+ wordBreak: wrap ? "break-all" : "normal",
20960
+ fontFamily: "inherit",
20961
+ fontSize: "inherit",
20962
+ lineHeight: "inherit"
20963
+ },
20964
+ codeTagProps: {
20965
+ style: {
20966
+ whiteSpace: wrap ? "pre-wrap" : "pre",
20967
+ fontFamily: "inherit",
20968
+ fontSize: "inherit"
20969
+ }
20970
+ },
20971
+ children: line.content || " "
20972
+ }
20973
+ )
20974
+ ]
20975
+ }
20976
+ )
20977
+ ] }, idx);
20978
+ });
20979
+ }, [diffLines, showLineNumbers, wrap, diffOverCapacity, activeLanguage, viewerStyle, languageReady]);
20023
20980
  useLayoutEffect(() => {
20024
20981
  const container = codeRef.current;
20025
20982
  if (!container) return;
@@ -20163,7 +21120,6 @@ var init_CodeBlock = __esm({
20163
21120
  label: file.label,
20164
21121
  content: null
20165
21122
  }));
20166
- const lines = activeCode.split("\n");
20167
21123
  return /* @__PURE__ */ jsx(Card, { className: cn("overflow-hidden", className), children: /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column" }, children: [
20168
21124
  tabItems && tabItems.length > 1 && /* @__PURE__ */ jsx(Box, { className: "border-b border-border", children: /* @__PURE__ */ jsx(
20169
21125
  Tabs,
@@ -20226,49 +21182,7 @@ var init_CodeBlock = __esm({
20226
21182
  ]
20227
21183
  }
20228
21184
  ),
20229
- /* @__PURE__ */ jsx(Box, { className: "overflow-auto bg-muted/20", style: { maxHeight }, children: diffLines ? /* @__PURE__ */ jsx("div", { style: { display: "flex", flexDirection: "column" }, className: "font-mono text-xs", children: diffLines.map((line, idx) => {
20230
- const style = DIFF_STYLES[line.type] ?? DIFF_STYLE_FALLBACK;
20231
- return /* @__PURE__ */ jsxs(HStack, { gap: "none", align: "start", className: cn(style.bg, "px-4 py-0.5"), children: [
20232
- showLineNumbers && /* @__PURE__ */ jsx(
20233
- Typography,
20234
- {
20235
- variant: "caption",
20236
- color: "secondary",
20237
- className: "w-8 text-right mr-3 select-none tabular-nums flex-shrink-0",
20238
- children: line.lineNumber ?? ""
20239
- }
20240
- ),
20241
- /* @__PURE__ */ jsxs(
20242
- Typography,
20243
- {
20244
- variant: "caption",
20245
- className: cn("font-mono flex-1 min-w-0", style.text, wrap ? "whitespace-pre-wrap break-all" : "whitespace-pre"),
20246
- children: [
20247
- /* @__PURE__ */ jsx(Box, { as: "span", className: "select-none opacity-50 mr-2", children: style.prefix }),
20248
- line.content
20249
- ]
20250
- }
20251
- )
20252
- ] }, idx);
20253
- }) }) : /* @__PURE__ */ jsx("div", { style: { display: "flex", flexDirection: "column" }, className: "font-mono text-xs", children: lines.map((line, idx) => /* @__PURE__ */ jsxs(HStack, { gap: "none", align: "start", className: "px-4 py-0.5 hover:bg-muted/50", children: [
20254
- showLineNumbers && /* @__PURE__ */ jsx(
20255
- Typography,
20256
- {
20257
- variant: "caption",
20258
- color: "secondary",
20259
- className: "w-8 text-right mr-4 select-none tabular-nums flex-shrink-0",
20260
- children: idx + 1
20261
- }
20262
- ),
20263
- /* @__PURE__ */ jsx(
20264
- Typography,
20265
- {
20266
- variant: "caption",
20267
- className: cn("font-mono flex-1 min-w-0", wrap ? "whitespace-pre-wrap break-all" : "whitespace-pre"),
20268
- children: line || " "
20269
- }
20270
- )
20271
- ] }, idx)) }) })
21185
+ /* @__PURE__ */ jsx(Box, { className: "overflow-auto bg-muted/20", style: { maxHeight }, children: diffLines ? /* @__PURE__ */ jsx("div", { style: { display: "flex", flexDirection: "column" }, className: "font-mono text-xs", children: diffRowElements }) : /* @__PURE__ */ jsx("div", { className: "font-mono text-xs", children: viewerHighlightedElement }) })
20272
21186
  ] }) });
20273
21187
  }
20274
21188
  const hasHeader = showLanguageBadge || effectiveCopy;
@@ -20347,35 +21261,7 @@ var init_CodeBlock = __esm({
20347
21261
  overflow: "hidden",
20348
21262
  pointerEvents: "none"
20349
21263
  },
20350
- children: /* @__PURE__ */ jsx(
20351
- SyntaxHighlighter,
20352
- {
20353
- PreTag: "div",
20354
- language,
20355
- style: activeStyle,
20356
- wrapLines: errorLines && errorLines.size > 0,
20357
- lineProps: errorLineProps,
20358
- customStyle: {
20359
- backgroundColor: "transparent",
20360
- borderRadius: 0,
20361
- padding: "1rem",
20362
- margin: 0,
20363
- whiteSpace: "pre",
20364
- minWidth: "100%",
20365
- fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, "Cascadia Mono", "Courier New", monospace',
20366
- fontSize: "13px",
20367
- lineHeight: "1.5"
20368
- },
20369
- codeTagProps: {
20370
- style: {
20371
- fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, "Cascadia Mono", "Courier New", monospace',
20372
- fontSize: "13px",
20373
- lineHeight: "1.5"
20374
- }
20375
- },
20376
- children: editableValue || " "
20377
- }
20378
- )
21264
+ children: editableHighlightedElement
20379
21265
  }
20380
21266
  ),
20381
21267
  /* @__PURE__ */ jsx(
@@ -20383,13 +21269,11 @@ var init_CodeBlock = __esm({
20383
21269
  {
20384
21270
  ref: editableTextareaRef,
20385
21271
  defaultValue: code,
20386
- onChange: (e) => {
20387
- const v = e.target.value;
20388
- lastPropCodeRef.current = v;
20389
- setEditableValue(v);
20390
- onChange?.(v);
20391
- },
21272
+ onChange: (e) => handleEditableChange(e.target.value),
20392
21273
  onScroll: handleEditableScroll,
21274
+ onSelect: (e) => setCaretIndex(e.currentTarget.selectionStart),
21275
+ onFocus: editorId ? () => eventBus.emit(`UI:${onEditorFocus}`, { editorId }) : void 0,
21276
+ onBlur: editorId ? () => eventBus.emit(`UI:${onEditorBlur}`, { editorId }) : void 0,
20393
21277
  spellCheck: false,
20394
21278
  style: {
20395
21279
  position: "absolute",
@@ -20404,7 +21288,7 @@ var init_CodeBlock = __esm({
20404
21288
  resize: "none",
20405
21289
  backgroundColor: "transparent",
20406
21290
  color: "transparent",
20407
- caretColor: "#e6e6e6",
21291
+ caretColor: caretMode === "block" ? "transparent" : "#e6e6e6",
20408
21292
  WebkitTextFillColor: "transparent",
20409
21293
  fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, "Cascadia Mono", "Courier New", monospace',
20410
21294
  fontSize: "13px",
@@ -20415,6 +21299,22 @@ var init_CodeBlock = __esm({
20415
21299
  }
20416
21300
  },
20417
21301
  editableTextareaKey
21302
+ ),
21303
+ caretMode !== "bar" && /* @__PURE__ */ jsx(
21304
+ "span",
21305
+ {
21306
+ "aria-hidden": true,
21307
+ style: {
21308
+ position: "absolute",
21309
+ top: `calc(1rem + ${caretRowCol.row * 19.5}px)`,
21310
+ left: `calc(1rem + ${caretRowCol.col}ch)`,
21311
+ width: "1ch",
21312
+ height: caretMode === "block" ? "19.5px" : "2px",
21313
+ backgroundColor: caretMode === "block" ? "rgba(230, 230, 230, 0.5)" : void 0,
21314
+ borderBottom: caretMode === "underline" ? "2px solid #e6e6e6" : void 0,
21315
+ pointerEvents: "none"
21316
+ }
21317
+ }
20418
21318
  )
20419
21319
  ]
20420
21320
  }
@@ -20442,55 +21342,175 @@ var init_CodeBlock = __esm({
20442
21342
  )
20443
21343
  ] });
20444
21344
  },
20445
- (prev, next) => prev.language === next.language && prev.code === next.code && prev.showCopyButton === next.showCopyButton && prev.showCopy === next.showCopy && prev.maxHeight === next.maxHeight && prev.foldable === next.foldable && prev.editable === next.editable && prev.onChange === next.onChange && prev.errorLines === next.errorLines && prev.mode === next.mode && prev.title === next.title && prev.diff === next.diff && prev.files === next.files && prev.actions === next.actions && prev.isLoading === next.isLoading && prev.error === next.error
21345
+ (prev, next) => prev.language === next.language && prev.code === next.code && prev.showCopyButton === next.showCopyButton && prev.showCopy === next.showCopy && prev.maxHeight === next.maxHeight && prev.foldable === next.foldable && prev.editable === next.editable && prev.onChange === next.onChange && prev.errorLines === next.errorLines && prev.mode === next.mode && prev.title === next.title && prev.diff === next.diff && prev.files === next.files && prev.actions === next.actions && prev.isLoading === next.isLoading && prev.error === next.error && prev.editorId === next.editorId && prev.onEditorFocus === next.onEditorFocus && prev.onEditorBlur === next.onEditorBlur && prev.onMotion === next.onMotion && prev.onOperate === next.onOperate && prev.onInsertText === next.onInsertText && prev.onSetMode === next.onSetMode && prev.motions === next.motions && prev.operators === next.operators
20446
21346
  );
20447
21347
  CodeBlock.displayName = "CodeBlock";
20448
21348
  }
20449
21349
  });
21350
+
21351
+ // components/core/molecules/markdown/mermaidSource.ts
21352
+ function isQuoted(label) {
21353
+ const trimmed = label.trim();
21354
+ return trimmed.length === 0 || trimmed.startsWith('"') && trimmed.endsWith('"') && trimmed.length > 1;
21355
+ }
21356
+ function quote(label) {
21357
+ return `"${label.replace(/"/g, "#quot;")}"`;
21358
+ }
21359
+ function isIdentifierChar(ch) {
21360
+ return /[A-Za-z0-9_\-.]/.test(ch);
21361
+ }
21362
+ function declaredType(code) {
21363
+ for (const line of code.split("\n")) {
21364
+ const trimmed = line.trim();
21365
+ if (trimmed.length === 0 || trimmed.startsWith("%%")) continue;
21366
+ return trimmed;
21367
+ }
21368
+ return "";
21369
+ }
21370
+ function isFlowchart(code) {
21371
+ return FLOWCHART_DIRECTIVE.test(declaredType(code));
21372
+ }
21373
+ function quoteNodeLabels(code) {
21374
+ let out = "";
21375
+ let i = 0;
21376
+ while (i < code.length) {
21377
+ const shape = NODE_SHAPES.find(([open2]) => code.startsWith(open2, i));
21378
+ const precededByIdentifier = i > 0 && isIdentifierChar(code[i - 1] ?? "");
21379
+ if (shape === void 0 || !precededByIdentifier) {
21380
+ out += code[i];
21381
+ i += 1;
21382
+ continue;
21383
+ }
21384
+ const [open, close] = shape;
21385
+ const contentStart = i + open.length;
21386
+ const closeAt = code.indexOf(close, contentStart);
21387
+ const newlineAt = code.indexOf("\n", contentStart);
21388
+ if (closeAt === -1 || newlineAt !== -1 && newlineAt < closeAt) {
21389
+ out += code[i];
21390
+ i += 1;
21391
+ continue;
21392
+ }
21393
+ const label = code.slice(contentStart, closeAt);
21394
+ out += open + (isQuoted(label) ? label : quote(label)) + close;
21395
+ i = closeAt + close.length;
21396
+ }
21397
+ return out;
21398
+ }
21399
+ function quoteEdgeLabels(code) {
21400
+ return code.split("\n").map((line) => {
21401
+ let out = "";
21402
+ let rest = line;
21403
+ for (; ; ) {
21404
+ const open = rest.indexOf("|");
21405
+ if (open === -1) break;
21406
+ const close = rest.indexOf("|", open + 1);
21407
+ if (close === -1) break;
21408
+ const label = rest.slice(open + 1, close);
21409
+ out += rest.slice(0, open + 1) + (isQuoted(label) ? label : quote(label)) + "|";
21410
+ rest = rest.slice(close + 1);
21411
+ }
21412
+ return out + rest;
21413
+ }).join("\n");
21414
+ }
21415
+ function quoteSubgraphTitles(code) {
21416
+ return code.split("\n").map((line) => {
21417
+ const match = /^(\s*subgraph\s+)(.+?)(\s*)$/.exec(line);
21418
+ if (match === null) return line;
21419
+ const [, prefix, title, trailing] = match;
21420
+ if (title === void 0 || prefix === void 0) return line;
21421
+ if (isQuoted(title) || title.includes("[")) return line;
21422
+ return prefix + quote(title) + (trailing ?? "");
21423
+ }).join("\n");
21424
+ }
21425
+ function mermaidRepairCandidates(code) {
21426
+ if (!isFlowchart(code)) return [];
21427
+ const nodes = quoteNodeLabels(code);
21428
+ const nodesAndEdges = quoteEdgeLabels(nodes);
21429
+ const all = quoteSubgraphTitles(nodesAndEdges);
21430
+ const ordered2 = [nodes, nodesAndEdges, all];
21431
+ const seen = /* @__PURE__ */ new Set([code]);
21432
+ const candidates = [];
21433
+ for (const candidate of ordered2) {
21434
+ if (seen.has(candidate)) continue;
21435
+ seen.add(candidate);
21436
+ candidates.push(candidate);
21437
+ }
21438
+ return candidates;
21439
+ }
21440
+ var NODE_SHAPES, FLOWCHART_DIRECTIVE;
21441
+ var init_mermaidSource = __esm({
21442
+ "components/core/molecules/markdown/mermaidSource.ts"() {
21443
+ NODE_SHAPES = [
21444
+ ["[[", "]]"],
21445
+ ["[(", ")]"],
21446
+ ["([", "])"],
21447
+ ["((", "))"],
21448
+ ["{{", "}}"],
21449
+ ["[", "]"],
21450
+ ["(", ")"],
21451
+ ["{", "}"]
21452
+ ];
21453
+ FLOWCHART_DIRECTIVE = /^(?:graph|flowchart)\b/;
21454
+ }
21455
+ });
20450
21456
  function loadMermaid() {
20451
21457
  mermaidModule ?? (mermaidModule = import('mermaid').then((m) => m.default));
20452
21458
  return mermaidModule;
20453
21459
  }
20454
- var mermaidModule, MermaidDiagram;
21460
+ var log5, mermaidModule, MermaidDiagram;
20455
21461
  var init_MermaidDiagram = __esm({
20456
21462
  "components/core/molecules/markdown/MermaidDiagram.tsx"() {
20457
21463
  init_Box();
20458
21464
  init_Typography();
20459
21465
  init_CodeBlock();
21466
+ init_mermaidSource();
20460
21467
  init_cn();
21468
+ log5 = createLogger("almadar:ui:mermaid-diagram");
20461
21469
  mermaidModule = null;
20462
- MermaidDiagram = React95__default.memo(
21470
+ MermaidDiagram = React96__default.memo(
20463
21471
  ({ code, className }) => {
20464
21472
  const { resolvedMode } = useTheme();
21473
+ const { t } = useTranslate();
20465
21474
  const containerRef = useRef(null);
20466
- const [error, setError] = useState(null);
21475
+ const [unrenderable, setUnrenderable] = useState(false);
20467
21476
  const reactId = useId();
20468
21477
  useEffect(() => {
20469
21478
  let active = true;
20470
21479
  void (async () => {
20471
- try {
20472
- const mermaid = await loadMermaid();
20473
- mermaid.initialize({
20474
- startOnLoad: false,
20475
- securityLevel: "strict",
20476
- theme: resolvedMode === "dark" ? "dark" : "default"
20477
- });
20478
- const domId = `mermaid-${reactId.replace(/[^a-zA-Z0-9]/g, "")}`;
20479
- const { svg } = await mermaid.render(domId, code);
20480
- if (!active || !containerRef.current) return;
20481
- containerRef.current.innerHTML = svg;
20482
- setError(null);
20483
- } catch (err) {
20484
- if (active) setError(err instanceof Error ? err.message : String(err));
21480
+ const mermaid = await loadMermaid();
21481
+ mermaid.initialize({
21482
+ startOnLoad: false,
21483
+ securityLevel: "strict",
21484
+ theme: resolvedMode === "dark" ? "dark" : "default"
21485
+ });
21486
+ const domId = `mermaid-${reactId.replace(/[^a-zA-Z0-9]/g, "")}`;
21487
+ let firstError = null;
21488
+ for (const [index, source] of [code, ...mermaidRepairCandidates(code)].entries()) {
21489
+ try {
21490
+ const { svg } = await mermaid.render(domId, source);
21491
+ if (!active) return;
21492
+ const container = containerRef.current;
21493
+ if (container === null) return;
21494
+ container.innerHTML = svg;
21495
+ container.dataset.mermaidRepaired = String(index > 0);
21496
+ setUnrenderable(false);
21497
+ if (index > 0) log5.debug("mermaid:repaired", { candidate: index });
21498
+ return;
21499
+ } catch (err) {
21500
+ firstError ?? (firstError = err instanceof Error ? err : new Error(String(err)));
21501
+ }
20485
21502
  }
21503
+ if (!active) return;
21504
+ log5.warn("mermaid:unrenderable", { error: firstError?.message ?? "", code });
21505
+ setUnrenderable(true);
20486
21506
  })();
20487
21507
  return () => {
20488
21508
  active = false;
20489
21509
  };
20490
21510
  }, [code, resolvedMode, reactId]);
20491
21511
  return /* @__PURE__ */ jsxs(Box, { className: cn("not-prose my-4", className), children: [
20492
- error !== null && /* @__PURE__ */ jsxs(Box, { className: "space-y-2 mb-2", children: [
20493
- /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-error whitespace-pre-wrap", children: error }),
21512
+ unrenderable && /* @__PURE__ */ jsxs(Box, { className: "space-y-2 mb-2", "data-testid": "mermaid-unrenderable", children: [
21513
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: t("mermaid.unrenderable") }),
20494
21514
  /* @__PURE__ */ jsx(CodeBlock, { code, language: "mermaid" })
20495
21515
  ] }),
20496
21516
  /* @__PURE__ */ jsx(
@@ -20499,7 +21519,7 @@ var init_MermaidDiagram = __esm({
20499
21519
  ref: containerRef,
20500
21520
  "data-testid": "mermaid-diagram",
20501
21521
  className: "overflow-x-auto",
20502
- style: error !== null ? { display: "none" } : void 0
21522
+ style: unrenderable ? { display: "none" } : void 0
20503
21523
  }
20504
21524
  )
20505
21525
  ] });
@@ -20517,7 +21537,7 @@ var init_MarkdownContent = __esm({
20517
21537
  init_CodeBlock();
20518
21538
  init_MermaidDiagram();
20519
21539
  init_cn();
20520
- MarkdownContent = React95__default.memo(
21540
+ MarkdownContent = React96__default.memo(
20521
21541
  ({ content, direction = "ltr", className }) => {
20522
21542
  const { t: _t } = useTranslate();
20523
21543
  const safeContent = typeof content === "string" ? content : String(content ?? "");
@@ -21847,7 +22867,7 @@ var init_StateMachineView = __esm({
21847
22867
  style: { top: title ? 30 : 0 },
21848
22868
  children: [
21849
22869
  entity && /* @__PURE__ */ jsx(EntityBox, { entity, config }),
21850
- states.map((state) => renderStateNode ? /* @__PURE__ */ jsx(React95__default.Fragment, { children: renderStateNode(state, config) }, state.id) : /* @__PURE__ */ jsx(
22870
+ states.map((state) => renderStateNode ? /* @__PURE__ */ jsx(React96__default.Fragment, { children: renderStateNode(state, config) }, state.id) : /* @__PURE__ */ jsx(
21851
22871
  StateNode2,
21852
22872
  {
21853
22873
  state,
@@ -23904,14 +24924,14 @@ function useSafeEventBus2() {
23904
24924
  } };
23905
24925
  }
23906
24926
  }
23907
- var log5, lookStyles4, ButtonGroup;
24927
+ var log6, lookStyles4, ButtonGroup;
23908
24928
  var init_ButtonGroup = __esm({
23909
24929
  "components/core/molecules/ButtonGroup.tsx"() {
23910
24930
  "use client";
23911
24931
  init_cn();
23912
24932
  init_atoms();
23913
24933
  init_useEventBus();
23914
- log5 = createLogger("almadar:ui:button-group");
24934
+ log6 = createLogger("almadar:ui:button-group");
23915
24935
  lookStyles4 = {
23916
24936
  "right-aligned-buttons": "",
23917
24937
  "floating-bar": "fixed bottom-section left-1/2 -translate-x-1/2 shadow-elevation-toast bg-card p-card-sm rounded-container",
@@ -23992,7 +25012,7 @@ var init_ButtonGroup = __esm({
23992
25012
  {
23993
25013
  variant: "ghost",
23994
25014
  onClick: () => {
23995
- log5.debug("Filter clicked", { field: filter.field });
25015
+ log6.debug("Filter clicked", { field: filter.field });
23996
25016
  },
23997
25017
  children: filter.label
23998
25018
  },
@@ -26761,6 +27781,187 @@ var init_CodeRunnerPanel = __esm({
26761
27781
  CodeRunnerPanel.displayName = "CodeRunnerPanel";
26762
27782
  }
26763
27783
  });
27784
+ function matchesQuery(query, text) {
27785
+ if (!query) return true;
27786
+ let qi = 0;
27787
+ const q = query.toLowerCase();
27788
+ const t = text.toLowerCase();
27789
+ for (let ti = 0; ti < t.length && qi < q.length; ti++) {
27790
+ if (t[ti] === q[qi]) qi++;
27791
+ }
27792
+ return qi === q.length;
27793
+ }
27794
+ function commandMatches(command, query) {
27795
+ if (!query) return true;
27796
+ if (matchesQuery(query, command.label)) return true;
27797
+ return (command.keywords ?? []).some((keyword) => matchesQuery(query, keyword));
27798
+ }
27799
+ function dispatchCommandPaletteCommand(command, deps) {
27800
+ if (command.disabled) return;
27801
+ if (command.event) deps.emit(`UI:${command.event}`, { commandId: command.id });
27802
+ if (command.action) deps.emit(`UI:${command.action}`, command.actionPayload ?? {});
27803
+ deps.onSelect?.(command);
27804
+ }
27805
+ var UNGROUPED, CommandPalette;
27806
+ var init_CommandPalette = __esm({
27807
+ "components/core/molecules/CommandPalette.tsx"() {
27808
+ "use client";
27809
+ init_Box();
27810
+ init_Stack();
27811
+ init_Typography();
27812
+ init_Icon();
27813
+ init_Input();
27814
+ init_Badge();
27815
+ init_cn();
27816
+ init_useEventBus();
27817
+ init_Modal();
27818
+ UNGROUPED = /* @__PURE__ */ Symbol("command-palette-ungrouped");
27819
+ CommandPalette = ({
27820
+ open,
27821
+ onOpenChange,
27822
+ commands,
27823
+ onSelect,
27824
+ placeholder = "Type a command...",
27825
+ emptyLabel = "No matching commands",
27826
+ className
27827
+ }) => {
27828
+ const eventBus = useEventBus();
27829
+ const [query, setQuery] = useState("");
27830
+ const [highlightIndex, setHighlightIndex] = useState(0);
27831
+ const filtered = useMemo(
27832
+ () => commands.filter((command) => commandMatches(command, query)),
27833
+ [commands, query]
27834
+ );
27835
+ const groups = useMemo(() => {
27836
+ const order = [];
27837
+ const byGroup = /* @__PURE__ */ new Map();
27838
+ for (const command of filtered) {
27839
+ const key = command.group ?? UNGROUPED;
27840
+ if (!byGroup.has(key)) {
27841
+ byGroup.set(key, []);
27842
+ order.push(key);
27843
+ }
27844
+ byGroup.get(key).push(command);
27845
+ }
27846
+ return order.map((key) => ({ group: key === UNGROUPED ? void 0 : key, items: byGroup.get(key) }));
27847
+ }, [filtered]);
27848
+ const resetQuery = useCallback(() => {
27849
+ setQuery("");
27850
+ setHighlightIndex(0);
27851
+ }, []);
27852
+ const handleClose = useCallback(() => {
27853
+ resetQuery();
27854
+ onOpenChange(false);
27855
+ }, [onOpenChange, resetQuery]);
27856
+ const handleSelect = useCallback(
27857
+ (command) => {
27858
+ if (command.disabled) return;
27859
+ dispatchCommandPaletteCommand(command, { emit: eventBus.emit, onSelect });
27860
+ handleClose();
27861
+ },
27862
+ [eventBus, onSelect, handleClose]
27863
+ );
27864
+ const handleQueryChange = useCallback((e) => {
27865
+ setQuery(e.target.value);
27866
+ setHighlightIndex(0);
27867
+ }, []);
27868
+ const handleKeyDown = useCallback(
27869
+ (e) => {
27870
+ if (filtered.length === 0) return;
27871
+ if (e.key === "ArrowDown") {
27872
+ e.preventDefault();
27873
+ setHighlightIndex((prev) => prev < filtered.length - 1 ? prev + 1 : 0);
27874
+ } else if (e.key === "ArrowUp") {
27875
+ e.preventDefault();
27876
+ setHighlightIndex((prev) => prev > 0 ? prev - 1 : filtered.length - 1);
27877
+ } else if (e.key === "Enter") {
27878
+ e.preventDefault();
27879
+ const command = filtered[highlightIndex];
27880
+ if (command) handleSelect(command);
27881
+ }
27882
+ },
27883
+ [filtered, highlightIndex, handleSelect]
27884
+ );
27885
+ return /* @__PURE__ */ jsx(
27886
+ Modal,
27887
+ {
27888
+ isOpen: open,
27889
+ onClose: handleClose,
27890
+ onExited: resetQuery,
27891
+ showCloseButton: false,
27892
+ size: "md",
27893
+ className,
27894
+ children: /* @__PURE__ */ jsx(Box, { "data-testid": "command-palette", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
27895
+ /* @__PURE__ */ jsx(
27896
+ Input,
27897
+ {
27898
+ inputType: "search",
27899
+ placeholder,
27900
+ value: query,
27901
+ onChange: handleQueryChange,
27902
+ onKeyDown: handleKeyDown,
27903
+ leftIcon: "search",
27904
+ clearable: query.length > 0,
27905
+ onClear: resetQuery,
27906
+ autoFocus: true,
27907
+ "data-testid": "command-palette-input"
27908
+ }
27909
+ ),
27910
+ filtered.length === 0 ? /* @__PURE__ */ jsx(Box, { className: "px-2 py-6 text-center", "data-testid": "command-palette-empty", children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "muted", children: emptyLabel }) }) : /* @__PURE__ */ jsx(
27911
+ Box,
27912
+ {
27913
+ className: "max-h-80 overflow-y-auto",
27914
+ role: "listbox",
27915
+ "aria-label": placeholder,
27916
+ children: /* @__PURE__ */ jsx(VStack, { gap: "none", children: groups.map(({ group, items }) => /* @__PURE__ */ jsxs(Box, { children: [
27917
+ group ? /* @__PURE__ */ jsx(
27918
+ Typography,
27919
+ {
27920
+ variant: "caption",
27921
+ color: "muted",
27922
+ className: "px-3 pt-2 pb-1 block",
27923
+ children: group
27924
+ }
27925
+ ) : null,
27926
+ items.map((command) => {
27927
+ const index = filtered.indexOf(command);
27928
+ const isHighlighted = index === highlightIndex;
27929
+ return /* @__PURE__ */ jsxs(
27930
+ Box,
27931
+ {
27932
+ as: "button",
27933
+ role: "option",
27934
+ "aria-selected": isHighlighted,
27935
+ "aria-disabled": command.disabled || void 0,
27936
+ "data-testid": `command-palette-item-${command.id}`,
27937
+ onMouseEnter: () => !command.disabled && setHighlightIndex(index),
27938
+ onClick: () => handleSelect(command),
27939
+ className: cn(
27940
+ "w-full flex items-center gap-3 px-3 py-2 text-start rounded-sm",
27941
+ "text-sm transition-colors",
27942
+ "focus:outline-none",
27943
+ isHighlighted && "bg-muted",
27944
+ command.disabled && "opacity-50 cursor-not-allowed"
27945
+ ),
27946
+ children: [
27947
+ command.icon ? /* @__PURE__ */ jsx(Icon, { icon: command.icon, size: "sm", className: "flex-shrink-0" }) : null,
27948
+ /* @__PURE__ */ jsx(Typography, { variant: "small", className: "flex-1 truncate", children: command.label }),
27949
+ command.shortcut ? /* @__PURE__ */ jsx(Badge, { variant: "neutral", size: "sm", children: command.shortcut }) : null
27950
+ ]
27951
+ },
27952
+ command.id
27953
+ );
27954
+ })
27955
+ ] }, String(group ?? "__ungrouped__"))) })
27956
+ }
27957
+ )
27958
+ ] }) })
27959
+ }
27960
+ );
27961
+ };
27962
+ CommandPalette.displayName = "CommandPalette";
27963
+ }
27964
+ });
26764
27965
  function formatCount(count) {
26765
27966
  if (count >= 1e3) {
26766
27967
  return `${(count / 1e3).toFixed(1)}k`;
@@ -28036,7 +29237,7 @@ var init_Menu = __esm({
28036
29237
  "bottom-end": "bottom-start"
28037
29238
  };
28038
29239
  const effectivePosition = direction === "rtl" ? rtlMirror[position] ?? position : position;
28039
- const triggerElement = React95__default.isValidElement(trigger) ? React95__default.cloneElement(trigger, {
29240
+ const triggerElement = React96__default.isValidElement(trigger) ? React96__default.cloneElement(trigger, {
28040
29241
  ref: triggerRef,
28041
29242
  onClick: handleToggle
28042
29243
  }) : /* @__PURE__ */ jsx(
@@ -28139,14 +29340,14 @@ function useDataDnd(args) {
28139
29340
  const isZone = Boolean(dragGroup || accepts || sortable);
28140
29341
  const enabled = isZone || Boolean(dndRoot);
28141
29342
  const eventBus = useEventBus();
28142
- const parentRoot = React95__default.useContext(RootCtx);
29343
+ const parentRoot = React96__default.useContext(RootCtx);
28143
29344
  const isRoot = enabled && parentRoot === null;
28144
- const zoneId = React95__default.useId();
29345
+ const zoneId = React96__default.useId();
28145
29346
  const ownGroup = dragGroup ?? accepts ?? zoneId;
28146
- const [optimisticOrders, setOptimisticOrders] = React95__default.useState(() => /* @__PURE__ */ new Map());
28147
- const optimisticOrdersRef = React95__default.useRef(optimisticOrders);
29347
+ const [optimisticOrders, setOptimisticOrders] = React96__default.useState(() => /* @__PURE__ */ new Map());
29348
+ const optimisticOrdersRef = React96__default.useRef(optimisticOrders);
28148
29349
  optimisticOrdersRef.current = optimisticOrders;
28149
- const clearOptimisticOrder = React95__default.useCallback((group) => {
29350
+ const clearOptimisticOrder = React96__default.useCallback((group) => {
28150
29351
  setOptimisticOrders((prev) => {
28151
29352
  if (!prev.has(group)) return prev;
28152
29353
  const next = new Map(prev);
@@ -28171,7 +29372,7 @@ function useDataDnd(args) {
28171
29372
  const raw = it[dndItemIdField];
28172
29373
  return raw != null ? String(raw) : `__idx_${idx}`;
28173
29374
  }).join("|");
28174
- const itemIds = React95__default.useMemo(
29375
+ const itemIds = React96__default.useMemo(
28175
29376
  () => orderedItems.map((it, idx) => {
28176
29377
  const raw = it[dndItemIdField];
28177
29378
  return raw != null ? String(raw) : `__idx_${idx}`;
@@ -28182,7 +29383,7 @@ function useDataDnd(args) {
28182
29383
  const raw = it[dndItemIdField];
28183
29384
  return raw != null ? String(raw) : `__${idx}`;
28184
29385
  }).join("|");
28185
- React95__default.useEffect(() => {
29386
+ React96__default.useEffect(() => {
28186
29387
  const root = isRoot ? null : parentRoot;
28187
29388
  if (root) {
28188
29389
  root.clearOptimisticOrder(ownGroup);
@@ -28190,20 +29391,20 @@ function useDataDnd(args) {
28190
29391
  clearOptimisticOrder(ownGroup);
28191
29392
  }
28192
29393
  }, [itemsContentSig, ownGroup]);
28193
- const zonesRef = React95__default.useRef(/* @__PURE__ */ new Map());
28194
- const registerZone = React95__default.useCallback((zoneId2, meta2) => {
29394
+ const zonesRef = React96__default.useRef(/* @__PURE__ */ new Map());
29395
+ const registerZone = React96__default.useCallback((zoneId2, meta2) => {
28195
29396
  zonesRef.current.set(zoneId2, meta2);
28196
29397
  }, []);
28197
- const unregisterZone = React95__default.useCallback((zoneId2) => {
29398
+ const unregisterZone = React96__default.useCallback((zoneId2) => {
28198
29399
  zonesRef.current.delete(zoneId2);
28199
29400
  }, []);
28200
- const [activeDrag, setActiveDrag] = React95__default.useState(null);
28201
- const [overZoneGroup, setOverZoneGroup] = React95__default.useState(null);
28202
- const meta = React95__default.useMemo(
29401
+ const [activeDrag, setActiveDrag] = React96__default.useState(null);
29402
+ const [overZoneGroup, setOverZoneGroup] = React96__default.useState(null);
29403
+ const meta = React96__default.useMemo(
28203
29404
  () => ({ group: ownGroup, dropEvent, reorderEvent, positionEvent, itemIds, rawItems: items, idField: dndItemIdField }),
28204
29405
  [ownGroup, dropEvent, reorderEvent, positionEvent, itemIds, items, dndItemIdField]
28205
29406
  );
28206
- React95__default.useEffect(() => {
29407
+ React96__default.useEffect(() => {
28207
29408
  const target = isRoot ? null : parentRoot;
28208
29409
  if (!target) {
28209
29410
  zonesRef.current.set(zoneId, meta);
@@ -28222,7 +29423,7 @@ function useDataDnd(args) {
28222
29423
  }, [parentRoot, isRoot, zoneId, meta]);
28223
29424
  const sensors = useAlmadarDndSensors(true);
28224
29425
  const collisionDetection = almadarDndCollisionDetection;
28225
- const findZoneByItem = React95__default.useCallback(
29426
+ const findZoneByItem = React96__default.useCallback(
28226
29427
  (id) => {
28227
29428
  for (const z of zonesRef.current.values()) {
28228
29429
  if (z.itemIds.includes(id)) return z;
@@ -28231,7 +29432,7 @@ function useDataDnd(args) {
28231
29432
  },
28232
29433
  []
28233
29434
  );
28234
- React95__default.useCallback(
29435
+ React96__default.useCallback(
28235
29436
  (group) => {
28236
29437
  for (const z of zonesRef.current.values()) {
28237
29438
  if (z.group === group) return z;
@@ -28240,7 +29441,7 @@ function useDataDnd(args) {
28240
29441
  },
28241
29442
  []
28242
29443
  );
28243
- const handleDragEnd = React95__default.useCallback(
29444
+ const handleDragEnd = React96__default.useCallback(
28244
29445
  (event) => {
28245
29446
  const { active, over } = event;
28246
29447
  const activeIdStr = String(active.id);
@@ -28331,8 +29532,8 @@ function useDataDnd(args) {
28331
29532
  },
28332
29533
  [eventBus]
28333
29534
  );
28334
- const sortableData = React95__default.useMemo(() => ({ dndGroup: ownGroup }), [ownGroup]);
28335
- const SortableItem = React95__default.useCallback(
29535
+ const sortableData = React96__default.useMemo(() => ({ dndGroup: ownGroup }), [ownGroup]);
29536
+ const SortableItem = React96__default.useCallback(
28336
29537
  ({ id, children }) => {
28337
29538
  const {
28338
29539
  attributes,
@@ -28372,7 +29573,7 @@ function useDataDnd(args) {
28372
29573
  id: droppableId,
28373
29574
  data: sortableData
28374
29575
  });
28375
- const ctx = React95__default.useContext(RootCtx);
29576
+ const ctx = React96__default.useContext(RootCtx);
28376
29577
  const activeDrag2 = ctx?.activeDrag ?? null;
28377
29578
  const overZoneGroup2 = ctx?.overZoneGroup ?? null;
28378
29579
  const isThisZoneOver = overZoneGroup2 === ownGroup;
@@ -28387,7 +29588,7 @@ function useDataDnd(args) {
28387
29588
  showForeignPlaceholder,
28388
29589
  ctxAvailable: ctx != null
28389
29590
  });
28390
- React95__default.useEffect(() => {
29591
+ React96__default.useEffect(() => {
28391
29592
  dndLog.info("dropzone:isOver:change", { droppableId, group: ownGroup, isOver, isThisZoneOver, showForeignPlaceholder, activeDragSourceGroup: activeDrag2?.sourceGroup ?? null });
28392
29593
  }, [droppableId, isOver, isThisZoneOver, showForeignPlaceholder]);
28393
29594
  return /* @__PURE__ */ jsx(
@@ -28401,11 +29602,11 @@ function useDataDnd(args) {
28401
29602
  }
28402
29603
  );
28403
29604
  };
28404
- const rootContextValue = React95__default.useMemo(
29605
+ const rootContextValue = React96__default.useMemo(
28405
29606
  () => ({ registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder }),
28406
29607
  [registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder]
28407
29608
  );
28408
- const handleDragStart = React95__default.useCallback((event) => {
29609
+ const handleDragStart = React96__default.useCallback((event) => {
28409
29610
  const sourceZone = findZoneByItem(event.active.id);
28410
29611
  const rect = event.active.rect.current.initial;
28411
29612
  const height = rect?.height && rect.height > 0 ? rect.height : 64;
@@ -28424,7 +29625,7 @@ function useDataDnd(args) {
28424
29625
  isRoot
28425
29626
  });
28426
29627
  }, [findZoneByItem, isRoot, zoneId]);
28427
- const handleDragOver = React95__default.useCallback((event) => {
29628
+ const handleDragOver = React96__default.useCallback((event) => {
28428
29629
  const { active, over } = event;
28429
29630
  const overData = over?.data?.current;
28430
29631
  const overGroup = overData?.dndGroup ?? null;
@@ -28494,7 +29695,7 @@ function useDataDnd(args) {
28494
29695
  return next;
28495
29696
  });
28496
29697
  }, []);
28497
- const handleDragCancel = React95__default.useCallback((event) => {
29698
+ const handleDragCancel = React96__default.useCallback((event) => {
28498
29699
  setActiveDrag(null);
28499
29700
  setOverZoneGroup(null);
28500
29701
  dndLog.warn("dragCancel", {
@@ -28502,12 +29703,12 @@ function useDataDnd(args) {
28502
29703
  reason: "dnd-kit cancelled the drag (escape key, pointer interrupted, or external)"
28503
29704
  });
28504
29705
  }, []);
28505
- const handleDragEndWithCleanup = React95__default.useCallback((event) => {
29706
+ const handleDragEndWithCleanup = React96__default.useCallback((event) => {
28506
29707
  handleDragEnd(event);
28507
29708
  setActiveDrag(null);
28508
29709
  setOverZoneGroup(null);
28509
29710
  }, [handleDragEnd]);
28510
- const wrapContainer = React95__default.useCallback(
29711
+ const wrapContainer = React96__default.useCallback(
28511
29712
  (children) => {
28512
29713
  if (!enabled) return children;
28513
29714
  const strategy = layout === "grid" ? rectSortingStrategy : verticalListSortingStrategy;
@@ -28561,7 +29762,7 @@ var init_useDataDnd = __esm({
28561
29762
  init_useAlmadarDndCollision();
28562
29763
  init_Box();
28563
29764
  dndLog = createLogger("almadar:ui:dnd");
28564
- RootCtx = React95__default.createContext(null);
29765
+ RootCtx = React96__default.createContext(null);
28565
29766
  }
28566
29767
  });
28567
29768
  function renderIconInput(icon, props) {
@@ -29076,7 +30277,7 @@ function DataList({
29076
30277
  }) {
29077
30278
  const eventBus = useEventBus();
29078
30279
  const { t } = useTranslate();
29079
- const [visibleCount, setVisibleCount] = React95__default.useState(pageSize || Infinity);
30280
+ const [visibleCount, setVisibleCount] = React96__default.useState(pageSize || Infinity);
29080
30281
  const fieldDefs = fields ?? columns ?? [];
29081
30282
  const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
29082
30283
  const dnd = useDataDnd({
@@ -29092,14 +30293,14 @@ function DataList({
29092
30293
  dndRoot
29093
30294
  });
29094
30295
  const orderedData = dnd.orderedItems;
29095
- const allData = React95__default.useMemo(
30296
+ const allData = React96__default.useMemo(
29096
30297
  () => sortRows(orderedData, sortBy, sortDirection),
29097
30298
  [orderedData, sortBy, sortDirection]
29098
30299
  );
29099
30300
  const data = pageSize > 0 ? allData.slice(0, visibleCount) : allData;
29100
30301
  const hasMoreLocal = pageSize > 0 && visibleCount < allData.length;
29101
30302
  const hasRenderProp = typeof children === "function";
29102
- React95__default.useEffect(() => {
30303
+ React96__default.useEffect(() => {
29103
30304
  const renderItemTypeOf = typeof schemaRenderItem;
29104
30305
  const childrenTypeOf = typeof children;
29105
30306
  if (data.length > 0 && !hasRenderProp) {
@@ -29219,7 +30420,7 @@ function DataList({
29219
30420
  return v === void 0 || v === null || v === "" ? raw : String(v);
29220
30421
  };
29221
30422
  return /* @__PURE__ */ jsxs(VStack, { gap: "sm", className: cn("py-2", className), children: [
29222
- groups2.map((group, gi) => /* @__PURE__ */ jsxs(React95__default.Fragment, { children: [
30423
+ groups2.map((group, gi) => /* @__PURE__ */ jsxs(React96__default.Fragment, { children: [
29223
30424
  group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: "my-2" }),
29224
30425
  group.items.map((itemData, index) => {
29225
30426
  const id = itemData.id || `${gi}-${index}`;
@@ -29435,7 +30636,7 @@ function DataList({
29435
30636
  className
29436
30637
  ),
29437
30638
  children: [
29438
- groups.map((group, gi) => /* @__PURE__ */ jsxs(React95__default.Fragment, { children: [
30639
+ groups.map((group, gi) => /* @__PURE__ */ jsxs(React96__default.Fragment, { children: [
29439
30640
  group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: gi > 0 ? "mt-4" : "mt-0" }),
29440
30641
  group.items.map(
29441
30642
  (itemData, index) => renderItem(itemData, index, gi === groups.length - 1 && index === group.items.length - 1)
@@ -29522,7 +30723,7 @@ var init_FormSection = __esm({
29522
30723
  columns = 1,
29523
30724
  className
29524
30725
  }) => {
29525
- const [collapsed, setCollapsed] = React95__default.useState(defaultCollapsed);
30726
+ const [collapsed, setCollapsed] = React96__default.useState(defaultCollapsed);
29526
30727
  const { t } = useTranslate();
29527
30728
  const eventBus = useEventBus();
29528
30729
  const gridClass = {
@@ -29530,7 +30731,7 @@ var init_FormSection = __esm({
29530
30731
  2: "grid-cols-1 md:grid-cols-2",
29531
30732
  3: "grid-cols-1 md:grid-cols-2 lg:grid-cols-3"
29532
30733
  }[columns];
29533
- React95__default.useCallback(() => {
30734
+ React96__default.useCallback(() => {
29534
30735
  if (collapsible) {
29535
30736
  setCollapsed((prev) => !prev);
29536
30737
  eventBus.emit("UI:TOGGLE_COLLAPSE", { collapsed: !collapsed });
@@ -30190,10 +31391,10 @@ var init_FileTree = __esm({
30190
31391
  indent = 16
30191
31392
  }) => {
30192
31393
  const [overrides, setOverrides] = useState(() => /* @__PURE__ */ new Map());
30193
- const byId = React95__default.useMemo(() => new Map(items.map((node) => [node.id, node])), [items]);
30194
- const selectedAncestors = React95__default.useMemo(() => ancestorsOf(selectedId, byId), [selectedId, byId]);
30195
- const lastSelectedRef = React95__default.useRef(selectedId);
30196
- React95__default.useEffect(() => {
31394
+ const byId = React96__default.useMemo(() => new Map(items.map((node) => [node.id, node])), [items]);
31395
+ const selectedAncestors = React96__default.useMemo(() => ancestorsOf(selectedId, byId), [selectedId, byId]);
31396
+ const lastSelectedRef = React96__default.useRef(selectedId);
31397
+ React96__default.useEffect(() => {
30197
31398
  if (selectedId === lastSelectedRef.current) return;
30198
31399
  lastSelectedRef.current = selectedId;
30199
31400
  setOverrides((prev) => {
@@ -31027,7 +32228,7 @@ var init_Flex = __esm({
31027
32228
  flexStyle.flexBasis = typeof basis === "number" ? `${basis}px` : basis;
31028
32229
  }
31029
32230
  }
31030
- return React95__default.createElement(Component, {
32231
+ return React96__default.createElement(Component, {
31031
32232
  className: cn(
31032
32233
  inline ? "inline-flex" : "flex",
31033
32234
  directionStyles[direction],
@@ -31146,7 +32347,7 @@ var init_Grid = __esm({
31146
32347
  as: Component = "div"
31147
32348
  }) => {
31148
32349
  const mergedStyle = rows ? { gridTemplateRows: `repeat(${rows}, minmax(0, 1fr))`, ...style } : style;
31149
- return React95__default.createElement(
32350
+ return React96__default.createElement(
31150
32351
  Component,
31151
32352
  {
31152
32353
  className: cn(
@@ -31568,9 +32769,9 @@ var init_Popover = __esm({
31568
32769
  onMouseLeave: handleClose,
31569
32770
  onPointerDown: tapTriggerProps.onPointerDown
31570
32771
  };
31571
- const childElement = React95__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
32772
+ const childElement = React96__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
31572
32773
  const childPointerDown = childElement.props.onPointerDown;
31573
- const triggerElement = React95__default.cloneElement(
32774
+ const triggerElement = React96__default.cloneElement(
31574
32775
  childElement,
31575
32776
  {
31576
32777
  ref: triggerRef,
@@ -31634,9 +32835,9 @@ function debug(...args) {
31634
32835
  const [first, ...rest] = args;
31635
32836
  const message = typeof first === "string" ? first : "<debug>";
31636
32837
  if (rest.length === 0 && typeof first === "string") {
31637
- log6.debug(message);
32838
+ log7.debug(message);
31638
32839
  } else {
31639
- log6.debug(message, { args: rest.length > 0 ? formatArgs(rest) : formatArgs([first]) });
32840
+ log7.debug(message, { args: rest.length > 0 ? formatArgs(rest) : formatArgs([first]) });
31640
32841
  }
31641
32842
  }
31642
32843
  function debugGroup(label) {
@@ -31664,11 +32865,11 @@ function toLogMetaValue(v) {
31664
32865
  }
31665
32866
  return String(v);
31666
32867
  }
31667
- var NAMESPACE, log6;
32868
+ var NAMESPACE, log7;
31668
32869
  var init_debug = __esm({
31669
32870
  "lib/debug.ts"() {
31670
32871
  NAMESPACE = "almadar:ui:debug";
31671
- log6 = createLogger(NAMESPACE);
32872
+ log7 = createLogger(NAMESPACE);
31672
32873
  createLogger("almadar:ui:debug:input");
31673
32874
  createLogger("almadar:ui:debug:collision");
31674
32875
  createLogger("almadar:ui:debug:physics");
@@ -32184,9 +33385,9 @@ var init_Tooltip = __esm({
32184
33385
  if (hideTimeoutRef.current) clearTimeout(hideTimeoutRef.current);
32185
33386
  };
32186
33387
  }, []);
32187
- const triggerElement = React95__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
33388
+ const triggerElement = React96__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
32188
33389
  const childPointerDown = triggerElement.props.onPointerDown;
32189
- const trigger = React95__default.cloneElement(triggerElement, {
33390
+ const trigger = React96__default.cloneElement(triggerElement, {
32190
33391
  ref: triggerRef,
32191
33392
  onMouseEnter: handleMouseEnter,
32192
33393
  onMouseLeave: handleMouseLeave,
@@ -32276,7 +33477,7 @@ var init_WizardProgress = __esm({
32276
33477
  children: /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", children: normalizedSteps.map((step, index) => {
32277
33478
  const isActive = index === currentStep;
32278
33479
  const isCompleted = index < currentStep;
32279
- return /* @__PURE__ */ jsxs(React95__default.Fragment, { children: [
33480
+ return /* @__PURE__ */ jsxs(React96__default.Fragment, { children: [
32280
33481
  /* @__PURE__ */ jsx(
32281
33482
  "button",
32282
33483
  {
@@ -33321,6 +34522,7 @@ var init_MathCanvas = __esm({
33321
34522
  init_perf();
33322
34523
  init_atoms();
33323
34524
  init_Stack();
34525
+ init_gameFonts();
33324
34526
  init_LearningCanvas();
33325
34527
  MathCanvas = ({
33326
34528
  className,
@@ -33340,6 +34542,7 @@ var init_MathCanvas = __esm({
33340
34542
  showTickLabels = false,
33341
34543
  tickLabelFontSize = 10,
33342
34544
  labelFontSize = 12,
34545
+ fontFamily: fontFamilyProp,
33343
34546
  showCurveLabels = false,
33344
34547
  curves = [],
33345
34548
  points = [],
@@ -33362,6 +34565,7 @@ var init_MathCanvas = __esm({
33362
34565
  error
33363
34566
  }) => {
33364
34567
  const eventBus = useEventBus();
34568
+ const fontFamily = resolveGameFontFamily(fontFamilyProp);
33365
34569
  const keyMapKey = keyMap ? JSON.stringify(keyMap) : null;
33366
34570
  const keyUpMapKey = keyUpMap ? JSON.stringify(keyUpMap) : null;
33367
34571
  const stableKeyMap = useMemo(() => keyMap, [keyMapKey]);
@@ -33411,18 +34615,18 @@ var init_MathCanvas = __esm({
33411
34615
  let kx = 0;
33412
34616
  for (let x = Math.ceil(xMin / gridStep) * gridStep; x <= xMax; x += gridStep, kx++) {
33413
34617
  if (kx % labelEveryX === 0 && x !== 0) {
33414
- out.push({ type: "text", x: mapX(x), y: xAxisY + 12, text: formatTick(x), color: "#6b7280", fontSize: tickLabelFontSize, align: "center" });
34618
+ out.push({ type: "text", fontFamily, x: mapX(x), y: xAxisY + 12, text: formatTick(x), color: "#6b7280", fontSize: tickLabelFontSize, align: "center" });
33415
34619
  }
33416
34620
  }
33417
34621
  const labelEveryY = Math.max(1, Math.ceil((yMax - yMin) / gridStep / Math.floor(plotH / 28)));
33418
34622
  let ky = 0;
33419
34623
  for (let y = Math.ceil(yMin / gridStep) * gridStep; y <= yMax; y += gridStep, ky++) {
33420
34624
  if (ky % labelEveryY === 0 && y !== 0) {
33421
- out.push({ type: "text", x: yAxisX - 6, y: mapY(y), text: formatTick(y), color: "#6b7280", fontSize: tickLabelFontSize, align: "right" });
34625
+ out.push({ type: "text", fontFamily, x: yAxisX - 6, y: mapY(y), text: formatTick(y), color: "#6b7280", fontSize: tickLabelFontSize, align: "right" });
33422
34626
  }
33423
34627
  }
33424
34628
  if (xMin <= 0 && xMax >= 0 && yMin <= 0 && yMax >= 0) {
33425
- out.push({ type: "text", x: yAxisX - 6, y: xAxisY + 12, text: "0", color: "#6b7280", fontSize: tickLabelFontSize, align: "right" });
34629
+ out.push({ type: "text", fontFamily, x: yAxisX - 6, y: xAxisY + 12, text: "0", color: "#6b7280", fontSize: tickLabelFontSize, align: "right" });
33426
34630
  }
33427
34631
  }
33428
34632
  for (const region of regions) {
@@ -33449,6 +34653,7 @@ var init_MathCanvas = __esm({
33449
34653
  const mid = Math.floor(region.samples.length / 2);
33450
34654
  out.push({
33451
34655
  type: "text",
34656
+ fontFamily,
33452
34657
  x: mapX((first.x + last.x) / 2),
33453
34658
  y: (mapY(region.samples[mid].y) + mapY(baseline)) / 2,
33454
34659
  text: region.label,
@@ -33485,14 +34690,14 @@ var init_MathCanvas = __esm({
33485
34690
  const px = mapX(guide.at);
33486
34691
  out.push({ type: "line", x1: px, y1: margin, x2: px, y2: height - margin, color, dash });
33487
34692
  if (guide.label) {
33488
- out.push({ type: "text", x: px + 4, y: margin + 10, text: guide.label, color, fontSize: 11 });
34693
+ out.push({ type: "text", fontFamily, x: px + 4, y: margin + 10, text: guide.label, color, fontSize: 11 });
33489
34694
  }
33490
34695
  } else {
33491
34696
  if (guide.at < yMin || guide.at > yMax) continue;
33492
34697
  const py = mapY(guide.at);
33493
34698
  out.push({ type: "line", x1: margin, y1: py, x2: width - margin, y2: py, color, dash });
33494
34699
  if (guide.label) {
33495
- out.push({ type: "text", x: width - margin - 4, y: py - 8, text: guide.label, color, fontSize: labelFontSize, align: "right" });
34700
+ out.push({ type: "text", fontFamily, x: width - margin - 4, y: py - 8, text: guide.label, color, fontSize: labelFontSize, align: "right" });
33496
34701
  }
33497
34702
  }
33498
34703
  }
@@ -33531,6 +34736,7 @@ var init_MathCanvas = __esm({
33531
34736
  if (showCurveLabels && curve.label && lastInRange) {
33532
34737
  out.push({
33533
34738
  type: "text",
34739
+ fontFamily,
33534
34740
  x: mapX(lastInRange.x) + 6,
33535
34741
  y: mapY(lastInRange.y) - 6,
33536
34742
  text: curve.label,
@@ -33568,6 +34774,7 @@ var init_MathCanvas = __esm({
33568
34774
  if (hop.label) {
33569
34775
  out.push({
33570
34776
  type: "text",
34777
+ fontFamily,
33571
34778
  x: (x1 + x2) / 2,
33572
34779
  y: xAxisY - peak - 8,
33573
34780
  text: hop.label,
@@ -33595,6 +34802,7 @@ var init_MathCanvas = __esm({
33595
34802
  const rad = mid * Math.PI / 180;
33596
34803
  out.push({
33597
34804
  type: "text",
34805
+ fontFamily,
33598
34806
  x: mapX(angle.x + 1.35 * radius * Math.cos(rad)),
33599
34807
  y: mapY(angle.y + 1.35 * radius * Math.sin(rad)),
33600
34808
  text: angle.label,
@@ -33616,7 +34824,7 @@ var init_MathCanvas = __esm({
33616
34824
  fill: isOpen ? "#ffffff" : p.color ?? "#dc2626"
33617
34825
  });
33618
34826
  if (p.label) {
33619
- out.push({ type: "text", x: mapX(p.x) + 8, y: mapY(p.y) - 8, text: p.label, color: p.color ?? "#111827", fontSize: labelFontSize });
34827
+ out.push({ type: "text", fontFamily, x: mapX(p.x) + 8, y: mapY(p.y) - 8, text: p.label, color: p.color ?? "#111827", fontSize: labelFontSize });
33620
34828
  }
33621
34829
  }
33622
34830
  for (const v of vectors) {
@@ -33627,7 +34835,7 @@ var init_MathCanvas = __esm({
33627
34835
  const y2 = mapY(v.y + v.vy);
33628
34836
  out.push({ type: "arrow", x1, y1, x2, y2, color: v.color ?? "#7c3aed", lineWidth: 2 });
33629
34837
  if (v.label) {
33630
- out.push({ type: "text", x: x2 + 6, y: y2 - 6, text: v.label, color: v.color ?? "#7c3aed", fontSize: labelFontSize });
34838
+ out.push({ type: "text", fontFamily, x: x2 + 6, y: y2 - 6, text: v.label, color: v.color ?? "#7c3aed", fontSize: labelFontSize });
33631
34839
  }
33632
34840
  }
33633
34841
  out.push(...shapes);
@@ -33648,6 +34856,7 @@ var init_MathCanvas = __esm({
33648
34856
  showTickLabels,
33649
34857
  tickLabelFontSize,
33650
34858
  labelFontSize,
34859
+ fontFamily,
33651
34860
  showCurveLabels,
33652
34861
  curves,
33653
34862
  points,
@@ -33703,6 +34912,7 @@ var init_MathCanvas = __esm({
33703
34912
  width,
33704
34913
  height,
33705
34914
  backgroundColor,
34915
+ fontFamily,
33706
34916
  shapes: derivedShapes,
33707
34917
  drawables,
33708
34918
  projector,
@@ -34935,13 +36145,13 @@ var init_MapView = __esm({
34935
36145
  shadowSize: [41, 41]
34936
36146
  });
34937
36147
  L.Marker.prototype.options.icon = defaultIcon;
34938
- const { useEffect: useEffect68, useRef: useRef67, useCallback: useCallback98, useState: useState106 } = React95__default;
36148
+ const { useEffect: useEffect70, useRef: useRef70, useCallback: useCallback100, useState: useState109 } = React96__default;
34939
36149
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
34940
36150
  const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
34941
36151
  function MapUpdater({ centerLat, centerLng, zoom }) {
34942
36152
  const map = useMap();
34943
- const prevRef = useRef67({ centerLat, centerLng, zoom });
34944
- useEffect68(() => {
36153
+ const prevRef = useRef70({ centerLat, centerLng, zoom });
36154
+ useEffect70(() => {
34945
36155
  const prev = prevRef.current;
34946
36156
  if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
34947
36157
  map.setView([centerLat, centerLng], zoom);
@@ -34952,7 +36162,7 @@ var init_MapView = __esm({
34952
36162
  }
34953
36163
  function MapClickHandler({ onMapClick }) {
34954
36164
  const map = useMap();
34955
- useEffect68(() => {
36165
+ useEffect70(() => {
34956
36166
  if (!onMapClick) return;
34957
36167
  const handler = (e) => {
34958
36168
  onMapClick(e.latlng.lat, e.latlng.lng);
@@ -34980,8 +36190,8 @@ var init_MapView = __esm({
34980
36190
  showAttribution = true
34981
36191
  }) {
34982
36192
  const eventBus = useEventBus2();
34983
- const [clickedPosition, setClickedPosition] = useState106(null);
34984
- const handleMapClick = useCallback98((lat, lng) => {
36193
+ const [clickedPosition, setClickedPosition] = useState109(null);
36194
+ const handleMapClick = useCallback100((lat, lng) => {
34985
36195
  if (showClickedPin) {
34986
36196
  setClickedPosition({ lat, lng });
34987
36197
  }
@@ -34990,7 +36200,7 @@ var init_MapView = __esm({
34990
36200
  eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
34991
36201
  }
34992
36202
  }, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
34993
- const handleMarkerClick = useCallback98((marker) => {
36203
+ const handleMarkerClick = useCallback100((marker) => {
34994
36204
  onMarkerClick?.(marker);
34995
36205
  if (markerClickEvent) {
34996
36206
  eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
@@ -35880,8 +37090,8 @@ function TableView({
35880
37090
  }) {
35881
37091
  const eventBus = useEventBus();
35882
37092
  const { t } = useTranslate();
35883
- const [visibleCount, setVisibleCount] = React95__default.useState(pageSize > 0 ? pageSize : Infinity);
35884
- const [localSelected, setLocalSelected] = React95__default.useState(/* @__PURE__ */ new Set());
37093
+ const [visibleCount, setVisibleCount] = React96__default.useState(pageSize > 0 ? pageSize : Infinity);
37094
+ const [localSelected, setLocalSelected] = React96__default.useState(/* @__PURE__ */ new Set());
35885
37095
  const colDefs = (Array.isArray(columns) ? columns : void 0) ?? (Array.isArray(fields) ? fields : void 0) ?? [];
35886
37096
  const actionDefs = Array.isArray(itemActions) ? itemActions : [];
35887
37097
  const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
@@ -35902,7 +37112,7 @@ function TableView({
35902
37112
  const hasMore = pageSize > 0 && visibleCount < ordered2.length;
35903
37113
  const hasRenderProp = typeof children === "function";
35904
37114
  const idField = dndItemIdField ?? "id";
35905
- React95__default.useEffect(() => {
37115
+ React96__default.useEffect(() => {
35906
37116
  tableViewLog.debug("render", {
35907
37117
  rowCount: data.length,
35908
37118
  colCount: colDefs.length,
@@ -35952,7 +37162,7 @@ function TableView({
35952
37162
  };
35953
37163
  eventBus.emit(`UI:${rowClickEvent}`, payload);
35954
37164
  };
35955
- const colFloors = React95__default.useMemo(
37165
+ const colFloors = React96__default.useMemo(
35956
37166
  () => colDefs.map((col) => {
35957
37167
  const longest = data.reduce((widest, row) => {
35958
37168
  const cell = formatCell(asFieldValue(getNestedValue(row, col.field ?? col.key)), col.format);
@@ -36095,12 +37305,12 @@ function TableView({
36095
37305
  ]
36096
37306
  }
36097
37307
  );
36098
- return dnd.isZone ? /* @__PURE__ */ jsx(dnd.SortableItem, { id: row[idField] ?? id, children: rowInner }, id) : /* @__PURE__ */ jsx(React95__default.Fragment, { children: rowInner }, id);
37308
+ return dnd.isZone ? /* @__PURE__ */ jsx(dnd.SortableItem, { id: row[idField] ?? id, children: rowInner }, id) : /* @__PURE__ */ jsx(React96__default.Fragment, { children: rowInner }, id);
36099
37309
  };
36100
37310
  const items = Array.from(data);
36101
37311
  const groups = groupBy ? groupData2(items, groupBy) : [{ label: "", items }];
36102
37312
  let runningIndex = 0;
36103
- const body = /* @__PURE__ */ jsx(Box, { role: "rowgroup", children: groups.map((group, gi) => /* @__PURE__ */ jsxs(React95__default.Fragment, { children: [
37313
+ const body = /* @__PURE__ */ jsx(Box, { role: "rowgroup", children: groups.map((group, gi) => /* @__PURE__ */ jsxs(React96__default.Fragment, { children: [
36104
37314
  group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: gi > 0 ? "mt-3" : "mt-0" }),
36105
37315
  group.items.map((row) => renderRow(row, runningIndex++))
36106
37316
  ] }, gi)) });
@@ -37469,7 +38679,7 @@ var init_StepFlow = __esm({
37469
38679
  className
37470
38680
  }) => {
37471
38681
  if (orientation === "vertical") {
37472
- return /* @__PURE__ */ jsx(VStack, { gap: "none", className: cn("w-full", className), children: steps.map((step, index) => /* @__PURE__ */ jsx(React95__default.Fragment, { children: /* @__PURE__ */ jsxs(HStack, { gap: "md", align: "start", className: "w-full", children: [
38682
+ return /* @__PURE__ */ jsx(VStack, { gap: "none", className: cn("w-full", className), children: steps.map((step, index) => /* @__PURE__ */ jsx(React96__default.Fragment, { children: /* @__PURE__ */ jsxs(HStack, { gap: "md", align: "start", className: "w-full", children: [
37473
38683
  /* @__PURE__ */ jsxs(VStack, { gap: "none", align: "center", children: [
37474
38684
  /* @__PURE__ */ jsx(StepCircle, { step, index }),
37475
38685
  showConnectors && index < steps.length - 1 && /* @__PURE__ */ jsx(Box, { className: "w-px h-8 bg-border" })
@@ -37480,7 +38690,7 @@ var init_StepFlow = __esm({
37480
38690
  ] })
37481
38691
  ] }) }, index)) });
37482
38692
  }
37483
- return /* @__PURE__ */ jsx(Box, { className: cn("w-full flex flex-col md:flex-row items-start gap-0", className), children: steps.map((step, index) => /* @__PURE__ */ jsxs(React95__default.Fragment, { children: [
38693
+ return /* @__PURE__ */ jsx(Box, { className: cn("w-full flex flex-col md:flex-row items-start gap-0", className), children: steps.map((step, index) => /* @__PURE__ */ jsxs(React96__default.Fragment, { children: [
37484
38694
  /* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", className: "flex-1 w-full md:w-auto", children: [
37485
38695
  /* @__PURE__ */ jsx(StepCircle, { step, index }),
37486
38696
  /* @__PURE__ */ jsx(Typography, { variant: "h4", className: "text-center", children: step.title }),
@@ -38470,7 +39680,7 @@ var init_LikertScale = __esm({
38470
39680
  md: "text-base",
38471
39681
  lg: "text-lg"
38472
39682
  };
38473
- LikertScale = React95__default.forwardRef(
39683
+ LikertScale = React96__default.forwardRef(
38474
39684
  ({
38475
39685
  question,
38476
39686
  options = DEFAULT_LIKERT_OPTIONS,
@@ -38482,7 +39692,7 @@ var init_LikertScale = __esm({
38482
39692
  variant = "radios",
38483
39693
  className
38484
39694
  }, ref) => {
38485
- const groupId = React95__default.useId();
39695
+ const groupId = React96__default.useId();
38486
39696
  const eventBus = useEventBus();
38487
39697
  const handleSelect = useCallback(
38488
39698
  (next) => {
@@ -40905,7 +42115,7 @@ var init_DocBreadcrumb = __esm({
40905
42115
  "aria-label": t("aria.breadcrumb"),
40906
42116
  children: /* @__PURE__ */ jsx(HStack, { gap: "xs", align: "center", wrap: true, children: items.map((item, idx) => {
40907
42117
  const isLast = idx === items.length - 1;
40908
- return /* @__PURE__ */ jsxs(React95__default.Fragment, { children: [
42118
+ return /* @__PURE__ */ jsxs(React96__default.Fragment, { children: [
40909
42119
  idx > 0 && /* @__PURE__ */ jsx(
40910
42120
  Icon,
40911
42121
  {
@@ -41570,7 +42780,7 @@ var init_PageHeader = __esm({
41570
42780
  info: "bg-info/10 text-info"
41571
42781
  };
41572
42782
  return /* @__PURE__ */ jsxs(Box, { className: cn("mb-6", className), children: [
41573
- breadcrumbs && breadcrumbs.length > 0 && /* @__PURE__ */ jsx(Box, { as: "nav", className: "mb-4", children: /* @__PURE__ */ jsx(Box, { as: "ol", className: "flex items-center gap-2 text-sm", children: breadcrumbs.map((crumb, idx) => /* @__PURE__ */ jsxs(React95__default.Fragment, { children: [
42783
+ breadcrumbs && breadcrumbs.length > 0 && /* @__PURE__ */ jsx(Box, { as: "nav", className: "mb-4", children: /* @__PURE__ */ jsx(Box, { as: "ol", className: "flex items-center gap-2 text-sm", children: breadcrumbs.map((crumb, idx) => /* @__PURE__ */ jsxs(React96__default.Fragment, { children: [
41574
42784
  idx > 0 && /* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", children: "/" }),
41575
42785
  crumb.href ? /* @__PURE__ */ jsx(
41576
42786
  "a",
@@ -41928,7 +43138,7 @@ var init_Section = __esm({
41928
43138
  as: Component = "section"
41929
43139
  }) => {
41930
43140
  const hasHeader = title || description || action;
41931
- return React95__default.createElement(
43141
+ return React96__default.createElement(
41932
43142
  Component,
41933
43143
  {
41934
43144
  className: cn(
@@ -42302,7 +43512,7 @@ var init_WizardContainer = __esm({
42302
43512
  const isCompleted = index < currentStep;
42303
43513
  const stepKey = step.id ?? step.tabId ?? `step-${index}`;
42304
43514
  const stepTitle = step.title ?? step.name ?? `Step ${index + 1}`;
42305
- return /* @__PURE__ */ jsxs(React95__default.Fragment, { children: [
43515
+ return /* @__PURE__ */ jsxs(React96__default.Fragment, { children: [
42306
43516
  /* @__PURE__ */ jsx(
42307
43517
  Button,
42308
43518
  {
@@ -44089,7 +45299,7 @@ var init_ImportPreviewTree = __esm({
44089
45299
  const renderUnit = (unit, childrenByParent, depth) => {
44090
45300
  const summary = fieldSummary(unit);
44091
45301
  const children = childrenByParent.get(unit.ref) ?? [];
44092
- return /* @__PURE__ */ jsxs(React95__default.Fragment, { children: [
45302
+ return /* @__PURE__ */ jsxs(React96__default.Fragment, { children: [
44093
45303
  /* @__PURE__ */ jsxs(
44094
45304
  Box,
44095
45305
  {
@@ -44186,7 +45396,7 @@ var init_ImportProgress = __esm({
44186
45396
  PIPELINE.map((key, index) => {
44187
45397
  const isComplete = index < currentIndex;
44188
45398
  const isActive = index === currentIndex;
44189
- return /* @__PURE__ */ jsxs(React95__default.Fragment, { children: [
45399
+ return /* @__PURE__ */ jsxs(React96__default.Fragment, { children: [
44190
45400
  index > 0 ? /* @__PURE__ */ jsx(Box, { className: "h-px w-4 bg-border" }) : null,
44191
45401
  /* @__PURE__ */ jsxs(Box, { className: "flex items-center gap-1", "data-testid": `import-progress-step-${key}`, children: [
44192
45402
  /* @__PURE__ */ jsx(
@@ -45127,7 +46337,7 @@ var init_DetailPanel = __esm({
45127
46337
  }) => {
45128
46338
  const eventBus = useEventBus();
45129
46339
  const { t } = useTranslate();
45130
- const [titleDraft, setTitleDraft] = React95__default.useState(null);
46340
+ const [titleDraft, setTitleDraft] = React96__default.useState(null);
45131
46341
  const isFieldDefArray = (arr) => {
45132
46342
  if (!arr || arr.length === 0) return false;
45133
46343
  const first = arr[0];
@@ -45593,7 +46803,7 @@ var init_SplitPane = __esm({
45593
46803
  /* @__PURE__ */ jsx(
45594
46804
  "div",
45595
46805
  {
45596
- className: cn("overflow-auto", leftClassName),
46806
+ className: cn("flex flex-col overflow-auto", leftClassName),
45597
46807
  style: {
45598
46808
  [isHorizontal ? "width" : "height"]: `${ratio}%`,
45599
46809
  flexShrink: 0
@@ -45611,7 +46821,7 @@ var init_SplitPane = __esm({
45611
46821
  )
45612
46822
  }
45613
46823
  ),
45614
- /* @__PURE__ */ jsx("div", { className: cn("flex-1 overflow-auto", rightClassName), children: right })
46824
+ /* @__PURE__ */ jsx("div", { className: cn("flex flex-col flex-1 min-h-0 min-w-0 overflow-auto", rightClassName), children: right })
45615
46825
  ]
45616
46826
  }
45617
46827
  );
@@ -45657,7 +46867,7 @@ var init_DockLayout = __esm({
45657
46867
  const showBottomPanel = Boolean(bottomPanel) && !bottomPanelCollapsed;
45658
46868
  const showSecondarySidebar = Boolean(secondarySidebar) && !secondarySidebarCollapsed;
45659
46869
  const centerRow = /* @__PURE__ */ jsxs(HStack, { gap: "none", className: "flex-1 min-h-0 min-w-0", children: [
45660
- /* @__PURE__ */ jsx(Box, { className: cn("flex-1 min-w-0 h-full overflow-auto", mainClassName), children: main }),
46870
+ /* @__PURE__ */ jsx(Box, { className: cn("flex-1 min-w-0 min-h-0 overflow-auto", mainClassName), children: main }),
45661
46871
  showSecondarySidebar && /* @__PURE__ */ jsx(
45662
46872
  Box,
45663
46873
  {
@@ -45688,7 +46898,7 @@ var init_DockLayout = __esm({
45688
46898
  Box,
45689
46899
  {
45690
46900
  className: cn(
45691
- "flex-shrink-0 h-full overflow-auto border-r border-border",
46901
+ "flex-shrink-0 min-h-0 overflow-auto border-r border-border",
45692
46902
  railClassName
45693
46903
  ),
45694
46904
  style: { width: railWidth },
@@ -45737,7 +46947,7 @@ var init_DockLayout = __esm({
45737
46947
  }
45738
46948
  });
45739
46949
  function extractTitle(children) {
45740
- if (!React95__default.isValidElement(children)) return void 0;
46950
+ if (!React96__default.isValidElement(children)) return void 0;
45741
46951
  const props = children.props;
45742
46952
  if (typeof props.title === "string") {
45743
46953
  return props.title;
@@ -46099,7 +47309,7 @@ var init_Form = __esm({
46099
47309
  const isSchemaEntity = isOrbitalEntitySchema(entity);
46100
47310
  const resolvedEntity = isSchemaEntity ? entity : void 0;
46101
47311
  const entityName = typeof entity === "string" ? entity : resolvedEntity?.name;
46102
- const normalizedInitialData = React95__default.useMemo(() => {
47312
+ const normalizedInitialData = React96__default.useMemo(() => {
46103
47313
  const entityRowAsInitial = isPlainEntityRow(entity) ? entity : void 0;
46104
47314
  const callerInitial = initialData !== null && typeof initialData === "object" && !Array.isArray(initialData) ? initialData : {};
46105
47315
  const merged = entityRowAsInitial !== void 0 ? { ...entityRowAsInitial, ...callerInitial } : callerInitial;
@@ -46118,7 +47328,7 @@ var init_Form = __esm({
46118
47328
  }
46119
47329
  return normalized;
46120
47330
  }, [entity, initialData]);
46121
- const entityDerivedFields = React95__default.useMemo(() => {
47331
+ const entityDerivedFields = React96__default.useMemo(() => {
46122
47332
  if (fields && fields.length > 0) return void 0;
46123
47333
  if (!resolvedEntity) return void 0;
46124
47334
  return resolvedEntity.fields.map(
@@ -46139,16 +47349,16 @@ var init_Form = __esm({
46139
47349
  const conditionalFields = typeof conditionalFieldsRaw === "boolean" ? {} : conditionalFieldsRaw;
46140
47350
  const hiddenCalculations = typeof hiddenCalculationsRaw === "boolean" ? [] : hiddenCalculationsRaw;
46141
47351
  const violationTriggers = typeof violationTriggersRaw === "boolean" ? [] : violationTriggersRaw;
46142
- const [formData, setFormData] = React95__default.useState(
47352
+ const [formData, setFormData] = React96__default.useState(
46143
47353
  normalizedInitialData
46144
47354
  );
46145
- const [collapsedSections, setCollapsedSections] = React95__default.useState(
47355
+ const [collapsedSections, setCollapsedSections] = React96__default.useState(
46146
47356
  /* @__PURE__ */ new Set()
46147
47357
  );
46148
- const [submitError, setSubmitError] = React95__default.useState(null);
46149
- const formRef = React95__default.useRef(null);
47358
+ const [submitError, setSubmitError] = React96__default.useState(null);
47359
+ const formRef = React96__default.useRef(null);
46150
47360
  const formMode = props.mode;
46151
- const mountedRef = React95__default.useRef(false);
47361
+ const mountedRef = React96__default.useRef(false);
46152
47362
  if (!mountedRef.current) {
46153
47363
  mountedRef.current = true;
46154
47364
  debug("forms", "mount", {
@@ -46161,7 +47371,7 @@ var init_Form = __esm({
46161
47371
  });
46162
47372
  }
46163
47373
  const shouldShowCancel = showCancel ?? (fields && fields.length > 0);
46164
- const evalContext = React95__default.useMemo(
47374
+ const evalContext = React96__default.useMemo(
46165
47375
  () => ({
46166
47376
  formValues: formData,
46167
47377
  globalVariables: externalContext?.globalVariables ?? {},
@@ -46170,7 +47380,7 @@ var init_Form = __esm({
46170
47380
  }),
46171
47381
  [formData, externalContext]
46172
47382
  );
46173
- React95__default.useEffect(() => {
47383
+ React96__default.useEffect(() => {
46174
47384
  debug("forms", "initialData-sync", {
46175
47385
  mode: formMode,
46176
47386
  normalizedInitialData,
@@ -46181,7 +47391,7 @@ var init_Form = __esm({
46181
47391
  setFormData(normalizedInitialData);
46182
47392
  }
46183
47393
  }, [normalizedInitialData]);
46184
- const processCalculations = React95__default.useCallback(
47394
+ const processCalculations = React96__default.useCallback(
46185
47395
  (changedFieldId, newFormData) => {
46186
47396
  if (!hiddenCalculations.length) return;
46187
47397
  const context = {
@@ -46206,7 +47416,7 @@ var init_Form = __esm({
46206
47416
  },
46207
47417
  [hiddenCalculations, externalContext, eventBus]
46208
47418
  );
46209
- const checkViolations = React95__default.useCallback(
47419
+ const checkViolations = React96__default.useCallback(
46210
47420
  (changedFieldId, newFormData) => {
46211
47421
  if (!violationTriggers.length) return;
46212
47422
  const context = {
@@ -46244,7 +47454,7 @@ var init_Form = __esm({
46244
47454
  processCalculations(name, newFormData);
46245
47455
  checkViolations(name, newFormData);
46246
47456
  };
46247
- const isFieldVisible = React95__default.useCallback(
47457
+ const isFieldVisible = React96__default.useCallback(
46248
47458
  (fieldName2) => {
46249
47459
  const condition = conditionalFields[fieldName2];
46250
47460
  if (!condition) return true;
@@ -46252,7 +47462,7 @@ var init_Form = __esm({
46252
47462
  },
46253
47463
  [conditionalFields, evalContext]
46254
47464
  );
46255
- const isSectionVisible = React95__default.useCallback(
47465
+ const isSectionVisible = React96__default.useCallback(
46256
47466
  (section) => {
46257
47467
  if (!section.condition) return true;
46258
47468
  return Boolean(evaluateFormExpression(section.condition, evalContext));
@@ -46328,7 +47538,7 @@ var init_Form = __esm({
46328
47538
  eventBus.emit(`UI:${onCancel}`);
46329
47539
  }
46330
47540
  };
46331
- const renderField = React95__default.useCallback(
47541
+ const renderField = React96__default.useCallback(
46332
47542
  (field) => {
46333
47543
  const fieldName2 = field.name || field.field;
46334
47544
  if (!fieldName2) return null;
@@ -46350,7 +47560,7 @@ var init_Form = __esm({
46350
47560
  [formData, isFieldVisible, relationsData, relationsLoading, isLoading]
46351
47561
  );
46352
47562
  const effectiveFields = entityDerivedFields ?? fields;
46353
- const normalizedFields = React95__default.useMemo(() => {
47563
+ const normalizedFields = React96__default.useMemo(() => {
46354
47564
  if (!effectiveFields || effectiveFields.length === 0) return [];
46355
47565
  return effectiveFields.map((field) => {
46356
47566
  if (typeof field === "string") {
@@ -46385,7 +47595,7 @@ var init_Form = __esm({
46385
47595
  };
46386
47596
  });
46387
47597
  }, [effectiveFields, resolvedEntity, fieldOverrides]);
46388
- const schemaFields = React95__default.useMemo(() => {
47598
+ const schemaFields = React96__default.useMemo(() => {
46389
47599
  if (normalizedFields.length === 0) return null;
46390
47600
  if (isDebugEnabled()) {
46391
47601
  debugGroup(`Form: ${entityName || "unknown"}`);
@@ -46395,7 +47605,7 @@ var init_Form = __esm({
46395
47605
  }
46396
47606
  return normalizedFields.map(renderField).filter(Boolean);
46397
47607
  }, [normalizedFields, renderField, entityName, conditionalFields]);
46398
- const sectionElements = React95__default.useMemo(() => {
47608
+ const sectionElements = React96__default.useMemo(() => {
46399
47609
  if (!sections || sections.length === 0) return null;
46400
47610
  return sections.map((section) => {
46401
47611
  if (!isSectionVisible(section)) {
@@ -47231,7 +48441,7 @@ var init_List = __esm({
47231
48441
  if (entity && typeof entity === "object" && "id" in entity) return [entity];
47232
48442
  return [];
47233
48443
  }, [entity]);
47234
- const getItemActions = React95__default.useCallback(
48444
+ const getItemActions = React96__default.useCallback(
47235
48445
  (item) => {
47236
48446
  if (!itemActions) return [];
47237
48447
  if (typeof itemActions === "function") {
@@ -47713,7 +48923,7 @@ var init_MediaGallery = __esm({
47713
48923
  [selectable, selectedItems, selectionEvent, eventBus]
47714
48924
  );
47715
48925
  const entityData = Array.isArray(entity) ? entity : [];
47716
- const items = React95__default.useMemo(() => {
48926
+ const items = React96__default.useMemo(() => {
47717
48927
  if (propItems && propItems.length > 0) return propItems;
47718
48928
  if (entityData.length === 0) return [];
47719
48929
  return entityData.map((record, idx) => {
@@ -47878,7 +49088,7 @@ var init_MediaGallery = __esm({
47878
49088
  }
47879
49089
  });
47880
49090
  function extractTitle2(children) {
47881
- if (!React95__default.isValidElement(children)) return void 0;
49091
+ if (!React96__default.isValidElement(children)) return void 0;
47882
49092
  const props = children.props;
47883
49093
  if (typeof props.title === "string") {
47884
49094
  return props.title;
@@ -48152,7 +49362,7 @@ var init_debugRegistry = __esm({
48152
49362
  }
48153
49363
  });
48154
49364
  function useDebugData() {
48155
- const [data, setData] = React95.useState(() => ({
49365
+ const [data, setData] = React96.useState(() => ({
48156
49366
  traits: [],
48157
49367
  ticks: [],
48158
49368
  guards: [],
@@ -48166,7 +49376,7 @@ function useDebugData() {
48166
49376
  },
48167
49377
  lastUpdate: Date.now()
48168
49378
  }));
48169
- React95.useEffect(() => {
49379
+ React96.useEffect(() => {
48170
49380
  const updateData = () => {
48171
49381
  setData({
48172
49382
  traits: getAllTraits(),
@@ -48275,12 +49485,12 @@ function layoutGraph(states, transitions, initialState, width, height) {
48275
49485
  return positions;
48276
49486
  }
48277
49487
  function WalkMinimap() {
48278
- const [walkStep, setWalkStep] = React95.useState(null);
48279
- const [traits2, setTraits] = React95.useState([]);
48280
- const [coveredEdges, setCoveredEdges] = React95.useState([]);
48281
- const [completedTraits, setCompletedTraits] = React95.useState(/* @__PURE__ */ new Set());
48282
- const prevTraitRef = React95.useRef(null);
48283
- React95.useEffect(() => {
49488
+ const [walkStep, setWalkStep] = React96.useState(null);
49489
+ const [traits2, setTraits] = React96.useState([]);
49490
+ const [coveredEdges, setCoveredEdges] = React96.useState([]);
49491
+ const [completedTraits, setCompletedTraits] = React96.useState(/* @__PURE__ */ new Set());
49492
+ const prevTraitRef = React96.useRef(null);
49493
+ React96.useEffect(() => {
48284
49494
  const interval = setInterval(() => {
48285
49495
  const w = window;
48286
49496
  const step = w.__orbitalWalkStep;
@@ -48716,15 +49926,15 @@ var init_EntitiesTab = __esm({
48716
49926
  });
48717
49927
  function EventFlowTab({ events: events2 }) {
48718
49928
  const { t } = useTranslate();
48719
- const [filter, setFilter] = React95.useState("all");
48720
- const containerRef = React95.useRef(null);
48721
- const [autoScroll, setAutoScroll] = React95.useState(true);
48722
- React95.useEffect(() => {
49929
+ const [filter, setFilter] = React96.useState("all");
49930
+ const containerRef = React96.useRef(null);
49931
+ const [autoScroll, setAutoScroll] = React96.useState(true);
49932
+ React96.useEffect(() => {
48723
49933
  if (autoScroll && containerRef.current) {
48724
49934
  containerRef.current.scrollTop = containerRef.current.scrollHeight;
48725
49935
  }
48726
49936
  }, [events2.length, autoScroll]);
48727
- const filteredEvents = React95.useMemo(() => {
49937
+ const filteredEvents = React96.useMemo(() => {
48728
49938
  if (filter === "all") return events2;
48729
49939
  return events2.filter((e) => e.type === filter);
48730
49940
  }, [events2, filter]);
@@ -48840,7 +50050,7 @@ var init_EventFlowTab = __esm({
48840
50050
  });
48841
50051
  function GuardsPanel({ guards }) {
48842
50052
  const { t } = useTranslate();
48843
- const [filter, setFilter] = React95.useState("all");
50053
+ const [filter, setFilter] = React96.useState("all");
48844
50054
  if (guards.length === 0) {
48845
50055
  return /* @__PURE__ */ jsx(
48846
50056
  EmptyState,
@@ -48853,7 +50063,7 @@ function GuardsPanel({ guards }) {
48853
50063
  }
48854
50064
  const passedCount = guards.filter((g) => g.result).length;
48855
50065
  const failedCount = guards.length - passedCount;
48856
- const filteredGuards = React95.useMemo(() => {
50066
+ const filteredGuards = React96.useMemo(() => {
48857
50067
  if (filter === "all") return guards;
48858
50068
  if (filter === "passed") return guards.filter((g) => g.result);
48859
50069
  return guards.filter((g) => !g.result);
@@ -49016,10 +50226,10 @@ function EffectBadge({ effect }) {
49016
50226
  }
49017
50227
  function TransitionTimeline({ transitions }) {
49018
50228
  const { t } = useTranslate();
49019
- const containerRef = React95.useRef(null);
49020
- const [autoScroll, setAutoScroll] = React95.useState(true);
49021
- const [expandedId, setExpandedId] = React95.useState(null);
49022
- React95.useEffect(() => {
50229
+ const containerRef = React96.useRef(null);
50230
+ const [autoScroll, setAutoScroll] = React96.useState(true);
50231
+ const [expandedId, setExpandedId] = React96.useState(null);
50232
+ React96.useEffect(() => {
49023
50233
  if (autoScroll && containerRef.current) {
49024
50234
  containerRef.current.scrollTop = containerRef.current.scrollHeight;
49025
50235
  }
@@ -49299,9 +50509,9 @@ function getAllEvents(traits2) {
49299
50509
  function EventDispatcherTab({ traits: traits2, schema }) {
49300
50510
  const eventBus = useEventBus();
49301
50511
  const { t } = useTranslate();
49302
- const [log11, setLog] = React95.useState([]);
49303
- const prevStatesRef = React95.useRef(/* @__PURE__ */ new Map());
49304
- React95.useEffect(() => {
50512
+ const [log12, setLog] = React96.useState([]);
50513
+ const prevStatesRef = React96.useRef(/* @__PURE__ */ new Map());
50514
+ React96.useEffect(() => {
49305
50515
  for (const trait of traits2) {
49306
50516
  const prev = prevStatesRef.current.get(trait.id);
49307
50517
  if (prev && prev !== trait.currentState) {
@@ -49363,9 +50573,9 @@ function EventDispatcherTab({ traits: traits2, schema }) {
49363
50573
  /* @__PURE__ */ jsx(Typography, { variant: "small", weight: "medium", className: "text-muted-foreground mb-1", children: t("debug.otherEvents") }),
49364
50574
  /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1", children: unavailableEvents.map((event) => /* @__PURE__ */ jsx(Badge, { variant: "default", size: "sm", className: "opacity-50", children: event }, event)) })
49365
50575
  ] }),
49366
- log11.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
50576
+ log12.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
49367
50577
  /* @__PURE__ */ jsx(Typography, { variant: "small", weight: "medium", className: "text-muted-foreground mb-1", children: t("debug.recentTransitions") }),
49368
- /* @__PURE__ */ jsx(Stack, { gap: "xs", children: log11.map((entry, i) => /* @__PURE__ */ jsxs(Typography, { variant: "small", className: "font-mono text-xs", children: [
50578
+ /* @__PURE__ */ jsx(Stack, { gap: "xs", children: log12.map((entry, i) => /* @__PURE__ */ jsxs(Typography, { variant: "small", className: "font-mono text-xs", children: [
49369
50579
  /* @__PURE__ */ jsx("span", { className: "text-primary", children: entry.traitName }),
49370
50580
  " ",
49371
50581
  /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: entry.from }),
@@ -49470,10 +50680,10 @@ function VerifyModePanel({
49470
50680
  localCount
49471
50681
  }) {
49472
50682
  const { t } = useTranslate();
49473
- const [expanded, setExpanded] = React95.useState(true);
49474
- const scrollRef = React95.useRef(null);
49475
- const prevCountRef = React95.useRef(0);
49476
- React95.useEffect(() => {
50683
+ const [expanded, setExpanded] = React96.useState(true);
50684
+ const scrollRef = React96.useRef(null);
50685
+ const prevCountRef = React96.useRef(0);
50686
+ React96.useEffect(() => {
49477
50687
  if (expanded && transitions.length > prevCountRef.current && scrollRef.current) {
49478
50688
  scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
49479
50689
  }
@@ -49530,10 +50740,10 @@ function RuntimeDebugger({
49530
50740
  schema
49531
50741
  }) {
49532
50742
  const { t } = useTranslate();
49533
- const [isCollapsed, setIsCollapsed] = React95.useState(mode === "verify" ? true : defaultCollapsed);
49534
- const [isVisible, setIsVisible] = React95.useState(mode === "inline" || mode === "verify" || isDebugEnabled2());
50743
+ const [isCollapsed, setIsCollapsed] = React96.useState(mode === "verify" ? true : defaultCollapsed);
50744
+ const [isVisible, setIsVisible] = React96.useState(mode === "inline" || mode === "verify" || isDebugEnabled2());
49535
50745
  const debugData = useDebugData();
49536
- React95.useEffect(() => {
50746
+ React96.useEffect(() => {
49537
50747
  if (mode === "inline") return;
49538
50748
  return onDebugToggle((enabled) => {
49539
50749
  setIsVisible(enabled);
@@ -49542,7 +50752,7 @@ function RuntimeDebugger({
49542
50752
  }
49543
50753
  });
49544
50754
  }, [mode]);
49545
- React95.useEffect(() => {
50755
+ React96.useEffect(() => {
49546
50756
  if (mode === "inline") return;
49547
50757
  const handleKeyDown = (e) => {
49548
50758
  if (e.key === "`" && isVisible) {
@@ -49973,7 +51183,7 @@ var init_StatCard = __esm({
49973
51183
  const labelToUse = propLabel ?? propTitle;
49974
51184
  const eventBus = useEventBus();
49975
51185
  const { t } = useTranslate();
49976
- const handleActionClick = React95__default.useCallback(() => {
51186
+ const handleActionClick = React96__default.useCallback(() => {
49977
51187
  if (action?.event) {
49978
51188
  eventBus.emit(`UI:${action.event}`, {});
49979
51189
  }
@@ -49984,7 +51194,7 @@ var init_StatCard = __esm({
49984
51194
  const data = Array.isArray(entity) ? entity : entity ? [entity] : [];
49985
51195
  const isLoading = externalLoading ?? false;
49986
51196
  const error = externalError;
49987
- const computeMetricValue = React95__default.useCallback(
51197
+ const computeMetricValue = React96__default.useCallback(
49988
51198
  (metric, items) => {
49989
51199
  if (metric.value !== void 0) {
49990
51200
  return metric.value;
@@ -50023,7 +51233,7 @@ var init_StatCard = __esm({
50023
51233
  },
50024
51234
  []
50025
51235
  );
50026
- const schemaStats = React95__default.useMemo(() => {
51236
+ const schemaStats = React96__default.useMemo(() => {
50027
51237
  if (!metrics || metrics.length === 0) return null;
50028
51238
  return metrics.map((metric) => ({
50029
51239
  label: metric.label,
@@ -50031,7 +51241,7 @@ var init_StatCard = __esm({
50031
51241
  format: metric.format
50032
51242
  }));
50033
51243
  }, [metrics, data, computeMetricValue]);
50034
- const calculatedTrend = React95__default.useMemo(() => {
51244
+ const calculatedTrend = React96__default.useMemo(() => {
50035
51245
  if (manualTrend !== void 0) return manualTrend;
50036
51246
  if (previousValue === void 0 || currentValue === void 0)
50037
51247
  return void 0;
@@ -50671,8 +51881,8 @@ var init_SubagentTracePanel = __esm({
50671
51881
  ] });
50672
51882
  };
50673
51883
  InlineActivityStream = ({ activities, autoScroll = true, className }) => {
50674
- const endRef = React95__default.useRef(null);
50675
- React95__default.useEffect(() => {
51884
+ const endRef = React96__default.useRef(null);
51885
+ React96__default.useEffect(() => {
50676
51886
  if (!autoScroll) return;
50677
51887
  endRef.current?.scrollIntoView({ behavior: "smooth", block: "end" });
50678
51888
  }, [activities.length, autoScroll]);
@@ -50766,7 +51976,7 @@ var init_SubagentTracePanel = __esm({
50766
51976
  };
50767
51977
  SubagentRichCard = ({ subagent }) => {
50768
51978
  const { t } = useTranslate();
50769
- const activities = React95__default.useMemo(
51979
+ const activities = React96__default.useMemo(
50770
51980
  () => subagentMessagesToActivities(subagent.messages),
50771
51981
  [subagent.messages]
50772
51982
  );
@@ -50843,8 +52053,8 @@ var init_SubagentTracePanel = __esm({
50843
52053
  ] });
50844
52054
  };
50845
52055
  CoordinatorConversation = ({ messages, autoScroll = true, className }) => {
50846
- const endRef = React95__default.useRef(null);
50847
- React95__default.useEffect(() => {
52056
+ const endRef = React96__default.useRef(null);
52057
+ React96__default.useEffect(() => {
50848
52058
  if (!autoScroll) return;
50849
52059
  endRef.current?.scrollIntoView({ behavior: "smooth", block: "end" });
50850
52060
  }, [messages.length, autoScroll]);
@@ -51279,7 +52489,7 @@ var init_Timeline = __esm({
51279
52489
  }) => {
51280
52490
  const { t } = useTranslate();
51281
52491
  const entityData = entity ?? [];
51282
- const items = React95__default.useMemo(() => {
52492
+ const items = React96__default.useMemo(() => {
51283
52493
  if (propItems) return propItems;
51284
52494
  if (entityData.length === 0) return [];
51285
52495
  return entityData.map((record, idx) => {
@@ -51381,7 +52591,7 @@ var init_Timeline = __esm({
51381
52591
  }
51382
52592
  });
51383
52593
  function extractToastProps(children) {
51384
- if (!React95__default.isValidElement(children)) {
52594
+ if (!React96__default.isValidElement(children)) {
51385
52595
  if (typeof children === "string") {
51386
52596
  return { message: children };
51387
52597
  }
@@ -51423,7 +52633,7 @@ var init_ToastSlot = __esm({
51423
52633
  eventBus.emit(`${prefix}CLOSE`);
51424
52634
  };
51425
52635
  if (!isVisible) return null;
51426
- const isCustomContent = React95__default.isValidElement(children) && !message;
52636
+ const isCustomContent = React96__default.isValidElement(children) && !message;
51427
52637
  return /* @__PURE__ */ jsx(Box, { className: "fixed bottom-4 right-4 z-50", children: isCustomContent ? children : /* @__PURE__ */ jsx(
51428
52638
  Toast,
51429
52639
  {
@@ -51491,6 +52701,7 @@ var init_component_registry_generated = __esm({
51491
52701
  init_ChoiceButton();
51492
52702
  init_CodeBlock();
51493
52703
  init_CodeRunnerPanel();
52704
+ init_CommandPalette();
51494
52705
  init_CommunityLinks();
51495
52706
  init_ConditionalWrapper();
51496
52707
  init_ConfettiEffect();
@@ -51555,6 +52766,7 @@ var init_component_registry_generated = __esm({
51555
52766
  init_FormSection();
51556
52767
  init_FormSectionHeader();
51557
52768
  init_FxOverlay();
52769
+ init_GameAudioCue();
51558
52770
  init_GameAudioToggle();
51559
52771
  init_GameHud();
51560
52772
  init_GameIcon();
@@ -51765,6 +52977,7 @@ var init_component_registry_generated = __esm({
51765
52977
  "ChoiceButton": ChoiceButton,
51766
52978
  "CodeBlock": CodeBlock,
51767
52979
  "CodeRunnerPanel": CodeRunnerPanel,
52980
+ "CommandPalette": CommandPalette,
51768
52981
  "CommunityLinks": CommunityLinks,
51769
52982
  "ConditionalWrapper": ConditionalWrapper,
51770
52983
  "ConfettiEffect": ConfettiEffect,
@@ -51831,6 +53044,7 @@ var init_component_registry_generated = __esm({
51831
53044
  "FormLayout": FormLayout,
51832
53045
  "FormSectionHeader": FormSectionHeader,
51833
53046
  "FxOverlay": FxOverlay,
53047
+ "GameAudioCue": GameAudioCue,
51834
53048
  "GameAudioToggle": GameAudioToggle,
51835
53049
  "GameHud": GameHud,
51836
53050
  "GameIcon": GameIcon,
@@ -52013,7 +53227,7 @@ function SuspenseConfigProvider({
52013
53227
  config,
52014
53228
  children
52015
53229
  }) {
52016
- return React95__default.createElement(
53230
+ return React96__default.createElement(
52017
53231
  SuspenseConfigContext.Provider,
52018
53232
  { value: config },
52019
53233
  children
@@ -52061,7 +53275,7 @@ function enrichFormFields(fields, entityDef) {
52061
53275
  }
52062
53276
  return { name: field, label: humanizeFieldName(field) };
52063
53277
  }
52064
- if (field && typeof field === "object" && !Array.isArray(field) && !React95__default.isValidElement(field) && !(field instanceof Date)) {
53278
+ if (field && typeof field === "object" && !Array.isArray(field) && !React96__default.isValidElement(field) && !(field instanceof Date)) {
52065
53279
  const obj = field;
52066
53280
  const fieldName2 = typeof obj.name === "string" ? obj.name : typeof obj.field === "string" ? obj.field : void 0;
52067
53281
  if (!fieldName2) return field;
@@ -52114,7 +53328,7 @@ function enrichDetailFields(fields, entityDef) {
52114
53328
  const meta = metaFor(field);
52115
53329
  return meta ? { key: field, ...meta } : field;
52116
53330
  }
52117
- if (field && typeof field === "object" && !Array.isArray(field) && !React95__default.isValidElement(field) && !(field instanceof Date)) {
53331
+ if (field && typeof field === "object" && !Array.isArray(field) && !React96__default.isValidElement(field) && !(field instanceof Date)) {
52118
53332
  const obj = field;
52119
53333
  const fieldName2 = typeof obj.key === "string" ? obj.key : typeof obj.name === "string" ? obj.name : void 0;
52120
53334
  if (!fieldName2 || obj.type) return field;
@@ -52573,7 +53787,7 @@ function renderPatternChildren(children, onDismiss, parentId = "root", parentPat
52573
53787
  const key = `${parentId}-${index}-trait:${traitName}`;
52574
53788
  return /* @__PURE__ */ jsx(TraitFrame, { traitName }, key);
52575
53789
  }
52576
- return /* @__PURE__ */ jsx(React95__default.Fragment, { children: child }, `${parentId}-${index}`);
53790
+ return /* @__PURE__ */ jsx(React96__default.Fragment, { children: child }, `${parentId}-${index}`);
52577
53791
  }
52578
53792
  if (!child || typeof child !== "object") return null;
52579
53793
  const childId = `${parentId}-${index}`;
@@ -52630,7 +53844,7 @@ function isPatternConfig(value) {
52630
53844
  if (value === null || value === void 0) return false;
52631
53845
  if (typeof value !== "object") return false;
52632
53846
  if (Array.isArray(value)) return false;
52633
- if (React95__default.isValidElement(value)) return false;
53847
+ if (React96__default.isValidElement(value)) return false;
52634
53848
  if (value instanceof Date) return false;
52635
53849
  if (typeof value === "function") return false;
52636
53850
  const record = value;
@@ -52643,9 +53857,9 @@ function renderPatternValue(value) {
52643
53857
  if (typeof value === "string") return renderPatternChildren(value, () => {
52644
53858
  });
52645
53859
  if (value instanceof Date) return value.toLocaleString();
52646
- if (React95__default.isValidElement(value)) return value;
53860
+ if (React96__default.isValidElement(value)) return value;
52647
53861
  if (Array.isArray(value)) {
52648
- return value.map((item, index) => /* @__PURE__ */ jsx(React95__default.Fragment, { children: renderPatternValue(item) }, index));
53862
+ return value.map((item, index) => /* @__PURE__ */ jsx(React96__default.Fragment, { children: renderPatternValue(item) }, index));
52649
53863
  }
52650
53864
  if (isPatternConfig(value)) {
52651
53865
  const { type, ...props } = value;
@@ -52655,7 +53869,7 @@ function renderPatternValue(value) {
52655
53869
  return null;
52656
53870
  }
52657
53871
  function isPlainConfigObject(value) {
52658
- if (React95__default.isValidElement(value)) return false;
53872
+ if (React96__default.isValidElement(value)) return false;
52659
53873
  if (value instanceof Date) return false;
52660
53874
  const proto = Object.getPrototypeOf(value);
52661
53875
  return proto === Object.prototype || proto === null;
@@ -52829,7 +54043,7 @@ function SlotContentRenderer({
52829
54043
  for (const slotKey of CONTENT_NODE_SLOTS) {
52830
54044
  const slotVal = restProps[slotKey];
52831
54045
  if (slotVal === void 0 || slotVal === null) continue;
52832
- if (React95__default.isValidElement(slotVal) || typeof slotVal === "string" || typeof slotVal === "number" || typeof slotVal === "boolean") continue;
54046
+ if (React96__default.isValidElement(slotVal) || typeof slotVal === "string" || typeof slotVal === "number" || typeof slotVal === "boolean") continue;
52833
54047
  const typelessChildren = !Array.isArray(slotVal) && typeof slotVal === "object" && !("type" in slotVal) && Array.isArray(slotVal.children) ? slotVal.children : void 0;
52834
54048
  if (typelessChildren !== void 0 || Array.isArray(slotVal) || typeof slotVal === "object" && "type" in slotVal) {
52835
54049
  nodeSlotOverrides[slotKey] = renderPatternChildren(
@@ -52883,7 +54097,7 @@ function SlotContentRenderer({
52883
54097
  const resolvedItems = Array.isArray(entityVal) && entityVal[0] !== "fn" ? entityVal : null;
52884
54098
  if (resolvedItems && resolvedItems.length > 0 && !finalProps.fields && !finalProps.columns) {
52885
54099
  const sample = resolvedItems[0];
52886
- if (sample && typeof sample === "object" && !Array.isArray(sample) && !React95__default.isValidElement(sample) && !(sample instanceof Date)) {
54100
+ if (sample && typeof sample === "object" && !Array.isArray(sample) && !React96__default.isValidElement(sample) && !(sample instanceof Date)) {
52887
54101
  const keys = Object.keys(sample).filter((k) => k !== "id" && k !== "_id");
52888
54102
  finalProps.fields = keys.map((k, i) => ({ name: k, variant: i === 0 ? "h4" : "body" }));
52889
54103
  }
@@ -53247,7 +54461,7 @@ var AvlTransition = ({
53247
54461
  opacity = 1,
53248
54462
  className
53249
54463
  }) => {
53250
- const ids = React95__default.useMemo(() => {
54464
+ const ids = React96__default.useMemo(() => {
53251
54465
  avlTransitionId += 1;
53252
54466
  return { arrow: `avl-tr-${avlTransitionId}-arrow` };
53253
54467
  }, []);
@@ -53808,7 +55022,7 @@ var AvlStateMachine = ({
53808
55022
  color = "var(--color-primary)",
53809
55023
  animated = false
53810
55024
  }) => {
53811
- const ids = React95__default.useMemo(() => {
55025
+ const ids = React96__default.useMemo(() => {
53812
55026
  avlSmId += 1;
53813
55027
  const base = `avl-sm-${avlSmId}`;
53814
55028
  return { glow: `${base}-glow`, grad: `${base}-grad` };
@@ -54007,7 +55221,7 @@ var AvlOrbitalUnit = ({
54007
55221
  color = "var(--color-primary)",
54008
55222
  animated = false
54009
55223
  }) => {
54010
- const ids = React95__default.useMemo(() => {
55224
+ const ids = React96__default.useMemo(() => {
54011
55225
  avlOuId += 1;
54012
55226
  const base = `avl-ou-${avlOuId}`;
54013
55227
  return { glow: `${base}-glow`, grad: `${base}-grad` };
@@ -54103,7 +55317,7 @@ var AvlClosedCircuit = ({
54103
55317
  color = "var(--color-primary)",
54104
55318
  animated = false
54105
55319
  }) => {
54106
- const ids = React95__default.useMemo(() => {
55320
+ const ids = React96__default.useMemo(() => {
54107
55321
  avlCcId += 1;
54108
55322
  const base = `avl-cc-${avlCcId}`;
54109
55323
  return { glow: `${base}-glow`, grad: `${base}-grad`, arrow: `${base}-arrow` };
@@ -54258,7 +55472,7 @@ var AvlEmitListen = ({
54258
55472
  color = "var(--color-primary)",
54259
55473
  animated = false
54260
55474
  }) => {
54261
- const ids = React95__default.useMemo(() => {
55475
+ const ids = React96__default.useMemo(() => {
54262
55476
  avlElId += 1;
54263
55477
  const base = `avl-el-${avlElId}`;
54264
55478
  return { arrow: `${base}-arrow`, grad: `${base}-grad` };
@@ -54532,7 +55746,7 @@ function renderNode(node, color, glowId) {
54532
55746
  const baseR = node.type === "operator" ? 20 : 16;
54533
55747
  const r2 = Math.max(baseR, labelLen * 3.5 + 6);
54534
55748
  const nc = nodeColor(node.type, color);
54535
- return /* @__PURE__ */ jsxs(React95__default.Fragment, { children: [
55749
+ return /* @__PURE__ */ jsxs(React96__default.Fragment, { children: [
54536
55750
  node.children.map((child, i) => {
54537
55751
  const childR = Math.max(
54538
55752
  child.type === "operator" ? 20 : 16,
@@ -54589,7 +55803,7 @@ var AvlExprTree = ({
54589
55803
  className,
54590
55804
  color = "var(--color-primary)"
54591
55805
  }) => {
54592
- const ids = React95__default.useMemo(() => {
55806
+ const ids = React96__default.useMemo(() => {
54593
55807
  avlEtId += 1;
54594
55808
  return { glow: `avl-et-${avlEtId}-glow` };
54595
55809
  }, []);
@@ -55424,7 +56638,7 @@ var SystemNode = ({ data }) => {
55424
56638
  stateChain.length > 0 && /* @__PURE__ */ jsx("svg", { width: stateChain.length * 14 + 2, height: 10, viewBox: `0 0 ${stateChain.length * 14 + 2} 10`, children: stateChain.map((s, i) => {
55425
56639
  const tc = transitionCounts[s.name] ?? 0;
55426
56640
  const role = getStateRole(s.name, s.isInitial ?? void 0, s.isTerminal ?? void 0, tc, maxTC);
55427
- return /* @__PURE__ */ jsxs(React95__default.Fragment, { children: [
56641
+ return /* @__PURE__ */ jsxs(React96__default.Fragment, { children: [
55428
56642
  /* @__PURE__ */ jsx(AvlState, { x: i * 14 + 1, y: 1, width: 10, height: 8, name: "", role, isInitial: s.isInitial ?? void 0, isTerminal: s.isTerminal ?? void 0 }),
55429
56643
  i < stateChain.length - 1 && /* @__PURE__ */ jsx("line", { x1: i * 14 + 12, y1: 5, x2: i * 14 + 15, y2: 5, stroke: "var(--color-border)", strokeWidth: 0.5 })
55430
56644
  ] }, s.name);
@@ -56511,7 +57725,7 @@ function resolveLambdaBindings(body, params, item, index) {
56511
57725
  }
56512
57726
  return substituted;
56513
57727
  }
56514
- if (body !== null && typeof body === "object" && !React95__default.isValidElement(body) && !(body instanceof Date) && typeof body !== "function") {
57728
+ if (body !== null && typeof body === "object" && !React96__default.isValidElement(body) && !(body instanceof Date) && typeof body !== "function") {
56515
57729
  const out = {};
56516
57730
  for (const [k, v] of Object.entries(body)) {
56517
57731
  out[k] = recur(v);
@@ -56544,7 +57758,7 @@ function deferLambdaEntityExprs(value) {
56544
57758
  }
56545
57759
  return arr.map((v) => deferLambdaEntityExprs(v));
56546
57760
  }
56547
- if (value !== null && typeof value === "object" && !React95__default.isValidElement(value) && !(value instanceof Date) && typeof value !== "function" && !isRenderBindingMarker(value)) {
57761
+ if (value !== null && typeof value === "object" && !React96__default.isValidElement(value) && !(value instanceof Date) && typeof value !== "function" && !isRenderBindingMarker(value)) {
56548
57762
  const out = {};
56549
57763
  for (const [k, v] of Object.entries(value)) {
56550
57764
  out[k] = deferLambdaEntityExprs(v);
@@ -56558,7 +57772,7 @@ function makeLambdaFn(params, lambdaBody, callerKey) {
56558
57772
  const resolvedBody = deferLambdaEntityExprs(
56559
57773
  resolveLambdaBindings(lambdaBody, params, item, index)
56560
57774
  );
56561
- if (resolvedBody === null || typeof resolvedBody !== "object" || Array.isArray(resolvedBody) || typeof resolvedBody === "function" || React95__default.isValidElement(resolvedBody) || resolvedBody instanceof Date) {
57775
+ if (resolvedBody === null || typeof resolvedBody !== "object" || Array.isArray(resolvedBody) || typeof resolvedBody === "function" || React96__default.isValidElement(resolvedBody) || resolvedBody instanceof Date) {
56562
57776
  return null;
56563
57777
  }
56564
57778
  const record = resolvedBody;
@@ -56577,7 +57791,7 @@ function makeLambdaFn(params, lambdaBody, callerKey) {
56577
57791
  props: childProps,
56578
57792
  priority: 0
56579
57793
  };
56580
- return React95__default.createElement(SlotContentRenderer2, { content: childContent });
57794
+ return React96__default.createElement(SlotContentRenderer2, { content: childContent });
56581
57795
  };
56582
57796
  }
56583
57797
  function convertNode(node, callerKey) {
@@ -56597,7 +57811,7 @@ function convertNode(node, callerKey) {
56597
57811
  });
56598
57812
  return anyChanged ? mapped : node;
56599
57813
  }
56600
- if (typeof node === "object" && !React95__default.isValidElement(node) && !(node instanceof Date)) {
57814
+ if (typeof node === "object" && !React96__default.isValidElement(node) && !(node instanceof Date)) {
56601
57815
  return convertObjectProps(node);
56602
57816
  }
56603
57817
  return node;
@@ -56627,7 +57841,7 @@ function convertFnFormLambdasInProps(props) {
56627
57841
 
56628
57842
  // hooks/index.ts
56629
57843
  init_useEventBus();
56630
- var log7 = createLogger("almadar:ui:shared-entity-store");
57844
+ var log8 = createLogger("almadar:ui:shared-entity-store");
56631
57845
  var EMPTY_ENTITY_STATE = {};
56632
57846
  function createSharedEntityStore() {
56633
57847
  const states = /* @__PURE__ */ new Map();
@@ -56657,7 +57871,7 @@ function createSharedEntityStore() {
56657
57871
  try {
56658
57872
  callback();
56659
57873
  } catch (error) {
56660
- log7.error("Shared entity subscriber error", {
57874
+ log8.error("Shared entity subscriber error", {
56661
57875
  entityId,
56662
57876
  error: error instanceof Error ? error : String(error)
56663
57877
  });
@@ -56688,7 +57902,7 @@ function runTickFrame(entityId, orderedWriters, store) {
56688
57902
  store.commit(entityId, scratch);
56689
57903
  return scratch;
56690
57904
  }
56691
- var log8 = createLogger("almadar:ui:effects:client-handlers");
57905
+ var log9 = createLogger("almadar:ui:effects:client-handlers");
56692
57906
  function createClientEffectHandlers(options) {
56693
57907
  const { eventBus, slotSetter, navigate, navigateBack, notify, callService, liveEntity } = options;
56694
57908
  return {
@@ -56697,12 +57911,12 @@ function createClientEffectHandlers(options) {
56697
57911
  eventBus.emit(prefixedEvent, payload, source);
56698
57912
  },
56699
57913
  persist: async () => {
56700
- log8.warn("persist is server-side only, ignored on client");
57914
+ log9.warn("persist is server-side only, ignored on client");
56701
57915
  },
56702
57916
  // @almadar/runtime EffectHandlers.set types value:unknown — should be FieldValue (upstream fix queued)
56703
57917
  set: ((_entityId, field, value) => {
56704
57918
  if (!liveEntity) {
56705
- log8.warn("set is server-side only, ignored on client (no live entity)");
57919
+ log9.warn("set is server-side only, ignored on client (no live entity)");
56706
57920
  return;
56707
57921
  }
56708
57922
  liveEntity[field] = value;
@@ -56738,13 +57952,13 @@ function createClientEffectHandlers(options) {
56738
57952
  window.location.href = path;
56739
57953
  return;
56740
57954
  }
56741
- log8.warn("No navigate handler, ignoring", { path });
57955
+ log9.warn("No navigate handler, ignoring", { path });
56742
57956
  }),
56743
57957
  navigateBack: navigateBack ?? (() => {
56744
- log8.warn("No navigate-back handler, ignoring");
57958
+ log9.warn("No navigate-back handler, ignoring");
56745
57959
  }),
56746
57960
  notify: notify ?? ((msg, type) => {
56747
- log8.debug("notify", { type, message: msg });
57961
+ log9.debug("notify", { type, message: msg });
56748
57962
  })
56749
57963
  };
56750
57964
  }
@@ -57179,7 +58393,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
57179
58393
  };
57180
58394
  }, [traitBindings]);
57181
58395
  const executeTransitionEffects = useCallback(async (params) => {
57182
- const { binding, previousState, newState, payload, flushEvent, syncOnly, log: log11 } = params;
58396
+ const { binding, previousState, newState, payload, flushEvent, syncOnly, log: log12 } = params;
57183
58397
  const traitName = binding.trait.name;
57184
58398
  const linkedEntity = binding.linkedEntity || "";
57185
58399
  const entityId = payload?.entityId;
@@ -57308,7 +58522,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
57308
58522
  if (sharedKey !== void 0) {
57309
58523
  sharedWrites.push({ field, value });
57310
58524
  }
57311
- log11.debug("set:write", {
58525
+ log12.debug("set:write", {
57312
58526
  traitName,
57313
58527
  field,
57314
58528
  value: JSON.stringify(value),
@@ -57376,7 +58590,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
57376
58590
  mergeEntityFrame(sharedEntityStore.getSnapshot(sharedKey), sharedWrites)
57377
58591
  );
57378
58592
  }
57379
- log11.debug("effects:executed", () => ({
58593
+ log12.debug("effects:executed", () => ({
57380
58594
  traitName,
57381
58595
  transition: `${previousState}->${newState}`,
57382
58596
  event: flushEvent,
@@ -57386,7 +58600,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
57386
58600
  slotsTouched: Array.from(pendingSlots.keys()).join(",")
57387
58601
  }));
57388
58602
  for (const [slot, patterns] of pendingSlots) {
57389
- log11.debug("flush:slot", {
58603
+ log12.debug("flush:slot", {
57390
58604
  traitName,
57391
58605
  slot,
57392
58606
  patternCount: patterns.length,
@@ -57404,7 +58618,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
57404
58618
  publishBindingSnapshot(traitName, liveEntity);
57405
58619
  }
57406
58620
  } catch (error) {
57407
- log11.error("effects:error", {
58621
+ log12.error("effects:error", {
57408
58622
  traitName,
57409
58623
  transition: `${previousState}->${newState}`,
57410
58624
  event: flushEvent,
@@ -58483,11 +59697,20 @@ function BrowserPlayground({
58483
59697
  mode = "mock",
58484
59698
  initialPagePath,
58485
59699
  height,
58486
- className
59700
+ className,
59701
+ paused
58487
59702
  }) {
58488
59703
  const [runtime] = useState(
58489
59704
  () => new OrbitalServerRuntime({ mode, debug: false })
58490
59705
  );
59706
+ useEffect(() => {
59707
+ if (paused === void 0) return;
59708
+ if (paused) {
59709
+ runtime.pauseTicks();
59710
+ } else {
59711
+ runtime.resumeTicks();
59712
+ }
59713
+ }, [runtime, paused]);
58491
59714
  const registrationReady = useMemo(() => {
58492
59715
  const orbitalNames = schema.orbitals.map((o) => o.name);
58493
59716
  playgroundLog.debug("register:start", { schema: schema.name, orbitalNames });
@@ -58548,7 +59771,7 @@ init_useEventBus();
58548
59771
  // components/avl/hooks/useCanvasDnd.tsx
58549
59772
  init_useEventBus();
58550
59773
  init_useAlmadarDndCollision();
58551
- var log9 = createLogger("almadar:ui:canvas-dnd");
59774
+ var log10 = createLogger("almadar:ui:canvas-dnd");
58552
59775
  function useCanvasDraggable({
58553
59776
  id,
58554
59777
  payload,
@@ -58586,7 +59809,7 @@ function defaultEmit(eventBus, drop) {
58586
59809
  if (payload.kind === "pattern") {
58587
59810
  const patternType = payload.data["type"];
58588
59811
  if (typeof patternType !== "string") {
58589
- log9.warn("default-emit:pattern:missing-type");
59812
+ log10.warn("default-emit:pattern:missing-type");
58590
59813
  return;
58591
59814
  }
58592
59815
  const out = { patternType, containerNode: target.containerNode };
@@ -58595,26 +59818,26 @@ function defaultEmit(eventBus, drop) {
58595
59818
  out.index = resolved.index;
58596
59819
  }
58597
59820
  eventBus.emit("UI:PATTERN_DROP", out);
58598
- log9.info("default-emit:pattern", { patternType, level: target.level });
59821
+ log10.info("default-emit:pattern", { patternType, level: target.level });
58599
59822
  return;
58600
59823
  }
58601
59824
  if (payload.kind === "behavior") {
58602
59825
  const behaviorName = payload.data["name"];
58603
59826
  if (typeof behaviorName !== "string") {
58604
- log9.warn("default-emit:behavior:missing-name");
59827
+ log10.warn("default-emit:behavior:missing-name");
58605
59828
  return;
58606
59829
  }
58607
59830
  eventBus.emit("UI:BEHAVIOR_DROP", {
58608
59831
  behaviorName,
58609
59832
  containerNode: target.containerNode
58610
59833
  });
58611
- log9.info("default-emit:behavior", { behaviorName, level: target.level });
59834
+ log10.info("default-emit:behavior", { behaviorName, level: target.level });
58612
59835
  return;
58613
59836
  }
58614
59837
  if (payload.kind === "pattern-instance") {
58615
59838
  const fromPath = payload.data["fromPath"];
58616
59839
  if (typeof fromPath !== "string") {
58617
- log9.warn("default-emit:pattern-instance:missing-fromPath");
59840
+ log10.warn("default-emit:pattern-instance:missing-fromPath");
58618
59841
  return;
58619
59842
  }
58620
59843
  const out = { fromPath, loc: payload.data["loc"] };
@@ -58623,10 +59846,10 @@ function defaultEmit(eventBus, drop) {
58623
59846
  out.toIndex = resolved.index;
58624
59847
  }
58625
59848
  eventBus.emit("UI:PATTERN_MOVE", out);
58626
- log9.info("default-emit:pattern-instance", { fromPath, level: target.level });
59849
+ log10.info("default-emit:pattern-instance", { fromPath, level: target.level });
58627
59850
  return;
58628
59851
  }
58629
- log9.debug("default-emit:unhandled-kind", { kind: payload.kind });
59852
+ log10.debug("default-emit:unhandled-kind", { kind: payload.kind });
58630
59853
  }
58631
59854
  function CanvasDndProvider({
58632
59855
  children,
@@ -58635,12 +59858,12 @@ function CanvasDndProvider({
58635
59858
  }) {
58636
59859
  const eventBus = useEventBus();
58637
59860
  const sensors = useAlmadarDndSensors(false);
58638
- const [activePayload, setActivePayload] = React95__default.useState(null);
58639
- const lastPointerRef = React95__default.useRef(null);
58640
- const trackPointer = React95__default.useCallback((ev) => {
59861
+ const [activePayload, setActivePayload] = React96__default.useState(null);
59862
+ const lastPointerRef = React96__default.useRef(null);
59863
+ const trackPointer = React96__default.useCallback((ev) => {
58641
59864
  lastPointerRef.current = { x: ev.clientX, y: ev.clientY };
58642
59865
  }, []);
58643
- const handleDragStart = React95__default.useCallback((e) => {
59866
+ const handleDragStart = React96__default.useCallback((e) => {
58644
59867
  const data = e.active.data.current;
58645
59868
  const payload = data?.payload;
58646
59869
  const activator = e.activatorEvent;
@@ -58649,12 +59872,12 @@ function CanvasDndProvider({
58649
59872
  if (payload) {
58650
59873
  setActivePayload(payload);
58651
59874
  eventBus.emit("UI:DRAG_START", { kind: payload.kind, data: payload.data });
58652
- log9.info("dragStart", { id: e.active.id, kind: payload.kind });
59875
+ log10.info("dragStart", { id: e.active.id, kind: payload.kind });
58653
59876
  } else {
58654
- log9.warn("dragStart:missing-payload", { id: e.active.id });
59877
+ log10.warn("dragStart:missing-payload", { id: e.active.id });
58655
59878
  }
58656
59879
  }, [eventBus, trackPointer]);
58657
- const handleDragEnd = React95__default.useCallback((e) => {
59880
+ const handleDragEnd = React96__default.useCallback((e) => {
58658
59881
  setActivePayload(null);
58659
59882
  document.removeEventListener("pointermove", trackPointer);
58660
59883
  const activeData = e.active.data.current;
@@ -58662,7 +59885,7 @@ function CanvasDndProvider({
58662
59885
  const overData = e.over?.data.current;
58663
59886
  const target = overData?.target;
58664
59887
  const accepts = overData?.accepts;
58665
- log9.info("dragEnd", {
59888
+ log10.info("dragEnd", {
58666
59889
  activeId: e.active.id,
58667
59890
  overId: e.over?.id,
58668
59891
  hasPayload: !!payload,
@@ -58674,12 +59897,12 @@ function CanvasDndProvider({
58674
59897
  }
58675
59898
  if (!payload || !target) return;
58676
59899
  if (accepts && !accepts.includes(payload.kind)) {
58677
- log9.debug("dragEnd:rejected:kind", { kind: payload.kind, accepts: [...accepts] });
59900
+ log10.debug("dragEnd:rejected:kind", { kind: payload.kind, accepts: [...accepts] });
58678
59901
  return;
58679
59902
  }
58680
59903
  const cursor = lastPointerRef.current;
58681
59904
  const resolved = target.resolvePath && cursor ? target.resolvePath(cursor) : null;
58682
- log9.debug("dragEnd:resolve", {
59905
+ log10.debug("dragEnd:resolve", {
58683
59906
  hasResolver: !!target.resolvePath,
58684
59907
  cursorX: cursor?.x,
58685
59908
  cursorY: cursor?.y,
@@ -58690,10 +59913,10 @@ function CanvasDndProvider({
58690
59913
  const suppressed = onDrop ? onDrop(drop) === true : false;
58691
59914
  if (!suppressed) defaultEmit(eventBus, drop);
58692
59915
  }, [eventBus, onDrop, trackPointer]);
58693
- const handleDragCancel = React95__default.useCallback(() => {
59916
+ const handleDragCancel = React96__default.useCallback(() => {
58694
59917
  setActivePayload(null);
58695
59918
  document.removeEventListener("pointermove", trackPointer);
58696
- log9.info("dragCancel");
59919
+ log10.info("dragCancel");
58697
59920
  }, [trackPointer]);
58698
59921
  return /* @__PURE__ */ jsxs(
58699
59922
  DndContext,
@@ -59542,7 +60765,7 @@ var OrbPreviewNodeInner = (props) => {
59542
60765
  }
59543
60766
  );
59544
60767
  };
59545
- var OrbPreviewNode = React95__default.memo(OrbPreviewNodeInner);
60768
+ var OrbPreviewNode = React96__default.memo(OrbPreviewNodeInner);
59546
60769
  OrbPreviewNode.displayName = "OrbPreviewNode";
59547
60770
  orbPreviewLog.debug("export-resolved", () => ({
59548
60771
  type: typeof OrbPreviewNode,
@@ -59647,7 +60870,7 @@ var EventFlowEdgeInner = (props) => {
59647
60870
  ) })
59648
60871
  ] });
59649
60872
  };
59650
- var EventFlowEdge = React95__default.memo(EventFlowEdgeInner);
60873
+ var EventFlowEdge = React96__default.memo(EventFlowEdgeInner);
59651
60874
  EventFlowEdge.displayName = "EventFlowEdge";
59652
60875
 
59653
60876
  // components/avl/molecules/BehaviorComposeNode.tsx
@@ -59794,7 +61017,7 @@ var BehaviorComposeNodeInner = (props) => {
59794
61017
  }
59795
61018
  );
59796
61019
  };
59797
- var BehaviorComposeNode = React95__default.memo(BehaviorComposeNodeInner);
61020
+ var BehaviorComposeNode = React96__default.memo(BehaviorComposeNodeInner);
59798
61021
  BehaviorComposeNode.displayName = "BehaviorComposeNode";
59799
61022
 
59800
61023
  // components/avl/lib/avl-behavior-compose-converter.ts
@@ -60753,7 +61976,7 @@ init_AvlTransitionLane();
60753
61976
  init_AvlSwimLane();
60754
61977
  init_avl_atom_types();
60755
61978
  init_avl_elk_layout();
60756
- var log10 = createLogger("almadar:ui:avl:trait-scene");
61979
+ var log11 = createLogger("almadar:ui:avl:trait-scene");
60757
61980
  var SWIM_GUTTER2 = 120;
60758
61981
  var CENTER_W2 = 360;
60759
61982
  var AvlTraitScene = ({
@@ -60766,7 +61989,7 @@ var AvlTraitScene = ({
60766
61989
  const dataKey = useMemo(() => JSON.stringify(data), [data]);
60767
61990
  useEffect(() => {
60768
61991
  computeTraitLayout(data).then(setLayout).catch((error) => {
60769
- log10.error("computeTraitLayout failed", { error: error instanceof Error ? error : String(error) });
61992
+ log11.error("computeTraitLayout failed", { error: error instanceof Error ? error : String(error) });
60770
61993
  });
60771
61994
  }, [dataKey]);
60772
61995
  if (!layout) {
@@ -60954,7 +62177,7 @@ var TraitCardNodeInner = (props) => {
60954
62177
  }
60955
62178
  );
60956
62179
  };
60957
- var TraitCardNode = React95__default.memo(TraitCardNodeInner);
62180
+ var TraitCardNode = React96__default.memo(TraitCardNodeInner);
60958
62181
  TraitCardNode.displayName = "TraitCardNode";
60959
62182
 
60960
62183
  // components/avl/organisms/FlowCanvas.tsx
@@ -61033,7 +62256,7 @@ function FlowCanvasInner({
61033
62256
  initialOrbital
61034
62257
  );
61035
62258
  const [expandedBehaviorAlias, setExpandedBehaviorAlias] = useState(void 0);
61036
- const screenSizeUserOverrideRef = React95__default.useRef(false);
62259
+ const screenSizeUserOverrideRef = React96__default.useRef(false);
61037
62260
  const [screenSize, setScreenSize] = useState(
61038
62261
  () => typeof window === "undefined" ? "laptop" : detectScreenSize(window.innerWidth)
61039
62262
  );
@@ -61101,9 +62324,9 @@ function FlowCanvasInner({
61101
62324
  const [nodes, setNodes, onNodesChange] = useNodesState(activeNodes);
61102
62325
  const [edges, setEdges, onEdgesChange] = useEdgesState(activeEdges);
61103
62326
  const reactFlow = useReactFlow();
61104
- const savedPositionsRef = React95__default.useRef(nodePositions);
62327
+ const savedPositionsRef = React96__default.useRef(nodePositions);
61105
62328
  savedPositionsRef.current = nodePositions;
61106
- const nodesRef = React95__default.useRef(nodes);
62329
+ const nodesRef = React96__default.useRef(nodes);
61107
62330
  nodesRef.current = nodes;
61108
62331
  useEffect(() => {
61109
62332
  setEdges([]);
@@ -61440,7 +62663,7 @@ var ZoomBreadcrumb = ({
61440
62663
  if (eventName && band === "detail") {
61441
62664
  segments.push({ icon: "\u26A1", label: eventName });
61442
62665
  }
61443
- return /* @__PURE__ */ jsx("div", { className: "absolute top-2 left-2 z-10 flex items-center gap-1 px-2 py-1 rounded-md bg-card/90 border border-border text-xs text-muted-foreground backdrop-blur-sm", children: segments.map((seg, i) => /* @__PURE__ */ jsxs(React95__default.Fragment, { children: [
62666
+ return /* @__PURE__ */ jsx("div", { className: "absolute top-2 left-2 z-10 flex items-center gap-1 px-2 py-1 rounded-md bg-card/90 border border-border text-xs text-muted-foreground backdrop-blur-sm", children: segments.map((seg, i) => /* @__PURE__ */ jsxs(React96__default.Fragment, { children: [
61444
62667
  i > 0 && /* @__PURE__ */ jsx("span", { className: "opacity-40", children: ">" }),
61445
62668
  /* @__PURE__ */ jsx("span", { className: "opacity-60", children: seg.icon }),
61446
62669
  /* @__PURE__ */ jsx("span", { children: seg.label })
@@ -61781,7 +63004,7 @@ var EventWireOverlay = ({
61781
63004
  containerW,
61782
63005
  containerH
61783
63006
  }) => {
61784
- const ids = React95__default.useMemo(() => {
63007
+ const ids = React96__default.useMemo(() => {
61785
63008
  avlOczWireId += 1;
61786
63009
  return { arrow: `avl-ocz-wire-${avlOczWireId}-arrow` };
61787
63010
  }, []);
@@ -62148,7 +63371,7 @@ var AvlOrbitalsCosmicZoom = ({
62148
63371
  borderRadius: 6,
62149
63372
  border: `1px solid ${color}`
62150
63373
  },
62151
- children: /* @__PURE__ */ jsx(HStack, { gap: "xs", align: "center", children: breadcrumbs.map((crumb, i) => /* @__PURE__ */ jsxs(React95__default.Fragment, { children: [
63374
+ children: /* @__PURE__ */ jsx(HStack, { gap: "xs", align: "center", children: breadcrumbs.map((crumb, i) => /* @__PURE__ */ jsxs(React96__default.Fragment, { children: [
62152
63375
  i > 0 && /* @__PURE__ */ jsx(Typography, { variant: "small", style: { opacity: 0.5, color }, children: "/" }),
62153
63376
  i < breadcrumbs.length - 1 ? /* @__PURE__ */ jsx(
62154
63377
  Box,