@almadar/ui 5.70.0 → 5.72.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 (63) hide show
  1. package/dist/avl/index.cjs +2198 -2218
  2. package/dist/avl/index.d.cts +93 -56
  3. package/dist/avl/index.js +931 -951
  4. package/dist/components/avl/molecules/AvlEventWireEdge.d.ts +2 -1
  5. package/dist/components/avl/molecules/AvlTransitionEdge.d.ts +2 -1
  6. package/dist/components/avl/molecules/avl-behavior-compose-converter.d.ts +7 -5
  7. package/dist/components/avl/molecules/avl-behavior-compose-types.d.ts +41 -21
  8. package/dist/components/avl/molecules/avl-canvas-types.d.ts +10 -7
  9. package/dist/components/avl/molecules/avl-preview-converter.d.ts +5 -5
  10. package/dist/components/avl/molecules/avl-preview-types.d.ts +15 -4
  11. package/dist/components/avl/organisms/FlowCanvas.d.ts +2 -2
  12. package/dist/components/avl/organisms/avl-schema-parser.d.ts +18 -16
  13. package/dist/components/core/atoms/Button.d.ts +2 -0
  14. package/dist/components/core/atoms/ConditionalWrapper.d.ts +5 -4
  15. package/dist/components/core/molecules/Carousel.d.ts +2 -2
  16. package/dist/components/core/molecules/OrbitalVisualization.d.ts +4 -3
  17. package/dist/components/core/molecules/PageHeader.d.ts +3 -3
  18. package/dist/components/core/molecules/RepeatableFormSection.d.ts +4 -3
  19. package/dist/components/core/molecules/ViolationAlert.d.ts +2 -0
  20. package/dist/components/core/molecules/WizardContainer.d.ts +23 -22
  21. package/dist/components/core/organisms/CardGrid.d.ts +2 -2
  22. package/dist/components/core/organisms/CustomPattern.d.ts +3 -4
  23. package/dist/components/core/organisms/DataTable.d.ts +2 -2
  24. package/dist/components/core/organisms/DetailPanel.d.ts +1 -1
  25. package/dist/components/core/organisms/Form.d.ts +11 -11
  26. package/dist/components/core/organisms/List.d.ts +3 -5
  27. package/dist/components/core/organisms/StatCard.d.ts +2 -2
  28. package/dist/components/core/organisms/book/types.d.ts +1 -1
  29. package/dist/components/core/organisms/debug/RuntimeDebugger.d.ts +2 -1
  30. package/dist/components/core/organisms/debug/tabs/EventDispatcherTab.d.ts +2 -1
  31. package/dist/components/core/organisms/layout/DashboardGrid.d.ts +0 -2
  32. package/dist/components/core/organisms/types.d.ts +3 -2
  33. package/dist/components/game/atoms/ScoreDisplay.d.ts +3 -3
  34. package/dist/components/game/atoms/Sprite.d.ts +6 -1
  35. package/dist/components/game/atoms/XPBar.d.ts +1 -1
  36. package/dist/components/game/molecules/GameCanvas3D.d.ts +0 -2
  37. package/dist/components/game/molecules/IsometricCanvas.d.ts +4 -2
  38. package/dist/components/game/molecules/PlatformerCanvas.d.ts +4 -1
  39. package/dist/components/game/molecules/StatBadge.d.ts +3 -1
  40. package/dist/components/game/molecules/three/hooks/useSceneGraph.d.ts +2 -1
  41. package/dist/components/game/molecules/three/index.cjs +41 -105
  42. package/dist/components/game/molecules/three/index.js +41 -105
  43. package/dist/components/game/molecules/useUnitSpriteAtlas.d.ts +3 -2
  44. package/dist/components/game/organisms/PinballBoard.d.ts +4 -4
  45. package/dist/components/game/organisms/boardEntity.d.ts +6 -6
  46. package/dist/components/game/organisms/puzzles/debugger/DebuggerBoard.d.ts +16 -2
  47. package/dist/components/game/organisms/puzzles/event-handler/puzzleObject.d.ts +21 -10
  48. package/dist/components/game/organisms/puzzles/state-architect/StateJsonView.d.ts +2 -1
  49. package/dist/components/game/organisms/types/isometric.d.ts +16 -0
  50. package/dist/components/index.cjs +2228 -2251
  51. package/dist/components/index.js +1116 -1139
  52. package/dist/docs/index.cjs +107 -104
  53. package/dist/docs/index.d.cts +2 -0
  54. package/dist/docs/index.js +38 -35
  55. package/dist/lib/getNestedValue.d.ts +2 -13
  56. package/dist/marketing/index.cjs +97 -98
  57. package/dist/marketing/index.d.cts +2 -0
  58. package/dist/marketing/index.js +54 -55
  59. package/dist/providers/index.cjs +1908 -1951
  60. package/dist/providers/index.js +808 -851
  61. package/dist/runtime/index.cjs +1966 -2009
  62. package/dist/runtime/index.js +814 -857
  63. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
- import * as React85 from 'react';
2
- import React85__default, { createContext, useMemo, useContext, useRef, useEffect, useCallback, Suspense, useState, useSyncExternalStore, useLayoutEffect, lazy, useId, forwardRef, useImperativeHandle, Component } from 'react';
1
+ import * as React87 from 'react';
2
+ import React87__default, { createContext, useMemo, useContext, useRef, useEffect, useCallback, Suspense, useState, useSyncExternalStore, useLayoutEffect, lazy, useId, forwardRef, useImperativeHandle, Component } from 'react';
3
3
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
4
  import { clsx } from 'clsx';
5
5
  import { twMerge } from 'tailwind-merge';
