@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
@@ -1,5 +1,5 @@
1
- import * as React88 from 'react';
2
- import React88__default, { createContext, useContext, useMemo, useRef, useEffect, useCallback, Suspense, useState, useSyncExternalStore, useLayoutEffect, lazy, useId } from 'react';
1
+ import * as React89 from 'react';
2
+ import React89__default, { createContext, useContext, useMemo, useRef, useEffect, useCallback, Suspense, useState, useSyncExternalStore, useLayoutEffect, lazy, useId } from 'react';
3
3
  import { EventBusContext, useTraitScopeChain, RenderSlotProvider, useEntitySchemaOptional, useEntityBindingSnapshot, useTraitScope, TraitScopeProvider, useNavStack, useCurrentPagePath, useRenderSlot, useGameAudioContextOptional, matchPathAmong } from '@almadar/ui/providers';
4
4
  import { createLogger, isLogLevelEnabled } from '@almadar/logger';
5
5
  import { createContextFromBindings, interpolateValue } from '@almadar/runtime';
@@ -281,7 +281,7 @@ function resolveMarkerExpression(expression, entity, config, state) {
281
281
  function isPlainObject(value) {
282
282
  if (value === null || value === void 0 || typeof value !== "object") return false;
283
283
  if (Array.isArray(value)) return false;
284
- if (React88__default.isValidElement(value)) return false;
284
+ if (React89__default.isValidElement(value)) return false;
285
285
  if (value instanceof Date) return false;
286
286
  if (typeof value === "function") return false;
287
287
  return true;
@@ -290,7 +290,7 @@ function isEvaluatorResolvedData(value) {
290
290
  return evaluatorResolvedData.has(value);
291
291
  }
292
292
  function brandResolved(value) {
293
- if (value !== null && typeof value === "object" && !React88__default.isValidElement(value) && !(value instanceof Date)) {
293
+ if (value !== null && typeof value === "object" && !React89__default.isValidElement(value) && !(value instanceof Date)) {
294
294
  resolvedMarkerFree.add(value);
295
295
  }
296
296
  }
@@ -323,7 +323,7 @@ function walkValue(value, scopeTrait, entity, config, state) {
323
323
  }
324
324
  const resolved = resolveMarkerExpression(value.expression, entity, config, state);
325
325
  markerResolutionCache.set(value, { entity, config, state, resolved });
326
- if (resolved !== null && typeof resolved === "object" && !React88__default.isValidElement(resolved) && !(resolved instanceof Date)) {
326
+ if (resolved !== null && typeof resolved === "object" && !React89__default.isValidElement(resolved) && !(resolved instanceof Date)) {
327
327
  resolvedMarkerFree.add(resolved);
328
328
  evaluatorResolvedData.add(resolved);
329
329
  }
@@ -557,7 +557,7 @@ var init_Box = __esm({
557
557
  fixed: "fixed",
558
558
  sticky: "sticky"
559
559
  };
560
- Box = React88__default.forwardRef(
560
+ Box = React89__default.forwardRef(
561
561
  ({
562
562
  padding,
563
563
  paddingX,
@@ -622,7 +622,7 @@ var init_Box = __esm({
622
622
  onPointerDown?.(e);
623
623
  }, [hoverEvent, tapReveal, triggerProps, onPointerDown]);
624
624
  const isClickable = action || onClick;
625
- return React88__default.createElement(
625
+ return React89__default.createElement(
626
626
  Component,
627
627
  {
628
628
  ref,
@@ -839,7 +839,7 @@ var init_Icon = __esm({
839
839
  const effectiveName = typeof icon === "string" && icon !== "" ? icon : name;
840
840
  const effectiveStrokeWidth = strokeWidth != null && strokeWidth > 0 ? strokeWidth : void 0;
841
841
  const family = useIconFamily();
842
- const RenderedComponent = React88__default.useMemo(() => {
842
+ const RenderedComponent = React89__default.useMemo(() => {
843
843
  if (directIcon) return null;
844
844
  return effectiveName ? resolveIconForFamily(effectiveName) : null;
845
845
  }, [directIcon, effectiveName, family]);
@@ -968,7 +968,7 @@ var init_atlasSlice = __esm({
968
968
  }
969
969
  });
970
970
  function useAtlasSliceDataUrl(asset) {
971
- const [, bump] = React88.useReducer((x) => x + 1, 0);
971
+ const [, bump] = React89.useReducer((x) => x + 1, 0);
972
972
  if (!isAtlasAsset(asset)) return void 0;
973
973
  const key = `${asset.atlas}#${asset.sprite}`;
974
974
  const cached = sliceDataUrlCache.get(key);
@@ -1031,13 +1031,13 @@ function AtlasImage({
1031
1031
  style,
1032
1032
  "aria-hidden": ariaHidden
1033
1033
  }) {
1034
- const [, bump] = React88.useReducer((x) => x + 1, 0);
1035
- const canvasRef = React88.useRef(null);
1034
+ const [, bump] = React89.useReducer((x) => x + 1, 0);
1035
+ const canvasRef = React89.useRef(null);
1036
1036
  const sliced = isAtlasAsset(asset);
1037
1037
  const atlas = sliced ? getAtlas(asset.atlas, bump) : void 0;
1038
1038
  const img = sliced && asset?.url ? getSheetImage(asset.url, bump) : null;
1039
1039
  const rect = sliced && atlas ? subRectFor(atlas, asset.sprite) : null;
1040
- React88.useEffect(() => {
1040
+ React89.useEffect(() => {
1041
1041
  const canvas = canvasRef.current;
1042
1042
  if (!canvas || !img || !rect) return;
1043
1043
  canvas.width = rect.sw;
@@ -1113,7 +1113,7 @@ function resolveIconProp(value, sizeClass) {
1113
1113
  const IconComp = value;
1114
1114
  return /* @__PURE__ */ jsx(IconComp, { className: sizeClass });
1115
1115
  }
1116
- if (React88__default.isValidElement(value)) {
1116
+ if (React89__default.isValidElement(value)) {
1117
1117
  return value;
1118
1118
  }
1119
1119
  if (typeof value === "object" && value !== null && isIconLike(value)) {
@@ -1190,7 +1190,7 @@ var init_Button = __esm({
1190
1190
  md: "h-icon-default w-icon-default",
1191
1191
  lg: "h-icon-default w-icon-default"
1192
1192
  };
1193
- Button = React88__default.forwardRef(
1193
+ Button = React89__default.forwardRef(
1194
1194
  ({
1195
1195
  className,
1196
1196
  variant = "primary",
@@ -1260,7 +1260,7 @@ var Dialog;
1260
1260
  var init_Dialog = __esm({
1261
1261
  "components/core/atoms/Dialog.tsx"() {
1262
1262
  init_cn();
1263
- Dialog = React88__default.forwardRef(
1263
+ Dialog = React89__default.forwardRef(
1264
1264
  ({
1265
1265
  role = "dialog",
1266
1266
  "aria-modal": ariaModal = true,
@@ -1471,7 +1471,7 @@ var init_Typography = __esm({
1471
1471
  if (format !== void 0 && format !== "none" && (typeof body === "string" || typeof body === "number" || body instanceof Date)) {
1472
1472
  body = formatValue(body, format);
1473
1473
  }
1474
- return React88__default.createElement(
1474
+ return React89__default.createElement(
1475
1475
  Component,
1476
1476
  {
1477
1477
  id,
@@ -2033,7 +2033,7 @@ var init_Badge = __esm({
2033
2033
  md: "px-2.5 py-1 text-sm",
2034
2034
  lg: "px-3 py-1.5 text-base"
2035
2035
  };
2036
- Badge = React88__default.forwardRef(
2036
+ Badge = React89__default.forwardRef(
2037
2037
  ({ className, variant = "default", size = "sm", amount, label, icon, iconAsset, children, onRemove, removeLabel, ...props }, ref) => {
2038
2038
  const iconSizes3 = {
2039
2039
  sm: "h-icon-default w-icon-default",
@@ -2383,7 +2383,7 @@ var init_SvgFlow = __esm({
2383
2383
  width = 100,
2384
2384
  height = 100
2385
2385
  }) => {
2386
- const markerId = React88__default.useMemo(() => {
2386
+ const markerId = React89__default.useMemo(() => {
2387
2387
  flowIdCounter += 1;
2388
2388
  return `almadar-flow-arrow-${flowIdCounter}`;
2389
2389
  }, []);
@@ -2976,7 +2976,7 @@ var init_SvgRing = __esm({
2976
2976
  width = 100,
2977
2977
  height = 100
2978
2978
  }) => {
2979
- const gradientId = React88__default.useMemo(() => {
2979
+ const gradientId = React89__default.useMemo(() => {
2980
2980
  ringIdCounter += 1;
2981
2981
  return `almadar-ring-glow-${ringIdCounter}`;
2982
2982
  }, []);
@@ -3157,7 +3157,7 @@ var init_Input = __esm({
3157
3157
  init_cn();
3158
3158
  init_Icon();
3159
3159
  init_useEventBus();
3160
- Input = React88__default.forwardRef(
3160
+ Input = React89__default.forwardRef(
3161
3161
  ({
3162
3162
  className,
3163
3163
  inputType,
@@ -3181,9 +3181,9 @@ var init_Input = __esm({
3181
3181
  const eventBus = useEventBus();
3182
3182
  const type = inputType || htmlType || "text";
3183
3183
  const isDeclarative = typeof onChange === "string";
3184
- const [localValue, setLocalValue] = React88__default.useState(value);
3185
- const pendingEchoRef = React88__default.useRef(/* @__PURE__ */ new Set());
3186
- React88__default.useEffect(() => {
3184
+ const [localValue, setLocalValue] = React89__default.useState(value);
3185
+ const pendingEchoRef = React89__default.useRef(/* @__PURE__ */ new Set());
3186
+ React89__default.useEffect(() => {
3187
3187
  if (!isDeclarative) return;
3188
3188
  const incoming = value == null ? "" : String(value);
3189
3189
  if (pendingEchoRef.current.has(incoming)) {
@@ -3350,7 +3350,7 @@ var Label;
3350
3350
  var init_Label = __esm({
3351
3351
  "components/core/atoms/Label.tsx"() {
3352
3352
  init_cn();
3353
- Label = React88__default.forwardRef(
3353
+ Label = React89__default.forwardRef(
3354
3354
  ({ className, required, children, ...props }, ref) => {
3355
3355
  return /* @__PURE__ */ jsxs(
3356
3356
  "label",
@@ -3377,7 +3377,7 @@ var init_Textarea = __esm({
3377
3377
  "components/core/atoms/Textarea.tsx"() {
3378
3378
  init_cn();
3379
3379
  init_useEventBus();
3380
- Textarea = React88__default.forwardRef(
3380
+ Textarea = React89__default.forwardRef(
3381
3381
  ({ className, error, onChange, ...props }, ref) => {
3382
3382
  const eventBus = useEventBus();
3383
3383
  const handleChange = (e) => {
@@ -3627,7 +3627,7 @@ var init_Select = __esm({
3627
3627
  init_cn();
3628
3628
  init_Icon();
3629
3629
  init_useEventBus();
3630
- Select = React88__default.forwardRef(
3630
+ Select = React89__default.forwardRef(
3631
3631
  (props, _ref) => {
3632
3632
  const { multiple, searchable, clearable } = props;
3633
3633
  if (multiple || searchable || clearable) {
@@ -3644,7 +3644,7 @@ var init_Checkbox = __esm({
3644
3644
  "components/core/atoms/Checkbox.tsx"() {
3645
3645
  init_cn();
3646
3646
  init_useEventBus();
3647
- Checkbox = React88__default.forwardRef(
3647
+ Checkbox = React89__default.forwardRef(
3648
3648
  ({ className, label, id, onChange, ...props }, ref) => {
3649
3649
  const inputId = id || `checkbox-${Math.random().toString(36).substr(2, 9)}`;
3650
3650
  const eventBus = useEventBus();
@@ -3698,7 +3698,7 @@ var init_Spinner = __esm({
3698
3698
  md: "h-6 w-6",
3699
3699
  lg: "h-8 w-8"
3700
3700
  };
3701
- Spinner = React88__default.forwardRef(
3701
+ Spinner = React89__default.forwardRef(
3702
3702
  ({ className, size = "md", overlay, ...props }, ref) => {
3703
3703
  if (overlay) {
3704
3704
  return /* @__PURE__ */ jsx(
@@ -3788,7 +3788,7 @@ var init_Card = __esm({
3788
3788
  chip: "shadow-none rounded-pill border-[length:var(--border-width)] border-border",
3789
3789
  "tile-image-first": "p-0 overflow-hidden"
3790
3790
  };
3791
- Card = React88__default.forwardRef(
3791
+ Card = React89__default.forwardRef(
3792
3792
  ({
3793
3793
  className,
3794
3794
  variant = "bordered",
@@ -3837,9 +3837,9 @@ var init_Card = __esm({
3837
3837
  }
3838
3838
  );
3839
3839
  Card.displayName = "Card";
3840
- CardHeader = React88__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("mb-4", className), ...props }));
3840
+ CardHeader = React89__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("mb-4", className), ...props }));
3841
3841
  CardHeader.displayName = "CardHeader";
3842
- CardTitle = React88__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3842
+ CardTitle = React89__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3843
3843
  "h3",
3844
3844
  {
3845
3845
  ref,
@@ -3852,11 +3852,11 @@ var init_Card = __esm({
3852
3852
  }
3853
3853
  ));
3854
3854
  CardTitle.displayName = "CardTitle";
3855
- CardContent = React88__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("", className), ...props }));
3855
+ CardContent = React89__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("", className), ...props }));
3856
3856
  CardContent.displayName = "CardContent";
3857
3857
  CardBody = CardContent;
3858
3858
  CardBody.displayName = "CardBody";
3859
- CardFooter = React88__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3859
+ CardFooter = React89__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3860
3860
  "div",
3861
3861
  {
3862
3862
  ref,
@@ -3943,7 +3943,7 @@ var init_FilterPill = __esm({
3943
3943
  md: "w-3.5 h-3.5",
3944
3944
  lg: "w-4 h-4"
3945
3945
  };
3946
- FilterPill = React88__default.forwardRef(
3946
+ FilterPill = React89__default.forwardRef(
3947
3947
  ({
3948
3948
  className,
3949
3949
  variant = "default",
@@ -4072,8 +4072,8 @@ var init_Avatar = __esm({
4072
4072
  actionPayload
4073
4073
  }) => {
4074
4074
  const eventBus = useEventBus();
4075
- const [imgFailed, setImgFailed] = React88__default.useState(false);
4076
- React88__default.useEffect(() => {
4075
+ const [imgFailed, setImgFailed] = React89__default.useState(false);
4076
+ React89__default.useEffect(() => {
4077
4077
  setImgFailed(false);
4078
4078
  }, [src]);
4079
4079
  const initials = providedInitials ?? (name ? generateInitials(name) : void 0);
@@ -4186,7 +4186,7 @@ var init_Center = __esm({
4186
4186
  as: Component = "div"
4187
4187
  }) => {
4188
4188
  const mergedStyle = minHeight ? { minHeight, ...style } : style;
4189
- return React88__default.createElement(Component, {
4189
+ return React89__default.createElement(Component, {
4190
4190
  className: cn(
4191
4191
  inline ? "inline-flex" : "flex",
4192
4192
  horizontal && "justify-center",
@@ -4454,7 +4454,7 @@ var init_Radio = __esm({
4454
4454
  md: "w-2.5 h-2.5",
4455
4455
  lg: "w-3 h-3"
4456
4456
  };
4457
- Radio = React88__default.forwardRef(
4457
+ Radio = React89__default.forwardRef(
4458
4458
  ({
4459
4459
  label,
4460
4460
  helperText,
@@ -4471,12 +4471,12 @@ var init_Radio = __esm({
4471
4471
  onChange,
4472
4472
  ...props
4473
4473
  }, ref) => {
4474
- const reactId = React88__default.useId();
4474
+ const reactId = React89__default.useId();
4475
4475
  const baseId = id || `radio-${reactId}`;
4476
4476
  const hasError = !!error;
4477
4477
  const eventBus = useEventBus();
4478
- const [selected, setSelected] = React88__default.useState(value);
4479
- React88__default.useEffect(() => {
4478
+ const [selected, setSelected] = React89__default.useState(value);
4479
+ React89__default.useEffect(() => {
4480
4480
  if (value !== void 0) setSelected(value);
4481
4481
  }, [value]);
4482
4482
  const pick = (next, e) => {
@@ -4658,7 +4658,7 @@ var init_Switch = __esm({
4658
4658
  "components/core/atoms/Switch.tsx"() {
4659
4659
  "use client";
4660
4660
  init_cn();
4661
- Switch = React88.forwardRef(
4661
+ Switch = React89.forwardRef(
4662
4662
  ({
4663
4663
  checked,
4664
4664
  defaultChecked = false,
@@ -4669,10 +4669,10 @@ var init_Switch = __esm({
4669
4669
  name,
4670
4670
  className
4671
4671
  }, ref) => {
4672
- const [isChecked, setIsChecked] = React88.useState(
4672
+ const [isChecked, setIsChecked] = React89.useState(
4673
4673
  checked !== void 0 ? checked : defaultChecked
4674
4674
  );
4675
- React88.useEffect(() => {
4675
+ React89.useEffect(() => {
4676
4676
  if (checked !== void 0) {
4677
4677
  setIsChecked(checked);
4678
4678
  }
@@ -4835,7 +4835,7 @@ var init_Stack = __esm({
4835
4835
  };
4836
4836
  const isHorizontal = direction === "horizontal";
4837
4837
  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";
4838
- return React88__default.createElement(
4838
+ return React89__default.createElement(
4839
4839
  Component,
4840
4840
  {
4841
4841
  className: cn(
@@ -5035,7 +5035,7 @@ var Aside;
5035
5035
  var init_Aside = __esm({
5036
5036
  "components/core/atoms/Aside.tsx"() {
5037
5037
  init_cn();
5038
- Aside = React88__default.forwardRef(
5038
+ Aside = React89__default.forwardRef(
5039
5039
  ({ className, children, ...rest }, ref) => /* @__PURE__ */ jsx("aside", { ref, className: cn(className), ...rest, children })
5040
5040
  );
5041
5041
  Aside.displayName = "Aside";
@@ -5114,9 +5114,9 @@ var init_LawReferenceTooltip = __esm({
5114
5114
  className
5115
5115
  }) => {
5116
5116
  const { t } = useTranslate();
5117
- const [isVisible, setIsVisible] = React88__default.useState(false);
5118
- const timeoutRef = React88__default.useRef(null);
5119
- const triggerRef = React88__default.useRef(null);
5117
+ const [isVisible, setIsVisible] = React89__default.useState(false);
5118
+ const timeoutRef = React89__default.useRef(null);
5119
+ const triggerRef = React89__default.useRef(null);
5120
5120
  const handleMouseEnter = () => {
5121
5121
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
5122
5122
  timeoutRef.current = setTimeout(() => setIsVisible(true), 200);
@@ -5127,7 +5127,7 @@ var init_LawReferenceTooltip = __esm({
5127
5127
  };
5128
5128
  const { revealed, triggerProps } = useTapReveal({ refs: [triggerRef] });
5129
5129
  const open = isVisible || revealed;
5130
- React88__default.useEffect(() => {
5130
+ React89__default.useEffect(() => {
5131
5131
  return () => {
5132
5132
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
5133
5133
  };
@@ -5337,7 +5337,7 @@ var init_StatusDot = __esm({
5337
5337
  md: "w-2.5 h-2.5",
5338
5338
  lg: "w-3 h-3"
5339
5339
  };
5340
- StatusDot = React88__default.forwardRef(
5340
+ StatusDot = React89__default.forwardRef(
5341
5341
  ({ className, status = "offline", pulse = false, size = "md", label, ...props }, ref) => {
5342
5342
  return /* @__PURE__ */ jsx(
5343
5343
  "span",
@@ -5391,7 +5391,7 @@ var init_TrendIndicator = __esm({
5391
5391
  down: "trending-down",
5392
5392
  flat: "arrow-right"
5393
5393
  };
5394
- TrendIndicator = React88__default.forwardRef(
5394
+ TrendIndicator = React89__default.forwardRef(
5395
5395
  ({
5396
5396
  className,
5397
5397
  value,
@@ -5460,7 +5460,7 @@ var init_RangeSlider = __esm({
5460
5460
  md: "w-4 h-4",
5461
5461
  lg: "w-5 h-5"
5462
5462
  };
5463
- RangeSlider = React88__default.forwardRef(
5463
+ RangeSlider = React89__default.forwardRef(
5464
5464
  ({
5465
5465
  className,
5466
5466
  min = 0,
@@ -6117,7 +6117,7 @@ var init_ContentSection = __esm({
6117
6117
  md: "py-16",
6118
6118
  lg: "py-24"
6119
6119
  };
6120
- ContentSection = React88__default.forwardRef(
6120
+ ContentSection = React89__default.forwardRef(
6121
6121
  ({ children, background = "default", padding = "lg", id, className }, ref) => {
6122
6122
  return /* @__PURE__ */ jsx(
6123
6123
  Box,
@@ -6651,7 +6651,7 @@ var init_AnimatedReveal = __esm({
6651
6651
  "scale-up": { opacity: 1, transform: "scale(1) translateY(0)" },
6652
6652
  "none": {}
6653
6653
  };
6654
- AnimatedReveal = React88__default.forwardRef(
6654
+ AnimatedReveal = React89__default.forwardRef(
6655
6655
  ({
6656
6656
  trigger = "scroll",
6657
6657
  animation = "fade-up",
@@ -6811,7 +6811,7 @@ var init_AnimatedGraphic = __esm({
6811
6811
  "components/marketing/atoms/AnimatedGraphic.tsx"() {
6812
6812
  "use client";
6813
6813
  init_cn();
6814
- AnimatedGraphic = React88__default.forwardRef(
6814
+ AnimatedGraphic = React89__default.forwardRef(
6815
6815
  ({
6816
6816
  src,
6817
6817
  svgContent,
@@ -6834,7 +6834,7 @@ var init_AnimatedGraphic = __esm({
6834
6834
  const fetchedSvg = useFetchedSvg(svgContent ? void 0 : src);
6835
6835
  const resolvedSvg = svgContent ?? fetchedSvg;
6836
6836
  const prevAnimateRef = useRef(animate);
6837
- const setRef = React88__default.useCallback(
6837
+ const setRef = React89__default.useCallback(
6838
6838
  (node) => {
6839
6839
  containerRef.current = node;
6840
6840
  if (typeof ref === "function") ref(node);
@@ -7587,9 +7587,9 @@ function ControlButton({
7587
7587
  className
7588
7588
  }) {
7589
7589
  const eventBus = useEventBus();
7590
- const [isPressed, setIsPressed] = React88.useState(false);
7590
+ const [isPressed, setIsPressed] = React89.useState(false);
7591
7591
  const actualPressed = pressed ?? isPressed;
7592
- const handlePointerDown = React88.useCallback(
7592
+ const handlePointerDown = React89.useCallback(
7593
7593
  (e) => {
7594
7594
  e.preventDefault();
7595
7595
  if (disabled) return;
@@ -7599,7 +7599,7 @@ function ControlButton({
7599
7599
  },
7600
7600
  [disabled, pressEvent, eventBus, onPress]
7601
7601
  );
7602
- const handlePointerUp = React88.useCallback(
7602
+ const handlePointerUp = React89.useCallback(
7603
7603
  (e) => {
7604
7604
  e.preventDefault();
7605
7605
  if (disabled) return;
@@ -7609,7 +7609,7 @@ function ControlButton({
7609
7609
  },
7610
7610
  [disabled, releaseEvent, eventBus, onRelease]
7611
7611
  );
7612
- const handlePointerLeave = React88.useCallback(
7612
+ const handlePointerLeave = React89.useCallback(
7613
7613
  (e) => {
7614
7614
  if (isPressed) {
7615
7615
  setIsPressed(false);
@@ -7868,18 +7868,18 @@ function ControlGrid({
7868
7868
  className
7869
7869
  }) {
7870
7870
  const eventBus = useEventBus();
7871
- const [active, setActive] = React88.useState(/* @__PURE__ */ new Set());
7872
- const [coarse, setCoarse] = React88.useState(
7871
+ const [active, setActive] = React89.useState(/* @__PURE__ */ new Set());
7872
+ const [coarse, setCoarse] = React89.useState(
7873
7873
  () => typeof window !== "undefined" && window.matchMedia("(pointer: coarse)").matches
7874
7874
  );
7875
- React88.useEffect(() => {
7875
+ React89.useEffect(() => {
7876
7876
  if (visibility !== "auto" || typeof window === "undefined") return;
7877
7877
  const mq = window.matchMedia("(pointer: coarse)");
7878
7878
  const onChange = (e) => setCoarse(e.matches);
7879
7879
  mq.addEventListener("change", onChange);
7880
7880
  return () => mq.removeEventListener("change", onChange);
7881
7881
  }, [visibility]);
7882
- const handlePress = React88.useCallback(
7882
+ const handlePress = React89.useCallback(
7883
7883
  (id) => {
7884
7884
  setActive((prev) => new Set(prev).add(id));
7885
7885
  if (actionEvent) eventBus.emit(`UI:${actionEvent}`, { id, pressed: true });
@@ -7893,7 +7893,7 @@ function ControlGrid({
7893
7893
  },
7894
7894
  [kind, actionEvent, directionEvent, directionEvents, eventBus, onAction, onDirection]
7895
7895
  );
7896
- const handleRelease = React88.useCallback(
7896
+ const handleRelease = React89.useCallback(
7897
7897
  (id) => {
7898
7898
  setActive((prev) => {
7899
7899
  const next = new Set(prev);
@@ -8256,7 +8256,7 @@ function GameMenu({
8256
8256
  }) {
8257
8257
  const resolvedOptions = (options?.length ? options : void 0) ?? (menuItems?.length ? menuItems : void 0) ?? DEFAULT_MENU_OPTIONS;
8258
8258
  const eventBus = useEventBus();
8259
- const handleOptionClick = React88.useCallback(
8259
+ const handleOptionClick = React89.useCallback(
8260
8260
  (option) => {
8261
8261
  if (option.event) {
8262
8262
  eventBus.emit(`UI:${option.event}`, { option });
@@ -8492,7 +8492,7 @@ function StateGraph({
8492
8492
  }) {
8493
8493
  const eventBus = useEventBus();
8494
8494
  const nodes = states ?? [];
8495
- const positions = React88.useMemo(() => layoutStates(nodes, width, height), [nodes, width, height]);
8495
+ const positions = React89.useMemo(() => layoutStates(nodes, width, height), [nodes, width, height]);
8496
8496
  return /* @__PURE__ */ jsxs(
8497
8497
  Box,
8498
8498
  {
@@ -8563,8 +8563,8 @@ function MiniMap({
8563
8563
  tileAssets,
8564
8564
  unitAssets
8565
8565
  }) {
8566
- const canvasRef = React88.useRef(null);
8567
- const imgCacheRef = React88.useRef(/* @__PURE__ */ new Map());
8566
+ const canvasRef = React89.useRef(null);
8567
+ const imgCacheRef = React89.useRef(/* @__PURE__ */ new Map());
8568
8568
  function loadImg(url) {
8569
8569
  const cached = imgCacheRef.current.get(url);
8570
8570
  if (cached) return cached.complete ? cached : null;
@@ -8580,7 +8580,7 @@ function MiniMap({
8580
8580
  imgCacheRef.current.set(url, img);
8581
8581
  return null;
8582
8582
  }
8583
- React88.useEffect(() => {
8583
+ React89.useEffect(() => {
8584
8584
  const canvas = canvasRef.current;
8585
8585
  if (!canvas) return;
8586
8586
  const ctx = canvas.getContext("2d");
@@ -9971,7 +9971,7 @@ function collectDrawnItems(nodes) {
9971
9971
  for (const n of nodes) {
9972
9972
  switch (n.type) {
9973
9973
  case "draw-sprite":
9974
- if (isValidScenePos(n.position)) out.push({ pos: n.position, id: n.id, anchor: n.anchor, width: n.width, height: n.height });
9974
+ if (isValidScenePos(n.position)) out.push({ pos: n.position, id: n.id, anchor: n.anchor, width: n.width, height: n.height, rotation: n.rotation });
9975
9975
  break;
9976
9976
  case "draw-shape":
9977
9977
  case "draw-text":
@@ -9981,7 +9981,7 @@ function collectDrawnItems(nodes) {
9981
9981
  break;
9982
9982
  case "draw-sprite-layer":
9983
9983
  for (const it of n.items) {
9984
- if (isValidScenePos(it.position)) out.push({ pos: it.position, id: it.id, anchor: it.anchor, width: it.width, height: it.height });
9984
+ if (isValidScenePos(it.position)) out.push({ pos: it.position, id: it.id, anchor: it.anchor, width: it.width, height: it.height, rotation: it.rotation });
9985
9985
  }
9986
9986
  break;
9987
9987
  case "draw-shape-layer":
@@ -10001,15 +10001,39 @@ function buildHitIndex(items) {
10001
10001
  }
10002
10002
  return m;
10003
10003
  }
10004
+ function withPreviewPosition(nodes, id, pos) {
10005
+ return nodes.map((n) => {
10006
+ if (n.type === "draw-sprite-layer" || n.type === "draw-shape-layer" || n.type === "draw-text-layer") {
10007
+ if (!n.items.some((it) => it.id === id)) return n;
10008
+ return { ...n, items: n.items.map((it) => it.id === id ? { ...it, position: pos } : it) };
10009
+ }
10010
+ if (n.type === "draw-group") {
10011
+ if (!Array.isArray(n.items)) return n;
10012
+ return { ...n, items: withPreviewPosition(n.items, id, pos) };
10013
+ }
10014
+ if (n.id === id && "position" in n) {
10015
+ return { ...n, position: pos };
10016
+ }
10017
+ return n;
10018
+ });
10019
+ }
10004
10020
  function hitTestSprites(items, projector, point) {
10005
10021
  for (let i = items.length - 1; i >= 0; i--) {
10006
10022
  const it = items[i];
10007
10023
  if (it.id === void 0) continue;
10008
10024
  const r = spriteRect(projector, { position: it.pos, anchor: it.anchor, width: it.width, height: it.height });
10009
- if (point.x >= r.x && point.x <= r.x + r.w && point.y >= r.y && point.y <= r.y + r.h) return it.id;
10025
+ const test = it.rotation ? rotatePoint(point, { x: r.x + r.w / 2, y: r.y + r.h / 2 }, -it.rotation) : point;
10026
+ if (test.x >= r.x && test.x <= r.x + r.w && test.y >= r.y && test.y <= r.y + r.h) return it.id;
10010
10027
  }
10011
10028
  return void 0;
10012
10029
  }
10030
+ function rotatePoint(p, center, radians) {
10031
+ const cos = Math.cos(radians);
10032
+ const sin = Math.sin(radians);
10033
+ const dx = p.x - center.x;
10034
+ const dy = p.y - center.y;
10035
+ return { x: center.x + dx * cos - dy * sin, y: center.y + dx * sin + dy * cos };
10036
+ }
10013
10037
  var init_hitTest = __esm({
10014
10038
  "lib/drawable/hitTest.ts"() {
10015
10039
  init_contract();
@@ -10018,6 +10042,41 @@ var init_hitTest = __esm({
10018
10042
  function normalizeBackdrop(bg) {
10019
10043
  return typeof bg === "string" ? { url: bg, role: "decoration", category: "background" } : bg;
10020
10044
  }
10045
+ function selectionOverlayNodes(projector, item) {
10046
+ const r = spriteRect(projector, { position: item.pos, anchor: item.anchor, width: item.width, height: item.height });
10047
+ const tw = projector.tileWidth;
10048
+ const cellTopLeft = projector.anchorPoint(item.pos, "top-left");
10049
+ const offsetX = (r.x - cellTopLeft.x) / tw;
10050
+ const offsetY = (r.y - cellTopLeft.y) / tw;
10051
+ const width = r.w / tw;
10052
+ const height = r.h / tw;
10053
+ const handle = EDIT_HANDLE_SIZE_PX / tw;
10054
+ const ring = {
10055
+ type: "draw-shape",
10056
+ shape: "rect",
10057
+ position: item.pos,
10058
+ anchor: "top-left",
10059
+ offsetX,
10060
+ offsetY,
10061
+ width,
10062
+ height,
10063
+ stroke: EDIT_SELECTION_COLOR,
10064
+ strokeWidth: 2,
10065
+ fill: "none"
10066
+ };
10067
+ const handles = EDIT_SELECTION_CORNERS.map(([cx, cy]) => ({
10068
+ type: "draw-shape",
10069
+ shape: "rect",
10070
+ position: item.pos,
10071
+ anchor: "top-left",
10072
+ offsetX: offsetX + cx * width - handle / 2,
10073
+ offsetY: offsetY + cy * height - handle / 2,
10074
+ width: handle,
10075
+ height: handle,
10076
+ fill: EDIT_SELECTION_COLOR
10077
+ }));
10078
+ return [ring, ...handles];
10079
+ }
10021
10080
  function Canvas2D({
10022
10081
  className,
10023
10082
  isLoading = false,
@@ -10031,6 +10090,12 @@ function Canvas2D({
10031
10090
  tileLeaveEvent,
10032
10091
  keyMap,
10033
10092
  keyUpMap,
10093
+ editable = false,
10094
+ selectedId = null,
10095
+ onSelect,
10096
+ onMove,
10097
+ selectEvent,
10098
+ moveEvent,
10034
10099
  camera = "pan-zoom",
10035
10100
  scale = 0.4,
10036
10101
  tileWidth,
@@ -10047,7 +10112,7 @@ function Canvas2D({
10047
10112
  const registerChildDrawable = useCallback((node) => {
10048
10113
  childDrawablesRef.current.push(node);
10049
10114
  }, []);
10050
- const hasJsxChildren = React88.Children.count(children) > 0;
10115
+ const hasJsxChildren = React89.Children.count(children) > 0;
10051
10116
  function isDrawableLayer(node) {
10052
10117
  return node.type === "draw-sprite-layer" || node.type === "draw-shape-layer" || node.type === "draw-text-layer";
10053
10118
  }
@@ -10288,10 +10353,22 @@ function Canvas2D({
10288
10353
  painter.scale(cam.zoom, cam.zoom);
10289
10354
  painter.translate(-viewportSize.width / 2 - cam.x, -viewportSize.height / 2 - cam.y);
10290
10355
  const dctx = { projector, time: timeMs, invalidate: bumpAtlas };
10291
- for (const node of drawables) paintDrawable(painter, node, dctx);
10356
+ let paintNodes = drawables;
10357
+ if (editable) {
10358
+ const drag = editDragRef.current;
10359
+ if (drag && drag.moved) {
10360
+ paintNodes = withPreviewPosition(paintNodes, drag.id, { x: drag.previewX, y: drag.previewY });
10361
+ }
10362
+ const selectedItem = selectedId != null ? drawnItems.find((it) => it.id === selectedId) : void 0;
10363
+ if (selectedItem) {
10364
+ const overlaySource = drag && drag.moved && drag.id === selectedId ? { ...selectedItem, pos: { x: drag.previewX, y: drag.previewY } } : selectedItem;
10365
+ paintNodes = [...paintNodes, ...selectionOverlayNodes(projector, overlaySource)];
10366
+ }
10367
+ }
10368
+ for (const node of paintNodes) paintDrawable(painter, node, dctx);
10292
10369
  painter.restore();
10293
- scheduleAnimation(drawables);
10294
- }, [viewportSize, backgroundImage, bgColor, drawables, projector, cameraRef, bumpAtlas, getImage, cameraPos, defaultGridFocus, camera, dragDistance]);
10370
+ scheduleAnimation(paintNodes);
10371
+ }, [viewportSize, backgroundImage, bgColor, drawables, projector, cameraRef, bumpAtlas, getImage, cameraPos, defaultGridFocus, camera, dragDistance, editable, selectedId, drawnItems]);
10295
10372
  useEffect(() => {
10296
10373
  drawTimeRef.current = draw;
10297
10374
  }, [draw]);
@@ -10336,23 +10413,83 @@ function Canvas2D({
10336
10413
  };
10337
10414
  }, [camera, followTarget, lerpToTarget, draw]);
10338
10415
  const singlePointerActiveRef = useRef(false);
10416
+ const editDragRef = useRef(null);
10417
+ const pointerToScene = useCallback((clientX, clientY) => {
10418
+ const canvas = canvasRef.current;
10419
+ if (!canvas) return { x: 0, y: 0 };
10420
+ const world = screenToWorld(clientX, clientY, canvas, viewportSize);
10421
+ const adjustedX = world.x - scaledTileWidth / 2;
10422
+ const adjustedY = squareGrid ? world.y - scaledTileWidth / 2 : world.y - scaledDiamondTopY - scaledFloorHeight / 2;
10423
+ return unproject(adjustedX, adjustedY);
10424
+ }, [screenToWorld, viewportSize, scaledTileWidth, squareGrid, scaledDiamondTopY, scaledFloorHeight, unproject]);
10339
10425
  const handleCanvasPointerDown = useCallback((e) => {
10340
10426
  singlePointerActiveRef.current = true;
10427
+ if (editable) {
10428
+ if (!canvasRef.current) return;
10429
+ const world = screenToWorld(e.clientX, e.clientY, canvasRef.current, viewportSize);
10430
+ const hitId = hitTestSprites(drawnItems, projector, world);
10431
+ if (hitId === void 0) return;
10432
+ const item = [...drawnItems].reverse().find((it) => it.id === hitId);
10433
+ if (!item) return;
10434
+ editDragRef.current = {
10435
+ id: hitId,
10436
+ pointerId: e.pointerId,
10437
+ startClientX: e.clientX,
10438
+ startClientY: e.clientY,
10439
+ startSceneX: item.pos.x,
10440
+ startSceneY: item.pos.y,
10441
+ moved: false,
10442
+ previewX: item.pos.x,
10443
+ previewY: item.pos.y
10444
+ };
10445
+ return;
10446
+ }
10341
10447
  if (enableCamera) handlePointerDown(e);
10342
- }, [enableCamera, handlePointerDown]);
10448
+ }, [editable, screenToWorld, viewportSize, drawnItems, projector, enableCamera, handlePointerDown]);
10343
10449
  const handleCanvasPointerMove = useCallback((e) => {
10450
+ if (editable) {
10451
+ const drag = editDragRef.current;
10452
+ if (!drag || drag.pointerId !== e.pointerId) return;
10453
+ const dxPx = e.clientX - drag.startClientX;
10454
+ const dyPx = e.clientY - drag.startClientY;
10455
+ if (!drag.moved && Math.abs(dxPx) + Math.abs(dyPx) <= 5) return;
10456
+ drag.moved = true;
10457
+ const nowScene = pointerToScene(e.clientX, e.clientY);
10458
+ const startScene = pointerToScene(drag.startClientX, drag.startClientY);
10459
+ drag.previewX = drag.startSceneX + (nowScene.x - startScene.x);
10460
+ drag.previewY = drag.startSceneY + (nowScene.y - startScene.y);
10461
+ draw();
10462
+ return;
10463
+ }
10344
10464
  if (enableCamera) handlePointerMove(e, () => draw());
10345
- }, [enableCamera, handlePointerMove, draw]);
10465
+ }, [editable, pointerToScene, draw, enableCamera, handlePointerMove]);
10346
10466
  const handleCanvasHover = useCallback((e) => {
10347
10467
  if (singlePointerActiveRef.current) return;
10348
10468
  if (!tileHoverEvent || !canvasRef.current) return;
10349
- const world = screenToWorld(e.clientX, e.clientY, canvasRef.current, viewportSize);
10350
- const adjustedX = world.x - scaledTileWidth / 2;
10351
- const adjustedY = squareGrid ? world.y - scaledTileWidth / 2 : world.y - scaledDiamondTopY - scaledFloorHeight / 2;
10352
- const isoPos = unproject(adjustedX, adjustedY);
10469
+ const isoPos = pointerToScene(e.clientX, e.clientY);
10353
10470
  eventBus.emit(`UI:${tileHoverEvent}`, { x: isoPos.x, y: isoPos.y });
10354
- }, [screenToWorld, viewportSize, scaledTileWidth, squareGrid, scaledDiamondTopY, scaledFloorHeight, unproject, tileHoverEvent, eventBus]);
10471
+ }, [pointerToScene, tileHoverEvent, eventBus]);
10355
10472
  const handleCanvasPointerUp = useCallback((e) => {
10473
+ if (editable) {
10474
+ singlePointerActiveRef.current = false;
10475
+ const drag = editDragRef.current;
10476
+ if (drag && drag.pointerId === e.pointerId) {
10477
+ editDragRef.current = null;
10478
+ if (drag.moved) {
10479
+ onMove?.(drag.id, drag.previewX, drag.previewY);
10480
+ if (moveEvent) eventBus.emit(`UI:${moveEvent}`, { id: drag.id, x: drag.previewX, y: drag.previewY });
10481
+ draw();
10482
+ return;
10483
+ }
10484
+ const next = selectedId === drag.id ? null : drag.id;
10485
+ onSelect?.(next);
10486
+ if (selectEvent) eventBus.emit(`UI:${selectEvent}`, { id: next });
10487
+ return;
10488
+ }
10489
+ onSelect?.(null);
10490
+ if (selectEvent) eventBus.emit(`UI:${selectEvent}`, { id: null });
10491
+ return;
10492
+ }
10356
10493
  singlePointerActiveRef.current = false;
10357
10494
  if (enableCamera) handlePointerUp();
10358
10495
  if (dragDistance() > 5) return;
@@ -10363,16 +10500,14 @@ function Canvas2D({
10363
10500
  eventBus.emit(`UI:${unitClickEvent}`, { unitId: spriteHit });
10364
10501
  return;
10365
10502
  }
10366
- const adjustedX = world.x - scaledTileWidth / 2;
10367
- const adjustedY = squareGrid ? world.y - scaledTileWidth / 2 : world.y - scaledDiamondTopY - scaledFloorHeight / 2;
10368
- const isoPos = unproject(adjustedX, adjustedY);
10503
+ const isoPos = pointerToScene(e.clientX, e.clientY);
10369
10504
  const hitId = hitIndex.get(`${isoPos.x},${isoPos.y}`);
10370
10505
  if (hitId !== void 0 && unitClickEvent) {
10371
10506
  eventBus.emit(`UI:${unitClickEvent}`, { unitId: hitId });
10372
10507
  } else if (tileClickEvent) {
10373
10508
  eventBus.emit(`UI:${tileClickEvent}`, { x: isoPos.x, y: isoPos.y });
10374
10509
  }
10375
- }, [enableCamera, handlePointerUp, dragDistance, screenToWorld, viewportSize, scaledTileWidth, squareGrid, scaledDiamondTopY, scaledFloorHeight, unproject, hitIndex, drawnItems, projector, tileClickEvent, unitClickEvent, eventBus]);
10510
+ }, [editable, selectedId, onMove, moveEvent, onSelect, selectEvent, eventBus, draw, enableCamera, handlePointerUp, dragDistance, screenToWorld, viewportSize, drawnItems, projector, tileClickEvent, unitClickEvent, hitIndex, pointerToScene]);
10376
10511
  const handleCanvasPointerLeave = useCallback(() => {
10377
10512
  handleMouseLeave();
10378
10513
  if (tileLeaveEvent) eventBus.emit(`UI:${tileLeaveEvent}`, {});
@@ -10391,7 +10526,7 @@ function Canvas2D({
10391
10526
  }, [enableCamera, handlePointerUp]);
10392
10527
  const gestureHandlers = useCanvasGestures({
10393
10528
  canvasRef,
10394
- enabled: enableCamera || !!tileHoverEvent || !!tileClickEvent || !!unitClickEvent,
10529
+ enabled: enableCamera || !!tileHoverEvent || !!tileClickEvent || !!unitClickEvent || editable,
10395
10530
  onPointerDown: handleCanvasPointerDown,
10396
10531
  onPointerMove: handleCanvasPointerMove,
10397
10532
  onPointerUp: handleCanvasPointerUp,
@@ -10523,7 +10658,7 @@ function Canvas2D({
10523
10658
  }
10524
10659
  ) });
10525
10660
  }
10526
- var canvas2DLog;
10661
+ var canvas2DLog, EDIT_SELECTION_COLOR, EDIT_HANDLE_SIZE_PX, EDIT_SELECTION_CORNERS;
10527
10662
  var init_Canvas2D = __esm({
10528
10663
  "components/game/molecules/Canvas2D.tsx"() {
10529
10664
  "use client";
@@ -10548,8 +10683,12 @@ var init_Canvas2D = __esm({
10548
10683
  init_DrawGroup();
10549
10684
  init_registry();
10550
10685
  init_hitTest();
10686
+ init_contract();
10551
10687
  init_isometric();
10552
10688
  canvas2DLog = createLogger("almadar:ui:game-canvas");
10689
+ EDIT_SELECTION_COLOR = "#3b82f6";
10690
+ EDIT_HANDLE_SIZE_PX = 8;
10691
+ EDIT_SELECTION_CORNERS = [[0, 0], [1, 0], [0, 1], [1, 1]];
10553
10692
  Canvas2D.displayName = "Canvas2D";
10554
10693
  }
10555
10694
  });
@@ -10591,6 +10730,12 @@ function Canvas({
10591
10730
  featureClickEvent,
10592
10731
  keyMap,
10593
10732
  keyUpMap,
10733
+ editable,
10734
+ selectedId,
10735
+ onSelect,
10736
+ onMove,
10737
+ selectEvent,
10738
+ moveEvent,
10594
10739
  children
10595
10740
  }) {
10596
10741
  canvasLog.debug("Canvas render", { mode, drawablesCount: drawables?.length, projection, camera: camera ? JSON.stringify(camera) : void 0 });
@@ -10605,7 +10750,7 @@ function Canvas({
10605
10750
  if (mode !== "3d") return;
10606
10751
  const next = childDrawablesRef.current;
10607
10752
  canvasLog.debug("children:adopt", { registered: next.length, adopted: childDrawables.length });
10608
- if (next.length === 0 && React88.Children.count(children) > 0) return;
10753
+ if (next.length === 0 && React89.Children.count(children) > 0) return;
10609
10754
  setChildDrawables(
10610
10755
  (prev) => prev.length === next.length && JSON.stringify(prev) === JSON.stringify(next) ? prev : [...next]
10611
10756
  );
@@ -10643,7 +10788,7 @@ function Canvas({
10643
10788
  };
10644
10789
  return /* @__PURE__ */ jsxs(Fragment, { children: [
10645
10790
  /* @__PURE__ */ jsx(Suspense, { fallback: null, children: /* @__PURE__ */ jsx(Canvas3DHost, { ...props3d }) }),
10646
- React88.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 }) })
10791
+ React89.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 }) })
10647
10792
  ] });
10648
10793
  }
10649
10794
  return /* @__PURE__ */ jsx(
@@ -10668,6 +10813,12 @@ function Canvas({
10668
10813
  tileLeaveEvent,
10669
10814
  keyMap,
10670
10815
  keyUpMap,
10816
+ editable,
10817
+ selectedId,
10818
+ onSelect,
10819
+ onMove,
10820
+ selectEvent,
10821
+ moveEvent,
10671
10822
  ...children !== void 0 ? { children } : {}
10672
10823
  }
10673
10824
  );
@@ -10689,15 +10840,19 @@ function GameAudioToggle({
10689
10840
  size = "sm",
10690
10841
  className,
10691
10842
  onAsset,
10692
- offAsset
10843
+ offAsset,
10844
+ toggleEvent
10693
10845
  }) {
10694
10846
  const ctx = useGameAudioContextOptional();
10695
10847
  const [localMuted, setLocalMuted] = useState(false);
10696
10848
  const muted = ctx ? ctx.muted : localMuted;
10697
10849
  const setMuted = ctx ? ctx.setMuted : setLocalMuted;
10850
+ const eventBus = useEventBus();
10698
10851
  const handleToggle = useCallback(() => {
10699
- setMuted(!muted);
10700
- }, [muted, setMuted]);
10852
+ const next = !muted;
10853
+ setMuted(next);
10854
+ if (toggleEvent) eventBus.emit(`UI:${toggleEvent}`, { muted: next });
10855
+ }, [muted, setMuted, toggleEvent, eventBus]);
10701
10856
  const activeAsset = muted ? offAsset : onAsset;
10702
10857
  return /* @__PURE__ */ jsx(
10703
10858
  Button,
@@ -10716,6 +10871,7 @@ var init_GameAudioToggle = __esm({
10716
10871
  "use client";
10717
10872
  init_atoms();
10718
10873
  init_cn();
10874
+ init_useEventBus();
10719
10875
  init_GameIcon();
10720
10876
  GameAudioToggle.displayName = "GameAudioToggle";
10721
10877
  }
@@ -10987,6 +11143,47 @@ var init_useGameAudio = __esm({
10987
11143
  useGameAudio.displayName = "useGameAudio";
10988
11144
  }
10989
11145
  });
11146
+ function GameAudioCue({
11147
+ cue,
11148
+ cueSeq,
11149
+ music,
11150
+ muted,
11151
+ volume,
11152
+ manifest,
11153
+ baseUrl
11154
+ }) {
11155
+ const { play, playMusic, stopMusic, setMuted, setMasterVolume } = useGameAudio({
11156
+ manifest,
11157
+ baseUrl,
11158
+ initialMuted: muted,
11159
+ initialVolume: volume
11160
+ });
11161
+ const prevCueSeqRef = useRef(cueSeq);
11162
+ useEffect(() => {
11163
+ if (cue && cueSeq !== void 0 && cueSeq !== prevCueSeqRef.current) {
11164
+ play(cue);
11165
+ }
11166
+ prevCueSeqRef.current = cueSeq;
11167
+ }, [cue, cueSeq, play]);
11168
+ useEffect(() => {
11169
+ if (music) playMusic(music);
11170
+ else stopMusic();
11171
+ }, [music, playMusic, stopMusic]);
11172
+ useEffect(() => {
11173
+ if (muted !== void 0) setMuted(muted);
11174
+ }, [muted, setMuted]);
11175
+ useEffect(() => {
11176
+ if (volume !== void 0) setMasterVolume(volume);
11177
+ }, [volume, setMasterVolume]);
11178
+ return null;
11179
+ }
11180
+ var init_GameAudioCue = __esm({
11181
+ "components/game/atoms/GameAudioCue.tsx"() {
11182
+ "use client";
11183
+ init_useGameAudio();
11184
+ GameAudioCue.displayName = "GameAudioCue";
11185
+ }
11186
+ });
10990
11187
  function isKnownState(s) {
10991
11188
  return s in DEFAULT_STATE_STYLES;
10992
11189
  }
@@ -11068,7 +11265,7 @@ function LinearView({
11068
11265
  /* @__PURE__ */ jsx(HStack, { className: "flex-wrap items-center", gap: "xs", children: trait.states.map((state, i) => {
11069
11266
  const isDone = i < currentIdx;
11070
11267
  const isCurrent = i === currentIdx;
11071
- return /* @__PURE__ */ jsxs(React88__default.Fragment, { children: [
11268
+ return /* @__PURE__ */ jsxs(React89__default.Fragment, { children: [
11072
11269
  i > 0 && /* @__PURE__ */ jsx(
11073
11270
  Typography,
11074
11271
  {
@@ -11603,7 +11800,7 @@ function SequenceBar({
11603
11800
  else onSlotRemove?.(index);
11604
11801
  }, [emit, slotRemoveEvent, onSlotRemove, playing]);
11605
11802
  const paddedSlots = Array.from({ length: maxSlots }, (_, i) => slots[i]);
11606
- return /* @__PURE__ */ jsx(HStack, { className: cn("items-center", className), gap: "sm", children: paddedSlots.map((slot, i) => /* @__PURE__ */ jsxs(React88__default.Fragment, { children: [
11803
+ return /* @__PURE__ */ jsx(HStack, { className: cn("items-center", className), gap: "sm", children: paddedSlots.map((slot, i) => /* @__PURE__ */ jsxs(React89__default.Fragment, { children: [
11607
11804
  i > 0 && /* @__PURE__ */ jsx(
11608
11805
  Typography,
11609
11806
  {
@@ -11685,15 +11882,18 @@ var init_StateJsonView = __esm({
11685
11882
  StateJsonView.displayName = "StateJsonView";
11686
11883
  }
11687
11884
  });
11688
- var GAME_FONTS, GameShell;
11689
- var init_GameShell = __esm({
11690
- "components/game/templates/GameShell.tsx"() {
11691
- init_cn();
11692
- init_Box();
11693
- init_Card();
11694
- init_Typography();
11695
- init_AtlasImage();
11696
- GAME_FONTS = {
11885
+
11886
+ // lib/gameFonts.ts
11887
+ function resolveGameFontFamily(input) {
11888
+ if (!input) return void 0;
11889
+ const resolved = GAME_FONT_KEYS[input];
11890
+ if (resolved) return `'${resolved}', ui-sans-serif, system-ui, sans-serif`;
11891
+ return input;
11892
+ }
11893
+ var GAME_FONT_KEYS;
11894
+ var init_gameFonts = __esm({
11895
+ "lib/gameFonts.ts"() {
11896
+ GAME_FONT_KEYS = {
11697
11897
  fredoka: "Fredoka",
11698
11898
  future: "Kenney Future",
11699
11899
  "future-narrow": "Kenney Future Narrow",
@@ -11701,6 +11901,17 @@ var init_GameShell = __esm({
11701
11901
  blocks: "Kenney Blocks",
11702
11902
  mini: "Kenney Mini"
11703
11903
  };
11904
+ }
11905
+ });
11906
+ var GameShell;
11907
+ var init_GameShell = __esm({
11908
+ "components/game/templates/GameShell.tsx"() {
11909
+ init_cn();
11910
+ init_gameFonts();
11911
+ init_Box();
11912
+ init_Card();
11913
+ init_Typography();
11914
+ init_AtlasImage();
11704
11915
  GameShell = ({
11705
11916
  appName = "Game",
11706
11917
  hud,
@@ -11714,7 +11925,7 @@ var init_GameShell = __esm({
11714
11925
  fontFamily,
11715
11926
  "data-theme": dataTheme
11716
11927
  }) => {
11717
- const font = fontFamily ? GAME_FONTS[fontFamily] ?? fontFamily : void 0;
11928
+ const displayFont = resolveGameFontFamily(fontFamily);
11718
11929
  return /* @__PURE__ */ jsxs(
11719
11930
  Box,
11720
11931
  {
@@ -11733,7 +11944,7 @@ var init_GameShell = __esm({
11733
11944
  // passed — an always-on inline stamp would shadow the orbital's
11734
11945
  // inline-theme font-family-display token (inline style beats the
11735
11946
  // theme provider's vars for the whole shell subtree).
11736
- ...font ? { "--font-family-display": `'${font}', ui-sans-serif, system-ui, sans-serif` } : {}
11947
+ ...displayFont ? { "--font-family-display": displayFont } : {}
11737
11948
  },
11738
11949
  children: [
11739
11950
  backgroundAsset && /* @__PURE__ */ jsx(
@@ -11935,14 +12146,15 @@ function drawArrowHead(ctx, x1, y1, x2, y2, size) {
11935
12146
  ctx.closePath();
11936
12147
  ctx.fill();
11937
12148
  }
11938
- function drawShape(ctx, shape, width, height, allShapes) {
12149
+ function drawShape(ctx, shape, width, height, allShapes, fontFamily) {
11939
12150
  ctx.save();
11940
12151
  const opacity = shape.opacity ?? 1;
11941
12152
  ctx.globalAlpha = opacity;
11942
12153
  const stroke = resolveColor2(shape.color, ctx, "#333333");
11943
12154
  const fill = shape.fill ? resolveColor2(shape.fill, ctx, "#cccccc") : void 0;
11944
12155
  ctx.lineWidth = shape.lineWidth ?? 2;
11945
- if (shape.dash) ctx.setLineDash([...DASH_PATTERNS[shape.dash]]);
12156
+ const dashPattern = shape.dash ? DASH_PATTERNS[shape.dash] : void 0;
12157
+ if (dashPattern) ctx.setLineDash([...dashPattern]);
11946
12158
  switch (shape.type) {
11947
12159
  case "grid": {
11948
12160
  const step = shape.step ?? 40;
@@ -12064,7 +12276,7 @@ function drawShape(ctx, shape, width, height, allShapes) {
12064
12276
  case "text": {
12065
12277
  if (shape.x == null || shape.y == null || !shape.text) break;
12066
12278
  ctx.fillStyle = stroke;
12067
- ctx.font = `${shape.fontSize ?? 14}px ${themeBodyFont(ctx.canvas)}`;
12279
+ ctx.font = `${shape.fontSize ?? 14}px ${shape.fontFamily ?? fontFamily ?? themeBodyFont(ctx.canvas)}`;
12068
12280
  ctx.textAlign = shape.align ?? "left";
12069
12281
  ctx.textBaseline = "middle";
12070
12282
  ctx.fillText(shape.text, shape.x, shape.y);
@@ -12106,7 +12318,7 @@ function drawShape(ctx, shape, width, height, allShapes) {
12106
12318
  }
12107
12319
  ctx.restore();
12108
12320
  }
12109
- function readoutShapes(readouts, width) {
12321
+ function readoutShapes(readouts, width, fontFamily) {
12110
12322
  const out = [];
12111
12323
  const chipH = 18;
12112
12324
  const gap = 6;
@@ -12130,13 +12342,14 @@ function readoutShapes(readouts, width) {
12130
12342
  text,
12131
12343
  color: "#ffffff",
12132
12344
  fontSize: 10,
12133
- align: "center"
12345
+ align: "center",
12346
+ fontFamily
12134
12347
  });
12135
12348
  rightEdge = chipX - gap;
12136
12349
  }
12137
12350
  return out;
12138
12351
  }
12139
- function traceShapes(panel, k, width, height) {
12352
+ function traceShapes(panel, k, width, height, fontFamily) {
12140
12353
  const w = panel.width ?? Math.round(width * 0.32);
12141
12354
  const h = panel.height ?? Math.round(height * 0.28);
12142
12355
  const x = panel.x ?? width - w - 8;
@@ -12190,14 +12403,14 @@ function traceShapes(panel, k, width, height) {
12190
12403
  out.push({ type: "circle", x: last.x, y: last.y, radius: 2, color, fill: color });
12191
12404
  }
12192
12405
  if (series.label) {
12193
- out.push({ type: "text", x: x + 6, y: y + 10 + 11 * j, text: series.label, color, fontSize: 9 });
12406
+ out.push({ type: "text", x: x + 6, y: y + 10 + 11 * j, text: series.label, color, fontSize: 9, fontFamily });
12194
12407
  }
12195
12408
  });
12196
12409
  if (panel.yLabel) {
12197
- out.push({ type: "text", x: x + w - 6, y: y + 10, text: panel.yLabel, color: "#6b7280", fontSize: 9, align: "right" });
12410
+ out.push({ type: "text", x: x + w - 6, y: y + 10, text: panel.yLabel, color: "#6b7280", fontSize: 9, align: "right", fontFamily });
12198
12411
  }
12199
12412
  if (panel.xLabel) {
12200
- out.push({ type: "text", x: x + w - 6, y: y + h - 6, text: panel.xLabel, color: "#6b7280", fontSize: 9, align: "right" });
12413
+ out.push({ type: "text", x: x + w - 6, y: y + h - 6, text: panel.xLabel, color: "#6b7280", fontSize: 9, align: "right", fontFamily });
12201
12414
  }
12202
12415
  return out;
12203
12416
  }
@@ -12220,13 +12433,14 @@ var init_LearningCanvas = __esm({
12220
12433
  init_useEventBus();
12221
12434
  init_webPainter2d();
12222
12435
  init_paintDispatch();
12223
- DASH_PATTERNS = { dashed: [6, 4], dotted: [2, 3] };
12436
+ DASH_PATTERNS = { solid: [], dashed: [6, 4], dotted: [2, 3] };
12224
12437
  TRACE_SERIES_COLORS = ["#2563eb", "#dc2626", "#16a34a", "#f59e0b"];
12225
12438
  LearningCanvas = ({
12226
12439
  className,
12227
12440
  width = 600,
12228
12441
  height = 400,
12229
12442
  backgroundColor,
12443
+ fontFamily,
12230
12444
  shapes = [],
12231
12445
  drawables,
12232
12446
  projector,
@@ -12262,10 +12476,10 @@ var init_LearningCanvas = __esm({
12262
12476
  }, [shapes]);
12263
12477
  const derivedShapes = useMemo(() => {
12264
12478
  if (!traces?.length && !readouts?.length) return shapes;
12265
- const traceOut = (traces ?? []).flatMap((panel, k) => traceShapes(panel, k, width, height));
12266
- const readoutOut = readouts?.length ? readoutShapes(readouts, width) : [];
12479
+ const traceOut = (traces ?? []).flatMap((panel, k) => traceShapes(panel, k, width, height, fontFamily));
12480
+ const readoutOut = readouts?.length ? readoutShapes(readouts, width, fontFamily) : [];
12267
12481
  return [...shapes, ...traceOut, ...readoutOut];
12268
- }, [shapes, traces, readouts, width, height]);
12482
+ }, [shapes, traces, readouts, width, height, fontFamily]);
12269
12483
  const draw = useCallback(() => {
12270
12484
  const _perfT = perfStart("learningcanvas:paint");
12271
12485
  const canvas = canvasRef.current;
@@ -12284,15 +12498,15 @@ var init_LearningCanvas = __esm({
12284
12498
  ctx.fillRect(0, 0, width, height);
12285
12499
  }
12286
12500
  for (const shape of derivedShapes) {
12287
- if (shape.type !== "text") drawShape(ctx, shape, width, height, derivedShapes);
12501
+ if (shape.type !== "text") drawShape(ctx, shape, width, height, derivedShapes, fontFamily);
12288
12502
  }
12289
12503
  for (const shape of derivedShapes) {
12290
- if (shape.type === "text") drawShape(ctx, shape, width, height, derivedShapes);
12504
+ if (shape.type === "text") drawShape(ctx, shape, width, height, derivedShapes, fontFamily);
12291
12505
  }
12292
12506
  if (drawables?.length && projector) {
12293
12507
  const painter = createWebPainter(ctx, invalidateRef.current);
12294
12508
  const timeMs = needsAnim && typeof performance !== "undefined" ? performance.now() : 0;
12295
- const dctx = { projector, time: timeMs, invalidate: invalidateRef.current, fontFamily: themeBodyFont(canvas) };
12509
+ const dctx = { projector, time: timeMs, invalidate: invalidateRef.current, fontFamily: fontFamily || themeBodyFont(canvas) };
12296
12510
  for (const node of drawables) {
12297
12511
  paintDrawable(painter, node, dctx);
12298
12512
  }
@@ -12454,7 +12668,7 @@ var init_ErrorBoundary = __esm({
12454
12668
  }
12455
12669
  );
12456
12670
  };
12457
- ErrorBoundary = class extends React88__default.Component {
12671
+ ErrorBoundary = class extends React89__default.Component {
12458
12672
  constructor(props) {
12459
12673
  super(props);
12460
12674
  __publicField(this, "reset", () => {
@@ -13106,7 +13320,7 @@ var init_Container = __esm({
13106
13320
  as: Component = "div"
13107
13321
  }) => {
13108
13322
  const resolvedSize = maxWidth ?? size ?? "lg";
13109
- return React88__default.createElement(
13323
+ return React89__default.createElement(
13110
13324
  Component,
13111
13325
  {
13112
13326
  className: cn(
@@ -17274,6 +17488,250 @@ var init_EmptyState = __esm({
17274
17488
  EmptyState.displayName = "EmptyState";
17275
17489
  }
17276
17490
  });
17491
+
17492
+ // lib/editorMotions.ts
17493
+ function clamp(value, min, max) {
17494
+ return Math.max(min, Math.min(max, value));
17495
+ }
17496
+ function computeLines(text) {
17497
+ const lines = [];
17498
+ let start = 0;
17499
+ for (let i = 0; i <= text.length; i++) {
17500
+ if (i === text.length || text[i] === "\n") {
17501
+ lines.push({ start, end: i });
17502
+ start = i + 1;
17503
+ }
17504
+ }
17505
+ return lines;
17506
+ }
17507
+ function lineIndexAt(lines, pos) {
17508
+ for (let i = 0; i < lines.length; i++) {
17509
+ if (pos <= lines[i].end) return i;
17510
+ }
17511
+ return lines.length - 1;
17512
+ }
17513
+ function findWords(text) {
17514
+ const words = [];
17515
+ const re = /\w+|\S+/g;
17516
+ let m;
17517
+ while ((m = re.exec(text)) !== null) {
17518
+ words.push({ start: m.index, end: m.index + m[0].length });
17519
+ }
17520
+ return words;
17521
+ }
17522
+ function nextWordStart(text, pos) {
17523
+ for (const w of findWords(text)) {
17524
+ if (w.start > pos) return w.start;
17525
+ }
17526
+ return text.length;
17527
+ }
17528
+ function prevWordStart(text, pos) {
17529
+ let result = 0;
17530
+ for (const w of findWords(text)) {
17531
+ if (w.start < pos) result = w.start;
17532
+ else break;
17533
+ }
17534
+ return result;
17535
+ }
17536
+ function nextWordEnd(text, pos) {
17537
+ for (const w of findWords(text)) {
17538
+ const lastChar = w.end - 1;
17539
+ if (lastChar > pos) return lastChar;
17540
+ }
17541
+ return text.length > 0 ? text.length - 1 : 0;
17542
+ }
17543
+ function firstNonBlank(text, line) {
17544
+ let i = line.start;
17545
+ while (i < line.end && (text[i] === " " || text[i] === " ")) i++;
17546
+ return i;
17547
+ }
17548
+ function nextParagraphBoundary(lines, fromLineIdx, textLength) {
17549
+ for (let i = fromLineIdx + 1; i < lines.length; i++) {
17550
+ if (lines[i].start === lines[i].end) return lines[i].start;
17551
+ }
17552
+ return textLength;
17553
+ }
17554
+ function prevParagraphBoundary(lines, fromLineIdx) {
17555
+ for (let i = fromLineIdx - 1; i >= 0; i--) {
17556
+ if (lines[i].start === lines[i].end) return lines[i].start;
17557
+ }
17558
+ return 0;
17559
+ }
17560
+ function applyMotion(text, caret, motion, count) {
17561
+ const n = Math.max(1, count);
17562
+ const lines = computeLines(text);
17563
+ const lineIdx = lineIndexAt(lines, caret);
17564
+ const line = lines[lineIdx];
17565
+ switch (motion) {
17566
+ case "left":
17567
+ return clamp(caret - n, line.start, line.end);
17568
+ case "right":
17569
+ return clamp(caret + n, line.start, line.end);
17570
+ case "up": {
17571
+ const col = caret - line.start;
17572
+ const targetIdx = clamp(lineIdx - n, 0, lines.length - 1);
17573
+ const target = lines[targetIdx];
17574
+ return clamp(target.start + col, target.start, target.end);
17575
+ }
17576
+ case "down": {
17577
+ const col = caret - line.start;
17578
+ const targetIdx = clamp(lineIdx + n, 0, lines.length - 1);
17579
+ const target = lines[targetIdx];
17580
+ return clamp(target.start + col, target.start, target.end);
17581
+ }
17582
+ case "word-forward": {
17583
+ let pos = caret;
17584
+ for (let i = 0; i < n; i++) pos = nextWordStart(text, pos);
17585
+ return pos;
17586
+ }
17587
+ case "word-back": {
17588
+ let pos = caret;
17589
+ for (let i = 0; i < n; i++) pos = prevWordStart(text, pos);
17590
+ return pos;
17591
+ }
17592
+ case "word-end": {
17593
+ let pos = caret;
17594
+ for (let i = 0; i < n; i++) pos = nextWordEnd(text, pos);
17595
+ return pos;
17596
+ }
17597
+ case "line-start":
17598
+ return line.start;
17599
+ case "line-end":
17600
+ return line.end > line.start ? line.end - 1 : line.start;
17601
+ case "first-nonblank":
17602
+ return firstNonBlank(text, line);
17603
+ case "doc-start":
17604
+ return 0;
17605
+ case "doc-end":
17606
+ return text.length;
17607
+ case "paragraph-forward": {
17608
+ let pos = caret;
17609
+ for (let i = 0; i < n; i++) {
17610
+ pos = nextParagraphBoundary(lines, lineIndexAt(lines, pos), text.length);
17611
+ }
17612
+ return pos;
17613
+ }
17614
+ case "paragraph-back": {
17615
+ let pos = caret;
17616
+ for (let i = 0; i < n; i++) {
17617
+ pos = prevParagraphBoundary(lines, lineIndexAt(lines, pos));
17618
+ }
17619
+ return pos;
17620
+ }
17621
+ case "line":
17622
+ case "selection":
17623
+ return caret;
17624
+ default: {
17625
+ const _exhaustive = motion;
17626
+ return _exhaustive;
17627
+ }
17628
+ }
17629
+ }
17630
+ function motionRange(text, caret, motion, count, selection) {
17631
+ if (motion === "selection") {
17632
+ if (!selection) return [caret, caret];
17633
+ return [Math.min(selection[0], selection[1]), Math.max(selection[0], selection[1])];
17634
+ }
17635
+ const lines = computeLines(text);
17636
+ if (motion === "line") {
17637
+ const n = Math.max(1, count);
17638
+ const startIdx = lineIndexAt(lines, caret);
17639
+ const endIdx = clamp(startIdx + n - 1, 0, lines.length - 1);
17640
+ const start2 = lines[startIdx].start;
17641
+ const rawEnd = lines[endIdx].end;
17642
+ const end2 = rawEnd < text.length ? rawEnd + 1 : rawEnd;
17643
+ return [start2, end2];
17644
+ }
17645
+ const newCaret = applyMotion(text, caret, motion, count);
17646
+ let start = Math.min(caret, newCaret);
17647
+ let end = Math.max(caret, newCaret);
17648
+ if (motion === "word-end" || motion === "line-end") {
17649
+ end = Math.min(Math.max(start, newCaret) + 1, text.length);
17650
+ } else if (motion === "word-forward" && newCaret > caret) {
17651
+ const startLine = lineIndexAt(lines, caret);
17652
+ const endLine = lineIndexAt(lines, newCaret);
17653
+ if (endLine !== startLine) {
17654
+ end = lines[startLine].end;
17655
+ }
17656
+ }
17657
+ return [start, end];
17658
+ }
17659
+ function applyOperator(text, range, operator, register) {
17660
+ const start = clamp(range[0], 0, text.length);
17661
+ const end = clamp(range[1], start, text.length);
17662
+ const removed = text.slice(start, end);
17663
+ if (operator === "yank") {
17664
+ return { text, caret: start, register: removed };
17665
+ }
17666
+ return { text: text.slice(0, start) + text.slice(end), caret: start, register: removed };
17667
+ }
17668
+ var init_editorMotions = __esm({
17669
+ "lib/editorMotions.ts"() {
17670
+ }
17671
+ });
17672
+ function isMotionPayload(payload) {
17673
+ return !!payload && typeof payload.editorId === "string" && typeof payload.motion === "string" && typeof payload.count === "number";
17674
+ }
17675
+ function isOperatePayload(payload) {
17676
+ return !!payload && typeof payload.editorId === "string" && typeof payload.operator === "string" && typeof payload.motion === "string" && typeof payload.count === "number";
17677
+ }
17678
+ function isInsertTextPayload(payload) {
17679
+ return !!payload && typeof payload.editorId === "string" && typeof payload.text === "string";
17680
+ }
17681
+ function isSetModePayload(payload) {
17682
+ return !!payload && typeof payload.editorId === "string" && typeof payload.mode === "string" && typeof payload.caret === "string";
17683
+ }
17684
+ function useEditorCapabilities(args) {
17685
+ const [caretMode, setCaretMode] = useState("bar");
17686
+ const registerRef = useRef("");
17687
+ useEventListener(`UI:${args.events.onMotion}`, (evt) => {
17688
+ if (!args.editorId || !isMotionPayload(evt.payload) || evt.payload.editorId !== args.editorId) return;
17689
+ const ta = args.textareaRef.current;
17690
+ if (!ta) return;
17691
+ const { motion, count } = evt.payload;
17692
+ const newCaret = applyMotion(ta.value, ta.selectionStart, motion, count);
17693
+ if (ta.selectionStart !== ta.selectionEnd) {
17694
+ ta.setSelectionRange(ta.selectionStart, newCaret);
17695
+ } else {
17696
+ ta.setSelectionRange(newCaret, newCaret);
17697
+ }
17698
+ });
17699
+ useEventListener(`UI:${args.events.onOperate}`, (evt) => {
17700
+ if (!args.editorId || !isOperatePayload(evt.payload) || evt.payload.editorId !== args.editorId) return;
17701
+ const ta = args.textareaRef.current;
17702
+ if (!ta) return;
17703
+ const { operator, motion, count } = evt.payload;
17704
+ const selection = motion === "selection" ? [ta.selectionStart, ta.selectionEnd] : void 0;
17705
+ const range = motionRange(ta.value, ta.selectionStart, motion, count, selection);
17706
+ const result = applyOperator(ta.value, range, operator, registerRef.current);
17707
+ registerRef.current = result.register;
17708
+ if (operator === "yank") {
17709
+ ta.setSelectionRange(range[0], range[0]);
17710
+ } else {
17711
+ ta.setRangeText("", range[0], range[1], "end");
17712
+ }
17713
+ args.applyChange(ta.value);
17714
+ });
17715
+ useEventListener(`UI:${args.events.onInsertText}`, (evt) => {
17716
+ if (!args.editorId || !isInsertTextPayload(evt.payload) || evt.payload.editorId !== args.editorId) return;
17717
+ const ta = args.textareaRef.current;
17718
+ if (!ta) return;
17719
+ ta.setRangeText(evt.payload.text, ta.selectionStart, ta.selectionEnd, "end");
17720
+ args.applyChange(ta.value);
17721
+ });
17722
+ useEventListener(`UI:${args.events.onSetMode}`, (evt) => {
17723
+ if (!args.editorId || !isSetModePayload(evt.payload) || evt.payload.editorId !== args.editorId) return;
17724
+ setCaretMode(evt.payload.caret);
17725
+ });
17726
+ return { caretMode };
17727
+ }
17728
+ var init_useEditorCapabilities = __esm({
17729
+ "components/core/molecules/markdown/useEditorCapabilities.ts"() {
17730
+ "use client";
17731
+ init_useEventBus();
17732
+ init_editorMotions();
17733
+ }
17734
+ });
17277
17735
  function isLanguageRegistered(lang) {
17278
17736
  return CODE_LANGUAGE_SET.has(lang) || dynamicallyLoaded.has(lang);
17279
17737
  }
@@ -17359,7 +17817,36 @@ function useLanguageReady(language) {
17359
17817
  }, [language]);
17360
17818
  return ready;
17361
17819
  }
17362
- var dynamicallyLoaded, codeLanguageLoader, orbStyleOverrides, orbStyle, loloStyleOverrides, loloStyle, log7, CODE_LANGUAGES, CODE_LANGUAGE_SET, DIFF_STYLES, DIFF_STYLE_FALLBACK, LINE_PROPS_FN, HIDDEN_LINE_NUMBERS, CodeBlock;
17820
+ function resolveHighlightStyle(lang) {
17821
+ if (lang === "orb") return orbStyle;
17822
+ if (lang === "lolo") return loloStyle;
17823
+ return dark;
17824
+ }
17825
+ function plainCodeColorOf(style) {
17826
+ return style['code[class*="language-"]']?.color ?? "#d4d4d4";
17827
+ }
17828
+ function buildLineProps(errorLines, extraClassName) {
17829
+ return (lineNumber) => {
17830
+ const base = {
17831
+ "data-line": String(lineNumber - 1),
17832
+ ...extraClassName ? { className: extraClassName } : {}
17833
+ };
17834
+ const severity = errorLines?.get(lineNumber);
17835
+ if (!severity) return base;
17836
+ return {
17837
+ ...base,
17838
+ style: {
17839
+ display: "block",
17840
+ backgroundColor: severity === "error" ? "rgba(248, 113, 113, 0.18)" : "rgba(251, 191, 36, 0.18)",
17841
+ // amber-400 @ 18%
17842
+ borderLeft: `3px solid ${severity === "error" ? "#ef4444" : "#f59e0b"}`,
17843
+ paddingLeft: "0.5rem",
17844
+ marginLeft: "-0.5rem"
17845
+ }
17846
+ };
17847
+ };
17848
+ }
17849
+ var dynamicallyLoaded, codeLanguageLoader, orbStyleOverrides, orbStyle, loloStyleOverrides, loloStyle, log7, 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;
17363
17850
  var init_CodeBlock = __esm({
17364
17851
  "components/core/molecules/markdown/CodeBlock.tsx"() {
17365
17852
  init_cn();
@@ -17375,6 +17862,7 @@ var init_CodeBlock = __esm({
17375
17862
  init_Textarea();
17376
17863
  init_Icon();
17377
17864
  init_useEventBus();
17865
+ init_useEditorCapabilities();
17378
17866
  SyntaxHighlighter.registerLanguage("json", langJson);
17379
17867
  SyntaxHighlighter.registerLanguage("javascript", langJavascript);
17380
17868
  SyntaxHighlighter.registerLanguage("js", langJavascript);
@@ -17592,7 +18080,17 @@ var init_CodeBlock = __esm({
17592
18080
  DIFF_STYLE_FALLBACK = { bg: "", prefix: " ", text: "text-foreground" };
17593
18081
  LINE_PROPS_FN = (n) => ({ "data-line": String(n - 1) });
17594
18082
  HIDDEN_LINE_NUMBERS = { display: "none" };
17595
- CodeBlock = React88__default.memo(
18083
+ HIGHLIGHT_CAPACITY_BYTES = 512 * 1024;
18084
+ MONO_FONT_FAMILY = 'ui-monospace, SFMono-Regular, Menlo, Monaco, "Cascadia Mono", "Courier New", monospace';
18085
+ VIEWER_LINE_NUMBER_STYLE = {
18086
+ minWidth: "2.5em",
18087
+ paddingRight: "1rem",
18088
+ textAlign: "right",
18089
+ userSelect: "none",
18090
+ opacity: 0.5,
18091
+ fontVariantNumeric: "tabular-nums"
18092
+ };
18093
+ CodeBlock = React89__default.memo(
17596
18094
  ({
17597
18095
  code: rawCode,
17598
18096
  language = "text",
@@ -17616,13 +18114,39 @@ var init_CodeBlock = __esm({
17616
18114
  actions,
17617
18115
  isLoading = false,
17618
18116
  error,
17619
- showCopy
18117
+ showCopy,
18118
+ // editor capability surface — P1 wires these
18119
+ editorId,
18120
+ onEditorFocus = "EDITOR_FOCUS",
18121
+ onEditorBlur = "EDITOR_BLUR",
18122
+ onMotion = "MOTION",
18123
+ onOperate = "OPERATE",
18124
+ onInsertText = "INSERT_TEXT",
18125
+ onSetMode = "SET_MODE",
18126
+ motions = [
18127
+ "left",
18128
+ "right",
18129
+ "up",
18130
+ "down",
18131
+ "word-forward",
18132
+ "word-back",
18133
+ "word-end",
18134
+ "line-start",
18135
+ "line-end",
18136
+ "first-nonblank",
18137
+ "doc-start",
18138
+ "doc-end",
18139
+ "paragraph-forward",
18140
+ "paragraph-back",
18141
+ "line",
18142
+ "selection"
18143
+ ],
18144
+ operators = ["delete", "yank", "change"]
17620
18145
  }) => {
17621
18146
  const code = typeof rawCode === "string" ? rawCode : String(rawCode ?? "");
17622
- const isOrb = language === "orb";
17623
- const isLolo = language === "lolo";
17624
- const activeStyle = isOrb ? orbStyle : isLolo ? loloStyle : dark;
17625
- const languageReady = useLanguageReady(language);
18147
+ const activeStyle = resolveHighlightStyle(language);
18148
+ const overCapacity = code.length > HIGHLIGHT_CAPACITY_BYTES;
18149
+ const plainCodeColor = plainCodeColorOf(activeStyle);
17626
18150
  const eventBus = useEventBus();
17627
18151
  const { t } = useTranslate();
17628
18152
  const scrollRef = useRef(null);
@@ -17634,6 +18158,9 @@ var init_CodeBlock = __esm({
17634
18158
  const activeFile = files?.[activeFileIndex];
17635
18159
  const activeCode = activeFile?.code ?? code;
17636
18160
  const activeLanguage = activeFile?.language ?? language;
18161
+ const languageReady = useLanguageReady(activeLanguage);
18162
+ const viewerStyle = resolveHighlightStyle(activeLanguage);
18163
+ const viewerPlainCodeColor = plainCodeColorOf(viewerStyle);
17637
18164
  const diffLines = useMemo(() => {
17638
18165
  if (propDiff) return propDiff;
17639
18166
  if (mode === "diff" && oldValue !== void 0 && newValue !== void 0) {
@@ -17663,33 +18190,33 @@ var init_CodeBlock = __esm({
17663
18190
  ov.scrollLeft = ta.scrollLeft;
17664
18191
  }
17665
18192
  }, []);
17666
- const errorLineProps = useMemo(() => {
17667
- if (!errorLines || errorLines.size === 0) {
17668
- return LINE_PROPS_FN;
17669
- }
17670
- return (lineNumber) => {
17671
- const severity = errorLines.get(lineNumber);
17672
- if (!severity) {
17673
- return { "data-line": String(lineNumber - 1) };
17674
- }
17675
- return {
17676
- "data-line": String(lineNumber - 1),
17677
- style: {
17678
- display: "block",
17679
- backgroundColor: severity === "error" ? "rgba(248, 113, 113, 0.18)" : "rgba(251, 191, 36, 0.18)",
17680
- // amber-400 @ 18%
17681
- borderLeft: `3px solid ${severity === "error" ? "#ef4444" : "#f59e0b"}`,
17682
- paddingLeft: "0.5rem",
17683
- marginLeft: "-0.5rem"
17684
- }
17685
- };
17686
- };
17687
- }, [errorLines]);
18193
+ const handleEditableChange = useCallback((v) => {
18194
+ lastPropCodeRef.current = v;
18195
+ setEditableValue(v);
18196
+ onChange?.(v);
18197
+ }, [onChange]);
18198
+ const { caretMode } = useEditorCapabilities({
18199
+ editorId: editable ? editorId : void 0,
18200
+ textareaRef: editableTextareaRef,
18201
+ events: { onMotion, onOperate, onInsertText, onSetMode },
18202
+ applyChange: handleEditableChange
18203
+ });
18204
+ const [caretIndex, setCaretIndex] = useState(0);
18205
+ const caretRowCol = useMemo(() => {
18206
+ const before = editableValue.slice(0, Math.min(caretIndex, editableValue.length));
18207
+ const lines = before.split("\n");
18208
+ return { row: lines.length - 1, col: lines[lines.length - 1].length };
18209
+ }, [editableValue, caretIndex]);
18210
+ const errorLineProps = useMemo(() => buildLineProps(errorLines), [errorLines]);
18211
+ const viewerLineProps = useMemo(
18212
+ () => buildLineProps(errorLines, "px-4 py-0.5 hover:bg-muted/50"),
18213
+ [errorLines]
18214
+ );
17688
18215
  const isFoldable = foldableProp ?? true;
17689
18216
  const [collapsed, setCollapsed] = useState(() => /* @__PURE__ */ new Set());
17690
18217
  const foldRegions = useMemo(
17691
- () => isFoldable ? computeFoldRegions(code) : [],
17692
- [code, isFoldable]
18218
+ () => isFoldable && !overCapacity ? computeFoldRegions(code) : [],
18219
+ [code, isFoldable, overCapacity]
17693
18220
  );
17694
18221
  const foldStartMap = useMemo(() => {
17695
18222
  const m = /* @__PURE__ */ new Map();
@@ -17723,8 +18250,67 @@ var init_CodeBlock = __esm({
17723
18250
  useEffect(() => {
17724
18251
  setCollapsed(/* @__PURE__ */ new Set());
17725
18252
  }, [code]);
18253
+ const editableOverCapacity = editableValue.length > HIGHLIGHT_CAPACITY_BYTES;
18254
+ const editableHighlightedElement = useMemo(
18255
+ () => editableOverCapacity ? /* @__PURE__ */ jsx(
18256
+ "div",
18257
+ {
18258
+ style: {
18259
+ padding: "1rem",
18260
+ margin: 0,
18261
+ whiteSpace: "pre",
18262
+ minWidth: "100%",
18263
+ color: plainCodeColor,
18264
+ fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, "Cascadia Mono", "Courier New", monospace',
18265
+ fontSize: "13px",
18266
+ lineHeight: "1.5"
18267
+ },
18268
+ children: editableValue || " "
18269
+ }
18270
+ ) : /* @__PURE__ */ jsx(
18271
+ SyntaxHighlighter,
18272
+ {
18273
+ PreTag: "div",
18274
+ language,
18275
+ style: activeStyle,
18276
+ wrapLines: errorLines && errorLines.size > 0,
18277
+ lineProps: errorLineProps,
18278
+ customStyle: {
18279
+ backgroundColor: "transparent",
18280
+ borderRadius: 0,
18281
+ padding: "1rem",
18282
+ margin: 0,
18283
+ whiteSpace: "pre",
18284
+ minWidth: "100%",
18285
+ fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, "Cascadia Mono", "Courier New", monospace',
18286
+ fontSize: "13px",
18287
+ lineHeight: "1.5"
18288
+ },
18289
+ codeTagProps: {
18290
+ style: {
18291
+ fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, "Cascadia Mono", "Courier New", monospace',
18292
+ fontSize: "13px",
18293
+ lineHeight: "1.5"
18294
+ }
18295
+ },
18296
+ children: editableValue || " "
18297
+ }
18298
+ ),
18299
+ [editableValue, editableOverCapacity, plainCodeColor, language, activeStyle, errorLines, errorLineProps, languageReady]
18300
+ );
17726
18301
  const highlightedElement = useMemo(
17727
- () => /* @__PURE__ */ jsx(
18302
+ () => overCapacity ? /* @__PURE__ */ jsx(
18303
+ "div",
18304
+ {
18305
+ style: {
18306
+ margin: 0,
18307
+ whiteSpace: "pre",
18308
+ minWidth: "100%",
18309
+ color: plainCodeColor
18310
+ },
18311
+ children: code
18312
+ }
18313
+ ) : /* @__PURE__ */ jsx(
17728
18314
  SyntaxHighlighter,
17729
18315
  {
17730
18316
  PreTag: "div",
@@ -17746,8 +18332,112 @@ var init_CodeBlock = __esm({
17746
18332
  children: code
17747
18333
  }
17748
18334
  ),
17749
- [code, language, activeStyle, languageReady]
18335
+ [code, overCapacity, plainCodeColor, language, activeStyle, languageReady]
17750
18336
  );
18337
+ const viewerOverCapacity = activeCode.length > HIGHLIGHT_CAPACITY_BYTES;
18338
+ const viewerHighlightedElement = useMemo(
18339
+ () => viewerOverCapacity ? /* @__PURE__ */ jsx(
18340
+ "div",
18341
+ {
18342
+ className: "px-4 py-0.5",
18343
+ style: {
18344
+ margin: 0,
18345
+ whiteSpace: wrap ? "pre-wrap" : "pre",
18346
+ wordBreak: wrap ? "break-all" : "normal",
18347
+ color: viewerPlainCodeColor,
18348
+ fontFamily: MONO_FONT_FAMILY,
18349
+ fontSize: "12px",
18350
+ lineHeight: "1.6"
18351
+ },
18352
+ children: activeCode
18353
+ }
18354
+ ) : /* @__PURE__ */ jsx(
18355
+ SyntaxHighlighter,
18356
+ {
18357
+ PreTag: "div",
18358
+ language: activeLanguage,
18359
+ style: viewerStyle,
18360
+ wrapLines: true,
18361
+ wrapLongLines: wrap,
18362
+ showLineNumbers,
18363
+ lineNumberStyle: VIEWER_LINE_NUMBER_STYLE,
18364
+ lineProps: viewerLineProps,
18365
+ customStyle: {
18366
+ backgroundColor: "transparent",
18367
+ borderRadius: 0,
18368
+ padding: "0.25rem 0",
18369
+ margin: 0,
18370
+ whiteSpace: wrap ? "pre-wrap" : "pre",
18371
+ wordBreak: wrap ? "break-all" : "normal",
18372
+ fontFamily: MONO_FONT_FAMILY,
18373
+ fontSize: "12px",
18374
+ lineHeight: "1.6"
18375
+ },
18376
+ codeTagProps: { style: { fontFamily: MONO_FONT_FAMILY, fontSize: "12px", lineHeight: "1.6" } },
18377
+ children: activeCode
18378
+ }
18379
+ ),
18380
+ [activeCode, viewerOverCapacity, viewerPlainCodeColor, activeLanguage, viewerStyle, wrap, showLineNumbers, viewerLineProps, languageReady]
18381
+ );
18382
+ const diffOverCapacity = useMemo(
18383
+ () => !!diffLines && diffLines.reduce((n, l) => n + l.content.length + 1, 0) > HIGHLIGHT_CAPACITY_BYTES,
18384
+ [diffLines]
18385
+ );
18386
+ const diffRowElements = useMemo(() => {
18387
+ if (!diffLines) return null;
18388
+ return diffLines.map((line, idx) => {
18389
+ const style = DIFF_STYLES[line.type] ?? DIFF_STYLE_FALLBACK;
18390
+ return /* @__PURE__ */ jsxs(HStack, { gap: "none", align: "start", className: cn(style.bg, "px-4 py-0.5"), children: [
18391
+ showLineNumbers && /* @__PURE__ */ jsx(
18392
+ Typography,
18393
+ {
18394
+ variant: "caption",
18395
+ color: "secondary",
18396
+ className: "w-8 text-right mr-3 select-none tabular-nums flex-shrink-0",
18397
+ children: line.lineNumber ?? ""
18398
+ }
18399
+ ),
18400
+ /* @__PURE__ */ jsxs(
18401
+ Typography,
18402
+ {
18403
+ variant: "caption",
18404
+ className: cn("font-mono flex-1 min-w-0", style.text, wrap ? "whitespace-pre-wrap break-all" : "whitespace-pre"),
18405
+ children: [
18406
+ /* @__PURE__ */ jsx(Box, { as: "span", className: "select-none opacity-50 mr-2", children: style.prefix }),
18407
+ diffOverCapacity ? line.content || " " : /* @__PURE__ */ jsx(
18408
+ SyntaxHighlighter,
18409
+ {
18410
+ PreTag: "span",
18411
+ CodeTag: "span",
18412
+ language: activeLanguage,
18413
+ style: viewerStyle,
18414
+ customStyle: {
18415
+ display: "inline",
18416
+ background: "transparent",
18417
+ padding: 0,
18418
+ margin: 0,
18419
+ whiteSpace: wrap ? "pre-wrap" : "pre",
18420
+ wordBreak: wrap ? "break-all" : "normal",
18421
+ fontFamily: "inherit",
18422
+ fontSize: "inherit",
18423
+ lineHeight: "inherit"
18424
+ },
18425
+ codeTagProps: {
18426
+ style: {
18427
+ whiteSpace: wrap ? "pre-wrap" : "pre",
18428
+ fontFamily: "inherit",
18429
+ fontSize: "inherit"
18430
+ }
18431
+ },
18432
+ children: line.content || " "
18433
+ }
18434
+ )
18435
+ ]
18436
+ }
18437
+ )
18438
+ ] }, idx);
18439
+ });
18440
+ }, [diffLines, showLineNumbers, wrap, diffOverCapacity, activeLanguage, viewerStyle, languageReady]);
17751
18441
  useLayoutEffect(() => {
17752
18442
  const container = codeRef.current;
17753
18443
  if (!container) return;
@@ -17891,7 +18581,6 @@ var init_CodeBlock = __esm({
17891
18581
  label: file.label,
17892
18582
  content: null
17893
18583
  }));
17894
- const lines = activeCode.split("\n");
17895
18584
  return /* @__PURE__ */ jsx(Card, { className: cn("overflow-hidden", className), children: /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column" }, children: [
17896
18585
  tabItems && tabItems.length > 1 && /* @__PURE__ */ jsx(Box, { className: "border-b border-border", children: /* @__PURE__ */ jsx(
17897
18586
  Tabs,
@@ -17954,49 +18643,7 @@ var init_CodeBlock = __esm({
17954
18643
  ]
17955
18644
  }
17956
18645
  ),
17957
- /* @__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) => {
17958
- const style = DIFF_STYLES[line.type] ?? DIFF_STYLE_FALLBACK;
17959
- return /* @__PURE__ */ jsxs(HStack, { gap: "none", align: "start", className: cn(style.bg, "px-4 py-0.5"), children: [
17960
- showLineNumbers && /* @__PURE__ */ jsx(
17961
- Typography,
17962
- {
17963
- variant: "caption",
17964
- color: "secondary",
17965
- className: "w-8 text-right mr-3 select-none tabular-nums flex-shrink-0",
17966
- children: line.lineNumber ?? ""
17967
- }
17968
- ),
17969
- /* @__PURE__ */ jsxs(
17970
- Typography,
17971
- {
17972
- variant: "caption",
17973
- className: cn("font-mono flex-1 min-w-0", style.text, wrap ? "whitespace-pre-wrap break-all" : "whitespace-pre"),
17974
- children: [
17975
- /* @__PURE__ */ jsx(Box, { as: "span", className: "select-none opacity-50 mr-2", children: style.prefix }),
17976
- line.content
17977
- ]
17978
- }
17979
- )
17980
- ] }, idx);
17981
- }) }) : /* @__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: [
17982
- showLineNumbers && /* @__PURE__ */ jsx(
17983
- Typography,
17984
- {
17985
- variant: "caption",
17986
- color: "secondary",
17987
- className: "w-8 text-right mr-4 select-none tabular-nums flex-shrink-0",
17988
- children: idx + 1
17989
- }
17990
- ),
17991
- /* @__PURE__ */ jsx(
17992
- Typography,
17993
- {
17994
- variant: "caption",
17995
- className: cn("font-mono flex-1 min-w-0", wrap ? "whitespace-pre-wrap break-all" : "whitespace-pre"),
17996
- children: line || " "
17997
- }
17998
- )
17999
- ] }, idx)) }) })
18646
+ /* @__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 }) })
18000
18647
  ] }) });
18001
18648
  }
18002
18649
  const hasHeader = showLanguageBadge || effectiveCopy;
@@ -18075,35 +18722,7 @@ var init_CodeBlock = __esm({
18075
18722
  overflow: "hidden",
18076
18723
  pointerEvents: "none"
18077
18724
  },
18078
- children: /* @__PURE__ */ jsx(
18079
- SyntaxHighlighter,
18080
- {
18081
- PreTag: "div",
18082
- language,
18083
- style: activeStyle,
18084
- wrapLines: errorLines && errorLines.size > 0,
18085
- lineProps: errorLineProps,
18086
- customStyle: {
18087
- backgroundColor: "transparent",
18088
- borderRadius: 0,
18089
- padding: "1rem",
18090
- margin: 0,
18091
- whiteSpace: "pre",
18092
- minWidth: "100%",
18093
- fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, "Cascadia Mono", "Courier New", monospace',
18094
- fontSize: "13px",
18095
- lineHeight: "1.5"
18096
- },
18097
- codeTagProps: {
18098
- style: {
18099
- fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, "Cascadia Mono", "Courier New", monospace',
18100
- fontSize: "13px",
18101
- lineHeight: "1.5"
18102
- }
18103
- },
18104
- children: editableValue || " "
18105
- }
18106
- )
18725
+ children: editableHighlightedElement
18107
18726
  }
18108
18727
  ),
18109
18728
  /* @__PURE__ */ jsx(
@@ -18111,13 +18730,11 @@ var init_CodeBlock = __esm({
18111
18730
  {
18112
18731
  ref: editableTextareaRef,
18113
18732
  defaultValue: code,
18114
- onChange: (e) => {
18115
- const v = e.target.value;
18116
- lastPropCodeRef.current = v;
18117
- setEditableValue(v);
18118
- onChange?.(v);
18119
- },
18733
+ onChange: (e) => handleEditableChange(e.target.value),
18120
18734
  onScroll: handleEditableScroll,
18735
+ onSelect: (e) => setCaretIndex(e.currentTarget.selectionStart),
18736
+ onFocus: editorId ? () => eventBus.emit(`UI:${onEditorFocus}`, { editorId }) : void 0,
18737
+ onBlur: editorId ? () => eventBus.emit(`UI:${onEditorBlur}`, { editorId }) : void 0,
18121
18738
  spellCheck: false,
18122
18739
  style: {
18123
18740
  position: "absolute",
@@ -18132,7 +18749,7 @@ var init_CodeBlock = __esm({
18132
18749
  resize: "none",
18133
18750
  backgroundColor: "transparent",
18134
18751
  color: "transparent",
18135
- caretColor: "#e6e6e6",
18752
+ caretColor: caretMode === "block" ? "transparent" : "#e6e6e6",
18136
18753
  WebkitTextFillColor: "transparent",
18137
18754
  fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, "Cascadia Mono", "Courier New", monospace',
18138
18755
  fontSize: "13px",
@@ -18143,6 +18760,22 @@ var init_CodeBlock = __esm({
18143
18760
  }
18144
18761
  },
18145
18762
  editableTextareaKey
18763
+ ),
18764
+ caretMode !== "bar" && /* @__PURE__ */ jsx(
18765
+ "span",
18766
+ {
18767
+ "aria-hidden": true,
18768
+ style: {
18769
+ position: "absolute",
18770
+ top: `calc(1rem + ${caretRowCol.row * 19.5}px)`,
18771
+ left: `calc(1rem + ${caretRowCol.col}ch)`,
18772
+ width: "1ch",
18773
+ height: caretMode === "block" ? "19.5px" : "2px",
18774
+ backgroundColor: caretMode === "block" ? "rgba(230, 230, 230, 0.5)" : void 0,
18775
+ borderBottom: caretMode === "underline" ? "2px solid #e6e6e6" : void 0,
18776
+ pointerEvents: "none"
18777
+ }
18778
+ }
18146
18779
  )
18147
18780
  ]
18148
18781
  }
@@ -18170,55 +18803,175 @@ var init_CodeBlock = __esm({
18170
18803
  )
18171
18804
  ] });
18172
18805
  },
18173
- (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
18806
+ (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
18174
18807
  );
18175
18808
  CodeBlock.displayName = "CodeBlock";
18176
18809
  }
18177
18810
  });
18811
+
18812
+ // components/core/molecules/markdown/mermaidSource.ts
18813
+ function isQuoted(label) {
18814
+ const trimmed = label.trim();
18815
+ return trimmed.length === 0 || trimmed.startsWith('"') && trimmed.endsWith('"') && trimmed.length > 1;
18816
+ }
18817
+ function quote(label) {
18818
+ return `"${label.replace(/"/g, "#quot;")}"`;
18819
+ }
18820
+ function isIdentifierChar(ch) {
18821
+ return /[A-Za-z0-9_\-.]/.test(ch);
18822
+ }
18823
+ function declaredType(code) {
18824
+ for (const line of code.split("\n")) {
18825
+ const trimmed = line.trim();
18826
+ if (trimmed.length === 0 || trimmed.startsWith("%%")) continue;
18827
+ return trimmed;
18828
+ }
18829
+ return "";
18830
+ }
18831
+ function isFlowchart(code) {
18832
+ return FLOWCHART_DIRECTIVE.test(declaredType(code));
18833
+ }
18834
+ function quoteNodeLabels(code) {
18835
+ let out = "";
18836
+ let i = 0;
18837
+ while (i < code.length) {
18838
+ const shape = NODE_SHAPES.find(([open2]) => code.startsWith(open2, i));
18839
+ const precededByIdentifier = i > 0 && isIdentifierChar(code[i - 1] ?? "");
18840
+ if (shape === void 0 || !precededByIdentifier) {
18841
+ out += code[i];
18842
+ i += 1;
18843
+ continue;
18844
+ }
18845
+ const [open, close] = shape;
18846
+ const contentStart = i + open.length;
18847
+ const closeAt = code.indexOf(close, contentStart);
18848
+ const newlineAt = code.indexOf("\n", contentStart);
18849
+ if (closeAt === -1 || newlineAt !== -1 && newlineAt < closeAt) {
18850
+ out += code[i];
18851
+ i += 1;
18852
+ continue;
18853
+ }
18854
+ const label = code.slice(contentStart, closeAt);
18855
+ out += open + (isQuoted(label) ? label : quote(label)) + close;
18856
+ i = closeAt + close.length;
18857
+ }
18858
+ return out;
18859
+ }
18860
+ function quoteEdgeLabels(code) {
18861
+ return code.split("\n").map((line) => {
18862
+ let out = "";
18863
+ let rest = line;
18864
+ for (; ; ) {
18865
+ const open = rest.indexOf("|");
18866
+ if (open === -1) break;
18867
+ const close = rest.indexOf("|", open + 1);
18868
+ if (close === -1) break;
18869
+ const label = rest.slice(open + 1, close);
18870
+ out += rest.slice(0, open + 1) + (isQuoted(label) ? label : quote(label)) + "|";
18871
+ rest = rest.slice(close + 1);
18872
+ }
18873
+ return out + rest;
18874
+ }).join("\n");
18875
+ }
18876
+ function quoteSubgraphTitles(code) {
18877
+ return code.split("\n").map((line) => {
18878
+ const match = /^(\s*subgraph\s+)(.+?)(\s*)$/.exec(line);
18879
+ if (match === null) return line;
18880
+ const [, prefix, title, trailing] = match;
18881
+ if (title === void 0 || prefix === void 0) return line;
18882
+ if (isQuoted(title) || title.includes("[")) return line;
18883
+ return prefix + quote(title) + (trailing ?? "");
18884
+ }).join("\n");
18885
+ }
18886
+ function mermaidRepairCandidates(code) {
18887
+ if (!isFlowchart(code)) return [];
18888
+ const nodes = quoteNodeLabels(code);
18889
+ const nodesAndEdges = quoteEdgeLabels(nodes);
18890
+ const all = quoteSubgraphTitles(nodesAndEdges);
18891
+ const ordered2 = [nodes, nodesAndEdges, all];
18892
+ const seen = /* @__PURE__ */ new Set([code]);
18893
+ const candidates = [];
18894
+ for (const candidate of ordered2) {
18895
+ if (seen.has(candidate)) continue;
18896
+ seen.add(candidate);
18897
+ candidates.push(candidate);
18898
+ }
18899
+ return candidates;
18900
+ }
18901
+ var NODE_SHAPES, FLOWCHART_DIRECTIVE;
18902
+ var init_mermaidSource = __esm({
18903
+ "components/core/molecules/markdown/mermaidSource.ts"() {
18904
+ NODE_SHAPES = [
18905
+ ["[[", "]]"],
18906
+ ["[(", ")]"],
18907
+ ["([", "])"],
18908
+ ["((", "))"],
18909
+ ["{{", "}}"],
18910
+ ["[", "]"],
18911
+ ["(", ")"],
18912
+ ["{", "}"]
18913
+ ];
18914
+ FLOWCHART_DIRECTIVE = /^(?:graph|flowchart)\b/;
18915
+ }
18916
+ });
18178
18917
  function loadMermaid() {
18179
18918
  mermaidModule ?? (mermaidModule = import('mermaid').then((m) => m.default));
18180
18919
  return mermaidModule;
18181
18920
  }
18182
- var mermaidModule, MermaidDiagram;
18921
+ var log8, mermaidModule, MermaidDiagram;
18183
18922
  var init_MermaidDiagram = __esm({
18184
18923
  "components/core/molecules/markdown/MermaidDiagram.tsx"() {
18185
18924
  init_Box();
18186
18925
  init_Typography();
18187
18926
  init_CodeBlock();
18927
+ init_mermaidSource();
18188
18928
  init_cn();
18929
+ log8 = createLogger("almadar:ui:mermaid-diagram");
18189
18930
  mermaidModule = null;
18190
- MermaidDiagram = React88__default.memo(
18931
+ MermaidDiagram = React89__default.memo(
18191
18932
  ({ code, className }) => {
18192
18933
  const { resolvedMode } = useTheme();
18934
+ const { t } = useTranslate();
18193
18935
  const containerRef = useRef(null);
18194
- const [error, setError] = useState(null);
18936
+ const [unrenderable, setUnrenderable] = useState(false);
18195
18937
  const reactId = useId();
18196
18938
  useEffect(() => {
18197
18939
  let active = true;
18198
18940
  void (async () => {
18199
- try {
18200
- const mermaid = await loadMermaid();
18201
- mermaid.initialize({
18202
- startOnLoad: false,
18203
- securityLevel: "strict",
18204
- theme: resolvedMode === "dark" ? "dark" : "default"
18205
- });
18206
- const domId = `mermaid-${reactId.replace(/[^a-zA-Z0-9]/g, "")}`;
18207
- const { svg } = await mermaid.render(domId, code);
18208
- if (!active || !containerRef.current) return;
18209
- containerRef.current.innerHTML = svg;
18210
- setError(null);
18211
- } catch (err) {
18212
- if (active) setError(err instanceof Error ? err.message : String(err));
18941
+ const mermaid = await loadMermaid();
18942
+ mermaid.initialize({
18943
+ startOnLoad: false,
18944
+ securityLevel: "strict",
18945
+ theme: resolvedMode === "dark" ? "dark" : "default"
18946
+ });
18947
+ const domId = `mermaid-${reactId.replace(/[^a-zA-Z0-9]/g, "")}`;
18948
+ let firstError = null;
18949
+ for (const [index, source] of [code, ...mermaidRepairCandidates(code)].entries()) {
18950
+ try {
18951
+ const { svg } = await mermaid.render(domId, source);
18952
+ if (!active) return;
18953
+ const container = containerRef.current;
18954
+ if (container === null) return;
18955
+ container.innerHTML = svg;
18956
+ container.dataset.mermaidRepaired = String(index > 0);
18957
+ setUnrenderable(false);
18958
+ if (index > 0) log8.debug("mermaid:repaired", { candidate: index });
18959
+ return;
18960
+ } catch (err) {
18961
+ firstError ?? (firstError = err instanceof Error ? err : new Error(String(err)));
18962
+ }
18213
18963
  }
18964
+ if (!active) return;
18965
+ log8.warn("mermaid:unrenderable", { error: firstError?.message ?? "", code });
18966
+ setUnrenderable(true);
18214
18967
  })();
18215
18968
  return () => {
18216
18969
  active = false;
18217
18970
  };
18218
18971
  }, [code, resolvedMode, reactId]);
18219
18972
  return /* @__PURE__ */ jsxs(Box, { className: cn("not-prose my-4", className), children: [
18220
- error !== null && /* @__PURE__ */ jsxs(Box, { className: "space-y-2 mb-2", children: [
18221
- /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-error whitespace-pre-wrap", children: error }),
18973
+ unrenderable && /* @__PURE__ */ jsxs(Box, { className: "space-y-2 mb-2", "data-testid": "mermaid-unrenderable", children: [
18974
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: t("mermaid.unrenderable") }),
18222
18975
  /* @__PURE__ */ jsx(CodeBlock, { code, language: "mermaid" })
18223
18976
  ] }),
18224
18977
  /* @__PURE__ */ jsx(
@@ -18227,7 +18980,7 @@ var init_MermaidDiagram = __esm({
18227
18980
  ref: containerRef,
18228
18981
  "data-testid": "mermaid-diagram",
18229
18982
  className: "overflow-x-auto",
18230
- style: error !== null ? { display: "none" } : void 0
18983
+ style: unrenderable ? { display: "none" } : void 0
18231
18984
  }
18232
18985
  )
18233
18986
  ] });
@@ -18245,7 +18998,7 @@ var init_MarkdownContent = __esm({
18245
18998
  init_CodeBlock();
18246
18999
  init_MermaidDiagram();
18247
19000
  init_cn();
18248
- MarkdownContent = React88__default.memo(
19001
+ MarkdownContent = React89__default.memo(
18249
19002
  ({ content, direction = "ltr", className }) => {
18250
19003
  const { t: _t } = useTranslate();
18251
19004
  const safeContent = typeof content === "string" ? content : String(content ?? "");
@@ -19575,7 +20328,7 @@ var init_StateMachineView = __esm({
19575
20328
  style: { top: title ? 30 : 0 },
19576
20329
  children: [
19577
20330
  entity && /* @__PURE__ */ jsx(EntityBox, { entity, config }),
19578
- states.map((state) => renderStateNode ? /* @__PURE__ */ jsx(React88__default.Fragment, { children: renderStateNode(state, config) }, state.id) : /* @__PURE__ */ jsx(
20331
+ states.map((state) => renderStateNode ? /* @__PURE__ */ jsx(React89__default.Fragment, { children: renderStateNode(state, config) }, state.id) : /* @__PURE__ */ jsx(
19579
20332
  StateNode2,
19580
20333
  {
19581
20334
  state,
@@ -21632,14 +22385,14 @@ function useSafeEventBus2() {
21632
22385
  } };
21633
22386
  }
21634
22387
  }
21635
- var log8, lookStyles4, ButtonGroup;
22388
+ var log9, lookStyles4, ButtonGroup;
21636
22389
  var init_ButtonGroup = __esm({
21637
22390
  "components/core/molecules/ButtonGroup.tsx"() {
21638
22391
  "use client";
21639
22392
  init_cn();
21640
22393
  init_atoms();
21641
22394
  init_useEventBus();
21642
- log8 = createLogger("almadar:ui:button-group");
22395
+ log9 = createLogger("almadar:ui:button-group");
21643
22396
  lookStyles4 = {
21644
22397
  "right-aligned-buttons": "",
21645
22398
  "floating-bar": "fixed bottom-section left-1/2 -translate-x-1/2 shadow-elevation-toast bg-card p-card-sm rounded-container",
@@ -21720,7 +22473,7 @@ var init_ButtonGroup = __esm({
21720
22473
  {
21721
22474
  variant: "ghost",
21722
22475
  onClick: () => {
21723
- log8.debug("Filter clicked", { field: filter.field });
22476
+ log9.debug("Filter clicked", { field: filter.field });
21724
22477
  },
21725
22478
  children: filter.label
21726
22479
  },
@@ -24489,6 +25242,187 @@ var init_CodeRunnerPanel = __esm({
24489
25242
  CodeRunnerPanel.displayName = "CodeRunnerPanel";
24490
25243
  }
24491
25244
  });
25245
+ function matchesQuery(query, text) {
25246
+ if (!query) return true;
25247
+ let qi = 0;
25248
+ const q = query.toLowerCase();
25249
+ const t = text.toLowerCase();
25250
+ for (let ti = 0; ti < t.length && qi < q.length; ti++) {
25251
+ if (t[ti] === q[qi]) qi++;
25252
+ }
25253
+ return qi === q.length;
25254
+ }
25255
+ function commandMatches(command, query) {
25256
+ if (!query) return true;
25257
+ if (matchesQuery(query, command.label)) return true;
25258
+ return (command.keywords ?? []).some((keyword) => matchesQuery(query, keyword));
25259
+ }
25260
+ function dispatchCommandPaletteCommand(command, deps) {
25261
+ if (command.disabled) return;
25262
+ if (command.event) deps.emit(`UI:${command.event}`, { commandId: command.id });
25263
+ if (command.action) deps.emit(`UI:${command.action}`, command.actionPayload ?? {});
25264
+ deps.onSelect?.(command);
25265
+ }
25266
+ var UNGROUPED, CommandPalette;
25267
+ var init_CommandPalette = __esm({
25268
+ "components/core/molecules/CommandPalette.tsx"() {
25269
+ "use client";
25270
+ init_Box();
25271
+ init_Stack();
25272
+ init_Typography();
25273
+ init_Icon();
25274
+ init_Input();
25275
+ init_Badge();
25276
+ init_cn();
25277
+ init_useEventBus();
25278
+ init_Modal();
25279
+ UNGROUPED = /* @__PURE__ */ Symbol("command-palette-ungrouped");
25280
+ CommandPalette = ({
25281
+ open,
25282
+ onOpenChange,
25283
+ commands,
25284
+ onSelect,
25285
+ placeholder = "Type a command...",
25286
+ emptyLabel = "No matching commands",
25287
+ className
25288
+ }) => {
25289
+ const eventBus = useEventBus();
25290
+ const [query, setQuery] = useState("");
25291
+ const [highlightIndex, setHighlightIndex] = useState(0);
25292
+ const filtered = useMemo(
25293
+ () => commands.filter((command) => commandMatches(command, query)),
25294
+ [commands, query]
25295
+ );
25296
+ const groups = useMemo(() => {
25297
+ const order = [];
25298
+ const byGroup = /* @__PURE__ */ new Map();
25299
+ for (const command of filtered) {
25300
+ const key = command.group ?? UNGROUPED;
25301
+ if (!byGroup.has(key)) {
25302
+ byGroup.set(key, []);
25303
+ order.push(key);
25304
+ }
25305
+ byGroup.get(key).push(command);
25306
+ }
25307
+ return order.map((key) => ({ group: key === UNGROUPED ? void 0 : key, items: byGroup.get(key) }));
25308
+ }, [filtered]);
25309
+ const resetQuery = useCallback(() => {
25310
+ setQuery("");
25311
+ setHighlightIndex(0);
25312
+ }, []);
25313
+ const handleClose = useCallback(() => {
25314
+ resetQuery();
25315
+ onOpenChange(false);
25316
+ }, [onOpenChange, resetQuery]);
25317
+ const handleSelect = useCallback(
25318
+ (command) => {
25319
+ if (command.disabled) return;
25320
+ dispatchCommandPaletteCommand(command, { emit: eventBus.emit, onSelect });
25321
+ handleClose();
25322
+ },
25323
+ [eventBus, onSelect, handleClose]
25324
+ );
25325
+ const handleQueryChange = useCallback((e) => {
25326
+ setQuery(e.target.value);
25327
+ setHighlightIndex(0);
25328
+ }, []);
25329
+ const handleKeyDown = useCallback(
25330
+ (e) => {
25331
+ if (filtered.length === 0) return;
25332
+ if (e.key === "ArrowDown") {
25333
+ e.preventDefault();
25334
+ setHighlightIndex((prev) => prev < filtered.length - 1 ? prev + 1 : 0);
25335
+ } else if (e.key === "ArrowUp") {
25336
+ e.preventDefault();
25337
+ setHighlightIndex((prev) => prev > 0 ? prev - 1 : filtered.length - 1);
25338
+ } else if (e.key === "Enter") {
25339
+ e.preventDefault();
25340
+ const command = filtered[highlightIndex];
25341
+ if (command) handleSelect(command);
25342
+ }
25343
+ },
25344
+ [filtered, highlightIndex, handleSelect]
25345
+ );
25346
+ return /* @__PURE__ */ jsx(
25347
+ Modal,
25348
+ {
25349
+ isOpen: open,
25350
+ onClose: handleClose,
25351
+ onExited: resetQuery,
25352
+ showCloseButton: false,
25353
+ size: "md",
25354
+ className,
25355
+ children: /* @__PURE__ */ jsx(Box, { "data-testid": "command-palette", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
25356
+ /* @__PURE__ */ jsx(
25357
+ Input,
25358
+ {
25359
+ inputType: "search",
25360
+ placeholder,
25361
+ value: query,
25362
+ onChange: handleQueryChange,
25363
+ onKeyDown: handleKeyDown,
25364
+ leftIcon: "search",
25365
+ clearable: query.length > 0,
25366
+ onClear: resetQuery,
25367
+ autoFocus: true,
25368
+ "data-testid": "command-palette-input"
25369
+ }
25370
+ ),
25371
+ 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(
25372
+ Box,
25373
+ {
25374
+ className: "max-h-80 overflow-y-auto",
25375
+ role: "listbox",
25376
+ "aria-label": placeholder,
25377
+ children: /* @__PURE__ */ jsx(VStack, { gap: "none", children: groups.map(({ group, items }) => /* @__PURE__ */ jsxs(Box, { children: [
25378
+ group ? /* @__PURE__ */ jsx(
25379
+ Typography,
25380
+ {
25381
+ variant: "caption",
25382
+ color: "muted",
25383
+ className: "px-3 pt-2 pb-1 block",
25384
+ children: group
25385
+ }
25386
+ ) : null,
25387
+ items.map((command) => {
25388
+ const index = filtered.indexOf(command);
25389
+ const isHighlighted = index === highlightIndex;
25390
+ return /* @__PURE__ */ jsxs(
25391
+ Box,
25392
+ {
25393
+ as: "button",
25394
+ role: "option",
25395
+ "aria-selected": isHighlighted,
25396
+ "aria-disabled": command.disabled || void 0,
25397
+ "data-testid": `command-palette-item-${command.id}`,
25398
+ onMouseEnter: () => !command.disabled && setHighlightIndex(index),
25399
+ onClick: () => handleSelect(command),
25400
+ className: cn(
25401
+ "w-full flex items-center gap-3 px-3 py-2 text-start rounded-sm",
25402
+ "text-sm transition-colors",
25403
+ "focus:outline-none",
25404
+ isHighlighted && "bg-muted",
25405
+ command.disabled && "opacity-50 cursor-not-allowed"
25406
+ ),
25407
+ children: [
25408
+ command.icon ? /* @__PURE__ */ jsx(Icon, { icon: command.icon, size: "sm", className: "flex-shrink-0" }) : null,
25409
+ /* @__PURE__ */ jsx(Typography, { variant: "small", className: "flex-1 truncate", children: command.label }),
25410
+ command.shortcut ? /* @__PURE__ */ jsx(Badge, { variant: "neutral", size: "sm", children: command.shortcut }) : null
25411
+ ]
25412
+ },
25413
+ command.id
25414
+ );
25415
+ })
25416
+ ] }, String(group ?? "__ungrouped__"))) })
25417
+ }
25418
+ )
25419
+ ] }) })
25420
+ }
25421
+ );
25422
+ };
25423
+ CommandPalette.displayName = "CommandPalette";
25424
+ }
25425
+ });
24492
25426
  function formatCount(count) {
24493
25427
  if (count >= 1e3) {
24494
25428
  return `${(count / 1e3).toFixed(1)}k`;
@@ -25764,7 +26698,7 @@ var init_Menu = __esm({
25764
26698
  "bottom-end": "bottom-start"
25765
26699
  };
25766
26700
  const effectivePosition = direction === "rtl" ? rtlMirror[position] ?? position : position;
25767
- const triggerElement = React88__default.isValidElement(trigger) ? React88__default.cloneElement(trigger, {
26701
+ const triggerElement = React89__default.isValidElement(trigger) ? React89__default.cloneElement(trigger, {
25768
26702
  ref: triggerRef,
25769
26703
  onClick: handleToggle
25770
26704
  }) : /* @__PURE__ */ jsx(
@@ -25867,14 +26801,14 @@ function useDataDnd(args) {
25867
26801
  const isZone = Boolean(dragGroup || accepts || sortable);
25868
26802
  const enabled = isZone || Boolean(dndRoot);
25869
26803
  const eventBus = useEventBus();
25870
- const parentRoot = React88__default.useContext(RootCtx);
26804
+ const parentRoot = React89__default.useContext(RootCtx);
25871
26805
  const isRoot = enabled && parentRoot === null;
25872
- const zoneId = React88__default.useId();
26806
+ const zoneId = React89__default.useId();
25873
26807
  const ownGroup = dragGroup ?? accepts ?? zoneId;
25874
- const [optimisticOrders, setOptimisticOrders] = React88__default.useState(() => /* @__PURE__ */ new Map());
25875
- const optimisticOrdersRef = React88__default.useRef(optimisticOrders);
26808
+ const [optimisticOrders, setOptimisticOrders] = React89__default.useState(() => /* @__PURE__ */ new Map());
26809
+ const optimisticOrdersRef = React89__default.useRef(optimisticOrders);
25876
26810
  optimisticOrdersRef.current = optimisticOrders;
25877
- const clearOptimisticOrder = React88__default.useCallback((group) => {
26811
+ const clearOptimisticOrder = React89__default.useCallback((group) => {
25878
26812
  setOptimisticOrders((prev) => {
25879
26813
  if (!prev.has(group)) return prev;
25880
26814
  const next = new Map(prev);
@@ -25899,7 +26833,7 @@ function useDataDnd(args) {
25899
26833
  const raw = it[dndItemIdField];
25900
26834
  return raw != null ? String(raw) : `__idx_${idx}`;
25901
26835
  }).join("|");
25902
- const itemIds = React88__default.useMemo(
26836
+ const itemIds = React89__default.useMemo(
25903
26837
  () => orderedItems.map((it, idx) => {
25904
26838
  const raw = it[dndItemIdField];
25905
26839
  return raw != null ? String(raw) : `__idx_${idx}`;
@@ -25910,7 +26844,7 @@ function useDataDnd(args) {
25910
26844
  const raw = it[dndItemIdField];
25911
26845
  return raw != null ? String(raw) : `__${idx}`;
25912
26846
  }).join("|");
25913
- React88__default.useEffect(() => {
26847
+ React89__default.useEffect(() => {
25914
26848
  const root = isRoot ? null : parentRoot;
25915
26849
  if (root) {
25916
26850
  root.clearOptimisticOrder(ownGroup);
@@ -25918,20 +26852,20 @@ function useDataDnd(args) {
25918
26852
  clearOptimisticOrder(ownGroup);
25919
26853
  }
25920
26854
  }, [itemsContentSig, ownGroup]);
25921
- const zonesRef = React88__default.useRef(/* @__PURE__ */ new Map());
25922
- const registerZone = React88__default.useCallback((zoneId2, meta2) => {
26855
+ const zonesRef = React89__default.useRef(/* @__PURE__ */ new Map());
26856
+ const registerZone = React89__default.useCallback((zoneId2, meta2) => {
25923
26857
  zonesRef.current.set(zoneId2, meta2);
25924
26858
  }, []);
25925
- const unregisterZone = React88__default.useCallback((zoneId2) => {
26859
+ const unregisterZone = React89__default.useCallback((zoneId2) => {
25926
26860
  zonesRef.current.delete(zoneId2);
25927
26861
  }, []);
25928
- const [activeDrag, setActiveDrag] = React88__default.useState(null);
25929
- const [overZoneGroup, setOverZoneGroup] = React88__default.useState(null);
25930
- const meta = React88__default.useMemo(
26862
+ const [activeDrag, setActiveDrag] = React89__default.useState(null);
26863
+ const [overZoneGroup, setOverZoneGroup] = React89__default.useState(null);
26864
+ const meta = React89__default.useMemo(
25931
26865
  () => ({ group: ownGroup, dropEvent, reorderEvent, positionEvent, itemIds, rawItems: items, idField: dndItemIdField }),
25932
26866
  [ownGroup, dropEvent, reorderEvent, positionEvent, itemIds, items, dndItemIdField]
25933
26867
  );
25934
- React88__default.useEffect(() => {
26868
+ React89__default.useEffect(() => {
25935
26869
  const target = isRoot ? null : parentRoot;
25936
26870
  if (!target) {
25937
26871
  zonesRef.current.set(zoneId, meta);
@@ -25950,7 +26884,7 @@ function useDataDnd(args) {
25950
26884
  }, [parentRoot, isRoot, zoneId, meta]);
25951
26885
  const sensors = useAlmadarDndSensors(true);
25952
26886
  const collisionDetection = almadarDndCollisionDetection;
25953
- const findZoneByItem = React88__default.useCallback(
26887
+ const findZoneByItem = React89__default.useCallback(
25954
26888
  (id) => {
25955
26889
  for (const z of zonesRef.current.values()) {
25956
26890
  if (z.itemIds.includes(id)) return z;
@@ -25959,7 +26893,7 @@ function useDataDnd(args) {
25959
26893
  },
25960
26894
  []
25961
26895
  );
25962
- React88__default.useCallback(
26896
+ React89__default.useCallback(
25963
26897
  (group) => {
25964
26898
  for (const z of zonesRef.current.values()) {
25965
26899
  if (z.group === group) return z;
@@ -25968,7 +26902,7 @@ function useDataDnd(args) {
25968
26902
  },
25969
26903
  []
25970
26904
  );
25971
- const handleDragEnd = React88__default.useCallback(
26905
+ const handleDragEnd = React89__default.useCallback(
25972
26906
  (event) => {
25973
26907
  const { active, over } = event;
25974
26908
  const activeIdStr = String(active.id);
@@ -26059,8 +26993,8 @@ function useDataDnd(args) {
26059
26993
  },
26060
26994
  [eventBus]
26061
26995
  );
26062
- const sortableData = React88__default.useMemo(() => ({ dndGroup: ownGroup }), [ownGroup]);
26063
- const SortableItem = React88__default.useCallback(
26996
+ const sortableData = React89__default.useMemo(() => ({ dndGroup: ownGroup }), [ownGroup]);
26997
+ const SortableItem = React89__default.useCallback(
26064
26998
  ({ id, children }) => {
26065
26999
  const {
26066
27000
  attributes,
@@ -26100,7 +27034,7 @@ function useDataDnd(args) {
26100
27034
  id: droppableId,
26101
27035
  data: sortableData
26102
27036
  });
26103
- const ctx = React88__default.useContext(RootCtx);
27037
+ const ctx = React89__default.useContext(RootCtx);
26104
27038
  const activeDrag2 = ctx?.activeDrag ?? null;
26105
27039
  const overZoneGroup2 = ctx?.overZoneGroup ?? null;
26106
27040
  const isThisZoneOver = overZoneGroup2 === ownGroup;
@@ -26115,7 +27049,7 @@ function useDataDnd(args) {
26115
27049
  showForeignPlaceholder,
26116
27050
  ctxAvailable: ctx != null
26117
27051
  });
26118
- React88__default.useEffect(() => {
27052
+ React89__default.useEffect(() => {
26119
27053
  dndLog.info("dropzone:isOver:change", { droppableId, group: ownGroup, isOver, isThisZoneOver, showForeignPlaceholder, activeDragSourceGroup: activeDrag2?.sourceGroup ?? null });
26120
27054
  }, [droppableId, isOver, isThisZoneOver, showForeignPlaceholder]);
26121
27055
  return /* @__PURE__ */ jsx(
@@ -26129,11 +27063,11 @@ function useDataDnd(args) {
26129
27063
  }
26130
27064
  );
26131
27065
  };
26132
- const rootContextValue = React88__default.useMemo(
27066
+ const rootContextValue = React89__default.useMemo(
26133
27067
  () => ({ registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder }),
26134
27068
  [registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder]
26135
27069
  );
26136
- const handleDragStart = React88__default.useCallback((event) => {
27070
+ const handleDragStart = React89__default.useCallback((event) => {
26137
27071
  const sourceZone = findZoneByItem(event.active.id);
26138
27072
  const rect = event.active.rect.current.initial;
26139
27073
  const height = rect?.height && rect.height > 0 ? rect.height : 64;
@@ -26152,7 +27086,7 @@ function useDataDnd(args) {
26152
27086
  isRoot
26153
27087
  });
26154
27088
  }, [findZoneByItem, isRoot, zoneId]);
26155
- const handleDragOver = React88__default.useCallback((event) => {
27089
+ const handleDragOver = React89__default.useCallback((event) => {
26156
27090
  const { active, over } = event;
26157
27091
  const overData = over?.data?.current;
26158
27092
  const overGroup = overData?.dndGroup ?? null;
@@ -26222,7 +27156,7 @@ function useDataDnd(args) {
26222
27156
  return next;
26223
27157
  });
26224
27158
  }, []);
26225
- const handleDragCancel = React88__default.useCallback((event) => {
27159
+ const handleDragCancel = React89__default.useCallback((event) => {
26226
27160
  setActiveDrag(null);
26227
27161
  setOverZoneGroup(null);
26228
27162
  dndLog.warn("dragCancel", {
@@ -26230,12 +27164,12 @@ function useDataDnd(args) {
26230
27164
  reason: "dnd-kit cancelled the drag (escape key, pointer interrupted, or external)"
26231
27165
  });
26232
27166
  }, []);
26233
- const handleDragEndWithCleanup = React88__default.useCallback((event) => {
27167
+ const handleDragEndWithCleanup = React89__default.useCallback((event) => {
26234
27168
  handleDragEnd(event);
26235
27169
  setActiveDrag(null);
26236
27170
  setOverZoneGroup(null);
26237
27171
  }, [handleDragEnd]);
26238
- const wrapContainer = React88__default.useCallback(
27172
+ const wrapContainer = React89__default.useCallback(
26239
27173
  (children) => {
26240
27174
  if (!enabled) return children;
26241
27175
  const strategy = layout === "grid" ? rectSortingStrategy : verticalListSortingStrategy;
@@ -26289,7 +27223,7 @@ var init_useDataDnd = __esm({
26289
27223
  init_useAlmadarDndCollision();
26290
27224
  init_Box();
26291
27225
  dndLog = createLogger("almadar:ui:dnd");
26292
- RootCtx = React88__default.createContext(null);
27226
+ RootCtx = React89__default.createContext(null);
26293
27227
  }
26294
27228
  });
26295
27229
  function renderIconInput(icon, props) {
@@ -26804,7 +27738,7 @@ function DataList({
26804
27738
  }) {
26805
27739
  const eventBus = useEventBus();
26806
27740
  const { t } = useTranslate();
26807
- const [visibleCount, setVisibleCount] = React88__default.useState(pageSize || Infinity);
27741
+ const [visibleCount, setVisibleCount] = React89__default.useState(pageSize || Infinity);
26808
27742
  const fieldDefs = fields ?? columns ?? [];
26809
27743
  const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
26810
27744
  const dnd = useDataDnd({
@@ -26820,14 +27754,14 @@ function DataList({
26820
27754
  dndRoot
26821
27755
  });
26822
27756
  const orderedData = dnd.orderedItems;
26823
- const allData = React88__default.useMemo(
27757
+ const allData = React89__default.useMemo(
26824
27758
  () => sortRows(orderedData, sortBy, sortDirection),
26825
27759
  [orderedData, sortBy, sortDirection]
26826
27760
  );
26827
27761
  const data = pageSize > 0 ? allData.slice(0, visibleCount) : allData;
26828
27762
  const hasMoreLocal = pageSize > 0 && visibleCount < allData.length;
26829
27763
  const hasRenderProp = typeof children === "function";
26830
- React88__default.useEffect(() => {
27764
+ React89__default.useEffect(() => {
26831
27765
  const renderItemTypeOf = typeof schemaRenderItem;
26832
27766
  const childrenTypeOf = typeof children;
26833
27767
  if (data.length > 0 && !hasRenderProp) {
@@ -26947,7 +27881,7 @@ function DataList({
26947
27881
  return v === void 0 || v === null || v === "" ? raw : String(v);
26948
27882
  };
26949
27883
  return /* @__PURE__ */ jsxs(VStack, { gap: "sm", className: cn("py-2", className), children: [
26950
- groups2.map((group, gi) => /* @__PURE__ */ jsxs(React88__default.Fragment, { children: [
27884
+ groups2.map((group, gi) => /* @__PURE__ */ jsxs(React89__default.Fragment, { children: [
26951
27885
  group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: "my-2" }),
26952
27886
  group.items.map((itemData, index) => {
26953
27887
  const id = itemData.id || `${gi}-${index}`;
@@ -27163,7 +28097,7 @@ function DataList({
27163
28097
  className
27164
28098
  ),
27165
28099
  children: [
27166
- groups.map((group, gi) => /* @__PURE__ */ jsxs(React88__default.Fragment, { children: [
28100
+ groups.map((group, gi) => /* @__PURE__ */ jsxs(React89__default.Fragment, { children: [
27167
28101
  group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: gi > 0 ? "mt-4" : "mt-0" }),
27168
28102
  group.items.map(
27169
28103
  (itemData, index) => renderItem(itemData, index, gi === groups.length - 1 && index === group.items.length - 1)
@@ -27250,7 +28184,7 @@ var init_FormSection = __esm({
27250
28184
  columns = 1,
27251
28185
  className
27252
28186
  }) => {
27253
- const [collapsed, setCollapsed] = React88__default.useState(defaultCollapsed);
28187
+ const [collapsed, setCollapsed] = React89__default.useState(defaultCollapsed);
27254
28188
  const { t } = useTranslate();
27255
28189
  const eventBus = useEventBus();
27256
28190
  const gridClass = {
@@ -27258,7 +28192,7 @@ var init_FormSection = __esm({
27258
28192
  2: "grid-cols-1 md:grid-cols-2",
27259
28193
  3: "grid-cols-1 md:grid-cols-2 lg:grid-cols-3"
27260
28194
  }[columns];
27261
- React88__default.useCallback(() => {
28195
+ React89__default.useCallback(() => {
27262
28196
  if (collapsible) {
27263
28197
  setCollapsed((prev) => !prev);
27264
28198
  eventBus.emit("UI:TOGGLE_COLLAPSE", { collapsed: !collapsed });
@@ -27918,10 +28852,10 @@ var init_FileTree = __esm({
27918
28852
  indent = 16
27919
28853
  }) => {
27920
28854
  const [overrides, setOverrides] = useState(() => /* @__PURE__ */ new Map());
27921
- const byId = React88__default.useMemo(() => new Map(items.map((node) => [node.id, node])), [items]);
27922
- const selectedAncestors = React88__default.useMemo(() => ancestorsOf(selectedId, byId), [selectedId, byId]);
27923
- const lastSelectedRef = React88__default.useRef(selectedId);
27924
- React88__default.useEffect(() => {
28855
+ const byId = React89__default.useMemo(() => new Map(items.map((node) => [node.id, node])), [items]);
28856
+ const selectedAncestors = React89__default.useMemo(() => ancestorsOf(selectedId, byId), [selectedId, byId]);
28857
+ const lastSelectedRef = React89__default.useRef(selectedId);
28858
+ React89__default.useEffect(() => {
27925
28859
  if (selectedId === lastSelectedRef.current) return;
27926
28860
  lastSelectedRef.current = selectedId;
27927
28861
  setOverrides((prev) => {
@@ -28755,7 +29689,7 @@ var init_Flex = __esm({
28755
29689
  flexStyle.flexBasis = typeof basis === "number" ? `${basis}px` : basis;
28756
29690
  }
28757
29691
  }
28758
- return React88__default.createElement(Component, {
29692
+ return React89__default.createElement(Component, {
28759
29693
  className: cn(
28760
29694
  inline ? "inline-flex" : "flex",
28761
29695
  directionStyles[direction],
@@ -28874,7 +29808,7 @@ var init_Grid = __esm({
28874
29808
  as: Component = "div"
28875
29809
  }) => {
28876
29810
  const mergedStyle = rows ? { gridTemplateRows: `repeat(${rows}, minmax(0, 1fr))`, ...style } : style;
28877
- return React88__default.createElement(
29811
+ return React89__default.createElement(
28878
29812
  Component,
28879
29813
  {
28880
29814
  className: cn(
@@ -29296,9 +30230,9 @@ var init_Popover = __esm({
29296
30230
  onMouseLeave: handleClose,
29297
30231
  onPointerDown: tapTriggerProps.onPointerDown
29298
30232
  };
29299
- const childElement = React88__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
30233
+ const childElement = React89__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
29300
30234
  const childPointerDown = childElement.props.onPointerDown;
29301
- const triggerElement = React88__default.cloneElement(
30235
+ const triggerElement = React89__default.cloneElement(
29302
30236
  childElement,
29303
30237
  {
29304
30238
  ref: triggerRef,
@@ -29362,9 +30296,9 @@ function debug(...args) {
29362
30296
  const [first, ...rest] = args;
29363
30297
  const message = typeof first === "string" ? first : "<debug>";
29364
30298
  if (rest.length === 0 && typeof first === "string") {
29365
- log9.debug(message);
30299
+ log10.debug(message);
29366
30300
  } else {
29367
- log9.debug(message, { args: rest.length > 0 ? formatArgs(rest) : formatArgs([first]) });
30301
+ log10.debug(message, { args: rest.length > 0 ? formatArgs(rest) : formatArgs([first]) });
29368
30302
  }
29369
30303
  }
29370
30304
  function debugGroup(label) {
@@ -29392,11 +30326,11 @@ function toLogMetaValue(v) {
29392
30326
  }
29393
30327
  return String(v);
29394
30328
  }
29395
- var NAMESPACE, log9;
30329
+ var NAMESPACE, log10;
29396
30330
  var init_debug = __esm({
29397
30331
  "lib/debug.ts"() {
29398
30332
  NAMESPACE = "almadar:ui:debug";
29399
- log9 = createLogger(NAMESPACE);
30333
+ log10 = createLogger(NAMESPACE);
29400
30334
  createLogger("almadar:ui:debug:input");
29401
30335
  createLogger("almadar:ui:debug:collision");
29402
30336
  createLogger("almadar:ui:debug:physics");
@@ -29912,9 +30846,9 @@ var init_Tooltip = __esm({
29912
30846
  if (hideTimeoutRef.current) clearTimeout(hideTimeoutRef.current);
29913
30847
  };
29914
30848
  }, []);
29915
- const triggerElement = React88__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
30849
+ const triggerElement = React89__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
29916
30850
  const childPointerDown = triggerElement.props.onPointerDown;
29917
- const trigger = React88__default.cloneElement(triggerElement, {
30851
+ const trigger = React89__default.cloneElement(triggerElement, {
29918
30852
  ref: triggerRef,
29919
30853
  onMouseEnter: handleMouseEnter,
29920
30854
  onMouseLeave: handleMouseLeave,
@@ -30004,7 +30938,7 @@ var init_WizardProgress = __esm({
30004
30938
  children: /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", children: normalizedSteps.map((step, index) => {
30005
30939
  const isActive = index === currentStep;
30006
30940
  const isCompleted = index < currentStep;
30007
- return /* @__PURE__ */ jsxs(React88__default.Fragment, { children: [
30941
+ return /* @__PURE__ */ jsxs(React89__default.Fragment, { children: [
30008
30942
  /* @__PURE__ */ jsx(
30009
30943
  "button",
30010
30944
  {
@@ -31049,6 +31983,7 @@ var init_MathCanvas = __esm({
31049
31983
  init_perf();
31050
31984
  init_atoms();
31051
31985
  init_Stack();
31986
+ init_gameFonts();
31052
31987
  init_LearningCanvas();
31053
31988
  MathCanvas = ({
31054
31989
  className,
@@ -31068,6 +32003,7 @@ var init_MathCanvas = __esm({
31068
32003
  showTickLabels = false,
31069
32004
  tickLabelFontSize = 10,
31070
32005
  labelFontSize = 12,
32006
+ fontFamily: fontFamilyProp,
31071
32007
  showCurveLabels = false,
31072
32008
  curves = [],
31073
32009
  points = [],
@@ -31090,6 +32026,7 @@ var init_MathCanvas = __esm({
31090
32026
  error
31091
32027
  }) => {
31092
32028
  const eventBus = useEventBus();
32029
+ const fontFamily = resolveGameFontFamily(fontFamilyProp);
31093
32030
  const keyMapKey = keyMap ? JSON.stringify(keyMap) : null;
31094
32031
  const keyUpMapKey = keyUpMap ? JSON.stringify(keyUpMap) : null;
31095
32032
  const stableKeyMap = useMemo(() => keyMap, [keyMapKey]);
@@ -31139,18 +32076,18 @@ var init_MathCanvas = __esm({
31139
32076
  let kx = 0;
31140
32077
  for (let x = Math.ceil(xMin / gridStep) * gridStep; x <= xMax; x += gridStep, kx++) {
31141
32078
  if (kx % labelEveryX === 0 && x !== 0) {
31142
- out.push({ type: "text", x: mapX(x), y: xAxisY + 12, text: formatTick(x), color: "#6b7280", fontSize: tickLabelFontSize, align: "center" });
32079
+ out.push({ type: "text", fontFamily, x: mapX(x), y: xAxisY + 12, text: formatTick(x), color: "#6b7280", fontSize: tickLabelFontSize, align: "center" });
31143
32080
  }
31144
32081
  }
31145
32082
  const labelEveryY = Math.max(1, Math.ceil((yMax - yMin) / gridStep / Math.floor(plotH / 28)));
31146
32083
  let ky = 0;
31147
32084
  for (let y = Math.ceil(yMin / gridStep) * gridStep; y <= yMax; y += gridStep, ky++) {
31148
32085
  if (ky % labelEveryY === 0 && y !== 0) {
31149
- out.push({ type: "text", x: yAxisX - 6, y: mapY(y), text: formatTick(y), color: "#6b7280", fontSize: tickLabelFontSize, align: "right" });
32086
+ out.push({ type: "text", fontFamily, x: yAxisX - 6, y: mapY(y), text: formatTick(y), color: "#6b7280", fontSize: tickLabelFontSize, align: "right" });
31150
32087
  }
31151
32088
  }
31152
32089
  if (xMin <= 0 && xMax >= 0 && yMin <= 0 && yMax >= 0) {
31153
- out.push({ type: "text", x: yAxisX - 6, y: xAxisY + 12, text: "0", color: "#6b7280", fontSize: tickLabelFontSize, align: "right" });
32090
+ out.push({ type: "text", fontFamily, x: yAxisX - 6, y: xAxisY + 12, text: "0", color: "#6b7280", fontSize: tickLabelFontSize, align: "right" });
31154
32091
  }
31155
32092
  }
31156
32093
  for (const region of regions) {
@@ -31177,6 +32114,7 @@ var init_MathCanvas = __esm({
31177
32114
  const mid = Math.floor(region.samples.length / 2);
31178
32115
  out.push({
31179
32116
  type: "text",
32117
+ fontFamily,
31180
32118
  x: mapX((first.x + last.x) / 2),
31181
32119
  y: (mapY(region.samples[mid].y) + mapY(baseline)) / 2,
31182
32120
  text: region.label,
@@ -31213,14 +32151,14 @@ var init_MathCanvas = __esm({
31213
32151
  const px = mapX(guide.at);
31214
32152
  out.push({ type: "line", x1: px, y1: margin, x2: px, y2: height - margin, color, dash });
31215
32153
  if (guide.label) {
31216
- out.push({ type: "text", x: px + 4, y: margin + 10, text: guide.label, color, fontSize: 11 });
32154
+ out.push({ type: "text", fontFamily, x: px + 4, y: margin + 10, text: guide.label, color, fontSize: 11 });
31217
32155
  }
31218
32156
  } else {
31219
32157
  if (guide.at < yMin || guide.at > yMax) continue;
31220
32158
  const py = mapY(guide.at);
31221
32159
  out.push({ type: "line", x1: margin, y1: py, x2: width - margin, y2: py, color, dash });
31222
32160
  if (guide.label) {
31223
- out.push({ type: "text", x: width - margin - 4, y: py - 8, text: guide.label, color, fontSize: labelFontSize, align: "right" });
32161
+ out.push({ type: "text", fontFamily, x: width - margin - 4, y: py - 8, text: guide.label, color, fontSize: labelFontSize, align: "right" });
31224
32162
  }
31225
32163
  }
31226
32164
  }
@@ -31259,6 +32197,7 @@ var init_MathCanvas = __esm({
31259
32197
  if (showCurveLabels && curve.label && lastInRange) {
31260
32198
  out.push({
31261
32199
  type: "text",
32200
+ fontFamily,
31262
32201
  x: mapX(lastInRange.x) + 6,
31263
32202
  y: mapY(lastInRange.y) - 6,
31264
32203
  text: curve.label,
@@ -31296,6 +32235,7 @@ var init_MathCanvas = __esm({
31296
32235
  if (hop.label) {
31297
32236
  out.push({
31298
32237
  type: "text",
32238
+ fontFamily,
31299
32239
  x: (x1 + x2) / 2,
31300
32240
  y: xAxisY - peak - 8,
31301
32241
  text: hop.label,
@@ -31323,6 +32263,7 @@ var init_MathCanvas = __esm({
31323
32263
  const rad = mid * Math.PI / 180;
31324
32264
  out.push({
31325
32265
  type: "text",
32266
+ fontFamily,
31326
32267
  x: mapX(angle.x + 1.35 * radius * Math.cos(rad)),
31327
32268
  y: mapY(angle.y + 1.35 * radius * Math.sin(rad)),
31328
32269
  text: angle.label,
@@ -31344,7 +32285,7 @@ var init_MathCanvas = __esm({
31344
32285
  fill: isOpen ? "#ffffff" : p.color ?? "#dc2626"
31345
32286
  });
31346
32287
  if (p.label) {
31347
- out.push({ type: "text", x: mapX(p.x) + 8, y: mapY(p.y) - 8, text: p.label, color: p.color ?? "#111827", fontSize: labelFontSize });
32288
+ out.push({ type: "text", fontFamily, x: mapX(p.x) + 8, y: mapY(p.y) - 8, text: p.label, color: p.color ?? "#111827", fontSize: labelFontSize });
31348
32289
  }
31349
32290
  }
31350
32291
  for (const v of vectors) {
@@ -31355,7 +32296,7 @@ var init_MathCanvas = __esm({
31355
32296
  const y2 = mapY(v.y + v.vy);
31356
32297
  out.push({ type: "arrow", x1, y1, x2, y2, color: v.color ?? "#7c3aed", lineWidth: 2 });
31357
32298
  if (v.label) {
31358
- out.push({ type: "text", x: x2 + 6, y: y2 - 6, text: v.label, color: v.color ?? "#7c3aed", fontSize: labelFontSize });
32299
+ out.push({ type: "text", fontFamily, x: x2 + 6, y: y2 - 6, text: v.label, color: v.color ?? "#7c3aed", fontSize: labelFontSize });
31359
32300
  }
31360
32301
  }
31361
32302
  out.push(...shapes);
@@ -31376,6 +32317,7 @@ var init_MathCanvas = __esm({
31376
32317
  showTickLabels,
31377
32318
  tickLabelFontSize,
31378
32319
  labelFontSize,
32320
+ fontFamily,
31379
32321
  showCurveLabels,
31380
32322
  curves,
31381
32323
  points,
@@ -31431,6 +32373,7 @@ var init_MathCanvas = __esm({
31431
32373
  width,
31432
32374
  height,
31433
32375
  backgroundColor,
32376
+ fontFamily,
31434
32377
  shapes: derivedShapes,
31435
32378
  drawables,
31436
32379
  projector,
@@ -32663,13 +33606,13 @@ var init_MapView = __esm({
32663
33606
  shadowSize: [41, 41]
32664
33607
  });
32665
33608
  L.Marker.prototype.options.icon = defaultIcon;
32666
- const { useEffect: useEffect68, useRef: useRef67, useCallback: useCallback99, useState: useState101 } = React88__default;
33609
+ const { useEffect: useEffect69, useRef: useRef69, useCallback: useCallback100, useState: useState103 } = React89__default;
32667
33610
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
32668
33611
  const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
32669
33612
  function MapUpdater({ centerLat, centerLng, zoom }) {
32670
33613
  const map = useMap();
32671
- const prevRef = useRef67({ centerLat, centerLng, zoom });
32672
- useEffect68(() => {
33614
+ const prevRef = useRef69({ centerLat, centerLng, zoom });
33615
+ useEffect69(() => {
32673
33616
  const prev = prevRef.current;
32674
33617
  if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
32675
33618
  map.setView([centerLat, centerLng], zoom);
@@ -32680,7 +33623,7 @@ var init_MapView = __esm({
32680
33623
  }
32681
33624
  function MapClickHandler({ onMapClick }) {
32682
33625
  const map = useMap();
32683
- useEffect68(() => {
33626
+ useEffect69(() => {
32684
33627
  if (!onMapClick) return;
32685
33628
  const handler = (e) => {
32686
33629
  onMapClick(e.latlng.lat, e.latlng.lng);
@@ -32708,8 +33651,8 @@ var init_MapView = __esm({
32708
33651
  showAttribution = true
32709
33652
  }) {
32710
33653
  const eventBus = useEventBus2();
32711
- const [clickedPosition, setClickedPosition] = useState101(null);
32712
- const handleMapClick = useCallback99((lat, lng) => {
33654
+ const [clickedPosition, setClickedPosition] = useState103(null);
33655
+ const handleMapClick = useCallback100((lat, lng) => {
32713
33656
  if (showClickedPin) {
32714
33657
  setClickedPosition({ lat, lng });
32715
33658
  }
@@ -32718,7 +33661,7 @@ var init_MapView = __esm({
32718
33661
  eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
32719
33662
  }
32720
33663
  }, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
32721
- const handleMarkerClick = useCallback99((marker) => {
33664
+ const handleMarkerClick = useCallback100((marker) => {
32722
33665
  onMarkerClick?.(marker);
32723
33666
  if (markerClickEvent) {
32724
33667
  eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
@@ -33608,8 +34551,8 @@ function TableView({
33608
34551
  }) {
33609
34552
  const eventBus = useEventBus();
33610
34553
  const { t } = useTranslate();
33611
- const [visibleCount, setVisibleCount] = React88__default.useState(pageSize > 0 ? pageSize : Infinity);
33612
- const [localSelected, setLocalSelected] = React88__default.useState(/* @__PURE__ */ new Set());
34554
+ const [visibleCount, setVisibleCount] = React89__default.useState(pageSize > 0 ? pageSize : Infinity);
34555
+ const [localSelected, setLocalSelected] = React89__default.useState(/* @__PURE__ */ new Set());
33613
34556
  const colDefs = (Array.isArray(columns) ? columns : void 0) ?? (Array.isArray(fields) ? fields : void 0) ?? [];
33614
34557
  const actionDefs = Array.isArray(itemActions) ? itemActions : [];
33615
34558
  const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
@@ -33630,7 +34573,7 @@ function TableView({
33630
34573
  const hasMore = pageSize > 0 && visibleCount < ordered2.length;
33631
34574
  const hasRenderProp = typeof children === "function";
33632
34575
  const idField = dndItemIdField ?? "id";
33633
- React88__default.useEffect(() => {
34576
+ React89__default.useEffect(() => {
33634
34577
  tableViewLog.debug("render", {
33635
34578
  rowCount: data.length,
33636
34579
  colCount: colDefs.length,
@@ -33680,7 +34623,7 @@ function TableView({
33680
34623
  };
33681
34624
  eventBus.emit(`UI:${rowClickEvent}`, payload);
33682
34625
  };
33683
- const colFloors = React88__default.useMemo(
34626
+ const colFloors = React89__default.useMemo(
33684
34627
  () => colDefs.map((col) => {
33685
34628
  const longest = data.reduce((widest, row) => {
33686
34629
  const cell = formatCell(asFieldValue(getNestedValue(row, col.field ?? col.key)), col.format);
@@ -33823,12 +34766,12 @@ function TableView({
33823
34766
  ]
33824
34767
  }
33825
34768
  );
33826
- return dnd.isZone ? /* @__PURE__ */ jsx(dnd.SortableItem, { id: row[idField] ?? id, children: rowInner }, id) : /* @__PURE__ */ jsx(React88__default.Fragment, { children: rowInner }, id);
34769
+ return dnd.isZone ? /* @__PURE__ */ jsx(dnd.SortableItem, { id: row[idField] ?? id, children: rowInner }, id) : /* @__PURE__ */ jsx(React89__default.Fragment, { children: rowInner }, id);
33827
34770
  };
33828
34771
  const items = Array.from(data);
33829
34772
  const groups = groupBy ? groupData2(items, groupBy) : [{ label: "", items }];
33830
34773
  let runningIndex = 0;
33831
- const body = /* @__PURE__ */ jsx(Box, { role: "rowgroup", children: groups.map((group, gi) => /* @__PURE__ */ jsxs(React88__default.Fragment, { children: [
34774
+ const body = /* @__PURE__ */ jsx(Box, { role: "rowgroup", children: groups.map((group, gi) => /* @__PURE__ */ jsxs(React89__default.Fragment, { children: [
33832
34775
  group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: gi > 0 ? "mt-3" : "mt-0" }),
33833
34776
  group.items.map((row) => renderRow(row, runningIndex++))
33834
34777
  ] }, gi)) });
@@ -35197,7 +36140,7 @@ var init_StepFlow = __esm({
35197
36140
  className
35198
36141
  }) => {
35199
36142
  if (orientation === "vertical") {
35200
- return /* @__PURE__ */ jsx(VStack, { gap: "none", className: cn("w-full", className), children: steps.map((step, index) => /* @__PURE__ */ jsx(React88__default.Fragment, { children: /* @__PURE__ */ jsxs(HStack, { gap: "md", align: "start", className: "w-full", children: [
36143
+ return /* @__PURE__ */ jsx(VStack, { gap: "none", className: cn("w-full", className), children: steps.map((step, index) => /* @__PURE__ */ jsx(React89__default.Fragment, { children: /* @__PURE__ */ jsxs(HStack, { gap: "md", align: "start", className: "w-full", children: [
35201
36144
  /* @__PURE__ */ jsxs(VStack, { gap: "none", align: "center", children: [
35202
36145
  /* @__PURE__ */ jsx(StepCircle, { step, index }),
35203
36146
  showConnectors && index < steps.length - 1 && /* @__PURE__ */ jsx(Box, { className: "w-px h-8 bg-border" })
@@ -35208,7 +36151,7 @@ var init_StepFlow = __esm({
35208
36151
  ] })
35209
36152
  ] }) }, index)) });
35210
36153
  }
35211
- 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(React88__default.Fragment, { children: [
36154
+ 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(React89__default.Fragment, { children: [
35212
36155
  /* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", className: "flex-1 w-full md:w-auto", children: [
35213
36156
  /* @__PURE__ */ jsx(StepCircle, { step, index }),
35214
36157
  /* @__PURE__ */ jsx(Typography, { variant: "h4", className: "text-center", children: step.title }),
@@ -36198,7 +37141,7 @@ var init_LikertScale = __esm({
36198
37141
  md: "text-base",
36199
37142
  lg: "text-lg"
36200
37143
  };
36201
- LikertScale = React88__default.forwardRef(
37144
+ LikertScale = React89__default.forwardRef(
36202
37145
  ({
36203
37146
  question,
36204
37147
  options = DEFAULT_LIKERT_OPTIONS,
@@ -36210,7 +37153,7 @@ var init_LikertScale = __esm({
36210
37153
  variant = "radios",
36211
37154
  className
36212
37155
  }, ref) => {
36213
- const groupId = React88__default.useId();
37156
+ const groupId = React89__default.useId();
36214
37157
  const eventBus = useEventBus();
36215
37158
  const handleSelect = useCallback(
36216
37159
  (next) => {
@@ -38633,7 +39576,7 @@ var init_DocBreadcrumb = __esm({
38633
39576
  "aria-label": t("aria.breadcrumb"),
38634
39577
  children: /* @__PURE__ */ jsx(HStack, { gap: "xs", align: "center", wrap: true, children: items.map((item, idx) => {
38635
39578
  const isLast = idx === items.length - 1;
38636
- return /* @__PURE__ */ jsxs(React88__default.Fragment, { children: [
39579
+ return /* @__PURE__ */ jsxs(React89__default.Fragment, { children: [
38637
39580
  idx > 0 && /* @__PURE__ */ jsx(
38638
39581
  Icon,
38639
39582
  {
@@ -39502,7 +40445,7 @@ var init_MiniStateMachine = __esm({
39502
40445
  const x = 2 + i * (NODE_W + GAP + ARROW_W + GAP);
39503
40446
  const tc = transitionCounts[s.name] ?? 0;
39504
40447
  const role = getStateRole(s.name, s.isInitial ?? void 0, s.isTerminal ?? void 0, tc, maxTC);
39505
- return /* @__PURE__ */ jsxs(React88__default.Fragment, { children: [
40448
+ return /* @__PURE__ */ jsxs(React89__default.Fragment, { children: [
39506
40449
  /* @__PURE__ */ jsx(
39507
40450
  AvlState,
39508
40451
  {
@@ -39707,7 +40650,7 @@ var init_PageHeader = __esm({
39707
40650
  info: "bg-info/10 text-info"
39708
40651
  };
39709
40652
  return /* @__PURE__ */ jsxs(Box, { className: cn("mb-6", className), children: [
39710
- 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(React88__default.Fragment, { children: [
40653
+ 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(React89__default.Fragment, { children: [
39711
40654
  idx > 0 && /* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", children: "/" }),
39712
40655
  crumb.href ? /* @__PURE__ */ jsx(
39713
40656
  "a",
@@ -40065,7 +41008,7 @@ var init_Section = __esm({
40065
41008
  as: Component = "section"
40066
41009
  }) => {
40067
41010
  const hasHeader = title || description || action;
40068
- return React88__default.createElement(
41011
+ return React89__default.createElement(
40069
41012
  Component,
40070
41013
  {
40071
41014
  className: cn(
@@ -40439,7 +41382,7 @@ var init_WizardContainer = __esm({
40439
41382
  const isCompleted = index < currentStep;
40440
41383
  const stepKey = step.id ?? step.tabId ?? `step-${index}`;
40441
41384
  const stepTitle = step.title ?? step.name ?? `Step ${index + 1}`;
40442
- return /* @__PURE__ */ jsxs(React88__default.Fragment, { children: [
41385
+ return /* @__PURE__ */ jsxs(React89__default.Fragment, { children: [
40443
41386
  /* @__PURE__ */ jsx(
40444
41387
  Button,
40445
41388
  {
@@ -42226,7 +43169,7 @@ var init_ImportPreviewTree = __esm({
42226
43169
  const renderUnit = (unit, childrenByParent, depth) => {
42227
43170
  const summary = fieldSummary(unit);
42228
43171
  const children = childrenByParent.get(unit.ref) ?? [];
42229
- return /* @__PURE__ */ jsxs(React88__default.Fragment, { children: [
43172
+ return /* @__PURE__ */ jsxs(React89__default.Fragment, { children: [
42230
43173
  /* @__PURE__ */ jsxs(
42231
43174
  Box,
42232
43175
  {
@@ -42323,7 +43266,7 @@ var init_ImportProgress = __esm({
42323
43266
  PIPELINE.map((key, index) => {
42324
43267
  const isComplete = index < currentIndex;
42325
43268
  const isActive = index === currentIndex;
42326
- return /* @__PURE__ */ jsxs(React88__default.Fragment, { children: [
43269
+ return /* @__PURE__ */ jsxs(React89__default.Fragment, { children: [
42327
43270
  index > 0 ? /* @__PURE__ */ jsx(Box, { className: "h-px w-4 bg-border" }) : null,
42328
43271
  /* @__PURE__ */ jsxs(Box, { className: "flex items-center gap-1", "data-testid": `import-progress-step-${key}`, children: [
42329
43272
  /* @__PURE__ */ jsx(
@@ -43264,7 +44207,7 @@ var init_DetailPanel = __esm({
43264
44207
  }) => {
43265
44208
  const eventBus = useEventBus();
43266
44209
  const { t } = useTranslate();
43267
- const [titleDraft, setTitleDraft] = React88__default.useState(null);
44210
+ const [titleDraft, setTitleDraft] = React89__default.useState(null);
43268
44211
  const isFieldDefArray = (arr) => {
43269
44212
  if (!arr || arr.length === 0) return false;
43270
44213
  const first = arr[0];
@@ -43730,7 +44673,7 @@ var init_SplitPane = __esm({
43730
44673
  /* @__PURE__ */ jsx(
43731
44674
  "div",
43732
44675
  {
43733
- className: cn("overflow-auto", leftClassName),
44676
+ className: cn("flex flex-col overflow-auto", leftClassName),
43734
44677
  style: {
43735
44678
  [isHorizontal ? "width" : "height"]: `${ratio}%`,
43736
44679
  flexShrink: 0
@@ -43748,7 +44691,7 @@ var init_SplitPane = __esm({
43748
44691
  )
43749
44692
  }
43750
44693
  ),
43751
- /* @__PURE__ */ jsx("div", { className: cn("flex-1 overflow-auto", rightClassName), children: right })
44694
+ /* @__PURE__ */ jsx("div", { className: cn("flex flex-col flex-1 min-h-0 min-w-0 overflow-auto", rightClassName), children: right })
43752
44695
  ]
43753
44696
  }
43754
44697
  );
@@ -43794,7 +44737,7 @@ var init_DockLayout = __esm({
43794
44737
  const showBottomPanel = Boolean(bottomPanel) && !bottomPanelCollapsed;
43795
44738
  const showSecondarySidebar = Boolean(secondarySidebar) && !secondarySidebarCollapsed;
43796
44739
  const centerRow = /* @__PURE__ */ jsxs(HStack, { gap: "none", className: "flex-1 min-h-0 min-w-0", children: [
43797
- /* @__PURE__ */ jsx(Box, { className: cn("flex-1 min-w-0 h-full overflow-auto", mainClassName), children: main }),
44740
+ /* @__PURE__ */ jsx(Box, { className: cn("flex-1 min-w-0 min-h-0 overflow-auto", mainClassName), children: main }),
43798
44741
  showSecondarySidebar && /* @__PURE__ */ jsx(
43799
44742
  Box,
43800
44743
  {
@@ -43825,7 +44768,7 @@ var init_DockLayout = __esm({
43825
44768
  Box,
43826
44769
  {
43827
44770
  className: cn(
43828
- "flex-shrink-0 h-full overflow-auto border-r border-border",
44771
+ "flex-shrink-0 min-h-0 overflow-auto border-r border-border",
43829
44772
  railClassName
43830
44773
  ),
43831
44774
  style: { width: railWidth },
@@ -43874,7 +44817,7 @@ var init_DockLayout = __esm({
43874
44817
  }
43875
44818
  });
43876
44819
  function extractTitle(children) {
43877
- if (!React88__default.isValidElement(children)) return void 0;
44820
+ if (!React89__default.isValidElement(children)) return void 0;
43878
44821
  const props = children.props;
43879
44822
  if (typeof props.title === "string") {
43880
44823
  return props.title;
@@ -44236,7 +45179,7 @@ var init_Form = __esm({
44236
45179
  const isSchemaEntity = isOrbitalEntitySchema(entity);
44237
45180
  const resolvedEntity = isSchemaEntity ? entity : void 0;
44238
45181
  const entityName = typeof entity === "string" ? entity : resolvedEntity?.name;
44239
- const normalizedInitialData = React88__default.useMemo(() => {
45182
+ const normalizedInitialData = React89__default.useMemo(() => {
44240
45183
  const entityRowAsInitial = isPlainEntityRow(entity) ? entity : void 0;
44241
45184
  const callerInitial = initialData !== null && typeof initialData === "object" && !Array.isArray(initialData) ? initialData : {};
44242
45185
  const merged = entityRowAsInitial !== void 0 ? { ...entityRowAsInitial, ...callerInitial } : callerInitial;
@@ -44255,7 +45198,7 @@ var init_Form = __esm({
44255
45198
  }
44256
45199
  return normalized;
44257
45200
  }, [entity, initialData]);
44258
- const entityDerivedFields = React88__default.useMemo(() => {
45201
+ const entityDerivedFields = React89__default.useMemo(() => {
44259
45202
  if (fields && fields.length > 0) return void 0;
44260
45203
  if (!resolvedEntity) return void 0;
44261
45204
  return resolvedEntity.fields.map(
@@ -44276,16 +45219,16 @@ var init_Form = __esm({
44276
45219
  const conditionalFields = typeof conditionalFieldsRaw === "boolean" ? {} : conditionalFieldsRaw;
44277
45220
  const hiddenCalculations = typeof hiddenCalculationsRaw === "boolean" ? [] : hiddenCalculationsRaw;
44278
45221
  const violationTriggers = typeof violationTriggersRaw === "boolean" ? [] : violationTriggersRaw;
44279
- const [formData, setFormData] = React88__default.useState(
45222
+ const [formData, setFormData] = React89__default.useState(
44280
45223
  normalizedInitialData
44281
45224
  );
44282
- const [collapsedSections, setCollapsedSections] = React88__default.useState(
45225
+ const [collapsedSections, setCollapsedSections] = React89__default.useState(
44283
45226
  /* @__PURE__ */ new Set()
44284
45227
  );
44285
- const [submitError, setSubmitError] = React88__default.useState(null);
44286
- const formRef = React88__default.useRef(null);
45228
+ const [submitError, setSubmitError] = React89__default.useState(null);
45229
+ const formRef = React89__default.useRef(null);
44287
45230
  const formMode = props.mode;
44288
- const mountedRef = React88__default.useRef(false);
45231
+ const mountedRef = React89__default.useRef(false);
44289
45232
  if (!mountedRef.current) {
44290
45233
  mountedRef.current = true;
44291
45234
  debug("forms", "mount", {
@@ -44298,7 +45241,7 @@ var init_Form = __esm({
44298
45241
  });
44299
45242
  }
44300
45243
  const shouldShowCancel = showCancel ?? (fields && fields.length > 0);
44301
- const evalContext = React88__default.useMemo(
45244
+ const evalContext = React89__default.useMemo(
44302
45245
  () => ({
44303
45246
  formValues: formData,
44304
45247
  globalVariables: externalContext?.globalVariables ?? {},
@@ -44307,7 +45250,7 @@ var init_Form = __esm({
44307
45250
  }),
44308
45251
  [formData, externalContext]
44309
45252
  );
44310
- React88__default.useEffect(() => {
45253
+ React89__default.useEffect(() => {
44311
45254
  debug("forms", "initialData-sync", {
44312
45255
  mode: formMode,
44313
45256
  normalizedInitialData,
@@ -44318,7 +45261,7 @@ var init_Form = __esm({
44318
45261
  setFormData(normalizedInitialData);
44319
45262
  }
44320
45263
  }, [normalizedInitialData]);
44321
- const processCalculations = React88__default.useCallback(
45264
+ const processCalculations = React89__default.useCallback(
44322
45265
  (changedFieldId, newFormData) => {
44323
45266
  if (!hiddenCalculations.length) return;
44324
45267
  const context = {
@@ -44343,7 +45286,7 @@ var init_Form = __esm({
44343
45286
  },
44344
45287
  [hiddenCalculations, externalContext, eventBus]
44345
45288
  );
44346
- const checkViolations = React88__default.useCallback(
45289
+ const checkViolations = React89__default.useCallback(
44347
45290
  (changedFieldId, newFormData) => {
44348
45291
  if (!violationTriggers.length) return;
44349
45292
  const context = {
@@ -44381,7 +45324,7 @@ var init_Form = __esm({
44381
45324
  processCalculations(name, newFormData);
44382
45325
  checkViolations(name, newFormData);
44383
45326
  };
44384
- const isFieldVisible = React88__default.useCallback(
45327
+ const isFieldVisible = React89__default.useCallback(
44385
45328
  (fieldName2) => {
44386
45329
  const condition = conditionalFields[fieldName2];
44387
45330
  if (!condition) return true;
@@ -44389,7 +45332,7 @@ var init_Form = __esm({
44389
45332
  },
44390
45333
  [conditionalFields, evalContext]
44391
45334
  );
44392
- const isSectionVisible = React88__default.useCallback(
45335
+ const isSectionVisible = React89__default.useCallback(
44393
45336
  (section) => {
44394
45337
  if (!section.condition) return true;
44395
45338
  return Boolean(evaluateFormExpression(section.condition, evalContext));
@@ -44465,7 +45408,7 @@ var init_Form = __esm({
44465
45408
  eventBus.emit(`UI:${onCancel}`);
44466
45409
  }
44467
45410
  };
44468
- const renderField = React88__default.useCallback(
45411
+ const renderField = React89__default.useCallback(
44469
45412
  (field) => {
44470
45413
  const fieldName2 = field.name || field.field;
44471
45414
  if (!fieldName2) return null;
@@ -44487,7 +45430,7 @@ var init_Form = __esm({
44487
45430
  [formData, isFieldVisible, relationsData, relationsLoading, isLoading]
44488
45431
  );
44489
45432
  const effectiveFields = entityDerivedFields ?? fields;
44490
- const normalizedFields = React88__default.useMemo(() => {
45433
+ const normalizedFields = React89__default.useMemo(() => {
44491
45434
  if (!effectiveFields || effectiveFields.length === 0) return [];
44492
45435
  return effectiveFields.map((field) => {
44493
45436
  if (typeof field === "string") {
@@ -44522,7 +45465,7 @@ var init_Form = __esm({
44522
45465
  };
44523
45466
  });
44524
45467
  }, [effectiveFields, resolvedEntity, fieldOverrides]);
44525
- const schemaFields = React88__default.useMemo(() => {
45468
+ const schemaFields = React89__default.useMemo(() => {
44526
45469
  if (normalizedFields.length === 0) return null;
44527
45470
  if (isDebugEnabled()) {
44528
45471
  debugGroup(`Form: ${entityName || "unknown"}`);
@@ -44532,7 +45475,7 @@ var init_Form = __esm({
44532
45475
  }
44533
45476
  return normalizedFields.map(renderField).filter(Boolean);
44534
45477
  }, [normalizedFields, renderField, entityName, conditionalFields]);
44535
- const sectionElements = React88__default.useMemo(() => {
45478
+ const sectionElements = React89__default.useMemo(() => {
44536
45479
  if (!sections || sections.length === 0) return null;
44537
45480
  return sections.map((section) => {
44538
45481
  if (!isSectionVisible(section)) {
@@ -45368,7 +46311,7 @@ var init_List = __esm({
45368
46311
  if (entity && typeof entity === "object" && "id" in entity) return [entity];
45369
46312
  return [];
45370
46313
  }, [entity]);
45371
- const getItemActions = React88__default.useCallback(
46314
+ const getItemActions = React89__default.useCallback(
45372
46315
  (item) => {
45373
46316
  if (!itemActions) return [];
45374
46317
  if (typeof itemActions === "function") {
@@ -45850,7 +46793,7 @@ var init_MediaGallery = __esm({
45850
46793
  [selectable, selectedItems, selectionEvent, eventBus]
45851
46794
  );
45852
46795
  const entityData = Array.isArray(entity) ? entity : [];
45853
- const items = React88__default.useMemo(() => {
46796
+ const items = React89__default.useMemo(() => {
45854
46797
  if (propItems && propItems.length > 0) return propItems;
45855
46798
  if (entityData.length === 0) return [];
45856
46799
  return entityData.map((record, idx) => {
@@ -46015,7 +46958,7 @@ var init_MediaGallery = __esm({
46015
46958
  }
46016
46959
  });
46017
46960
  function extractTitle2(children) {
46018
- if (!React88__default.isValidElement(children)) return void 0;
46961
+ if (!React89__default.isValidElement(children)) return void 0;
46019
46962
  const props = children.props;
46020
46963
  if (typeof props.title === "string") {
46021
46964
  return props.title;
@@ -46270,7 +47213,7 @@ var init_debugRegistry = __esm({
46270
47213
  }
46271
47214
  });
46272
47215
  function useDebugData() {
46273
- const [data, setData] = React88.useState(() => ({
47216
+ const [data, setData] = React89.useState(() => ({
46274
47217
  traits: [],
46275
47218
  ticks: [],
46276
47219
  guards: [],
@@ -46284,7 +47227,7 @@ function useDebugData() {
46284
47227
  },
46285
47228
  lastUpdate: Date.now()
46286
47229
  }));
46287
- React88.useEffect(() => {
47230
+ React89.useEffect(() => {
46288
47231
  const updateData = () => {
46289
47232
  setData({
46290
47233
  traits: getAllTraits(),
@@ -46393,12 +47336,12 @@ function layoutGraph(states, transitions, initialState, width, height) {
46393
47336
  return positions;
46394
47337
  }
46395
47338
  function WalkMinimap() {
46396
- const [walkStep, setWalkStep] = React88.useState(null);
46397
- const [traits2, setTraits] = React88.useState([]);
46398
- const [coveredEdges, setCoveredEdges] = React88.useState([]);
46399
- const [completedTraits, setCompletedTraits] = React88.useState(/* @__PURE__ */ new Set());
46400
- const prevTraitRef = React88.useRef(null);
46401
- React88.useEffect(() => {
47339
+ const [walkStep, setWalkStep] = React89.useState(null);
47340
+ const [traits2, setTraits] = React89.useState([]);
47341
+ const [coveredEdges, setCoveredEdges] = React89.useState([]);
47342
+ const [completedTraits, setCompletedTraits] = React89.useState(/* @__PURE__ */ new Set());
47343
+ const prevTraitRef = React89.useRef(null);
47344
+ React89.useEffect(() => {
46402
47345
  const interval = setInterval(() => {
46403
47346
  const w = window;
46404
47347
  const step = w.__orbitalWalkStep;
@@ -46834,15 +47777,15 @@ var init_EntitiesTab = __esm({
46834
47777
  });
46835
47778
  function EventFlowTab({ events: events2 }) {
46836
47779
  const { t } = useTranslate();
46837
- const [filter, setFilter] = React88.useState("all");
46838
- const containerRef = React88.useRef(null);
46839
- const [autoScroll, setAutoScroll] = React88.useState(true);
46840
- React88.useEffect(() => {
47780
+ const [filter, setFilter] = React89.useState("all");
47781
+ const containerRef = React89.useRef(null);
47782
+ const [autoScroll, setAutoScroll] = React89.useState(true);
47783
+ React89.useEffect(() => {
46841
47784
  if (autoScroll && containerRef.current) {
46842
47785
  containerRef.current.scrollTop = containerRef.current.scrollHeight;
46843
47786
  }
46844
47787
  }, [events2.length, autoScroll]);
46845
- const filteredEvents = React88.useMemo(() => {
47788
+ const filteredEvents = React89.useMemo(() => {
46846
47789
  if (filter === "all") return events2;
46847
47790
  return events2.filter((e) => e.type === filter);
46848
47791
  }, [events2, filter]);
@@ -46958,7 +47901,7 @@ var init_EventFlowTab = __esm({
46958
47901
  });
46959
47902
  function GuardsPanel({ guards }) {
46960
47903
  const { t } = useTranslate();
46961
- const [filter, setFilter] = React88.useState("all");
47904
+ const [filter, setFilter] = React89.useState("all");
46962
47905
  if (guards.length === 0) {
46963
47906
  return /* @__PURE__ */ jsx(
46964
47907
  EmptyState,
@@ -46971,7 +47914,7 @@ function GuardsPanel({ guards }) {
46971
47914
  }
46972
47915
  const passedCount = guards.filter((g) => g.result).length;
46973
47916
  const failedCount = guards.length - passedCount;
46974
- const filteredGuards = React88.useMemo(() => {
47917
+ const filteredGuards = React89.useMemo(() => {
46975
47918
  if (filter === "all") return guards;
46976
47919
  if (filter === "passed") return guards.filter((g) => g.result);
46977
47920
  return guards.filter((g) => !g.result);
@@ -47134,10 +48077,10 @@ function EffectBadge({ effect }) {
47134
48077
  }
47135
48078
  function TransitionTimeline({ transitions }) {
47136
48079
  const { t } = useTranslate();
47137
- const containerRef = React88.useRef(null);
47138
- const [autoScroll, setAutoScroll] = React88.useState(true);
47139
- const [expandedId, setExpandedId] = React88.useState(null);
47140
- React88.useEffect(() => {
48080
+ const containerRef = React89.useRef(null);
48081
+ const [autoScroll, setAutoScroll] = React89.useState(true);
48082
+ const [expandedId, setExpandedId] = React89.useState(null);
48083
+ React89.useEffect(() => {
47141
48084
  if (autoScroll && containerRef.current) {
47142
48085
  containerRef.current.scrollTop = containerRef.current.scrollHeight;
47143
48086
  }
@@ -47417,9 +48360,9 @@ function getAllEvents(traits2) {
47417
48360
  function EventDispatcherTab({ traits: traits2, schema }) {
47418
48361
  const eventBus = useEventBus();
47419
48362
  const { t } = useTranslate();
47420
- const [log13, setLog] = React88.useState([]);
47421
- const prevStatesRef = React88.useRef(/* @__PURE__ */ new Map());
47422
- React88.useEffect(() => {
48363
+ const [log14, setLog] = React89.useState([]);
48364
+ const prevStatesRef = React89.useRef(/* @__PURE__ */ new Map());
48365
+ React89.useEffect(() => {
47423
48366
  for (const trait of traits2) {
47424
48367
  const prev = prevStatesRef.current.get(trait.id);
47425
48368
  if (prev && prev !== trait.currentState) {
@@ -47481,9 +48424,9 @@ function EventDispatcherTab({ traits: traits2, schema }) {
47481
48424
  /* @__PURE__ */ jsx(Typography, { variant: "small", weight: "medium", className: "text-muted-foreground mb-1", children: t("debug.otherEvents") }),
47482
48425
  /* @__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)) })
47483
48426
  ] }),
47484
- log13.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
48427
+ log14.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
47485
48428
  /* @__PURE__ */ jsx(Typography, { variant: "small", weight: "medium", className: "text-muted-foreground mb-1", children: t("debug.recentTransitions") }),
47486
- /* @__PURE__ */ jsx(Stack, { gap: "xs", children: log13.map((entry, i) => /* @__PURE__ */ jsxs(Typography, { variant: "small", className: "font-mono text-xs", children: [
48429
+ /* @__PURE__ */ jsx(Stack, { gap: "xs", children: log14.map((entry, i) => /* @__PURE__ */ jsxs(Typography, { variant: "small", className: "font-mono text-xs", children: [
47487
48430
  /* @__PURE__ */ jsx("span", { className: "text-primary", children: entry.traitName }),
47488
48431
  " ",
47489
48432
  /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: entry.from }),
@@ -47588,10 +48531,10 @@ function VerifyModePanel({
47588
48531
  localCount
47589
48532
  }) {
47590
48533
  const { t } = useTranslate();
47591
- const [expanded, setExpanded] = React88.useState(true);
47592
- const scrollRef = React88.useRef(null);
47593
- const prevCountRef = React88.useRef(0);
47594
- React88.useEffect(() => {
48534
+ const [expanded, setExpanded] = React89.useState(true);
48535
+ const scrollRef = React89.useRef(null);
48536
+ const prevCountRef = React89.useRef(0);
48537
+ React89.useEffect(() => {
47595
48538
  if (expanded && transitions.length > prevCountRef.current && scrollRef.current) {
47596
48539
  scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
47597
48540
  }
@@ -47648,10 +48591,10 @@ function RuntimeDebugger({
47648
48591
  schema
47649
48592
  }) {
47650
48593
  const { t } = useTranslate();
47651
- const [isCollapsed, setIsCollapsed] = React88.useState(mode === "verify" ? true : defaultCollapsed);
47652
- const [isVisible, setIsVisible] = React88.useState(mode === "inline" || mode === "verify" || isDebugEnabled2());
48594
+ const [isCollapsed, setIsCollapsed] = React89.useState(mode === "verify" ? true : defaultCollapsed);
48595
+ const [isVisible, setIsVisible] = React89.useState(mode === "inline" || mode === "verify" || isDebugEnabled2());
47653
48596
  const debugData = useDebugData();
47654
- React88.useEffect(() => {
48597
+ React89.useEffect(() => {
47655
48598
  if (mode === "inline") return;
47656
48599
  return onDebugToggle((enabled) => {
47657
48600
  setIsVisible(enabled);
@@ -47660,7 +48603,7 @@ function RuntimeDebugger({
47660
48603
  }
47661
48604
  });
47662
48605
  }, [mode]);
47663
- React88.useEffect(() => {
48606
+ React89.useEffect(() => {
47664
48607
  if (mode === "inline") return;
47665
48608
  const handleKeyDown = (e) => {
47666
48609
  if (e.key === "`" && isVisible) {
@@ -48091,7 +49034,7 @@ var init_StatCard = __esm({
48091
49034
  const labelToUse = propLabel ?? propTitle;
48092
49035
  const eventBus = useEventBus();
48093
49036
  const { t } = useTranslate();
48094
- const handleActionClick = React88__default.useCallback(() => {
49037
+ const handleActionClick = React89__default.useCallback(() => {
48095
49038
  if (action?.event) {
48096
49039
  eventBus.emit(`UI:${action.event}`, {});
48097
49040
  }
@@ -48102,7 +49045,7 @@ var init_StatCard = __esm({
48102
49045
  const data = Array.isArray(entity) ? entity : entity ? [entity] : [];
48103
49046
  const isLoading = externalLoading ?? false;
48104
49047
  const error = externalError;
48105
- const computeMetricValue = React88__default.useCallback(
49048
+ const computeMetricValue = React89__default.useCallback(
48106
49049
  (metric, items) => {
48107
49050
  if (metric.value !== void 0) {
48108
49051
  return metric.value;
@@ -48141,7 +49084,7 @@ var init_StatCard = __esm({
48141
49084
  },
48142
49085
  []
48143
49086
  );
48144
- const schemaStats = React88__default.useMemo(() => {
49087
+ const schemaStats = React89__default.useMemo(() => {
48145
49088
  if (!metrics || metrics.length === 0) return null;
48146
49089
  return metrics.map((metric) => ({
48147
49090
  label: metric.label,
@@ -48149,7 +49092,7 @@ var init_StatCard = __esm({
48149
49092
  format: metric.format
48150
49093
  }));
48151
49094
  }, [metrics, data, computeMetricValue]);
48152
- const calculatedTrend = React88__default.useMemo(() => {
49095
+ const calculatedTrend = React89__default.useMemo(() => {
48153
49096
  if (manualTrend !== void 0) return manualTrend;
48154
49097
  if (previousValue === void 0 || currentValue === void 0)
48155
49098
  return void 0;
@@ -48789,8 +49732,8 @@ var init_SubagentTracePanel = __esm({
48789
49732
  ] });
48790
49733
  };
48791
49734
  InlineActivityStream = ({ activities, autoScroll = true, className }) => {
48792
- const endRef = React88__default.useRef(null);
48793
- React88__default.useEffect(() => {
49735
+ const endRef = React89__default.useRef(null);
49736
+ React89__default.useEffect(() => {
48794
49737
  if (!autoScroll) return;
48795
49738
  endRef.current?.scrollIntoView({ behavior: "smooth", block: "end" });
48796
49739
  }, [activities.length, autoScroll]);
@@ -48884,7 +49827,7 @@ var init_SubagentTracePanel = __esm({
48884
49827
  };
48885
49828
  SubagentRichCard = ({ subagent }) => {
48886
49829
  const { t } = useTranslate();
48887
- const activities = React88__default.useMemo(
49830
+ const activities = React89__default.useMemo(
48888
49831
  () => subagentMessagesToActivities(subagent.messages),
48889
49832
  [subagent.messages]
48890
49833
  );
@@ -48961,8 +49904,8 @@ var init_SubagentTracePanel = __esm({
48961
49904
  ] });
48962
49905
  };
48963
49906
  CoordinatorConversation = ({ messages, autoScroll = true, className }) => {
48964
- const endRef = React88__default.useRef(null);
48965
- React88__default.useEffect(() => {
49907
+ const endRef = React89__default.useRef(null);
49908
+ React89__default.useEffect(() => {
48966
49909
  if (!autoScroll) return;
48967
49910
  endRef.current?.scrollIntoView({ behavior: "smooth", block: "end" });
48968
49911
  }, [messages.length, autoScroll]);
@@ -49397,7 +50340,7 @@ var init_Timeline = __esm({
49397
50340
  }) => {
49398
50341
  const { t } = useTranslate();
49399
50342
  const entityData = entity ?? [];
49400
- const items = React88__default.useMemo(() => {
50343
+ const items = React89__default.useMemo(() => {
49401
50344
  if (propItems) return propItems;
49402
50345
  if (entityData.length === 0) return [];
49403
50346
  return entityData.map((record, idx) => {
@@ -49499,7 +50442,7 @@ var init_Timeline = __esm({
49499
50442
  }
49500
50443
  });
49501
50444
  function extractToastProps(children) {
49502
- if (!React88__default.isValidElement(children)) {
50445
+ if (!React89__default.isValidElement(children)) {
49503
50446
  if (typeof children === "string") {
49504
50447
  return { message: children };
49505
50448
  }
@@ -49541,7 +50484,7 @@ var init_ToastSlot = __esm({
49541
50484
  eventBus.emit(`${prefix}CLOSE`);
49542
50485
  };
49543
50486
  if (!isVisible) return null;
49544
- const isCustomContent = React88__default.isValidElement(children) && !message;
50487
+ const isCustomContent = React89__default.isValidElement(children) && !message;
49545
50488
  return /* @__PURE__ */ jsx(Box, { className: "fixed bottom-4 right-4 z-50", children: isCustomContent ? children : /* @__PURE__ */ jsx(
49546
50489
  Toast,
49547
50490
  {
@@ -49609,6 +50552,7 @@ var init_component_registry_generated = __esm({
49609
50552
  init_ChoiceButton();
49610
50553
  init_CodeBlock();
49611
50554
  init_CodeRunnerPanel();
50555
+ init_CommandPalette();
49612
50556
  init_CommunityLinks();
49613
50557
  init_ConditionalWrapper();
49614
50558
  init_ConfettiEffect();
@@ -49673,6 +50617,7 @@ var init_component_registry_generated = __esm({
49673
50617
  init_FormSection();
49674
50618
  init_FormSectionHeader();
49675
50619
  init_FxOverlay();
50620
+ init_GameAudioCue();
49676
50621
  init_GameAudioToggle();
49677
50622
  init_GameHud();
49678
50623
  init_GameIcon();
@@ -49883,6 +50828,7 @@ var init_component_registry_generated = __esm({
49883
50828
  "ChoiceButton": ChoiceButton,
49884
50829
  "CodeBlock": CodeBlock,
49885
50830
  "CodeRunnerPanel": CodeRunnerPanel,
50831
+ "CommandPalette": CommandPalette,
49886
50832
  "CommunityLinks": CommunityLinks,
49887
50833
  "ConditionalWrapper": ConditionalWrapper,
49888
50834
  "ConfettiEffect": ConfettiEffect,
@@ -49949,6 +50895,7 @@ var init_component_registry_generated = __esm({
49949
50895
  "FormLayout": FormLayout,
49950
50896
  "FormSectionHeader": FormSectionHeader,
49951
50897
  "FxOverlay": FxOverlay,
50898
+ "GameAudioCue": GameAudioCue,
49952
50899
  "GameAudioToggle": GameAudioToggle,
49953
50900
  "GameHud": GameHud,
49954
50901
  "GameIcon": GameIcon,
@@ -50131,7 +51078,7 @@ function SuspenseConfigProvider({
50131
51078
  config,
50132
51079
  children
50133
51080
  }) {
50134
- return React88__default.createElement(
51081
+ return React89__default.createElement(
50135
51082
  SuspenseConfigContext.Provider,
50136
51083
  { value: config },
50137
51084
  children
@@ -50179,7 +51126,7 @@ function enrichFormFields(fields, entityDef) {
50179
51126
  }
50180
51127
  return { name: field, label: humanizeFieldName(field) };
50181
51128
  }
50182
- if (field && typeof field === "object" && !Array.isArray(field) && !React88__default.isValidElement(field) && !(field instanceof Date)) {
51129
+ if (field && typeof field === "object" && !Array.isArray(field) && !React89__default.isValidElement(field) && !(field instanceof Date)) {
50183
51130
  const obj = field;
50184
51131
  const fieldName2 = typeof obj.name === "string" ? obj.name : typeof obj.field === "string" ? obj.field : void 0;
50185
51132
  if (!fieldName2) return field;
@@ -50232,7 +51179,7 @@ function enrichDetailFields(fields, entityDef) {
50232
51179
  const meta = metaFor(field);
50233
51180
  return meta ? { key: field, ...meta } : field;
50234
51181
  }
50235
- if (field && typeof field === "object" && !Array.isArray(field) && !React88__default.isValidElement(field) && !(field instanceof Date)) {
51182
+ if (field && typeof field === "object" && !Array.isArray(field) && !React89__default.isValidElement(field) && !(field instanceof Date)) {
50236
51183
  const obj = field;
50237
51184
  const fieldName2 = typeof obj.key === "string" ? obj.key : typeof obj.name === "string" ? obj.name : void 0;
50238
51185
  if (!fieldName2 || obj.type) return field;
@@ -50691,7 +51638,7 @@ function renderPatternChildren(children, onDismiss, parentId = "root", parentPat
50691
51638
  const key = `${parentId}-${index}-trait:${traitName}`;
50692
51639
  return /* @__PURE__ */ jsx(TraitFrame, { traitName }, key);
50693
51640
  }
50694
- return /* @__PURE__ */ jsx(React88__default.Fragment, { children: child }, `${parentId}-${index}`);
51641
+ return /* @__PURE__ */ jsx(React89__default.Fragment, { children: child }, `${parentId}-${index}`);
50695
51642
  }
50696
51643
  if (!child || typeof child !== "object") return null;
50697
51644
  const childId = `${parentId}-${index}`;
@@ -50748,7 +51695,7 @@ function isPatternConfig(value) {
50748
51695
  if (value === null || value === void 0) return false;
50749
51696
  if (typeof value !== "object") return false;
50750
51697
  if (Array.isArray(value)) return false;
50751
- if (React88__default.isValidElement(value)) return false;
51698
+ if (React89__default.isValidElement(value)) return false;
50752
51699
  if (value instanceof Date) return false;
50753
51700
  if (typeof value === "function") return false;
50754
51701
  const record = value;
@@ -50761,9 +51708,9 @@ function renderPatternValue(value) {
50761
51708
  if (typeof value === "string") return renderPatternChildren(value, () => {
50762
51709
  });
50763
51710
  if (value instanceof Date) return value.toLocaleString();
50764
- if (React88__default.isValidElement(value)) return value;
51711
+ if (React89__default.isValidElement(value)) return value;
50765
51712
  if (Array.isArray(value)) {
50766
- return value.map((item, index) => /* @__PURE__ */ jsx(React88__default.Fragment, { children: renderPatternValue(item) }, index));
51713
+ return value.map((item, index) => /* @__PURE__ */ jsx(React89__default.Fragment, { children: renderPatternValue(item) }, index));
50767
51714
  }
50768
51715
  if (isPatternConfig(value)) {
50769
51716
  const { type, ...props } = value;
@@ -50773,7 +51720,7 @@ function renderPatternValue(value) {
50773
51720
  return null;
50774
51721
  }
50775
51722
  function isPlainConfigObject(value) {
50776
- if (React88__default.isValidElement(value)) return false;
51723
+ if (React89__default.isValidElement(value)) return false;
50777
51724
  if (value instanceof Date) return false;
50778
51725
  const proto = Object.getPrototypeOf(value);
50779
51726
  return proto === Object.prototype || proto === null;
@@ -50947,7 +51894,7 @@ function SlotContentRenderer({
50947
51894
  for (const slotKey of CONTENT_NODE_SLOTS) {
50948
51895
  const slotVal = restProps[slotKey];
50949
51896
  if (slotVal === void 0 || slotVal === null) continue;
50950
- if (React88__default.isValidElement(slotVal) || typeof slotVal === "string" || typeof slotVal === "number" || typeof slotVal === "boolean") continue;
51897
+ if (React89__default.isValidElement(slotVal) || typeof slotVal === "string" || typeof slotVal === "number" || typeof slotVal === "boolean") continue;
50951
51898
  const typelessChildren = !Array.isArray(slotVal) && typeof slotVal === "object" && !("type" in slotVal) && Array.isArray(slotVal.children) ? slotVal.children : void 0;
50952
51899
  if (typelessChildren !== void 0 || Array.isArray(slotVal) || typeof slotVal === "object" && "type" in slotVal) {
50953
51900
  nodeSlotOverrides[slotKey] = renderPatternChildren(
@@ -51001,7 +51948,7 @@ function SlotContentRenderer({
51001
51948
  const resolvedItems = Array.isArray(entityVal) && entityVal[0] !== "fn" ? entityVal : null;
51002
51949
  if (resolvedItems && resolvedItems.length > 0 && !finalProps.fields && !finalProps.columns) {
51003
51950
  const sample = resolvedItems[0];
51004
- if (sample && typeof sample === "object" && !Array.isArray(sample) && !React88__default.isValidElement(sample) && !(sample instanceof Date)) {
51951
+ if (sample && typeof sample === "object" && !Array.isArray(sample) && !React89__default.isValidElement(sample) && !(sample instanceof Date)) {
51005
51952
  const keys = Object.keys(sample).filter((k) => k !== "id" && k !== "_id");
51006
51953
  finalProps.fields = keys.map((k, i) => ({ name: k, variant: i === 0 ? "h4" : "body" }));
51007
51954
  }
@@ -51444,7 +52391,7 @@ init_UISlotRenderer();
51444
52391
  // providers/VerificationProvider.tsx
51445
52392
  init_useEventBus();
51446
52393
  init_verificationRegistry();
51447
- var log10 = createLogger("almadar:verify");
52394
+ var log11 = createLogger("almadar:verify");
51448
52395
  var DISPATCH_SUFFIX = ":DISPATCH";
51449
52396
  var SUCCESS_SUFFIX = ":SUCCESS";
51450
52397
  var ERROR_SUFFIX = ":ERROR";
@@ -51491,7 +52438,7 @@ function VerificationProvider({
51491
52438
  const verificationProviderLifecycleListener = (evt) => {
51492
52439
  const parsed = parseLifecycleEvent(evt.type);
51493
52440
  if (!parsed) return;
51494
- log10.debug("lifecycle:event", { kind: parsed.kind, traitName: parsed.traitName, event: parsed.event, type: evt.type });
52441
+ log11.debug("lifecycle:event", { kind: parsed.kind, traitName: parsed.traitName, event: parsed.event, type: evt.type });
51495
52442
  const payload = evt.payload ?? {};
51496
52443
  if (parsed.kind === "dispatch") {
51497
52444
  const key = `${parsed.traitName}:${String(payload["event"] ?? "")}`;
@@ -51547,7 +52494,7 @@ function VerificationProvider({
51547
52494
  },
51548
52495
  timestamp: Date.now()
51549
52496
  });
51550
- log10.debug("transition:success", { trait: parsed.traitName, event: parsed.event, from: pending?.from, to: newState, effectCount: effects.length });
52497
+ log11.debug("transition:success", { trait: parsed.traitName, event: parsed.event, from: pending?.from, to: newState, effectCount: effects.length });
51551
52498
  } else if (parsed.kind === "error" && parsed.event) {
51552
52499
  const key = `${parsed.traitName}:${parsed.event}`;
51553
52500
  const pending = pendingRef.current.get(key);
@@ -51577,7 +52524,7 @@ function VerificationProvider({
51577
52524
  },
51578
52525
  timestamp: Date.now()
51579
52526
  });
51580
- log10.warn("transition:error", { trait: parsed.traitName, event: parsed.event, from: fromState, error: errorMsg });
52527
+ log11.warn("transition:error", { trait: parsed.traitName, event: parsed.event, from: fromState, error: errorMsg });
51581
52528
  }
51582
52529
  };
51583
52530
  Object.defineProperty(verificationProviderLifecycleListener, "name", {
@@ -52039,7 +52986,7 @@ function useEntitySchema() {
52039
52986
  function useEntitySchemaOptional6() {
52040
52987
  return useContext(EntitySchemaContext);
52041
52988
  }
52042
- var log11 = createLogger("almadar:ui:navigation");
52989
+ var log12 = createLogger("almadar:ui:navigation");
52043
52990
  function matchPath2(pattern, path) {
52044
52991
  const normalizeSegment = (p) => {
52045
52992
  let normalized = p.trim();
@@ -52200,12 +53147,12 @@ function NavigationProvider2({
52200
53147
  const navigateTo = useCallback((path, payload) => {
52201
53148
  const result = findPageByPath2(schema, path);
52202
53149
  if (!result) {
52203
- log11.error("No page found for path", { path });
53150
+ log12.error("No page found for path", { path });
52204
53151
  return;
52205
53152
  }
52206
53153
  const { page, params } = result;
52207
53154
  const finalPayload = { ...params, ...payload };
52208
- log11.debug("Navigating to", () => ({
53155
+ log12.debug("Navigating to", () => ({
52209
53156
  path,
52210
53157
  page: page.name,
52211
53158
  params,
@@ -52222,7 +53169,7 @@ function NavigationProvider2({
52222
53169
  try {
52223
53170
  window.history.pushState(finalPayload, "", path);
52224
53171
  } catch (e) {
52225
- log11.warn("Could not update URL", { error: e instanceof Error ? e : String(e) });
53172
+ log12.warn("Could not update URL", { error: e instanceof Error ? e : String(e) });
52226
53173
  }
52227
53174
  }
52228
53175
  if (onNavigate) {
@@ -52232,12 +53179,12 @@ function NavigationProvider2({
52232
53179
  const navigateToPage = useCallback((pageName, payload) => {
52233
53180
  const result = findPageByName2(schema, pageName);
52234
53181
  if (!result) {
52235
- log11.error("No page found with name", { pageName });
53182
+ log12.error("No page found with name", { pageName });
52236
53183
  return;
52237
53184
  }
52238
53185
  const { page } = result;
52239
53186
  const path = page.path || `/${pageName.toLowerCase()}`;
52240
- log11.debug("Navigating to page", () => ({
53187
+ log12.debug("Navigating to page", () => ({
52241
53188
  pageName,
52242
53189
  path,
52243
53190
  payload: JSON.stringify(payload)
@@ -52252,7 +53199,7 @@ function NavigationProvider2({
52252
53199
  try {
52253
53200
  window.history.pushState(payload || {}, "", path);
52254
53201
  } catch (e) {
52255
- log11.warn("Could not update URL", { error: e instanceof Error ? e : String(e) });
53202
+ log12.warn("Could not update URL", { error: e instanceof Error ? e : String(e) });
52256
53203
  }
52257
53204
  }
52258
53205
  if (onNavigate) {
@@ -52274,7 +53221,7 @@ function useNavigation2() {
52274
53221
  function useNavigateTo2() {
52275
53222
  const context = useContext(NavigationContext);
52276
53223
  const noOp = useCallback((path, _payload) => {
52277
- log11.warn("navigateTo called outside NavigationProvider", { path });
53224
+ log12.warn("navigateTo called outside NavigationProvider", { path });
52278
53225
  }, []);
52279
53226
  return context?.navigateTo || noOp;
52280
53227
  }
@@ -52617,7 +53564,7 @@ function ServerBridgeProvider({
52617
53564
  }, [serverUrl, eventBus]);
52618
53565
  return /* @__PURE__ */ jsx(ServerBridgeContext.Provider, { value: { connected, sendEvent }, children });
52619
53566
  }
52620
- var log12 = createLogger("almadar:ui:trait-provider");
53567
+ var log13 = createLogger("almadar:ui:trait-provider");
52621
53568
  var TraitContext = createContext(null);
52622
53569
  function TraitProvider({
52623
53570
  traits: traitBindings,
@@ -52634,7 +53581,7 @@ function TraitProvider({
52634
53581
  currentState: stateName,
52635
53582
  availableEvents: trait.transitions.filter((t) => t.from === stateName).map((t) => t.event),
52636
53583
  dispatch: (eventKey, payload) => {
52637
- log12.debug("Dispatch", () => ({
53584
+ log13.debug("Dispatch", () => ({
52638
53585
  trait: trait.name,
52639
53586
  event: eventKey,
52640
53587
  payloadKeys: payload ? Object.keys(payload) : []