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