@@ -445,7 +445,7 @@ var init_Box = __esm({
445
445
  fixed: "fixed",
446
446
  sticky: "sticky"
447
447
  };
448
- Box = React85__default.forwardRef(
448
+ Box = React87__default.forwardRef(
449
449
  ({
450
450
  padding,
451
451
  paddingX,
@@ -510,7 +510,7 @@ var init_Box = __esm({
510
510
  onPointerDown?.(e);
511
511
  }, [hoverEvent, tapReveal, triggerProps, onPointerDown]);
512
512
  const isClickable = action || onClick;
513
- return React85__default.createElement(
513
+ return React87__default.createElement(
514
514
  Component2,
515
515
  {
516
516
  ref,
@@ -606,7 +606,7 @@ function loadLib(key, importer) {
606
606
  return p2;
607
607
  }
608
608
  function lazyFamilyIcon(libKey, importer, pick, fallbackName, family) {
609
- const Lazy = React85__default.lazy(async () => {
609
+ const Lazy = React87__default.lazy(async () => {
610
610
  const lib = await loadLib(libKey, importer);
611
611
  const Comp = pick(lib);
612
612
  if (!Comp) {
@@ -616,7 +616,7 @@ function lazyFamilyIcon(libKey, importer, pick, fallbackName, family) {
616
616
  return { default: Comp };
617
617
  });
618
618
  const Wrapped = (props) => /* @__PURE__ */ jsx(
619
- React85__default.Suspense,
619
+ React87__default.Suspense,
620
620
  {
621
621
  fallback: /* @__PURE__ */ jsx(
622
622
  "span",
@@ -1284,9 +1284,10 @@ function resolveIcon(name) {
1284
1284
  function doResolve(name) {
1285
1285
  if (iconAliases[name]) return iconAliases[name];
1286
1286
  const pascalName = kebabToPascal2(name);
1287
- const directLookup = LucideIcons2[pascalName];
1287
+ const lucideMap = LucideIcons2;
1288
+ const directLookup = lucideMap[pascalName];
1288
1289
  if (directLookup && typeof directLookup === "object") return directLookup;
1289
- const asIs = LucideIcons2[name];
1290
+ const asIs = lucideMap[name];
1290
1291
  if (asIs && typeof asIs === "object") return asIs;
1291
1292
  return LucideIcons2.HelpCircle;
1292
1293
  }
@@ -1342,7 +1343,7 @@ var init_Icon = __esm({
1342
1343
  const directIcon = typeof icon === "string" ? void 0 : icon;
1343
1344
  const effectiveName = typeof icon === "string" ? icon : name;
1344
1345
  const family = useIconFamily();
1345
- const RenderedComponent = React85__default.useMemo(() => {
1346
+ const RenderedComponent = React87__default.useMemo(() => {
1346
1347
  if (directIcon) return null;
1347
1348
  return effectiveName ? resolveIconForFamily(effectiveName, family) : null;
1348
1349
  }, [directIcon, effectiveName, family]);
@@ -1392,6 +1393,9 @@ var init_Icon = __esm({
1392
1393
  Icon.displayName = "Icon";
1393
1394
  }
1394
1395
  });
1396
+ function isIconLike(v) {
1397
+ return typeof v.render === "function";
1398
+ }
1395
1399
  function resolveIconProp(value, sizeClass) {
1396
1400
  if (!value) return null;
1397
1401
  if (typeof value === "string") {
@@ -1401,10 +1405,10 @@ function resolveIconProp(value, sizeClass) {
1401
1405
  const IconComp = value;
1402
1406
  return /* @__PURE__ */ jsx(IconComp, { className: sizeClass });
1403
1407
  }
1404
- if (React85__default.isValidElement(value)) {
1408
+ if (React87__default.isValidElement(value)) {
1405
1409
  return value;
1406
1410
  }
1407
- if (typeof value === "object" && value !== null && "render" in value) {
1411
+ if (typeof value === "object" && value !== null && isIconLike(value)) {
1408
1412
  const IconComp = value;
1409
1413
  return /* @__PURE__ */ jsx(IconComp, { className: sizeClass });
1410
1414
  }
@@ -1477,7 +1481,7 @@ var init_Button = __esm({
1477
1481
  md: "h-icon-default w-icon-default",
1478
1482
  lg: "h-icon-default w-icon-default"
1479
1483
  };
1480
- Button = React85__default.forwardRef(
1484
+ Button = React87__default.forwardRef(
1481
1485
  ({
1482
1486
  className,
1483
1487
  variant = "primary",
@@ -1493,6 +1497,7 @@ var init_Button = __esm({
1493
1497
  label,
1494
1498
  children,
1495
1499
  onClick,
1500
+ "data-testid": dataTestId,
1496
1501
  ...props
1497
1502
  }, ref) => {
1498
1503
  const eventBus = useEventBus();
@@ -1525,7 +1530,7 @@ var init_Button = __esm({
1525
1530
  ),
1526
1531
  onClick: handleClick,
1527
1532
  ...props,
1528
- "data-testid": props["data-testid"] ?? (action ? `action-${action}` : void 0),
1533
+ "data-testid": dataTestId ?? (action ? `action-${action}` : void 0),
1529
1534
  children: [
1530
1535
  isLoading ? /* @__PURE__ */ jsx(Loader2, { className: "h-icon-default w-icon-default animate-spin" }) : resolvedLeftIcon && /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", children: resolvedLeftIcon }),
1531
1536
  children || label,
@@ -1542,7 +1547,7 @@ var Dialog;
1542
1547
  var init_Dialog = __esm({
1543
1548
  "components/core/atoms/Dialog.tsx"() {
1544
1549
  init_cn();
1545
- Dialog = React85__default.forwardRef(
1550
+ Dialog = React87__default.forwardRef(
1546
1551
  ({
1547
1552
  role = "dialog",
1548
1553
  "aria-modal": ariaModal = true,
@@ -1660,9 +1665,8 @@ var init_Typography = __esm({
1660
1665
  }) => {
1661
1666
  const variant = variantProp ?? (level ? `h${level}` : "body1");
1662
1667
  const Component2 = as || defaultElements[variant];
1663
- const Comp = Component2;
1664
- return /* @__PURE__ */ jsx(
1665
- Comp,
1668
+ return React87__default.createElement(
1669
+ Component2,
1666
1670
  {
1667
1671
  id,
1668
1672
  className: cn(
@@ -1675,9 +1679,9 @@ var init_Typography = __esm({
1675
1679
  overflow && overflowStyles2[overflow],
1676
1680
  className
1677
1681
  ),
1678
- style,
1679
- children: children ?? content
1680
- }
1682
+ style
1683
+ },
1684
+ children ?? content
1681
1685
  );
1682
1686
  };
1683
1687
  Typography.displayName = "Typography";
@@ -2156,7 +2160,7 @@ var init_Badge = __esm({
2156
2160
  md: "px-2.5 py-1 text-sm",
2157
2161
  lg: "px-3 py-1.5 text-base"
2158
2162
  };
2159
- Badge = React85__default.forwardRef(
2163
+ Badge = React87__default.forwardRef(
2160
2164
  ({ className, variant = "default", size = "sm", amount, label, icon, children, onRemove, removeLabel, ...props }, ref) => {
2161
2165
  const iconSizes3 = {
2162
2166
  sm: "h-icon-default w-icon-default",
@@ -2492,7 +2496,7 @@ var init_SvgFlow = __esm({
2492
2496
  width = 100,
2493
2497
  height = 100
2494
2498
  }) => {
2495
- const markerId = React85__default.useMemo(() => {
2499
+ const markerId = React87__default.useMemo(() => {
2496
2500
  flowIdCounter += 1;
2497
2501
  return `almadar-flow-arrow-${flowIdCounter}`;
2498
2502
  }, []);
@@ -3085,7 +3089,7 @@ var init_SvgRing = __esm({
3085
3089
  width = 100,
3086
3090
  height = 100
3087
3091
  }) => {
3088
- const gradientId = React85__default.useMemo(() => {
3092
+ const gradientId = React87__default.useMemo(() => {
3089
3093
  ringIdCounter += 1;
3090
3094
  return `almadar-ring-glow-${ringIdCounter}`;
3091
3095
  }, []);
@@ -3266,7 +3270,7 @@ var init_Input = __esm({
3266
3270
  init_cn();
3267
3271
  init_Icon();
3268
3272
  init_useEventBus();
3269
- Input = React85__default.forwardRef(
3273
+ Input = React87__default.forwardRef(
3270
3274
  ({
3271
3275
  className,
3272
3276
  inputType,
@@ -3426,7 +3430,7 @@ var Label;
3426
3430
  var init_Label = __esm({
3427
3431
  "components/core/atoms/Label.tsx"() {
3428
3432
  init_cn();
3429
- Label = React85__default.forwardRef(
3433
+ Label = React87__default.forwardRef(
3430
3434
  ({ className, required, children, ...props }, ref) => {
3431
3435
  return /* @__PURE__ */ jsxs(
3432
3436
  "label",
@@ -3453,7 +3457,7 @@ var init_Textarea = __esm({
3453
3457
  "components/core/atoms/Textarea.tsx"() {
3454
3458
  init_cn();
3455
3459
  init_useEventBus();
3456
- Textarea = React85__default.forwardRef(
3460
+ Textarea = React87__default.forwardRef(
3457
3461
  ({ className, error, onChange, ...props }, ref) => {
3458
3462
  const eventBus = useEventBus();
3459
3463
  const handleChange = (e) => {
@@ -3692,7 +3696,7 @@ var init_Select = __esm({
3692
3696
  init_cn();
3693
3697
  init_Icon();
3694
3698
  init_useEventBus();
3695
- Select = React85__default.forwardRef(
3699
+ Select = React87__default.forwardRef(
3696
3700
  (props, _ref) => {
3697
3701
  const { multiple, searchable, clearable } = props;
3698
3702
  if (multiple || searchable || clearable) {
@@ -3709,7 +3713,7 @@ var init_Checkbox = __esm({
3709
3713
  "components/core/atoms/Checkbox.tsx"() {
3710
3714
  init_cn();
3711
3715
  init_useEventBus();
3712
- Checkbox = React85__default.forwardRef(
3716
+ Checkbox = React87__default.forwardRef(
3713
3717
  ({ className, label, id, onChange, ...props }, ref) => {
3714
3718
  const inputId = id || `checkbox-${Math.random().toString(36).substr(2, 9)}`;
3715
3719
  const eventBus = useEventBus();
@@ -3763,7 +3767,7 @@ var init_Spinner = __esm({
3763
3767
  md: "h-6 w-6",
3764
3768
  lg: "h-8 w-8"
3765
3769
  };
3766
- Spinner = React85__default.forwardRef(
3770
+ Spinner = React87__default.forwardRef(
3767
3771
  ({ className, size = "md", overlay, ...props }, ref) => {
3768
3772
  if (overlay) {
3769
3773
  return /* @__PURE__ */ jsx(
@@ -3853,7 +3857,7 @@ var init_Card = __esm({
3853
3857
  chip: "shadow-none rounded-pill border-[length:var(--border-width)] border-border",
3854
3858
  "tile-image-first": "p-0 overflow-hidden"
3855
3859
  };
3856
- Card = React85__default.forwardRef(
3860
+ Card = React87__default.forwardRef(
3857
3861
  ({
3858
3862
  className,
3859
3863
  variant = "bordered",
@@ -3901,9 +3905,9 @@ var init_Card = __esm({
3901
3905
  }
3902
3906
  );
3903
3907
  Card.displayName = "Card";
3904
- CardHeader = React85__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("mb-4", className), ...props }));
3908
+ CardHeader = React87__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("mb-4", className), ...props }));
3905
3909
  CardHeader.displayName = "CardHeader";
3906
- CardTitle = React85__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3910
+ CardTitle = React87__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3907
3911
  "h3",
3908
3912
  {
3909
3913
  ref,
@@ -3916,11 +3920,11 @@ var init_Card = __esm({
3916
3920
  }
3917
3921
  ));
3918
3922
  CardTitle.displayName = "CardTitle";
3919
- CardContent = React85__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("", className), ...props }));
3923
+ CardContent = React87__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("", className), ...props }));
3920
3924
  CardContent.displayName = "CardContent";
3921
3925
  CardBody = CardContent;
3922
3926
  CardBody.displayName = "CardBody";
3923
- CardFooter = React85__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3927
+ CardFooter = React87__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3924
3928
  "div",
3925
3929
  {
3926
3930
  ref,
@@ -3975,7 +3979,7 @@ var init_FilterPill = __esm({
3975
3979
  md: "w-3.5 h-3.5",
3976
3980
  lg: "w-4 h-4"
3977
3981
  };
3978
- FilterPill = React85__default.forwardRef(
3982
+ FilterPill = React87__default.forwardRef(
3979
3983
  ({
3980
3984
  className,
3981
3985
  variant = "default",
@@ -4104,8 +4108,8 @@ var init_Avatar = __esm({
4104
4108
  actionPayload
4105
4109
  }) => {
4106
4110
  const eventBus = useEventBus();
4107
- const [imgFailed, setImgFailed] = React85__default.useState(false);
4108
- React85__default.useEffect(() => {
4111
+ const [imgFailed, setImgFailed] = React87__default.useState(false);
4112
+ React87__default.useEffect(() => {
4109
4113
  setImgFailed(false);
4110
4114
  }, [src]);
4111
4115
  const initials = providedInitials ?? (name ? generateInitials(name) : void 0);
@@ -4218,22 +4222,18 @@ var init_Center = __esm({
4218
4222
  as: Component2 = "div"
4219
4223
  }) => {
4220
4224
  const mergedStyle = minHeight ? { minHeight, ...style } : style;
4221
- const Comp = Component2;
4222
- return /* @__PURE__ */ jsx(
4223
- Comp,
4224
- {
4225
- className: cn(
4226
- inline ? "inline-flex" : "flex",
4227
- horizontal && "justify-center",
4228
- vertical && "items-center",
4229
- fullHeight && "h-full",
4230
- fullWidth && "w-full",
4231
- className
4232
- ),
4233
- style: mergedStyle,
4234
- children
4235
- }
4236
- );
4225
+ return React87__default.createElement(Component2, {
4226
+ className: cn(
4227
+ inline ? "inline-flex" : "flex",
4228
+ horizontal && "justify-center",
4229
+ vertical && "items-center",
4230
+ fullHeight && "h-full",
4231
+ fullWidth && "w-full",
4232
+ className
4233
+ ),
4234
+ style: mergedStyle,
4235
+ children
4236
+ });
4237
4237
  };
4238
4238
  }
4239
4239
  });
@@ -4490,7 +4490,7 @@ var init_Radio = __esm({
4490
4490
  md: "w-2.5 h-2.5",
4491
4491
  lg: "w-3 h-3"
4492
4492
  };
4493
- Radio = React85__default.forwardRef(
4493
+ Radio = React87__default.forwardRef(
4494
4494
  ({
4495
4495
  label,
4496
4496
  helperText,
@@ -4507,12 +4507,12 @@ var init_Radio = __esm({
4507
4507
  onChange,
4508
4508
  ...props
4509
4509
  }, ref) => {
4510
- const reactId = React85__default.useId();
4510
+ const reactId = React87__default.useId();
4511
4511
  const baseId = id || `radio-${reactId}`;
4512
4512
  const hasError = !!error;
4513
4513
  const eventBus = useEventBus();
4514
- const [selected, setSelected] = React85__default.useState(value);
4515
- React85__default.useEffect(() => {
4514
+ const [selected, setSelected] = React87__default.useState(value);
4515
+ React87__default.useEffect(() => {
4516
4516
  if (value !== void 0) setSelected(value);
4517
4517
  }, [value]);
4518
4518
  const pick = (next, e) => {
@@ -4694,7 +4694,7 @@ var init_Switch = __esm({
4694
4694
  "components/core/atoms/Switch.tsx"() {
4695
4695
  "use client";
4696
4696
  init_cn();
4697
- Switch = React85.forwardRef(
4697
+ Switch = React87.forwardRef(
4698
4698
  ({
4699
4699
  checked,
4700
4700
  defaultChecked = false,
@@ -4705,10 +4705,10 @@ var init_Switch = __esm({
4705
4705
  name,
4706
4706
  className
4707
4707
  }, ref) => {
4708
- const [isChecked, setIsChecked] = React85.useState(
4708
+ const [isChecked, setIsChecked] = React87.useState(
4709
4709
  checked !== void 0 ? checked : defaultChecked
4710
4710
  );
4711
- React85.useEffect(() => {
4711
+ React87.useEffect(() => {
4712
4712
  if (checked !== void 0) {
4713
4713
  setIsChecked(checked);
4714
4714
  }
@@ -4867,9 +4867,8 @@ var init_Stack = __esm({
4867
4867
  };
4868
4868
  const isHorizontal = direction === "horizontal";
4869
4869
  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";
4870
- const Comp = Component2;
4871
- return /* @__PURE__ */ jsx(
4872
- Comp,
4870
+ return React87__default.createElement(
4871
+ Component2,
4873
4872
  {
4874
4873
  className: cn(
4875
4874
  "flex",
@@ -4885,9 +4884,9 @@ var init_Stack = __esm({
4885
4884
  onClick: action || onClick ? handleClick : void 0,
4886
4885
  onKeyDown,
4887
4886
  role,
4888
- tabIndex,
4889
- children
4890
- }
4887
+ tabIndex
4888
+ },
4889
+ children
4891
4890
  );
4892
4891
  };
4893
4892
  VStack = (props) => /* @__PURE__ */ jsx(Stack, { direction: "vertical", ...props });
@@ -5068,7 +5067,7 @@ var Aside;
5068
5067
  var init_Aside = __esm({
5069
5068
  "components/core/atoms/Aside.tsx"() {
5070
5069
  init_cn();
5071
- Aside = React85__default.forwardRef(
5070
+ Aside = React87__default.forwardRef(
5072
5071
  ({ className, children, ...rest }, ref) => /* @__PURE__ */ jsx("aside", { ref, className: cn(className), ...rest, children })
5073
5072
  );
5074
5073
  Aside.displayName = "Aside";
@@ -5147,9 +5146,9 @@ var init_LawReferenceTooltip = __esm({
5147
5146
  className
5148
5147
  }) => {
5149
5148
  const { t } = useTranslate();
5150
- const [isVisible, setIsVisible] = React85__default.useState(false);
5151
- const timeoutRef = React85__default.useRef(null);
5152
- const triggerRef = React85__default.useRef(null);
5149
+ const [isVisible, setIsVisible] = React87__default.useState(false);
5150
+ const timeoutRef = React87__default.useRef(null);
5151
+ const triggerRef = React87__default.useRef(null);
5153
5152
  const handleMouseEnter = () => {
5154
5153
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
5155
5154
  timeoutRef.current = setTimeout(() => setIsVisible(true), 200);
@@ -5160,7 +5159,7 @@ var init_LawReferenceTooltip = __esm({
5160
5159
  };
5161
5160
  const { revealed, triggerProps } = useTapReveal({ refs: [triggerRef] });
5162
5161
  const open = isVisible || revealed;
5163
- React85__default.useEffect(() => {
5162
+ React87__default.useEffect(() => {
5164
5163
  return () => {
5165
5164
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
5166
5165
  };
@@ -5372,7 +5371,7 @@ var init_StatusDot = __esm({
5372
5371
  md: "w-2.5 h-2.5",
5373
5372
  lg: "w-3 h-3"
5374
5373
  };
5375
- StatusDot = React85__default.forwardRef(
5374
+ StatusDot = React87__default.forwardRef(
5376
5375
  ({ className, status = "offline", pulse = false, size = "md", label, ...props }, ref) => {
5377
5376
  return /* @__PURE__ */ jsx(
5378
5377
  "span",
@@ -5426,7 +5425,7 @@ var init_TrendIndicator = __esm({
5426
5425
  down: "trending-down",
5427
5426
  flat: "arrow-right"
5428
5427
  };
5429
- TrendIndicator = React85__default.forwardRef(
5428
+ TrendIndicator = React87__default.forwardRef(
5430
5429
  ({
5431
5430
  className,
5432
5431
  value,
@@ -5493,7 +5492,7 @@ var init_RangeSlider = __esm({
5493
5492
  md: "w-4 h-4",
5494
5493
  lg: "w-5 h-5"
5495
5494
  };
5496
- RangeSlider = React85__default.forwardRef(
5495
+ RangeSlider = React87__default.forwardRef(
5497
5496
  ({
5498
5497
  className,
5499
5498
  min = 0,
@@ -6001,7 +6000,7 @@ var init_ContentSection = __esm({
6001
6000
  md: "py-16",
6002
6001
  lg: "py-24"
6003
6002
  };
6004
- ContentSection = React85__default.forwardRef(
6003
+ ContentSection = React87__default.forwardRef(
6005
6004
  ({ children, background = "default", padding = "lg", id, className }, ref) => {
6006
6005
  return /* @__PURE__ */ jsx(
6007
6006
  Box,
@@ -6535,7 +6534,7 @@ var init_AnimatedReveal = __esm({
6535
6534
  "scale-up": { opacity: 1, transform: "scale(1) translateY(0)" },
6536
6535
  "none": {}
6537
6536
  };
6538
- AnimatedReveal = React85__default.forwardRef(
6537
+ AnimatedReveal = React87__default.forwardRef(
6539
6538
  ({
6540
6539
  trigger = "scroll",
6541
6540
  animation = "fade-up",
@@ -6695,7 +6694,7 @@ var init_AnimatedGraphic = __esm({
6695
6694
  "components/marketing/atoms/AnimatedGraphic.tsx"() {
6696
6695
  "use client";
6697
6696
  init_cn();
6698
- AnimatedGraphic = React85__default.forwardRef(
6697
+ AnimatedGraphic = React87__default.forwardRef(
6699
6698
  ({
6700
6699
  src,
6701
6700
  svgContent,
@@ -6718,7 +6717,7 @@ var init_AnimatedGraphic = __esm({
6718
6717
  const fetchedSvg = useFetchedSvg(svgContent ? void 0 : src);
6719
6718
  const resolvedSvg = svgContent ?? fetchedSvg;
6720
6719
  const prevAnimateRef = useRef(animate);
6721
- const setRef = React85__default.useCallback(
6720
+ const setRef = React87__default.useCallback(
6722
6721
  (node) => {
6723
6722
  containerRef.current = node;
6724
6723
  if (typeof ref === "function") ref(node);
@@ -6935,48 +6934,21 @@ var init_HealthBar = __esm({
6935
6934
  function ScoreDisplay({
6936
6935
  assetUrl = DEFAULT_ASSET_URL,
6937
6936
  value,
6937
+ score,
6938
6938
  label,
6939
6939
  icon,
6940
6940
  size = "md",
6941
6941
  className,
6942
- animated = true,
6943
- locale = "en-US",
6944
- ...rest
6942
+ locale = "en-US"
6945
6943
  }) {
6946
- const resolvedValue = typeof value === "number" && !Number.isNaN(value) ? value : typeof rest.score === "number" && !Number.isNaN(rest.score) ? rest.score : 0;
6947
- const [displayValue, setDisplayValue] = React85.useState(resolvedValue);
6948
- const [isAnimating, setIsAnimating] = React85.useState(false);
6949
- React85.useEffect(() => {
6950
- if (!animated || displayValue === resolvedValue) {
6951
- setDisplayValue(resolvedValue);
6952
- return;
6953
- }
6954
- setIsAnimating(true);
6955
- const diff = resolvedValue - displayValue;
6956
- const steps = Math.min(Math.abs(diff), 20);
6957
- const increment = diff / steps;
6958
- let current = displayValue;
6959
- let step = 0;
6960
- const timer = setInterval(() => {
6961
- step++;
6962
- current += increment;
6963
- setDisplayValue(Math.round(current));
6964
- if (step >= steps) {
6965
- clearInterval(timer);
6966
- setDisplayValue(resolvedValue);
6967
- setIsAnimating(false);
6968
- }
6969
- }, 50);
6970
- return () => clearInterval(timer);
6971
- }, [resolvedValue, animated]);
6972
- const formattedValue = new Intl.NumberFormat(locale).format(displayValue);
6944
+ const resolvedValue = typeof value === "number" && !Number.isNaN(value) ? value : typeof score === "number" && !Number.isNaN(score) ? score : 0;
6945
+ const formattedValue = new Intl.NumberFormat(locale).format(resolvedValue);
6973
6946
  return /* @__PURE__ */ jsxs(
6974
6947
  "div",
6975
6948
  {
6976
6949
  className: cn(
6977
6950
  "flex items-center gap-2 font-bold",
6978
6951
  sizeMap2[size],
6979
- isAnimating && "animate-pulse",
6980
6952
  className
6981
6953
  ),
6982
6954
  children: [
@@ -7000,7 +6972,6 @@ function ScoreDisplay({
7000
6972
  var sizeMap2, DEFAULT_ASSET_URL;
7001
6973
  var init_ScoreDisplay = __esm({
7002
6974
  "components/game/atoms/ScoreDisplay.tsx"() {
7003
- "use client";
7004
6975
  init_cn();
7005
6976
  init_Icon();
7006
6977
  sizeMap2 = {
@@ -7029,9 +7000,9 @@ function ControlButton({
7029
7000
  className
7030
7001
  }) {
7031
7002
  const eventBus = useEventBus();
7032
- const [isPressed, setIsPressed] = React85.useState(false);
7003
+ const [isPressed, setIsPressed] = React87.useState(false);
7033
7004
  const actualPressed = pressed ?? isPressed;
7034
- const handlePointerDown = React85.useCallback(
7005
+ const handlePointerDown = React87.useCallback(
7035
7006
  (e) => {
7036
7007
  e.preventDefault();
7037
7008
  if (disabled) return;
@@ -7041,7 +7012,7 @@ function ControlButton({
7041
7012
  },
7042
7013
  [disabled, pressEvent, eventBus, onPress]
7043
7014
  );
7044
- const handlePointerUp = React85.useCallback(
7015
+ const handlePointerUp = React87.useCallback(
7045
7016
  (e) => {
7046
7017
  e.preventDefault();
7047
7018
  if (disabled) return;
@@ -7051,7 +7022,7 @@ function ControlButton({
7051
7022
  },
7052
7023
  [disabled, releaseEvent, eventBus, onRelease]
7053
7024
  );
7054
- const handlePointerLeave = React85.useCallback(
7025
+ const handlePointerLeave = React87.useCallback(
7055
7026
  (e) => {
7056
7027
  if (isPressed) {
7057
7028
  setIsPressed(false);
@@ -7139,13 +7110,6 @@ var init_spriteSheetConstants = __esm({
7139
7110
  });
7140
7111
 
7141
7112
  // components/game/organisms/utils/spriteAnimation.ts
7142
- function inferDirection(dx, dy) {
7143
- if (dx === 0 && dy === 0) return "se";
7144
- if (dx >= 0 && dy >= 0) return "se";
7145
- if (dx <= 0 && dy >= 0) return "sw";
7146
- if (dx >= 0 && dy <= 0) return "ne";
7147
- return "nw";
7148
- }
7149
7113
  function resolveSheetDirection(facing) {
7150
7114
  switch (facing) {
7151
7115
  case "se":
@@ -7166,19 +7130,6 @@ function frameRect(frame, row, columns, frameWidth, frameHeight) {
7166
7130
  sh: frameHeight
7167
7131
  };
7168
7132
  }
7169
- function getCurrentFrameFromDef(def, elapsed) {
7170
- const frameDuration = 1e3 / def.frameRate;
7171
- const totalDuration = def.frames * frameDuration;
7172
- if (def.loop) {
7173
- const frame2 = Math.floor(elapsed % totalDuration / frameDuration);
7174
- return { frame: frame2, finished: false };
7175
- }
7176
- if (elapsed >= totalDuration) {
7177
- return { frame: def.frames - 1, finished: true };
7178
- }
7179
- const frame = Math.floor(elapsed / frameDuration);
7180
- return { frame, finished: false };
7181
- }
7182
7133
  var init_spriteAnimation = __esm({
7183
7134
  "components/game/organisms/utils/spriteAnimation.ts"() {
7184
7135
  }
@@ -7197,6 +7148,8 @@ function Sprite({
7197
7148
  opacity = 1,
7198
7149
  zIndex = 0,
7199
7150
  columns = 16,
7151
+ animState: _animState,
7152
+ frameRate: _frameRate,
7200
7153
  className,
7201
7154
  onClick,
7202
7155
  action
@@ -7680,21 +7633,6 @@ function XPBar({
7680
7633
  }) {
7681
7634
  const sizes = sizeMap9[size];
7682
7635
  const percentage = max > 0 ? Math.max(0, Math.min(100, current / max * 100)) : 0;
7683
- const [fillWidth, setFillWidth] = React85.useState(animated ? 0 : percentage);
7684
- React85.useEffect(() => {
7685
- if (!animated) {
7686
- setFillWidth(percentage);
7687
- return;
7688
- }
7689
- let frame2;
7690
- const frame1 = requestAnimationFrame(() => {
7691
- frame2 = requestAnimationFrame(() => setFillWidth(percentage));
7692
- });
7693
- return () => {
7694
- cancelAnimationFrame(frame1);
7695
- cancelAnimationFrame(frame2);
7696
- };
7697
- }, [animated, percentage]);
7698
7636
  return /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-2", className), children: [
7699
7637
  level != null && /* @__PURE__ */ jsxs(
7700
7638
  "span",
@@ -7726,7 +7664,7 @@ function XPBar({
7726
7664
  "bg-gradient-to-r from-accent to-info",
7727
7665
  animated && "transition-all duration-500 ease-out"
7728
7666
  ),
7729
- style: { width: `${fillWidth}%` }
7667
+ style: { width: `${percentage}%` }
7730
7668
  }
7731
7669
  )
7732
7670
  }
@@ -7743,7 +7681,6 @@ function XPBar({
7743
7681
  var sizeMap9;
7744
7682
  var init_XPBar = __esm({
7745
7683
  "components/game/atoms/XPBar.tsx"() {
7746
- "use client";
7747
7684
  init_cn();
7748
7685
  sizeMap9 = {
7749
7686
  sm: { bar: "h-2", text: "text-xs", badge: "text-xs px-1.5 py-0.5" },
@@ -8189,9 +8126,9 @@ function MiniMap({
8189
8126
  viewportRect = DEFAULT_VIEWPORT,
8190
8127
  className
8191
8128
  }) {
8192
- const canvasRef = React85.useRef(null);
8193
- const frameRef = React85.useRef(0);
8194
- React85.useEffect(() => {
8129
+ const canvasRef = React87.useRef(null);
8130
+ const frameRef = React87.useRef(0);
8131
+ React87.useEffect(() => {
8195
8132
  const canvas = canvasRef.current;
8196
8133
  if (!canvas) return;
8197
8134
  const ctx = canvas.getContext("2d");
@@ -8380,7 +8317,7 @@ var init_ErrorBoundary = __esm({
8380
8317
  }
8381
8318
  );
8382
8319
  };
8383
- ErrorBoundary = class extends React85__default.Component {
8320
+ ErrorBoundary = class extends React87__default.Component {
8384
8321
  constructor(props) {
8385
8322
  super(props);
8386
8323
  __publicField(this, "reset", () => {
@@ -8691,9 +8628,8 @@ var init_Container = __esm({
8691
8628
  as: Component2 = "div"
8692
8629
  }) => {
8693
8630
  const resolvedSize = maxWidth ?? size ?? "lg";
8694
- const Comp = Component2;
8695
- return /* @__PURE__ */ jsx(
8696
- Comp,
8631
+ return React87__default.createElement(
8632
+ Component2,
8697
8633
  {
8698
8634
  className: cn(
8699
8635
  "w-full",
@@ -8701,9 +8637,9 @@ var init_Container = __esm({
8701
8637
  paddingStyles3[padding],
8702
8638
  center && "mx-auto",
8703
8639
  className
8704
- ),
8705
- children
8706
- }
8640
+ )
8641
+ },
8642
+ children
8707
8643
  );
8708
8644
  };
8709
8645
  Container.displayName = "Container";
@@ -9415,8 +9351,8 @@ function ActionButtons({
9415
9351
  disabled
9416
9352
  }) {
9417
9353
  const eventBus = useEventBus();
9418
- const [activeButtons, setActiveButtons] = React85.useState(/* @__PURE__ */ new Set());
9419
- const handlePress = React85.useCallback(
9354
+ const [activeButtons, setActiveButtons] = React87.useState(/* @__PURE__ */ new Set());
9355
+ const handlePress = React87.useCallback(
9420
9356
  (id) => {
9421
9357
  setActiveButtons((prev) => new Set(prev).add(id));
9422
9358
  if (actionEvent) eventBus.emit(`UI:${actionEvent}`, { id, pressed: true });
@@ -9424,7 +9360,7 @@ function ActionButtons({
9424
9360
  },
9425
9361
  [actionEvent, eventBus, onAction]
9426
9362
  );
9427
- const handleRelease = React85.useCallback(
9363
+ const handleRelease = React87.useCallback(
9428
9364
  (id) => {
9429
9365
  setActiveButtons((prev) => {
9430
9366
  const next = new Set(prev);
@@ -10254,50 +10190,6 @@ var init_AuthLayout = __esm({
10254
10190
  AuthLayout.displayName = "AuthLayout";
10255
10191
  }
10256
10192
  });
10257
- var LoadingState;
10258
- var init_LoadingState = __esm({
10259
- "components/core/molecules/LoadingState.tsx"() {
10260
- "use client";
10261
- init_cn();
10262
- init_atoms2();
10263
- init_Stack();
10264
- init_Typography();
10265
- LoadingState = ({
10266
- title,
10267
- message,
10268
- className
10269
- }) => {
10270
- const { t } = useTranslate();
10271
- const displayMessage = message ?? t("common.loading");
10272
- return /* @__PURE__ */ jsxs(
10273
- VStack,
10274
- {
10275
- align: "center",
10276
- className: cn(
10277
- "justify-center py-12",
10278
- className
10279
- ),
10280
- children: [
10281
- /* @__PURE__ */ jsx(Spinner, { size: "lg" }),
10282
- title && /* @__PURE__ */ jsx(Typography, { variant: "h3", className: "mt-4 text-lg font-semibold text-foreground", children: title }),
10283
- /* @__PURE__ */ jsx(
10284
- Typography,
10285
- {
10286
- variant: "small",
10287
- className: cn(
10288
- "text-muted-foreground",
10289
- title ? "mt-2" : "mt-4"
10290
- ),
10291
- children: displayMessage
10292
- }
10293
- )
10294
- ]
10295
- }
10296
- );
10297
- };
10298
- LoadingState.displayName = "LoadingState";
10299
- }
10300
- });
10301
10193
  function getState() {
10302
10194
  if (typeof window !== "undefined") {
10303
10195
  const w = window;
@@ -10827,9 +10719,6 @@ function useUnitSpriteAtlas(units) {
10827
10719
  const loadingRef = useRef(/* @__PURE__ */ new Set());
10828
10720
  const [pendingCount, setPendingCount] = useState(0);
10829
10721
  const [, forceTick] = useState(0);
10830
- const animStatesRef = useRef(/* @__PURE__ */ new Map());
10831
- const lastTickRef = useRef(0);
10832
- const rafRef = useRef(0);
10833
10722
  const atlasUrls = useMemo(() => {
10834
10723
  const set = /* @__PURE__ */ new Set();
10835
10724
  for (const unit of units) {
@@ -10875,54 +10764,6 @@ function useUnitSpriteAtlas(units) {
10875
10764
  }
10876
10765
  return [...urls];
10877
10766
  }, [units, pendingCount]);
10878
- useEffect(() => {
10879
- const hasAtlasUnits = units.some((u) => unitAtlasUrl(u) !== null);
10880
- if (!hasAtlasUnits) return;
10881
- let running = true;
10882
- const tick = (ts) => {
10883
- if (!running) return;
10884
- const last = lastTickRef.current || ts;
10885
- const delta = ts - last;
10886
- lastTickRef.current = ts;
10887
- const states = animStatesRef.current;
10888
- const currentIds = /* @__PURE__ */ new Set();
10889
- for (const unit of units) {
10890
- if (unitAtlasUrl(unit) === null) continue;
10891
- currentIds.add(unit.id);
10892
- let state = states.get(unit.id);
10893
- if (!state) {
10894
- state = { animation: "idle", direction: "se", elapsed: 0, walkHold: 0, prev: null };
10895
- states.set(unit.id, state);
10896
- }
10897
- const posX = unit.position?.x ?? unit.x ?? 0;
10898
- const posY = unit.position?.y ?? unit.y ?? 0;
10899
- if (state.prev) {
10900
- const dx = posX - state.prev.x;
10901
- const dy = posY - state.prev.y;
10902
- if (dx !== 0 || dy !== 0) {
10903
- state.animation = "walk";
10904
- state.direction = inferDirection(dx, dy);
10905
- state.walkHold = WALK_HOLD_MS;
10906
- } else if (state.animation === "walk") {
10907
- state.walkHold -= delta;
10908
- if (state.walkHold <= 0) state.animation = "idle";
10909
- }
10910
- }
10911
- state.prev = { x: posX, y: posY };
10912
- state.elapsed += delta;
10913
- }
10914
- for (const id of states.keys()) {
10915
- if (!currentIds.has(id)) states.delete(id);
10916
- }
10917
- rafRef.current = requestAnimationFrame(tick);
10918
- };
10919
- rafRef.current = requestAnimationFrame(tick);
10920
- return () => {
10921
- running = false;
10922
- cancelAnimationFrame(rafRef.current);
10923
- lastTickRef.current = 0;
10924
- };
10925
- }, [units]);
10926
10767
  const resolveUnitFrame = useCallback((unitId) => {
10927
10768
  const unit = units.find((u) => u.id === unitId);
10928
10769
  if (!unit) return null;
@@ -10930,18 +10771,14 @@ function useUnitSpriteAtlas(units) {
10930
10771
  if (!atlasUrl) return null;
10931
10772
  const atlas = atlasCacheRef.current.get(atlasUrl);
10932
10773
  if (!atlas) return null;
10933
- const state = animStatesRef.current.get(unitId);
10934
- const animation = state?.animation ?? "idle";
10935
- const direction = state?.direction ?? "se";
10936
- const elapsed = state?.elapsed ?? 0;
10774
+ const animation = unit.animation ?? "idle";
10775
+ const frame = unit.frame ?? 0;
10937
10776
  const def = atlas.animations[animation] ?? atlas.animations.idle;
10938
10777
  if (!def) return null;
10939
- const { sheetDir, flipX } = resolveSheetDirection(direction);
10778
+ const { sheetDir, flipX } = resolveSheetDirection("se");
10940
10779
  const rel = atlas.sheets[sheetDir] ?? atlas.sheets.se ?? atlas.sheets.sw;
10941
10780
  if (!rel) return null;
10942
10781
  const sheetUrl = resolveSheetUrl(atlasUrl, rel);
10943
- const isIdle = animation === "idle";
10944
- const frame = isIdle ? 0 : getCurrentFrameFromDef(def, elapsed).frame;
10945
10782
  const rect = frameRect(frame, def.row, atlas.columns, atlas.frameWidth, atlas.frameHeight);
10946
10783
  return {
10947
10784
  sheetUrl,
@@ -10950,17 +10787,15 @@ function useUnitSpriteAtlas(units) {
10950
10787
  sw: rect.sw,
10951
10788
  sh: rect.sh,
10952
10789
  flipX,
10953
- applyBreathing: isIdle
10790
+ applyBreathing: animation === "idle"
10954
10791
  };
10955
10792
  }, [units]);
10956
10793
  return { sheetUrls, resolveUnitFrame, pendingCount };
10957
10794
  }
10958
- var WALK_HOLD_MS;
10959
10795
  var init_useUnitSpriteAtlas = __esm({
10960
10796
  "components/game/molecules/useUnitSpriteAtlas.ts"() {
10961
10797
  "use client";
10962
10798
  init_spriteAnimation();
10963
- WALK_HOLD_MS = 600;
10964
10799
  }
10965
10800
  });
10966
10801
 
@@ -11028,6 +10863,7 @@ function IsometricCanvas({
11028
10863
  tiles: _tilesPropRaw = [],
11029
10864
  units: _unitsPropRaw = [],
11030
10865
  features: _featuresPropRaw = [],
10866
+ effects: _effectsPropRaw = [],
11031
10867
  // Interaction state
11032
10868
  selectedUnitId = null,
11033
10869
  validMoves = [],
@@ -11060,7 +10896,7 @@ function IsometricCanvas({
11060
10896
  resolveUnitFrame,
11061
10897
  effectSpriteUrls = [],
11062
10898
  onDrawEffects,
11063
- hasActiveEffects: hasActiveEffects2 = false,
10899
+ hasActiveEffects: _hasActiveEffects = false,
11064
10900
  // Tuning
11065
10901
  diamondTopY: diamondTopYProp,
11066
10902
  // Remote asset loading
@@ -11070,13 +10906,12 @@ function IsometricCanvas({
11070
10906
  const tilesProp = Array.isArray(_tilesPropRaw) ? _tilesPropRaw : [];
11071
10907
  const unitsProp = Array.isArray(_unitsPropRaw) ? _unitsPropRaw : [];
11072
10908
  const featuresProp = Array.isArray(_featuresPropRaw) ? _featuresPropRaw : [];
10909
+ const effects = Array.isArray(_effectsPropRaw) ? _effectsPropRaw : [];
11073
10910
  const eventBus = useEventBus();
11074
10911
  const { t } = useTranslate();
11075
10912
  const canvasRef = useRef(null);
11076
10913
  const containerRef = useRef(null);
11077
- const minimapRef = useRef(null);
11078
- const animTimeRef = useRef(0);
11079
- const rafIdRef = useRef(0);
10914
+ const lerpRafRef = useRef(0);
11080
10915
  const [viewportSize, setViewportSize] = useState({ width: 800, height: 600 });
11081
10916
  useEffect(() => {
11082
10917
  const el = containerRef.current;
@@ -11100,7 +10935,7 @@ function IsometricCanvas({
11100
10935
  () => unitsProp.map((u) => u.position ? u : { ...u, position: { x: u.x ?? 0, y: u.y ?? 0 } }),
11101
10936
  [unitsProp]
11102
10937
  );
11103
- const { sheetUrls: atlasSheetUrls, resolveUnitFrame: resolveUnitFrameInternal, pendingCount: atlasPending } = useUnitSpriteAtlas(units);
10938
+ const { sheetUrls: atlasSheetUrls, resolveUnitFrame: resolveUnitFrameInternal } = useUnitSpriteAtlas(units);
11104
10939
  const resolveFrameForUnit = useCallback((unitId) => {
11105
10940
  return resolveUnitFrame?.(unitId) ?? resolveUnitFrameInternal(unitId);
11106
10941
  }, [resolveUnitFrame, resolveUnitFrameInternal]);
@@ -11195,7 +11030,7 @@ function IsometricCanvas({
11195
11030
  if (backgroundImage) urls.push(backgroundImage);
11196
11031
  return [...new Set(urls.filter(Boolean))];
11197
11032
  }, [sortedTiles, features, units, getTerrainSprite, getFeatureSprite, getUnitSprite, effectSpriteUrls, atlasSheetUrls, backgroundImage, assetManifest, resolveManifestUrl7]);
11198
- const { getImage, pendingCount } = useImageCache(spriteUrls);
11033
+ const { getImage, pendingCount: _imagePendingCount } = useImageCache(spriteUrls);
11199
11034
  useEffect(() => {
11200
11035
  if (typeof window === "undefined") return;
11201
11036
  const canvas = canvasRef.current;
@@ -11227,63 +11062,26 @@ function IsometricCanvas({
11227
11062
  const resolveUnitSpriteUrl = useCallback((unit) => {
11228
11063
  return unit.sprite || getUnitSprite?.(unit) || (unit.unitType ? resolveManifestUrl7(assetManifest?.units?.[unit.unitType]) : void 0);
11229
11064
  }, [getUnitSprite, assetManifest, resolveManifestUrl7]);
11230
- const drawMinimap = useCallback(() => {
11231
- if (!showMinimap) return;
11232
- const miniCanvas = minimapRef.current;
11233
- if (!miniCanvas || sortedTiles.length === 0) return;
11234
- const mCtx = miniCanvas.getContext("2d");
11235
- if (!mCtx) return;
11236
- const mW = 150;
11237
- const mH = 100;
11238
- miniCanvas.width = mW;
11239
- miniCanvas.height = mH;
11240
- mCtx.clearRect(0, 0, mW, mH);
11241
- const allScreenPos = sortedTiles.map((t2) => isoToScreen(t2.x, t2.y, scale, baseOffsetX, tileLayout));
11242
- const minX = Math.min(...allScreenPos.map((p2) => p2.x));
11243
- const maxX = Math.max(...allScreenPos.map((p2) => p2.x + scaledTileWidth));
11244
- const minY = Math.min(...allScreenPos.map((p2) => p2.y));
11245
- const tileBottomExtent = tileLayout === "hex" || tileLayout === "flat" ? scaledTileWidth : scaledTileHeight;
11246
- const maxY = Math.max(...allScreenPos.map((p2) => p2.y + tileBottomExtent));
11247
- const worldW = maxX - minX;
11248
- const worldH = maxY - minY;
11249
- const scaleM = Math.min(mW / worldW, mH / worldH) * 0.9;
11250
- const offsetMx = (mW - worldW * scaleM) / 2;
11251
- const offsetMy = (mH - worldH * scaleM) / 2;
11252
- for (const tile of sortedTiles) {
11253
- const pos = isoToScreen(tile.x, tile.y, scale, baseOffsetX, tileLayout);
11254
- const mx = (pos.x - minX) * scaleM + offsetMx;
11255
- const my = (pos.y - minY) * scaleM + offsetMy;
11256
- const mTileW = scaledTileWidth * scaleM;
11257
- const mFloorH = scaledFloorHeight * scaleM;
11258
- mCtx.fillStyle = tile.terrain === "water" ? "#3b82f6" : tile.terrain === "mountain" ? "#78716c" : "#4ade80";
11259
- mCtx.beginPath();
11260
- mCtx.moveTo(mx + mTileW / 2, my);
11261
- mCtx.lineTo(mx + mTileW, my + mFloorH / 2);
11262
- mCtx.lineTo(mx + mTileW / 2, my + mFloorH);
11263
- mCtx.lineTo(mx, my + mFloorH / 2);
11264
- mCtx.closePath();
11265
- mCtx.fill();
11266
- }
11267
- for (const unit of units) {
11268
- if (!unit.position) continue;
11269
- const pos = isoToScreen(unit.position.x, unit.position.y, scale, baseOffsetX, tileLayout);
11270
- const mx = (pos.x + scaledTileWidth / 2 - minX) * scaleM + offsetMx;
11271
- const my = (pos.y + scaledTileHeight / 2 - minY) * scaleM + offsetMy;
11272
- mCtx.fillStyle = unit.team === "player" ? "#60a5fa" : unit.team === "enemy" ? "#f87171" : "#9ca3af";
11273
- mCtx.beginPath();
11274
- mCtx.arc(mx, my, 3, 0, Math.PI * 2);
11275
- mCtx.fill();
11276
- }
11277
- const cam = cameraRef.current;
11278
- const vLeft = (cam.x - minX) * scaleM + offsetMx;
11279
- const vTop = (cam.y - minY) * scaleM + offsetMy;
11280
- const vW = viewportSize.width / cam.zoom * scaleM;
11281
- const vH = viewportSize.height / cam.zoom * scaleM;
11282
- mCtx.strokeStyle = "rgba(255, 255, 255, 0.8)";
11283
- mCtx.lineWidth = 1;
11284
- mCtx.strokeRect(vLeft, vTop, vW, vH);
11285
- }, [showMinimap, sortedTiles, units, tileLayout, scale, baseOffsetX, scaledTileWidth, scaledTileHeight, scaledFloorHeight, viewportSize, cameraRef]);
11286
- const draw = useCallback((animTime) => {
11065
+ const miniMapTiles = useMemo(() => {
11066
+ if (!showMinimap) return [];
11067
+ return sortedTiles.map((t2) => ({
11068
+ x: t2.x,
11069
+ y: t2.y,
11070
+ color: t2.terrain === "water" ? "#3b82f6" : t2.terrain === "mountain" ? "#78716c" : "#4ade80"
11071
+ }));
11072
+ }, [showMinimap, sortedTiles]);
11073
+ const miniMapUnits = useMemo(() => {
11074
+ if (!showMinimap) return [];
11075
+ return units.filter((u) => u.position).map((u) => ({
11076
+ x: u.position.x,
11077
+ y: u.position.y,
11078
+ color: u.team === "player" ? "#60a5fa" : u.team === "enemy" ? "#f87171" : "#9ca3af",
11079
+ isPlayer: u.team === "player"
11080
+ }));
11081
+ }, [showMinimap, units]);
11082
+ const miniMapWidth = gridWidth || 10;
11083
+ const miniMapHeight = gridHeight || 10;
11084
+ const draw = useCallback(() => {
11287
11085
  const canvas = canvasRef.current;
11288
11086
  if (!canvas) return;
11289
11087
  const ctx = canvas.getContext("2d");
@@ -11369,8 +11167,7 @@ function IsometricCanvas({
11369
11167
  if (validMoveSet.has(tileKey)) {
11370
11168
  const centerX = pos.x + scaledTileWidth / 2;
11371
11169
  const topY = pos.y + scaledDiamondTopY;
11372
- const pulse = 0.15 + 0.1 * Math.sin(animTime * 4e-3);
11373
- ctx.fillStyle = `rgba(74, 222, 128, ${pulse})`;
11170
+ ctx.fillStyle = "rgba(74, 222, 128, 0.25)";
11374
11171
  ctx.beginPath();
11375
11172
  ctx.moveTo(centerX, topY);
11376
11173
  ctx.lineTo(pos.x + scaledTileWidth, topY + scaledFloorHeight / 2);
@@ -11382,8 +11179,7 @@ function IsometricCanvas({
11382
11179
  if (attackTargetSet.has(tileKey)) {
11383
11180
  const centerX = pos.x + scaledTileWidth / 2;
11384
11181
  const topY = pos.y + scaledDiamondTopY;
11385
- const pulse = 0.2 + 0.15 * Math.sin(animTime * 5e-3);
11386
- ctx.fillStyle = `rgba(239, 68, 68, ${pulse})`;
11182
+ ctx.fillStyle = "rgba(239, 68, 68, 0.35)";
11387
11183
  ctx.beginPath();
11388
11184
  ctx.moveTo(centerX, topY);
11389
11185
  ctx.lineTo(pos.x + scaledTileWidth, topY + scaledFloorHeight / 2);
@@ -11456,7 +11252,7 @@ function IsometricCanvas({
11456
11252
  const isSelected = unit.id === selectedUnitId;
11457
11253
  const centerX = pos.x + scaledTileWidth / 2;
11458
11254
  const groundY = pos.y + scaledDiamondTopY + scaledFloorHeight * 0.5;
11459
- const breatheOffset = 0.8 * scale * (1 + Math.sin(animTime * 2e-3 + (unit.position.x * 3.7 + unit.position.y * 5.3)));
11255
+ const breatheOffset = 0;
11460
11256
  const unitSpriteUrl = resolveUnitSpriteUrl(unit);
11461
11257
  const img = unitSpriteUrl ? getImage(unitSpriteUrl) : null;
11462
11258
  const unitDrawH = scaledFloorHeight * spriteHeightRatio * unitScale;
@@ -11496,10 +11292,9 @@ function IsometricCanvas({
11496
11292
  ctx.restore();
11497
11293
  }
11498
11294
  if (isSelected) {
11499
- const ringAlpha = 0.6 + 0.3 * Math.sin(animTime * 4e-3);
11500
11295
  ctx.beginPath();
11501
11296
  ctx.ellipse(centerX, groundY, drawW / 2 + 4 * scale, 12 * scale, 0, 0, Math.PI * 2);
11502
- ctx.strokeStyle = `rgba(0, 200, 255, ${ringAlpha})`;
11297
+ ctx.strokeStyle = "rgba(0, 200, 255, 0.8)";
11503
11298
  ctx.lineWidth = 3;
11504
11299
  ctx.stroke();
11505
11300
  }
@@ -11555,66 +11350,29 @@ function IsometricCanvas({
11555
11350
  ctx.lineWidth = 2;
11556
11351
  ctx.stroke();
11557
11352
  }
11558
- if (unit.name) {
11559
- const labelBg = unit.team === "player" ? "rgba(59, 130, 246, 0.9)" : unit.team === "enemy" ? "rgba(239, 68, 68, 0.9)" : "rgba(107, 114, 128, 0.9)";
11560
- ctx.font = `bold ${10 * scale * 2.5}px system-ui`;
11561
- ctx.textAlign = "center";
11562
- const textWidth = ctx.measureText(unit.name).width;
11563
- const labelY = groundY + 14 * scale - breatheOffset;
11564
- ctx.fillStyle = labelBg;
11565
- ctx.beginPath();
11566
- ctx.roundRect(centerX - textWidth / 2 - 6 * scale, labelY - 8 * scale, textWidth + 12 * scale, 16 * scale, 4 * scale);
11567
- ctx.fill();
11568
- ctx.fillStyle = "white";
11569
- ctx.fillText(unit.name, centerX, labelY + 4 * scale);
11570
- }
11571
- if (unit.health !== void 0 && unit.maxHealth !== void 0) {
11572
- const barWidth = 40 * scale;
11573
- const barHeight = 6 * scale;
11574
- const barX = centerX - barWidth / 2;
11575
- const barY = groundY - drawH - 2 * scale - breatheOffset;
11576
- const healthRatio = unit.health / unit.maxHealth;
11577
- const barRadius = barHeight / 2;
11578
- ctx.fillStyle = "rgba(0, 0, 0, 0.7)";
11579
- ctx.beginPath();
11580
- ctx.roundRect(barX, barY, barWidth, barHeight, barRadius);
11581
- ctx.fill();
11582
- if (healthRatio > 0) {
11583
- const fillWidth = barWidth * healthRatio;
11584
- const gradient = ctx.createLinearGradient(barX, barY, barX, barY + barHeight);
11585
- if (healthRatio > 0.6) {
11586
- gradient.addColorStop(0, "#4ade80");
11587
- gradient.addColorStop(1, "#22c55e");
11588
- } else if (healthRatio > 0.3) {
11589
- gradient.addColorStop(0, "#fde047");
11590
- gradient.addColorStop(1, "#eab308");
11591
- } else {
11592
- gradient.addColorStop(0, "#f87171");
11593
- gradient.addColorStop(1, "#ef4444");
11594
- }
11595
- ctx.fillStyle = gradient;
11596
- ctx.save();
11597
- ctx.beginPath();
11598
- ctx.roundRect(barX, barY, fillWidth, barHeight, barRadius);
11599
- ctx.clip();
11600
- ctx.fillRect(barX, barY, fillWidth, barHeight);
11601
- ctx.restore();
11602
- }
11603
- ctx.strokeStyle = "rgba(255, 255, 255, 0.3)";
11604
- ctx.lineWidth = 1;
11605
- ctx.beginPath();
11606
- ctx.roundRect(barX, barY, barWidth, barHeight, barRadius);
11607
- ctx.stroke();
11608
- }
11609
11353
  }
11610
- onDrawEffects?.(ctx, animTime, getImage);
11354
+ for (const fx of effects) {
11355
+ const spriteUrl = resolveManifestUrl7(assetManifest?.effects?.[fx.key]);
11356
+ if (!spriteUrl) continue;
11357
+ const img = getImage(spriteUrl);
11358
+ if (!img) continue;
11359
+ const pos = isoToScreen(fx.x, fx.y, scale, baseOffsetX, tileLayout);
11360
+ const cx = pos.x + scaledTileWidth / 2;
11361
+ const cy = pos.y + scaledDiamondTopY + scaledFloorHeight * 0.5;
11362
+ const alpha = Math.min(1, fx.ttl / 4);
11363
+ const prev = ctx.globalAlpha;
11364
+ ctx.globalAlpha = alpha;
11365
+ ctx.drawImage(img, cx - img.naturalWidth / 2, cy - img.naturalHeight / 2);
11366
+ ctx.globalAlpha = prev;
11367
+ }
11368
+ onDrawEffects?.(ctx, 0, getImage);
11611
11369
  ctx.restore();
11612
- drawMinimap();
11613
11370
  }, [
11614
11371
  sortedTiles,
11615
11372
  units,
11616
11373
  features,
11617
11374
  selectedUnitId,
11375
+ effects,
11618
11376
  tileLayout,
11619
11377
  scale,
11620
11378
  debug2,
@@ -11634,11 +11392,12 @@ function IsometricCanvas({
11634
11392
  attackTargetSet,
11635
11393
  hoveredTile,
11636
11394
  viewportSize,
11637
- drawMinimap,
11638
11395
  onDrawEffects,
11639
11396
  backgroundImage,
11640
11397
  cameraRef,
11641
- unitScale
11398
+ unitScale,
11399
+ resolveManifestUrl7,
11400
+ assetManifest
11642
11401
  ]);
11643
11402
  useEffect(() => {
11644
11403
  if (!selectedUnitId) return;
@@ -11653,30 +11412,33 @@ function IsometricCanvas({
11653
11412
  };
11654
11413
  }, [selectedUnitId, units, tileLayout, scale, baseOffsetX, scaledTileWidth, scaledDiamondTopY, scaledFloorHeight, viewportSize, targetCameraRef]);
11655
11414
  useEffect(() => {
11656
- const hasAnimations = units.length > 0 || validMoves.length > 0 || attackTargets.length > 0 || selectedUnitId != null || targetCameraRef.current != null || hasActiveEffects2 || pendingCount > 0 || atlasPending > 0;
11657
- draw(animTimeRef.current);
11658
- if (!hasAnimations) return;
11415
+ draw();
11416
+ }, [draw]);
11417
+ useEffect(() => {
11418
+ draw();
11419
+ }, [_imagePendingCount]);
11420
+ useEffect(() => {
11421
+ if (selectedUnitId == null) return;
11659
11422
  let running = true;
11660
- const animate = (timestamp) => {
11423
+ const tick = () => {
11661
11424
  if (!running) return;
11662
- animTimeRef.current = timestamp;
11663
- lerpToTarget();
11664
- draw(timestamp);
11665
- rafIdRef.current = requestAnimationFrame(animate);
11425
+ const stillLerping = lerpToTarget();
11426
+ draw();
11427
+ if (stillLerping) lerpRafRef.current = requestAnimationFrame(tick);
11666
11428
  };
11667
- rafIdRef.current = requestAnimationFrame(animate);
11429
+ lerpRafRef.current = requestAnimationFrame(tick);
11668
11430
  return () => {
11669
11431
  running = false;
11670
- cancelAnimationFrame(rafIdRef.current);
11432
+ cancelAnimationFrame(lerpRafRef.current);
11671
11433
  };
11672
- }, [draw, units.length, validMoves.length, attackTargets.length, selectedUnitId, hasActiveEffects2, pendingCount, atlasPending, lerpToTarget, targetCameraRef]);
11434
+ }, [selectedUnitId, lerpToTarget, draw]);
11673
11435
  const singlePointerActiveRef = useRef(false);
11674
11436
  const handleCanvasPointerDown = useCallback((e) => {
11675
11437
  singlePointerActiveRef.current = true;
11676
11438
  if (enableCamera) handlePointerDown(e);
11677
11439
  }, [enableCamera, handlePointerDown]);
11678
11440
  const handleCanvasPointerMove = useCallback((e) => {
11679
- if (enableCamera) handlePointerMove(e, () => draw(animTimeRef.current));
11441
+ if (enableCamera) handlePointerMove(e, () => draw());
11680
11442
  }, [enableCamera, handlePointerMove, draw]);
11681
11443
  const handleCanvasHover = useCallback((e) => {
11682
11444
  if (singlePointerActiveRef.current) return;
@@ -11718,10 +11480,10 @@ function IsometricCanvas({
11718
11480
  onTileLeave?.();
11719
11481
  }, [handleMouseLeave, onTileLeave, tileLeaveEvent, eventBus]);
11720
11482
  const applyZoom = useCallback((factor, centerX, centerY) => {
11721
- if (enableCamera) zoomAtPoint(factor, centerX, centerY, viewportSize, () => draw(animTimeRef.current));
11483
+ if (enableCamera) zoomAtPoint(factor, centerX, centerY, viewportSize, () => draw());
11722
11484
  }, [enableCamera, zoomAtPoint, viewportSize, draw]);
11723
11485
  const applyPanDelta = useCallback((dx, dy) => {
11724
- if (enableCamera) panBy(dx, dy, () => draw(animTimeRef.current));
11486
+ if (enableCamera) panBy(dx, dy, () => draw());
11725
11487
  }, [enableCamera, panBy, draw]);
11726
11488
  const cancelSinglePointer = useCallback(() => {
11727
11489
  singlePointerActiveRef.current = false;
@@ -11737,11 +11499,27 @@ function IsometricCanvas({
11737
11499
  onPanDelta: applyPanDelta,
11738
11500
  onMultiTouchStart: cancelSinglePointer
11739
11501
  });
11502
+ const unitOverlays = useMemo(() => {
11503
+ if (sortedTiles.length === 0) return [];
11504
+ return units.filter((u) => !!u.position).map((u) => {
11505
+ const pos = isoToScreen(u.position.x, u.position.y, scale, baseOffsetX, tileLayout);
11506
+ const cam = cameraRef.current;
11507
+ const screenX = (pos.x + scaledTileWidth / 2 - (cam.x + viewportSize.width / 2)) * cam.zoom + viewportSize.width / 2;
11508
+ const screenY = (pos.y + scaledDiamondTopY + scaledFloorHeight * 0.5 - (cam.y + viewportSize.height / 2)) * cam.zoom + viewportSize.height / 2;
11509
+ return { unit: u, screenX, screenY };
11510
+ });
11511
+ }, [units, sortedTiles.length, scale, baseOffsetX, tileLayout, scaledTileWidth, scaledDiamondTopY, scaledFloorHeight, viewportSize, cameraRef]);
11740
11512
  if (error) {
11741
- return /* @__PURE__ */ jsx(ErrorState, { title: t("canvas.errorTitle"), message: error.message, className });
11513
+ return /* @__PURE__ */ jsx(Box, { className: cn("flex items-center justify-center w-full h-full bg-[var(--color-card)] rounded-container", className), children: /* @__PURE__ */ jsxs(Stack, { direction: "vertical", gap: "md", align: "center", children: [
11514
+ /* @__PURE__ */ jsx(Icon, { name: "alert-circle", size: "xl" }),
11515
+ /* @__PURE__ */ jsx(Typography, { variant: "body", className: "text-error", children: error.message })
11516
+ ] }) });
11742
11517
  }
11743
11518
  if (isLoading) {
11744
- return /* @__PURE__ */ jsx(LoadingState, { className });
11519
+ return /* @__PURE__ */ jsx(Box, { className: cn("flex items-center justify-center w-full h-full bg-[var(--color-card)] rounded-container", className), children: /* @__PURE__ */ jsxs(Stack, { direction: "vertical", gap: "md", align: "center", children: [
11520
+ /* @__PURE__ */ jsx(Icon, { name: "loader", size: "xl", className: "animate-spin" }),
11521
+ /* @__PURE__ */ jsx(Typography, { variant: "body", className: "text-muted-foreground", children: t("canvas.loadingMessage") || "Loading\u2026" })
11522
+ ] }) });
11745
11523
  }
11746
11524
  if (sortedTiles.length === 0) {
11747
11525
  return /* @__PURE__ */ jsx(
@@ -11806,14 +11584,36 @@ function IsometricCanvas({
11806
11584
  }
11807
11585
  )
11808
11586
  ] }),
11809
- showMinimap && /* @__PURE__ */ jsx(
11810
- "canvas",
11587
+ unitOverlays.map(({ unit, screenX, screenY }) => /* @__PURE__ */ jsxs(
11588
+ "div",
11589
+ {
11590
+ className: "absolute pointer-events-none",
11591
+ style: { left: Math.round(screenX), top: Math.round(screenY), transform: "translate(-50%, 0)", zIndex: 5 },
11592
+ children: [
11593
+ unit.name && /* @__PURE__ */ jsx(
11594
+ "div",
11595
+ {
11596
+ className: "text-white text-xs font-bold px-1.5 py-0.5 rounded mb-0.5 whitespace-nowrap",
11597
+ style: { background: unit.team === "player" ? "rgba(59,130,246,0.9)" : unit.team === "enemy" ? "rgba(239,68,68,0.9)" : "rgba(107,114,128,0.9)" },
11598
+ children: unit.name
11599
+ }
11600
+ ),
11601
+ unit.health !== void 0 && unit.maxHealth !== void 0 && unit.maxHealth > 0 && /* @__PURE__ */ jsx(HealthBar, { current: unit.health, max: unit.maxHealth, format: "bar", size: "sm" })
11602
+ ]
11603
+ },
11604
+ unit.id
11605
+ )),
11606
+ showMinimap && /* @__PURE__ */ jsx("div", { className: "absolute bottom-2 right-2 pointer-events-none", style: { zIndex: 10 }, children: /* @__PURE__ */ jsx(
11607
+ MiniMap,
11811
11608
  {
11812
- ref: minimapRef,
11813
- className: "absolute bottom-2 right-2 border border-border rounded bg-background/80 pointer-events-none",
11814
- style: { width: 150, height: 100, zIndex: 10 }
11609
+ tiles: miniMapTiles,
11610
+ units: miniMapUnits,
11611
+ width: 150,
11612
+ height: 100,
11613
+ mapWidth: miniMapWidth,
11614
+ mapHeight: miniMapHeight
11815
11615
  }
11816
- )
11616
+ ) })
11817
11617
  ]
11818
11618
  }
11819
11619
  );
@@ -11828,8 +11628,8 @@ var init_IsometricCanvas = __esm({
11828
11628
  init_Stack();
11829
11629
  init_Icon();
11830
11630
  init_Typography();
11831
- init_LoadingState();
11832
- init_ErrorState();
11631
+ init_MiniMap();
11632
+ init_HealthBar();
11833
11633
  init_useImageCache();
11834
11634
  init_useCamera();
11835
11635
  init_useCanvasGestures();
@@ -11923,9 +11723,37 @@ function BattleBoard({
11923
11723
  className
11924
11724
  }) {
11925
11725
  const board = boardEntity(entity) ?? {};
11926
- const rawTiles = propTiles ?? (Array.isArray(board.tiles) ? board.tiles : []);
11726
+ function asFieldObj(v) {
11727
+ if (v === null || typeof v !== "object" || Array.isArray(v) || v instanceof Date) return null;
11728
+ return v;
11729
+ }
11730
+ const rawTiles = propTiles ?? (Array.isArray(board.tiles) ? board.tiles.flatMap((v) => {
11731
+ const o = asFieldObj(v);
11732
+ if (o === null || typeof o.x !== "number" || typeof o.y !== "number") return [];
11733
+ const tile = { x: o.x, y: o.y };
11734
+ if (typeof o.terrain === "string") tile.terrain = o.terrain;
11735
+ if (typeof o.terrainSprite === "string") tile.terrainSprite = o.terrainSprite;
11736
+ if (typeof o.passable === "boolean") tile.passable = o.passable;
11737
+ if (typeof o.movementCost === "number") tile.movementCost = o.movementCost;
11738
+ if (typeof o.elevation === "number") tile.elevation = o.elevation;
11739
+ if (typeof o.type === "string") tile.type = o.type;
11740
+ if (typeof o.tileType === "string") tile.tileType = o.tileType;
11741
+ if (typeof o.id === "string") tile.id = o.id;
11742
+ if (typeof o.modelUrl === "string") tile.modelUrl = o.modelUrl;
11743
+ return [tile];
11744
+ }) : []);
11927
11745
  const tiles = rawTiles.length === 0 ? DEFAULT_BATTLE_TILES : rawTiles;
11928
- const features = propFeatures ?? (Array.isArray(board.features) ? board.features : []);
11746
+ const features = propFeatures ?? (Array.isArray(board.features) ? board.features.flatMap((v) => {
11747
+ const o = asFieldObj(v);
11748
+ if (o === null || typeof o.type !== "string" || typeof o.x !== "number" || typeof o.y !== "number") return [];
11749
+ const feat = { type: o.type, x: o.x, y: o.y };
11750
+ if (typeof o.id === "string") feat.id = o.id;
11751
+ if (typeof o.sprite === "string") feat.sprite = o.sprite;
11752
+ if (typeof o.color === "string") feat.color = o.color;
11753
+ if (typeof o.elevation === "number") feat.elevation = o.elevation;
11754
+ if (typeof o.assetUrl === "string") feat.assetUrl = o.assetUrl;
11755
+ return [feat];
11756
+ }) : []);
11929
11757
  const boardWidth = num(board.gridWidth ?? board.boardWidth, BATTLE_GRID_W);
11930
11758
  const boardHeight = num(board.gridHeight ?? board.boardHeight, BATTLE_GRID_H);
11931
11759
  const assetManifest = propAssetManifest ?? board.assetManifest;
@@ -12024,7 +11852,12 @@ function BattleBoard({
12024
11852
  return units.filter((u) => unitHealth(u) > 0).map((unit) => {
12025
11853
  const id = str(unit.id);
12026
11854
  const pos = movingPositions.get(id) ?? unitPosition(unit);
12027
- const unitTraits = Array.isArray(unit.traits) ? unit.traits : void 0;
11855
+ const unitTraits = Array.isArray(unit.traits) ? unit.traits.flatMap((v) => {
11856
+ const o = asFieldObj(v);
11857
+ if (o === null || typeof o.name !== "string" || typeof o.currentState !== "string" || !Array.isArray(o.states)) return [];
11858
+ const stateNames = Array.from(o.states).flatMap((s) => typeof s === "string" ? [s] : []);
11859
+ return [{ name: o.name, currentState: o.currentState, states: stateNames, cooldown: typeof o.cooldown === "number" ? o.cooldown : void 0 }];
11860
+ }) : void 0;
12028
11861
  return {
12029
11862
  id,
12030
11863
  position: pos,
@@ -13020,9 +12853,9 @@ async function computeTraitLayout(data) {
13020
12853
  y: n.y ?? 0,
13021
12854
  width: n.width ?? 110,
13022
12855
  height: n.height ?? STATE_H,
13023
- isInitial: stateInfo?.isInitial,
13024
- isTerminal: stateInfo?.isTerminal,
13025
- role: getStateRole(name, stateInfo?.isInitial, stateInfo?.isTerminal, tc, maxTC),
12856
+ isInitial: stateInfo?.isInitial ?? void 0,
12857
+ isTerminal: stateInfo?.isTerminal ?? void 0,
12858
+ role: getStateRole(name, stateInfo?.isInitial ?? void 0, stateInfo?.isTerminal ?? void 0, tc, maxTC),
13026
12859
  transitionCount: tc
13027
12860
  };
13028
12861
  });
@@ -13033,12 +12866,10 @@ async function computeTraitLayout(data) {
13033
12866
  const sections = e.sections ?? [];
13034
12867
  const points = [];
13035
12868
  for (const section of sections) {
13036
- const startPoint = section.startPoint;
13037
- const endPoint = section.endPoint;
13038
12869
  const bendPoints = section.bendPoints ?? [];
13039
- points.push({ x: startPoint.x, y: startPoint.y });
12870
+ points.push({ x: section.startPoint.x, y: section.startPoint.y });
13040
12871
  for (const bp of bendPoints) points.push({ x: bp.x, y: bp.y });
13041
- points.push({ x: endPoint.x, y: endPoint.y });
12872
+ points.push({ x: section.endPoint.x, y: section.endPoint.y });
13042
12873
  }
13043
12874
  const isSelf = t.from === t.to;
13044
12875
  const isBackward = !isSelf && (nodeXMap[t.to] ?? 0) <= (nodeXMap[t.from] ?? 0);
@@ -13356,6 +13187,50 @@ var init_Tabs = __esm({
13356
13187
  Tabs.displayName = "Tabs";
13357
13188
  }
13358
13189
  });
13190
+ var LoadingState;
13191
+ var init_LoadingState = __esm({
13192
+ "components/core/molecules/LoadingState.tsx"() {
13193
+ "use client";
13194
+ init_cn();
13195
+ init_atoms2();
13196
+ init_Stack();
13197
+ init_Typography();
13198
+ LoadingState = ({
13199
+ title,
13200
+ message,
13201
+ className
13202
+ }) => {
13203
+ const { t } = useTranslate();
13204
+ const displayMessage = message ?? t("common.loading");
13205
+ return /* @__PURE__ */ jsxs(
13206
+ VStack,
13207
+ {
13208
+ align: "center",
13209
+ className: cn(
13210
+ "justify-center py-12",
13211
+ className
13212
+ ),
13213
+ children: [
13214
+ /* @__PURE__ */ jsx(Spinner, { size: "lg" }),
13215
+ title && /* @__PURE__ */ jsx(Typography, { variant: "h3", className: "mt-4 text-lg font-semibold text-foreground", children: title }),
13216
+ /* @__PURE__ */ jsx(
13217
+ Typography,
13218
+ {
13219
+ variant: "small",
13220
+ className: cn(
13221
+ "text-muted-foreground",
13222
+ title ? "mt-2" : "mt-4"
13223
+ ),
13224
+ children: displayMessage
13225
+ }
13226
+ )
13227
+ ]
13228
+ }
13229
+ );
13230
+ };
13231
+ LoadingState.displayName = "LoadingState";
13232
+ }
13233
+ });
13359
13234
  var ICON_NAME_ALIASES, lookStyles3, EmptyState;
13360
13235
  var init_EmptyState = __esm({
13361
13236
  "components/core/molecules/EmptyState.tsx"() {
@@ -13636,7 +13511,7 @@ var init_CodeBlock = __esm({
13636
13511
  };
13637
13512
  LINE_PROPS_FN = (n) => ({ "data-line": String(n - 1) });
13638
13513
  HIDDEN_LINE_NUMBERS = { display: "none" };
13639
- CodeBlock = React85__default.memo(
13514
+ CodeBlock = React87__default.memo(
13640
13515
  ({
13641
13516
  code: rawCode,
13642
13517
  language = "text",
@@ -14223,7 +14098,7 @@ var init_MarkdownContent = __esm({
14223
14098
  init_Box();
14224
14099
  init_CodeBlock();
14225
14100
  init_cn();
14226
- MarkdownContent = React85__default.memo(
14101
+ MarkdownContent = React87__default.memo(
14227
14102
  ({ content, direction = "ltr", className }) => {
14228
14103
  const { t: _t } = useTranslate();
14229
14104
  const safeContent = typeof content === "string" ? content : String(content ?? "");
@@ -15592,7 +15467,7 @@ var init_StateMachineView = __esm({
15592
15467
  style: { top: title ? 30 : 0 },
15593
15468
  children: [
15594
15469
  entity && /* @__PURE__ */ jsx(EntityBox, { entity, config }),
15595
- states.map((state) => renderStateNode ? /* @__PURE__ */ jsx(React85__default.Fragment, { children: renderStateNode(state, config) }, state.id) : /* @__PURE__ */ jsx(
15470
+ states.map((state) => renderStateNode ? /* @__PURE__ */ jsx(React87__default.Fragment, { children: renderStateNode(state, config) }, state.id) : /* @__PURE__ */ jsx(
15596
15471
  StateNode,
15597
15472
  {
15598
15473
  state,
@@ -16411,12 +16286,13 @@ var init_ContentRenderer = __esm({
16411
16286
  );
16412
16287
  case "orbital": {
16413
16288
  const parsed = segment.schema;
16289
+ const isFullSchema = (v) => Array.isArray(v.orbitals);
16414
16290
  const inlineTrait = {
16415
16291
  name: "inline",
16416
16292
  scope: "instance",
16417
16293
  stateMachine: parsed
16418
16294
  };
16419
- const schema = Array.isArray(parsed.orbitals) ? parsed : {
16295
+ const schema = isFullSchema(parsed) ? parsed : {
16420
16296
  name: "inline",
16421
16297
  orbitals: [{
16422
16298
  name: "inline",
@@ -17642,8 +17518,21 @@ function BuilderBoard({
17642
17518
  const resolved = boardEntity(entity);
17643
17519
  const [headerError, setHeaderError] = useState(false);
17644
17520
  const [selectedComponent, setSelectedComponent] = useState(null);
17645
- const components = Array.isArray(resolved?.components) ? resolved.components : [];
17646
- const slots = Array.isArray(resolved?.slots) ? resolved.slots : [];
17521
+ const components = rows(resolved?.components).map((r) => ({
17522
+ id: str(r.id),
17523
+ label: str(r.label),
17524
+ description: str(r.description) || void 0,
17525
+ iconEmoji: str(r.iconEmoji) || void 0,
17526
+ iconUrl: str(r.iconUrl) || void 0,
17527
+ category: str(r.category) || void 0
17528
+ }));
17529
+ const slots = rows(resolved?.slots).map((r) => ({
17530
+ id: str(r.id),
17531
+ label: str(r.label) || void 0,
17532
+ description: str(r.description) || void 0,
17533
+ requiredComponentId: str(r.requiredComponentId),
17534
+ placedComponentId: str(r.placedComponentId) || void 0
17535
+ }));
17647
17536
  const placements = {};
17648
17537
  for (const slot of slots) {
17649
17538
  if (slot.placedComponentId) placements[slot.id] = slot.placedComponentId;
@@ -19547,7 +19436,7 @@ function CardHand({
19547
19436
  className
19548
19437
  }) {
19549
19438
  const eventBus = useEventBus();
19550
- const handleClick = React85.useCallback(
19439
+ const handleClick = React87.useCallback(
19551
19440
  (card) => {
19552
19441
  if (card.disabled) return;
19553
19442
  onCardClick?.(card.id);
@@ -20294,14 +20183,15 @@ var init_CardGrid = __esm({
20294
20183
  bodyFields.length > 0 && /* @__PURE__ */ jsx(Box, { className: "px-4 py-3 flex-1", children: /* @__PURE__ */ jsx(VStack, { gap: "xs", children: bodyFields.map((field) => {
20295
20184
  const value = getNestedValue(itemData, field);
20296
20185
  if (value === void 0 || value === null || value === "") return null;
20297
- const boolVal = asBooleanValue(value);
20186
+ const fieldValue = value;
20187
+ const boolVal = asBooleanValue(fieldValue);
20298
20188
  if (boolVal !== null) {
20299
20189
  return /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "justify-between", children: [
20300
20190
  /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: fieldLabel(field) }),
20301
20191
  boolVal ? /* @__PURE__ */ jsx(Badge, { variant: "success", children: t("common.yes") || "Yes" }) : /* @__PURE__ */ jsx(Badge, { variant: "neutral", children: t("common.no") || "No" })
20302
20192
  ] }, field);
20303
20193
  }
20304
- const displayValue = isDateField(field) ? formatDate(value) : STATUS_FIELDS.has(field.toLowerCase()) ? void 0 : String(value);
20194
+ const displayValue = isDateField(field) ? formatDate(fieldValue) : STATUS_FIELDS.has(field.toLowerCase()) ? void 0 : String(value);
20305
20195
  if (!displayValue) return null;
20306
20196
  return /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "justify-between", children: [
20307
20197
  /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: fieldLabel(field) }),
@@ -20686,9 +20576,9 @@ function CastleBoard({
20686
20576
  const eventBus = useEventBus();
20687
20577
  const { t } = useTranslate();
20688
20578
  const resolved = boardEntity(entity);
20689
- const tiles = propTiles ?? (Array.isArray(resolved?.tiles) ? resolved.tiles : []);
20690
- const features = propFeatures ?? (Array.isArray(resolved?.features) ? resolved.features : []);
20691
- const units = propUnits ?? (Array.isArray(resolved?.units) ? resolved.units : []);
20579
+ const tiles = propTiles ?? (resolved?.tiles ?? []);
20580
+ const features = propFeatures ?? (resolved?.features ?? []);
20581
+ const units = propUnits ?? (resolved?.units ?? []);
20692
20582
  const assetManifest = propAssetManifest ?? resolved?.assetManifest;
20693
20583
  const backgroundImage = resolved?.backgroundImage;
20694
20584
  const gold = num(resolved?.gold);
@@ -22223,8 +22113,8 @@ function ClassifierBoard({
22223
22113
  const { t } = useTranslate();
22224
22114
  const resolved = boardEntity(entity);
22225
22115
  const [headerError, setHeaderError] = useState(false);
22226
- const items = Array.isArray(resolved?.items) ? resolved.items : [];
22227
- const categories = Array.isArray(resolved?.categories) ? resolved.categories : [];
22116
+ const items = rows(resolved?.items);
22117
+ const categories = rows(resolved?.categories);
22228
22118
  const result = str(resolved?.result);
22229
22119
  const submitted = result === "win";
22230
22120
  const attempts = num(resolved?.attempts);
@@ -22535,10 +22425,10 @@ function CombatLog({
22535
22425
  }, [events2, autoScroll]);
22536
22426
  const safeEvents = events2 ?? [];
22537
22427
  const visibleEvents = safeEvents.slice(-maxVisible);
22538
- return /* @__PURE__ */ jsxs(Card, { variant: "default", className: cn("flex flex-col", className), children: [
22428
+ return /* @__PURE__ */ jsxs(Box, { className: cn("flex flex-col rounded-container border border-border bg-card shadow-elevation-card", className), children: [
22539
22429
  /* @__PURE__ */ jsx(Box, { padding: "sm", border: true, className: "border-b-2 border-x-0 border-t-0 border-border", children: /* @__PURE__ */ jsxs(Box, { display: "flex", className: "items-center justify-between", children: [
22540
22430
  /* @__PURE__ */ jsx(Typography, { variant: "body2", className: "font-bold", children: title }),
22541
- /* @__PURE__ */ jsxs(Badge, { variant: "neutral", size: "sm", children: [
22431
+ /* @__PURE__ */ jsxs("span", { className: "text-xs text-muted-foreground bg-muted/60 rounded px-1.5 py-0.5 border border-border/50 font-mono", children: [
22542
22432
  safeEvents.length,
22543
22433
  " events"
22544
22434
  ] })
@@ -22558,7 +22448,7 @@ function CombatLog({
22558
22448
  /* @__PURE__ */ jsx(Box, { className: cn("flex-shrink-0 mt-0.5", colorClass), children: /* @__PURE__ */ jsx(EventIcon, { className: "h-4 w-4" }) }),
22559
22449
  /* @__PURE__ */ jsxs(Box, { className: "flex-1 min-w-0", children: [
22560
22450
  /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "block", children: event.message }),
22561
- event.value !== void 0 && /* @__PURE__ */ jsxs(Badge, { variant: eventBadgeVariants[eventType], size: "sm", className: "mt-1", children: [
22451
+ event.value !== void 0 && /* @__PURE__ */ jsxs("span", { className: cn("inline-block mt-1 text-xs font-bold rounded px-1.5 py-0.5 border", eventValueColors[eventType]), children: [
22562
22452
  eventType === "heal" ? "+" : eventType === "attack" ? "-" : "",
22563
22453
  event.value
22564
22454
  ] })
@@ -22571,7 +22461,7 @@ function CombatLog({
22571
22461
  }) }) })
22572
22462
  ] });
22573
22463
  }
22574
- var eventIcons, eventColors, eventBadgeVariants, DEFAULT_COMBAT_EVENTS;
22464
+ var eventIcons, eventColors, eventValueColors, DEFAULT_COMBAT_EVENTS;
22575
22465
  var init_CombatLog = __esm({
22576
22466
  "components/game/molecules/CombatLog.tsx"() {
22577
22467
  init_atoms2();
@@ -22594,14 +22484,14 @@ var init_CombatLog = __esm({
22594
22484
  death: "text-muted-foreground",
22595
22485
  spawn: "text-accent"
22596
22486
  };
22597
- eventBadgeVariants = {
22598
- attack: "danger",
22599
- defend: "primary",
22600
- heal: "success",
22601
- move: "warning",
22602
- special: "secondary",
22603
- death: "secondary",
22604
- spawn: "secondary"
22487
+ eventValueColors = {
22488
+ attack: "text-error bg-error/10 border-error/30",
22489
+ defend: "text-info bg-info/10 border-info/30",
22490
+ heal: "text-success bg-success/10 border-success/30",
22491
+ move: "text-warning bg-warning/10 border-warning/30",
22492
+ special: "text-accent bg-accent/10 border-accent/30",
22493
+ death: "text-muted-foreground bg-muted/30 border-border",
22494
+ spawn: "text-accent bg-accent/10 border-accent/30"
22605
22495
  };
22606
22496
  DEFAULT_COMBAT_EVENTS = [
22607
22497
  { id: "e1", type: "spawn", message: "Shadow Guard entered the field.", timestamp: 0, turn: 1 },
@@ -23025,7 +22915,7 @@ function CraftingRecipe({
23025
22915
  className
23026
22916
  }) {
23027
22917
  const eventBus = useEventBus();
23028
- const handleCraft = React85.useCallback(() => {
22918
+ const handleCraft = React87.useCallback(() => {
23029
22919
  onCraft?.();
23030
22920
  if (craftEvent) {
23031
22921
  eventBus.emit(craftEvent, { output: output.label });
@@ -23042,7 +22932,7 @@ function CraftingRecipe({
23042
22932
  children: [
23043
22933
  /* @__PURE__ */ jsx(HStack, { gap: "xs", className: "flex-wrap items-center", children: inputs.map((ingredient, index) => {
23044
22934
  const hasSufficient = ingredient.available >= ingredient.required;
23045
- return /* @__PURE__ */ jsxs(React85.Fragment, { children: [
22935
+ return /* @__PURE__ */ jsxs(React87.Fragment, { children: [
23046
22936
  /* @__PURE__ */ jsx(Box, { className: "relative", children: /* @__PURE__ */ jsx(
23047
22937
  ItemSlot,
23048
22938
  {
@@ -23067,13 +22957,13 @@ function CraftingRecipe({
23067
22957
  }
23068
22958
  ),
23069
22959
  /* @__PURE__ */ jsx(
23070
- Button,
22960
+ ActionButton,
23071
22961
  {
22962
+ label: "Craft",
23072
22963
  onClick: handleCraft,
23073
22964
  disabled: !canCraft,
23074
22965
  variant: canCraft ? "primary" : "secondary",
23075
- size: "sm",
23076
- children: "Craft"
22966
+ size: "sm"
23077
22967
  }
23078
22968
  )
23079
22969
  ]
@@ -23087,7 +22977,7 @@ var init_CraftingRecipe = __esm({
23087
22977
  init_cn();
23088
22978
  init_useEventBus();
23089
22979
  init_ItemSlot();
23090
- init_Button();
22980
+ init_ActionButton();
23091
22981
  init_Box();
23092
22982
  init_Stack();
23093
22983
  init_Icon();
@@ -23114,8 +23004,8 @@ function DPad({
23114
23004
  }) {
23115
23005
  const eventBus = useEventBus();
23116
23006
  const sizes = sizeMap15[size];
23117
- const [activeDirections, setActiveDirections] = React85.useState(/* @__PURE__ */ new Set());
23118
- const handlePress = React85.useCallback(
23007
+ const [activeDirections, setActiveDirections] = React87.useState(/* @__PURE__ */ new Set());
23008
+ const handlePress = React87.useCallback(
23119
23009
  (direction) => {
23120
23010
  setActiveDirections((prev) => new Set(prev).add(direction));
23121
23011
  if (directionEvent) eventBus.emit(`UI:${directionEvent}`, { direction, pressed: true });
@@ -23123,7 +23013,7 @@ function DPad({
23123
23013
  },
23124
23014
  [directionEvent, eventBus, onDirection]
23125
23015
  );
23126
- const handleRelease = React85.useCallback(
23016
+ const handleRelease = React87.useCallback(
23127
23017
  (direction) => {
23128
23018
  setActiveDirections((prev) => {
23129
23019
  const next = new Set(prev);
@@ -24008,8 +23898,8 @@ var init_Menu = __esm({
24008
23898
  "bottom-end": "bottom-start"
24009
23899
  };
24010
23900
  const effectivePosition = direction === "rtl" ? rtlMirror[position] ?? position : position;
24011
- const triggerChild = React85__default.isValidElement(trigger) ? trigger : /* @__PURE__ */ jsx(Typography, { variant: "small", as: "span", children: trigger });
24012
- const triggerElement = React85__default.cloneElement(
23901
+ const triggerChild = React87__default.isValidElement(trigger) ? trigger : /* @__PURE__ */ jsx(Typography, { variant: "small", as: "span", children: trigger });
23902
+ const triggerElement = React87__default.cloneElement(
24013
23903
  triggerChild,
24014
23904
  {
24015
23905
  ref: triggerRef,
@@ -24104,14 +23994,14 @@ function useDataDnd(args) {
24104
23994
  const isZone = Boolean(dragGroup || accepts || sortable);
24105
23995
  const enabled = isZone || Boolean(dndRoot);
24106
23996
  const eventBus = useEventBus();
24107
- const parentRoot = React85__default.useContext(RootCtx);
23997
+ const parentRoot = React87__default.useContext(RootCtx);
24108
23998
  const isRoot = enabled && parentRoot === null;
24109
- const zoneId = React85__default.useId();
23999
+ const zoneId = React87__default.useId();
24110
24000
  const ownGroup = dragGroup ?? accepts ?? zoneId;
24111
- const [optimisticOrders, setOptimisticOrders] = React85__default.useState(() => /* @__PURE__ */ new Map());
24112
- const optimisticOrdersRef = React85__default.useRef(optimisticOrders);
24001
+ const [optimisticOrders, setOptimisticOrders] = React87__default.useState(() => /* @__PURE__ */ new Map());
24002
+ const optimisticOrdersRef = React87__default.useRef(optimisticOrders);
24113
24003
  optimisticOrdersRef.current = optimisticOrders;
24114
- const clearOptimisticOrder = React85__default.useCallback((group) => {
24004
+ const clearOptimisticOrder = React87__default.useCallback((group) => {
24115
24005
  setOptimisticOrders((prev) => {
24116
24006
  if (!prev.has(group)) return prev;
24117
24007
  const next = new Map(prev);
@@ -24134,17 +24024,20 @@ function useDataDnd(args) {
24134
24024
  }
24135
24025
  const itemIdsSignature = orderedItems.map((it, idx) => {
24136
24026
  const raw = it[dndItemIdField];
24137
- return String(raw ?? `__idx_${idx}`);
24027
+ return raw != null ? String(raw) : `__idx_${idx}`;
24138
24028
  }).join("|");
24139
- const itemIds = React85__default.useMemo(
24029
+ const itemIds = React87__default.useMemo(
24140
24030
  () => orderedItems.map((it, idx) => {
24141
24031
  const raw = it[dndItemIdField];
24142
- return raw ?? `__idx_${idx}`;
24032
+ return raw != null ? String(raw) : `__idx_${idx}`;
24143
24033
  }),
24144
24034
  [itemIdsSignature]
24145
24035
  );
24146
- const itemsContentSig = items.map((it, idx) => String(it[dndItemIdField] ?? `__${idx}`)).join("|");
24147
- React85__default.useEffect(() => {
24036
+ const itemsContentSig = items.map((it, idx) => {
24037
+ const raw = it[dndItemIdField];
24038
+ return raw != null ? String(raw) : `__${idx}`;
24039
+ }).join("|");
24040
+ React87__default.useEffect(() => {
24148
24041
  const root = isRoot ? null : parentRoot;
24149
24042
  if (root) {
24150
24043
  root.clearOptimisticOrder(ownGroup);
@@ -24152,20 +24045,20 @@ function useDataDnd(args) {
24152
24045
  clearOptimisticOrder(ownGroup);
24153
24046
  }
24154
24047
  }, [itemsContentSig, ownGroup]);
24155
- const zonesRef = React85__default.useRef(/* @__PURE__ */ new Map());
24156
- const registerZone = React85__default.useCallback((zoneId2, meta2) => {
24048
+ const zonesRef = React87__default.useRef(/* @__PURE__ */ new Map());
24049
+ const registerZone = React87__default.useCallback((zoneId2, meta2) => {
24157
24050
  zonesRef.current.set(zoneId2, meta2);
24158
24051
  }, []);
24159
- const unregisterZone = React85__default.useCallback((zoneId2) => {
24052
+ const unregisterZone = React87__default.useCallback((zoneId2) => {
24160
24053
  zonesRef.current.delete(zoneId2);
24161
24054
  }, []);
24162
- const [activeDrag, setActiveDrag] = React85__default.useState(null);
24163
- const [overZoneGroup, setOverZoneGroup] = React85__default.useState(null);
24164
- const meta = React85__default.useMemo(
24055
+ const [activeDrag, setActiveDrag] = React87__default.useState(null);
24056
+ const [overZoneGroup, setOverZoneGroup] = React87__default.useState(null);
24057
+ const meta = React87__default.useMemo(
24165
24058
  () => ({ group: ownGroup, dropEvent, reorderEvent, positionEvent, itemIds, rawItems: items, idField: dndItemIdField }),
24166
24059
  [ownGroup, dropEvent, reorderEvent, positionEvent, itemIds, items, dndItemIdField]
24167
24060
  );
24168
- React85__default.useEffect(() => {
24061
+ React87__default.useEffect(() => {
24169
24062
  const target = isRoot ? null : parentRoot;
24170
24063
  if (!target) {
24171
24064
  zonesRef.current.set(zoneId, meta);
@@ -24184,7 +24077,7 @@ function useDataDnd(args) {
24184
24077
  }, [parentRoot, isRoot, zoneId, meta]);
24185
24078
  const sensors = useAlmadarDndSensors(true);
24186
24079
  const collisionDetection = almadarDndCollisionDetection;
24187
- const findZoneByItem = React85__default.useCallback(
24080
+ const findZoneByItem = React87__default.useCallback(
24188
24081
  (id) => {
24189
24082
  for (const z of zonesRef.current.values()) {
24190
24083
  if (z.itemIds.includes(id)) return z;
@@ -24193,7 +24086,7 @@ function useDataDnd(args) {
24193
24086
  },
24194
24087
  []
24195
24088
  );
24196
- React85__default.useCallback(
24089
+ React87__default.useCallback(
24197
24090
  (group) => {
24198
24091
  for (const z of zonesRef.current.values()) {
24199
24092
  if (z.group === group) return z;
@@ -24202,7 +24095,7 @@ function useDataDnd(args) {
24202
24095
  },
24203
24096
  []
24204
24097
  );
24205
- const handleDragEnd = React85__default.useCallback(
24098
+ const handleDragEnd = React87__default.useCallback(
24206
24099
  (event) => {
24207
24100
  const { active, over } = event;
24208
24101
  const activeIdStr = String(active.id);
@@ -24293,8 +24186,8 @@ function useDataDnd(args) {
24293
24186
  },
24294
24187
  [eventBus]
24295
24188
  );
24296
- const sortableData = React85__default.useMemo(() => ({ dndGroup: ownGroup }), [ownGroup]);
24297
- const SortableItem = React85__default.useCallback(
24189
+ const sortableData = React87__default.useMemo(() => ({ dndGroup: ownGroup }), [ownGroup]);
24190
+ const SortableItem = React87__default.useCallback(
24298
24191
  ({ id, children }) => {
24299
24192
  const {
24300
24193
  attributes,
@@ -24334,7 +24227,7 @@ function useDataDnd(args) {
24334
24227
  id: droppableId,
24335
24228
  data: sortableData
24336
24229
  });
24337
- const ctx = React85__default.useContext(RootCtx);
24230
+ const ctx = React87__default.useContext(RootCtx);
24338
24231
  const activeDrag2 = ctx?.activeDrag ?? null;
24339
24232
  const overZoneGroup2 = ctx?.overZoneGroup ?? null;
24340
24233
  const isThisZoneOver = overZoneGroup2 === ownGroup;
@@ -24349,7 +24242,7 @@ function useDataDnd(args) {
24349
24242
  showForeignPlaceholder,
24350
24243
  ctxAvailable: ctx != null
24351
24244
  });
24352
- React85__default.useEffect(() => {
24245
+ React87__default.useEffect(() => {
24353
24246
  dndLog.info("dropzone:isOver:change", { droppableId, group: ownGroup, isOver, isThisZoneOver, showForeignPlaceholder, activeDragSourceGroup: activeDrag2?.sourceGroup ?? null });
24354
24247
  }, [droppableId, isOver, isThisZoneOver, showForeignPlaceholder]);
24355
24248
  return /* @__PURE__ */ jsx(
@@ -24363,11 +24256,11 @@ function useDataDnd(args) {
24363
24256
  }
24364
24257
  );
24365
24258
  };
24366
- const rootContextValue = React85__default.useMemo(
24259
+ const rootContextValue = React87__default.useMemo(
24367
24260
  () => ({ registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder }),
24368
24261
  [registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder]
24369
24262
  );
24370
- const handleDragStart = React85__default.useCallback((event) => {
24263
+ const handleDragStart = React87__default.useCallback((event) => {
24371
24264
  const sourceZone = findZoneByItem(event.active.id);
24372
24265
  const rect = event.active.rect.current.initial;
24373
24266
  const height = rect?.height && rect.height > 0 ? rect.height : 64;
@@ -24386,7 +24279,7 @@ function useDataDnd(args) {
24386
24279
  isRoot
24387
24280
  });
24388
24281
  }, [findZoneByItem, isRoot, zoneId]);
24389
- const handleDragOver = React85__default.useCallback((event) => {
24282
+ const handleDragOver = React87__default.useCallback((event) => {
24390
24283
  const { active, over } = event;
24391
24284
  const overData = over?.data?.current;
24392
24285
  const overGroup = overData?.dndGroup ?? null;
@@ -24456,7 +24349,7 @@ function useDataDnd(args) {
24456
24349
  return next;
24457
24350
  });
24458
24351
  }, []);
24459
- const handleDragCancel = React85__default.useCallback((event) => {
24352
+ const handleDragCancel = React87__default.useCallback((event) => {
24460
24353
  setActiveDrag(null);
24461
24354
  setOverZoneGroup(null);
24462
24355
  dndLog.warn("dragCancel", {
@@ -24464,12 +24357,12 @@ function useDataDnd(args) {
24464
24357
  reason: "dnd-kit cancelled the drag (escape key, pointer interrupted, or external)"
24465
24358
  });
24466
24359
  }, []);
24467
- const handleDragEndWithCleanup = React85__default.useCallback((event) => {
24360
+ const handleDragEndWithCleanup = React87__default.useCallback((event) => {
24468
24361
  handleDragEnd(event);
24469
24362
  setActiveDrag(null);
24470
24363
  setOverZoneGroup(null);
24471
24364
  }, [handleDragEnd]);
24472
- const wrapContainer = React85__default.useCallback(
24365
+ const wrapContainer = React87__default.useCallback(
24473
24366
  (children) => {
24474
24367
  if (!enabled) return children;
24475
24368
  const strategy = layout === "grid" ? rectSortingStrategy : verticalListSortingStrategy;
@@ -24523,7 +24416,7 @@ var init_useDataDnd = __esm({
24523
24416
  init_useAlmadarDndCollision();
24524
24417
  init_Box();
24525
24418
  dndLog = createLogger("almadar:ui:dnd");
24526
- RootCtx = React85__default.createContext(null);
24419
+ RootCtx = React87__default.createContext(null);
24527
24420
  }
24528
24421
  });
24529
24422
  function renderIconInput(icon, props) {
@@ -24666,8 +24559,8 @@ function DataGrid({
24666
24559
  const hasRenderProp = typeof children === "function";
24667
24560
  useEffect(() => {
24668
24561
  if (data.length > 0 && !hasRenderProp && fieldDefs.length === 0) {
24669
- const renderItemRaw = schemaRenderItem;
24670
- const isFnLambda = Array.isArray(renderItemRaw) && renderItemRaw.length >= 3 && (renderItemRaw[0] === "fn" || renderItemRaw[0] === "lambda");
24562
+ const schemaArr = Array.isArray(schemaRenderItem) ? schemaRenderItem : null;
24563
+ const isFnLambda = schemaArr !== null && schemaArr.length >= 3 && (schemaArr[0] === "fn" || schemaArr[0] === "lambda");
24671
24564
  dataGridLog.warn("renderItem-unresolved", {
24672
24565
  rowCount: data.length,
24673
24566
  renderItemIsFnLambda: isFnLambda
@@ -25049,7 +24942,7 @@ function DataList({
25049
24942
  }) {
25050
24943
  const eventBus = useEventBus();
25051
24944
  const { t } = useTranslate();
25052
- const [visibleCount, setVisibleCount] = React85__default.useState(pageSize || Infinity);
24945
+ const [visibleCount, setVisibleCount] = React87__default.useState(pageSize || Infinity);
25053
24946
  const fieldDefs = fields ?? columns ?? [];
25054
24947
  const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
25055
24948
  const dnd = useDataDnd({
@@ -25068,21 +24961,20 @@ function DataList({
25068
24961
  const data = pageSize > 0 ? allData.slice(0, visibleCount) : allData;
25069
24962
  const hasMoreLocal = pageSize > 0 && visibleCount < allData.length;
25070
24963
  const hasRenderProp = typeof children === "function";
25071
- React85__default.useEffect(() => {
24964
+ React87__default.useEffect(() => {
25072
24965
  const renderItemTypeOf = typeof schemaRenderItem;
25073
24966
  const childrenTypeOf = typeof children;
25074
24967
  if (data.length > 0 && !hasRenderProp) {
25075
24968
  const firstRow = data[0];
25076
24969
  const sampleKeys = firstRow ? Object.keys(firstRow).slice(0, 6) : [];
25077
- const renderItemRaw = schemaRenderItem;
25078
- const isFnLambda = Array.isArray(renderItemRaw) && renderItemRaw.length >= 3 && (renderItemRaw[0] === "fn" || renderItemRaw[0] === "lambda");
24970
+ const isFnLambda = Array.isArray(schemaRenderItem) && schemaRenderItem.length >= 3 && (schemaRenderItem[0] === "fn" || schemaRenderItem[0] === "lambda");
25079
24971
  dataListLog.warn("renderItem-unresolved", {
25080
24972
  rowCount: data.length,
25081
24973
  fieldsCount: fieldDefs.length,
25082
24974
  renderItemTypeOf,
25083
- renderItemIsArray: Array.isArray(renderItemRaw),
24975
+ renderItemIsArray: Array.isArray(schemaRenderItem),
25084
24976
  renderItemIsFnLambda: isFnLambda,
25085
- renderItemHead: Array.isArray(renderItemRaw) ? String(renderItemRaw[0]) : void 0,
24977
+ renderItemHead: Array.isArray(schemaRenderItem) ? String(schemaRenderItem[0]) : void 0,
25086
24978
  childrenTypeOf,
25087
24979
  sampleRowKeys: sampleKeys
25088
24980
  });
@@ -25170,10 +25062,10 @@ function DataList({
25170
25062
  const isCompact = variant === "compact";
25171
25063
  const isMessage = variant === "message";
25172
25064
  if (isMessage) {
25173
- const items2 = data.map((item) => item);
25065
+ const items2 = [...data];
25174
25066
  const groups2 = groupBy ? groupData(items2, groupBy) : [{ label: "", items: items2 }];
25175
25067
  const contentField = titleField?.name ?? fieldDefs[0]?.name ?? "";
25176
- return /* @__PURE__ */ jsx(VStack, { gap: "sm", className: cn("py-2", className), children: groups2.map((group, gi) => /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
25068
+ return /* @__PURE__ */ jsx(VStack, { gap: "sm", className: cn("py-2", className), children: groups2.map((group, gi) => /* @__PURE__ */ jsxs(React87__default.Fragment, { children: [
25177
25069
  group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: "my-2" }),
25178
25070
  group.items.map((itemData, index) => {
25179
25071
  const id = itemData.id || `${gi}-${index}`;
@@ -25219,7 +25111,7 @@ function DataList({
25219
25111
  })
25220
25112
  ] }, gi)) });
25221
25113
  }
25222
- const items = data.map((item) => item);
25114
+ const items = [...data];
25223
25115
  const groups = groupBy ? groupData(items, groupBy) : [{ label: "", items }];
25224
25116
  const idFieldName = dndItemIdField ?? "id";
25225
25117
  const renderItem = (itemData, index, isLast) => {
@@ -25314,7 +25206,7 @@ function DataList({
25314
25206
  className
25315
25207
  ),
25316
25208
  children: [
25317
- groups.map((group, gi) => /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
25209
+ groups.map((group, gi) => /* @__PURE__ */ jsxs(React87__default.Fragment, { children: [
25318
25210
  group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: gi > 0 ? "mt-4" : "mt-0" }),
25319
25211
  group.items.map(
25320
25212
  (itemData, index) => renderItem(itemData, index, gi === groups.length - 1 && index === group.items.length - 1)
@@ -26107,23 +25999,19 @@ var init_Flex = __esm({
26107
25999
  flexStyle.flexBasis = typeof basis === "number" ? `${basis}px` : basis;
26108
26000
  }
26109
26001
  }
26110
- const Comp = Component2;
26111
- return /* @__PURE__ */ jsx(
26112
- Comp,
26113
- {
26114
- className: cn(
26115
- inline ? "inline-flex" : "flex",
26116
- directionStyles[direction],
26117
- wrapStyles[wrap],
26118
- alignStyles3[align],
26119
- justifyStyles2[justify],
26120
- gapStyles6[gap],
26121
- className
26122
- ),
26123
- style: Object.keys(flexStyle).length > 0 ? flexStyle : void 0,
26124
- children
26125
- }
26126
- );
26002
+ return React87__default.createElement(Component2, {
26003
+ className: cn(
26004
+ inline ? "inline-flex" : "flex",
26005
+ directionStyles[direction],
26006
+ wrapStyles[wrap],
26007
+ alignStyles3[align],
26008
+ justifyStyles2[justify],
26009
+ gapStyles6[gap],
26010
+ className
26011
+ ),
26012
+ style: Object.keys(flexStyle).length > 0 ? flexStyle : void 0,
26013
+ children
26014
+ });
26127
26015
  };
26128
26016
  Flex.displayName = "Flex";
26129
26017
  }
@@ -26230,7 +26118,7 @@ var init_Grid = __esm({
26230
26118
  as: Component2 = "div"
26231
26119
  }) => {
26232
26120
  const mergedStyle = rows2 ? { gridTemplateRows: `repeat(${rows2}, minmax(0, 1fr))`, ...style } : style;
26233
- return React85__default.createElement(
26121
+ return React87__default.createElement(
26234
26122
  Component2,
26235
26123
  {
26236
26124
  className: cn(
@@ -26426,9 +26314,9 @@ var init_Popover = __esm({
26426
26314
  onMouseLeave: handleClose,
26427
26315
  onPointerDown: tapTriggerProps.onPointerDown
26428
26316
  };
26429
- const childElement = React85__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
26317
+ const childElement = React87__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
26430
26318
  const childPointerDown = childElement.props.onPointerDown;
26431
- const triggerElement = React85__default.cloneElement(
26319
+ const triggerElement = React87__default.cloneElement(
26432
26320
  childElement,
26433
26321
  {
26434
26322
  ref: triggerRef,
@@ -27030,9 +26918,9 @@ var init_Tooltip = __esm({
27030
26918
  if (hideTimeoutRef.current) clearTimeout(hideTimeoutRef.current);
27031
26919
  };
27032
26920
  }, []);
27033
- const triggerElement = React85__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
26921
+ const triggerElement = React87__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
27034
26922
  const childPointerDown = triggerElement.props.onPointerDown;
27035
- const trigger = React85__default.cloneElement(triggerElement, {
26923
+ const trigger = React87__default.cloneElement(triggerElement, {
27036
26924
  ref: triggerRef,
27037
26925
  onMouseEnter: handleMouseEnter,
27038
26926
  onMouseLeave: handleMouseLeave,
@@ -27122,7 +27010,7 @@ var init_WizardProgress = __esm({
27122
27010
  children: /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", children: normalizedSteps.map((step, index) => {
27123
27011
  const isActive = index === currentStep;
27124
27012
  const isCompleted = index < currentStep;
27125
- return /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
27013
+ return /* @__PURE__ */ jsxs(React87__default.Fragment, { children: [
27126
27014
  /* @__PURE__ */ jsx(
27127
27015
  "button",
27128
27016
  {
@@ -27434,13 +27322,14 @@ var init_ViolationAlert = __esm({
27434
27322
  onNavigateToField,
27435
27323
  compact = false,
27436
27324
  className,
27437
- ...flatProps
27325
+ message
27438
27326
  }) => {
27439
27327
  const { t } = useTranslate();
27328
+ const fallbackMessage = message ?? t("violationAlert.fallbackMessage");
27440
27329
  const resolvedViolation = violation ?? {
27441
27330
  law: "",
27442
27331
  article: "",
27443
- message: flatProps.message ?? t("violationAlert.fallbackMessage"),
27332
+ message: fallbackMessage,
27444
27333
  actionType: "measure"
27445
27334
  };
27446
27335
  const effectiveSeverity = severity ?? (resolvedViolation.actionType === "measure" ? "warning" : "error");
@@ -28084,6 +27973,7 @@ var init_ProgressDots = __esm({
28084
27973
  });
28085
27974
  function StatBadge({
28086
27975
  assetUrl,
27976
+ iconUrl,
28087
27977
  label,
28088
27978
  value = 0,
28089
27979
  max,
@@ -28097,6 +27987,7 @@ function StatBadge({
28097
27987
  field: _field
28098
27988
  }) {
28099
27989
  const numValue = typeof value === "number" ? value : parseInt(String(value), 10) || 0;
27990
+ const resolvedAsset = iconUrl ?? assetUrl;
28100
27991
  return /* @__PURE__ */ jsxs(
28101
27992
  "div",
28102
27993
  {
@@ -28107,10 +27998,10 @@ function StatBadge({
28107
27998
  className
28108
27999
  ),
28109
28000
  children: [
28110
- assetUrl ? /* @__PURE__ */ jsx(
28001
+ resolvedAsset ? /* @__PURE__ */ jsx(
28111
28002
  "img",
28112
28003
  {
28113
- src: assetUrl,
28004
+ src: resolvedAsset,
28114
28005
  alt: "",
28115
28006
  width: 16,
28116
28007
  height: 16,
@@ -28141,8 +28032,7 @@ function StatBadge({
28141
28032
  ScoreDisplay,
28142
28033
  {
28143
28034
  value: numValue,
28144
- size: size === "lg" ? "md" : "sm",
28145
- animated: true
28035
+ size: size === "lg" ? "md" : "sm"
28146
28036
  }
28147
28037
  ),
28148
28038
  format === "text" && /* @__PURE__ */ jsx("span", { className: "font-bold text-foreground", children: value })
@@ -28185,7 +28075,7 @@ function InventoryGrid({
28185
28075
  const eventBus = useEventBus();
28186
28076
  const slotCount = totalSlots ?? items.length;
28187
28077
  const emptySlotCount = Math.max(0, slotCount - items.length);
28188
- const handleSelect = React85.useCallback(
28078
+ const handleSelect = React87.useCallback(
28189
28079
  (id) => {
28190
28080
  onSelect?.(id);
28191
28081
  if (selectEvent) {
@@ -28292,12 +28182,14 @@ function QuestTracker({
28292
28182
  }
28293
28183
  ),
28294
28184
  /* @__PURE__ */ jsx(Box, { className: "mt-1.5", children: /* @__PURE__ */ jsx(
28295
- ProgressBar,
28185
+ HealthBar,
28296
28186
  {
28297
- value: quest.progress,
28187
+ current: quest.progress,
28298
28188
  max: quest.maxProgress,
28299
- variant: isCompleted ? "success" : isActive ? "primary" : "default",
28300
- size: "sm"
28189
+ format: "bar",
28190
+ size: "sm",
28191
+ animated: true,
28192
+ className: isCompleted ? "[--health-color:var(--color-success)]" : isActive ? "" : "opacity-60"
28301
28193
  }
28302
28194
  ) }),
28303
28195
  /* @__PURE__ */ jsxs(
@@ -28325,7 +28217,7 @@ var init_QuestTracker = __esm({
28325
28217
  "use client";
28326
28218
  init_cn();
28327
28219
  init_WaypointMarker();
28328
- init_ProgressBar();
28220
+ init_HealthBar();
28329
28221
  init_Typography();
28330
28222
  init_Box();
28331
28223
  init_Stack();
@@ -28420,31 +28312,31 @@ function GameCanvas2D({
28420
28312
  assetBaseUrl,
28421
28313
  className
28422
28314
  }) {
28423
- const canvasRef = React85.useRef(null);
28424
- const rafRef = React85.useRef(0);
28425
- const frameRef = React85.useRef(0);
28426
- const lastTimeRef = React85.useRef(0);
28427
- const imageCache = React85.useRef(/* @__PURE__ */ new Map());
28315
+ const canvasRef = React87.useRef(null);
28316
+ const rafRef = React87.useRef(0);
28317
+ const frameRef = React87.useRef(0);
28318
+ const lastTimeRef = React87.useRef(0);
28319
+ const imageCache = React87.useRef(/* @__PURE__ */ new Map());
28428
28320
  const emit = useEmitEvent();
28429
- const onDrawRef = React85.useRef(onDraw);
28321
+ const onDrawRef = React87.useRef(onDraw);
28430
28322
  onDrawRef.current = onDraw;
28431
- const onTickRef = React85.useRef(onTick);
28323
+ const onTickRef = React87.useRef(onTick);
28432
28324
  onTickRef.current = onTick;
28433
- const tickEventRef = React85.useRef(tickEvent);
28325
+ const tickEventRef = React87.useRef(tickEvent);
28434
28326
  tickEventRef.current = tickEvent;
28435
- const drawEventRef = React85.useRef(drawEvent);
28327
+ const drawEventRef = React87.useRef(drawEvent);
28436
28328
  drawEventRef.current = drawEvent;
28437
- const emitRef = React85.useRef(emit);
28329
+ const emitRef = React87.useRef(emit);
28438
28330
  emitRef.current = emit;
28439
- const assetBaseUrlRef = React85.useRef(assetBaseUrl);
28331
+ const assetBaseUrlRef = React87.useRef(assetBaseUrl);
28440
28332
  assetBaseUrlRef.current = assetBaseUrl;
28441
- const backgroundImageRef = React85.useRef(backgroundImage);
28333
+ const backgroundImageRef = React87.useRef(backgroundImage);
28442
28334
  backgroundImageRef.current = backgroundImage;
28443
- const widthRef = React85.useRef(width);
28335
+ const widthRef = React87.useRef(width);
28444
28336
  widthRef.current = width;
28445
- const heightRef = React85.useRef(height);
28337
+ const heightRef = React87.useRef(height);
28446
28338
  heightRef.current = height;
28447
- const loadImage = React85.useCallback((url) => {
28339
+ const loadImage = React87.useCallback((url) => {
28448
28340
  const base = assetBaseUrlRef.current;
28449
28341
  if (!url.startsWith("http") && !base) return null;
28450
28342
  const fullUrl = url.startsWith("http") ? url : `${base}${url}`;
@@ -28458,7 +28350,7 @@ function GameCanvas2D({
28458
28350
  }
28459
28351
  return null;
28460
28352
  }, []);
28461
- React85.useEffect(() => {
28353
+ React87.useEffect(() => {
28462
28354
  const canvas = canvasRef.current;
28463
28355
  if (!canvas) return;
28464
28356
  const ctx = canvas.getContext("2d");
@@ -28606,26 +28498,14 @@ function HealthPanel({
28606
28498
  )
28607
28499
  }
28608
28500
  ),
28609
- effects && effects.length > 0 && /* @__PURE__ */ jsx(Box, { className: "flex items-center gap-1 flex-wrap", children: effects.map((effect, i) => /* @__PURE__ */ jsxs(
28610
- Badge,
28501
+ effects && effects.length > 0 && /* @__PURE__ */ jsx(Box, { className: "flex items-center gap-1 flex-wrap", children: effects.map((effect, i) => /* @__PURE__ */ jsx(
28502
+ StatusEffect,
28611
28503
  {
28504
+ assetUrl: effect.assetUrl,
28505
+ icon: effect.icon,
28506
+ label: effect.label,
28612
28507
  variant: effectVariantMap[effect.variant ?? "neutral"],
28613
- size: "sm",
28614
- icon: effect.assetUrl ? void 0 : effect.icon,
28615
- children: [
28616
- effect.assetUrl && /* @__PURE__ */ jsx(
28617
- "img",
28618
- {
28619
- src: effect.assetUrl,
28620
- alt: "",
28621
- width: 12,
28622
- height: 12,
28623
- style: { imageRendering: "pixelated", objectFit: "contain" },
28624
- className: "flex-shrink-0 inline-block"
28625
- }
28626
- ),
28627
- effect.label
28628
- ]
28508
+ size: "sm"
28629
28509
  },
28630
28510
  i
28631
28511
  )) })
@@ -28639,17 +28519,17 @@ var init_HealthPanel = __esm({
28639
28519
  "use client";
28640
28520
  init_cn();
28641
28521
  init_HealthBar();
28522
+ init_StatusEffect();
28642
28523
  init_Box();
28643
28524
  init_Typography();
28644
- init_Badge();
28645
28525
  sizeMap18 = {
28646
28526
  sm: { gap: "gap-1", padding: "px-2 py-1.5", text: "text-xs", barSize: "sm" },
28647
28527
  md: { gap: "gap-1.5", padding: "px-3 py-2", text: "text-sm", barSize: "md" },
28648
28528
  lg: { gap: "gap-2", padding: "px-4 py-3", text: "text-base", barSize: "lg" }
28649
28529
  };
28650
28530
  effectVariantMap = {
28651
- buff: "success",
28652
- debuff: "danger",
28531
+ buff: "buff",
28532
+ debuff: "debuff",
28653
28533
  neutral: "neutral"
28654
28534
  };
28655
28535
  HealthPanel.displayName = "HealthPanel";
@@ -28669,13 +28549,13 @@ function ScoreBoard({
28669
28549
  const multiplier = rawMultiplier ?? 1;
28670
28550
  const level = rawLevel ?? 1;
28671
28551
  return /* @__PURE__ */ jsx(
28672
- Card,
28552
+ Box,
28673
28553
  {
28674
28554
  className: cn(
28675
- "bg-[var(--color-card)]/90 border-border backdrop-blur-sm",
28555
+ "rounded-container border border-border bg-[var(--color-card)]/90 backdrop-blur-sm p-3",
28676
28556
  className
28677
28557
  ),
28678
- children: /* @__PURE__ */ jsx(CardContent, { className: "p-3", children: /* @__PURE__ */ jsxs(Box, { className: "flex items-center gap-3 flex-wrap", children: [
28558
+ children: /* @__PURE__ */ jsxs(Box, { className: "flex items-center gap-3 flex-wrap", children: [
28679
28559
  /* @__PURE__ */ jsx(
28680
28560
  StatBadge,
28681
28561
  {
@@ -28717,7 +28597,7 @@ function ScoreBoard({
28717
28597
  }
28718
28598
  ),
28719
28599
  combo != null && combo > 0 && /* @__PURE__ */ jsx(ComboCounter, { combo, multiplier, size: "sm" })
28720
- ] }) })
28600
+ ] })
28721
28601
  }
28722
28602
  );
28723
28603
  }
@@ -28727,7 +28607,6 @@ var init_ScoreBoard = __esm({
28727
28607
  init_cn();
28728
28608
  init_ComboCounter();
28729
28609
  init_StatBadge();
28730
- init_Card();
28731
28610
  init_Box();
28732
28611
  ScoreBoard.displayName = "ScoreBoard";
28733
28612
  }
@@ -28783,7 +28662,7 @@ function TurnPanel({
28783
28662
  className
28784
28663
  }) {
28785
28664
  const eventBus = useEventBus();
28786
- const handleAction = React85.useCallback(
28665
+ const handleAction = React87.useCallback(
28787
28666
  (event) => {
28788
28667
  if (event) {
28789
28668
  eventBus.emit(event, { turn: currentTurn, phase, activeTeam });
@@ -28808,28 +28687,16 @@ function TurnPanel({
28808
28687
  activeTeam
28809
28688
  }
28810
28689
  ),
28811
- actions && actions.length > 0 && /* @__PURE__ */ jsx(Box, { className: "flex items-center gap-1.5 ml-auto", children: actions.map((action, i) => /* @__PURE__ */ jsxs(
28812
- Button,
28690
+ actions && actions.length > 0 && /* @__PURE__ */ jsx(Box, { className: "flex items-center gap-1.5 ml-auto", children: actions.map((action, i) => /* @__PURE__ */ jsx(
28691
+ ActionButton,
28813
28692
  {
28814
- variant: "ghost",
28815
- size: "sm",
28693
+ label: action.label,
28694
+ icon: action.assetUrl ? void 0 : action.icon,
28695
+ assetUrl: action.assetUrl,
28816
28696
  disabled: action.disabled,
28817
- leftIcon: action.assetUrl ? void 0 : action.icon,
28818
- onClick: () => handleAction(action.event),
28819
- children: [
28820
- action.assetUrl && /* @__PURE__ */ jsx(
28821
- "img",
28822
- {
28823
- src: action.assetUrl,
28824
- alt: "",
28825
- width: 14,
28826
- height: 14,
28827
- style: { imageRendering: "pixelated", objectFit: "contain" },
28828
- className: "flex-shrink-0"
28829
- }
28830
- ),
28831
- action.label
28832
- ]
28697
+ variant: "secondary",
28698
+ size: "sm",
28699
+ onClick: () => handleAction(action.event)
28833
28700
  },
28834
28701
  i
28835
28702
  )) })
@@ -28843,7 +28710,7 @@ var init_TurnPanel = __esm({
28843
28710
  "use client";
28844
28711
  init_cn();
28845
28712
  init_TurnIndicator();
28846
- init_Button();
28713
+ init_ActionButton();
28847
28714
  init_Box();
28848
28715
  init_useEventBus();
28849
28716
  DEFAULT_TURN_ACTIONS = [
@@ -28894,7 +28761,7 @@ function EnemyPlate({
28894
28761
  }
28895
28762
  )
28896
28763
  ] }),
28897
- level != null && /* @__PURE__ */ jsxs(Badge, { variant: "neutral", size: "sm", children: [
28764
+ level != null && /* @__PURE__ */ jsxs("span", { className: "text-xs font-bold text-muted-foreground bg-muted/60 rounded px-1.5 py-0.5 border border-border/50 shrink-0", children: [
28898
28765
  "Lv.",
28899
28766
  level
28900
28767
  ] })
@@ -28925,12 +28792,12 @@ function EnemyPlate({
28925
28792
  )
28926
28793
  ] }),
28927
28794
  effects && effects.length > 0 && /* @__PURE__ */ jsx(Box, { className: "flex items-center gap-1 flex-wrap", children: effects.map((effect, i) => /* @__PURE__ */ jsx(
28928
- Badge,
28795
+ StatusEffect,
28929
28796
  {
28930
- variant: effectVariantMap2[effect.variant ?? "neutral"],
28931
- size: "sm",
28932
28797
  icon: effect.icon,
28933
- children: effect.label
28798
+ label: effect.label,
28799
+ variant: effectVariantMap2[effect.variant ?? "neutral"],
28800
+ size: "sm"
28934
28801
  },
28935
28802
  i
28936
28803
  )) })
@@ -28944,12 +28811,12 @@ var init_EnemyPlate = __esm({
28944
28811
  "use client";
28945
28812
  init_cn();
28946
28813
  init_HealthBar();
28814
+ init_StatusEffect();
28947
28815
  init_Box();
28948
28816
  init_Typography();
28949
- init_Badge();
28950
28817
  effectVariantMap2 = {
28951
- buff: "success",
28952
- debuff: "danger",
28818
+ buff: "buff",
28819
+ debuff: "debuff",
28953
28820
  neutral: "neutral"
28954
28821
  };
28955
28822
  DEFAULT_ENEMY_EFFECTS = [
@@ -28964,7 +28831,7 @@ function UnitCommandBar({
28964
28831
  className
28965
28832
  }) {
28966
28833
  const eventBus = useEventBus();
28967
- const handleCommand = React85.useCallback(
28834
+ const handleCommand = React87.useCallback(
28968
28835
  (event) => {
28969
28836
  if (event) {
28970
28837
  eventBus.emit(event, { unitId: selectedUnitId });
@@ -28979,27 +28846,18 @@ function UnitCommandBar({
28979
28846
  "flex items-center gap-1.5 rounded-container bg-[var(--color-card)]/90 border border-border backdrop-blur-sm px-2 py-1.5",
28980
28847
  className
28981
28848
  ),
28982
- children: commands.map((command, i) => /* @__PURE__ */ jsxs(Box, { className: "flex flex-col items-center gap-0.5", children: [
28983
- /* @__PURE__ */ jsx(
28984
- Button,
28985
- {
28986
- variant: "ghost",
28987
- size: "sm",
28988
- disabled: command.disabled,
28989
- leftIcon: command.icon,
28990
- onClick: () => handleCommand(command.event),
28991
- children: command.label
28992
- }
28993
- ),
28994
- command.hotkey && /* @__PURE__ */ jsx(
28995
- Typography,
28996
- {
28997
- variant: "caption",
28998
- className: "text-muted-foreground text-xs font-mono",
28999
- children: command.hotkey
29000
- }
29001
- )
29002
- ] }, i))
28849
+ children: commands.map((command, i) => /* @__PURE__ */ jsx(Box, { className: "flex flex-col items-center gap-0.5", children: /* @__PURE__ */ jsx(
28850
+ ActionButton,
28851
+ {
28852
+ label: command.label,
28853
+ icon: command.icon,
28854
+ disabled: command.disabled,
28855
+ hotkey: command.hotkey,
28856
+ variant: "secondary",
28857
+ size: "sm",
28858
+ onClick: () => handleCommand(command.event)
28859
+ }
28860
+ ) }, i))
29003
28861
  }
29004
28862
  );
29005
28863
  }
@@ -29008,9 +28866,8 @@ var init_UnitCommandBar = __esm({
29008
28866
  "components/game/molecules/UnitCommandBar.tsx"() {
29009
28867
  "use client";
29010
28868
  init_cn();
29011
- init_Button();
28869
+ init_ActionButton();
29012
28870
  init_Box();
29013
- init_Typography();
29014
28871
  init_useEventBus();
29015
28872
  DEFAULT_COMMANDS = [
29016
28873
  { label: "Move", icon: "move", event: "MOVE", hotkey: "M" },
@@ -29515,7 +29372,7 @@ function GameMenu({
29515
29372
  } catch {
29516
29373
  }
29517
29374
  const eventBus = eventBusProp || eventBusFromHook;
29518
- const handleOptionClick = React85.useCallback(
29375
+ const handleOptionClick = React87.useCallback(
29519
29376
  (option) => {
29520
29377
  if (option.event && eventBus) {
29521
29378
  eventBus.emit(`UI:${option.event}`, { option });
@@ -29634,7 +29491,7 @@ function GameOverScreen({
29634
29491
  } catch {
29635
29492
  }
29636
29493
  const eventBus = eventBusProp || eventBusFromHook;
29637
- const handleActionClick = React85.useCallback(
29494
+ const handleActionClick = React87.useCallback(
29638
29495
  (action) => {
29639
29496
  if (action.event && eventBus) {
29640
29497
  eventBus.emit(`UI:${action.event}`, { action });
@@ -29849,6 +29706,7 @@ function PlatformerCanvas({
29849
29706
  rightEvent = "MOVE_RIGHT",
29850
29707
  jumpEvent = "JUMP",
29851
29708
  stopEvent = "STOP",
29709
+ effects = [],
29852
29710
  className
29853
29711
  }) {
29854
29712
  const canvasRef = useRef(null);
@@ -29919,7 +29777,8 @@ function PlatformerCanvas({
29919
29777
  playerSprite,
29920
29778
  tileSprites,
29921
29779
  backgroundImage,
29922
- assetBaseUrl
29780
+ assetBaseUrl,
29781
+ effects
29923
29782
  });
29924
29783
  propsRef.current = {
29925
29784
  platforms,
@@ -29932,7 +29791,8 @@ function PlatformerCanvas({
29932
29791
  playerSprite,
29933
29792
  tileSprites,
29934
29793
  backgroundImage,
29935
- assetBaseUrl
29794
+ assetBaseUrl,
29795
+ effects
29936
29796
  };
29937
29797
  const handleKeyDown = useCallback((e) => {
29938
29798
  if (keysRef.current.has(e.code)) return;
@@ -29999,7 +29859,8 @@ function PlatformerCanvas({
29999
29859
  bgColor: bg,
30000
29860
  playerSprite: pSprite,
30001
29861
  tileSprites: tSprites,
30002
- backgroundImage: bgImg
29862
+ backgroundImage: bgImg,
29863
+ effects: fxList
30003
29864
  } = propsRef.current;
30004
29865
  const auth = playerRef.current;
30005
29866
  const interped = positions.get("player");
@@ -30153,6 +30014,18 @@ function PlatformerCanvas({
30153
30014
  ctx.arc(ppx + eyeOffsetX + 7, eyeY, eyeSize, 0, Math.PI * 2);
30154
30015
  ctx.fill();
30155
30016
  }
30017
+ for (const fx of fxList) {
30018
+ const fxScreenX = fx.x - camX;
30019
+ const fxScreenY = fx.y - camY;
30020
+ const alpha = Math.min(1, fx.ttl / 4);
30021
+ const prev = ctx.globalAlpha;
30022
+ ctx.globalAlpha = alpha;
30023
+ ctx.fillStyle = "#ffe066";
30024
+ ctx.beginPath();
30025
+ ctx.arc(fxScreenX, fxScreenY, 12, 0, Math.PI * 2);
30026
+ ctx.fill();
30027
+ ctx.globalAlpha = prev;
30028
+ }
30156
30029
  };
30157
30030
  return interp.startLoop(drawFrame);
30158
30031
  }, [interp.startLoop, loadImage]);
@@ -30566,13 +30439,13 @@ var init_MapView = __esm({
30566
30439
  shadowSize: [41, 41]
30567
30440
  });
30568
30441
  L.Marker.prototype.options.icon = defaultIcon;
30569
- const { useEffect: useEffect85, useRef: useRef80, useCallback: useCallback127, useState: useState117 } = React85__default;
30442
+ const { useEffect: useEffect83, useRef: useRef80, useCallback: useCallback127, useState: useState115 } = React87__default;
30570
30443
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
30571
30444
  const { useEventBus: useEventBus4 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
30572
30445
  function MapUpdater({ centerLat, centerLng, zoom }) {
30573
30446
  const map = useMap();
30574
30447
  const prevRef = useRef80({ centerLat, centerLng, zoom });
30575
- useEffect85(() => {
30448
+ useEffect83(() => {
30576
30449
  const prev = prevRef.current;
30577
30450
  if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
30578
30451
  map.setView([centerLat, centerLng], zoom);
@@ -30583,7 +30456,7 @@ var init_MapView = __esm({
30583
30456
  }
30584
30457
  function MapClickHandler({ onMapClick }) {
30585
30458
  const map = useMap();
30586
- useEffect85(() => {
30459
+ useEffect83(() => {
30587
30460
  if (!onMapClick) return;
30588
30461
  const handler = (e) => {
30589
30462
  onMapClick(e.latlng.lat, e.latlng.lng);
@@ -30611,7 +30484,7 @@ var init_MapView = __esm({
30611
30484
  showAttribution = true
30612
30485
  }) {
30613
30486
  const eventBus = useEventBus4();
30614
- const [clickedPosition, setClickedPosition] = useState117(null);
30487
+ const [clickedPosition, setClickedPosition] = useState115(null);
30615
30488
  const handleMapClick = useCallback127((lat, lng) => {
30616
30489
  if (showClickedPin) {
30617
30490
  setClickedPosition({ lat, lng });
@@ -31402,6 +31275,15 @@ function renderIconInput3(icon, props) {
31402
31275
  function columnLabel(col) {
31403
31276
  return col.header ?? col.label ?? col.key.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/[_-]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
31404
31277
  }
31278
+ function asFieldValue(v) {
31279
+ if (v === void 0 || v === null) return v;
31280
+ const t = typeof v;
31281
+ if (t === "string" || t === "number" || t === "boolean") return v;
31282
+ if (v instanceof Date) return v;
31283
+ if (Array.isArray(v)) return v;
31284
+ if (t === "object") return v;
31285
+ return void 0;
31286
+ }
31405
31287
  function statusVariant4(value) {
31406
31288
  const v = value.toLowerCase();
31407
31289
  if (["active", "completed", "done", "approved", "published", "resolved", "open", "online", "ok"].includes(v)) return "success";
@@ -31472,8 +31354,8 @@ function TableView({
31472
31354
  }) {
31473
31355
  const eventBus = useEventBus();
31474
31356
  const { t } = useTranslate();
31475
- const [visibleCount, setVisibleCount] = React85__default.useState(pageSize > 0 ? pageSize : Infinity);
31476
- const [localSelected, setLocalSelected] = React85__default.useState(/* @__PURE__ */ new Set());
31357
+ const [visibleCount, setVisibleCount] = React87__default.useState(pageSize > 0 ? pageSize : Infinity);
31358
+ const [localSelected, setLocalSelected] = React87__default.useState(/* @__PURE__ */ new Set());
31477
31359
  const colDefs = columns ?? fields ?? [];
31478
31360
  const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
31479
31361
  const dnd = useDataDnd({
@@ -31618,7 +31500,7 @@ function TableView({
31618
31500
  }
31619
31501
  ) }),
31620
31502
  hasRenderProp ? /* @__PURE__ */ jsx(Box, { className: "flex-1 min-w-0", children: children(row, index) }) : colDefs.map((col) => {
31621
- const raw = getNestedValue(row, col.field ?? col.key);
31503
+ const raw = asFieldValue(getNestedValue(row, col.field ?? col.key));
31622
31504
  const cellBase = cn(
31623
31505
  "flex items-center min-w-0",
31624
31506
  alignClass[col.align ?? "left"],
@@ -31668,12 +31550,12 @@ function TableView({
31668
31550
  ]
31669
31551
  }
31670
31552
  );
31671
- return dnd.isZone ? /* @__PURE__ */ jsx(dnd.SortableItem, { id: row[idField] ?? id, children: rowInner }, id) : /* @__PURE__ */ jsx(React85__default.Fragment, { children: rowInner }, id);
31553
+ return dnd.isZone ? /* @__PURE__ */ jsx(dnd.SortableItem, { id: row[idField] ?? id, children: rowInner }, id) : /* @__PURE__ */ jsx(React87__default.Fragment, { children: rowInner }, id);
31672
31554
  };
31673
- const items = data.map((row) => row);
31555
+ const items = Array.from(data);
31674
31556
  const groups = groupBy ? groupData2(items, groupBy) : [{ label: "", items }];
31675
31557
  let runningIndex = 0;
31676
- const body = /* @__PURE__ */ jsx(Box, { role: "rowgroup", children: groups.map((group, gi) => /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
31558
+ const body = /* @__PURE__ */ jsx(Box, { role: "rowgroup", children: groups.map((group, gi) => /* @__PURE__ */ jsxs(React87__default.Fragment, { children: [
31677
31559
  group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: gi > 0 ? "mt-3" : "mt-0" }),
31678
31560
  group.items.map((row) => renderRow(row, runningIndex++))
31679
31561
  ] }, gi)) });
@@ -33030,7 +32912,7 @@ var init_StepFlow = __esm({
33030
32912
  className
33031
32913
  }) => {
33032
32914
  if (orientation === "vertical") {
33033
- return /* @__PURE__ */ jsx(VStack, { gap: "none", className: cn("w-full", className), children: steps.map((step, index) => /* @__PURE__ */ jsx(React85__default.Fragment, { children: /* @__PURE__ */ jsxs(HStack, { gap: "md", align: "start", className: "w-full", children: [
32915
+ return /* @__PURE__ */ jsx(VStack, { gap: "none", className: cn("w-full", className), children: steps.map((step, index) => /* @__PURE__ */ jsx(React87__default.Fragment, { children: /* @__PURE__ */ jsxs(HStack, { gap: "md", align: "start", className: "w-full", children: [
33034
32916
  /* @__PURE__ */ jsxs(VStack, { gap: "none", align: "center", children: [
33035
32917
  /* @__PURE__ */ jsx(StepCircle, { step, index }),
33036
32918
  showConnectors && index < steps.length - 1 && /* @__PURE__ */ jsx(Box, { className: "w-px h-8 bg-border" })
@@ -33041,7 +32923,7 @@ var init_StepFlow = __esm({
33041
32923
  ] })
33042
32924
  ] }) }, index)) });
33043
32925
  }
33044
- 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(React85__default.Fragment, { children: [
32926
+ 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(React87__default.Fragment, { children: [
33045
32927
  /* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", className: "flex-1 w-full md:w-auto", children: [
33046
32928
  /* @__PURE__ */ jsx(StepCircle, { step, index }),
33047
32929
  /* @__PURE__ */ jsx(Typography, { variant: "h4", className: "text-center", children: step.title }),
@@ -34026,7 +33908,7 @@ var init_LikertScale = __esm({
34026
33908
  md: "text-base",
34027
33909
  lg: "text-lg"
34028
33910
  };
34029
- LikertScale = React85__default.forwardRef(
33911
+ LikertScale = React87__default.forwardRef(
34030
33912
  ({
34031
33913
  question,
34032
33914
  options = DEFAULT_LIKERT_OPTIONS,
@@ -34038,7 +33920,7 @@ var init_LikertScale = __esm({
34038
33920
  variant = "radios",
34039
33921
  className
34040
33922
  }, ref) => {
34041
- const groupId = React85__default.useId();
33923
+ const groupId = React87__default.useId();
34042
33924
  const eventBus = useEventBus();
34043
33925
  const handleSelect = useCallback(
34044
33926
  (next) => {
@@ -34933,11 +34815,11 @@ function nextBlockId(prefix = "blk") {
34933
34815
  function normalizeBlocks(raw) {
34934
34816
  if (!Array.isArray(raw) || raw.length === 0) return [createBlock("paragraph")];
34935
34817
  return raw.map((row) => {
34936
- const r = row;
34937
- const rawType = r.type;
34818
+ const entity = row;
34819
+ const rawType = entity.type;
34938
34820
  const type = typeof rawType === "string" && BLOCK_TYPES.has(rawType) ? rawType : "paragraph";
34939
- const id = typeof r.id === "string" && r.id ? r.id : nextBlockId(type);
34940
- return { ...r, id, type };
34821
+ const id = typeof entity.id === "string" && entity.id ? entity.id : nextBlockId(type);
34822
+ return { ...entity, id, type };
34941
34823
  });
34942
34824
  }
34943
34825
  function createBlock(type) {
@@ -36320,7 +36202,7 @@ var init_DocBreadcrumb = __esm({
36320
36202
  "aria-label": t("aria.breadcrumb"),
36321
36203
  children: /* @__PURE__ */ jsx(HStack, { gap: "xs", align: "center", wrap: true, children: items.map((item, idx) => {
36322
36204
  const isLast = idx === items.length - 1;
36323
- return /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
36205
+ return /* @__PURE__ */ jsxs(React87__default.Fragment, { children: [
36324
36206
  idx > 0 && /* @__PURE__ */ jsx(
36325
36207
  Icon,
36326
36208
  {
@@ -37188,8 +37070,8 @@ var init_MiniStateMachine = __esm({
37188
37070
  states.map((s, i) => {
37189
37071
  const x = 2 + i * (NODE_W + GAP + ARROW_W + GAP);
37190
37072
  const tc = transitionCounts[s.name] ?? 0;
37191
- const role = getStateRole(s.name, s.isInitial, s.isTerminal, tc, maxTC);
37192
- return /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
37073
+ const role = getStateRole(s.name, s.isInitial ?? void 0, s.isTerminal ?? void 0, tc, maxTC);
37074
+ return /* @__PURE__ */ jsxs(React87__default.Fragment, { children: [
37193
37075
  /* @__PURE__ */ jsx(
37194
37076
  AvlState,
37195
37077
  {
@@ -37199,8 +37081,8 @@ var init_MiniStateMachine = __esm({
37199
37081
  height: NODE_H,
37200
37082
  name: "",
37201
37083
  role,
37202
- isInitial: s.isInitial,
37203
- isTerminal: s.isTerminal
37084
+ isInitial: s.isInitial ?? void 0,
37085
+ isTerminal: s.isTerminal ?? void 0
37204
37086
  }
37205
37087
  ),
37206
37088
  i < states.length - 1 && /* @__PURE__ */ jsxs("g", { children: [
@@ -37393,7 +37275,7 @@ var init_PageHeader = __esm({
37393
37275
  info: "bg-info/10 text-info"
37394
37276
  };
37395
37277
  return /* @__PURE__ */ jsxs(Box, { className: cn("mb-6", className), children: [
37396
- 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(React85__default.Fragment, { children: [
37278
+ 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(React87__default.Fragment, { children: [
37397
37279
  idx > 0 && /* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", children: "/" }),
37398
37280
  crumb.href ? /* @__PURE__ */ jsx(
37399
37281
  "a",
@@ -37751,52 +37633,49 @@ var init_Section = __esm({
37751
37633
  as: Component2 = "section"
37752
37634
  }) => {
37753
37635
  const hasHeader = title || description || action;
37754
- const Comp = Component2;
37755
- return /* @__PURE__ */ jsxs(
37756
- Comp,
37636
+ return React87__default.createElement(
37637
+ Component2,
37757
37638
  {
37758
37639
  className: cn(
37759
37640
  paddingStyles4[padding],
37760
37641
  variantStyles9[variant],
37761
37642
  className
37762
- ),
37763
- children: [
37764
- hasHeader && /* @__PURE__ */ jsxs(
37765
- Box,
37766
- {
37767
- className: cn(
37768
- "flex flex-col sm:flex-row sm:items-start sm:justify-between gap-2 sm:gap-4",
37769
- divider && "pb-4 mb-4 border-b-[length:var(--border-width)] border-border",
37770
- !divider && "mb-4",
37771
- headerClassName
37772
- ),
37773
- children: [
37774
- /* @__PURE__ */ jsxs(Box, { className: "flex-1 min-w-0", children: [
37775
- title && /* @__PURE__ */ jsx(
37776
- Typography,
37777
- {
37778
- variant: "h4",
37779
- className: "text-foreground font-semibold",
37780
- children: title
37781
- }
37782
- ),
37783
- description && /* @__PURE__ */ jsx(
37784
- Typography,
37785
- {
37786
- variant: "body",
37787
- color: "muted",
37788
- className: "mt-1",
37789
- children: description
37790
- }
37791
- )
37792
- ] }),
37793
- action && /* @__PURE__ */ jsx(Box, { className: "flex-shrink-0 flex items-center gap-2", children: action })
37794
- ]
37795
- }
37643
+ )
37644
+ },
37645
+ hasHeader && /* @__PURE__ */ jsxs(
37646
+ Box,
37647
+ {
37648
+ className: cn(
37649
+ "flex flex-col sm:flex-row sm:items-start sm:justify-between gap-2 sm:gap-4",
37650
+ divider && "pb-4 mb-4 border-b-[length:var(--border-width)] border-border",
37651
+ !divider && "mb-4",
37652
+ headerClassName
37796
37653
  ),
37797
- /* @__PURE__ */ jsx(Box, { className: contentClassName, children })
37798
- ]
37799
- }
37654
+ children: [
37655
+ /* @__PURE__ */ jsxs(Box, { className: "flex-1 min-w-0", children: [
37656
+ title && /* @__PURE__ */ jsx(
37657
+ Typography,
37658
+ {
37659
+ variant: "h4",
37660
+ className: "text-foreground font-semibold",
37661
+ children: title
37662
+ }
37663
+ ),
37664
+ description && /* @__PURE__ */ jsx(
37665
+ Typography,
37666
+ {
37667
+ variant: "body",
37668
+ color: "muted",
37669
+ className: "mt-1",
37670
+ children: description
37671
+ }
37672
+ )
37673
+ ] }),
37674
+ action && /* @__PURE__ */ jsx(Box, { className: "flex-shrink-0 flex items-center gap-2", children: action })
37675
+ ]
37676
+ }
37677
+ ),
37678
+ /* @__PURE__ */ jsx(Box, { className: contentClassName, children })
37800
37679
  );
37801
37680
  };
37802
37681
  Section.displayName = "Section";
@@ -38122,7 +38001,7 @@ var init_WizardContainer = __esm({
38122
38001
  const isCompleted = index < currentStep;
38123
38002
  const stepKey = step.id ?? step.tabId ?? `step-${index}`;
38124
38003
  const stepTitle = step.title ?? step.name ?? `Step ${index + 1}`;
38125
- return /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
38004
+ return /* @__PURE__ */ jsxs(React87__default.Fragment, { children: [
38126
38005
  /* @__PURE__ */ jsx(
38127
38006
  Button,
38128
38007
  {
@@ -40065,6 +39944,22 @@ var init_DataTable = __esm({
40065
39944
  DataTable.displayName = "DataTable";
40066
39945
  }
40067
39946
  });
39947
+ function toDebuggerLine(v) {
39948
+ if (v === null || typeof v !== "object" || Array.isArray(v) || v instanceof Date) return null;
39949
+ const id = v["id"];
39950
+ const content = v["content"];
39951
+ const isBug = v["isBug"];
39952
+ if (typeof id !== "string" || typeof content !== "string" || typeof isBug !== "boolean") return null;
39953
+ const isFlagged = v["isFlagged"];
39954
+ const explanation = v["explanation"];
39955
+ return {
39956
+ id,
39957
+ content,
39958
+ isBug,
39959
+ isFlagged: typeof isFlagged === "boolean" ? isFlagged : void 0,
39960
+ explanation: typeof explanation === "string" ? explanation : void 0
39961
+ };
39962
+ }
40068
39963
  function DebuggerBoard({
40069
39964
  entity,
40070
39965
  completeEvent = "PUZZLE_COMPLETE",
@@ -40077,7 +39972,10 @@ function DebuggerBoard({
40077
39972
  const { t } = useTranslate();
40078
39973
  const resolved = boardEntity(entity);
40079
39974
  const [headerError, setHeaderError] = useState(false);
40080
- const lines = Array.isArray(resolved?.lines) ? resolved.lines : [];
39975
+ const lines = Array.isArray(resolved?.lines) ? resolved.lines.flatMap((v) => {
39976
+ const l = toDebuggerLine(v);
39977
+ return l ? [l] : [];
39978
+ }) : [];
40081
39979
  const result = str(resolved?.result) || "none";
40082
39980
  const attempts = num(resolved?.attempts);
40083
39981
  const submitted = result === "win";
@@ -40682,7 +40580,7 @@ var init_DetailPanel = __esm({
40682
40580
  }
40683
40581
  });
40684
40582
  function extractTitle(children) {
40685
- if (!React85__default.isValidElement(children)) return void 0;
40583
+ if (!React87__default.isValidElement(children)) return void 0;
40686
40584
  const props = children.props;
40687
40585
  if (typeof props.title === "string") {
40688
40586
  return props.title;
@@ -40737,7 +40635,7 @@ function LinearView({
40737
40635
  /* @__PURE__ */ jsx(HStack, { className: "flex-wrap items-center", gap: "xs", children: trait.states.map((state, i) => {
40738
40636
  const isDone = i < currentIdx;
40739
40637
  const isCurrent = i === currentIdx;
40740
- return /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
40638
+ return /* @__PURE__ */ jsxs(React87__default.Fragment, { children: [
40741
40639
  i > 0 && /* @__PURE__ */ jsx(
40742
40640
  Typography,
40743
40641
  {
@@ -41559,12 +41457,12 @@ function evaluateFormExpression(expr, formCtx) {
41559
41457
  return evaluate(expr, ctx);
41560
41458
  }
41561
41459
  function isOrbitalEntitySchema(value) {
41562
- if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
41460
+ if (value === null || value === void 0 || typeof value !== "object" || Array.isArray(value)) return false;
41563
41461
  const fields = value.fields;
41564
41462
  return Array.isArray(fields);
41565
41463
  }
41566
41464
  function isPlainEntityRow(value) {
41567
- if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
41465
+ if (value === null || value === void 0 || typeof value !== "object" || Array.isArray(value)) return false;
41568
41466
  const fields = value.fields;
41569
41467
  return !Array.isArray(fields);
41570
41468
  }
@@ -41723,12 +41621,12 @@ var init_Form = __esm({
41723
41621
  const isSchemaEntity = isOrbitalEntitySchema(entity);
41724
41622
  const resolvedEntity = isSchemaEntity ? entity : void 0;
41725
41623
  const entityName = typeof entity === "string" ? entity : resolvedEntity?.name;
41726
- const normalizedInitialData = React85__default.useMemo(() => {
41624
+ const normalizedInitialData = React87__default.useMemo(() => {
41727
41625
  const entityRowAsInitial = isPlainEntityRow(entity) ? entity : void 0;
41728
41626
  const callerInitial = initialData !== null && typeof initialData === "object" && !Array.isArray(initialData) ? initialData : {};
41729
41627
  return entityRowAsInitial !== void 0 ? { ...entityRowAsInitial, ...callerInitial } : callerInitial;
41730
41628
  }, [entity, initialData]);
41731
- const entityDerivedFields = React85__default.useMemo(() => {
41629
+ const entityDerivedFields = React87__default.useMemo(() => {
41732
41630
  if (fields && fields.length > 0) return void 0;
41733
41631
  if (!resolvedEntity) return void 0;
41734
41632
  return resolvedEntity.fields.map(
@@ -41736,6 +41634,7 @@ var init_Form = __esm({
41736
41634
  name: f3.name,
41737
41635
  type: f3.type,
41738
41636
  required: f3.required,
41637
+ // EntityField.default is typed `unknown` upstream — safe cast: schema defaults are always FieldValues.
41739
41638
  defaultValue: f3.default,
41740
41639
  // EntityField is a discriminated union — `values` lives on Scalar/Enum, `relation` lives on Relation.
41741
41640
  values: "values" in f3 ? f3.values : void 0,
@@ -41748,16 +41647,16 @@ var init_Form = __esm({
41748
41647
  const conditionalFields = typeof conditionalFieldsRaw === "boolean" ? {} : conditionalFieldsRaw;
41749
41648
  const hiddenCalculations = typeof hiddenCalculationsRaw === "boolean" ? [] : hiddenCalculationsRaw;
41750
41649
  const violationTriggers = typeof violationTriggersRaw === "boolean" ? [] : violationTriggersRaw;
41751
- const [formData, setFormData] = React85__default.useState(
41650
+ const [formData, setFormData] = React87__default.useState(
41752
41651
  normalizedInitialData
41753
41652
  );
41754
- const [collapsedSections, setCollapsedSections] = React85__default.useState(
41653
+ const [collapsedSections, setCollapsedSections] = React87__default.useState(
41755
41654
  /* @__PURE__ */ new Set()
41756
41655
  );
41757
- const [submitError, setSubmitError] = React85__default.useState(null);
41758
- const formRef = React85__default.useRef(null);
41656
+ const [submitError, setSubmitError] = React87__default.useState(null);
41657
+ const formRef = React87__default.useRef(null);
41759
41658
  const formMode = props.mode;
41760
- const mountedRef = React85__default.useRef(false);
41659
+ const mountedRef = React87__default.useRef(false);
41761
41660
  if (!mountedRef.current) {
41762
41661
  mountedRef.current = true;
41763
41662
  debug("forms", "mount", {
@@ -41770,7 +41669,7 @@ var init_Form = __esm({
41770
41669
  });
41771
41670
  }
41772
41671
  const shouldShowCancel = showCancel ?? (fields && fields.length > 0);
41773
- const evalContext = React85__default.useMemo(
41672
+ const evalContext = React87__default.useMemo(
41774
41673
  () => ({
41775
41674
  formValues: formData,
41776
41675
  globalVariables: externalContext?.globalVariables ?? {},
@@ -41779,7 +41678,7 @@ var init_Form = __esm({
41779
41678
  }),
41780
41679
  [formData, externalContext]
41781
41680
  );
41782
- React85__default.useEffect(() => {
41681
+ React87__default.useEffect(() => {
41783
41682
  debug("forms", "initialData-sync", {
41784
41683
  mode: formMode,
41785
41684
  normalizedInitialData,
@@ -41790,7 +41689,7 @@ var init_Form = __esm({
41790
41689
  setFormData(normalizedInitialData);
41791
41690
  }
41792
41691
  }, [normalizedInitialData]);
41793
- const processCalculations = React85__default.useCallback(
41692
+ const processCalculations = React87__default.useCallback(
41794
41693
  (changedFieldId, newFormData) => {
41795
41694
  if (!hiddenCalculations.length) return;
41796
41695
  const context = {
@@ -41815,7 +41714,7 @@ var init_Form = __esm({
41815
41714
  },
41816
41715
  [hiddenCalculations, externalContext, eventBus]
41817
41716
  );
41818
- const checkViolations = React85__default.useCallback(
41717
+ const checkViolations = React87__default.useCallback(
41819
41718
  (changedFieldId, newFormData) => {
41820
41719
  if (!violationTriggers.length) return;
41821
41720
  const context = {
@@ -41853,7 +41752,7 @@ var init_Form = __esm({
41853
41752
  processCalculations(name, newFormData);
41854
41753
  checkViolations(name, newFormData);
41855
41754
  };
41856
- const isFieldVisible = React85__default.useCallback(
41755
+ const isFieldVisible = React87__default.useCallback(
41857
41756
  (fieldName) => {
41858
41757
  const condition = conditionalFields[fieldName];
41859
41758
  if (!condition) return true;
@@ -41861,7 +41760,7 @@ var init_Form = __esm({
41861
41760
  },
41862
41761
  [conditionalFields, evalContext]
41863
41762
  );
41864
- const isSectionVisible = React85__default.useCallback(
41763
+ const isSectionVisible = React87__default.useCallback(
41865
41764
  (section) => {
41866
41765
  if (!section.condition) return true;
41867
41766
  return Boolean(evaluateFormExpression(section.condition, evalContext));
@@ -41937,7 +41836,7 @@ var init_Form = __esm({
41937
41836
  eventBus.emit(`UI:${onCancel}`);
41938
41837
  }
41939
41838
  };
41940
- const renderField = React85__default.useCallback(
41839
+ const renderField = React87__default.useCallback(
41941
41840
  (field) => {
41942
41841
  const fieldName = field.name || field.field;
41943
41842
  if (!fieldName) return null;
@@ -41958,7 +41857,7 @@ var init_Form = __esm({
41958
41857
  [formData, isFieldVisible, relationsData, relationsLoading, isLoading]
41959
41858
  );
41960
41859
  const effectiveFields = entityDerivedFields ?? fields;
41961
- const normalizedFields = React85__default.useMemo(() => {
41860
+ const normalizedFields = React87__default.useMemo(() => {
41962
41861
  if (!effectiveFields || effectiveFields.length === 0) return [];
41963
41862
  return effectiveFields.map((field) => {
41964
41863
  if (typeof field === "string") {
@@ -41968,6 +41867,7 @@ var init_Form = __esm({
41968
41867
  name: field,
41969
41868
  type: entityField.type,
41970
41869
  required: entityField.required,
41870
+ // EntityField.default is typed `unknown` upstream — safe cast: schema defaults are always FieldValues.
41971
41871
  defaultValue: entityField.default,
41972
41872
  // EntityField is a discriminated union — `values` lives on Scalar/Enum, `relation` lives on Relation.
41973
41873
  values: "values" in entityField ? entityField.values : void 0,
@@ -41981,7 +41881,7 @@ var init_Form = __esm({
41981
41881
  return field;
41982
41882
  });
41983
41883
  }, [effectiveFields, resolvedEntity]);
41984
- const schemaFields = React85__default.useMemo(() => {
41884
+ const schemaFields = React87__default.useMemo(() => {
41985
41885
  if (normalizedFields.length === 0) return null;
41986
41886
  if (isDebugEnabled()) {
41987
41887
  debugGroup(`Form: ${entityName || "unknown"}`);
@@ -41991,7 +41891,7 @@ var init_Form = __esm({
41991
41891
  }
41992
41892
  return normalizedFields.map(renderField).filter(Boolean);
41993
41893
  }, [normalizedFields, renderField, entityName, conditionalFields]);
41994
- const sectionElements = React85__default.useMemo(() => {
41894
+ const sectionElements = React87__default.useMemo(() => {
41995
41895
  if (!sections || sections.length === 0) return null;
41996
41896
  return sections.map((section) => {
41997
41897
  if (!isSectionVisible(section)) {
@@ -43512,7 +43412,6 @@ var init_GameCanvas3D2 = __esm({
43512
43412
  className,
43513
43413
  isLoading: externalLoading,
43514
43414
  error: externalError,
43515
- entity,
43516
43415
  preloadAssets = [],
43517
43416
  tileClickEvent,
43518
43417
  unitClickEvent,
@@ -44247,6 +44146,14 @@ var init_GameBoard3D = __esm({
44247
44146
  GameBoard3D.displayName = "GameBoard3D";
44248
44147
  }
44249
44148
  });
44149
+ function asDescriptor(v) {
44150
+ if (Array.isArray(v) || React87__default.isValidElement(v)) return null;
44151
+ const o = v;
44152
+ if (typeof o.type !== "string") return null;
44153
+ const props = o.props !== void 0 && typeof o.props === "object" && !Array.isArray(o.props) && o.props !== null ? o.props : void 0;
44154
+ const _id = typeof o._id === "string" ? o._id : void 0;
44155
+ return { type: o.type, props, _id };
44156
+ }
44250
44157
  function getSlotContentRenderer2() {
44251
44158
  if (_scr) return _scr;
44252
44159
  const mod = (init_UISlotRenderer(), __toCommonJS(UISlotRenderer_exports));
@@ -44255,17 +44162,16 @@ function getSlotContentRenderer2() {
44255
44162
  }
44256
44163
  function resolveDescriptor(value, idPrefix) {
44257
44164
  if (value === null || value === void 0) return value;
44258
- if (React85__default.isValidElement(value)) return value;
44165
+ if (React87__default.isValidElement(value)) return value;
44259
44166
  if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") return value;
44260
44167
  if (Array.isArray(value)) {
44261
- return value.map((item, i) => /* @__PURE__ */ jsx(React85__default.Fragment, { children: resolveDescriptor(item, `${idPrefix}-${i}`) }, i));
44168
+ return value.map((item, i) => /* @__PURE__ */ jsx(React87__default.Fragment, { children: resolveDescriptor(item, `${idPrefix}-${i}`) }, i));
44262
44169
  }
44263
- if (typeof value === "object") {
44264
- const rec = value;
44265
- if (typeof rec.type === "string" && getComponentForPattern(rec.type) !== null) {
44266
- const { type, props: nestedProps, _id, ...flatProps } = rec;
44267
- const resolvedProps = nestedProps !== void 0 ? nestedProps : flatProps;
44268
- const content = { id: _id ?? idPrefix, pattern: type, props: resolvedProps, priority: 0 };
44170
+ if (typeof value === "object" && value !== null) {
44171
+ const desc = asDescriptor(value);
44172
+ if (desc !== null && getComponentForPattern(desc.type) !== null) {
44173
+ const resolvedProps = desc.props ?? {};
44174
+ const content = { id: desc._id ?? idPrefix, pattern: desc.type, props: resolvedProps, priority: 0 };
44269
44175
  const SCR = getSlotContentRenderer2();
44270
44176
  return /* @__PURE__ */ jsx(SCR, { content, onDismiss: () => void 0 });
44271
44177
  }
@@ -44359,16 +44265,19 @@ function getSlotContentRenderer3() {
44359
44265
  }
44360
44266
  function resolveDescriptor2(value, idPrefix) {
44361
44267
  if (value === null || value === void 0) return value;
44362
- if (React85__default.isValidElement(value)) return value;
44268
+ if (React87__default.isValidElement(value)) return value;
44363
44269
  if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") return value;
44364
44270
  if (Array.isArray(value)) {
44365
- return value.map((item, i) => /* @__PURE__ */ jsx(React85__default.Fragment, { children: resolveDescriptor2(item, `${idPrefix}-${i}`) }, i));
44271
+ return value.map((item, i) => /* @__PURE__ */ jsx(React87__default.Fragment, { children: resolveDescriptor2(item, `${idPrefix}-${i}`) }, i));
44366
44272
  }
44367
44273
  if (typeof value === "object") {
44368
44274
  const rec = value;
44369
44275
  if (typeof rec.type === "string" && getComponentForPattern(rec.type) !== null) {
44370
- const { type, props: nestedProps, _id, ...flatProps } = rec;
44371
- const resolvedProps = nestedProps !== void 0 ? nestedProps : flatProps;
44276
+ const type = rec.type;
44277
+ const _id = typeof rec._id === "string" ? rec._id : void 0;
44278
+ const nestedProps = rec.props !== void 0 && typeof rec.props === "object" && !Array.isArray(rec.props) && rec.props !== null ? rec.props : void 0;
44279
+ const { type: _t, props: _p, _id: _d, ...flatRest } = rec;
44280
+ const resolvedProps = nestedProps !== void 0 ? nestedProps : flatRest;
44372
44281
  const content = { id: _id ?? idPrefix, pattern: type, props: resolvedProps, priority: 0 };
44373
44282
  const SCR = getSlotContentRenderer3();
44374
44283
  return /* @__PURE__ */ jsx(SCR, { content, onDismiss: () => void 0 });
@@ -45072,7 +44981,7 @@ var init_List = __esm({
45072
44981
  if (entity && typeof entity === "object" && "id" in entity) return [entity];
45073
44982
  return [];
45074
44983
  }, [entity]);
45075
- const getItemActions = React85__default.useCallback(
44984
+ const getItemActions = React87__default.useCallback(
45076
44985
  (item) => {
45077
44986
  if (!itemActions) return [];
45078
44987
  if (typeof itemActions === "function") {
@@ -45129,15 +45038,14 @@ var init_List = __esm({
45129
45038
  };
45130
45039
  if (effectiveFieldNames && effectiveFieldNames.length > 0) {
45131
45040
  const firstField = effectiveFieldNames[0];
45132
- const itemRecord = item;
45133
- if (!normalizedItem.title && getNestedValue(itemRecord, firstField)) {
45041
+ if (!normalizedItem.title && getNestedValue(item, firstField)) {
45134
45042
  normalizedItem.title = String(
45135
- getNestedValue(itemRecord, firstField)
45043
+ getNestedValue(item, firstField)
45136
45044
  );
45137
45045
  }
45138
45046
  normalizedItem._fields = effectiveFieldNames.reduce(
45139
45047
  (acc, field) => {
45140
- const value = getNestedValue(itemRecord, field);
45048
+ const value = getNestedValue(item, field);
45141
45049
  if (value !== void 0 && value !== null) {
45142
45050
  acc[field] = value;
45143
45051
  }
@@ -45590,16 +45498,18 @@ var init_MediaGallery = __esm({
45590
45498
  [selectable, selectedItems, selectionEvent, eventBus]
45591
45499
  );
45592
45500
  const entityData = Array.isArray(entity) ? entity : [];
45593
- const items = React85__default.useMemo(() => {
45501
+ const items = React87__default.useMemo(() => {
45594
45502
  if (propItems) return propItems;
45595
45503
  if (entityData.length === 0) return [];
45596
- return entityData.map((record, idx) => ({
45597
- id: String(record.id ?? idx),
45598
- src: String(record.src ?? record.url ?? record.image ?? ""),
45599
- alt: record.alt ? String(record.alt) : void 0,
45600
- thumbnail: record.thumbnail ? String(record.thumbnail) : void 0,
45601
- caption: record.caption ? String(record.caption) : record.title ? String(record.title) : void 0
45602
- }));
45504
+ return entityData.map((record, idx) => {
45505
+ return {
45506
+ id: String(record.id ?? idx),
45507
+ src: String(record.src ?? ("url" in record ? record.url : "") ?? ("image" in record ? record.image : "") ?? ""),
45508
+ alt: record.alt ? String(record.alt) : void 0,
45509
+ thumbnail: record.thumbnail ? String(record.thumbnail) : void 0,
45510
+ caption: record.caption ? String(record.caption) : "title" in record ? String(record.title) : void 0
45511
+ };
45512
+ });
45603
45513
  }, [propItems, entityData]);
45604
45514
  if (isLoading) {
45605
45515
  return /* @__PURE__ */ jsx(LoadingState, { message: t("common.loading"), className });
@@ -45793,7 +45703,7 @@ var init_MinigolfBoard = __esm({
45793
45703
  }
45794
45704
  });
45795
45705
  function extractTitle2(children) {
45796
- if (!React85__default.isValidElement(children)) return void 0;
45706
+ if (!React87__default.isValidElement(children)) return void 0;
45797
45707
  const props = children.props;
45798
45708
  if (typeof props.title === "string") {
45799
45709
  return props.title;
@@ -45859,8 +45769,16 @@ function NegotiatorBoard({
45859
45769
  const lastPlayerAction = str(resolved?.lastPlayerAction);
45860
45770
  const lastOpponentAction = str(resolved?.lastOpponentAction);
45861
45771
  const lastPayoff = num(resolved?.lastPayoff);
45862
- const actions = Array.isArray(resolved?.actions) ? resolved.actions : [];
45863
- const payoffMatrix = Array.isArray(resolved?.payoffMatrix) ? resolved.payoffMatrix : [];
45772
+ const actions = Array.isArray(resolved?.actions) ? resolved.actions.flatMap((item) => {
45773
+ if (item !== null && typeof item === "object" && !Array.isArray(item) && !(item instanceof Date) && typeof item.id === "string" && typeof item.label === "string")
45774
+ return [{ id: item.id, label: item.label, description: typeof item.description === "string" ? item.description : void 0 }];
45775
+ return [];
45776
+ }) : [];
45777
+ const payoffMatrix = Array.isArray(resolved?.payoffMatrix) ? resolved.payoffMatrix.flatMap((item) => {
45778
+ if (item !== null && typeof item === "object" && !Array.isArray(item) && !(item instanceof Date) && typeof item.playerAction === "string" && typeof item.opponentAction === "string")
45779
+ return [{ playerAction: item.playerAction, opponentAction: item.opponentAction, playerPayoff: typeof item.playerPayoff === "number" ? item.playerPayoff : 0, opponentPayoff: typeof item.opponentPayoff === "number" ? item.opponentPayoff : 0 }];
45780
+ return [];
45781
+ }) : [];
45864
45782
  const prevRoundRef = useRef(currentRound);
45865
45783
  useEffect(() => {
45866
45784
  if (currentRound > prevRoundRef.current && lastPlayerAction) {
@@ -46986,7 +46904,7 @@ var init_debugRegistry = __esm({
46986
46904
  }
46987
46905
  });
46988
46906
  function useDebugData() {
46989
- const [data, setData] = React85.useState(() => ({
46907
+ const [data, setData] = React87.useState(() => ({
46990
46908
  traits: [],
46991
46909
  ticks: [],
46992
46910
  guards: [],
@@ -47000,7 +46918,7 @@ function useDebugData() {
47000
46918
  },
47001
46919
  lastUpdate: Date.now()
47002
46920
  }));
47003
- React85.useEffect(() => {
46921
+ React87.useEffect(() => {
47004
46922
  const updateData = () => {
47005
46923
  setData({
47006
46924
  traits: getAllTraits(),
@@ -47109,12 +47027,12 @@ function layoutGraph(states, transitions, initialState, width, height) {
47109
47027
  return positions;
47110
47028
  }
47111
47029
  function WalkMinimap() {
47112
- const [walkStep, setWalkStep] = React85.useState(null);
47113
- const [traits2, setTraits] = React85.useState([]);
47114
- const [coveredEdges, setCoveredEdges] = React85.useState([]);
47115
- const [completedTraits, setCompletedTraits] = React85.useState(/* @__PURE__ */ new Set());
47116
- const prevTraitRef = React85.useRef(null);
47117
- React85.useEffect(() => {
47030
+ const [walkStep, setWalkStep] = React87.useState(null);
47031
+ const [traits2, setTraits] = React87.useState([]);
47032
+ const [coveredEdges, setCoveredEdges] = React87.useState([]);
47033
+ const [completedTraits, setCompletedTraits] = React87.useState(/* @__PURE__ */ new Set());
47034
+ const prevTraitRef = React87.useRef(null);
47035
+ React87.useEffect(() => {
47118
47036
  const interval = setInterval(() => {
47119
47037
  const w = window;
47120
47038
  const step = w.__orbitalWalkStep;
@@ -47550,15 +47468,15 @@ var init_EntitiesTab = __esm({
47550
47468
  });
47551
47469
  function EventFlowTab({ events: events2 }) {
47552
47470
  const { t } = useTranslate();
47553
- const [filter, setFilter] = React85.useState("all");
47554
- const containerRef = React85.useRef(null);
47555
- const [autoScroll, setAutoScroll] = React85.useState(true);
47556
- React85.useEffect(() => {
47471
+ const [filter, setFilter] = React87.useState("all");
47472
+ const containerRef = React87.useRef(null);
47473
+ const [autoScroll, setAutoScroll] = React87.useState(true);
47474
+ React87.useEffect(() => {
47557
47475
  if (autoScroll && containerRef.current) {
47558
47476
  containerRef.current.scrollTop = containerRef.current.scrollHeight;
47559
47477
  }
47560
47478
  }, [events2.length, autoScroll]);
47561
- const filteredEvents = React85.useMemo(() => {
47479
+ const filteredEvents = React87.useMemo(() => {
47562
47480
  if (filter === "all") return events2;
47563
47481
  return events2.filter((e) => e.type === filter);
47564
47482
  }, [events2, filter]);
@@ -47674,7 +47592,7 @@ var init_EventFlowTab = __esm({
47674
47592
  });
47675
47593
  function GuardsPanel({ guards }) {
47676
47594
  const { t } = useTranslate();
47677
- const [filter, setFilter] = React85.useState("all");
47595
+ const [filter, setFilter] = React87.useState("all");
47678
47596
  if (guards.length === 0) {
47679
47597
  return /* @__PURE__ */ jsx(
47680
47598
  EmptyState,
@@ -47687,7 +47605,7 @@ function GuardsPanel({ guards }) {
47687
47605
  }
47688
47606
  const passedCount = guards.filter((g) => g.result).length;
47689
47607
  const failedCount = guards.length - passedCount;
47690
- const filteredGuards = React85.useMemo(() => {
47608
+ const filteredGuards = React87.useMemo(() => {
47691
47609
  if (filter === "all") return guards;
47692
47610
  if (filter === "passed") return guards.filter((g) => g.result);
47693
47611
  return guards.filter((g) => !g.result);
@@ -47850,10 +47768,10 @@ function EffectBadge({ effect }) {
47850
47768
  }
47851
47769
  function TransitionTimeline({ transitions }) {
47852
47770
  const { t } = useTranslate();
47853
- const containerRef = React85.useRef(null);
47854
- const [autoScroll, setAutoScroll] = React85.useState(true);
47855
- const [expandedId, setExpandedId] = React85.useState(null);
47856
- React85.useEffect(() => {
47771
+ const containerRef = React87.useRef(null);
47772
+ const [autoScroll, setAutoScroll] = React87.useState(true);
47773
+ const [expandedId, setExpandedId] = React87.useState(null);
47774
+ React87.useEffect(() => {
47857
47775
  if (autoScroll && containerRef.current) {
47858
47776
  containerRef.current.scrollTop = containerRef.current.scrollHeight;
47859
47777
  }
@@ -48059,18 +47977,18 @@ var init_ServerBridgeTab = __esm({
48059
47977
  });
48060
47978
  function extractPayloadFields(schema, eventName) {
48061
47979
  if (!schema) return [];
48062
- const orbitals = schema.orbitals;
48063
- if (!orbitals) return [];
48064
- for (const orbital of orbitals) {
48065
- const traits2 = orbital.traits ?? [];
48066
- for (const trait of traits2) {
48067
- const sm = trait.stateMachine;
47980
+ for (const orbital of schema.orbitals) {
47981
+ const traitRefs = orbital.traits ?? [];
47982
+ for (const traitRef of traitRefs) {
47983
+ if (!isInlineTrait(traitRef)) continue;
47984
+ const inlineTrait = traitRef;
47985
+ const sm = inlineTrait.stateMachine;
48068
47986
  if (!sm) continue;
48069
47987
  const events2 = sm.events ?? [];
48070
47988
  for (const evt of events2) {
48071
47989
  if (evt.name !== eventName) continue;
48072
- const payload = evt.payload ?? [];
48073
- return payload.map((f3) => ({
47990
+ const payloadFields = evt.payloadSchema ?? [];
47991
+ return payloadFields.map((f3) => ({
48074
47992
  name: f3.name,
48075
47993
  type: f3.type ?? "string"
48076
47994
  }));
@@ -48133,9 +48051,9 @@ function getAllEvents(traits2) {
48133
48051
  function EventDispatcherTab({ traits: traits2, schema }) {
48134
48052
  const eventBus = useEventBus();
48135
48053
  const { t } = useTranslate();
48136
- const [log14, setLog] = React85.useState([]);
48137
- const prevStatesRef = React85.useRef(/* @__PURE__ */ new Map());
48138
- React85.useEffect(() => {
48054
+ const [log14, setLog] = React87.useState([]);
48055
+ const prevStatesRef = React87.useRef(/* @__PURE__ */ new Map());
48056
+ React87.useEffect(() => {
48139
48057
  for (const trait of traits2) {
48140
48058
  const prev = prevStatesRef.current.get(trait.id);
48141
48059
  if (prev && prev !== trait.currentState) {
@@ -48304,10 +48222,10 @@ function VerifyModePanel({
48304
48222
  localCount
48305
48223
  }) {
48306
48224
  const { t } = useTranslate();
48307
- const [expanded, setExpanded] = React85.useState(true);
48308
- const scrollRef = React85.useRef(null);
48309
- const prevCountRef = React85.useRef(0);
48310
- React85.useEffect(() => {
48225
+ const [expanded, setExpanded] = React87.useState(true);
48226
+ const scrollRef = React87.useRef(null);
48227
+ const prevCountRef = React87.useRef(0);
48228
+ React87.useEffect(() => {
48311
48229
  if (expanded && transitions.length > prevCountRef.current && scrollRef.current) {
48312
48230
  scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
48313
48231
  }
@@ -48364,10 +48282,10 @@ function RuntimeDebugger({
48364
48282
  schema
48365
48283
  }) {
48366
48284
  const { t } = useTranslate();
48367
- const [isCollapsed, setIsCollapsed] = React85.useState(mode === "verify" ? true : defaultCollapsed);
48368
- const [isVisible, setIsVisible] = React85.useState(mode === "inline" || mode === "verify" || isDebugEnabled2());
48285
+ const [isCollapsed, setIsCollapsed] = React87.useState(mode === "verify" ? true : defaultCollapsed);
48286
+ const [isVisible, setIsVisible] = React87.useState(mode === "inline" || mode === "verify" || isDebugEnabled2());
48369
48287
  const debugData = useDebugData();
48370
- React85.useEffect(() => {
48288
+ React87.useEffect(() => {
48371
48289
  if (mode === "inline") return;
48372
48290
  return onDebugToggle((enabled) => {
48373
48291
  setIsVisible(enabled);
@@ -48376,7 +48294,7 @@ function RuntimeDebugger({
48376
48294
  }
48377
48295
  });
48378
48296
  }, [mode]);
48379
- React85.useEffect(() => {
48297
+ React87.useEffect(() => {
48380
48298
  if (mode === "inline") return;
48381
48299
  const handleKeyDown = (e) => {
48382
48300
  if (e.key === "`" && isVisible) {
@@ -48936,7 +48854,7 @@ function SequenceBar({
48936
48854
  onSlotRemove(index);
48937
48855
  }, [onSlotRemove, playing]);
48938
48856
  const paddedSlots = Array.from({ length: maxSlots }, (_, i) => slots[i]);
48939
- return /* @__PURE__ */ jsx(HStack, { className: cn("items-center", className), gap: "sm", children: paddedSlots.map((slot, i) => /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
48857
+ return /* @__PURE__ */ jsx(HStack, { className: cn("items-center", className), gap: "sm", children: paddedSlots.map((slot, i) => /* @__PURE__ */ jsxs(React87__default.Fragment, { children: [
48940
48858
  i > 0 && /* @__PURE__ */ jsx(
48941
48859
  Typography,
48942
48860
  {
@@ -49551,6 +49469,29 @@ var init_SimulationCanvas = __esm({
49551
49469
  SimulationCanvas.displayName = "SimulationCanvas";
49552
49470
  }
49553
49471
  });
49472
+ function readSimulatorParameters(v) {
49473
+ if (!Array.isArray(v)) return [];
49474
+ const result = [];
49475
+ for (const item of v) {
49476
+ if (typeof item === "object" && item !== null && !Array.isArray(item) && !(item instanceof Date)) {
49477
+ const param = item;
49478
+ if ("id" in item && "label" in item && "unit" in item && "min" in item && "max" in item && "step" in item) {
49479
+ result.push({
49480
+ id: str(param.id),
49481
+ label: str(param.label),
49482
+ unit: str(param.unit),
49483
+ min: num(param.min),
49484
+ max: num(param.max),
49485
+ step: num(param.step),
49486
+ initial: num(param.initial),
49487
+ correct: num(param.correct),
49488
+ tolerance: num(param.tolerance)
49489
+ });
49490
+ }
49491
+ }
49492
+ }
49493
+ return result;
49494
+ }
49554
49495
  function SimulatorBoard({
49555
49496
  entity,
49556
49497
  completeEvent = "PUZZLE_COMPLETE",
@@ -49563,7 +49504,7 @@ function SimulatorBoard({
49563
49504
  const { emit } = useEventBus();
49564
49505
  const { t } = useTranslate();
49565
49506
  const resolved = boardEntity(entity);
49566
- const parameters = Array.isArray(resolved?.parameters) ? resolved.parameters : [];
49507
+ const parameters = readSimulatorParameters(resolved?.parameters);
49567
49508
  const [headerError, setHeaderError] = useState(false);
49568
49509
  if (!resolved) return null;
49569
49510
  const paramA = num(resolved.paramA);
@@ -49590,8 +49531,14 @@ function SimulatorBoard({
49590
49531
  const handlePlayAgain = () => {
49591
49532
  if (playAgainEvent) emit(`UI:${playAgainEvent}`, {});
49592
49533
  };
49593
- const theme = resolved.theme ?? void 0;
49594
- const themeBackground = theme?.background;
49534
+ const themeBackground = (() => {
49535
+ const t2 = resolved.theme;
49536
+ if (typeof t2 === "object" && t2 !== null && !Array.isArray(t2) && !(t2 instanceof Date)) {
49537
+ const bg = t2.background;
49538
+ return str(bg);
49539
+ }
49540
+ return "";
49541
+ })();
49595
49542
  const headerImage = str(resolved.headerImage);
49596
49543
  const hint = str(resolved.hint);
49597
49544
  const showHint = isComplete && !isWin && attempts >= 2 && Boolean(hint);
@@ -49996,7 +49943,7 @@ var init_StatCard = __esm({
49996
49943
  const labelToUse = propLabel ?? propTitle;
49997
49944
  const eventBus = useEventBus();
49998
49945
  const { t } = useTranslate();
49999
- const handleActionClick = React85__default.useCallback(() => {
49946
+ const handleActionClick = React87__default.useCallback(() => {
50000
49947
  if (action?.event) {
50001
49948
  eventBus.emit(`UI:${action.event}`, {});
50002
49949
  }
@@ -50007,7 +49954,7 @@ var init_StatCard = __esm({
50007
49954
  const data = Array.isArray(entity) ? entity : entity ? [entity] : [];
50008
49955
  const isLoading = externalLoading ?? false;
50009
49956
  const error = externalError;
50010
- const computeMetricValue = React85__default.useCallback(
49957
+ const computeMetricValue = React87__default.useCallback(
50011
49958
  (metric, items) => {
50012
49959
  if (metric.value !== void 0) {
50013
49960
  return metric.value;
@@ -50046,7 +49993,7 @@ var init_StatCard = __esm({
50046
49993
  },
50047
49994
  []
50048
49995
  );
50049
- const schemaStats = React85__default.useMemo(() => {
49996
+ const schemaStats = React87__default.useMemo(() => {
50050
49997
  if (!metrics || metrics.length === 0) return null;
50051
49998
  return metrics.map((metric) => ({
50052
49999
  label: metric.label,
@@ -50054,7 +50001,7 @@ var init_StatCard = __esm({
50054
50001
  format: metric.format
50055
50002
  }));
50056
50003
  }, [metrics, data, computeMetricValue]);
50057
- const calculatedTrend = React85__default.useMemo(() => {
50004
+ const calculatedTrend = React87__default.useMemo(() => {
50058
50005
  if (manualTrend !== void 0) return manualTrend;
50059
50006
  if (previousValue === void 0 || currentValue === void 0)
50060
50007
  return void 0;
@@ -50397,8 +50344,25 @@ function StateArchitectBoard({
50397
50344
  const initialState = str(resolved?.initialState);
50398
50345
  const entityName = str(resolved?.entityName);
50399
50346
  const availableEvents = Array.isArray(resolved?.availableEvents) ? resolved.availableEvents : [];
50400
- const testCases = Array.isArray(resolved?.testCases) ? resolved.testCases : [];
50401
- const entityTransitions = Array.isArray(resolved?.transitions) ? resolved.transitions : [];
50347
+ const testCases = (Array.isArray(resolved?.testCases) ? resolved.testCases : []).map((item) => {
50348
+ const o = typeof item === "object" && item !== null && !Array.isArray(item) ? item : {};
50349
+ const eventsField = o["events"];
50350
+ return {
50351
+ events: Array.isArray(eventsField) ? eventsField : [],
50352
+ expectedState: str(o["expectedState"]),
50353
+ label: str(o["label"])
50354
+ };
50355
+ });
50356
+ const entityTransitions = (Array.isArray(resolved?.transitions) ? resolved.transitions : []).map((item) => {
50357
+ const o = typeof item === "object" && item !== null && !Array.isArray(item) ? item : {};
50358
+ return {
50359
+ id: str(o["id"]),
50360
+ from: str(o["from"]),
50361
+ to: str(o["to"]),
50362
+ event: str(o["event"]),
50363
+ ...o["guardHint"] ? { guardHint: str(o["guardHint"]) } : {}
50364
+ };
50365
+ });
50402
50366
  const entityVariables = rows(resolved?.variables);
50403
50367
  const transitions = entityTransitions;
50404
50368
  const attempts = typeof resolved?.attempts === "number" ? resolved.attempts : 0;
@@ -51243,8 +51207,8 @@ var init_SubagentTracePanel = __esm({
51243
51207
  ] });
51244
51208
  };
51245
51209
  InlineActivityStream = ({ activities, autoScroll = true, className }) => {
51246
- const endRef = React85__default.useRef(null);
51247
- React85__default.useEffect(() => {
51210
+ const endRef = React87__default.useRef(null);
51211
+ React87__default.useEffect(() => {
51248
51212
  if (!autoScroll) return;
51249
51213
  endRef.current?.scrollIntoView({ behavior: "smooth", block: "end" });
51250
51214
  }, [activities.length, autoScroll]);
@@ -51338,7 +51302,7 @@ var init_SubagentTracePanel = __esm({
51338
51302
  };
51339
51303
  SubagentRichCard = ({ subagent }) => {
51340
51304
  const { t } = useTranslate();
51341
- const activities = React85__default.useMemo(
51305
+ const activities = React87__default.useMemo(
51342
51306
  () => subagentMessagesToActivities(subagent.messages),
51343
51307
  [subagent.messages]
51344
51308
  );
@@ -51415,8 +51379,8 @@ var init_SubagentTracePanel = __esm({
51415
51379
  ] });
51416
51380
  };
51417
51381
  CoordinatorConversation = ({ messages, autoScroll = true, className }) => {
51418
- const endRef = React85__default.useRef(null);
51419
- React85__default.useEffect(() => {
51382
+ const endRef = React87__default.useRef(null);
51383
+ React87__default.useEffect(() => {
51420
51384
  if (!autoScroll) return;
51421
51385
  endRef.current?.scrollIntoView({ behavior: "smooth", block: "end" });
51422
51386
  }, [messages.length, autoScroll]);
@@ -51887,17 +51851,12 @@ var init_Timeline = __esm({
51887
51851
  look = "vertical-spacious"
51888
51852
  }) => {
51889
51853
  const { t } = useTranslate();
51890
- const entityData = Array.isArray(entity) ? entity : [];
51891
- const items = React85__default.useMemo(() => {
51854
+ const entityData = entity ?? [];
51855
+ const items = React87__default.useMemo(() => {
51892
51856
  if (propItems) return propItems;
51893
51857
  if (entityData.length === 0) return [];
51894
51858
  return entityData.map((record, idx) => {
51895
- const resolveField = (f3) => {
51896
- if (typeof f3 === "string") return f3;
51897
- if (f3 && typeof f3 === "object" && "name" in f3) return String(f3.name);
51898
- return "";
51899
- };
51900
- const resolvedFields = fields?.map(resolveField) ?? [];
51859
+ const resolvedFields = fields ?? [];
51901
51860
  const titleField = resolvedFields[0] || "title";
51902
51861
  const descField = resolvedFields[1] || "description";
51903
51862
  const dateField = resolvedFields.find(
@@ -51995,7 +51954,7 @@ var init_Timeline = __esm({
51995
51954
  }
51996
51955
  });
51997
51956
  function extractToastProps(children) {
51998
- if (!React85__default.isValidElement(children)) {
51957
+ if (!React87__default.isValidElement(children)) {
51999
51958
  if (typeof children === "string") {
52000
51959
  return { message: children };
52001
51960
  }
@@ -52033,7 +51992,7 @@ var init_ToastSlot = __esm({
52033
51992
  eventBus.emit("UI:CLOSE");
52034
51993
  };
52035
51994
  if (!isVisible) return null;
52036
- const isCustomContent = React85__default.isValidElement(children) && !message;
51995
+ const isCustomContent = React87__default.isValidElement(children) && !message;
52037
51996
  return /* @__PURE__ */ jsx(Box, { className: "fixed bottom-4 right-4 z-50", children: isCustomContent ? children : /* @__PURE__ */ jsx(
52038
51997
  Toast,
52039
51998
  {
@@ -53305,7 +53264,7 @@ function WorldMapBoard({
53305
53264
  const resolved = boardEntity(entity);
53306
53265
  const entityUnits = rows(resolved?.units);
53307
53266
  const entityTiles = rows(resolved?.tiles);
53308
- const features = propFeatures ?? (Array.isArray(resolved?.features) ? resolved.features : []);
53267
+ const features = propFeatures ?? rows(resolved?.features);
53309
53268
  const selectedHeroId = resolved?.selectedHeroId ?? null;
53310
53269
  const assetManifest = propAssetManifest ?? resolved?.assetManifest;
53311
53270
  const backgroundImage = resolved?.backgroundImage;
@@ -53438,7 +53397,8 @@ function WorldMapBoard({
53438
53397
  if (heroMoveEvent) {
53439
53398
  eventBus.emit(`UI:${heroMoveEvent}`, { heroId, toX: x, toY: y });
53440
53399
  }
53441
- const feature = tile ? str(tile.feature) : "";
53400
+ const tileWithFeature = tile;
53401
+ const feature = tileWithFeature ? str(tileWithFeature.feature) : "";
53442
53402
  if (feature && feature !== "none") {
53443
53403
  const tileRow = tile;
53444
53404
  onFeatureEnter?.(heroId, tileRow);
@@ -53649,7 +53609,7 @@ var init_WorldMapTemplate = __esm({
53649
53609
  }
53650
53610
  });
53651
53611
  function lazyThree(name, loader) {
53652
- const Lazy = React85__default.lazy(
53612
+ const Lazy = React87__default.lazy(
53653
53613
  () => loader().then((m) => {
53654
53614
  const Resolved = m[name];
53655
53615
  if (!Resolved) {
@@ -53661,13 +53621,13 @@ function lazyThree(name, loader) {
53661
53621
  })
53662
53622
  );
53663
53623
  function ThreeWrapper(props) {
53664
- return React85__default.createElement(
53624
+ return React87__default.createElement(
53665
53625
  ThreeBoundary,
53666
53626
  { name },
53667
- React85__default.createElement(
53668
- React85__default.Suspense,
53627
+ React87__default.createElement(
53628
+ React87__default.Suspense,
53669
53629
  { fallback: null },
53670
- React85__default.createElement(Lazy, props)
53630
+ React87__default.createElement(Lazy, props)
53671
53631
  )
53672
53632
  );
53673
53633
  }
@@ -53990,7 +53950,7 @@ var init_component_registry_generated = __esm({
53990
53950
  init_WorldMapBoard();
53991
53951
  init_WorldMapTemplate();
53992
53952
  init_XPBar();
53993
- ThreeBoundary = class extends React85__default.Component {
53953
+ ThreeBoundary = class extends React87__default.Component {
53994
53954
  constructor() {
53995
53955
  super(...arguments);
53996
53956
  __publicField(this, "state", { failed: false });
@@ -54000,7 +53960,7 @@ var init_component_registry_generated = __esm({
54000
53960
  }
54001
53961
  render() {
54002
53962
  if (this.state.failed) {
54003
- return React85__default.createElement(
53963
+ return React87__default.createElement(
54004
53964
  "div",
54005
53965
  {
54006
53966
  "data-testid": "three-unavailable",
@@ -54366,7 +54326,7 @@ function SuspenseConfigProvider({
54366
54326
  config,
54367
54327
  children
54368
54328
  }) {
54369
- return React85__default.createElement(
54329
+ return React87__default.createElement(
54370
54330
  SuspenseConfigContext.Provider,
54371
54331
  { value: config },
54372
54332
  children
@@ -54382,9 +54342,7 @@ function getComponentForPattern3(patternType) {
54382
54342
  if (!mapping) {
54383
54343
  return null;
54384
54344
  }
54385
- const name = typeof mapping === "string" ? mapping : mapping.component;
54386
- if (!name) return null;
54387
- return COMPONENT_REGISTRY[name] ?? null;
54345
+ return COMPONENT_REGISTRY[mapping] ?? null;
54388
54346
  }
54389
54347
  function enrichFormFields(fields, entityDef) {
54390
54348
  const fieldMap = new Map(entityDef.fields.map((f3) => [f3.name, f3]));
@@ -54396,7 +54354,7 @@ function enrichFormFields(fields, entityDef) {
54396
54354
  name: field,
54397
54355
  label: field.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/\b\w/g, (c) => c.toUpperCase()),
54398
54356
  type: entityField.type,
54399
- required: entityField.required
54357
+ required: entityField.required ?? false
54400
54358
  };
54401
54359
  if (entityField.values && entityField.values.length > 0) {
54402
54360
  enriched.values = entityField.values;
@@ -54404,15 +54362,15 @@ function enrichFormFields(fields, entityDef) {
54404
54362
  enriched.values = entityField.enumValues;
54405
54363
  }
54406
54364
  if (entityField.relation) {
54407
- enriched.relation = entityField.relation;
54365
+ enriched.relation = entityField.relation.entity;
54408
54366
  }
54409
54367
  return enriched;
54410
54368
  }
54411
54369
  return { name: field, label: field.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/\b\w/g, (c) => c.toUpperCase()) };
54412
54370
  }
54413
- if (field && typeof field === "object" && !Array.isArray(field)) {
54371
+ if (field && typeof field === "object" && !Array.isArray(field) && !React87__default.isValidElement(field) && !(field instanceof Date)) {
54414
54372
  const obj = field;
54415
- const fieldName = obj.name ?? obj.field;
54373
+ const fieldName = typeof obj.name === "string" ? obj.name : typeof obj.field === "string" ? obj.field : void 0;
54416
54374
  if (!fieldName) return field;
54417
54375
  if (obj.type || obj.inputType) return field;
54418
54376
  const entityField = fieldMap.get(fieldName);
@@ -54429,7 +54387,7 @@ function enrichFormFields(fields, entityDef) {
54429
54387
  }
54430
54388
  }
54431
54389
  if (!obj.relation && entityField.relation) {
54432
- enriched.relation = entityField.relation;
54390
+ enriched.relation = entityField.relation.entity;
54433
54391
  }
54434
54392
  return enriched;
54435
54393
  }
@@ -54856,7 +54814,7 @@ function renderPatternChildren(children, onDismiss, parentId = "root", parentPat
54856
54814
  const key = `${parentId}-${index}-trait:${traitName}`;
54857
54815
  return /* @__PURE__ */ jsx(TraitFrame, { traitName }, key);
54858
54816
  }
54859
- return /* @__PURE__ */ jsx(React85__default.Fragment, { children: child }, `${parentId}-${index}`);
54817
+ return /* @__PURE__ */ jsx(React87__default.Fragment, { children: child }, `${parentId}-${index}`);
54860
54818
  }
54861
54819
  if (!child || typeof child !== "object") return null;
54862
54820
  const childId = `${parentId}-${index}`;
@@ -54896,14 +54854,14 @@ function isPatternConfig(value) {
54896
54854
  if (value === null || value === void 0) return false;
54897
54855
  if (typeof value !== "object") return false;
54898
54856
  if (Array.isArray(value)) return false;
54899
- if (React85__default.isValidElement(value)) return false;
54857
+ if (React87__default.isValidElement(value)) return false;
54900
54858
  if (value instanceof Date) return false;
54901
54859
  if (typeof value === "function") return false;
54902
54860
  const record = value;
54903
54861
  return "type" in record && typeof record.type === "string" && getComponentForPattern(record.type) !== null;
54904
54862
  }
54905
54863
  function isPlainConfigObject(value) {
54906
- if (React85__default.isValidElement(value)) return false;
54864
+ if (React87__default.isValidElement(value)) return false;
54907
54865
  if (value instanceof Date) return false;
54908
54866
  const proto = Object.getPrototypeOf(value);
54909
54867
  return proto === Object.prototype || proto === null;
@@ -55029,7 +54987,7 @@ function SlotContentRenderer({
55029
54987
  for (const slotKey of CONTENT_NODE_SLOTS) {
55030
54988
  const slotVal = restProps[slotKey];
55031
54989
  if (slotVal === void 0 || slotVal === null) continue;
55032
- if (React85__default.isValidElement(slotVal) || typeof slotVal === "string" || typeof slotVal === "number" || typeof slotVal === "boolean") continue;
54990
+ if (React87__default.isValidElement(slotVal) || typeof slotVal === "string" || typeof slotVal === "number" || typeof slotVal === "boolean") continue;
55033
54991
  if (Array.isArray(slotVal) || typeof slotVal === "object" && "type" in slotVal) {
55034
54992
  nodeSlotOverrides[slotKey] = renderPatternChildren(
55035
54993
  slotVal,
@@ -55074,19 +55032,18 @@ function SlotContentRenderer({
55074
55032
  for (const [k, v] of Object.entries(nodeSlotOverrides)) {
55075
55033
  finalProps[k] = v;
55076
55034
  }
55077
- const resolvedItems = Array.isArray(
55078
- finalProps.entity
55079
- ) ? finalProps.entity : null;
55035
+ const entityVal = finalProps.entity;
55036
+ const resolvedItems = Array.isArray(entityVal) && entityVal[0] !== "fn" ? entityVal : null;
55080
55037
  if (resolvedItems && resolvedItems.length > 0 && !finalProps.fields && !finalProps.columns) {
55081
55038
  const sample = resolvedItems[0];
55082
- if (sample && typeof sample === "object") {
55039
+ if (sample && typeof sample === "object" && !Array.isArray(sample) && !React87__default.isValidElement(sample) && !(sample instanceof Date)) {
55083
55040
  const keys = Object.keys(sample).filter((k) => k !== "id" && k !== "_id");
55084
55041
  finalProps.fields = keys.map((k, i) => ({ name: k, variant: i === 0 ? "h4" : "body" }));
55085
55042
  }
55086
55043
  }
55087
55044
  const isFormPattern = FORM_PATTERNS.has(content.pattern) || content.pattern.includes("form");
55088
- if (isFormPattern && entityDef && Array.isArray(finalProps.fields)) {
55089
- finalProps.fields = enrichFormFields(finalProps.fields, entityDef);
55045
+ if (isFormPattern && entityDef && Array.isArray(finalProps.fields) && finalProps.fields[0] !== "fn") {
55046
+ finalProps.fields = enrichFormFields([...finalProps.fields], entityDef);
55090
55047
  }
55091
55048
  const acceptsChildren = PATTERNS_WITH_CHILDREN.has(content.pattern);
55092
55049
  return /* @__PURE__ */ jsx(
@@ -55367,7 +55324,7 @@ function resolveLambdaBindings(body, params, item, index) {
55367
55324
  if (Array.isArray(body)) {
55368
55325
  return body.map((b) => recur(b));
55369
55326
  }
55370
- if (body !== null && typeof body === "object" && !React85__default.isValidElement(body) && !(body instanceof Date) && typeof body !== "function") {
55327
+ if (body !== null && typeof body === "object" && !React87__default.isValidElement(body) && !(body instanceof Date) && typeof body !== "function") {
55371
55328
  const out = {};
55372
55329
  for (const [k, v] of Object.entries(body)) {
55373
55330
  out[k] = recur(v);
@@ -55386,7 +55343,7 @@ function getSlotContentRenderer4() {
55386
55343
  function makeLambdaFn(params, lambdaBody, callerKey) {
55387
55344
  return (item, index) => {
55388
55345
  const resolvedBody = resolveLambdaBindings(lambdaBody, params, item, index);
55389
- if (resolvedBody === null || typeof resolvedBody !== "object" || Array.isArray(resolvedBody) || typeof resolvedBody === "function" || React85__default.isValidElement(resolvedBody) || resolvedBody instanceof Date) {
55346
+ if (resolvedBody === null || typeof resolvedBody !== "object" || Array.isArray(resolvedBody) || typeof resolvedBody === "function" || React87__default.isValidElement(resolvedBody) || resolvedBody instanceof Date) {
55390
55347
  return null;
55391
55348
  }
55392
55349
  const record = resolvedBody;
@@ -55405,7 +55362,7 @@ function makeLambdaFn(params, lambdaBody, callerKey) {
55405
55362
  props: childProps,
55406
55363
  priority: 0
55407
55364
  };
55408
- return React85__default.createElement(SlotContentRenderer2, { content: childContent });
55365
+ return React87__default.createElement(SlotContentRenderer2, { content: childContent });
55409
55366
  };
55410
55367
  }
55411
55368
  function convertNode(node, callerKey) {
@@ -55424,7 +55381,7 @@ function convertNode(node, callerKey) {
55424
55381
  });
55425
55382
  return anyChanged ? mapped : node;
55426
55383
  }
55427
- if (typeof node === "object" && !React85__default.isValidElement(node) && !(node instanceof Date)) {
55384
+ if (typeof node === "object" && !React87__default.isValidElement(node) && !(node instanceof Date)) {
55428
55385
  return convertObjectProps(node);
55429
55386
  }
55430
55387
  return node;
@@ -57250,7 +57207,7 @@ function buildMockData(schema) {
57250
57207
  perfEnd("build-mock-data", t, { orbitalCount: schema.orbitals.length, entityCount: Object.keys(result).length });
57251
57208
  return result;
57252
57209
  }
57253
- function isInlineTrait2(traitRef) {
57210
+ function isInlineTrait3(traitRef) {
57254
57211
  return typeof traitRef === "object" && traitRef !== null && "stateMachine" in traitRef;
57255
57212
  }
57256
57213
  function findDataState(sm, initialStateName) {
@@ -57282,7 +57239,7 @@ function adjustSchemaForMockData(schema, mockData) {
57282
57239
  const updatedOrbitals = schema.orbitals.map((orbital) => {
57283
57240
  const traits2 = orbital.traits ?? [];
57284
57241
  const updatedTraits = traits2.map((traitRef) => {
57285
- if (!isInlineTrait2(traitRef)) return traitRef;
57242
+ if (!isInlineTrait3(traitRef)) return traitRef;
57286
57243
  const updated = rewriteTraitInitialState(traitRef, mockData);
57287
57244
  if (updated !== traitRef) changed = true;
57288
57245
  return updated;