@almadar/ui 5.86.0 → 5.89.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 (35) hide show
  1. package/dist/avl/index.cjs +3435 -1250
  2. package/dist/avl/index.js +2485 -300
  3. package/dist/components/game/2d/molecules/StateGraph.d.ts +38 -0
  4. package/dist/components/game/2d/molecules/index.d.ts +24 -15
  5. package/dist/components/game/2d/organisms/BuilderBoard.d.ts +60 -0
  6. package/dist/components/game/2d/organisms/ClassifierBoard.d.ts +66 -0
  7. package/dist/components/game/2d/organisms/DebuggerBoard.d.ts +61 -0
  8. package/dist/components/game/2d/organisms/EventHandlerBoard.d.ts +42 -0
  9. package/dist/components/game/2d/organisms/NegotiatorBoard.d.ts +56 -0
  10. package/dist/components/game/2d/{molecules → organisms}/SequenceBar.d.ts +3 -8
  11. package/dist/components/game/2d/organisms/SequencerBoard.d.ts +69 -0
  12. package/dist/components/game/2d/organisms/SimulatorBoard.d.ts +58 -0
  13. package/dist/components/game/2d/organisms/StateArchitectBoard.d.ts +61 -0
  14. package/dist/components/game/shared/lib/puzzleObject.d.ts +1 -1
  15. package/dist/components/index.cjs +3168 -1351
  16. package/dist/components/index.js +2199 -391
  17. package/dist/providers/index.cjs +3295 -1110
  18. package/dist/providers/index.js +2454 -269
  19. package/dist/runtime/index.cjs +3291 -1106
  20. package/dist/runtime/index.js +2460 -275
  21. package/package.json +1 -1
  22. /package/dist/components/game/2d/{molecules → organisms}/ActionPalette.d.ts +0 -0
  23. /package/dist/components/game/2d/{molecules → organisms}/ActionTile.d.ts +0 -0
  24. /package/dist/components/game/2d/{molecules → organisms}/EventLog.d.ts +0 -0
  25. /package/dist/components/game/2d/{molecules → organisms}/ObjectRulePanel.d.ts +0 -0
  26. /package/dist/components/game/2d/{molecules → organisms}/RuleEditor.d.ts +0 -0
  27. /package/dist/components/game/2d/{molecules → organisms}/SimulationCanvas.d.ts +0 -0
  28. /package/dist/components/game/2d/{molecules → organisms}/SimulationControls.d.ts +0 -0
  29. /package/dist/components/game/2d/{molecules → organisms}/SimulationGraph.d.ts +0 -0
  30. /package/dist/components/game/2d/{molecules → organisms}/StateJsonView.d.ts +0 -0
  31. /package/dist/components/game/2d/{molecules → organisms}/StateNode.d.ts +0 -0
  32. /package/dist/components/game/2d/{molecules → organisms}/TraitSlot.d.ts +0 -0
  33. /package/dist/components/game/2d/{molecules → organisms}/TraitStateViewer.d.ts +0 -0
  34. /package/dist/components/game/2d/{molecules → organisms}/TransitionArrow.d.ts +0 -0
  35. /package/dist/components/game/2d/{molecules → organisms}/VariablePanel.d.ts +0 -0
@@ -1,12 +1,12 @@
1
- import * as React84 from 'react';
2
- import React84__default, { useContext, useMemo, useRef, useEffect, useCallback, Suspense, useState, createContext, useSyncExternalStore, useLayoutEffect, lazy, useId } from 'react';
1
+ import * as React96 from 'react';
2
+ import React96__default, { useContext, useMemo, useRef, useEffect, useCallback, Suspense, useState, createContext, useSyncExternalStore, useLayoutEffect, lazy, useId } from 'react';
3
3
  import { EventBusContext, useTraitScope, useEntitySchemaOptional, useEntitySchema, getAllPages, OrbitalProvider, TraitScopeProvider, ServerBridgeProvider, useCurrentPagePath, VerificationProvider, EntitySchemaProvider, OrbitalThemeProvider, useServerBridge } from '@almadar/ui/providers';
4
4
  export { EntitySchemaProvider, ServerBridgeProvider, TraitContext, TraitProvider, useEntitySchema, useEntitySchemaOptional, useServerBridge, useTrait, useTraitContext } from '@almadar/ui/providers';
5
5
  import { createLogger, isLogLevelEnabled } from '@almadar/logger';
6
6
  import { clsx } from 'clsx';
7
7
  import { twMerge } from 'tailwind-merge';
8
8
  import * as LucideIcons2 from 'lucide-react';
9
- import { Loader2, X, Lightbulb, CheckCircle, List, Printer, ChevronRight, ChevronLeft, GitBranch, Pencil, Eye, Plus, ArrowRight, Trash, Code, FileText, WrapText, Check, Copy, RotateCcw, Play, Terminal, XCircle, AlertTriangle, Trash2, Link2, ZoomOut, ZoomIn, Download, ChevronDown, Menu as Menu$1, Package, Calendar, MoreHorizontal, Image as Image$1, Upload, ArrowLeft, HelpCircle, PauseCircle, Search, Type, Heading1, Heading2, Heading3, ListOrdered, Quote, Minus, Eraser, TrendingUp, TrendingDown, AlertCircle, Circle, Clock, CheckCircle2, ChevronUp, Tag, User, DollarSign } from 'lucide-react';
9
+ import { Loader2, X, Lightbulb, CheckCircle, List, Printer, ChevronRight, ChevronLeft, GitBranch, Pencil, Eye, Plus, ArrowRight, Trash, Code, FileText, WrapText, Check, Copy, RotateCcw, Play, Terminal, XCircle, AlertTriangle, Trash2, Link2, ZoomOut, ZoomIn, Download, ChevronDown, Menu as Menu$1, Package, Calendar, MoreHorizontal, Image as Image$1, Upload, ArrowLeft, HelpCircle, PauseCircle, Search, Type, Heading1, Heading2, Heading3, ListOrdered, Quote, Minus, Eraser, TrendingUp, TrendingDown, AlertCircle, Circle, Clock, CheckCircle2, Bug, Send, ChevronUp, Wrench, Tag, User, DollarSign } from 'lucide-react';
10
10
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
11
11
  import { createPortal } from 'react-dom';
12
12
  import { useTranslate } from '@almadar/ui/hooks';
@@ -937,7 +937,7 @@ var init_Box = __esm({
937
937
  fixed: "fixed",
938
938
  sticky: "sticky"
939
939
  };
940
- Box = React84__default.forwardRef(
940
+ Box = React96__default.forwardRef(
941
941
  ({
942
942
  padding,
943
943
  paddingX,
@@ -1002,7 +1002,7 @@ var init_Box = __esm({
1002
1002
  onPointerDown?.(e);
1003
1003
  }, [hoverEvent, tapReveal, triggerProps, onPointerDown]);
1004
1004
  const isClickable = action || onClick;
1005
- return React84__default.createElement(
1005
+ return React96__default.createElement(
1006
1006
  Component,
1007
1007
  {
1008
1008
  ref,
@@ -1098,7 +1098,7 @@ function loadLib(key, importer) {
1098
1098
  return p;
1099
1099
  }
1100
1100
  function lazyFamilyIcon(libKey, importer, pick, fallbackName, family) {
1101
- const Lazy = React84__default.lazy(async () => {
1101
+ const Lazy = React96__default.lazy(async () => {
1102
1102
  const lib = await loadLib(libKey, importer);
1103
1103
  const Comp = pick(lib);
1104
1104
  if (!Comp) {
@@ -1108,7 +1108,7 @@ function lazyFamilyIcon(libKey, importer, pick, fallbackName, family) {
1108
1108
  return { default: Comp };
1109
1109
  });
1110
1110
  const Wrapped = (props) => /* @__PURE__ */ jsx(
1111
- React84__default.Suspense,
1111
+ React96__default.Suspense,
1112
1112
  {
1113
1113
  fallback: /* @__PURE__ */ jsx(
1114
1114
  "span",
@@ -1839,7 +1839,7 @@ var init_Icon = __esm({
1839
1839
  const directIcon = typeof icon === "string" ? void 0 : icon;
1840
1840
  const effectiveName = typeof icon === "string" ? icon : name;
1841
1841
  const family = useIconFamily();
1842
- const RenderedComponent = React84__default.useMemo(() => {
1842
+ const RenderedComponent = React96__default.useMemo(() => {
1843
1843
  if (directIcon) return null;
1844
1844
  return effectiveName ? resolveIconForFamily(effectiveName, family) : null;
1845
1845
  }, [directIcon, effectiveName, family]);
@@ -1901,7 +1901,7 @@ function resolveIconProp(value, sizeClass) {
1901
1901
  const IconComp = value;
1902
1902
  return /* @__PURE__ */ jsx(IconComp, { className: sizeClass });
1903
1903
  }
1904
- if (React84__default.isValidElement(value)) {
1904
+ if (React96__default.isValidElement(value)) {
1905
1905
  return value;
1906
1906
  }
1907
1907
  if (typeof value === "object" && value !== null && isIconLike(value)) {
@@ -1977,7 +1977,7 @@ var init_Button = __esm({
1977
1977
  md: "h-icon-default w-icon-default",
1978
1978
  lg: "h-icon-default w-icon-default"
1979
1979
  };
1980
- Button = React84__default.forwardRef(
1980
+ Button = React96__default.forwardRef(
1981
1981
  ({
1982
1982
  className,
1983
1983
  variant = "primary",
@@ -2045,7 +2045,7 @@ var Dialog;
2045
2045
  var init_Dialog = __esm({
2046
2046
  "components/core/atoms/Dialog.tsx"() {
2047
2047
  init_cn();
2048
- Dialog = React84__default.forwardRef(
2048
+ Dialog = React96__default.forwardRef(
2049
2049
  ({
2050
2050
  role = "dialog",
2051
2051
  "aria-modal": ariaModal = true,
@@ -2163,7 +2163,7 @@ var init_Typography = __esm({
2163
2163
  }) => {
2164
2164
  const variant = variantProp ?? (level ? `h${level}` : "body1");
2165
2165
  const Component = as || defaultElements[variant];
2166
- return React84__default.createElement(
2166
+ return React96__default.createElement(
2167
2167
  Component,
2168
2168
  {
2169
2169
  id,
@@ -2658,7 +2658,7 @@ var init_Badge = __esm({
2658
2658
  md: "px-2.5 py-1 text-sm",
2659
2659
  lg: "px-3 py-1.5 text-base"
2660
2660
  };
2661
- Badge = React84__default.forwardRef(
2661
+ Badge = React96__default.forwardRef(
2662
2662
  ({ className, variant = "default", size = "sm", amount, label, icon, iconAsset, children, onRemove, removeLabel, ...props }, ref) => {
2663
2663
  const iconSizes3 = {
2664
2664
  sm: "h-icon-default w-icon-default",
@@ -2995,7 +2995,7 @@ var init_SvgFlow = __esm({
2995
2995
  width = 100,
2996
2996
  height = 100
2997
2997
  }) => {
2998
- const markerId = React84__default.useMemo(() => {
2998
+ const markerId = React96__default.useMemo(() => {
2999
2999
  flowIdCounter += 1;
3000
3000
  return `almadar-flow-arrow-${flowIdCounter}`;
3001
3001
  }, []);
@@ -3048,7 +3048,7 @@ var init_SvgGrid = __esm({
3048
3048
  x = 10,
3049
3049
  y = 10,
3050
3050
  cols = 4,
3051
- rows = 3,
3051
+ rows: rows2 = 3,
3052
3052
  spacing = 20,
3053
3053
  nodeRadius = 3,
3054
3054
  color = "var(--color-primary)",
@@ -3060,7 +3060,7 @@ var init_SvgGrid = __esm({
3060
3060
  height = 100
3061
3061
  }) => {
3062
3062
  const highlightSet = new Set(highlights);
3063
- const inner = /* @__PURE__ */ jsx("g", { className, opacity, children: Array.from({ length: rows }).map(
3063
+ const inner = /* @__PURE__ */ jsx("g", { className, opacity, children: Array.from({ length: rows2 }).map(
3064
3064
  (_, row) => Array.from({ length: cols }).map((_2, col) => {
3065
3065
  const index = row * cols + col;
3066
3066
  const isHighlighted = highlightSet.has(index);
@@ -3588,7 +3588,7 @@ var init_SvgRing = __esm({
3588
3588
  width = 100,
3589
3589
  height = 100
3590
3590
  }) => {
3591
- const gradientId = React84__default.useMemo(() => {
3591
+ const gradientId = React96__default.useMemo(() => {
3592
3592
  ringIdCounter += 1;
3593
3593
  return `almadar-ring-glow-${ringIdCounter}`;
3594
3594
  }, []);
@@ -3769,7 +3769,7 @@ var init_Input = __esm({
3769
3769
  init_cn();
3770
3770
  init_Icon();
3771
3771
  init_useEventBus();
3772
- Input = React84__default.forwardRef(
3772
+ Input = React96__default.forwardRef(
3773
3773
  ({
3774
3774
  className,
3775
3775
  inputType,
@@ -3784,7 +3784,7 @@ var init_Input = __esm({
3784
3784
  onClear,
3785
3785
  value,
3786
3786
  options,
3787
- rows = 3,
3787
+ rows: rows2 = 3,
3788
3788
  onChange,
3789
3789
  ...props
3790
3790
  }, ref) => {
@@ -3866,7 +3866,7 @@ var init_Input = __esm({
3866
3866
  ref,
3867
3867
  value,
3868
3868
  onChange: handleChange,
3869
- rows,
3869
+ rows: rows2,
3870
3870
  className: baseClassName,
3871
3871
  ...props
3872
3872
  }
@@ -3929,7 +3929,7 @@ var Label;
3929
3929
  var init_Label = __esm({
3930
3930
  "components/core/atoms/Label.tsx"() {
3931
3931
  init_cn();
3932
- Label = React84__default.forwardRef(
3932
+ Label = React96__default.forwardRef(
3933
3933
  ({ className, required, children, ...props }, ref) => {
3934
3934
  return /* @__PURE__ */ jsxs(
3935
3935
  "label",
@@ -3956,7 +3956,7 @@ var init_Textarea = __esm({
3956
3956
  "components/core/atoms/Textarea.tsx"() {
3957
3957
  init_cn();
3958
3958
  init_useEventBus();
3959
- Textarea = React84__default.forwardRef(
3959
+ Textarea = React96__default.forwardRef(
3960
3960
  ({ className, error, onChange, ...props }, ref) => {
3961
3961
  const eventBus = useEventBus();
3962
3962
  const handleChange = (e) => {
@@ -4195,7 +4195,7 @@ var init_Select = __esm({
4195
4195
  init_cn();
4196
4196
  init_Icon();
4197
4197
  init_useEventBus();
4198
- Select = React84__default.forwardRef(
4198
+ Select = React96__default.forwardRef(
4199
4199
  (props, _ref) => {
4200
4200
  const { multiple, searchable, clearable } = props;
4201
4201
  if (multiple || searchable || clearable) {
@@ -4212,7 +4212,7 @@ var init_Checkbox = __esm({
4212
4212
  "components/core/atoms/Checkbox.tsx"() {
4213
4213
  init_cn();
4214
4214
  init_useEventBus();
4215
- Checkbox = React84__default.forwardRef(
4215
+ Checkbox = React96__default.forwardRef(
4216
4216
  ({ className, label, id, onChange, ...props }, ref) => {
4217
4217
  const inputId = id || `checkbox-${Math.random().toString(36).substr(2, 9)}`;
4218
4218
  const eventBus = useEventBus();
@@ -4266,7 +4266,7 @@ var init_Spinner = __esm({
4266
4266
  md: "h-6 w-6",
4267
4267
  lg: "h-8 w-8"
4268
4268
  };
4269
- Spinner = React84__default.forwardRef(
4269
+ Spinner = React96__default.forwardRef(
4270
4270
  ({ className, size = "md", overlay, ...props }, ref) => {
4271
4271
  if (overlay) {
4272
4272
  return /* @__PURE__ */ jsx(
@@ -4356,7 +4356,7 @@ var init_Card = __esm({
4356
4356
  chip: "shadow-none rounded-pill border-[length:var(--border-width)] border-border",
4357
4357
  "tile-image-first": "p-0 overflow-hidden"
4358
4358
  };
4359
- Card = React84__default.forwardRef(
4359
+ Card = React96__default.forwardRef(
4360
4360
  ({
4361
4361
  className,
4362
4362
  variant = "bordered",
@@ -4404,9 +4404,9 @@ var init_Card = __esm({
4404
4404
  }
4405
4405
  );
4406
4406
  Card.displayName = "Card";
4407
- CardHeader = React84__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("mb-4", className), ...props }));
4407
+ CardHeader = React96__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("mb-4", className), ...props }));
4408
4408
  CardHeader.displayName = "CardHeader";
4409
- CardTitle = React84__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
4409
+ CardTitle = React96__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
4410
4410
  "h3",
4411
4411
  {
4412
4412
  ref,
@@ -4419,11 +4419,11 @@ var init_Card = __esm({
4419
4419
  }
4420
4420
  ));
4421
4421
  CardTitle.displayName = "CardTitle";
4422
- CardContent = React84__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("", className), ...props }));
4422
+ CardContent = React96__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("", className), ...props }));
4423
4423
  CardContent.displayName = "CardContent";
4424
4424
  CardBody = CardContent;
4425
4425
  CardBody.displayName = "CardBody";
4426
- CardFooter = React84__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
4426
+ CardFooter = React96__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
4427
4427
  "div",
4428
4428
  {
4429
4429
  ref,
@@ -4478,7 +4478,7 @@ var init_FilterPill = __esm({
4478
4478
  md: "w-3.5 h-3.5",
4479
4479
  lg: "w-4 h-4"
4480
4480
  };
4481
- FilterPill = React84__default.forwardRef(
4481
+ FilterPill = React96__default.forwardRef(
4482
4482
  ({
4483
4483
  className,
4484
4484
  variant = "default",
@@ -4607,8 +4607,8 @@ var init_Avatar = __esm({
4607
4607
  actionPayload
4608
4608
  }) => {
4609
4609
  const eventBus = useEventBus();
4610
- const [imgFailed, setImgFailed] = React84__default.useState(false);
4611
- React84__default.useEffect(() => {
4610
+ const [imgFailed, setImgFailed] = React96__default.useState(false);
4611
+ React96__default.useEffect(() => {
4612
4612
  setImgFailed(false);
4613
4613
  }, [src]);
4614
4614
  const initials = providedInitials ?? (name ? generateInitials(name) : void 0);
@@ -4721,7 +4721,7 @@ var init_Center = __esm({
4721
4721
  as: Component = "div"
4722
4722
  }) => {
4723
4723
  const mergedStyle = minHeight ? { minHeight, ...style } : style;
4724
- return React84__default.createElement(Component, {
4724
+ return React96__default.createElement(Component, {
4725
4725
  className: cn(
4726
4726
  inline ? "inline-flex" : "flex",
4727
4727
  horizontal && "justify-center",
@@ -4989,7 +4989,7 @@ var init_Radio = __esm({
4989
4989
  md: "w-2.5 h-2.5",
4990
4990
  lg: "w-3 h-3"
4991
4991
  };
4992
- Radio = React84__default.forwardRef(
4992
+ Radio = React96__default.forwardRef(
4993
4993
  ({
4994
4994
  label,
4995
4995
  helperText,
@@ -5006,12 +5006,12 @@ var init_Radio = __esm({
5006
5006
  onChange,
5007
5007
  ...props
5008
5008
  }, ref) => {
5009
- const reactId = React84__default.useId();
5009
+ const reactId = React96__default.useId();
5010
5010
  const baseId = id || `radio-${reactId}`;
5011
5011
  const hasError = !!error;
5012
5012
  const eventBus = useEventBus();
5013
- const [selected, setSelected] = React84__default.useState(value);
5014
- React84__default.useEffect(() => {
5013
+ const [selected, setSelected] = React96__default.useState(value);
5014
+ React96__default.useEffect(() => {
5015
5015
  if (value !== void 0) setSelected(value);
5016
5016
  }, [value]);
5017
5017
  const pick = (next, e) => {
@@ -5193,7 +5193,7 @@ var init_Switch = __esm({
5193
5193
  "components/core/atoms/Switch.tsx"() {
5194
5194
  "use client";
5195
5195
  init_cn();
5196
- Switch = React84.forwardRef(
5196
+ Switch = React96.forwardRef(
5197
5197
  ({
5198
5198
  checked,
5199
5199
  defaultChecked = false,
@@ -5204,10 +5204,10 @@ var init_Switch = __esm({
5204
5204
  name,
5205
5205
  className
5206
5206
  }, ref) => {
5207
- const [isChecked, setIsChecked] = React84.useState(
5207
+ const [isChecked, setIsChecked] = React96.useState(
5208
5208
  checked !== void 0 ? checked : defaultChecked
5209
5209
  );
5210
- React84.useEffect(() => {
5210
+ React96.useEffect(() => {
5211
5211
  if (checked !== void 0) {
5212
5212
  setIsChecked(checked);
5213
5213
  }
@@ -5370,7 +5370,7 @@ var init_Stack = __esm({
5370
5370
  };
5371
5371
  const isHorizontal = direction === "horizontal";
5372
5372
  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";
5373
- return React84__default.createElement(
5373
+ return React96__default.createElement(
5374
5374
  Component,
5375
5375
  {
5376
5376
  className: cn(
@@ -5570,7 +5570,7 @@ var Aside;
5570
5570
  var init_Aside = __esm({
5571
5571
  "components/core/atoms/Aside.tsx"() {
5572
5572
  init_cn();
5573
- Aside = React84__default.forwardRef(
5573
+ Aside = React96__default.forwardRef(
5574
5574
  ({ className, children, ...rest }, ref) => /* @__PURE__ */ jsx("aside", { ref, className: cn(className), ...rest, children })
5575
5575
  );
5576
5576
  Aside.displayName = "Aside";
@@ -5649,9 +5649,9 @@ var init_LawReferenceTooltip = __esm({
5649
5649
  className
5650
5650
  }) => {
5651
5651
  const { t } = useTranslate();
5652
- const [isVisible, setIsVisible] = React84__default.useState(false);
5653
- const timeoutRef = React84__default.useRef(null);
5654
- const triggerRef = React84__default.useRef(null);
5652
+ const [isVisible, setIsVisible] = React96__default.useState(false);
5653
+ const timeoutRef = React96__default.useRef(null);
5654
+ const triggerRef = React96__default.useRef(null);
5655
5655
  const handleMouseEnter = () => {
5656
5656
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
5657
5657
  timeoutRef.current = setTimeout(() => setIsVisible(true), 200);
@@ -5662,7 +5662,7 @@ var init_LawReferenceTooltip = __esm({
5662
5662
  };
5663
5663
  const { revealed, triggerProps } = useTapReveal({ refs: [triggerRef] });
5664
5664
  const open = isVisible || revealed;
5665
- React84__default.useEffect(() => {
5665
+ React96__default.useEffect(() => {
5666
5666
  return () => {
5667
5667
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
5668
5668
  };
@@ -5872,7 +5872,7 @@ var init_StatusDot = __esm({
5872
5872
  md: "w-2.5 h-2.5",
5873
5873
  lg: "w-3 h-3"
5874
5874
  };
5875
- StatusDot = React84__default.forwardRef(
5875
+ StatusDot = React96__default.forwardRef(
5876
5876
  ({ className, status = "offline", pulse = false, size = "md", label, ...props }, ref) => {
5877
5877
  return /* @__PURE__ */ jsx(
5878
5878
  "span",
@@ -5926,7 +5926,7 @@ var init_TrendIndicator = __esm({
5926
5926
  down: "trending-down",
5927
5927
  flat: "arrow-right"
5928
5928
  };
5929
- TrendIndicator = React84__default.forwardRef(
5929
+ TrendIndicator = React96__default.forwardRef(
5930
5930
  ({
5931
5931
  className,
5932
5932
  value,
@@ -5993,7 +5993,7 @@ var init_RangeSlider = __esm({
5993
5993
  md: "w-4 h-4",
5994
5994
  lg: "w-5 h-5"
5995
5995
  };
5996
- RangeSlider = React84__default.forwardRef(
5996
+ RangeSlider = React96__default.forwardRef(
5997
5997
  ({
5998
5998
  className,
5999
5999
  min = 0,
@@ -6552,7 +6552,7 @@ var init_ContentSection = __esm({
6552
6552
  md: "py-16",
6553
6553
  lg: "py-24"
6554
6554
  };
6555
- ContentSection = React84__default.forwardRef(
6555
+ ContentSection = React96__default.forwardRef(
6556
6556
  ({ children, background = "default", padding = "lg", id, className }, ref) => {
6557
6557
  return /* @__PURE__ */ jsx(
6558
6558
  Box,
@@ -7086,7 +7086,7 @@ var init_AnimatedReveal = __esm({
7086
7086
  "scale-up": { opacity: 1, transform: "scale(1) translateY(0)" },
7087
7087
  "none": {}
7088
7088
  };
7089
- AnimatedReveal = React84__default.forwardRef(
7089
+ AnimatedReveal = React96__default.forwardRef(
7090
7090
  ({
7091
7091
  trigger = "scroll",
7092
7092
  animation = "fade-up",
@@ -7246,7 +7246,7 @@ var init_AnimatedGraphic = __esm({
7246
7246
  "components/marketing/atoms/AnimatedGraphic.tsx"() {
7247
7247
  "use client";
7248
7248
  init_cn();
7249
- AnimatedGraphic = React84__default.forwardRef(
7249
+ AnimatedGraphic = React96__default.forwardRef(
7250
7250
  ({
7251
7251
  src,
7252
7252
  svgContent,
@@ -7269,7 +7269,7 @@ var init_AnimatedGraphic = __esm({
7269
7269
  const fetchedSvg = useFetchedSvg(svgContent ? void 0 : src);
7270
7270
  const resolvedSvg = svgContent ?? fetchedSvg;
7271
7271
  const prevAnimateRef = useRef(animate);
7272
- const setRef = React84__default.useCallback(
7272
+ const setRef = React96__default.useCallback(
7273
7273
  (node) => {
7274
7274
  containerRef.current = node;
7275
7275
  if (typeof ref === "function") ref(node);
@@ -7417,6 +7417,20 @@ var init_effects = __esm({
7417
7417
  });
7418
7418
 
7419
7419
  // components/game/shared/boardEntity.ts
7420
+ function boardEntity(entity) {
7421
+ if (!entity) return void 0;
7422
+ return Array.isArray(entity) ? entity[0] : entity;
7423
+ }
7424
+ function str(v) {
7425
+ return v == null ? "" : String(v);
7426
+ }
7427
+ function num(v, fallback = 0) {
7428
+ const n = Number(v);
7429
+ return Number.isFinite(n) ? n : fallback;
7430
+ }
7431
+ function rows(v) {
7432
+ return Array.isArray(v) ? v : [];
7433
+ }
7420
7434
  var init_boardEntity = __esm({
7421
7435
  "components/game/shared/boardEntity.ts"() {
7422
7436
  }
@@ -7862,7 +7876,7 @@ function GameCard({
7862
7876
  className
7863
7877
  }) {
7864
7878
  const eventBus = useEventBus();
7865
- const handleClick = React84.useCallback(() => {
7879
+ const handleClick = React96.useCallback(() => {
7866
7880
  if (disabled) return;
7867
7881
  onClick?.(id);
7868
7882
  if (clickEvent) eventBus.emit(`UI:${clickEvent}`, { cardId: id });
@@ -8144,9 +8158,9 @@ function ControlButton({
8144
8158
  className
8145
8159
  }) {
8146
8160
  const eventBus = useEventBus();
8147
- const [isPressed, setIsPressed] = React84.useState(false);
8161
+ const [isPressed, setIsPressed] = React96.useState(false);
8148
8162
  const actualPressed = pressed ?? isPressed;
8149
- const handlePointerDown = React84.useCallback(
8163
+ const handlePointerDown = React96.useCallback(
8150
8164
  (e) => {
8151
8165
  e.preventDefault();
8152
8166
  if (disabled) return;
@@ -8156,7 +8170,7 @@ function ControlButton({
8156
8170
  },
8157
8171
  [disabled, pressEvent, eventBus, onPress]
8158
8172
  );
8159
- const handlePointerUp = React84.useCallback(
8173
+ const handlePointerUp = React96.useCallback(
8160
8174
  (e) => {
8161
8175
  e.preventDefault();
8162
8176
  if (disabled) return;
@@ -8166,7 +8180,7 @@ function ControlButton({
8166
8180
  },
8167
8181
  [disabled, releaseEvent, eventBus, onRelease]
8168
8182
  );
8169
- const handlePointerLeave = React84.useCallback(
8183
+ const handlePointerLeave = React96.useCallback(
8170
8184
  (e) => {
8171
8185
  if (isPressed) {
8172
8186
  setIsPressed(false);
@@ -9185,8 +9199,8 @@ function MiniMap({
9185
9199
  tileAssets,
9186
9200
  unitAssets
9187
9201
  }) {
9188
- const canvasRef = React84.useRef(null);
9189
- const imgCacheRef = React84.useRef(/* @__PURE__ */ new Map());
9202
+ const canvasRef = React96.useRef(null);
9203
+ const imgCacheRef = React96.useRef(/* @__PURE__ */ new Map());
9190
9204
  function loadImg(url) {
9191
9205
  const cached = imgCacheRef.current.get(url);
9192
9206
  if (cached) return cached.complete ? cached : null;
@@ -9201,7 +9215,7 @@ function MiniMap({
9201
9215
  imgCacheRef.current.set(url, img);
9202
9216
  return null;
9203
9217
  }
9204
- React84.useEffect(() => {
9218
+ React96.useEffect(() => {
9205
9219
  const canvas = canvasRef.current;
9206
9220
  if (!canvas) return;
9207
9221
  const ctx = canvas.getContext("2d");
@@ -9336,8 +9350,8 @@ function ControlGrid({
9336
9350
  className
9337
9351
  }) {
9338
9352
  const eventBus = useEventBus();
9339
- const [active, setActive] = React84.useState(/* @__PURE__ */ new Set());
9340
- const handlePress = React84.useCallback(
9353
+ const [active, setActive] = React96.useState(/* @__PURE__ */ new Set());
9354
+ const handlePress = React96.useCallback(
9341
9355
  (id) => {
9342
9356
  setActive((prev) => new Set(prev).add(id));
9343
9357
  if (actionEvent) eventBus.emit(`UI:${actionEvent}`, { id, pressed: true });
@@ -9351,7 +9365,7 @@ function ControlGrid({
9351
9365
  },
9352
9366
  [kind, actionEvent, directionEvent, directionEvents, eventBus, onAction, onDirection]
9353
9367
  );
9354
- const handleRelease = React84.useCallback(
9368
+ const handleRelease = React96.useCallback(
9355
9369
  (id) => {
9356
9370
  setActive((prev) => {
9357
9371
  const next = new Set(prev);
@@ -9609,7 +9623,7 @@ function InventoryGrid({
9609
9623
  const eventBus = useEventBus();
9610
9624
  const slotCount = totalSlots ?? items.length;
9611
9625
  const emptySlotCount = Math.max(0, slotCount - items.length);
9612
- const handleSelect = React84.useCallback(
9626
+ const handleSelect = React96.useCallback(
9613
9627
  (id) => {
9614
9628
  onSelect?.(id);
9615
9629
  if (selectEvent) {
@@ -9826,7 +9840,7 @@ function GameMenu({
9826
9840
  }) {
9827
9841
  const resolvedOptions = options ?? menuItems ?? DEFAULT_MENU_OPTIONS;
9828
9842
  const eventBus = useEventBus();
9829
- const handleOptionClick = React84.useCallback(
9843
+ const handleOptionClick = React96.useCallback(
9830
9844
  (option) => {
9831
9845
  if (option.event) {
9832
9846
  eventBus.emit(`UI:${option.event}`, { option });
@@ -9903,6 +9917,214 @@ var init_GameMenu = __esm({
9903
9917
  GameMenu.displayName = "GameMenu";
9904
9918
  }
9905
9919
  });
9920
+ function StateNode({
9921
+ name,
9922
+ isCurrent = false,
9923
+ isSelected = false,
9924
+ isInitial = false,
9925
+ position,
9926
+ onClick,
9927
+ className
9928
+ }) {
9929
+ return /* @__PURE__ */ jsx(
9930
+ Box,
9931
+ {
9932
+ position: "absolute",
9933
+ display: "flex",
9934
+ className: cn(
9935
+ "items-center justify-center rounded-pill border-3 transition-all cursor-pointer select-none",
9936
+ "min-w-[80px] h-[80px] px-3",
9937
+ isCurrent && "bg-primary/20 border-primary shadow-lg shadow-primary/30 scale-110",
9938
+ isSelected && !isCurrent && "bg-accent/20 border-accent ring-2 ring-accent/50",
9939
+ !isCurrent && !isSelected && "bg-card border-border hover:border-muted-foreground hover:scale-105",
9940
+ className
9941
+ ),
9942
+ style: {
9943
+ left: position.x,
9944
+ top: position.y,
9945
+ transform: "translate(-50%, -50%)"
9946
+ },
9947
+ onClick,
9948
+ children: /* @__PURE__ */ jsxs(Box, { className: "text-center", children: [
9949
+ isInitial && /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground text-xs block", children: "\u25B6 start" }),
9950
+ /* @__PURE__ */ jsx(
9951
+ Typography,
9952
+ {
9953
+ variant: "body2",
9954
+ className: cn(
9955
+ "font-bold whitespace-nowrap",
9956
+ isCurrent ? "text-primary" : "text-foreground"
9957
+ ),
9958
+ children: name
9959
+ }
9960
+ )
9961
+ ] })
9962
+ }
9963
+ );
9964
+ }
9965
+ var init_StateNode = __esm({
9966
+ "components/game/2d/organisms/StateNode.tsx"() {
9967
+ init_atoms();
9968
+ init_cn();
9969
+ StateNode.displayName = "StateNode";
9970
+ }
9971
+ });
9972
+ function TransitionArrow({
9973
+ from,
9974
+ to,
9975
+ eventLabel,
9976
+ guardHint,
9977
+ isActive = false,
9978
+ onClick,
9979
+ className
9980
+ }) {
9981
+ const dx = to.x - from.x;
9982
+ const dy = to.y - from.y;
9983
+ const dist = Math.sqrt(dx * dx + dy * dy);
9984
+ if (dist === 0) return /* @__PURE__ */ jsx(Fragment, {});
9985
+ const nx = dx / dist;
9986
+ const ny = dy / dist;
9987
+ const startX = from.x + nx * NODE_RADIUS;
9988
+ const startY = from.y + ny * NODE_RADIUS;
9989
+ const endX = to.x - nx * NODE_RADIUS;
9990
+ const endY = to.y - ny * NODE_RADIUS;
9991
+ const midX = (startX + endX) / 2;
9992
+ const midY = (startY + endY) / 2;
9993
+ const perpX = -ny * 20;
9994
+ const perpY = nx * 20;
9995
+ const ctrlX = midX + perpX;
9996
+ const ctrlY = midY + perpY;
9997
+ const path = `M ${startX} ${startY} Q ${ctrlX} ${ctrlY} ${endX} ${endY}`;
9998
+ return /* @__PURE__ */ jsxs("g", { className: cn("cursor-pointer", className), onClick, children: [
9999
+ /* @__PURE__ */ jsx(
10000
+ "path",
10001
+ {
10002
+ d: path,
10003
+ fill: "none",
10004
+ stroke: isActive ? "var(--color-primary)" : "var(--color-border)",
10005
+ strokeWidth: isActive ? 3 : 2,
10006
+ markerEnd: isActive ? "url(#arrowhead-active)" : "url(#arrowhead)"
10007
+ }
10008
+ ),
10009
+ /* @__PURE__ */ jsx(
10010
+ "text",
10011
+ {
10012
+ x: ctrlX,
10013
+ y: ctrlY - 8,
10014
+ textAnchor: "middle",
10015
+ fill: isActive ? "var(--color-primary)" : "var(--color-foreground)",
10016
+ fontSize: 12,
10017
+ fontWeight: isActive ? "bold" : "normal",
10018
+ className: "select-none",
10019
+ children: eventLabel
10020
+ }
10021
+ ),
10022
+ guardHint && /* @__PURE__ */ jsx(
10023
+ "text",
10024
+ {
10025
+ x: ctrlX,
10026
+ y: ctrlY + 6,
10027
+ textAnchor: "middle",
10028
+ fill: "var(--color-warning)",
10029
+ fontSize: 10,
10030
+ className: "select-none",
10031
+ children: "\u26A0 " + guardHint
10032
+ }
10033
+ )
10034
+ ] });
10035
+ }
10036
+ var NODE_RADIUS;
10037
+ var init_TransitionArrow = __esm({
10038
+ "components/game/2d/organisms/TransitionArrow.tsx"() {
10039
+ init_cn();
10040
+ NODE_RADIUS = 40;
10041
+ TransitionArrow.displayName = "TransitionArrow";
10042
+ }
10043
+ });
10044
+ function layoutStates(states, width, height) {
10045
+ const cx = width / 2;
10046
+ const cy = height / 2;
10047
+ const radius = Math.min(cx, cy) - 60;
10048
+ const positions = {};
10049
+ states.forEach((state, i) => {
10050
+ const angle = 2 * Math.PI * i / Math.max(states.length, 1) - Math.PI / 2;
10051
+ positions[state] = { x: cx + radius * Math.cos(angle), y: cy + radius * Math.sin(angle) };
10052
+ });
10053
+ return positions;
10054
+ }
10055
+ function StateGraph({
10056
+ states,
10057
+ transitions = [],
10058
+ currentState,
10059
+ selectedState,
10060
+ addingFrom,
10061
+ initialState,
10062
+ width = 500,
10063
+ height = 400,
10064
+ nodeClickEvent,
10065
+ className
10066
+ }) {
10067
+ const eventBus = useEventBus();
10068
+ const nodes = states ?? [];
10069
+ const positions = React96.useMemo(() => layoutStates(nodes, width, height), [nodes, width, height]);
10070
+ return /* @__PURE__ */ jsxs(
10071
+ Box,
10072
+ {
10073
+ position: "relative",
10074
+ className: cn("rounded-container border border-border bg-background overflow-hidden", className),
10075
+ style: { width, height },
10076
+ children: [
10077
+ /* @__PURE__ */ jsxs("svg", { width, height, className: "absolute inset-0", style: { pointerEvents: "none" }, children: [
10078
+ /* @__PURE__ */ jsxs("defs", { children: [
10079
+ /* @__PURE__ */ jsx("marker", { id: "arrowhead", markerWidth: "10", markerHeight: "7", refX: "10", refY: "3.5", orient: "auto", children: /* @__PURE__ */ jsx("polygon", { points: "0 0, 10 3.5, 0 7", fill: "var(--color-border)" }) }),
10080
+ /* @__PURE__ */ jsx("marker", { id: "arrowhead-active", markerWidth: "10", markerHeight: "7", refX: "10", refY: "3.5", orient: "auto", children: /* @__PURE__ */ jsx("polygon", { points: "0 0, 10 3.5, 0 7", fill: "var(--color-primary)" }) })
10081
+ ] }),
10082
+ transitions.map((tr, i) => {
10083
+ const fromPos = positions[tr.from];
10084
+ const toPos = positions[tr.to];
10085
+ if (!fromPos || !toPos) return null;
10086
+ return /* @__PURE__ */ jsx(
10087
+ TransitionArrow,
10088
+ {
10089
+ from: fromPos,
10090
+ to: toPos,
10091
+ eventLabel: tr.event,
10092
+ guardHint: tr.guardHint,
10093
+ isActive: tr.from === currentState
10094
+ },
10095
+ `${tr.from}-${tr.event}-${tr.to}-${i}`
10096
+ );
10097
+ })
10098
+ ] }),
10099
+ nodes.map((state) => {
10100
+ const pos = positions[state];
10101
+ if (!pos) return null;
10102
+ return /* @__PURE__ */ jsx(
10103
+ StateNode,
10104
+ {
10105
+ name: state,
10106
+ position: pos,
10107
+ isCurrent: state === currentState,
10108
+ isSelected: state === selectedState || state === addingFrom,
10109
+ isInitial: state === initialState,
10110
+ onClick: nodeClickEvent ? () => eventBus.emit(`UI:${nodeClickEvent}`, { stateId: state }) : void 0
10111
+ },
10112
+ state
10113
+ );
10114
+ })
10115
+ ]
10116
+ }
10117
+ );
10118
+ }
10119
+ var init_StateGraph = __esm({
10120
+ "components/game/2d/molecules/StateGraph.tsx"() {
10121
+ init_atoms();
10122
+ init_cn();
10123
+ init_useEventBus();
10124
+ init_StateNode();
10125
+ init_TransitionArrow();
10126
+ }
10127
+ });
9906
10128
  function useCamera() {
9907
10129
  const cameraRef = useRef({ x: 0, y: 0, zoom: 1 });
9908
10130
  const targetCameraRef = useRef(null);
@@ -11321,7 +11543,7 @@ function LinearView({
11321
11543
  /* @__PURE__ */ jsx(HStack, { className: "flex-wrap items-center", gap: "xs", children: trait.states.map((state, i) => {
11322
11544
  const isDone = i < currentIdx;
11323
11545
  const isCurrent = i === currentIdx;
11324
- return /* @__PURE__ */ jsxs(React84__default.Fragment, { children: [
11546
+ return /* @__PURE__ */ jsxs(React96__default.Fragment, { children: [
11325
11547
  i > 0 && /* @__PURE__ */ jsx(
11326
11548
  Typography,
11327
11549
  {
@@ -11518,7 +11740,7 @@ function TraitStateViewer({
11518
11740
  }
11519
11741
  var SIZE_CONFIG;
11520
11742
  var init_TraitStateViewer = __esm({
11521
- "components/game/2d/molecules/TraitStateViewer.tsx"() {
11743
+ "components/game/2d/organisms/TraitStateViewer.tsx"() {
11522
11744
  "use client";
11523
11745
  init_cn();
11524
11746
  init_Box();
@@ -11725,7 +11947,7 @@ function TraitSlot({
11725
11947
  }
11726
11948
  var SIZE_CONFIG2, DRAG_MIME;
11727
11949
  var init_TraitSlot = __esm({
11728
- "components/game/2d/molecules/TraitSlot.tsx"() {
11950
+ "components/game/2d/organisms/TraitSlot.tsx"() {
11729
11951
  "use client";
11730
11952
  init_cn();
11731
11953
  init_useEventBus();
@@ -11784,7 +12006,7 @@ function ActionTile({
11784
12006
  }
11785
12007
  var DRAG_MIME2, SIZE_CONFIG3;
11786
12008
  var init_ActionTile = __esm({
11787
- "components/game/2d/molecules/ActionTile.tsx"() {
12009
+ "components/game/2d/organisms/ActionTile.tsx"() {
11788
12010
  init_atoms();
11789
12011
  init_cn();
11790
12012
  DRAG_MIME2 = "application/x-almadar-slot-item";
@@ -11821,7 +12043,7 @@ function ActionPalette({
11821
12043
  ] });
11822
12044
  }
11823
12045
  var init_ActionPalette = __esm({
11824
- "components/game/2d/molecules/ActionPalette.tsx"() {
12046
+ "components/game/2d/organisms/ActionPalette.tsx"() {
11825
12047
  init_atoms();
11826
12048
  init_cn();
11827
12049
  init_ActionTile();
@@ -11833,8 +12055,6 @@ function SequenceBar({
11833
12055
  maxSlots,
11834
12056
  onSlotDrop,
11835
12057
  onSlotRemove,
11836
- slotDropEvent,
11837
- slotRemoveEvent,
11838
12058
  playing = false,
11839
12059
  currentStep = -1,
11840
12060
  categoryColors,
@@ -11842,19 +12062,16 @@ function SequenceBar({
11842
12062
  size = "lg",
11843
12063
  className
11844
12064
  }) {
11845
- const { emit } = useEventBus();
11846
12065
  const handleDrop = useCallback((index) => (item) => {
11847
12066
  if (playing) return;
11848
- if (slotDropEvent) emit(`UI:${slotDropEvent}`, { slotIndex: index, actionId: item.id });
11849
- onSlotDrop?.(index, item);
11850
- }, [onSlotDrop, slotDropEvent, emit, playing]);
12067
+ onSlotDrop(index, item);
12068
+ }, [onSlotDrop, playing]);
11851
12069
  const handleRemove = useCallback((index) => () => {
11852
12070
  if (playing) return;
11853
- if (slotRemoveEvent) emit(`UI:${slotRemoveEvent}`, { slotIndex: index });
11854
- onSlotRemove?.(index);
11855
- }, [onSlotRemove, slotRemoveEvent, emit, playing]);
12071
+ onSlotRemove(index);
12072
+ }, [onSlotRemove, playing]);
11856
12073
  const paddedSlots = Array.from({ length: maxSlots }, (_, i) => slots[i]);
11857
- return /* @__PURE__ */ jsx(HStack, { className: cn("items-center", className), gap: "sm", children: paddedSlots.map((slot, i) => /* @__PURE__ */ jsxs(React84__default.Fragment, { children: [
12074
+ return /* @__PURE__ */ jsx(HStack, { className: cn("items-center", className), gap: "sm", children: paddedSlots.map((slot, i) => /* @__PURE__ */ jsxs(React96__default.Fragment, { children: [
11858
12075
  i > 0 && /* @__PURE__ */ jsx(
11859
12076
  Typography,
11860
12077
  {
@@ -11884,14 +12101,330 @@ function SequenceBar({
11884
12101
  ] }, i)) });
11885
12102
  }
11886
12103
  var init_SequenceBar = __esm({
11887
- "components/game/2d/molecules/SequenceBar.tsx"() {
12104
+ "components/game/2d/organisms/SequenceBar.tsx"() {
11888
12105
  init_atoms();
11889
12106
  init_cn();
11890
- init_useEventBus();
11891
12107
  init_TraitSlot();
11892
12108
  SequenceBar.displayName = "SequenceBar";
11893
12109
  }
11894
12110
  });
12111
+ function computeSlotFeedback(playerSeq, solutions) {
12112
+ let bestSolution = solutions[0];
12113
+ let bestMatches = -1;
12114
+ for (const sol of solutions) {
12115
+ const matches = sol.filter((id, i) => id === playerSeq[i]).length;
12116
+ if (matches > bestMatches) {
12117
+ bestMatches = matches;
12118
+ bestSolution = sol;
12119
+ }
12120
+ }
12121
+ return playerSeq.map(
12122
+ (id, i) => id !== void 0 && id === bestSolution[i] ? "correct" : "wrong"
12123
+ );
12124
+ }
12125
+ function isFieldRecord(v) {
12126
+ return typeof v === "object" && v !== null && !Array.isArray(v) && !(v instanceof Date);
12127
+ }
12128
+ function assetFromField(v) {
12129
+ if (!isFieldRecord(v)) return void 0;
12130
+ const url = typeof v.url === "string" ? v.url : void 0;
12131
+ const role = typeof v.role === "string" ? v.role : void 0;
12132
+ const category = typeof v.category === "string" ? v.category : "";
12133
+ if (!url || !role) return void 0;
12134
+ return {
12135
+ url,
12136
+ role,
12137
+ category,
12138
+ name: typeof v.name === "string" ? v.name : void 0,
12139
+ thumbnailUrl: typeof v.thumbnailUrl === "string" ? v.thumbnailUrl : void 0,
12140
+ style: typeof v.style === "string" ? v.style : void 0,
12141
+ variant: typeof v.variant === "string" ? v.variant : void 0,
12142
+ dimension: typeof v.dimension === "string" ? v.dimension : void 0,
12143
+ aspect: typeof v.aspect === "string" ? v.aspect : void 0
12144
+ };
12145
+ }
12146
+ function slotItemFromField(fv) {
12147
+ if (!isFieldRecord(fv)) return void 0;
12148
+ const id = typeof fv.id === "string" ? fv.id : void 0;
12149
+ const name = typeof fv.name === "string" ? fv.name : void 0;
12150
+ const category = typeof fv.category === "string" ? fv.category : void 0;
12151
+ if (!id || !name || !category) return void 0;
12152
+ return {
12153
+ id,
12154
+ name,
12155
+ category,
12156
+ description: typeof fv.description === "string" ? fv.description : void 0,
12157
+ iconEmoji: typeof fv.iconEmoji === "string" ? fv.iconEmoji : void 0,
12158
+ iconUrl: assetFromField(fv.iconUrl)
12159
+ };
12160
+ }
12161
+ function SequencerBoard({
12162
+ entity,
12163
+ categoryColors,
12164
+ stepDurationMs = 1e3,
12165
+ playEvent,
12166
+ completeEvent,
12167
+ placeEvent,
12168
+ removeEvent,
12169
+ checkEvent,
12170
+ playAgainEvent,
12171
+ stepEvent,
12172
+ className
12173
+ }) {
12174
+ const { emit } = useEventBus();
12175
+ const { t } = useTranslate();
12176
+ const resolved = boardEntity(entity);
12177
+ const maxSlots = num(resolved?.maxSlots) || 3;
12178
+ const solutions = Array.isArray(resolved?.solutions) ? resolved.solutions : [];
12179
+ const availableActions = (Array.isArray(resolved?.availableActions) ? resolved.availableActions : []).reduce((acc, fv) => {
12180
+ const item = slotItemFromField(fv);
12181
+ if (item) acc.push(item);
12182
+ return acc;
12183
+ }, []);
12184
+ const allowDuplicates = resolved?.allowDuplicates !== false;
12185
+ const entitySlots = Array.isArray(resolved?.slots) ? resolved.slots : [];
12186
+ const entityResult = str(resolved?.result);
12187
+ const entityAttempts = num(resolved?.attempts);
12188
+ const entityCurrentStep = typeof resolved?.currentStep === "number" ? resolved.currentStep : -1;
12189
+ const slots = Array.from({ length: maxSlots }, (_, i) => {
12190
+ const entitySlot = entitySlots.find((s) => s.index === i);
12191
+ if (!entitySlot?.placedActionId) return void 0;
12192
+ return availableActions.find((a) => a.id === entitySlot.placedActionId);
12193
+ });
12194
+ const isSuccess = entityResult === "win";
12195
+ const attempts = entityAttempts;
12196
+ const isPlayingBack = entityCurrentStep >= 0 && !isSuccess;
12197
+ const currentStep = entityCurrentStep;
12198
+ const [headerError, setHeaderError] = useState(false);
12199
+ const [slotFeedback, setSlotFeedback] = useState(
12200
+ () => Array.from({ length: maxSlots }, () => null)
12201
+ );
12202
+ const timerRef = useRef(null);
12203
+ useEffect(() => () => {
12204
+ if (timerRef.current) clearTimeout(timerRef.current);
12205
+ }, []);
12206
+ const handleSlotDrop = useCallback((index, item) => {
12207
+ setSlotFeedback((prev) => {
12208
+ const next = [...prev];
12209
+ next[index] = null;
12210
+ return next;
12211
+ });
12212
+ emit("UI:PLAY_SOUND", { key: "drop_slot" });
12213
+ if (placeEvent) emit(`UI:${placeEvent}`, { slotIndex: index, actionId: item.id });
12214
+ }, [emit, placeEvent]);
12215
+ const handleSlotRemove = useCallback((index) => {
12216
+ setSlotFeedback((prev) => {
12217
+ const next = [...prev];
12218
+ next[index] = null;
12219
+ return next;
12220
+ });
12221
+ emit("UI:PLAY_SOUND", { key: "back" });
12222
+ if (removeEvent) emit(`UI:${removeEvent}`, { slotIndex: index });
12223
+ }, [emit, removeEvent]);
12224
+ const handleReset = useCallback(() => {
12225
+ if (timerRef.current) clearTimeout(timerRef.current);
12226
+ setSlotFeedback(Array.from({ length: maxSlots }, () => null));
12227
+ if (playAgainEvent) emit(`UI:${playAgainEvent}`, {});
12228
+ }, [maxSlots, playAgainEvent, emit]);
12229
+ const filledSlots = slots.filter((s) => !!s);
12230
+ const canPlay = filledSlots.length > 0 && !isPlayingBack && !isSuccess;
12231
+ const handlePlay = useCallback(() => {
12232
+ if (!canPlay) return;
12233
+ setSlotFeedback(Array.from({ length: maxSlots }, () => null));
12234
+ emit("UI:PLAY_SOUND", { key: "confirm" });
12235
+ const sequence = slots.map((s) => s?.id || "");
12236
+ const playerIds = slots.filter(Boolean).map((s) => s?.id || "");
12237
+ if (playEvent) emit(`UI:${playEvent}`, { sequence });
12238
+ let step = 0;
12239
+ const advance = () => {
12240
+ step++;
12241
+ if (stepEvent) emit(`UI:${stepEvent}`, { step });
12242
+ if (step >= maxSlots) {
12243
+ if (checkEvent) emit(`UI:${checkEvent}`, { sequence: playerIds });
12244
+ const playerSeq = slots.map((s) => s?.id);
12245
+ const success = solutions.some(
12246
+ (sol) => sol.length === playerIds.length && sol.every((id, i) => id === playerIds[i])
12247
+ );
12248
+ if (success) {
12249
+ emit("UI:PLAY_SOUND", { key: "levelComplete" });
12250
+ if (completeEvent) emit(`UI:${completeEvent}`, { success: true, sequence: playerIds });
12251
+ } else {
12252
+ const feedback = computeSlotFeedback(playerSeq, solutions);
12253
+ setSlotFeedback(feedback);
12254
+ emit("UI:PLAY_SOUND", { key: "fail" });
12255
+ const correctCount2 = feedback.filter((f3) => f3 === "correct").length;
12256
+ for (let ci = 0; ci < correctCount2; ci++) {
12257
+ setTimeout(() => {
12258
+ emit("UI:PLAY_SOUND", { key: "correctSlot" });
12259
+ }, 300 + ci * 150);
12260
+ }
12261
+ }
12262
+ } else {
12263
+ timerRef.current = setTimeout(advance, stepDurationMs);
12264
+ }
12265
+ };
12266
+ timerRef.current = setTimeout(advance, stepDurationMs);
12267
+ }, [canPlay, slots, maxSlots, solutions, stepDurationMs, playEvent, completeEvent, checkEvent, emit]);
12268
+ const machine = {
12269
+ name: str(resolved?.title),
12270
+ description: str(resolved?.description),
12271
+ states: slots.map((s, i) => stepLabel(s, i)),
12272
+ currentState: currentStep >= 0 ? stepLabel(slots[currentStep], currentStep) : "__idle__",
12273
+ transitions: slots.slice(0, -1).map((s, i) => ({
12274
+ from: stepLabel(s, i),
12275
+ to: stepLabel(slots[i + 1], i + 1),
12276
+ event: "NEXT"
12277
+ }))
12278
+ };
12279
+ const usedIds = !allowDuplicates ? slots.filter(Boolean).map((s) => s?.id || "") : [];
12280
+ const hint = str(resolved?.hint);
12281
+ const showHint = attempts >= 3 && !!hint;
12282
+ const hasFeedback = slotFeedback.some((f3) => f3 !== null);
12283
+ const correctCount = slotFeedback.filter((f3) => f3 === "correct").length;
12284
+ const encourageKey = ENCOURAGEMENT_KEYS[Math.min(attempts - 1, ENCOURAGEMENT_KEYS.length - 1)] ?? ENCOURAGEMENT_KEYS[0];
12285
+ if (!resolved) return null;
12286
+ const theme = resolved.theme ?? void 0;
12287
+ const themeBackground = theme?.background;
12288
+ const headerImage = str(resolved.headerImage);
12289
+ return /* @__PURE__ */ jsxs(
12290
+ VStack,
12291
+ {
12292
+ className: cn("p-4 gap-6", className),
12293
+ style: {
12294
+ backgroundImage: themeBackground ? `url(${themeBackground})` : void 0,
12295
+ backgroundSize: "cover",
12296
+ backgroundPosition: "center"
12297
+ },
12298
+ children: [
12299
+ headerImage && !headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsx("img", { src: headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : headerImage && headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
12300
+ /* @__PURE__ */ jsxs(VStack, { gap: "xs", children: [
12301
+ /* @__PURE__ */ jsx(Typography, { variant: "h4", className: "text-foreground", children: str(resolved.title) }),
12302
+ /* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-muted-foreground", children: str(resolved.description) })
12303
+ ] }),
12304
+ showHint && /* @__PURE__ */ jsx(Box, { className: "p-3 rounded-container bg-accent/10 border border-accent/30", children: /* @__PURE__ */ jsxs(HStack, { className: "items-start", gap: "xs", children: [
12305
+ /* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-accent font-bold shrink-0", children: "\u{1F4A1} " + t("game.hint") + ":" }),
12306
+ /* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-foreground", children: hint })
12307
+ ] }) }),
12308
+ filledSlots.length > 0 && /* @__PURE__ */ jsx(TraitStateViewer, { trait: machine, variant: "linear", size: "md" }),
12309
+ /* @__PURE__ */ jsxs(VStack, { gap: "xs", children: [
12310
+ /* @__PURE__ */ jsxs(HStack, { className: "items-center justify-between", children: [
12311
+ /* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-muted-foreground font-medium", children: t("sequencer.yourSequence") + ":" }),
12312
+ hasFeedback && !isPlayingBack && !isSuccess && /* @__PURE__ */ jsxs(Typography, { variant: "caption", className: "text-muted-foreground", children: [
12313
+ `${correctCount}/${maxSlots} `,
12314
+ "\u2705"
12315
+ ] })
12316
+ ] }),
12317
+ /* @__PURE__ */ jsx(
12318
+ SequenceBar,
12319
+ {
12320
+ slots,
12321
+ maxSlots,
12322
+ onSlotDrop: handleSlotDrop,
12323
+ onSlotRemove: handleSlotRemove,
12324
+ playing: isPlayingBack,
12325
+ currentStep,
12326
+ categoryColors,
12327
+ slotFeedback,
12328
+ size: "lg"
12329
+ }
12330
+ )
12331
+ ] }),
12332
+ !isPlayingBack && /* @__PURE__ */ jsx(
12333
+ ActionPalette,
12334
+ {
12335
+ actions: availableActions,
12336
+ usedActionIds: usedIds,
12337
+ allowDuplicates,
12338
+ categoryColors,
12339
+ label: t("sequencer.dragActions")
12340
+ }
12341
+ ),
12342
+ hasFeedback && !isPlayingBack && !isSuccess && attempts > 0 && /* @__PURE__ */ jsx(Box, { className: "p-3 rounded-container bg-warning/10 border border-warning/30 text-center", children: /* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-foreground", children: t(encourageKey) }) }),
12343
+ isSuccess && /* @__PURE__ */ jsx(Box, { className: "p-4 rounded-container bg-success/20 border border-success text-center", children: /* @__PURE__ */ jsx(Typography, { variant: "h5", className: "text-success", children: str(resolved.successMessage) || t("sequencer.levelComplete") }) }),
12344
+ /* @__PURE__ */ jsxs(HStack, { gap: "sm", children: [
12345
+ /* @__PURE__ */ jsx(
12346
+ Button,
12347
+ {
12348
+ variant: "primary",
12349
+ onClick: handlePlay,
12350
+ disabled: !canPlay,
12351
+ children: "\u25B6 " + t("game.play")
12352
+ }
12353
+ ),
12354
+ /* @__PURE__ */ jsx(Button, { variant: "ghost", onClick: handleReset, children: "\u21BA " + t("game.reset") })
12355
+ ] })
12356
+ ]
12357
+ }
12358
+ );
12359
+ }
12360
+ var ENCOURAGEMENT_KEYS, stepLabel;
12361
+ var init_SequencerBoard = __esm({
12362
+ "components/game/2d/organisms/SequencerBoard.tsx"() {
12363
+ init_atoms();
12364
+ init_cn();
12365
+ init_useEventBus();
12366
+ init_TraitStateViewer();
12367
+ init_boardEntity();
12368
+ init_SequenceBar();
12369
+ init_ActionPalette();
12370
+ ENCOURAGEMENT_KEYS = [
12371
+ "puzzle.tryAgain1",
12372
+ "puzzle.tryAgain2",
12373
+ "puzzle.tryAgain3"
12374
+ ];
12375
+ stepLabel = (slot, i) => slot ? `${i + 1}. ${slot.name}` : `Step ${i + 1}`;
12376
+ SequencerBoard.displayName = "SequencerBoard";
12377
+ }
12378
+ });
12379
+ function RuleEditor({
12380
+ rule,
12381
+ availableEvents,
12382
+ availableActions,
12383
+ onChange,
12384
+ onRemove,
12385
+ disabled = false,
12386
+ className
12387
+ }) {
12388
+ const { t } = useTranslate();
12389
+ const handleWhenChange = useCallback((v) => {
12390
+ onChange({ ...rule, whenEvent: v });
12391
+ }, [rule, onChange]);
12392
+ const handleThenChange = useCallback((v) => {
12393
+ onChange({ ...rule, thenAction: v });
12394
+ }, [rule, onChange]);
12395
+ return /* @__PURE__ */ jsxs(HStack, { className: cn("items-center p-2 rounded-lg bg-muted/50 border border-border", className), gap: "sm", children: [
12396
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-primary font-bold whitespace-nowrap", children: t("eventHandler.when") }),
12397
+ /* @__PURE__ */ jsx(
12398
+ Select,
12399
+ {
12400
+ value: rule.whenEvent,
12401
+ onValueChange: handleWhenChange,
12402
+ options: availableEvents,
12403
+ disabled,
12404
+ className: "flex-1 min-w-0"
12405
+ }
12406
+ ),
12407
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-accent font-bold whitespace-nowrap", children: "\u2192 " + t("eventHandler.then") }),
12408
+ /* @__PURE__ */ jsx(
12409
+ Select,
12410
+ {
12411
+ value: rule.thenAction,
12412
+ onValueChange: handleThenChange,
12413
+ options: availableActions,
12414
+ disabled,
12415
+ className: "flex-1 min-w-0"
12416
+ }
12417
+ ),
12418
+ onRemove && /* @__PURE__ */ jsx(Button, { variant: "ghost", onClick: onRemove, disabled, className: "shrink-0", children: "\xD7" })
12419
+ ] });
12420
+ }
12421
+ var init_RuleEditor = __esm({
12422
+ "components/game/2d/organisms/RuleEditor.tsx"() {
12423
+ init_atoms();
12424
+ init_cn();
12425
+ RuleEditor.displayName = "RuleEditor";
12426
+ }
12427
+ });
11895
12428
  function EventLog({
11896
12429
  entries,
11897
12430
  maxHeight = 200,
@@ -11927,7 +12460,7 @@ function EventLog({
11927
12460
  }
11928
12461
  var STATUS_STYLES, STATUS_DOTS;
11929
12462
  var init_EventLog = __esm({
11930
- "components/game/2d/molecules/EventLog.tsx"() {
12463
+ "components/game/2d/organisms/EventLog.tsx"() {
11931
12464
  init_atoms();
11932
12465
  init_cn();
11933
12466
  STATUS_STYLES = {
@@ -11947,10 +12480,1644 @@ var init_EventLog = __esm({
11947
12480
  });
11948
12481
 
11949
12482
  // components/game/shared/lib/puzzleObject.ts
12483
+ function objId(o) {
12484
+ return o.id == null ? "" : String(o.id);
12485
+ }
12486
+ function objName(o) {
12487
+ return o.name == null ? "" : String(o.name);
12488
+ }
12489
+ function objIcon(o) {
12490
+ return o.icon == null ? "" : String(o.icon);
12491
+ }
12492
+ function objStates(o) {
12493
+ return Array.isArray(o.states) ? o.states : [];
12494
+ }
12495
+ function objCurrentState(o) {
12496
+ return o.currentState == null ? "" : String(o.currentState);
12497
+ }
12498
+ function objAvailableEvents(o) {
12499
+ return Array.isArray(o.availableEvents) ? o.availableEvents : [];
12500
+ }
12501
+ function objAvailableActions(o) {
12502
+ return Array.isArray(o.availableActions) ? o.availableActions : [];
12503
+ }
12504
+ function objRules(o) {
12505
+ return Array.isArray(o.rules) ? o.rules : [];
12506
+ }
12507
+ function objMaxRules(o) {
12508
+ const n = Number(o.maxRules);
12509
+ return Number.isFinite(n) && n > 0 ? n : 3;
12510
+ }
11950
12511
  var init_puzzleObject = __esm({
11951
12512
  "components/game/shared/lib/puzzleObject.ts"() {
11952
12513
  }
11953
12514
  });
12515
+ function ObjectRulePanel({
12516
+ object,
12517
+ onRulesChange,
12518
+ disabled = false,
12519
+ className
12520
+ }) {
12521
+ const { t } = useTranslate();
12522
+ const id = objId(object);
12523
+ const name = objName(object);
12524
+ const icon = objIcon(object);
12525
+ const states = objStates(object);
12526
+ const currentState = objCurrentState(object);
12527
+ const availableEvents = objAvailableEvents(object);
12528
+ const availableActions = objAvailableActions(object);
12529
+ const rules = objRules(object);
12530
+ const maxRules = objMaxRules(object);
12531
+ const canAdd = rules.length < maxRules;
12532
+ const handleRuleChange = useCallback((index, updatedRule) => {
12533
+ const newRules = [...rules];
12534
+ newRules[index] = updatedRule;
12535
+ onRulesChange(id, newRules);
12536
+ }, [id, rules, onRulesChange]);
12537
+ const handleRuleRemove = useCallback((index) => {
12538
+ const newRules = rules.filter((_, i) => i !== index);
12539
+ onRulesChange(id, newRules);
12540
+ }, [id, rules, onRulesChange]);
12541
+ const handleAddRule = useCallback(() => {
12542
+ if (!canAdd || disabled) return;
12543
+ const firstEvent = availableEvents[0]?.value || "";
12544
+ const firstAction = availableActions[0]?.value || "";
12545
+ const newRule = {
12546
+ id: `rule-${nextRuleId++}`,
12547
+ whenEvent: firstEvent,
12548
+ thenAction: firstAction
12549
+ };
12550
+ onRulesChange(id, [...rules, newRule]);
12551
+ }, [canAdd, disabled, id, rules, availableEvents, availableActions, onRulesChange]);
12552
+ const machine = {
12553
+ name,
12554
+ states,
12555
+ currentState,
12556
+ transitions: rules.map((r) => ({
12557
+ from: currentState,
12558
+ to: states.find((s) => s !== currentState) || currentState,
12559
+ event: r.whenEvent
12560
+ }))
12561
+ };
12562
+ return /* @__PURE__ */ jsxs(VStack, { className: cn("p-4 rounded-lg bg-card border border-border", className), gap: "sm", children: [
12563
+ /* @__PURE__ */ jsxs(HStack, { className: "items-center", gap: "sm", children: [
12564
+ /* @__PURE__ */ jsx(Typography, { variant: "h5", children: icon }),
12565
+ /* @__PURE__ */ jsxs(VStack, { gap: "none", children: [
12566
+ /* @__PURE__ */ jsx(Typography, { variant: "body1", className: "text-foreground font-bold", children: name }),
12567
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: t("eventHandler.state") + ": " + currentState })
12568
+ ] })
12569
+ ] }),
12570
+ /* @__PURE__ */ jsx(TraitStateViewer, { trait: machine, variant: "compact", size: "sm" }),
12571
+ /* @__PURE__ */ jsxs(VStack, { gap: "xs", children: [
12572
+ /* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-muted-foreground font-medium", children: t("eventHandler.rules", { count: rules.length, max: maxRules }) + ":" }),
12573
+ rules.map((rule, i) => /* @__PURE__ */ jsx(
12574
+ RuleEditor,
12575
+ {
12576
+ rule,
12577
+ availableEvents,
12578
+ availableActions,
12579
+ onChange: (r) => handleRuleChange(i, r),
12580
+ onRemove: () => handleRuleRemove(i),
12581
+ disabled
12582
+ },
12583
+ rule.id
12584
+ )),
12585
+ canAdd && !disabled && /* @__PURE__ */ jsx(Button, { variant: "ghost", onClick: handleAddRule, className: "self-start", children: t("eventHandler.addRule") })
12586
+ ] })
12587
+ ] });
12588
+ }
12589
+ var nextRuleId;
12590
+ var init_ObjectRulePanel = __esm({
12591
+ "components/game/2d/organisms/ObjectRulePanel.tsx"() {
12592
+ init_atoms();
12593
+ init_cn();
12594
+ init_TraitStateViewer();
12595
+ init_RuleEditor();
12596
+ init_puzzleObject();
12597
+ nextRuleId = 1;
12598
+ ObjectRulePanel.displayName = "ObjectRulePanel";
12599
+ }
12600
+ });
12601
+ function EventHandlerBoard({
12602
+ entity,
12603
+ stepDurationMs = 800,
12604
+ playEvent,
12605
+ completeEvent,
12606
+ editRuleEvent,
12607
+ playAgainEvent,
12608
+ className
12609
+ }) {
12610
+ const { emit } = useEventBus();
12611
+ const { t } = useTranslate();
12612
+ const resolved = boardEntity(entity);
12613
+ const objects = rows(resolved?.objects);
12614
+ const entityResult = str(resolved?.result) || "none";
12615
+ const isSuccess = entityResult === "win";
12616
+ const attempts = typeof resolved?.attempts === "number" ? resolved.attempts : 0;
12617
+ const [selectedObjectId, setSelectedObjectId] = useState(
12618
+ objects[0] ? objId(objects[0]) : null
12619
+ );
12620
+ const [headerError, setHeaderError] = useState(false);
12621
+ const [isPlaying, setIsPlaying] = useState(false);
12622
+ const [eventLog, setEventLog] = useState([]);
12623
+ const timerRef = useRef(null);
12624
+ const logIdCounter = useRef(0);
12625
+ useEffect(() => () => {
12626
+ if (timerRef.current) clearTimeout(timerRef.current);
12627
+ }, []);
12628
+ const selectedObject = objects.find((o) => objId(o) === selectedObjectId) ?? null;
12629
+ const handleRulesChange = useCallback((objectId, rules) => {
12630
+ if (editRuleEvent) emit(`UI:${editRuleEvent}`, { objectId, rules });
12631
+ }, [editRuleEvent, emit]);
12632
+ const addLogEntry = useCallback((icon, message, status = "done") => {
12633
+ const id = `log-${logIdCounter.current++}`;
12634
+ setEventLog((prev) => [...prev, { id, timestamp: Date.now(), icon, message, status }]);
12635
+ }, []);
12636
+ const handlePlay = useCallback(() => {
12637
+ if (isPlaying || isSuccess) return;
12638
+ if (playEvent) emit(`UI:${playEvent}`, {});
12639
+ setIsPlaying(true);
12640
+ setEventLog([]);
12641
+ const allRules = [];
12642
+ objects.forEach((obj) => {
12643
+ objRules(obj).forEach((rule) => {
12644
+ allRules.push({ object: obj, rule });
12645
+ });
12646
+ });
12647
+ const triggers = Array.isArray(resolved?.triggerEvents) ? resolved.triggerEvents : [];
12648
+ const goalEvent = str(resolved?.goalEvent);
12649
+ const eventQueue = [...triggers];
12650
+ const firedEvents = /* @__PURE__ */ new Set();
12651
+ let stepIdx = 0;
12652
+ let goalReached = false;
12653
+ const processNext = () => {
12654
+ if (eventQueue.length === 0 || stepIdx > 20) {
12655
+ setIsPlaying(false);
12656
+ if (goalReached && completeEvent) emit(`UI:${completeEvent}`, { success: true });
12657
+ return;
12658
+ }
12659
+ const currentEvent = eventQueue.shift();
12660
+ if (firedEvents.has(currentEvent)) {
12661
+ timerRef.current = setTimeout(processNext, 100);
12662
+ return;
12663
+ }
12664
+ firedEvents.add(currentEvent);
12665
+ const matching = allRules.filter((r) => r.rule.whenEvent === currentEvent);
12666
+ if (matching.length === 0) {
12667
+ addLogEntry("\u26A1", t("eventHandler.noListeners", { event: currentEvent }), "done");
12668
+ } else {
12669
+ matching.forEach(({ object, rule }) => {
12670
+ addLogEntry(objIcon(object), t("eventHandler.heardEvent", { object: objName(object), event: currentEvent, action: rule.thenAction }), "done");
12671
+ eventQueue.push(rule.thenAction);
12672
+ if (rule.thenAction === goalEvent) {
12673
+ goalReached = true;
12674
+ }
12675
+ });
12676
+ }
12677
+ if (currentEvent === goalEvent) {
12678
+ goalReached = true;
12679
+ }
12680
+ stepIdx++;
12681
+ timerRef.current = setTimeout(processNext, stepDurationMs);
12682
+ };
12683
+ if (triggers.length > 0) {
12684
+ addLogEntry("\u{1F3AC}", t("eventHandler.simulationStarted", { events: triggers.join(", ") }), "active");
12685
+ }
12686
+ timerRef.current = setTimeout(processNext, stepDurationMs);
12687
+ }, [isPlaying, isSuccess, objects, resolved, stepDurationMs, playEvent, completeEvent, emit, addLogEntry, t]);
12688
+ const handleTryAgain = useCallback(() => {
12689
+ if (timerRef.current) clearTimeout(timerRef.current);
12690
+ setIsPlaying(false);
12691
+ setEventLog([]);
12692
+ }, []);
12693
+ const handleReset = useCallback(() => {
12694
+ if (timerRef.current) clearTimeout(timerRef.current);
12695
+ setIsPlaying(false);
12696
+ setEventLog([]);
12697
+ setSelectedObjectId(objects[0] ? objId(objects[0]) : null);
12698
+ if (playAgainEvent) emit(`UI:${playAgainEvent}`, {});
12699
+ }, [objects, playAgainEvent, emit]);
12700
+ if (!resolved) return null;
12701
+ const objectViewers = objects.map((obj) => {
12702
+ const states = objStates(obj);
12703
+ const currentState = objCurrentState(obj);
12704
+ const machine = {
12705
+ name: objName(obj),
12706
+ states,
12707
+ currentState,
12708
+ transitions: objRules(obj).map((r) => ({
12709
+ from: currentState,
12710
+ to: states.find((s) => s !== currentState) || currentState,
12711
+ event: r.whenEvent
12712
+ }))
12713
+ };
12714
+ return { obj, machine };
12715
+ });
12716
+ const hint = str(resolved.hint);
12717
+ const showHint = attempts >= 3 && hint;
12718
+ const theme = resolved.theme ?? void 0;
12719
+ const themeBackground = theme?.background;
12720
+ const headerImage = str(resolved.headerImage);
12721
+ const encourageKey = ENCOURAGEMENT_KEYS2[Math.min(attempts - 1, ENCOURAGEMENT_KEYS2.length - 1)] ?? ENCOURAGEMENT_KEYS2[0];
12722
+ return /* @__PURE__ */ jsxs(
12723
+ VStack,
12724
+ {
12725
+ className: cn("p-4 gap-6", className),
12726
+ style: {
12727
+ backgroundImage: themeBackground ? `url(${themeBackground})` : void 0,
12728
+ backgroundSize: "cover",
12729
+ backgroundPosition: "center"
12730
+ },
12731
+ children: [
12732
+ headerImage && !headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsx("img", { src: headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : headerImage && headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
12733
+ /* @__PURE__ */ jsxs(VStack, { gap: "xs", children: [
12734
+ /* @__PURE__ */ jsx(Typography, { variant: "h4", className: "text-foreground", children: str(resolved.title) }),
12735
+ /* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-muted-foreground", children: str(resolved.description) }),
12736
+ /* @__PURE__ */ jsxs(HStack, { className: "items-center p-2 rounded bg-primary/10 border border-primary/30", gap: "xs", children: [
12737
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-primary font-bold", children: t("game.goal") + ":" }),
12738
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-foreground", children: str(resolved.goalCondition) })
12739
+ ] })
12740
+ ] }),
12741
+ /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
12742
+ /* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-muted-foreground font-medium", children: t("eventHandler.clickObject") + ":" }),
12743
+ /* @__PURE__ */ jsx(HStack, { className: "flex-wrap", gap: "sm", children: objectViewers.map(({ obj, machine }) => {
12744
+ const oid = objId(obj);
12745
+ return /* @__PURE__ */ jsx(
12746
+ Box,
12747
+ {
12748
+ className: cn(
12749
+ "p-3 rounded-container border-2 cursor-pointer transition-all hover:scale-105",
12750
+ selectedObjectId === oid ? "border-primary bg-primary/10" : "border-border bg-card hover:border-muted-foreground"
12751
+ ),
12752
+ onClick: () => setSelectedObjectId(oid),
12753
+ children: /* @__PURE__ */ jsxs(VStack, { gap: "xs", className: "items-center min-w-[120px]", children: [
12754
+ /* @__PURE__ */ jsx(Typography, { variant: "h5", children: objIcon(obj) }),
12755
+ /* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-foreground font-medium", children: objName(obj) }),
12756
+ /* @__PURE__ */ jsx(TraitStateViewer, { trait: machine, variant: "compact", size: "sm" })
12757
+ ] })
12758
+ },
12759
+ oid
12760
+ );
12761
+ }) })
12762
+ ] }),
12763
+ selectedObject && /* @__PURE__ */ jsx(
12764
+ ObjectRulePanel,
12765
+ {
12766
+ object: selectedObject,
12767
+ onRulesChange: handleRulesChange,
12768
+ disabled: isPlaying
12769
+ }
12770
+ ),
12771
+ eventLog.length > 0 && /* @__PURE__ */ jsx(EventLog, { entries: eventLog }),
12772
+ isSuccess && /* @__PURE__ */ jsx(Box, { className: "p-4 rounded-container bg-success/20 border border-success text-center", children: /* @__PURE__ */ jsx(Typography, { variant: "h5", className: "text-success", children: str(resolved.successMessage) || t("eventHandler.chainComplete") }) }),
12773
+ !isPlaying && !isSuccess && attempts > 0 && /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
12774
+ /* @__PURE__ */ jsx(Box, { className: "p-4 rounded-container bg-warning/10 border border-warning/30 text-center", children: /* @__PURE__ */ jsx(Typography, { variant: "body1", className: "text-foreground font-medium", children: t(encourageKey) }) }),
12775
+ showHint && /* @__PURE__ */ jsx(Box, { className: "p-3 rounded-container bg-accent/10 border border-accent/30", children: /* @__PURE__ */ jsxs(HStack, { className: "items-start", gap: "xs", children: [
12776
+ /* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-accent font-bold shrink-0", children: "\u{1F4A1} " + t("game.hint") + ":" }),
12777
+ /* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-foreground", children: hint })
12778
+ ] }) })
12779
+ ] }),
12780
+ /* @__PURE__ */ jsxs(HStack, { gap: "sm", children: [
12781
+ !isPlaying && !isSuccess && attempts > 0 ? /* @__PURE__ */ jsx(Button, { variant: "primary", onClick: handleTryAgain, children: "\u{1F504} " + t("puzzle.tryAgainButton") }) : /* @__PURE__ */ jsx(
12782
+ Button,
12783
+ {
12784
+ variant: "primary",
12785
+ onClick: handlePlay,
12786
+ disabled: isPlaying || isSuccess,
12787
+ children: "\u25B6 " + t("game.play")
12788
+ }
12789
+ ),
12790
+ /* @__PURE__ */ jsx(Button, { variant: "ghost", onClick: handleReset, children: "\u21BA " + t("game.reset") })
12791
+ ] })
12792
+ ]
12793
+ }
12794
+ );
12795
+ }
12796
+ var ENCOURAGEMENT_KEYS2;
12797
+ var init_EventHandlerBoard = __esm({
12798
+ "components/game/2d/organisms/EventHandlerBoard.tsx"() {
12799
+ init_atoms();
12800
+ init_cn();
12801
+ init_useEventBus();
12802
+ init_TraitStateViewer();
12803
+ init_ObjectRulePanel();
12804
+ init_EventLog();
12805
+ init_puzzleObject();
12806
+ init_boardEntity();
12807
+ ENCOURAGEMENT_KEYS2 = [
12808
+ "puzzle.tryAgain1",
12809
+ "puzzle.tryAgain2",
12810
+ "puzzle.tryAgain3"
12811
+ ];
12812
+ EventHandlerBoard.displayName = "EventHandlerBoard";
12813
+ }
12814
+ });
12815
+ function VariablePanel({
12816
+ entityName,
12817
+ variables,
12818
+ className
12819
+ }) {
12820
+ const { t } = useTranslate();
12821
+ return /* @__PURE__ */ jsxs(VStack, { className: cn("p-3 rounded-lg bg-card border border-border", className), gap: "sm", children: [
12822
+ /* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-muted-foreground font-medium", children: t("stateArchitect.variables", { name: entityName }) }),
12823
+ variables.map((v) => {
12824
+ const name = v.name == null ? "" : String(v.name);
12825
+ const value = numField(v.value);
12826
+ const max = numField(v.max, 100);
12827
+ const min = numField(v.min, 0);
12828
+ const unit = v.unit == null ? "" : String(v.unit);
12829
+ const pct = Math.round((value - min) / (max - min) * 100);
12830
+ const isHigh = pct > 80;
12831
+ const isLow = pct < 20;
12832
+ return /* @__PURE__ */ jsxs(VStack, { gap: "none", children: [
12833
+ /* @__PURE__ */ jsxs(HStack, { className: "items-center justify-between", children: [
12834
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-foreground font-medium", children: name }),
12835
+ /* @__PURE__ */ jsxs(Typography, { variant: "caption", className: cn(
12836
+ isHigh ? "text-error" : isLow ? "text-warning" : "text-foreground"
12837
+ ), children: [
12838
+ value,
12839
+ unit,
12840
+ " / ",
12841
+ max,
12842
+ unit
12843
+ ] })
12844
+ ] }),
12845
+ /* @__PURE__ */ jsx(
12846
+ ProgressBar,
12847
+ {
12848
+ value: pct,
12849
+ color: isHigh ? "danger" : isLow ? "warning" : "primary",
12850
+ size: "sm"
12851
+ }
12852
+ )
12853
+ ] }, name);
12854
+ })
12855
+ ] });
12856
+ }
12857
+ var numField;
12858
+ var init_VariablePanel = __esm({
12859
+ "components/game/2d/organisms/VariablePanel.tsx"() {
12860
+ init_atoms();
12861
+ init_cn();
12862
+ numField = (v, fallback = 0) => {
12863
+ const n = Number(v);
12864
+ return Number.isFinite(n) ? n : fallback;
12865
+ };
12866
+ VariablePanel.displayName = "VariablePanel";
12867
+ }
12868
+ });
12869
+ function StateJsonView({
12870
+ data,
12871
+ label,
12872
+ defaultExpanded = false,
12873
+ className
12874
+ }) {
12875
+ const { t } = useTranslate();
12876
+ const [expanded, setExpanded] = useState(defaultExpanded);
12877
+ const jsonString = JSON.stringify(data, null, 2);
12878
+ return /* @__PURE__ */ jsxs(VStack, { className: cn("rounded-lg border border-border overflow-hidden", className), gap: "none", children: [
12879
+ /* @__PURE__ */ jsxs(HStack, { className: "items-center justify-between p-2 bg-muted", gap: "sm", children: [
12880
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground font-medium", children: label ?? t("stateArchitect.viewCode") }),
12881
+ /* @__PURE__ */ jsx(Button, { variant: "ghost", onClick: () => setExpanded(!expanded), className: "text-xs", children: expanded ? t("stateArchitect.hideJson") : t("stateArchitect.showJson") })
12882
+ ] }),
12883
+ expanded && /* @__PURE__ */ jsx(Box, { className: "p-3 bg-background overflow-x-auto", children: /* @__PURE__ */ jsx(
12884
+ Typography,
12885
+ {
12886
+ variant: "caption",
12887
+ className: "text-foreground font-mono whitespace-pre text-xs leading-relaxed block",
12888
+ children: jsonString
12889
+ }
12890
+ ) })
12891
+ ] });
12892
+ }
12893
+ var init_StateJsonView = __esm({
12894
+ "components/game/2d/organisms/StateJsonView.tsx"() {
12895
+ init_atoms();
12896
+ init_cn();
12897
+ StateJsonView.displayName = "StateJsonView";
12898
+ }
12899
+ });
12900
+ function layoutStates2(states, width, height) {
12901
+ const cx = width / 2;
12902
+ const cy = height / 2;
12903
+ const radius = Math.min(cx, cy) - 60;
12904
+ const positions = {};
12905
+ states.forEach((state, i) => {
12906
+ const angle = 2 * Math.PI * i / states.length - Math.PI / 2;
12907
+ positions[state] = {
12908
+ x: cx + radius * Math.cos(angle),
12909
+ y: cy + radius * Math.sin(angle)
12910
+ };
12911
+ });
12912
+ return positions;
12913
+ }
12914
+ function StateArchitectBoard({
12915
+ entity,
12916
+ stepDurationMs = 600,
12917
+ testEvent,
12918
+ completeEvent,
12919
+ addTransitionEvent,
12920
+ removeTransitionEvent,
12921
+ playAgainEvent,
12922
+ className
12923
+ }) {
12924
+ const { emit } = useEventBus();
12925
+ const { t } = useTranslate();
12926
+ const resolved = boardEntity(entity);
12927
+ const entityStates = Array.isArray(resolved?.states) ? resolved.states : [];
12928
+ const initialState = str(resolved?.initialState);
12929
+ const entityName = str(resolved?.entityName);
12930
+ const availableEvents = Array.isArray(resolved?.availableEvents) ? resolved.availableEvents : [];
12931
+ const testCases = (Array.isArray(resolved?.testCases) ? resolved.testCases : []).map((item) => {
12932
+ const o = typeof item === "object" && item !== null && !Array.isArray(item) ? item : {};
12933
+ const eventsField = o["events"];
12934
+ return {
12935
+ events: Array.isArray(eventsField) ? eventsField : [],
12936
+ expectedState: str(o["expectedState"]),
12937
+ label: str(o["label"])
12938
+ };
12939
+ });
12940
+ const entityTransitions = (Array.isArray(resolved?.transitions) ? resolved.transitions : []).map((item) => {
12941
+ const o = typeof item === "object" && item !== null && !Array.isArray(item) ? item : {};
12942
+ return {
12943
+ id: str(o["id"]),
12944
+ from: str(o["from"]),
12945
+ to: str(o["to"]),
12946
+ event: str(o["event"]),
12947
+ ...o["guardHint"] ? { guardHint: str(o["guardHint"]) } : {}
12948
+ };
12949
+ });
12950
+ const entityVariables = rows(resolved?.variables);
12951
+ const transitions = entityTransitions;
12952
+ const attempts = typeof resolved?.attempts === "number" ? resolved.attempts : 0;
12953
+ const entityResult = str(resolved?.result) || "none";
12954
+ const isSuccess = entityResult === "win";
12955
+ const [isTesting, setIsTesting] = useState(false);
12956
+ const [headerError, setHeaderError] = useState(false);
12957
+ const [currentState, setCurrentState] = useState(initialState);
12958
+ const [selectedState, setSelectedState] = useState(null);
12959
+ const [testResults, setTestResults] = useState([]);
12960
+ const [variables, setVariables] = useState(() => [...entityVariables]);
12961
+ const timerRef = useRef(null);
12962
+ const [addingFrom, setAddingFrom] = useState(null);
12963
+ useEffect(() => () => {
12964
+ if (timerRef.current) clearTimeout(timerRef.current);
12965
+ }, []);
12966
+ const GRAPH_W = 500;
12967
+ const GRAPH_H = 400;
12968
+ const positions = useMemo(() => layoutStates2(entityStates, GRAPH_W, GRAPH_H), [entityStates]);
12969
+ const handleStateClick = useCallback((state) => {
12970
+ if (isTesting) return;
12971
+ if (addingFrom) {
12972
+ if (addingFrom !== state) {
12973
+ const event = availableEvents[0] || "EVENT";
12974
+ const newTrans = {
12975
+ id: `t-${nextTransId++}`,
12976
+ from: addingFrom,
12977
+ to: state,
12978
+ event
12979
+ };
12980
+ if (addTransitionEvent) emit(`UI:${addTransitionEvent}`, { id: newTrans.id, from: newTrans.from, to: newTrans.to, event: newTrans.event });
12981
+ }
12982
+ setAddingFrom(null);
12983
+ } else {
12984
+ setSelectedState(state);
12985
+ }
12986
+ }, [isTesting, addingFrom, availableEvents, addTransitionEvent, emit]);
12987
+ const handleStartAddTransition = useCallback(() => {
12988
+ if (!selectedState) return;
12989
+ setAddingFrom(selectedState);
12990
+ }, [selectedState]);
12991
+ const handleRemoveTransition = useCallback((transId) => {
12992
+ if (removeTransitionEvent) emit(`UI:${removeTransitionEvent}`, { id: transId });
12993
+ }, [removeTransitionEvent, emit]);
12994
+ const machine = useMemo(() => ({
12995
+ name: entityName,
12996
+ description: str(resolved?.description),
12997
+ states: entityStates,
12998
+ currentState,
12999
+ transitions: transitions.map((t2) => ({
13000
+ from: t2.from,
13001
+ to: t2.to,
13002
+ event: t2.event,
13003
+ guardHint: t2.guardHint
13004
+ }))
13005
+ }), [entityName, resolved, entityStates, currentState, transitions]);
13006
+ const handleTest = useCallback(() => {
13007
+ if (isTesting) return;
13008
+ if (testEvent) emit(`UI:${testEvent}`, {});
13009
+ setIsTesting(true);
13010
+ setTestResults([]);
13011
+ const results = [];
13012
+ let testIdx = 0;
13013
+ const runNextTest = () => {
13014
+ if (testIdx >= testCases.length) {
13015
+ const allPassed = results.every((r) => r.passed);
13016
+ setIsTesting(false);
13017
+ setTestResults(results);
13018
+ if (allPassed && completeEvent) {
13019
+ emit(`UI:${completeEvent}`, {
13020
+ success: true,
13021
+ passedTests: results.filter((r) => r.passed).length
13022
+ });
13023
+ }
13024
+ return;
13025
+ }
13026
+ const testCase = testCases[testIdx];
13027
+ if (!testCase) return;
13028
+ let state = initialState;
13029
+ for (const event of testCase.events) {
13030
+ const trans = transitions.find((t2) => t2.from === state && t2.event === event);
13031
+ if (trans) {
13032
+ state = trans.to;
13033
+ }
13034
+ }
13035
+ setCurrentState(state);
13036
+ results.push({
13037
+ label: testCase.label,
13038
+ passed: state === testCase.expectedState,
13039
+ actualState: state,
13040
+ expectedState: testCase.expectedState
13041
+ });
13042
+ testIdx++;
13043
+ timerRef.current = setTimeout(runNextTest, stepDurationMs);
13044
+ };
13045
+ timerRef.current = setTimeout(runNextTest, stepDurationMs);
13046
+ }, [isTesting, transitions, testCases, initialState, stepDurationMs, testEvent, completeEvent, emit]);
13047
+ const handleTryAgain = useCallback(() => {
13048
+ if (timerRef.current) clearTimeout(timerRef.current);
13049
+ setIsTesting(false);
13050
+ setCurrentState(initialState);
13051
+ setTestResults([]);
13052
+ }, [initialState]);
13053
+ const handleReset = useCallback(() => {
13054
+ if (timerRef.current) clearTimeout(timerRef.current);
13055
+ setIsTesting(false);
13056
+ setCurrentState(initialState);
13057
+ setTestResults([]);
13058
+ setVariables([...entityVariables]);
13059
+ setSelectedState(null);
13060
+ setAddingFrom(null);
13061
+ if (playAgainEvent) emit(`UI:${playAgainEvent}`, {});
13062
+ }, [initialState, entityVariables, playAgainEvent, emit]);
13063
+ const codeData = useMemo(() => ({
13064
+ name: entityName,
13065
+ states: entityStates,
13066
+ initialState,
13067
+ transitions: transitions.map((t2) => ({
13068
+ from: t2.from,
13069
+ to: t2.to,
13070
+ event: t2.event,
13071
+ ...t2.guardHint ? { guard: t2.guardHint } : {}
13072
+ }))
13073
+ }), [entityName, entityStates, initialState, transitions]);
13074
+ if (!resolved) return null;
13075
+ const theme = resolved.theme ?? void 0;
13076
+ const themeBackground = theme?.background;
13077
+ const headerImage = str(resolved.headerImage);
13078
+ const hint = str(resolved.hint);
13079
+ return /* @__PURE__ */ jsxs(
13080
+ VStack,
13081
+ {
13082
+ className: cn("p-4 gap-6", className),
13083
+ style: {
13084
+ backgroundImage: themeBackground ? `url(${themeBackground})` : void 0,
13085
+ backgroundSize: "cover",
13086
+ backgroundPosition: "center"
13087
+ },
13088
+ children: [
13089
+ headerImage && !headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsx("img", { src: headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : headerImage && headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
13090
+ /* @__PURE__ */ jsxs(VStack, { gap: "xs", children: [
13091
+ /* @__PURE__ */ jsx(Typography, { variant: "h4", className: "text-foreground", children: str(resolved.title) }),
13092
+ /* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-muted-foreground", children: str(resolved.description) }),
13093
+ /* @__PURE__ */ jsxs(HStack, { className: "items-center p-2 rounded bg-warning/10 border border-warning/30", gap: "xs", children: [
13094
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-warning font-bold", children: t("game.hint") + ":" }),
13095
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-foreground", children: hint })
13096
+ ] })
13097
+ ] }),
13098
+ /* @__PURE__ */ jsxs(HStack, { className: "flex-wrap items-start", gap: "lg", children: [
13099
+ /* @__PURE__ */ jsxs(VStack, { gap: "sm", className: "flex-1 min-w-[300px]", children: [
13100
+ /* @__PURE__ */ jsxs(HStack, { className: "items-center justify-between", children: [
13101
+ /* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-muted-foreground font-medium", children: t("stateArchitect.graph") }),
13102
+ addingFrom && /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-accent animate-pulse", children: t("stateArchitect.clickTarget", { state: addingFrom || "" }) })
13103
+ ] }),
13104
+ /* @__PURE__ */ jsxs(
13105
+ Box,
13106
+ {
13107
+ position: "relative",
13108
+ className: "rounded-container border border-border bg-background overflow-hidden",
13109
+ style: { width: GRAPH_W, height: GRAPH_H },
13110
+ children: [
13111
+ /* @__PURE__ */ jsxs(
13112
+ "svg",
13113
+ {
13114
+ width: GRAPH_W,
13115
+ height: GRAPH_H,
13116
+ className: "absolute inset-0",
13117
+ style: { pointerEvents: "none" },
13118
+ children: [
13119
+ /* @__PURE__ */ jsxs("defs", { children: [
13120
+ /* @__PURE__ */ jsx("marker", { id: "arrowhead", markerWidth: "10", markerHeight: "7", refX: "10", refY: "3.5", orient: "auto", children: /* @__PURE__ */ jsx("polygon", { points: "0 0, 10 3.5, 0 7", fill: "var(--color-border)" }) }),
13121
+ /* @__PURE__ */ jsx("marker", { id: "arrowhead-active", markerWidth: "10", markerHeight: "7", refX: "10", refY: "3.5", orient: "auto", children: /* @__PURE__ */ jsx("polygon", { points: "0 0, 10 3.5, 0 7", fill: "var(--color-primary)" }) })
13122
+ ] }),
13123
+ transitions.map((t2) => {
13124
+ const fromPos = positions[t2.from];
13125
+ const toPos = positions[t2.to];
13126
+ if (!fromPos || !toPos) return null;
13127
+ const isActive = t2.from === currentState;
13128
+ return /* @__PURE__ */ jsx(
13129
+ TransitionArrow,
13130
+ {
13131
+ from: fromPos,
13132
+ to: toPos,
13133
+ eventLabel: t2.event,
13134
+ guardHint: t2.guardHint,
13135
+ isActive
13136
+ },
13137
+ t2.id
13138
+ );
13139
+ })
13140
+ ]
13141
+ }
13142
+ ),
13143
+ entityStates.map((state) => /* @__PURE__ */ jsx(
13144
+ StateNode,
13145
+ {
13146
+ name: state,
13147
+ position: positions[state],
13148
+ isCurrent: state === currentState,
13149
+ isSelected: state === selectedState,
13150
+ isInitial: state === initialState,
13151
+ onClick: () => handleStateClick(state)
13152
+ },
13153
+ state
13154
+ ))
13155
+ ]
13156
+ }
13157
+ ),
13158
+ !isTesting && /* @__PURE__ */ jsx(HStack, { gap: "sm", children: /* @__PURE__ */ jsx(
13159
+ Button,
13160
+ {
13161
+ variant: "ghost",
13162
+ onClick: handleStartAddTransition,
13163
+ disabled: !selectedState,
13164
+ children: selectedState ? t("stateArchitect.addTransition", { state: selectedState }) : t("stateArchitect.addTransitionPrompt")
13165
+ }
13166
+ ) }),
13167
+ transitions.length > 0 && /* @__PURE__ */ jsxs(VStack, { gap: "xs", className: "p-3 rounded-container bg-muted/50 border border-border", children: [
13168
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground font-medium", children: t("stateArchitect.transitions", { count: transitions.length }) + ":" }),
13169
+ transitions.map((t2) => /* @__PURE__ */ jsxs(HStack, { className: "items-center text-xs", gap: "xs", children: [
13170
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-foreground", children: t2.from }),
13171
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: "\u2014[" }),
13172
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-accent font-medium", children: t2.event }),
13173
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: "]\u2192" }),
13174
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-success", children: t2.to }),
13175
+ t2.guardHint && /* @__PURE__ */ jsxs(Typography, { variant: "caption", className: "text-warning", children: [
13176
+ "(",
13177
+ t2.guardHint,
13178
+ ")"
13179
+ ] }),
13180
+ !isTesting && /* @__PURE__ */ jsx(
13181
+ Button,
13182
+ {
13183
+ variant: "ghost",
13184
+ onClick: () => handleRemoveTransition(t2.id),
13185
+ className: "text-xs ml-auto",
13186
+ children: "\xD7"
13187
+ }
13188
+ )
13189
+ ] }, t2.id))
13190
+ ] })
13191
+ ] }),
13192
+ /* @__PURE__ */ jsxs(VStack, { gap: "sm", className: "w-[280px] shrink-0", children: [
13193
+ /* @__PURE__ */ jsx(TraitStateViewer, { trait: machine, variant: "full", size: "sm" }),
13194
+ /* @__PURE__ */ jsx(
13195
+ VariablePanel,
13196
+ {
13197
+ entityName,
13198
+ variables
13199
+ }
13200
+ ),
13201
+ testResults.length > 0 && /* @__PURE__ */ jsxs(VStack, { className: "p-3 rounded-container bg-card border border-border", gap: "xs", children: [
13202
+ /* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-muted-foreground font-medium", children: t("stateArchitect.testResults") + ":" }),
13203
+ testResults.map((r, i) => /* @__PURE__ */ jsxs(HStack, { className: "items-center text-xs", gap: "xs", children: [
13204
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", className: r.passed ? "text-success" : "text-error", children: r.passed ? "\u2714" : "\u2717" }),
13205
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-foreground flex-1", children: r.label }),
13206
+ !r.passed && /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-error", children: t("stateArchitect.gotState", { state: r.actualState }) })
13207
+ ] }, i))
13208
+ ] }),
13209
+ resolved.showCodeView !== false && /* @__PURE__ */ jsx(StateJsonView, { data: codeData, label: "View Code" })
13210
+ ] })
13211
+ ] }),
13212
+ isSuccess && /* @__PURE__ */ jsx(Box, { className: "p-4 rounded-container bg-success/20 border border-success text-center", children: /* @__PURE__ */ jsx(Typography, { variant: "h5", className: "text-success", children: str(resolved.successMessage) || t("stateArchitect.allPassed") }) }),
13213
+ !isTesting && !isSuccess && testResults.some((r) => !r.passed) && /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
13214
+ /* @__PURE__ */ jsx(Box, { className: "p-4 rounded-container bg-warning/10 border border-warning/30 text-center", children: /* @__PURE__ */ jsx(Typography, { variant: "body1", className: "text-foreground font-medium", children: t(ENCOURAGEMENT_KEYS3[Math.min(attempts - 1, ENCOURAGEMENT_KEYS3.length - 1)] ?? ENCOURAGEMENT_KEYS3[0]) }) }),
13215
+ !isSuccess && attempts >= 2 && Boolean(str(resolved?.hint)) && /* @__PURE__ */ jsx(Box, { className: "p-3 rounded-container bg-accent/10 border border-accent/30", children: /* @__PURE__ */ jsxs(HStack, { className: "items-start", gap: "xs", children: [
13216
+ /* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-accent font-bold shrink-0", children: "\u{1F4A1} " + t("game.hint") + ":" }),
13217
+ /* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-foreground", children: hint })
13218
+ ] }) })
13219
+ ] }),
13220
+ /* @__PURE__ */ jsxs(HStack, { gap: "sm", children: [
13221
+ !isTesting && !isSuccess && testResults.some((r) => !r.passed) ? /* @__PURE__ */ jsx(Button, { variant: "primary", onClick: handleTryAgain, children: "\u{1F504} " + t("puzzle.tryAgainButton") }) : /* @__PURE__ */ jsx(
13222
+ Button,
13223
+ {
13224
+ variant: "primary",
13225
+ onClick: handleTest,
13226
+ disabled: isTesting,
13227
+ children: "\u25B6 " + t("game.runTests")
13228
+ }
13229
+ ),
13230
+ /* @__PURE__ */ jsx(Button, { variant: "ghost", onClick: handleReset, children: "\u21BA " + t("game.reset") })
13231
+ ] })
13232
+ ]
13233
+ }
13234
+ );
13235
+ }
13236
+ var ENCOURAGEMENT_KEYS3, nextTransId;
13237
+ var init_StateArchitectBoard = __esm({
13238
+ "components/game/2d/organisms/StateArchitectBoard.tsx"() {
13239
+ init_atoms();
13240
+ init_cn();
13241
+ init_useEventBus();
13242
+ init_TraitStateViewer();
13243
+ init_StateNode();
13244
+ init_TransitionArrow();
13245
+ init_VariablePanel();
13246
+ init_StateJsonView();
13247
+ init_boardEntity();
13248
+ ENCOURAGEMENT_KEYS3 = [
13249
+ "puzzle.tryAgain1",
13250
+ "puzzle.tryAgain2",
13251
+ "puzzle.tryAgain3"
13252
+ ];
13253
+ nextTransId = 100;
13254
+ StateArchitectBoard.displayName = "StateArchitectBoard";
13255
+ }
13256
+ });
13257
+ function readSimulatorParameters(v) {
13258
+ if (!Array.isArray(v)) return [];
13259
+ const result = [];
13260
+ for (const item of v) {
13261
+ if (typeof item === "object" && item !== null && !Array.isArray(item) && !(item instanceof Date)) {
13262
+ const param = item;
13263
+ if ("id" in item && "label" in item && "unit" in item && "min" in item && "max" in item && "step" in item) {
13264
+ result.push({
13265
+ id: str(param.id),
13266
+ label: str(param.label),
13267
+ unit: str(param.unit),
13268
+ min: num(param.min),
13269
+ max: num(param.max),
13270
+ step: num(param.step),
13271
+ initial: num(param.initial),
13272
+ correct: num(param.correct),
13273
+ tolerance: num(param.tolerance)
13274
+ });
13275
+ }
13276
+ }
13277
+ }
13278
+ return result;
13279
+ }
13280
+ function SimulatorBoard({
13281
+ entity,
13282
+ completeEvent = "PUZZLE_COMPLETE",
13283
+ setAEvent,
13284
+ setBEvent,
13285
+ checkEvent,
13286
+ playAgainEvent,
13287
+ assetManifest,
13288
+ className
13289
+ }) {
13290
+ const ui = assetManifest?.ui;
13291
+ const { emit } = useEventBus();
13292
+ const { t } = useTranslate();
13293
+ const resolved = boardEntity(entity);
13294
+ const parameters = readSimulatorParameters(resolved?.parameters);
13295
+ const [headerError, setHeaderError] = useState(false);
13296
+ if (!resolved) return null;
13297
+ const paramA = num(resolved.paramA);
13298
+ const paramB = num(resolved.paramB);
13299
+ const output = num(resolved.output);
13300
+ const targetValue = num(resolved.target);
13301
+ const targetTolerance = num(resolved.tolerance);
13302
+ const attempts = num(resolved.attempts);
13303
+ const result = str(resolved.result);
13304
+ const isWin = result === "win";
13305
+ const isComplete = result !== "none" && result !== "";
13306
+ const paramAValue = parameters[0];
13307
+ const paramBValue = parameters[1];
13308
+ const sliderValues = [paramA, paramB];
13309
+ const sliderEvents = [setAEvent, setBEvent];
13310
+ const handleParameterChange = (index, value) => {
13311
+ if (isComplete) return;
13312
+ const ev = sliderEvents[index];
13313
+ if (ev) emit(`UI:${ev}`, { value });
13314
+ };
13315
+ const handleCheck = () => {
13316
+ if (checkEvent) emit(`UI:${checkEvent}`, {});
13317
+ };
13318
+ const handlePlayAgain = () => {
13319
+ if (playAgainEvent) emit(`UI:${playAgainEvent}`, {});
13320
+ };
13321
+ const themeBackground = (() => {
13322
+ const t2 = resolved.theme;
13323
+ if (typeof t2 === "object" && t2 !== null && !Array.isArray(t2) && !(t2 instanceof Date)) {
13324
+ const bg = t2.background;
13325
+ return str(bg);
13326
+ }
13327
+ return "";
13328
+ })();
13329
+ const headerImage = str(resolved.headerImage);
13330
+ const hint = str(resolved.hint);
13331
+ const showHint = isComplete && !isWin && attempts >= 2 && Boolean(hint);
13332
+ const outputLabel = str(resolved.outputLabel);
13333
+ const outputUnit = str(resolved.outputUnit);
13334
+ return /* @__PURE__ */ jsx(
13335
+ Box,
13336
+ {
13337
+ className,
13338
+ style: {
13339
+ backgroundImage: themeBackground ? `url(${themeBackground})` : void 0,
13340
+ backgroundSize: "cover",
13341
+ backgroundPosition: "center"
13342
+ },
13343
+ children: /* @__PURE__ */ jsxs(VStack, { gap: "lg", className: "p-4", children: [
13344
+ headerImage && !headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsx("img", { src: headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : headerImage && headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
13345
+ /* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
13346
+ /* @__PURE__ */ jsx(Typography, { variant: "h4", weight: "bold", children: str(resolved.title) }),
13347
+ /* @__PURE__ */ jsx(Typography, { variant: "body", children: str(resolved.description) })
13348
+ ] }) }),
13349
+ /* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "md", children: [
13350
+ /* @__PURE__ */ jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: t("simulator.parameters") }),
13351
+ [paramAValue, paramBValue].map(
13352
+ (param, index) => param ? /* @__PURE__ */ jsxs(VStack, { gap: "xs", children: [
13353
+ /* @__PURE__ */ jsxs(HStack, { justify: "between", align: "center", children: [
13354
+ /* @__PURE__ */ jsx(Typography, { variant: "body", weight: "medium", children: param.label }),
13355
+ /* @__PURE__ */ jsxs(Badge, { size: "sm", children: [
13356
+ sliderValues[index],
13357
+ " ",
13358
+ param.unit
13359
+ ] })
13360
+ ] }),
13361
+ /* @__PURE__ */ jsx(
13362
+ "input",
13363
+ {
13364
+ type: "range",
13365
+ min: param.min,
13366
+ max: param.max,
13367
+ step: param.step,
13368
+ value: sliderValues[index],
13369
+ onChange: (e) => handleParameterChange(index, Number(e.target.value)),
13370
+ disabled: isComplete,
13371
+ className: "w-full accent-foreground"
13372
+ }
13373
+ ),
13374
+ /* @__PURE__ */ jsxs(HStack, { justify: "between", children: [
13375
+ /* @__PURE__ */ jsxs(Typography, { variant: "caption", className: "text-muted-foreground", children: [
13376
+ param.min,
13377
+ " ",
13378
+ param.unit
13379
+ ] }),
13380
+ /* @__PURE__ */ jsxs(Typography, { variant: "caption", className: "text-muted-foreground", children: [
13381
+ param.max,
13382
+ " ",
13383
+ param.unit
13384
+ ] })
13385
+ ] })
13386
+ ] }, param.id ?? index) : null
13387
+ )
13388
+ ] }) }),
13389
+ /* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", children: [
13390
+ /* @__PURE__ */ jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: outputLabel }),
13391
+ /* @__PURE__ */ jsxs(Typography, { variant: "h3", weight: "bold", children: [
13392
+ output.toFixed(2),
13393
+ " ",
13394
+ outputUnit
13395
+ ] }),
13396
+ isComplete && /* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
13397
+ /* @__PURE__ */ jsx(
13398
+ GameIcon,
13399
+ {
13400
+ icon: isWin ? CheckCircle : XCircle,
13401
+ assetUrl: isWin ? ui?.["correct"] : ui?.["incorrect"],
13402
+ size: "sm",
13403
+ className: isWin ? "text-success" : "text-error"
13404
+ }
13405
+ ),
13406
+ /* @__PURE__ */ jsx(Typography, { variant: "body", className: isWin ? "text-success" : "text-error", children: isWin ? str(resolved.successMessage) || t("simulator.correct") : str(resolved.failMessage) || t("simulator.incorrect") })
13407
+ ] }),
13408
+ /* @__PURE__ */ jsxs(Typography, { variant: "caption", className: "text-muted-foreground", children: [
13409
+ t("simulator.target"),
13410
+ ": ",
13411
+ targetValue,
13412
+ " ",
13413
+ outputUnit,
13414
+ " (\xB1",
13415
+ targetTolerance,
13416
+ ")"
13417
+ ] })
13418
+ ] }) }),
13419
+ showHint && hint && /* @__PURE__ */ jsx(Card, { className: "p-4 border-l-4 border-l-warning", children: /* @__PURE__ */ jsx(Typography, { variant: "body", children: hint }) }),
13420
+ /* @__PURE__ */ jsxs(HStack, { gap: "sm", justify: "center", children: [
13421
+ !isComplete ? /* @__PURE__ */ jsxs(Button, { variant: "primary", onClick: handleCheck, children: [
13422
+ /* @__PURE__ */ jsx(GameIcon, { icon: Play, assetUrl: ui?.["play"], size: "sm" }),
13423
+ t("simulator.simulate")
13424
+ ] }) : null,
13425
+ /* @__PURE__ */ jsxs(Button, { variant: "secondary", onClick: handlePlayAgain, children: [
13426
+ /* @__PURE__ */ jsx(GameIcon, { icon: RotateCcw, assetUrl: ui?.["reset"], size: "sm" }),
13427
+ t("simulator.reset")
13428
+ ] })
13429
+ ] })
13430
+ ] })
13431
+ }
13432
+ );
13433
+ }
13434
+ var init_SimulatorBoard = __esm({
13435
+ "components/game/2d/organisms/SimulatorBoard.tsx"() {
13436
+ init_atoms();
13437
+ init_useEventBus();
13438
+ init_boardEntity();
13439
+ init_GameIcon();
13440
+ SimulatorBoard.displayName = "SimulatorBoard";
13441
+ }
13442
+ });
13443
+ function ClassifierBoard({
13444
+ entity,
13445
+ completeEvent = "PUZZLE_COMPLETE",
13446
+ assignEvent,
13447
+ checkEvent,
13448
+ playAgainEvent,
13449
+ assetManifest,
13450
+ className
13451
+ }) {
13452
+ const ui = assetManifest?.ui;
13453
+ const { emit } = useEventBus();
13454
+ const { t } = useTranslate();
13455
+ const resolved = boardEntity(entity);
13456
+ const [headerError, setHeaderError] = useState(false);
13457
+ const items = rows(resolved?.items);
13458
+ const categories = rows(resolved?.categories);
13459
+ const result = str(resolved?.result);
13460
+ const submitted = result === "win";
13461
+ const attempts = num(resolved?.attempts);
13462
+ const assignments = items.reduce((acc, item) => {
13463
+ if (item.assignedCategory != null && item.assignedCategory !== "") acc[item.id] = item.assignedCategory;
13464
+ return acc;
13465
+ }, {});
13466
+ const unassignedItems = items.filter((item) => !assignments[item.id]);
13467
+ const allAssigned = items.length > 0 && Object.keys(assignments).length === items.length;
13468
+ const results = submitted ? items.map((item) => ({
13469
+ item,
13470
+ assigned: assignments[item.id],
13471
+ correct: assignments[item.id] === item.correctCategory
13472
+ })) : [];
13473
+ const allCorrect = result === "win";
13474
+ const correctCount = results.filter((r) => r.correct).length;
13475
+ const showHint = attempts >= 2 && Boolean(str(resolved?.hint));
13476
+ const handleAssign = (itemId, categoryId) => {
13477
+ if (submitted) return;
13478
+ if (assignEvent) emit(`UI:${assignEvent}`, { itemId, categoryId });
13479
+ };
13480
+ const handleUnassign = (itemId) => {
13481
+ if (submitted) return;
13482
+ if (assignEvent) emit(`UI:${assignEvent}`, { itemId, categoryId: "" });
13483
+ };
13484
+ const handleSubmit = () => {
13485
+ if (checkEvent) emit(`UI:${checkEvent}`, {});
13486
+ if (allAssigned && items.every((item) => assignments[item.id] === item.correctCategory)) {
13487
+ emit(`UI:${completeEvent}`, { success: true, attempts: attempts + 1 });
13488
+ }
13489
+ };
13490
+ const handleFullReset = () => {
13491
+ if (playAgainEvent) emit(`UI:${playAgainEvent}`, {});
13492
+ };
13493
+ if (!resolved) return null;
13494
+ const theme = resolved.theme ?? void 0;
13495
+ const themeBackground = theme?.background;
13496
+ const headerImage = str(resolved.headerImage);
13497
+ const hint = str(resolved.hint);
13498
+ const failMessage = str(resolved.failMessage);
13499
+ return /* @__PURE__ */ jsx(
13500
+ Box,
13501
+ {
13502
+ className,
13503
+ style: {
13504
+ backgroundImage: themeBackground ? `url(${themeBackground})` : void 0,
13505
+ backgroundSize: "cover",
13506
+ backgroundPosition: "center"
13507
+ },
13508
+ children: /* @__PURE__ */ jsxs(VStack, { gap: "lg", className: "p-4", children: [
13509
+ headerImage && !headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsx("img", { src: headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : headerImage && headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
13510
+ /* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
13511
+ /* @__PURE__ */ jsx(Typography, { variant: "h4", weight: "bold", children: str(resolved.title) }),
13512
+ /* @__PURE__ */ jsx(Typography, { variant: "body", children: str(resolved.description) })
13513
+ ] }) }),
13514
+ unassignedItems.length > 0 && /* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
13515
+ /* @__PURE__ */ jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: t("classifier.itemsToSort") }),
13516
+ /* @__PURE__ */ jsx(HStack, { gap: "sm", className: "flex-wrap", children: unassignedItems.map((item) => /* @__PURE__ */ jsxs(Badge, { size: "md", className: "cursor-pointer", children: [
13517
+ item.iconUrl && /* @__PURE__ */ jsx("img", { src: item.iconUrl, alt: "", className: "w-4 h-4 object-contain inline-block" }),
13518
+ item.label
13519
+ ] }, item.id)) })
13520
+ ] }) }),
13521
+ /* @__PURE__ */ jsx(VStack, { gap: "md", children: categories.map((cat) => {
13522
+ const catItems = items.filter((item) => assignments[item.id] === cat.id);
13523
+ return /* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
13524
+ cat.imageUrl && /* @__PURE__ */ jsx(Box, { className: "w-full h-16 overflow-hidden rounded-container", children: /* @__PURE__ */ jsx("img", { src: cat.imageUrl, alt: "", className: "w-full h-full object-cover" }) }),
13525
+ /* @__PURE__ */ jsxs(HStack, { justify: "between", align: "center", children: [
13526
+ /* @__PURE__ */ jsx(Typography, { variant: "body", weight: "bold", children: cat.label }),
13527
+ /* @__PURE__ */ jsx(Badge, { size: "sm", children: catItems.length })
13528
+ ] }),
13529
+ /* @__PURE__ */ jsx(HStack, { gap: "xs", className: "flex-wrap min-h-[2rem]", children: catItems.map((item) => {
13530
+ const result2 = results.find((r) => r.item.id === item.id);
13531
+ return /* @__PURE__ */ jsxs(
13532
+ Badge,
13533
+ {
13534
+ size: "sm",
13535
+ className: `cursor-pointer ${result2 ? result2.correct ? "border-success bg-success/10" : "border-error bg-error/10" : ""}`,
13536
+ onClick: () => handleUnassign(item.id),
13537
+ children: [
13538
+ item.iconUrl && /* @__PURE__ */ jsx("img", { src: item.iconUrl, alt: "", className: "w-3 h-3 object-contain inline-block" }),
13539
+ item.label,
13540
+ result2 && /* @__PURE__ */ jsx(
13541
+ GameIcon,
13542
+ {
13543
+ icon: result2.correct ? CheckCircle : XCircle,
13544
+ assetUrl: result2.correct ? ui?.["correct"] : ui?.["incorrect"],
13545
+ size: "sm",
13546
+ className: result2.correct ? "text-success" : "text-error"
13547
+ }
13548
+ )
13549
+ ]
13550
+ },
13551
+ item.id
13552
+ );
13553
+ }) }),
13554
+ !submitted && unassignedItems.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", className: "flex-wrap", children: unassignedItems.map((item) => /* @__PURE__ */ jsxs(
13555
+ Button,
13556
+ {
13557
+ size: "sm",
13558
+ variant: "ghost",
13559
+ onClick: () => handleAssign(item.id, cat.id),
13560
+ className: "text-xs opacity-50 hover:opacity-100",
13561
+ children: [
13562
+ "+ ",
13563
+ item.label
13564
+ ]
13565
+ },
13566
+ item.id
13567
+ )) })
13568
+ ] }) }, cat.id);
13569
+ }) }),
13570
+ submitted && /* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", children: [
13571
+ /* @__PURE__ */ jsx(
13572
+ GameIcon,
13573
+ {
13574
+ icon: allCorrect ? CheckCircle : XCircle,
13575
+ assetUrl: allCorrect ? ui?.["correct"] : ui?.["incorrect"],
13576
+ size: "lg",
13577
+ className: allCorrect ? "text-success" : "text-error"
13578
+ }
13579
+ ),
13580
+ /* @__PURE__ */ jsx(Typography, { variant: "body", weight: "bold", children: allCorrect ? str(resolved.successMessage) || t("classifier.allCorrect") : `${correctCount}/${items.length} ${t("classifier.correct")}` }),
13581
+ !allCorrect && failMessage && /* @__PURE__ */ jsx(Typography, { variant: "body", className: "text-muted-foreground", children: failMessage })
13582
+ ] }) }),
13583
+ showHint && hint && /* @__PURE__ */ jsx(Card, { className: "p-4 border-l-4 border-l-warning", children: /* @__PURE__ */ jsx(Typography, { variant: "body", children: hint }) }),
13584
+ /* @__PURE__ */ jsxs(HStack, { gap: "sm", justify: "center", children: [
13585
+ !submitted && /* @__PURE__ */ jsxs(Button, { variant: "primary", onClick: handleSubmit, disabled: !allAssigned, children: [
13586
+ /* @__PURE__ */ jsx(GameIcon, { icon: Send, assetUrl: ui?.["send"], size: "sm" }),
13587
+ t("classifier.check")
13588
+ ] }),
13589
+ /* @__PURE__ */ jsxs(Button, { variant: "secondary", onClick: handleFullReset, children: [
13590
+ /* @__PURE__ */ jsx(GameIcon, { icon: RotateCcw, assetUrl: ui?.["reset"], size: "sm" }),
13591
+ t("classifier.reset")
13592
+ ] })
13593
+ ] })
13594
+ ] })
13595
+ }
13596
+ );
13597
+ }
13598
+ var init_ClassifierBoard = __esm({
13599
+ "components/game/2d/organisms/ClassifierBoard.tsx"() {
13600
+ init_atoms();
13601
+ init_useEventBus();
13602
+ init_boardEntity();
13603
+ init_GameIcon();
13604
+ ClassifierBoard.displayName = "ClassifierBoard";
13605
+ }
13606
+ });
13607
+ function BuilderBoard({
13608
+ entity,
13609
+ completeEvent = "PUZZLE_COMPLETE",
13610
+ placeEvent,
13611
+ checkEvent,
13612
+ playAgainEvent,
13613
+ assetManifest,
13614
+ className
13615
+ }) {
13616
+ const ui = assetManifest?.ui;
13617
+ const { emit } = useEventBus();
13618
+ const { t } = useTranslate();
13619
+ const resolved = boardEntity(entity);
13620
+ const [headerError, setHeaderError] = useState(false);
13621
+ const [selectedComponent, setSelectedComponent] = useState(null);
13622
+ const components = rows(resolved?.components).map((r) => ({
13623
+ id: str(r.id),
13624
+ label: str(r.label),
13625
+ description: str(r.description) || void 0,
13626
+ iconEmoji: str(r.iconEmoji) || void 0,
13627
+ iconUrl: str(r.iconUrl) || void 0,
13628
+ category: str(r.category) || void 0
13629
+ }));
13630
+ const slots = rows(resolved?.slots).map((r) => ({
13631
+ id: str(r.id),
13632
+ label: str(r.label) || void 0,
13633
+ description: str(r.description) || void 0,
13634
+ requiredComponentId: str(r.requiredComponentId),
13635
+ placedComponentId: str(r.placedComponentId) || void 0
13636
+ }));
13637
+ const placements = {};
13638
+ for (const slot of slots) {
13639
+ if (slot.placedComponentId) placements[slot.id] = slot.placedComponentId;
13640
+ }
13641
+ const attempts = num(resolved?.attempts);
13642
+ const result = str(resolved?.result) || "none";
13643
+ const submitted = result === "win";
13644
+ const usedComponentIds = new Set(Object.values(placements));
13645
+ const availableComponents = components.filter((c) => !usedComponentIds.has(c.id));
13646
+ const allPlaced = slots.length > 0 && slots.every((s) => Boolean(placements[s.id]));
13647
+ const results = submitted ? slots.map((slot) => ({
13648
+ slot,
13649
+ placed: placements[slot.id],
13650
+ correct: placements[slot.id] === slot.requiredComponentId
13651
+ })) : [];
13652
+ const showHint = attempts >= 2 && Boolean(str(resolved?.hint));
13653
+ const handlePlaceComponent = (slotId) => {
13654
+ if (submitted || !selectedComponent) return;
13655
+ if (placeEvent) emit(`UI:${placeEvent}`, { slotId, componentId: selectedComponent });
13656
+ setSelectedComponent(null);
13657
+ };
13658
+ const handleRemoveFromSlot = (slotId) => {
13659
+ if (submitted) return;
13660
+ if (placeEvent) emit(`UI:${placeEvent}`, { slotId, componentId: "" });
13661
+ };
13662
+ const handleSubmit = () => {
13663
+ if (checkEvent) emit(`UI:${checkEvent}`, {});
13664
+ const solved = slots.length > 0 && slots.every((s) => placements[s.id] === s.requiredComponentId);
13665
+ if (solved && completeEvent) {
13666
+ emit(`UI:${completeEvent}`, { success: true, attempts: attempts + 1 });
13667
+ }
13668
+ };
13669
+ const handlePlayAgain = () => {
13670
+ setSelectedComponent(null);
13671
+ if (playAgainEvent) emit(`UI:${playAgainEvent}`, {});
13672
+ };
13673
+ const getComponentById = (id) => components.find((c) => c.id === id);
13674
+ if (!resolved) return null;
13675
+ const theme = resolved.theme ?? void 0;
13676
+ const themeBackground = theme?.background;
13677
+ const headerImage = str(resolved.headerImage);
13678
+ const hint = str(resolved.hint);
13679
+ return /* @__PURE__ */ jsx(
13680
+ Box,
13681
+ {
13682
+ className,
13683
+ style: {
13684
+ backgroundImage: themeBackground ? `url(${themeBackground})` : void 0,
13685
+ backgroundSize: "cover",
13686
+ backgroundPosition: "center"
13687
+ },
13688
+ children: /* @__PURE__ */ jsxs(VStack, { gap: "lg", className: "p-4", children: [
13689
+ headerImage && !headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsx("img", { src: headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : headerImage && headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
13690
+ /* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
13691
+ /* @__PURE__ */ jsx(Typography, { variant: "h4", weight: "bold", children: str(resolved.title) }),
13692
+ /* @__PURE__ */ jsx(Typography, { variant: "body", children: str(resolved.description) })
13693
+ ] }) }),
13694
+ /* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
13695
+ /* @__PURE__ */ jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: t("builder.components") }),
13696
+ /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "flex-wrap", children: [
13697
+ availableComponents.map((comp) => /* @__PURE__ */ jsxs(
13698
+ Button,
13699
+ {
13700
+ size: "sm",
13701
+ variant: selectedComponent === comp.id ? "primary" : "secondary",
13702
+ onClick: () => setSelectedComponent(selectedComponent === comp.id ? null : comp.id),
13703
+ disabled: submitted,
13704
+ children: [
13705
+ comp.iconUrl ? /* @__PURE__ */ jsx("img", { src: comp.iconUrl, alt: "", className: "w-5 h-5 object-contain inline-block mr-1" }) : comp.iconEmoji ? /* @__PURE__ */ jsxs(Fragment, { children: [
13706
+ comp.iconEmoji,
13707
+ " "
13708
+ ] }) : null,
13709
+ comp.label
13710
+ ]
13711
+ },
13712
+ comp.id
13713
+ )),
13714
+ availableComponents.length === 0 && !submitted && /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: t("builder.allPlaced") })
13715
+ ] })
13716
+ ] }) }),
13717
+ /* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
13718
+ /* @__PURE__ */ jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: t("builder.blueprint") }),
13719
+ /* @__PURE__ */ jsx(VStack, { gap: "sm", children: slots.map((slot) => {
13720
+ const placedComp = placements[slot.id] ? getComponentById(placements[slot.id]) : null;
13721
+ const result2 = results.find((r) => r.slot.id === slot.id);
13722
+ return /* @__PURE__ */ jsxs(
13723
+ HStack,
13724
+ {
13725
+ gap: "sm",
13726
+ align: "center",
13727
+ className: `p-3 border-2 rounded ${result2 ? result2.correct ? "border-success" : "border-error" : selectedComponent ? "border-dashed border-foreground cursor-pointer" : "border-border"}`,
13728
+ onClick: () => handlePlaceComponent(slot.id),
13729
+ children: [
13730
+ /* @__PURE__ */ jsxs(VStack, { gap: "none", className: "flex-1", children: [
13731
+ /* @__PURE__ */ jsx(Typography, { variant: "body", weight: "medium", children: slot.label }),
13732
+ slot.description && /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: slot.description })
13733
+ ] }),
13734
+ placedComp ? /* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
13735
+ /* @__PURE__ */ jsxs(Badge, { size: "sm", onClick: () => handleRemoveFromSlot(slot.id), children: [
13736
+ placedComp.iconUrl ? /* @__PURE__ */ jsx("img", { src: placedComp.iconUrl, alt: "", className: "w-4 h-4 object-contain inline-block mr-1" }) : placedComp.iconEmoji ? /* @__PURE__ */ jsxs(Fragment, { children: [
13737
+ placedComp.iconEmoji,
13738
+ " "
13739
+ ] }) : null,
13740
+ placedComp.label
13741
+ ] }),
13742
+ result2 && /* @__PURE__ */ jsx(
13743
+ GameIcon,
13744
+ {
13745
+ icon: result2.correct ? CheckCircle : XCircle,
13746
+ assetUrl: result2.correct ? ui?.["correct"] : ui?.["incorrect"],
13747
+ size: "sm",
13748
+ className: result2.correct ? "text-success" : "text-error"
13749
+ }
13750
+ )
13751
+ ] }) : /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: t("builder.empty") })
13752
+ ]
13753
+ },
13754
+ slot.id
13755
+ );
13756
+ }) })
13757
+ ] }) }),
13758
+ submitted && /* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", children: [
13759
+ /* @__PURE__ */ jsx(GameIcon, { icon: CheckCircle, assetUrl: ui?.["correct"], size: "lg", className: "text-success" }),
13760
+ /* @__PURE__ */ jsx(Typography, { variant: "body", weight: "bold", children: str(resolved.successMessage) || t("builder.success") })
13761
+ ] }) }),
13762
+ showHint && hint && /* @__PURE__ */ jsx(Card, { className: "p-4 border-l-4 border-l-warning", children: /* @__PURE__ */ jsx(Typography, { variant: "body", children: hint }) }),
13763
+ /* @__PURE__ */ jsxs(HStack, { gap: "sm", justify: "center", children: [
13764
+ !submitted && /* @__PURE__ */ jsxs(Button, { variant: "primary", onClick: handleSubmit, disabled: !allPlaced, children: [
13765
+ /* @__PURE__ */ jsx(GameIcon, { icon: Wrench, assetUrl: ui?.["build"], size: "sm" }),
13766
+ t("builder.build")
13767
+ ] }),
13768
+ /* @__PURE__ */ jsxs(Button, { variant: "secondary", onClick: handlePlayAgain, children: [
13769
+ /* @__PURE__ */ jsx(GameIcon, { icon: RotateCcw, assetUrl: ui?.["reset"], size: "sm" }),
13770
+ t("builder.reset")
13771
+ ] })
13772
+ ] })
13773
+ ] })
13774
+ }
13775
+ );
13776
+ }
13777
+ var init_BuilderBoard = __esm({
13778
+ "components/game/2d/organisms/BuilderBoard.tsx"() {
13779
+ init_atoms();
13780
+ init_useEventBus();
13781
+ init_boardEntity();
13782
+ init_GameIcon();
13783
+ BuilderBoard.displayName = "BuilderBoard";
13784
+ }
13785
+ });
13786
+ function toDebuggerLine(v) {
13787
+ if (v === null || typeof v !== "object" || Array.isArray(v) || v instanceof Date) return null;
13788
+ const id = v["id"];
13789
+ const content = v["content"];
13790
+ const isBug = v["isBug"];
13791
+ if (typeof id !== "string" || typeof content !== "string" || typeof isBug !== "boolean") return null;
13792
+ const isFlagged = v["isFlagged"];
13793
+ const explanation = v["explanation"];
13794
+ return {
13795
+ id,
13796
+ content,
13797
+ isBug,
13798
+ isFlagged: typeof isFlagged === "boolean" ? isFlagged : void 0,
13799
+ explanation: typeof explanation === "string" ? explanation : void 0
13800
+ };
13801
+ }
13802
+ function DebuggerBoard({
13803
+ entity,
13804
+ completeEvent = "PUZZLE_COMPLETE",
13805
+ toggleFlagEvent,
13806
+ checkEvent,
13807
+ playAgainEvent,
13808
+ assetManifest,
13809
+ className
13810
+ }) {
13811
+ const ui = assetManifest?.ui;
13812
+ const { emit } = useEventBus();
13813
+ const { t } = useTranslate();
13814
+ const resolved = boardEntity(entity);
13815
+ const [headerError, setHeaderError] = useState(false);
13816
+ const lines = Array.isArray(resolved?.lines) ? resolved.lines.flatMap((v) => {
13817
+ const l = toDebuggerLine(v);
13818
+ return l ? [l] : [];
13819
+ }) : [];
13820
+ const result = str(resolved?.result) || "none";
13821
+ const attempts = num(resolved?.attempts);
13822
+ const submitted = result === "win";
13823
+ const showHint = !submitted && attempts >= 2 && Boolean(str(resolved?.hint));
13824
+ const bugLines = lines.filter((l) => l.isBug);
13825
+ const flaggedLines = lines.filter((l) => l.isFlagged);
13826
+ const correctFlags = lines.filter((l) => l.isBug && l.isFlagged);
13827
+ const falseFlags = lines.filter((l) => !l.isBug && l.isFlagged);
13828
+ const allCorrect = submitted;
13829
+ const toggleLine = (lineId) => {
13830
+ if (submitted) return;
13831
+ if (toggleFlagEvent) emit(`UI:${toggleFlagEvent}`, { lineId });
13832
+ };
13833
+ const handleSubmit = useCallback(() => {
13834
+ if (checkEvent) emit(`UI:${checkEvent}`, {});
13835
+ const correct = correctFlags.length === bugLines.length && falseFlags.length === 0;
13836
+ if (correct) emit(`UI:${completeEvent}`, { success: true, attempts: attempts + 1 });
13837
+ }, [checkEvent, correctFlags.length, bugLines.length, falseFlags.length, attempts, completeEvent, emit]);
13838
+ const handleReset = () => {
13839
+ if (playAgainEvent) emit(`UI:${playAgainEvent}`, {});
13840
+ };
13841
+ if (!resolved) return null;
13842
+ const theme = resolved.theme ?? void 0;
13843
+ const themeBackground = theme?.background;
13844
+ const headerImage = str(resolved.headerImage);
13845
+ const hint = str(resolved.hint);
13846
+ return /* @__PURE__ */ jsx(
13847
+ Box,
13848
+ {
13849
+ className,
13850
+ style: {
13851
+ backgroundImage: themeBackground ? `url(${themeBackground})` : void 0,
13852
+ backgroundSize: "cover",
13853
+ backgroundPosition: "center"
13854
+ },
13855
+ children: /* @__PURE__ */ jsxs(VStack, { gap: "lg", className: "p-4", children: [
13856
+ headerImage && !headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsx("img", { src: headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : headerImage && headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
13857
+ /* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
13858
+ /* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
13859
+ /* @__PURE__ */ jsx(GameIcon, { icon: Bug, assetUrl: ui?.["bug"], size: "sm" }),
13860
+ /* @__PURE__ */ jsx(Typography, { variant: "h4", weight: "bold", children: str(resolved.title) })
13861
+ ] }),
13862
+ /* @__PURE__ */ jsx(Typography, { variant: "body", children: str(resolved.description) }),
13863
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: t("debugger.findBugs", { count: String(lines.filter((l) => l.isBug).length) }) })
13864
+ ] }) }),
13865
+ /* @__PURE__ */ jsx(Card, { className: "p-0 overflow-hidden", children: /* @__PURE__ */ jsx(VStack, { gap: "none", children: lines.map((line, i) => {
13866
+ const isFlagged = !!line.isFlagged;
13867
+ let lineStyle = "";
13868
+ if (submitted) {
13869
+ if (line.isBug && isFlagged) lineStyle = "bg-success/10";
13870
+ else if (line.isBug && !isFlagged) lineStyle = "bg-warning/10";
13871
+ else if (!line.isBug && isFlagged) lineStyle = "bg-error/10";
13872
+ } else if (isFlagged) {
13873
+ lineStyle = "bg-error/10";
13874
+ }
13875
+ return /* @__PURE__ */ jsxs(
13876
+ HStack,
13877
+ {
13878
+ gap: "none",
13879
+ align: "stretch",
13880
+ className: `border-b border-border cursor-pointer hover:bg-muted ${lineStyle}`,
13881
+ onClick: () => toggleLine(line.id),
13882
+ children: [
13883
+ /* @__PURE__ */ jsx(Box, { className: "w-10 flex-shrink-0 flex items-center justify-center border-r border-border text-muted-foreground", children: /* @__PURE__ */ jsx(Typography, { variant: "caption", children: i + 1 }) }),
13884
+ /* @__PURE__ */ jsx(Box, { className: "flex-1 px-3 py-1.5 font-mono text-sm whitespace-pre", children: /* @__PURE__ */ jsx(Typography, { variant: "body", className: "font-mono text-sm", children: line.content }) }),
13885
+ /* @__PURE__ */ jsxs(Box, { className: "w-8 flex-shrink-0 flex items-center justify-center", children: [
13886
+ isFlagged && /* @__PURE__ */ jsx(GameIcon, { icon: Bug, assetUrl: ui?.["bug"], size: "sm", className: "text-error" }),
13887
+ submitted && line.isBug && !isFlagged && /* @__PURE__ */ jsx(GameIcon, { icon: Bug, assetUrl: ui?.["bug"], size: "sm", className: "text-warning" })
13888
+ ] })
13889
+ ]
13890
+ },
13891
+ line.id
13892
+ );
13893
+ }) }) }),
13894
+ submitted && /* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
13895
+ /* @__PURE__ */ jsx(Typography, { variant: "body", weight: "bold", children: allCorrect ? str(resolved.successMessage) || t("debugger.allFound") : `${correctFlags.length}/${bugLines.length} ${t("debugger.bugsFound")}` }),
13896
+ bugLines.map((line) => /* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "start", children: [
13897
+ /* @__PURE__ */ jsx(
13898
+ GameIcon,
13899
+ {
13900
+ icon: line.isFlagged ? CheckCircle : XCircle,
13901
+ assetUrl: line.isFlagged ? ui?.["correct"] : ui?.["incorrect"],
13902
+ size: "sm",
13903
+ className: line.isFlagged ? "text-success mt-0.5" : "text-warning mt-0.5"
13904
+ }
13905
+ ),
13906
+ /* @__PURE__ */ jsxs(VStack, { gap: "none", children: [
13907
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", weight: "bold", className: "font-mono", children: line.content.trim() }),
13908
+ line.explanation && /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: line.explanation })
13909
+ ] })
13910
+ ] }, line.id))
13911
+ ] }) }),
13912
+ showHint && hint && /* @__PURE__ */ jsx(Card, { className: "p-4 border-l-4 border-l-warning", children: /* @__PURE__ */ jsx(Typography, { variant: "body", children: hint }) }),
13913
+ /* @__PURE__ */ jsxs(HStack, { gap: "sm", justify: "center", children: [
13914
+ !submitted && /* @__PURE__ */ jsxs(Button, { variant: "primary", onClick: handleSubmit, disabled: flaggedLines.length === 0, children: [
13915
+ /* @__PURE__ */ jsx(GameIcon, { icon: Send, assetUrl: ui?.["send"], size: "sm" }),
13916
+ t("debugger.submit")
13917
+ ] }),
13918
+ /* @__PURE__ */ jsxs(Button, { variant: "secondary", onClick: handleReset, children: [
13919
+ /* @__PURE__ */ jsx(GameIcon, { icon: RotateCcw, assetUrl: ui?.["reset"], size: "sm" }),
13920
+ t("debugger.reset")
13921
+ ] })
13922
+ ] })
13923
+ ] })
13924
+ }
13925
+ );
13926
+ }
13927
+ var init_DebuggerBoard = __esm({
13928
+ "components/game/2d/organisms/DebuggerBoard.tsx"() {
13929
+ init_atoms();
13930
+ init_useEventBus();
13931
+ init_boardEntity();
13932
+ init_GameIcon();
13933
+ DebuggerBoard.displayName = "DebuggerBoard";
13934
+ }
13935
+ });
13936
+ function NegotiatorBoard({
13937
+ entity,
13938
+ completeEvent = "PUZZLE_COMPLETE",
13939
+ playRoundEvent,
13940
+ finishEvent,
13941
+ playAgainEvent,
13942
+ assetManifest,
13943
+ className
13944
+ }) {
13945
+ const ui = assetManifest?.ui;
13946
+ const { emit } = useEventBus();
13947
+ const { t } = useTranslate();
13948
+ const resolved = boardEntity(entity);
13949
+ const [history, setHistory] = useState([]);
13950
+ const [headerError, setHeaderError] = useState(false);
13951
+ const [showHint, setShowHint] = useState(false);
13952
+ const totalRounds = num(resolved?.maxRounds);
13953
+ const targetScore = num(resolved?.targetScore);
13954
+ const currentRound = num(resolved?.round);
13955
+ const result = str(resolved?.result) || "none";
13956
+ const playerTotal = num(resolved?.score);
13957
+ const isComplete = result !== "none" || totalRounds > 0 && currentRound >= totalRounds;
13958
+ const won = result === "win";
13959
+ const lastPlayerAction = str(resolved?.lastPlayerAction);
13960
+ const lastOpponentAction = str(resolved?.lastOpponentAction);
13961
+ const lastPayoff = num(resolved?.lastPayoff);
13962
+ const actions = Array.isArray(resolved?.actions) ? resolved.actions.flatMap((item) => {
13963
+ if (item !== null && typeof item === "object" && !Array.isArray(item) && !(item instanceof Date) && typeof item.id === "string" && typeof item.label === "string")
13964
+ return [{ id: item.id, label: item.label, description: typeof item.description === "string" ? item.description : void 0 }];
13965
+ return [];
13966
+ }) : [];
13967
+ const payoffMatrix = Array.isArray(resolved?.payoffMatrix) ? resolved.payoffMatrix.flatMap((item) => {
13968
+ if (item !== null && typeof item === "object" && !Array.isArray(item) && !(item instanceof Date) && typeof item.playerAction === "string" && typeof item.opponentAction === "string")
13969
+ return [{ playerAction: item.playerAction, opponentAction: item.opponentAction, playerPayoff: typeof item.playerPayoff === "number" ? item.playerPayoff : 0, opponentPayoff: typeof item.opponentPayoff === "number" ? item.opponentPayoff : 0 }];
13970
+ return [];
13971
+ }) : [];
13972
+ const prevRoundRef = useRef(currentRound);
13973
+ useEffect(() => {
13974
+ if (currentRound > prevRoundRef.current && lastPlayerAction) {
13975
+ const opponentPayoffEntry = payoffMatrix.find(
13976
+ (p) => p.playerAction === lastPlayerAction && p.opponentAction === lastOpponentAction
13977
+ );
13978
+ setHistory((prev) => [
13979
+ ...prev,
13980
+ {
13981
+ round: currentRound,
13982
+ playerAction: lastPlayerAction,
13983
+ opponentAction: lastOpponentAction,
13984
+ playerPayoff: lastPayoff,
13985
+ opponentPayoff: opponentPayoffEntry?.opponentPayoff ?? 0
13986
+ }
13987
+ ]);
13988
+ }
13989
+ prevRoundRef.current = currentRound;
13990
+ }, [currentRound, lastPlayerAction, lastOpponentAction, lastPayoff, payoffMatrix]);
13991
+ const opponentTotal = useMemo(() => history.reduce((s, r) => s + r.opponentPayoff, 0), [history]);
13992
+ const handleAction = useCallback((actionId) => {
13993
+ if (isComplete) return;
13994
+ if (playRoundEvent) {
13995
+ emit(`UI:${playRoundEvent}`, { playerAction: actionId, payoff: 0 });
13996
+ }
13997
+ if (totalRounds > 0 && currentRound + 1 >= totalRounds) {
13998
+ if (finishEvent) {
13999
+ emit(`UI:${finishEvent}`, {});
14000
+ }
14001
+ if (str(resolved?.hint)) {
14002
+ setShowHint(true);
14003
+ }
14004
+ }
14005
+ }, [isComplete, resolved, totalRounds, currentRound, playRoundEvent, finishEvent, emit]);
14006
+ const handleReset = useCallback(() => {
14007
+ setHistory([]);
14008
+ setShowHint(false);
14009
+ prevRoundRef.current = 0;
14010
+ if (playAgainEvent) {
14011
+ emit(`UI:${playAgainEvent}`, {});
14012
+ }
14013
+ }, [playAgainEvent, emit]);
14014
+ const completedRef = useRef(false);
14015
+ useEffect(() => {
14016
+ if (result === "win" && !completedRef.current) {
14017
+ completedRef.current = true;
14018
+ emit(`UI:${completeEvent}`, { success: true, score: playerTotal });
14019
+ } else if (result === "none") {
14020
+ completedRef.current = false;
14021
+ }
14022
+ }, [result, playerTotal, completeEvent, emit]);
14023
+ const getActionLabel = (id) => actions.find((a) => a.id === id)?.label ?? id;
14024
+ if (!resolved) return null;
14025
+ const theme = resolved.theme ?? void 0;
14026
+ const themeBackground = theme?.background;
14027
+ const headerImage = str(resolved.headerImage);
14028
+ const hint = str(resolved.hint);
14029
+ return /* @__PURE__ */ jsx(
14030
+ Box,
14031
+ {
14032
+ className,
14033
+ style: {
14034
+ backgroundImage: themeBackground ? `url(${themeBackground})` : void 0,
14035
+ backgroundSize: "cover",
14036
+ backgroundPosition: "center"
14037
+ },
14038
+ children: /* @__PURE__ */ jsxs(VStack, { gap: "lg", className: "p-4", children: [
14039
+ headerImage && !headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsx("img", { src: headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : headerImage && headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
14040
+ /* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
14041
+ /* @__PURE__ */ jsx(Typography, { variant: "h4", weight: "bold", children: str(resolved.title) }),
14042
+ /* @__PURE__ */ jsx(Typography, { variant: "body", children: str(resolved.description) }),
14043
+ /* @__PURE__ */ jsxs(HStack, { gap: "md", children: [
14044
+ /* @__PURE__ */ jsx(Badge, { size: "sm", children: t("negotiator.round", { current: String(currentRound), total: String(totalRounds) }) }),
14045
+ /* @__PURE__ */ jsxs(Badge, { size: "sm", children: [
14046
+ t("negotiator.target"),
14047
+ ": ",
14048
+ targetScore
14049
+ ] })
14050
+ ] })
14051
+ ] }) }),
14052
+ /* @__PURE__ */ jsxs(HStack, { gap: "md", justify: "center", children: [
14053
+ /* @__PURE__ */ jsx(Card, { className: "p-4 flex-1 text-center", children: /* @__PURE__ */ jsxs(VStack, { gap: "xs", align: "center", children: [
14054
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: t("negotiator.you") }),
14055
+ /* @__PURE__ */ jsx(Typography, { variant: "h3", weight: "bold", children: playerTotal })
14056
+ ] }) }),
14057
+ /* @__PURE__ */ jsx(Card, { className: "p-4 flex-1 text-center", children: /* @__PURE__ */ jsxs(VStack, { gap: "xs", align: "center", children: [
14058
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: t("negotiator.opponent") }),
14059
+ /* @__PURE__ */ jsx(Typography, { variant: "h3", weight: "bold", children: opponentTotal })
14060
+ ] }) })
14061
+ ] }),
14062
+ !isComplete && /* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
14063
+ /* @__PURE__ */ jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: t("negotiator.chooseAction") }),
14064
+ /* @__PURE__ */ jsx(HStack, { gap: "sm", justify: "center", className: "flex-wrap", children: actions.map((action) => /* @__PURE__ */ jsx(
14065
+ Button,
14066
+ {
14067
+ variant: "primary",
14068
+ onClick: () => handleAction(action.id),
14069
+ children: action.label
14070
+ },
14071
+ action.id
14072
+ )) })
14073
+ ] }) }),
14074
+ history.length > 0 && /* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
14075
+ /* @__PURE__ */ jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: t("negotiator.history") }),
14076
+ history.map((round) => /* @__PURE__ */ jsxs(HStack, { gap: "sm", align: "center", className: "text-sm", children: [
14077
+ /* @__PURE__ */ jsxs(Badge, { size: "sm", children: [
14078
+ "R",
14079
+ round.round
14080
+ ] }),
14081
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", children: getActionLabel(round.playerAction) }),
14082
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: "vs" }),
14083
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", children: getActionLabel(round.opponentAction) }),
14084
+ /* @__PURE__ */ jsx(GameIcon, { icon: ArrowRight, assetUrl: ui?.["arrow"], size: "sm" }),
14085
+ /* @__PURE__ */ jsxs(Typography, { variant: "caption", weight: "bold", className: "text-success", children: [
14086
+ "+",
14087
+ round.playerPayoff
14088
+ ] }),
14089
+ /* @__PURE__ */ jsxs(Typography, { variant: "caption", className: "text-muted-foreground", children: [
14090
+ "/ +",
14091
+ round.opponentPayoff
14092
+ ] })
14093
+ ] }, round.round))
14094
+ ] }) }),
14095
+ isComplete && /* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", children: [
14096
+ /* @__PURE__ */ jsx(GameIcon, { icon: CheckCircle, assetUrl: ui?.["correct"], size: "lg", className: won ? "text-success" : "text-error" }),
14097
+ /* @__PURE__ */ jsx(Typography, { variant: "body", weight: "bold", children: won ? str(resolved.successMessage) || t("negotiator.success") : str(resolved.failMessage) || t("negotiator.failed") }),
14098
+ /* @__PURE__ */ jsxs(Typography, { variant: "caption", className: "text-muted-foreground", children: [
14099
+ t("negotiator.finalScore"),
14100
+ ": ",
14101
+ playerTotal,
14102
+ "/",
14103
+ targetScore
14104
+ ] })
14105
+ ] }) }),
14106
+ showHint && hint && !won && /* @__PURE__ */ jsx(Card, { className: "p-4 border-l-4 border-l-warning", children: /* @__PURE__ */ jsx(Typography, { variant: "body", children: hint }) }),
14107
+ isComplete && !won && /* @__PURE__ */ jsx(HStack, { justify: "center", children: /* @__PURE__ */ jsx(Button, { variant: "primary", onClick: handleReset, children: t("negotiator.playAgain") }) })
14108
+ ] })
14109
+ }
14110
+ );
14111
+ }
14112
+ var init_NegotiatorBoard = __esm({
14113
+ "components/game/2d/organisms/NegotiatorBoard.tsx"() {
14114
+ init_atoms();
14115
+ init_useEventBus();
14116
+ init_boardEntity();
14117
+ init_GameIcon();
14118
+ NegotiatorBoard.displayName = "NegotiatorBoard";
14119
+ }
14120
+ });
11954
14121
 
11955
14122
  // components/game/shared/lib/mechanics.ts
11956
14123
  var projectileMotion, pendulum, springOscillator;
@@ -12158,7 +14325,7 @@ function SimulationCanvas({
12158
14325
  }
12159
14326
  var PRESET_BY_ID;
12160
14327
  var init_SimulationCanvas = __esm({
12161
- "components/game/2d/molecules/SimulationCanvas.tsx"() {
14328
+ "components/game/2d/organisms/SimulationCanvas.tsx"() {
12162
14329
  init_cn();
12163
14330
  init_atoms();
12164
14331
  init_verificationRegistry();
@@ -12780,7 +14947,7 @@ var init_ErrorBoundary = __esm({
12780
14947
  }
12781
14948
  );
12782
14949
  };
12783
- ErrorBoundary = class extends React84__default.Component {
14950
+ ErrorBoundary = class extends React96__default.Component {
12784
14951
  constructor(props) {
12785
14952
  super(props);
12786
14953
  __publicField(this, "reset", () => {
@@ -12825,15 +14992,15 @@ function HeaderSkeleton({ className }) {
12825
14992
  ] })
12826
14993
  ] });
12827
14994
  }
12828
- function TableSkeleton({ rows = 5, columns = 4, className }) {
14995
+ function TableSkeleton({ rows: rows2 = 5, columns = 4, className }) {
12829
14996
  return /* @__PURE__ */ jsxs(VStack, { gap: "none", className: cn("border border-border rounded-lg overflow-hidden", className), children: [
12830
14997
  /* @__PURE__ */ jsx(HStack, { className: "px-4 py-3 bg-muted/30 border-b border-border", children: Array.from({ length: columns }).map((_, i) => /* @__PURE__ */ jsx(SkeletonBlock, { className: "h-4 flex-1 mx-2" }, i)) }),
12831
- Array.from({ length: rows }).map((_, rowIdx) => /* @__PURE__ */ jsx(
14998
+ Array.from({ length: rows2 }).map((_, rowIdx) => /* @__PURE__ */ jsx(
12832
14999
  HStack,
12833
15000
  {
12834
15001
  className: cn(
12835
15002
  "px-4 py-3",
12836
- rowIdx < rows - 1 && "border-b border-border"
15003
+ rowIdx < rows2 - 1 && "border-b border-border"
12837
15004
  ),
12838
15005
  children: Array.from({ length: columns }).map((_2, colIdx) => /* @__PURE__ */ jsx(SkeletonLine, { className: "flex-1 mx-2" }, colIdx))
12839
15006
  },
@@ -12881,18 +15048,18 @@ function CardSkeleton({ className }) {
12881
15048
  }
12882
15049
  );
12883
15050
  }
12884
- function TextSkeleton({ rows = 3, className }) {
12885
- return /* @__PURE__ */ jsx(VStack, { gap: "sm", className, children: Array.from({ length: rows }).map((_, i) => /* @__PURE__ */ jsx(
15051
+ function TextSkeleton({ rows: rows2 = 3, className }) {
15052
+ return /* @__PURE__ */ jsx(VStack, { gap: "sm", className, children: Array.from({ length: rows2 }).map((_, i) => /* @__PURE__ */ jsx(
12886
15053
  SkeletonLine,
12887
15054
  {
12888
- className: i === rows - 1 ? "w-2/3" : "w-full"
15055
+ className: i === rows2 - 1 ? "w-2/3" : "w-full"
12889
15056
  },
12890
15057
  i
12891
15058
  )) });
12892
15059
  }
12893
15060
  function Skeleton({
12894
15061
  variant = "text",
12895
- rows,
15062
+ rows: rows2,
12896
15063
  columns,
12897
15064
  fields,
12898
15065
  className
@@ -12902,15 +15069,15 @@ function Skeleton({
12902
15069
  case "header":
12903
15070
  return /* @__PURE__ */ jsx(HeaderSkeleton, { className });
12904
15071
  case "table":
12905
- return /* @__PURE__ */ jsx(TableSkeleton, { rows, columns, className });
15072
+ return /* @__PURE__ */ jsx(TableSkeleton, { rows: rows2, columns, className });
12906
15073
  case "form":
12907
15074
  return /* @__PURE__ */ jsx(FormSkeleton, { fields, className });
12908
15075
  case "card":
12909
15076
  return /* @__PURE__ */ jsx(CardSkeleton, { className });
12910
15077
  case "text":
12911
- return /* @__PURE__ */ jsx(TextSkeleton, { rows, className });
15078
+ return /* @__PURE__ */ jsx(TextSkeleton, { rows: rows2, className });
12912
15079
  default:
12913
- return /* @__PURE__ */ jsx(TextSkeleton, { rows, className });
15080
+ return /* @__PURE__ */ jsx(TextSkeleton, { rows: rows2, className });
12914
15081
  }
12915
15082
  }
12916
15083
  var pulseClass;
@@ -13062,7 +15229,7 @@ var init_Container = __esm({
13062
15229
  as: Component = "div"
13063
15230
  }) => {
13064
15231
  const resolvedSize = maxWidth ?? size ?? "lg";
13065
- return React84__default.createElement(
15232
+ return React96__default.createElement(
13066
15233
  Component,
13067
15234
  {
13068
15235
  className: cn(
@@ -15730,7 +17897,7 @@ var init_CodeBlock = __esm({
15730
17897
  DIFF_STYLE_FALLBACK = { bg: "", prefix: " ", text: "text-foreground" };
15731
17898
  LINE_PROPS_FN = (n) => ({ "data-line": String(n - 1) });
15732
17899
  HIDDEN_LINE_NUMBERS = { display: "none" };
15733
- CodeBlock = React84__default.memo(
17900
+ CodeBlock = React96__default.memo(
15734
17901
  ({
15735
17902
  code: rawCode,
15736
17903
  language = "text",
@@ -15899,24 +18066,24 @@ var init_CodeBlock = __esm({
15899
18066
  return;
15900
18067
  }
15901
18068
  lineEls.forEach((el) => {
15902
- const num = parseInt(el.getAttribute("data-line") ?? "-1", 10);
15903
- if (hiddenLines.has(num)) {
18069
+ const num2 = parseInt(el.getAttribute("data-line") ?? "-1", 10);
18070
+ if (hiddenLines.has(num2)) {
15904
18071
  el.style.display = "none";
15905
18072
  return;
15906
18073
  }
15907
18074
  el.style.display = "";
15908
18075
  el.style.position = "relative";
15909
18076
  el.style.paddingLeft = "1.2em";
15910
- const region = foldStartMap.get(num);
18077
+ const region = foldStartMap.get(num2);
15911
18078
  if (!region) return;
15912
- const isCollapsed = collapsed.has(num);
18079
+ const isCollapsed = collapsed.has(num2);
15913
18080
  const toggle = document.createElement("span");
15914
18081
  toggle.className = "fold-toggle";
15915
18082
  toggle.textContent = isCollapsed ? "\u25B6" : "\u25BC";
15916
18083
  toggle.style.cssText = "position:absolute;left:0;top:0;width:1.2em;text-align:center;cursor:pointer;color:#858585;font-size:10px;user-select:none;line-height:inherit;height:100%";
15917
18084
  toggle.addEventListener("click", (e) => {
15918
18085
  e.stopPropagation();
15919
- toggleFoldRef.current(num);
18086
+ toggleFoldRef.current(num2);
15920
18087
  });
15921
18088
  el.insertBefore(toggle, el.firstChild);
15922
18089
  if (isCollapsed) {
@@ -16317,7 +18484,7 @@ var init_MarkdownContent = __esm({
16317
18484
  init_Box();
16318
18485
  init_CodeBlock();
16319
18486
  init_cn();
16320
- MarkdownContent = React84__default.memo(
18487
+ MarkdownContent = React96__default.memo(
16321
18488
  ({ content, direction = "ltr", className }) => {
16322
18489
  const { t: _t } = useTranslate();
16323
18490
  const safeContent = typeof content === "string" ? content : String(content ?? "");
@@ -16836,7 +19003,7 @@ var init_QuizBlock = __esm({
16836
19003
  QuizBlock.displayName = "QuizBlock";
16837
19004
  }
16838
19005
  });
16839
- var StateNode, TransitionBundleArrow, BundleTooltip, EntityBox, OutputsBox, Legend, StateMachineView;
19006
+ var StateNode2, TransitionBundleArrow, BundleTooltip, EntityBox, OutputsBox, Legend, StateMachineView;
16840
19007
  var init_StateMachineView = __esm({
16841
19008
  "components/core/organisms/StateMachineView.tsx"() {
16842
19009
  "use client";
@@ -16848,7 +19015,7 @@ var init_StateMachineView = __esm({
16848
19015
  init_Icon();
16849
19016
  init_useEventBus();
16850
19017
  init_cn();
16851
- StateNode = ({ state, config }) => {
19018
+ StateNode2 = ({ state, config }) => {
16852
19019
  const { t } = useTranslate();
16853
19020
  const size = state.radius * 2;
16854
19021
  let borderColor = config.colors.nodeBorder;
@@ -17594,8 +19761,8 @@ var init_StateMachineView = __esm({
17594
19761
  style: { top: title ? 30 : 0 },
17595
19762
  children: [
17596
19763
  entity && /* @__PURE__ */ jsx(EntityBox, { entity, config }),
17597
- states.map((state) => renderStateNode ? /* @__PURE__ */ jsx(React84__default.Fragment, { children: renderStateNode(state, config) }, state.id) : /* @__PURE__ */ jsx(
17598
- StateNode,
19764
+ states.map((state) => renderStateNode ? /* @__PURE__ */ jsx(React96__default.Fragment, { children: renderStateNode(state, config) }, state.id) : /* @__PURE__ */ jsx(
19765
+ StateNode2,
17599
19766
  {
17600
19767
  state,
17601
19768
  config
@@ -23151,8 +25318,8 @@ var init_Menu = __esm({
23151
25318
  "bottom-end": "bottom-start"
23152
25319
  };
23153
25320
  const effectivePosition = direction === "rtl" ? rtlMirror[position] ?? position : position;
23154
- const triggerChild = React84__default.isValidElement(trigger) ? trigger : /* @__PURE__ */ jsx(Typography, { variant: "small", as: "span", children: trigger });
23155
- const triggerElement = React84__default.cloneElement(
25321
+ const triggerChild = React96__default.isValidElement(trigger) ? trigger : /* @__PURE__ */ jsx(Typography, { variant: "small", as: "span", children: trigger });
25322
+ const triggerElement = React96__default.cloneElement(
23156
25323
  triggerChild,
23157
25324
  {
23158
25325
  ref: triggerRef,
@@ -23247,14 +25414,14 @@ function useDataDnd(args) {
23247
25414
  const isZone = Boolean(dragGroup || accepts || sortable);
23248
25415
  const enabled = isZone || Boolean(dndRoot);
23249
25416
  const eventBus = useEventBus();
23250
- const parentRoot = React84__default.useContext(RootCtx);
25417
+ const parentRoot = React96__default.useContext(RootCtx);
23251
25418
  const isRoot = enabled && parentRoot === null;
23252
- const zoneId = React84__default.useId();
25419
+ const zoneId = React96__default.useId();
23253
25420
  const ownGroup = dragGroup ?? accepts ?? zoneId;
23254
- const [optimisticOrders, setOptimisticOrders] = React84__default.useState(() => /* @__PURE__ */ new Map());
23255
- const optimisticOrdersRef = React84__default.useRef(optimisticOrders);
25421
+ const [optimisticOrders, setOptimisticOrders] = React96__default.useState(() => /* @__PURE__ */ new Map());
25422
+ const optimisticOrdersRef = React96__default.useRef(optimisticOrders);
23256
25423
  optimisticOrdersRef.current = optimisticOrders;
23257
- const clearOptimisticOrder = React84__default.useCallback((group) => {
25424
+ const clearOptimisticOrder = React96__default.useCallback((group) => {
23258
25425
  setOptimisticOrders((prev) => {
23259
25426
  if (!prev.has(group)) return prev;
23260
25427
  const next = new Map(prev);
@@ -23279,7 +25446,7 @@ function useDataDnd(args) {
23279
25446
  const raw = it[dndItemIdField];
23280
25447
  return raw != null ? String(raw) : `__idx_${idx}`;
23281
25448
  }).join("|");
23282
- const itemIds = React84__default.useMemo(
25449
+ const itemIds = React96__default.useMemo(
23283
25450
  () => orderedItems.map((it, idx) => {
23284
25451
  const raw = it[dndItemIdField];
23285
25452
  return raw != null ? String(raw) : `__idx_${idx}`;
@@ -23290,7 +25457,7 @@ function useDataDnd(args) {
23290
25457
  const raw = it[dndItemIdField];
23291
25458
  return raw != null ? String(raw) : `__${idx}`;
23292
25459
  }).join("|");
23293
- React84__default.useEffect(() => {
25460
+ React96__default.useEffect(() => {
23294
25461
  const root = isRoot ? null : parentRoot;
23295
25462
  if (root) {
23296
25463
  root.clearOptimisticOrder(ownGroup);
@@ -23298,20 +25465,20 @@ function useDataDnd(args) {
23298
25465
  clearOptimisticOrder(ownGroup);
23299
25466
  }
23300
25467
  }, [itemsContentSig, ownGroup]);
23301
- const zonesRef = React84__default.useRef(/* @__PURE__ */ new Map());
23302
- const registerZone = React84__default.useCallback((zoneId2, meta2) => {
25468
+ const zonesRef = React96__default.useRef(/* @__PURE__ */ new Map());
25469
+ const registerZone = React96__default.useCallback((zoneId2, meta2) => {
23303
25470
  zonesRef.current.set(zoneId2, meta2);
23304
25471
  }, []);
23305
- const unregisterZone = React84__default.useCallback((zoneId2) => {
25472
+ const unregisterZone = React96__default.useCallback((zoneId2) => {
23306
25473
  zonesRef.current.delete(zoneId2);
23307
25474
  }, []);
23308
- const [activeDrag, setActiveDrag] = React84__default.useState(null);
23309
- const [overZoneGroup, setOverZoneGroup] = React84__default.useState(null);
23310
- const meta = React84__default.useMemo(
25475
+ const [activeDrag, setActiveDrag] = React96__default.useState(null);
25476
+ const [overZoneGroup, setOverZoneGroup] = React96__default.useState(null);
25477
+ const meta = React96__default.useMemo(
23311
25478
  () => ({ group: ownGroup, dropEvent, reorderEvent, positionEvent, itemIds, rawItems: items, idField: dndItemIdField }),
23312
25479
  [ownGroup, dropEvent, reorderEvent, positionEvent, itemIds, items, dndItemIdField]
23313
25480
  );
23314
- React84__default.useEffect(() => {
25481
+ React96__default.useEffect(() => {
23315
25482
  const target = isRoot ? null : parentRoot;
23316
25483
  if (!target) {
23317
25484
  zonesRef.current.set(zoneId, meta);
@@ -23330,7 +25497,7 @@ function useDataDnd(args) {
23330
25497
  }, [parentRoot, isRoot, zoneId, meta]);
23331
25498
  const sensors = useAlmadarDndSensors(true);
23332
25499
  const collisionDetection = almadarDndCollisionDetection;
23333
- const findZoneByItem = React84__default.useCallback(
25500
+ const findZoneByItem = React96__default.useCallback(
23334
25501
  (id) => {
23335
25502
  for (const z of zonesRef.current.values()) {
23336
25503
  if (z.itemIds.includes(id)) return z;
@@ -23339,7 +25506,7 @@ function useDataDnd(args) {
23339
25506
  },
23340
25507
  []
23341
25508
  );
23342
- React84__default.useCallback(
25509
+ React96__default.useCallback(
23343
25510
  (group) => {
23344
25511
  for (const z of zonesRef.current.values()) {
23345
25512
  if (z.group === group) return z;
@@ -23348,7 +25515,7 @@ function useDataDnd(args) {
23348
25515
  },
23349
25516
  []
23350
25517
  );
23351
- const handleDragEnd = React84__default.useCallback(
25518
+ const handleDragEnd = React96__default.useCallback(
23352
25519
  (event) => {
23353
25520
  const { active, over } = event;
23354
25521
  const activeIdStr = String(active.id);
@@ -23439,8 +25606,8 @@ function useDataDnd(args) {
23439
25606
  },
23440
25607
  [eventBus]
23441
25608
  );
23442
- const sortableData = React84__default.useMemo(() => ({ dndGroup: ownGroup }), [ownGroup]);
23443
- const SortableItem = React84__default.useCallback(
25609
+ const sortableData = React96__default.useMemo(() => ({ dndGroup: ownGroup }), [ownGroup]);
25610
+ const SortableItem = React96__default.useCallback(
23444
25611
  ({ id, children }) => {
23445
25612
  const {
23446
25613
  attributes,
@@ -23480,7 +25647,7 @@ function useDataDnd(args) {
23480
25647
  id: droppableId,
23481
25648
  data: sortableData
23482
25649
  });
23483
- const ctx = React84__default.useContext(RootCtx);
25650
+ const ctx = React96__default.useContext(RootCtx);
23484
25651
  const activeDrag2 = ctx?.activeDrag ?? null;
23485
25652
  const overZoneGroup2 = ctx?.overZoneGroup ?? null;
23486
25653
  const isThisZoneOver = overZoneGroup2 === ownGroup;
@@ -23495,7 +25662,7 @@ function useDataDnd(args) {
23495
25662
  showForeignPlaceholder,
23496
25663
  ctxAvailable: ctx != null
23497
25664
  });
23498
- React84__default.useEffect(() => {
25665
+ React96__default.useEffect(() => {
23499
25666
  dndLog.info("dropzone:isOver:change", { droppableId, group: ownGroup, isOver, isThisZoneOver, showForeignPlaceholder, activeDragSourceGroup: activeDrag2?.sourceGroup ?? null });
23500
25667
  }, [droppableId, isOver, isThisZoneOver, showForeignPlaceholder]);
23501
25668
  return /* @__PURE__ */ jsx(
@@ -23509,11 +25676,11 @@ function useDataDnd(args) {
23509
25676
  }
23510
25677
  );
23511
25678
  };
23512
- const rootContextValue = React84__default.useMemo(
25679
+ const rootContextValue = React96__default.useMemo(
23513
25680
  () => ({ registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder }),
23514
25681
  [registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder]
23515
25682
  );
23516
- const handleDragStart = React84__default.useCallback((event) => {
25683
+ const handleDragStart = React96__default.useCallback((event) => {
23517
25684
  const sourceZone = findZoneByItem(event.active.id);
23518
25685
  const rect = event.active.rect.current.initial;
23519
25686
  const height = rect?.height && rect.height > 0 ? rect.height : 64;
@@ -23532,7 +25699,7 @@ function useDataDnd(args) {
23532
25699
  isRoot
23533
25700
  });
23534
25701
  }, [findZoneByItem, isRoot, zoneId]);
23535
- const handleDragOver = React84__default.useCallback((event) => {
25702
+ const handleDragOver = React96__default.useCallback((event) => {
23536
25703
  const { active, over } = event;
23537
25704
  const overData = over?.data?.current;
23538
25705
  const overGroup = overData?.dndGroup ?? null;
@@ -23602,7 +25769,7 @@ function useDataDnd(args) {
23602
25769
  return next;
23603
25770
  });
23604
25771
  }, []);
23605
- const handleDragCancel = React84__default.useCallback((event) => {
25772
+ const handleDragCancel = React96__default.useCallback((event) => {
23606
25773
  setActiveDrag(null);
23607
25774
  setOverZoneGroup(null);
23608
25775
  dndLog.warn("dragCancel", {
@@ -23610,12 +25777,12 @@ function useDataDnd(args) {
23610
25777
  reason: "dnd-kit cancelled the drag (escape key, pointer interrupted, or external)"
23611
25778
  });
23612
25779
  }, []);
23613
- const handleDragEndWithCleanup = React84__default.useCallback((event) => {
25780
+ const handleDragEndWithCleanup = React96__default.useCallback((event) => {
23614
25781
  handleDragEnd(event);
23615
25782
  setActiveDrag(null);
23616
25783
  setOverZoneGroup(null);
23617
25784
  }, [handleDragEnd]);
23618
- const wrapContainer = React84__default.useCallback(
25785
+ const wrapContainer = React96__default.useCallback(
23619
25786
  (children) => {
23620
25787
  if (!enabled) return children;
23621
25788
  const strategy = layout === "grid" ? rectSortingStrategy : verticalListSortingStrategy;
@@ -23669,7 +25836,7 @@ var init_useDataDnd = __esm({
23669
25836
  init_useAlmadarDndCollision();
23670
25837
  init_Box();
23671
25838
  dndLog = createLogger("almadar:ui:dnd");
23672
- RootCtx = React84__default.createContext(null);
25839
+ RootCtx = React96__default.createContext(null);
23673
25840
  }
23674
25841
  });
23675
25842
  function renderIconInput(icon, props) {
@@ -24195,7 +26362,7 @@ function DataList({
24195
26362
  }) {
24196
26363
  const eventBus = useEventBus();
24197
26364
  const { t } = useTranslate();
24198
- const [visibleCount, setVisibleCount] = React84__default.useState(pageSize || Infinity);
26365
+ const [visibleCount, setVisibleCount] = React96__default.useState(pageSize || Infinity);
24199
26366
  const fieldDefs = fields ?? columns ?? [];
24200
26367
  const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
24201
26368
  const dnd = useDataDnd({
@@ -24214,7 +26381,7 @@ function DataList({
24214
26381
  const data = pageSize > 0 ? allData.slice(0, visibleCount) : allData;
24215
26382
  const hasMoreLocal = pageSize > 0 && visibleCount < allData.length;
24216
26383
  const hasRenderProp = typeof children === "function";
24217
- React84__default.useEffect(() => {
26384
+ React96__default.useEffect(() => {
24218
26385
  const renderItemTypeOf = typeof schemaRenderItem;
24219
26386
  const childrenTypeOf = typeof children;
24220
26387
  if (data.length > 0 && !hasRenderProp) {
@@ -24318,7 +26485,7 @@ function DataList({
24318
26485
  const items2 = [...data];
24319
26486
  const groups2 = groupBy ? groupData(items2, groupBy) : [{ label: "", items: items2 }];
24320
26487
  const contentField = titleField?.name ?? fieldDefs[0]?.name ?? "";
24321
- return /* @__PURE__ */ jsx(VStack, { gap: "sm", className: cn("py-2", className), children: groups2.map((group, gi) => /* @__PURE__ */ jsxs(React84__default.Fragment, { children: [
26488
+ return /* @__PURE__ */ jsx(VStack, { gap: "sm", className: cn("py-2", className), children: groups2.map((group, gi) => /* @__PURE__ */ jsxs(React96__default.Fragment, { children: [
24322
26489
  group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: "my-2" }),
24323
26490
  group.items.map((itemData, index) => {
24324
26491
  const id = itemData.id || `${gi}-${index}`;
@@ -24459,7 +26626,7 @@ function DataList({
24459
26626
  className
24460
26627
  ),
24461
26628
  children: [
24462
- groups.map((group, gi) => /* @__PURE__ */ jsxs(React84__default.Fragment, { children: [
26629
+ groups.map((group, gi) => /* @__PURE__ */ jsxs(React96__default.Fragment, { children: [
24463
26630
  group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: gi > 0 ? "mt-4" : "mt-0" }),
24464
26631
  group.items.map(
24465
26632
  (itemData, index) => renderItem(itemData, index, gi === groups.length - 1 && index === group.items.length - 1)
@@ -24544,7 +26711,7 @@ var init_FormSection = __esm({
24544
26711
  columns = 1,
24545
26712
  className
24546
26713
  }) => {
24547
- const [collapsed, setCollapsed] = React84__default.useState(defaultCollapsed);
26714
+ const [collapsed, setCollapsed] = React96__default.useState(defaultCollapsed);
24548
26715
  const { t } = useTranslate();
24549
26716
  const eventBus = useEventBus();
24550
26717
  const gridClass = {
@@ -24552,7 +26719,7 @@ var init_FormSection = __esm({
24552
26719
  2: "grid-cols-1 md:grid-cols-2",
24553
26720
  3: "grid-cols-1 md:grid-cols-2 lg:grid-cols-3"
24554
26721
  }[columns];
24555
- React84__default.useCallback(() => {
26722
+ React96__default.useCallback(() => {
24556
26723
  if (collapsible) {
24557
26724
  setCollapsed((prev) => !prev);
24558
26725
  eventBus.emit("UI:TOGGLE_COLLAPSE", { collapsed: !collapsed });
@@ -25438,7 +27605,7 @@ var init_Flex = __esm({
25438
27605
  flexStyle.flexBasis = typeof basis === "number" ? `${basis}px` : basis;
25439
27606
  }
25440
27607
  }
25441
- return React84__default.createElement(Component, {
27608
+ return React96__default.createElement(Component, {
25442
27609
  className: cn(
25443
27610
  inline ? "inline-flex" : "flex",
25444
27611
  directionStyles[direction],
@@ -25544,7 +27711,7 @@ var init_Grid = __esm({
25544
27711
  };
25545
27712
  Grid = ({
25546
27713
  cols = 1,
25547
- rows,
27714
+ rows: rows2,
25548
27715
  gap = "md",
25549
27716
  rowGap,
25550
27717
  colGap,
@@ -25556,8 +27723,8 @@ var init_Grid = __esm({
25556
27723
  children,
25557
27724
  as: Component = "div"
25558
27725
  }) => {
25559
- const mergedStyle = rows ? { gridTemplateRows: `repeat(${rows}, minmax(0, 1fr))`, ...style } : style;
25560
- return React84__default.createElement(
27726
+ const mergedStyle = rows2 ? { gridTemplateRows: `repeat(${rows2}, minmax(0, 1fr))`, ...style } : style;
27727
+ return React96__default.createElement(
25561
27728
  Component,
25562
27729
  {
25563
27730
  className: cn(
@@ -25753,9 +27920,9 @@ var init_Popover = __esm({
25753
27920
  onMouseLeave: handleClose,
25754
27921
  onPointerDown: tapTriggerProps.onPointerDown
25755
27922
  };
25756
- const childElement = React84__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
27923
+ const childElement = React96__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
25757
27924
  const childPointerDown = childElement.props.onPointerDown;
25758
- const triggerElement = React84__default.cloneElement(
27925
+ const triggerElement = React96__default.cloneElement(
25759
27926
  childElement,
25760
27927
  {
25761
27928
  ref: triggerRef,
@@ -26357,9 +28524,9 @@ var init_Tooltip = __esm({
26357
28524
  if (hideTimeoutRef.current) clearTimeout(hideTimeoutRef.current);
26358
28525
  };
26359
28526
  }, []);
26360
- const triggerElement = React84__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
28527
+ const triggerElement = React96__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
26361
28528
  const childPointerDown = triggerElement.props.onPointerDown;
26362
- const trigger = React84__default.cloneElement(triggerElement, {
28529
+ const trigger = React96__default.cloneElement(triggerElement, {
26363
28530
  ref: triggerRef,
26364
28531
  onMouseEnter: handleMouseEnter,
26365
28532
  onMouseLeave: handleMouseLeave,
@@ -26449,7 +28616,7 @@ var init_WizardProgress = __esm({
26449
28616
  children: /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", children: normalizedSteps.map((step, index) => {
26450
28617
  const isActive = index === currentStep;
26451
28618
  const isCompleted = index < currentStep;
26452
- return /* @__PURE__ */ jsxs(React84__default.Fragment, { children: [
28619
+ return /* @__PURE__ */ jsxs(React96__default.Fragment, { children: [
26453
28620
  /* @__PURE__ */ jsx(
26454
28621
  "button",
26455
28622
  {
@@ -28009,13 +30176,13 @@ var init_MapView = __esm({
28009
30176
  shadowSize: [41, 41]
28010
30177
  });
28011
30178
  L.Marker.prototype.options.icon = defaultIcon;
28012
- const { useEffect: useEffect63, useRef: useRef61, useCallback: useCallback92, useState: useState88 } = React84__default;
30179
+ const { useEffect: useEffect67, useRef: useRef65, useCallback: useCallback99, useState: useState97 } = React96__default;
28013
30180
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
28014
30181
  const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
28015
30182
  function MapUpdater({ centerLat, centerLng, zoom }) {
28016
30183
  const map = useMap();
28017
- const prevRef = useRef61({ centerLat, centerLng, zoom });
28018
- useEffect63(() => {
30184
+ const prevRef = useRef65({ centerLat, centerLng, zoom });
30185
+ useEffect67(() => {
28019
30186
  const prev = prevRef.current;
28020
30187
  if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
28021
30188
  map.setView([centerLat, centerLng], zoom);
@@ -28026,7 +30193,7 @@ var init_MapView = __esm({
28026
30193
  }
28027
30194
  function MapClickHandler({ onMapClick }) {
28028
30195
  const map = useMap();
28029
- useEffect63(() => {
30196
+ useEffect67(() => {
28030
30197
  if (!onMapClick) return;
28031
30198
  const handler = (e) => {
28032
30199
  onMapClick(e.latlng.lat, e.latlng.lng);
@@ -28054,8 +30221,8 @@ var init_MapView = __esm({
28054
30221
  showAttribution = true
28055
30222
  }) {
28056
30223
  const eventBus = useEventBus2();
28057
- const [clickedPosition, setClickedPosition] = useState88(null);
28058
- const handleMapClick = useCallback92((lat, lng) => {
30224
+ const [clickedPosition, setClickedPosition] = useState97(null);
30225
+ const handleMapClick = useCallback99((lat, lng) => {
28059
30226
  if (showClickedPin) {
28060
30227
  setClickedPosition({ lat, lng });
28061
30228
  }
@@ -28064,7 +30231,7 @@ var init_MapView = __esm({
28064
30231
  eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
28065
30232
  }
28066
30233
  }, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
28067
- const handleMarkerClick = useCallback92((marker) => {
30234
+ const handleMarkerClick = useCallback99((marker) => {
28068
30235
  onMarkerClick?.(marker);
28069
30236
  if (markerClickEvent) {
28070
30237
  eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
@@ -28924,8 +31091,8 @@ function TableView({
28924
31091
  }) {
28925
31092
  const eventBus = useEventBus();
28926
31093
  const { t } = useTranslate();
28927
- const [visibleCount, setVisibleCount] = React84__default.useState(pageSize > 0 ? pageSize : Infinity);
28928
- const [localSelected, setLocalSelected] = React84__default.useState(/* @__PURE__ */ new Set());
31094
+ const [visibleCount, setVisibleCount] = React96__default.useState(pageSize > 0 ? pageSize : Infinity);
31095
+ const [localSelected, setLocalSelected] = React96__default.useState(/* @__PURE__ */ new Set());
28929
31096
  const colDefs = columns ?? fields ?? [];
28930
31097
  const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
28931
31098
  const dnd = useDataDnd({
@@ -29120,12 +31287,12 @@ function TableView({
29120
31287
  ]
29121
31288
  }
29122
31289
  );
29123
- return dnd.isZone ? /* @__PURE__ */ jsx(dnd.SortableItem, { id: row[idField] ?? id, children: rowInner }, id) : /* @__PURE__ */ jsx(React84__default.Fragment, { children: rowInner }, id);
31290
+ return dnd.isZone ? /* @__PURE__ */ jsx(dnd.SortableItem, { id: row[idField] ?? id, children: rowInner }, id) : /* @__PURE__ */ jsx(React96__default.Fragment, { children: rowInner }, id);
29124
31291
  };
29125
31292
  const items = Array.from(data);
29126
31293
  const groups = groupBy ? groupData2(items, groupBy) : [{ label: "", items }];
29127
31294
  let runningIndex = 0;
29128
- const body = /* @__PURE__ */ jsx(Box, { role: "rowgroup", children: groups.map((group, gi) => /* @__PURE__ */ jsxs(React84__default.Fragment, { children: [
31295
+ const body = /* @__PURE__ */ jsx(Box, { role: "rowgroup", children: groups.map((group, gi) => /* @__PURE__ */ jsxs(React96__default.Fragment, { children: [
29129
31296
  group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: gi > 0 ? "mt-3" : "mt-0" }),
29130
31297
  group.items.map((row) => renderRow(row, runningIndex++))
29131
31298
  ] }, gi)) });
@@ -30344,7 +32511,7 @@ var init_StepFlow = __esm({
30344
32511
  className
30345
32512
  }) => {
30346
32513
  if (orientation === "vertical") {
30347
- return /* @__PURE__ */ jsx(VStack, { gap: "none", className: cn("w-full", className), children: steps.map((step, index) => /* @__PURE__ */ jsx(React84__default.Fragment, { children: /* @__PURE__ */ jsxs(HStack, { gap: "md", align: "start", className: "w-full", children: [
32514
+ return /* @__PURE__ */ jsx(VStack, { gap: "none", className: cn("w-full", className), children: steps.map((step, index) => /* @__PURE__ */ jsx(React96__default.Fragment, { children: /* @__PURE__ */ jsxs(HStack, { gap: "md", align: "start", className: "w-full", children: [
30348
32515
  /* @__PURE__ */ jsxs(VStack, { gap: "none", align: "center", children: [
30349
32516
  /* @__PURE__ */ jsx(StepCircle, { step, index }),
30350
32517
  showConnectors && index < steps.length - 1 && /* @__PURE__ */ jsx(Box, { className: "w-px h-8 bg-border" })
@@ -30355,7 +32522,7 @@ var init_StepFlow = __esm({
30355
32522
  ] })
30356
32523
  ] }) }, index)) });
30357
32524
  }
30358
- 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(React84__default.Fragment, { children: [
32525
+ return /* @__PURE__ */ jsx(Box, { className: cn("w-full flex flex-col md:flex-row items-start gap-0", className), children: steps.map((step, index) => /* @__PURE__ */ jsxs(React96__default.Fragment, { children: [
30359
32526
  /* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", className: "flex-1 w-full md:w-auto", children: [
30360
32527
  /* @__PURE__ */ jsx(StepCircle, { step, index }),
30361
32528
  /* @__PURE__ */ jsx(Typography, { variant: "h4", className: "text-center", children: step.title }),
@@ -31081,11 +33248,11 @@ function LatticeSVG({
31081
33248
  }) {
31082
33249
  const paths = [];
31083
33250
  const cols = 5;
31084
- const rows = Math.ceil(h / (w / cols));
33251
+ const rows2 = Math.ceil(h / (w / cols));
31085
33252
  const cellW = w / cols;
31086
33253
  const cellH = cellW;
31087
33254
  const bulge = cellW * 0.3;
31088
- for (let row = 0; row < rows; row++) {
33255
+ for (let row = 0; row < rows2; row++) {
31089
33256
  for (let col = 0; col < cols; col++) {
31090
33257
  const cx = col * cellW + cellW / 2;
31091
33258
  const cy = row * cellH + cellH / 2;
@@ -31340,7 +33507,7 @@ var init_LikertScale = __esm({
31340
33507
  md: "text-base",
31341
33508
  lg: "text-lg"
31342
33509
  };
31343
- LikertScale = React84__default.forwardRef(
33510
+ LikertScale = React96__default.forwardRef(
31344
33511
  ({
31345
33512
  question,
31346
33513
  options = DEFAULT_LIKERT_OPTIONS,
@@ -31352,7 +33519,7 @@ var init_LikertScale = __esm({
31352
33519
  variant = "radios",
31353
33520
  className
31354
33521
  }, ref) => {
31355
- const groupId = React84__default.useId();
33522
+ const groupId = React96__default.useId();
31356
33523
  const eventBus = useEventBus();
31357
33524
  const handleSelect = useCallback(
31358
33525
  (next) => {
@@ -31506,7 +33673,7 @@ var init_MatrixQuestion = __esm({
31506
33673
  };
31507
33674
  MatrixQuestion = ({
31508
33675
  title,
31509
- rows,
33676
+ rows: rows2,
31510
33677
  columns = DEFAULT_MATRIX_COLUMNS,
31511
33678
  values,
31512
33679
  onChange,
@@ -31516,7 +33683,7 @@ var init_MatrixQuestion = __esm({
31516
33683
  className
31517
33684
  }) => {
31518
33685
  const styles = sizeStyles12[size];
31519
- const safeRows = rows ?? [];
33686
+ const safeRows = rows2 ?? [];
31520
33687
  const safeValues = values ?? {};
31521
33688
  const eventBus = useEventBus();
31522
33689
  const handleChange = useCallback(
@@ -33634,7 +35801,7 @@ var init_DocBreadcrumb = __esm({
33634
35801
  "aria-label": t("aria.breadcrumb"),
33635
35802
  children: /* @__PURE__ */ jsx(HStack, { gap: "xs", align: "center", wrap: true, children: items.map((item, idx) => {
33636
35803
  const isLast = idx === items.length - 1;
33637
- return /* @__PURE__ */ jsxs(React84__default.Fragment, { children: [
35804
+ return /* @__PURE__ */ jsxs(React96__default.Fragment, { children: [
33638
35805
  idx > 0 && /* @__PURE__ */ jsx(
33639
35806
  Icon,
33640
35807
  {
@@ -34503,7 +36670,7 @@ var init_MiniStateMachine = __esm({
34503
36670
  const x = 2 + i * (NODE_W + GAP + ARROW_W + GAP);
34504
36671
  const tc = transitionCounts[s.name] ?? 0;
34505
36672
  const role = getStateRole(s.name, s.isInitial ?? void 0, s.isTerminal ?? void 0, tc, maxTC);
34506
- return /* @__PURE__ */ jsxs(React84__default.Fragment, { children: [
36673
+ return /* @__PURE__ */ jsxs(React96__default.Fragment, { children: [
34507
36674
  /* @__PURE__ */ jsx(
34508
36675
  AvlState,
34509
36676
  {
@@ -34707,7 +36874,7 @@ var init_PageHeader = __esm({
34707
36874
  info: "bg-info/10 text-info"
34708
36875
  };
34709
36876
  return /* @__PURE__ */ jsxs(Box, { className: cn("mb-6", className), children: [
34710
- 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(React84__default.Fragment, { children: [
36877
+ breadcrumbs && breadcrumbs.length > 0 && /* @__PURE__ */ jsx(Box, { as: "nav", className: "mb-4", children: /* @__PURE__ */ jsx(Box, { as: "ol", className: "flex items-center gap-2 text-sm", children: breadcrumbs.map((crumb, idx) => /* @__PURE__ */ jsxs(React96__default.Fragment, { children: [
34711
36878
  idx > 0 && /* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", children: "/" }),
34712
36879
  crumb.href ? /* @__PURE__ */ jsx(
34713
36880
  "a",
@@ -35065,7 +37232,7 @@ var init_Section = __esm({
35065
37232
  as: Component = "section"
35066
37233
  }) => {
35067
37234
  const hasHeader = title || description || action;
35068
- return React84__default.createElement(
37235
+ return React96__default.createElement(
35069
37236
  Component,
35070
37237
  {
35071
37238
  className: cn(
@@ -35389,8 +37556,8 @@ var init_WizardContainer = __esm({
35389
37556
  return void 0;
35390
37557
  if (typeof controlledStep === "number") return controlledStep;
35391
37558
  if (typeof controlledStep === "string") return parseInt(controlledStep, 10);
35392
- const num = Number(controlledStep);
35393
- return isNaN(num) ? void 0 : num;
37559
+ const num2 = Number(controlledStep);
37560
+ return isNaN(num2) ? void 0 : num2;
35394
37561
  })();
35395
37562
  const currentStep = normalizedControlledStep !== void 0 ? normalizedControlledStep : internalStep;
35396
37563
  const totalSteps = steps.length;
@@ -35439,7 +37606,7 @@ var init_WizardContainer = __esm({
35439
37606
  const isCompleted = index < currentStep;
35440
37607
  const stepKey = step.id ?? step.tabId ?? `step-${index}`;
35441
37608
  const stepTitle = step.title ?? step.name ?? `Step ${index + 1}`;
35442
- return /* @__PURE__ */ jsxs(React84__default.Fragment, { children: [
37609
+ return /* @__PURE__ */ jsxs(React96__default.Fragment, { children: [
35443
37610
  /* @__PURE__ */ jsx(
35444
37611
  Button,
35445
37612
  {
@@ -37416,7 +39583,7 @@ function getBadgeVariant(fieldName, value) {
37416
39583
  return "default";
37417
39584
  }
37418
39585
  function formatFieldLabel(fieldName) {
37419
- return fieldName.replace(/([A-Z])/g, " $1").replace(/^./, (str) => str.toUpperCase());
39586
+ return fieldName.replace(/([A-Z])/g, " $1").replace(/^./, (str2) => str2.toUpperCase());
37420
39587
  }
37421
39588
  function formatFieldValue(value, fieldName) {
37422
39589
  if (typeof value === "number") {
@@ -37435,26 +39602,26 @@ function formatFieldValue(value, fieldName) {
37435
39602
  }
37436
39603
  function renderRichFieldValue(value, fieldName, fieldType) {
37437
39604
  if (value === void 0 || value === null) return "\u2014";
37438
- const str = String(value);
39605
+ const str2 = String(value);
37439
39606
  switch (fieldType) {
37440
39607
  case "image":
37441
39608
  case "url": {
37442
- if (str.match(/\.(png|jpe?g|gif|svg|webp|avif)(\?|$)/i) || str.startsWith("data:image/")) {
39609
+ if (str2.match(/\.(png|jpe?g|gif|svg|webp|avif)(\?|$)/i) || str2.startsWith("data:image/")) {
37443
39610
  return /* @__PURE__ */ jsx(Box, { className: "mt-1 max-w-full", children: /* @__PURE__ */ jsx(
37444
39611
  "img",
37445
39612
  {
37446
- src: str,
39613
+ src: str2,
37447
39614
  alt: formatFieldLabel(fieldName),
37448
39615
  className: "max-w-full max-h-64 rounded-md object-contain",
37449
39616
  loading: "lazy"
37450
39617
  }
37451
39618
  ) });
37452
39619
  }
37453
- return str;
39620
+ return str2;
37454
39621
  }
37455
39622
  case "markdown":
37456
39623
  case "richtext":
37457
- return /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(Typography, { variant: "body", className: "break-words", children: str }), children: /* @__PURE__ */ jsx(
39624
+ return /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(Typography, { variant: "body", className: "break-words", children: str2 }), children: /* @__PURE__ */ jsx(
37458
39625
  Box,
37459
39626
  {
37460
39627
  className: "prose prose-sm max-w-none",
@@ -37472,11 +39639,11 @@ function renderRichFieldValue(value, fieldName, fieldType) {
37472
39639
  "--tw-prose-th-borders": "var(--color-border)",
37473
39640
  "--tw-prose-td-borders": "var(--color-border)"
37474
39641
  },
37475
- children: /* @__PURE__ */ jsx(ReactMarkdown2, { children: str })
39642
+ children: /* @__PURE__ */ jsx(ReactMarkdown2, { children: str2 })
37476
39643
  }
37477
39644
  ) });
37478
39645
  case "code":
37479
- return /* @__PURE__ */ jsx(Box, { className: "mt-1 rounded-md bg-muted p-3 overflow-x-auto", children: /* @__PURE__ */ jsx("pre", { className: "text-sm font-mono whitespace-pre-wrap break-words m-0", children: /* @__PURE__ */ jsx("code", { children: str }) }) });
39646
+ return /* @__PURE__ */ jsx(Box, { className: "mt-1 rounded-md bg-muted p-3 overflow-x-auto", children: /* @__PURE__ */ jsx("pre", { className: "text-sm font-mono whitespace-pre-wrap break-words m-0", children: /* @__PURE__ */ jsx("code", { children: str2 }) }) });
37480
39647
  case "html":
37481
39648
  return /* @__PURE__ */ jsx(
37482
39649
  Box,
@@ -37496,12 +39663,12 @@ function renderRichFieldValue(value, fieldName, fieldType) {
37496
39663
  "--tw-prose-th-borders": "var(--color-border)",
37497
39664
  "--tw-prose-td-borders": "var(--color-border)"
37498
39665
  },
37499
- children: /* @__PURE__ */ jsx(Typography, { variant: "body", children: str })
39666
+ children: /* @__PURE__ */ jsx(Typography, { variant: "body", children: str2 })
37500
39667
  }
37501
39668
  );
37502
39669
  case "date":
37503
39670
  case "datetime": {
37504
- const d = new Date(str);
39671
+ const d = new Date(str2);
37505
39672
  if (!isNaN(d.getTime())) {
37506
39673
  return d.toLocaleDateString(void 0, {
37507
39674
  year: "numeric",
@@ -37510,7 +39677,7 @@ function renderRichFieldValue(value, fieldName, fieldType) {
37510
39677
  ...fieldType === "datetime" ? { hour: "2-digit", minute: "2-digit" } : {}
37511
39678
  });
37512
39679
  }
37513
- return str;
39680
+ return str2;
37514
39681
  }
37515
39682
  default:
37516
39683
  return formatFieldValue(value, fieldName);
@@ -37872,7 +40039,7 @@ var init_DetailPanel = __esm({
37872
40039
  }
37873
40040
  });
37874
40041
  function extractTitle(children) {
37875
- if (!React84__default.isValidElement(children)) return void 0;
40042
+ if (!React96__default.isValidElement(children)) return void 0;
37876
40043
  const props = children.props;
37877
40044
  if (typeof props.title === "string") {
37878
40045
  return props.title;
@@ -38222,12 +40389,12 @@ var init_Form = __esm({
38222
40389
  const isSchemaEntity = isOrbitalEntitySchema(entity);
38223
40390
  const resolvedEntity = isSchemaEntity ? entity : void 0;
38224
40391
  const entityName = typeof entity === "string" ? entity : resolvedEntity?.name;
38225
- const normalizedInitialData = React84__default.useMemo(() => {
40392
+ const normalizedInitialData = React96__default.useMemo(() => {
38226
40393
  const entityRowAsInitial = isPlainEntityRow(entity) ? entity : void 0;
38227
40394
  const callerInitial = initialData !== null && typeof initialData === "object" && !Array.isArray(initialData) ? initialData : {};
38228
40395
  return entityRowAsInitial !== void 0 ? { ...entityRowAsInitial, ...callerInitial } : callerInitial;
38229
40396
  }, [entity, initialData]);
38230
- const entityDerivedFields = React84__default.useMemo(() => {
40397
+ const entityDerivedFields = React96__default.useMemo(() => {
38231
40398
  if (fields && fields.length > 0) return void 0;
38232
40399
  if (!resolvedEntity) return void 0;
38233
40400
  return resolvedEntity.fields.map(
@@ -38248,16 +40415,16 @@ var init_Form = __esm({
38248
40415
  const conditionalFields = typeof conditionalFieldsRaw === "boolean" ? {} : conditionalFieldsRaw;
38249
40416
  const hiddenCalculations = typeof hiddenCalculationsRaw === "boolean" ? [] : hiddenCalculationsRaw;
38250
40417
  const violationTriggers = typeof violationTriggersRaw === "boolean" ? [] : violationTriggersRaw;
38251
- const [formData, setFormData] = React84__default.useState(
40418
+ const [formData, setFormData] = React96__default.useState(
38252
40419
  normalizedInitialData
38253
40420
  );
38254
- const [collapsedSections, setCollapsedSections] = React84__default.useState(
40421
+ const [collapsedSections, setCollapsedSections] = React96__default.useState(
38255
40422
  /* @__PURE__ */ new Set()
38256
40423
  );
38257
- const [submitError, setSubmitError] = React84__default.useState(null);
38258
- const formRef = React84__default.useRef(null);
40424
+ const [submitError, setSubmitError] = React96__default.useState(null);
40425
+ const formRef = React96__default.useRef(null);
38259
40426
  const formMode = props.mode;
38260
- const mountedRef = React84__default.useRef(false);
40427
+ const mountedRef = React96__default.useRef(false);
38261
40428
  if (!mountedRef.current) {
38262
40429
  mountedRef.current = true;
38263
40430
  debug("forms", "mount", {
@@ -38270,7 +40437,7 @@ var init_Form = __esm({
38270
40437
  });
38271
40438
  }
38272
40439
  const shouldShowCancel = showCancel ?? (fields && fields.length > 0);
38273
- const evalContext = React84__default.useMemo(
40440
+ const evalContext = React96__default.useMemo(
38274
40441
  () => ({
38275
40442
  formValues: formData,
38276
40443
  globalVariables: externalContext?.globalVariables ?? {},
@@ -38279,7 +40446,7 @@ var init_Form = __esm({
38279
40446
  }),
38280
40447
  [formData, externalContext]
38281
40448
  );
38282
- React84__default.useEffect(() => {
40449
+ React96__default.useEffect(() => {
38283
40450
  debug("forms", "initialData-sync", {
38284
40451
  mode: formMode,
38285
40452
  normalizedInitialData,
@@ -38290,7 +40457,7 @@ var init_Form = __esm({
38290
40457
  setFormData(normalizedInitialData);
38291
40458
  }
38292
40459
  }, [normalizedInitialData]);
38293
- const processCalculations = React84__default.useCallback(
40460
+ const processCalculations = React96__default.useCallback(
38294
40461
  (changedFieldId, newFormData) => {
38295
40462
  if (!hiddenCalculations.length) return;
38296
40463
  const context = {
@@ -38315,7 +40482,7 @@ var init_Form = __esm({
38315
40482
  },
38316
40483
  [hiddenCalculations, externalContext, eventBus]
38317
40484
  );
38318
- const checkViolations = React84__default.useCallback(
40485
+ const checkViolations = React96__default.useCallback(
38319
40486
  (changedFieldId, newFormData) => {
38320
40487
  if (!violationTriggers.length) return;
38321
40488
  const context = {
@@ -38353,7 +40520,7 @@ var init_Form = __esm({
38353
40520
  processCalculations(name, newFormData);
38354
40521
  checkViolations(name, newFormData);
38355
40522
  };
38356
- const isFieldVisible = React84__default.useCallback(
40523
+ const isFieldVisible = React96__default.useCallback(
38357
40524
  (fieldName) => {
38358
40525
  const condition = conditionalFields[fieldName];
38359
40526
  if (!condition) return true;
@@ -38361,7 +40528,7 @@ var init_Form = __esm({
38361
40528
  },
38362
40529
  [conditionalFields, evalContext]
38363
40530
  );
38364
- const isSectionVisible = React84__default.useCallback(
40531
+ const isSectionVisible = React96__default.useCallback(
38365
40532
  (section) => {
38366
40533
  if (!section.condition) return true;
38367
40534
  return Boolean(evaluateFormExpression(section.condition, evalContext));
@@ -38437,7 +40604,7 @@ var init_Form = __esm({
38437
40604
  eventBus.emit(`UI:${onCancel}`);
38438
40605
  }
38439
40606
  };
38440
- const renderField = React84__default.useCallback(
40607
+ const renderField = React96__default.useCallback(
38441
40608
  (field) => {
38442
40609
  const fieldName = field.name || field.field;
38443
40610
  if (!fieldName) return null;
@@ -38458,7 +40625,7 @@ var init_Form = __esm({
38458
40625
  [formData, isFieldVisible, relationsData, relationsLoading, isLoading]
38459
40626
  );
38460
40627
  const effectiveFields = entityDerivedFields ?? fields;
38461
- const normalizedFields = React84__default.useMemo(() => {
40628
+ const normalizedFields = React96__default.useMemo(() => {
38462
40629
  if (!effectiveFields || effectiveFields.length === 0) return [];
38463
40630
  return effectiveFields.map((field) => {
38464
40631
  if (typeof field === "string") {
@@ -38482,7 +40649,7 @@ var init_Form = __esm({
38482
40649
  return field;
38483
40650
  });
38484
40651
  }, [effectiveFields, resolvedEntity]);
38485
- const schemaFields = React84__default.useMemo(() => {
40652
+ const schemaFields = React96__default.useMemo(() => {
38486
40653
  if (normalizedFields.length === 0) return null;
38487
40654
  if (isDebugEnabled()) {
38488
40655
  debugGroup(`Form: ${entityName || "unknown"}`);
@@ -38492,7 +40659,7 @@ var init_Form = __esm({
38492
40659
  }
38493
40660
  return normalizedFields.map(renderField).filter(Boolean);
38494
40661
  }, [normalizedFields, renderField, entityName, conditionalFields]);
38495
- const sectionElements = React84__default.useMemo(() => {
40662
+ const sectionElements = React96__default.useMemo(() => {
38496
40663
  if (!sections || sections.length === 0) return null;
38497
40664
  return sections.map((section) => {
38498
40665
  if (!isSectionVisible(section)) {
@@ -39071,7 +41238,7 @@ function formatValue3(value, fieldName) {
39071
41238
  return String(value);
39072
41239
  }
39073
41240
  function formatFieldLabel2(fieldName) {
39074
- return fieldName.replace(/([A-Z])/g, " $1").replace(/^./, (str) => str.toUpperCase()).replace(/Id$/, "").trim();
41241
+ return fieldName.replace(/([A-Z])/g, " $1").replace(/^./, (str2) => str2.toUpperCase()).replace(/Id$/, "").trim();
39075
41242
  }
39076
41243
  var STATUS_STYLES2, StatusBadge, ProgressIndicator, List3;
39077
41244
  var init_List = __esm({
@@ -39217,7 +41384,7 @@ var init_List = __esm({
39217
41384
  if (entity && typeof entity === "object" && "id" in entity) return [entity];
39218
41385
  return [];
39219
41386
  }, [entity]);
39220
- const getItemActions = React84__default.useCallback(
41387
+ const getItemActions = React96__default.useCallback(
39221
41388
  (item) => {
39222
41389
  if (!itemActions) return [];
39223
41390
  if (typeof itemActions === "function") {
@@ -39692,7 +41859,7 @@ var init_MediaGallery = __esm({
39692
41859
  [selectable, selectedItems, selectionEvent, eventBus]
39693
41860
  );
39694
41861
  const entityData = Array.isArray(entity) ? entity : [];
39695
- const items = React84__default.useMemo(() => {
41862
+ const items = React96__default.useMemo(() => {
39696
41863
  if (propItems) return propItems;
39697
41864
  if (entityData.length === 0) return [];
39698
41865
  return entityData.map((record, idx) => {
@@ -39855,7 +42022,7 @@ var init_MediaGallery = __esm({
39855
42022
  }
39856
42023
  });
39857
42024
  function extractTitle2(children) {
39858
- if (!React84__default.isValidElement(children)) return void 0;
42025
+ if (!React96__default.isValidElement(children)) return void 0;
39859
42026
  const props = children.props;
39860
42027
  if (typeof props.title === "string") {
39861
42028
  return props.title;
@@ -40129,7 +42296,7 @@ var init_debugRegistry = __esm({
40129
42296
  }
40130
42297
  });
40131
42298
  function useDebugData() {
40132
- const [data, setData] = React84.useState(() => ({
42299
+ const [data, setData] = React96.useState(() => ({
40133
42300
  traits: [],
40134
42301
  ticks: [],
40135
42302
  guards: [],
@@ -40143,7 +42310,7 @@ function useDebugData() {
40143
42310
  },
40144
42311
  lastUpdate: Date.now()
40145
42312
  }));
40146
- React84.useEffect(() => {
42313
+ React96.useEffect(() => {
40147
42314
  const updateData = () => {
40148
42315
  setData({
40149
42316
  traits: getAllTraits(),
@@ -40252,12 +42419,12 @@ function layoutGraph(states, transitions, initialState, width, height) {
40252
42419
  return positions;
40253
42420
  }
40254
42421
  function WalkMinimap() {
40255
- const [walkStep, setWalkStep] = React84.useState(null);
40256
- const [traits2, setTraits] = React84.useState([]);
40257
- const [coveredEdges, setCoveredEdges] = React84.useState([]);
40258
- const [completedTraits, setCompletedTraits] = React84.useState(/* @__PURE__ */ new Set());
40259
- const prevTraitRef = React84.useRef(null);
40260
- React84.useEffect(() => {
42422
+ const [walkStep, setWalkStep] = React96.useState(null);
42423
+ const [traits2, setTraits] = React96.useState([]);
42424
+ const [coveredEdges, setCoveredEdges] = React96.useState([]);
42425
+ const [completedTraits, setCompletedTraits] = React96.useState(/* @__PURE__ */ new Set());
42426
+ const prevTraitRef = React96.useRef(null);
42427
+ React96.useEffect(() => {
40261
42428
  const interval = setInterval(() => {
40262
42429
  const w = window;
40263
42430
  const step = w.__orbitalWalkStep;
@@ -40693,15 +42860,15 @@ var init_EntitiesTab = __esm({
40693
42860
  });
40694
42861
  function EventFlowTab({ events: events2 }) {
40695
42862
  const { t } = useTranslate();
40696
- const [filter, setFilter] = React84.useState("all");
40697
- const containerRef = React84.useRef(null);
40698
- const [autoScroll, setAutoScroll] = React84.useState(true);
40699
- React84.useEffect(() => {
42863
+ const [filter, setFilter] = React96.useState("all");
42864
+ const containerRef = React96.useRef(null);
42865
+ const [autoScroll, setAutoScroll] = React96.useState(true);
42866
+ React96.useEffect(() => {
40700
42867
  if (autoScroll && containerRef.current) {
40701
42868
  containerRef.current.scrollTop = containerRef.current.scrollHeight;
40702
42869
  }
40703
42870
  }, [events2.length, autoScroll]);
40704
- const filteredEvents = React84.useMemo(() => {
42871
+ const filteredEvents = React96.useMemo(() => {
40705
42872
  if (filter === "all") return events2;
40706
42873
  return events2.filter((e) => e.type === filter);
40707
42874
  }, [events2, filter]);
@@ -40817,7 +42984,7 @@ var init_EventFlowTab = __esm({
40817
42984
  });
40818
42985
  function GuardsPanel({ guards }) {
40819
42986
  const { t } = useTranslate();
40820
- const [filter, setFilter] = React84.useState("all");
42987
+ const [filter, setFilter] = React96.useState("all");
40821
42988
  if (guards.length === 0) {
40822
42989
  return /* @__PURE__ */ jsx(
40823
42990
  EmptyState,
@@ -40830,7 +42997,7 @@ function GuardsPanel({ guards }) {
40830
42997
  }
40831
42998
  const passedCount = guards.filter((g) => g.result).length;
40832
42999
  const failedCount = guards.length - passedCount;
40833
- const filteredGuards = React84.useMemo(() => {
43000
+ const filteredGuards = React96.useMemo(() => {
40834
43001
  if (filter === "all") return guards;
40835
43002
  if (filter === "passed") return guards.filter((g) => g.result);
40836
43003
  return guards.filter((g) => !g.result);
@@ -40993,10 +43160,10 @@ function EffectBadge({ effect }) {
40993
43160
  }
40994
43161
  function TransitionTimeline({ transitions }) {
40995
43162
  const { t } = useTranslate();
40996
- const containerRef = React84.useRef(null);
40997
- const [autoScroll, setAutoScroll] = React84.useState(true);
40998
- const [expandedId, setExpandedId] = React84.useState(null);
40999
- React84.useEffect(() => {
43163
+ const containerRef = React96.useRef(null);
43164
+ const [autoScroll, setAutoScroll] = React96.useState(true);
43165
+ const [expandedId, setExpandedId] = React96.useState(null);
43166
+ React96.useEffect(() => {
41000
43167
  if (autoScroll && containerRef.current) {
41001
43168
  containerRef.current.scrollTop = containerRef.current.scrollHeight;
41002
43169
  }
@@ -41276,9 +43443,9 @@ function getAllEvents(traits2) {
41276
43443
  function EventDispatcherTab({ traits: traits2, schema }) {
41277
43444
  const eventBus = useEventBus();
41278
43445
  const { t } = useTranslate();
41279
- const [log9, setLog] = React84.useState([]);
41280
- const prevStatesRef = React84.useRef(/* @__PURE__ */ new Map());
41281
- React84.useEffect(() => {
43446
+ const [log9, setLog] = React96.useState([]);
43447
+ const prevStatesRef = React96.useRef(/* @__PURE__ */ new Map());
43448
+ React96.useEffect(() => {
41282
43449
  for (const trait of traits2) {
41283
43450
  const prev = prevStatesRef.current.get(trait.id);
41284
43451
  if (prev && prev !== trait.currentState) {
@@ -41447,10 +43614,10 @@ function VerifyModePanel({
41447
43614
  localCount
41448
43615
  }) {
41449
43616
  const { t } = useTranslate();
41450
- const [expanded, setExpanded] = React84.useState(true);
41451
- const scrollRef = React84.useRef(null);
41452
- const prevCountRef = React84.useRef(0);
41453
- React84.useEffect(() => {
43617
+ const [expanded, setExpanded] = React96.useState(true);
43618
+ const scrollRef = React96.useRef(null);
43619
+ const prevCountRef = React96.useRef(0);
43620
+ React96.useEffect(() => {
41454
43621
  if (expanded && transitions.length > prevCountRef.current && scrollRef.current) {
41455
43622
  scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
41456
43623
  }
@@ -41507,10 +43674,10 @@ function RuntimeDebugger({
41507
43674
  schema
41508
43675
  }) {
41509
43676
  const { t } = useTranslate();
41510
- const [isCollapsed, setIsCollapsed] = React84.useState(mode === "verify" ? true : defaultCollapsed);
41511
- const [isVisible, setIsVisible] = React84.useState(mode === "inline" || mode === "verify" || isDebugEnabled2());
43677
+ const [isCollapsed, setIsCollapsed] = React96.useState(mode === "verify" ? true : defaultCollapsed);
43678
+ const [isVisible, setIsVisible] = React96.useState(mode === "inline" || mode === "verify" || isDebugEnabled2());
41512
43679
  const debugData = useDebugData();
41513
- React84.useEffect(() => {
43680
+ React96.useEffect(() => {
41514
43681
  if (mode === "inline") return;
41515
43682
  return onDebugToggle((enabled) => {
41516
43683
  setIsVisible(enabled);
@@ -41519,7 +43686,7 @@ function RuntimeDebugger({
41519
43686
  }
41520
43687
  });
41521
43688
  }, [mode]);
41522
- React84.useEffect(() => {
43689
+ React96.useEffect(() => {
41523
43690
  if (mode === "inline") return;
41524
43691
  const handleKeyDown = (e) => {
41525
43692
  if (e.key === "`" && isVisible) {
@@ -42039,7 +44206,7 @@ var init_StatCard = __esm({
42039
44206
  const labelToUse = propLabel ?? propTitle;
42040
44207
  const eventBus = useEventBus();
42041
44208
  const { t } = useTranslate();
42042
- const handleActionClick = React84__default.useCallback(() => {
44209
+ const handleActionClick = React96__default.useCallback(() => {
42043
44210
  if (action?.event) {
42044
44211
  eventBus.emit(`UI:${action.event}`, {});
42045
44212
  }
@@ -42050,7 +44217,7 @@ var init_StatCard = __esm({
42050
44217
  const data = Array.isArray(entity) ? entity : entity ? [entity] : [];
42051
44218
  const isLoading = externalLoading ?? false;
42052
44219
  const error = externalError;
42053
- const computeMetricValue = React84__default.useCallback(
44220
+ const computeMetricValue = React96__default.useCallback(
42054
44221
  (metric, items) => {
42055
44222
  if (metric.value !== void 0) {
42056
44223
  return metric.value;
@@ -42089,7 +44256,7 @@ var init_StatCard = __esm({
42089
44256
  },
42090
44257
  []
42091
44258
  );
42092
- const schemaStats = React84__default.useMemo(() => {
44259
+ const schemaStats = React96__default.useMemo(() => {
42093
44260
  if (!metrics || metrics.length === 0) return null;
42094
44261
  return metrics.map((metric) => ({
42095
44262
  label: metric.label,
@@ -42097,7 +44264,7 @@ var init_StatCard = __esm({
42097
44264
  format: metric.format
42098
44265
  }));
42099
44266
  }, [metrics, data, computeMetricValue]);
42100
- const calculatedTrend = React84__default.useMemo(() => {
44267
+ const calculatedTrend = React96__default.useMemo(() => {
42101
44268
  if (manualTrend !== void 0) return manualTrend;
42102
44269
  if (previousValue === void 0 || currentValue === void 0)
42103
44270
  return void 0;
@@ -42737,8 +44904,8 @@ var init_SubagentTracePanel = __esm({
42737
44904
  ] });
42738
44905
  };
42739
44906
  InlineActivityStream = ({ activities, autoScroll = true, className }) => {
42740
- const endRef = React84__default.useRef(null);
42741
- React84__default.useEffect(() => {
44907
+ const endRef = React96__default.useRef(null);
44908
+ React96__default.useEffect(() => {
42742
44909
  if (!autoScroll) return;
42743
44910
  endRef.current?.scrollIntoView({ behavior: "smooth", block: "end" });
42744
44911
  }, [activities.length, autoScroll]);
@@ -42832,7 +44999,7 @@ var init_SubagentTracePanel = __esm({
42832
44999
  };
42833
45000
  SubagentRichCard = ({ subagent }) => {
42834
45001
  const { t } = useTranslate();
42835
- const activities = React84__default.useMemo(
45002
+ const activities = React96__default.useMemo(
42836
45003
  () => subagentMessagesToActivities(subagent.messages),
42837
45004
  [subagent.messages]
42838
45005
  );
@@ -42909,8 +45076,8 @@ var init_SubagentTracePanel = __esm({
42909
45076
  ] });
42910
45077
  };
42911
45078
  CoordinatorConversation = ({ messages, autoScroll = true, className }) => {
42912
- const endRef = React84__default.useRef(null);
42913
- React84__default.useEffect(() => {
45079
+ const endRef = React96__default.useRef(null);
45080
+ React96__default.useEffect(() => {
42914
45081
  if (!autoScroll) return;
42915
45082
  endRef.current?.scrollIntoView({ behavior: "smooth", block: "end" });
42916
45083
  }, [messages.length, autoScroll]);
@@ -43340,7 +45507,7 @@ var init_Timeline = __esm({
43340
45507
  }) => {
43341
45508
  const { t } = useTranslate();
43342
45509
  const entityData = entity ?? [];
43343
- const items = React84__default.useMemo(() => {
45510
+ const items = React96__default.useMemo(() => {
43344
45511
  if (propItems) return propItems;
43345
45512
  if (entityData.length === 0) return [];
43346
45513
  return entityData.map((record, idx) => {
@@ -43442,7 +45609,7 @@ var init_Timeline = __esm({
43442
45609
  }
43443
45610
  });
43444
45611
  function extractToastProps(children) {
43445
- if (!React84__default.isValidElement(children)) {
45612
+ if (!React96__default.isValidElement(children)) {
43446
45613
  if (typeof children === "string") {
43447
45614
  return { message: children };
43448
45615
  }
@@ -43484,7 +45651,7 @@ var init_ToastSlot = __esm({
43484
45651
  eventBus.emit(`${prefix}CLOSE`);
43485
45652
  };
43486
45653
  if (!isVisible) return null;
43487
- const isCustomContent = React84__default.isValidElement(children) && !message;
45654
+ const isCustomContent = React96__default.isValidElement(children) && !message;
43488
45655
  return /* @__PURE__ */ jsx(Box, { className: "fixed bottom-4 right-4 z-50", children: isCustomContent ? children : /* @__PURE__ */ jsx(
43489
45656
  Toast,
43490
45657
  {
@@ -43501,7 +45668,7 @@ var init_ToastSlot = __esm({
43501
45668
  }
43502
45669
  });
43503
45670
  function lazyThree(name, loader) {
43504
- const Lazy = React84__default.lazy(
45671
+ const Lazy = React96__default.lazy(
43505
45672
  () => loader().then((m) => {
43506
45673
  const Resolved = m[name];
43507
45674
  if (!Resolved) {
@@ -43513,13 +45680,13 @@ function lazyThree(name, loader) {
43513
45680
  })
43514
45681
  );
43515
45682
  function ThreeWrapper(props) {
43516
- return React84__default.createElement(
45683
+ return React96__default.createElement(
43517
45684
  ThreeBoundary,
43518
45685
  { name },
43519
- React84__default.createElement(
43520
- React84__default.Suspense,
45686
+ React96__default.createElement(
45687
+ React96__default.Suspense,
43521
45688
  { fallback: null },
43522
- React84__default.createElement(Lazy, props)
45689
+ React96__default.createElement(Lazy, props)
43523
45690
  )
43524
45691
  );
43525
45692
  }
@@ -43555,6 +45722,7 @@ var init_component_registry_generated = __esm({
43555
45722
  init_LayoutPatterns();
43556
45723
  init_BranchingLogicBuilder();
43557
45724
  init_Breadcrumb();
45725
+ init_BuilderBoard();
43558
45726
  init_CTABanner();
43559
45727
  init_CalendarGrid();
43560
45728
  init_Canvas2D();
@@ -43570,6 +45738,7 @@ var init_component_registry_generated = __esm({
43570
45738
  init_Checkbox();
43571
45739
  init_ChemistryCanvas();
43572
45740
  init_ChoiceButton();
45741
+ init_ClassifierBoard();
43573
45742
  init_CodeBlock();
43574
45743
  init_CodeRunnerPanel();
43575
45744
  init_ComboCounter();
@@ -43593,6 +45762,7 @@ var init_component_registry_generated = __esm({
43593
45762
  init_DateRangePicker();
43594
45763
  init_DateRangeSelector();
43595
45764
  init_DayCell();
45765
+ init_DebuggerBoard();
43596
45766
  init_DetailPanel();
43597
45767
  init_Dialog();
43598
45768
  init_DialogueBubble();
@@ -43608,6 +45778,7 @@ var init_component_registry_generated = __esm({
43608
45778
  init_EmptyState();
43609
45779
  init_ErrorBoundary();
43610
45780
  init_ErrorState();
45781
+ init_EventHandlerBoard();
43611
45782
  init_EventLog();
43612
45783
  init_FeatureCard();
43613
45784
  init_FeatureDetailPageTemplate();
@@ -43674,6 +45845,7 @@ var init_component_registry_generated = __esm({
43674
45845
  init_ModalSlot();
43675
45846
  init_ModuleCard();
43676
45847
  init_Navigation();
45848
+ init_NegotiatorBoard();
43677
45849
  init_NumberStepper();
43678
45850
  init_OptionConstraintGroup();
43679
45851
  init_OrbitalVisualization();
@@ -43712,6 +45884,7 @@ var init_component_registry_generated = __esm({
43712
45884
  init_SegmentRenderer();
43713
45885
  init_Select();
43714
45886
  init_SequenceBar();
45887
+ init_SequencerBoard();
43715
45888
  init_ServiceCatalog();
43716
45889
  init_ShowcaseCard();
43717
45890
  init_ShowcaseOrganism();
@@ -43720,6 +45893,7 @@ var init_component_registry_generated = __esm({
43720
45893
  init_SignaturePad();
43721
45894
  init_SimpleGrid();
43722
45895
  init_SimulationCanvas();
45896
+ init_SimulatorBoard();
43723
45897
  init_Skeleton();
43724
45898
  init_SocialProof();
43725
45899
  init_SortableList();
@@ -43733,6 +45907,8 @@ var init_component_registry_generated = __esm({
43733
45907
  init_StatBadge();
43734
45908
  init_StatCard();
43735
45909
  init_StatDisplay();
45910
+ init_StateArchitectBoard();
45911
+ init_StateGraph();
43736
45912
  init_StateIndicator();
43737
45913
  init_StateMachineView();
43738
45914
  init_StatsGrid();
@@ -43787,7 +45963,7 @@ var init_component_registry_generated = __esm({
43787
45963
  init_WizardContainer();
43788
45964
  init_WizardNavigation();
43789
45965
  init_WizardProgress();
43790
- ThreeBoundary = class extends React84__default.Component {
45966
+ ThreeBoundary = class extends React96__default.Component {
43791
45967
  constructor() {
43792
45968
  super(...arguments);
43793
45969
  __publicField(this, "state", { failed: false });
@@ -43797,7 +45973,7 @@ var init_component_registry_generated = __esm({
43797
45973
  }
43798
45974
  render() {
43799
45975
  if (this.state.failed) {
43800
- return React84__default.createElement(
45976
+ return React96__default.createElement(
43801
45977
  "div",
43802
45978
  {
43803
45979
  "data-testid": "three-unavailable",
@@ -43843,6 +46019,7 @@ var init_component_registry_generated = __esm({
43843
46019
  "BoxPattern": BoxPattern,
43844
46020
  "BranchingLogicBuilder": BranchingLogicBuilder,
43845
46021
  "Breadcrumb": Breadcrumb,
46022
+ "BuilderBoard": BuilderBoard,
43846
46023
  "Button": ButtonPattern,
43847
46024
  "ButtonPattern": ButtonPattern,
43848
46025
  "CTABanner": CTABanner,
@@ -43860,6 +46037,7 @@ var init_component_registry_generated = __esm({
43860
46037
  "Checkbox": Checkbox,
43861
46038
  "ChemistryCanvas": ChemistryCanvas,
43862
46039
  "ChoiceButton": ChoiceButton,
46040
+ "ClassifierBoard": ClassifierBoard,
43863
46041
  "CodeBlock": CodeBlock,
43864
46042
  "CodeRunnerPanel": CodeRunnerPanel,
43865
46043
  "ComboCounter": ComboCounter,
@@ -43883,6 +46061,7 @@ var init_component_registry_generated = __esm({
43883
46061
  "DateRangePicker": DateRangePicker,
43884
46062
  "DateRangeSelector": DateRangeSelector,
43885
46063
  "DayCell": DayCell,
46064
+ "DebuggerBoard": DebuggerBoard,
43886
46065
  "DetailPanel": DetailPanel,
43887
46066
  "Dialog": Dialog,
43888
46067
  "DialogueBubble": DialogueBubble,
@@ -43900,6 +46079,7 @@ var init_component_registry_generated = __esm({
43900
46079
  "EmptyState": EmptyState,
43901
46080
  "ErrorBoundary": ErrorBoundary,
43902
46081
  "ErrorState": ErrorState,
46082
+ "EventHandlerBoard": EventHandlerBoard,
43903
46083
  "EventLog": EventLog,
43904
46084
  "FeatureCard": FeatureCard,
43905
46085
  "FeatureDetailPageTemplate": FeatureDetailPageTemplate,
@@ -43974,6 +46154,7 @@ var init_component_registry_generated = __esm({
43974
46154
  "ModalSlot": ModalSlot,
43975
46155
  "ModuleCard": ModuleCard,
43976
46156
  "Navigation": Navigation,
46157
+ "NegotiatorBoard": NegotiatorBoard,
43977
46158
  "NumberStepper": NumberStepper,
43978
46159
  "OptionConstraintGroup": OptionConstraintGroup,
43979
46160
  "OrbitalVisualization": OrbitalVisualization,
@@ -44012,6 +46193,7 @@ var init_component_registry_generated = __esm({
44012
46193
  "SegmentRenderer": SegmentRenderer,
44013
46194
  "Select": Select,
44014
46195
  "SequenceBar": SequenceBar,
46196
+ "SequencerBoard": SequencerBoard,
44015
46197
  "ServiceCatalog": ServiceCatalog,
44016
46198
  "ShowcaseCard": ShowcaseCard,
44017
46199
  "ShowcaseOrganism": ShowcaseOrganism,
@@ -44020,6 +46202,7 @@ var init_component_registry_generated = __esm({
44020
46202
  "SignaturePad": SignaturePad,
44021
46203
  "SimpleGrid": SimpleGrid,
44022
46204
  "SimulationCanvas": SimulationCanvas,
46205
+ "SimulatorBoard": SimulatorBoard,
44023
46206
  "Skeleton": Skeleton,
44024
46207
  "SocialProof": SocialProof,
44025
46208
  "SortableList": SortableList,
@@ -44036,6 +46219,8 @@ var init_component_registry_generated = __esm({
44036
46219
  "StatBadge": StatBadge,
44037
46220
  "StatCard": StatCard,
44038
46221
  "StatDisplay": StatDisplay,
46222
+ "StateArchitectBoard": StateArchitectBoard,
46223
+ "StateGraph": StateGraph,
44039
46224
  "StateIndicator": StateIndicator,
44040
46225
  "StateMachineView": StateMachineView,
44041
46226
  "StatsGrid": StatsGrid,
@@ -44109,7 +46294,7 @@ function SuspenseConfigProvider({
44109
46294
  config,
44110
46295
  children
44111
46296
  }) {
44112
- return React84__default.createElement(
46297
+ return React96__default.createElement(
44113
46298
  SuspenseConfigContext.Provider,
44114
46299
  { value: config },
44115
46300
  children
@@ -44151,7 +46336,7 @@ function enrichFormFields(fields, entityDef) {
44151
46336
  }
44152
46337
  return { name: field, label: field.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/\b\w/g, (c) => c.toUpperCase()) };
44153
46338
  }
44154
- if (field && typeof field === "object" && !Array.isArray(field) && !React84__default.isValidElement(field) && !(field instanceof Date)) {
46339
+ if (field && typeof field === "object" && !Array.isArray(field) && !React96__default.isValidElement(field) && !(field instanceof Date)) {
44155
46340
  const obj = field;
44156
46341
  const fieldName = typeof obj.name === "string" ? obj.name : typeof obj.field === "string" ? obj.field : void 0;
44157
46342
  if (!fieldName) return field;
@@ -44604,7 +46789,7 @@ function renderPatternChildren(children, onDismiss, parentId = "root", parentPat
44604
46789
  const key = `${parentId}-${index}-trait:${traitName}`;
44605
46790
  return /* @__PURE__ */ jsx(TraitFrame, { traitName }, key);
44606
46791
  }
44607
- return /* @__PURE__ */ jsx(React84__default.Fragment, { children: child }, `${parentId}-${index}`);
46792
+ return /* @__PURE__ */ jsx(React96__default.Fragment, { children: child }, `${parentId}-${index}`);
44608
46793
  }
44609
46794
  if (!child || typeof child !== "object") return null;
44610
46795
  const childId = `${parentId}-${index}`;
@@ -44644,14 +46829,14 @@ function isPatternConfig(value) {
44644
46829
  if (value === null || value === void 0) return false;
44645
46830
  if (typeof value !== "object") return false;
44646
46831
  if (Array.isArray(value)) return false;
44647
- if (React84__default.isValidElement(value)) return false;
46832
+ if (React96__default.isValidElement(value)) return false;
44648
46833
  if (value instanceof Date) return false;
44649
46834
  if (typeof value === "function") return false;
44650
46835
  const record = value;
44651
46836
  return "type" in record && typeof record.type === "string" && getComponentForPattern$1(record.type) !== null;
44652
46837
  }
44653
46838
  function isPlainConfigObject(value) {
44654
- if (React84__default.isValidElement(value)) return false;
46839
+ if (React96__default.isValidElement(value)) return false;
44655
46840
  if (value instanceof Date) return false;
44656
46841
  const proto = Object.getPrototypeOf(value);
44657
46842
  return proto === Object.prototype || proto === null;
@@ -44777,7 +46962,7 @@ function SlotContentRenderer({
44777
46962
  for (const slotKey of CONTENT_NODE_SLOTS) {
44778
46963
  const slotVal = restProps[slotKey];
44779
46964
  if (slotVal === void 0 || slotVal === null) continue;
44780
- if (React84__default.isValidElement(slotVal) || typeof slotVal === "string" || typeof slotVal === "number" || typeof slotVal === "boolean") continue;
46965
+ if (React96__default.isValidElement(slotVal) || typeof slotVal === "string" || typeof slotVal === "number" || typeof slotVal === "boolean") continue;
44781
46966
  if (Array.isArray(slotVal) || typeof slotVal === "object" && "type" in slotVal) {
44782
46967
  nodeSlotOverrides[slotKey] = renderPatternChildren(
44783
46968
  slotVal,
@@ -44826,7 +47011,7 @@ function SlotContentRenderer({
44826
47011
  const resolvedItems = Array.isArray(entityVal) && entityVal[0] !== "fn" ? entityVal : null;
44827
47012
  if (resolvedItems && resolvedItems.length > 0 && !finalProps.fields && !finalProps.columns) {
44828
47013
  const sample = resolvedItems[0];
44829
- if (sample && typeof sample === "object" && !Array.isArray(sample) && !React84__default.isValidElement(sample) && !(sample instanceof Date)) {
47014
+ if (sample && typeof sample === "object" && !Array.isArray(sample) && !React96__default.isValidElement(sample) && !(sample instanceof Date)) {
44830
47015
  const keys = Object.keys(sample).filter((k) => k !== "id" && k !== "_id");
44831
47016
  finalProps.fields = keys.map((k, i) => ({ name: k, variant: i === 0 ? "h4" : "body" }));
44832
47017
  }
@@ -45118,7 +47303,7 @@ function resolveLambdaBindings(body, params, item, index) {
45118
47303
  if (Array.isArray(body)) {
45119
47304
  return body.map((b) => recur(b));
45120
47305
  }
45121
- if (body !== null && typeof body === "object" && !React84__default.isValidElement(body) && !(body instanceof Date) && typeof body !== "function") {
47306
+ if (body !== null && typeof body === "object" && !React96__default.isValidElement(body) && !(body instanceof Date) && typeof body !== "function") {
45122
47307
  const out = {};
45123
47308
  for (const [k, v] of Object.entries(body)) {
45124
47309
  out[k] = recur(v);
@@ -45137,7 +47322,7 @@ function getSlotContentRenderer2() {
45137
47322
  function makeLambdaFn(params, lambdaBody, callerKey) {
45138
47323
  return (item, index) => {
45139
47324
  const resolvedBody = resolveLambdaBindings(lambdaBody, params, item, index);
45140
- if (resolvedBody === null || typeof resolvedBody !== "object" || Array.isArray(resolvedBody) || typeof resolvedBody === "function" || React84__default.isValidElement(resolvedBody) || resolvedBody instanceof Date) {
47325
+ if (resolvedBody === null || typeof resolvedBody !== "object" || Array.isArray(resolvedBody) || typeof resolvedBody === "function" || React96__default.isValidElement(resolvedBody) || resolvedBody instanceof Date) {
45141
47326
  return null;
45142
47327
  }
45143
47328
  const record = resolvedBody;
@@ -45156,7 +47341,7 @@ function makeLambdaFn(params, lambdaBody, callerKey) {
45156
47341
  props: childProps,
45157
47342
  priority: 0
45158
47343
  };
45159
- return React84__default.createElement(SlotContentRenderer2, { content: childContent });
47344
+ return React96__default.createElement(SlotContentRenderer2, { content: childContent });
45160
47345
  };
45161
47346
  }
45162
47347
  function convertNode(node, callerKey) {
@@ -45175,7 +47360,7 @@ function convertNode(node, callerKey) {
45175
47360
  });
45176
47361
  return anyChanged ? mapped : node;
45177
47362
  }
45178
- if (typeof node === "object" && !React84__default.isValidElement(node) && !(node instanceof Date)) {
47363
+ if (typeof node === "object" && !React96__default.isValidElement(node) && !(node instanceof Date)) {
45179
47364
  return convertObjectProps(node);
45180
47365
  }
45181
47366
  return node;
@@ -46321,11 +48506,11 @@ function buildMockData(schema) {
46321
48506
  result[entityName] = entity.instances;
46322
48507
  continue;
46323
48508
  }
46324
- const rows = Array.from(
48509
+ const rows2 = Array.from(
46325
48510
  { length: 10 },
46326
48511
  (_, i) => generateEntityRow(entity, i + 1)
46327
48512
  );
46328
- result[entityName] = rows;
48513
+ result[entityName] = rows2;
46329
48514
  }
46330
48515
  for (const orbital of schema.orbitals) {
46331
48516
  for (const traitRef of orbital.traits ?? []) {