@almadar/ui 5.17.0 → 5.18.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 +219 -171
- package/dist/avl/index.js +219 -171
- package/dist/components/atoms/Avatar.d.ts +4 -2
- package/dist/components/atoms/ConditionalWrapper.d.ts +2 -2
- package/dist/components/atoms/Icon.d.ts +6 -2
- package/dist/components/atoms/Input.d.ts +3 -2
- package/dist/components/atoms/LawReferenceTooltip.d.ts +2 -2
- package/dist/components/atoms/types.d.ts +10 -10
- package/dist/components/index.cjs +188 -156
- package/dist/components/index.js +188 -156
- package/dist/components/molecules/OptionConstraintGroup.d.ts +5 -3
- package/dist/components/molecules/ViolationAlert.d.ts +2 -2
- package/dist/components/molecules/game/CraftingRecipe.d.ts +4 -4
- package/dist/components/molecules/game/DialogueBox.d.ts +2 -2
- package/dist/components/organisms/ComponentPatterns.d.ts +2 -1
- package/dist/components/organisms/CustomPattern.d.ts +2 -1
- package/dist/components/organisms/DataTable.d.ts +1 -1
- package/dist/components/organisms/Form.d.ts +3 -3
- package/dist/components/organisms/LayoutPatterns.d.ts +4 -3
- package/dist/components/organisms/StateMachineView.d.ts +6 -3
- package/dist/components/organisms/book/types.d.ts +2 -2
- package/dist/components/organisms/game/CastleBoard.d.ts +4 -3
- package/dist/components/organisms/game/TraitStateViewer.d.ts +4 -4
- package/dist/components/organisms/game/UncontrolledBattleBoard.d.ts +9 -4
- package/dist/components/organisms/game/WorldMapBoard.d.ts +5 -4
- package/dist/components/organisms/game/puzzles/builder/BuilderBoard.d.ts +3 -3
- package/dist/components/organisms/game/puzzles/classifier/ClassifierBoard.d.ts +3 -3
- package/dist/components/organisms/game/puzzles/debugger/DebuggerBoard.d.ts +3 -3
- package/dist/components/organisms/game/puzzles/event-handler/EventHandlerBoard.d.ts +7 -4
- package/dist/components/organisms/game/puzzles/event-handler/ObjectRulePanel.d.ts +2 -2
- package/dist/components/organisms/game/puzzles/negotiator/NegotiatorBoard.d.ts +3 -3
- package/dist/components/organisms/game/puzzles/sequencer/SequencerBoard.d.ts +5 -4
- package/dist/components/organisms/game/puzzles/simulator/SimulatorBoard.d.ts +3 -3
- package/dist/components/organisms/game/puzzles/state-architect/StateArchitectBoard.d.ts +5 -4
- package/dist/components/templates/GenericAppTemplate.d.ts +1 -7
- package/dist/components/templates/types.d.ts +14 -6
- package/dist/docs/index.cjs +60 -22
- package/dist/docs/index.d.cts +9 -4
- package/dist/docs/index.js +58 -20
- package/dist/marketing/index.cjs +61 -23
- package/dist/marketing/index.d.cts +10 -6
- package/dist/marketing/index.js +58 -20
- package/dist/providers/index.cjs +188 -156
- package/dist/providers/index.js +188 -156
- package/dist/runtime/fn-form-lambda.d.ts +1 -1
- package/dist/runtime/index.cjs +219 -171
- package/dist/runtime/index.js +219 -171
- package/package.json +1 -1
|
@@ -1880,11 +1880,13 @@ var init_Icon = __esm({
|
|
|
1880
1880
|
strokeWidth,
|
|
1881
1881
|
style
|
|
1882
1882
|
}) => {
|
|
1883
|
+
const directIcon = typeof icon === "string" ? void 0 : icon;
|
|
1884
|
+
const effectiveName = typeof icon === "string" ? icon : name;
|
|
1883
1885
|
const family = useIconFamily();
|
|
1884
1886
|
const RenderedComponent = React80__namespace.default.useMemo(() => {
|
|
1885
|
-
if (
|
|
1886
|
-
return
|
|
1887
|
-
}, [
|
|
1887
|
+
if (directIcon) return null;
|
|
1888
|
+
return effectiveName ? resolveIconForFamily(effectiveName, family) : null;
|
|
1889
|
+
}, [directIcon, effectiveName, family]);
|
|
1888
1890
|
const effectiveStrokeWidth = strokeWidth ?? void 0;
|
|
1889
1891
|
const inlineStyle = {
|
|
1890
1892
|
...effectiveStrokeWidth === void 0 ? { strokeWidth: "var(--icon-stroke-width, 2)" } : {},
|
|
@@ -1896,8 +1898,8 @@ var init_Icon = __esm({
|
|
|
1896
1898
|
color ? color : "text-current",
|
|
1897
1899
|
className
|
|
1898
1900
|
);
|
|
1899
|
-
if (
|
|
1900
|
-
const Direct =
|
|
1901
|
+
if (directIcon) {
|
|
1902
|
+
const Direct = directIcon;
|
|
1901
1903
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1902
1904
|
Direct,
|
|
1903
1905
|
{
|
|
@@ -2089,7 +2091,7 @@ var init_Input = __esm({
|
|
|
2089
2091
|
error,
|
|
2090
2092
|
leftIcon,
|
|
2091
2093
|
rightIcon,
|
|
2092
|
-
icon:
|
|
2094
|
+
icon: iconProp,
|
|
2093
2095
|
clearable,
|
|
2094
2096
|
onClear,
|
|
2095
2097
|
value,
|
|
@@ -2099,6 +2101,7 @@ var init_Input = __esm({
|
|
|
2099
2101
|
...props
|
|
2100
2102
|
}, ref) => {
|
|
2101
2103
|
const type = inputType || htmlType || "text";
|
|
2104
|
+
const IconComponent = typeof iconProp === "string" ? resolveIcon(iconProp) : iconProp;
|
|
2102
2105
|
const resolvedLeftIcon = leftIcon || IconComponent && /* @__PURE__ */ jsxRuntime.jsx(IconComponent, { className: "h-icon-default w-icon-default" });
|
|
2103
2106
|
const showClearButton = clearable && value && String(value).length > 0;
|
|
2104
2107
|
const isMultiline = type === "textarea";
|
|
@@ -2737,7 +2740,7 @@ var init_Avatar = __esm({
|
|
|
2737
2740
|
alt,
|
|
2738
2741
|
name,
|
|
2739
2742
|
initials: providedInitials,
|
|
2740
|
-
icon:
|
|
2743
|
+
icon: iconProp,
|
|
2741
2744
|
size = "md",
|
|
2742
2745
|
status,
|
|
2743
2746
|
badge,
|
|
@@ -2748,6 +2751,7 @@ var init_Avatar = __esm({
|
|
|
2748
2751
|
}) => {
|
|
2749
2752
|
const eventBus = useEventBus();
|
|
2750
2753
|
const initials = providedInitials ?? (name ? generateInitials(name) : void 0);
|
|
2754
|
+
const IconComponent = typeof iconProp === "string" ? resolveIcon(iconProp) : iconProp;
|
|
2751
2755
|
const hasImage = !!src;
|
|
2752
2756
|
const hasInitials = !!initials;
|
|
2753
2757
|
const hasIcon = !!IconComponent;
|
|
@@ -13731,6 +13735,7 @@ var init_StateMachineView = __esm({
|
|
|
13731
13735
|
setTooltip((prev) => ({ ...prev, pinned: false, visible: false }));
|
|
13732
13736
|
}, []);
|
|
13733
13737
|
useEventListener("UI:TOOLTIP_CLOSE", handleCloseTooltip);
|
|
13738
|
+
if (!layoutData) return null;
|
|
13734
13739
|
const { width, height, title, states, labels, entity, outputs, config } = layoutData;
|
|
13735
13740
|
const bundles = React80.useMemo(() => {
|
|
13736
13741
|
const bundleMap = {};
|
|
@@ -16075,13 +16080,14 @@ function BuilderBoard({
|
|
|
16075
16080
|
}) {
|
|
16076
16081
|
const { emit } = useEventBus();
|
|
16077
16082
|
const { t } = useTranslate();
|
|
16083
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
16078
16084
|
const [placements, setPlacements] = React80.useState({});
|
|
16079
16085
|
const [headerError, setHeaderError] = React80.useState(false);
|
|
16080
16086
|
const [submitted, setSubmitted] = React80.useState(false);
|
|
16081
16087
|
const [attempts, setAttempts] = React80.useState(0);
|
|
16082
16088
|
const [showHint, setShowHint] = React80.useState(false);
|
|
16083
|
-
const components =
|
|
16084
|
-
const slots =
|
|
16089
|
+
const components = resolved?.components ?? [];
|
|
16090
|
+
const slots = resolved?.slots ?? [];
|
|
16085
16091
|
const usedComponentIds = new Set(Object.values(placements));
|
|
16086
16092
|
const availableComponents = components.filter((c) => !usedComponentIds.has(c.id));
|
|
16087
16093
|
const [selectedComponent, setSelectedComponent] = React80.useState(null);
|
|
@@ -16115,7 +16121,7 @@ function BuilderBoard({
|
|
|
16115
16121
|
}, [slots, placements, attempts, completeEvent, emit]);
|
|
16116
16122
|
const handleReset = () => {
|
|
16117
16123
|
setSubmitted(false);
|
|
16118
|
-
if (attempts >= 2 &&
|
|
16124
|
+
if (attempts >= 2 && resolved?.hint) {
|
|
16119
16125
|
setShowHint(true);
|
|
16120
16126
|
}
|
|
16121
16127
|
};
|
|
@@ -16127,20 +16133,21 @@ function BuilderBoard({
|
|
|
16127
16133
|
setShowHint(false);
|
|
16128
16134
|
};
|
|
16129
16135
|
const getComponentById = (id) => components.find((c) => c.id === id);
|
|
16136
|
+
if (!resolved) return null;
|
|
16130
16137
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
16131
16138
|
exports.Box,
|
|
16132
16139
|
{
|
|
16133
16140
|
className,
|
|
16134
16141
|
style: {
|
|
16135
|
-
backgroundImage:
|
|
16142
|
+
backgroundImage: resolved.theme?.background ? `url(${resolved.theme.background})` : void 0,
|
|
16136
16143
|
backgroundSize: "cover",
|
|
16137
16144
|
backgroundPosition: "center"
|
|
16138
16145
|
},
|
|
16139
16146
|
children: /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "lg", className: "p-4", children: [
|
|
16140
|
-
|
|
16147
|
+
resolved.headerImage && !headerError ? /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: resolved.headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : resolved.headerImage && headerError ? /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
16141
16148
|
/* @__PURE__ */ jsxRuntime.jsx(exports.Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "sm", children: [
|
|
16142
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "h4", weight: "bold", children:
|
|
16143
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body", children:
|
|
16149
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "h4", weight: "bold", children: resolved.title }),
|
|
16150
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body", children: resolved.description })
|
|
16144
16151
|
] }) }),
|
|
16145
16152
|
/* @__PURE__ */ jsxRuntime.jsx(exports.Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "sm", children: [
|
|
16146
16153
|
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: t("builder.components") }),
|
|
@@ -16200,9 +16207,9 @@ function BuilderBoard({
|
|
|
16200
16207
|
] }) }),
|
|
16201
16208
|
submitted && /* @__PURE__ */ jsxRuntime.jsx(exports.Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "sm", align: "center", children: [
|
|
16202
16209
|
/* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { icon: allCorrect ? LucideIcons2.CheckCircle : LucideIcons2.XCircle, size: "lg", className: allCorrect ? "text-success" : "text-error" }),
|
|
16203
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body", weight: "bold", children: allCorrect ?
|
|
16210
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body", weight: "bold", children: allCorrect ? resolved.successMessage ?? t("builder.success") : resolved.failMessage ?? t("builder.incorrect") })
|
|
16204
16211
|
] }) }),
|
|
16205
|
-
showHint &&
|
|
16212
|
+
showHint && resolved.hint && /* @__PURE__ */ jsxRuntime.jsx(exports.Card, { className: "p-4 border-l-4 border-l-warning", children: /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body", children: resolved.hint }) }),
|
|
16206
16213
|
/* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { gap: "sm", justify: "center", children: [
|
|
16207
16214
|
!submitted ? /* @__PURE__ */ jsxRuntime.jsxs(exports.Button, { variant: "primary", onClick: handleSubmit, disabled: !allPlaced, children: [
|
|
16208
16215
|
/* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { icon: LucideIcons2.Wrench, size: "sm" }),
|
|
@@ -18743,11 +18750,12 @@ function CastleBoard({
|
|
|
18743
18750
|
className
|
|
18744
18751
|
}) {
|
|
18745
18752
|
const eventBus = useEventBus();
|
|
18746
|
-
const
|
|
18747
|
-
const
|
|
18748
|
-
const
|
|
18749
|
-
const
|
|
18750
|
-
const
|
|
18753
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
18754
|
+
const tiles = resolved?.tiles ?? [];
|
|
18755
|
+
const features = resolved?.features ?? [];
|
|
18756
|
+
const units = resolved?.units ?? [];
|
|
18757
|
+
const assetManifest = resolved?.assetManifest;
|
|
18758
|
+
const backgroundImage = resolved?.backgroundImage;
|
|
18751
18759
|
const [hoveredTile, setHoveredTile] = React80.useState(null);
|
|
18752
18760
|
const [selectedFeature, setSelectedFeature] = React80.useState(null);
|
|
18753
18761
|
const hoveredFeature = React80.useMemo(() => {
|
|
@@ -19698,13 +19706,14 @@ function ClassifierBoard({
|
|
|
19698
19706
|
}) {
|
|
19699
19707
|
const { emit } = useEventBus();
|
|
19700
19708
|
const { t } = useTranslate();
|
|
19709
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
19701
19710
|
const [assignments, setAssignments] = React80.useState({});
|
|
19702
19711
|
const [headerError, setHeaderError] = React80.useState(false);
|
|
19703
19712
|
const [submitted, setSubmitted] = React80.useState(false);
|
|
19704
19713
|
const [attempts, setAttempts] = React80.useState(0);
|
|
19705
19714
|
const [showHint, setShowHint] = React80.useState(false);
|
|
19706
|
-
const items =
|
|
19707
|
-
const categories =
|
|
19715
|
+
const items = resolved?.items ?? [];
|
|
19716
|
+
const categories = resolved?.categories ?? [];
|
|
19708
19717
|
const unassignedItems = items.filter((item) => !assignments[item.id]);
|
|
19709
19718
|
const allAssigned = Object.keys(assignments).length === items.length;
|
|
19710
19719
|
const results = submitted ? items.map((item) => ({
|
|
@@ -19736,7 +19745,7 @@ function ClassifierBoard({
|
|
|
19736
19745
|
}, [items, assignments, attempts, completeEvent, emit]);
|
|
19737
19746
|
const handleReset = () => {
|
|
19738
19747
|
setSubmitted(false);
|
|
19739
|
-
if (attempts >= 2 &&
|
|
19748
|
+
if (attempts >= 2 && resolved?.hint) {
|
|
19740
19749
|
setShowHint(true);
|
|
19741
19750
|
}
|
|
19742
19751
|
};
|
|
@@ -19746,20 +19755,21 @@ function ClassifierBoard({
|
|
|
19746
19755
|
setAttempts(0);
|
|
19747
19756
|
setShowHint(false);
|
|
19748
19757
|
};
|
|
19758
|
+
if (!resolved) return null;
|
|
19749
19759
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
19750
19760
|
exports.Box,
|
|
19751
19761
|
{
|
|
19752
19762
|
className,
|
|
19753
19763
|
style: {
|
|
19754
|
-
backgroundImage:
|
|
19764
|
+
backgroundImage: resolved.theme?.background ? `url(${resolved.theme.background})` : void 0,
|
|
19755
19765
|
backgroundSize: "cover",
|
|
19756
19766
|
backgroundPosition: "center"
|
|
19757
19767
|
},
|
|
19758
19768
|
children: /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "lg", className: "p-4", children: [
|
|
19759
|
-
|
|
19769
|
+
resolved.headerImage && !headerError ? /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: resolved.headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : resolved.headerImage && headerError ? /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
19760
19770
|
/* @__PURE__ */ jsxRuntime.jsx(exports.Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "sm", children: [
|
|
19761
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "h4", weight: "bold", children:
|
|
19762
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body", children:
|
|
19771
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "h4", weight: "bold", children: resolved.title }),
|
|
19772
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body", children: resolved.description })
|
|
19763
19773
|
] }) }),
|
|
19764
19774
|
unassignedItems.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(exports.Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "sm", children: [
|
|
19765
19775
|
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: t("classifier.itemsToSort") }),
|
|
@@ -19811,10 +19821,10 @@ function ClassifierBoard({
|
|
|
19811
19821
|
}) }),
|
|
19812
19822
|
submitted && /* @__PURE__ */ jsxRuntime.jsx(exports.Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "sm", align: "center", children: [
|
|
19813
19823
|
/* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { icon: allCorrect ? LucideIcons2.CheckCircle : LucideIcons2.XCircle, size: "lg", className: allCorrect ? "text-success" : "text-error" }),
|
|
19814
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body", weight: "bold", children: allCorrect ?
|
|
19815
|
-
!allCorrect &&
|
|
19824
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body", weight: "bold", children: allCorrect ? resolved.successMessage ?? t("classifier.allCorrect") : `${correctCount}/${items.length} ${t("classifier.correct")}` }),
|
|
19825
|
+
!allCorrect && resolved.failMessage && /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body", className: "text-muted-foreground", children: resolved.failMessage })
|
|
19816
19826
|
] }) }),
|
|
19817
|
-
showHint &&
|
|
19827
|
+
showHint && resolved.hint && /* @__PURE__ */ jsxRuntime.jsx(exports.Card, { className: "p-4 border-l-4 border-l-warning", children: /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body", children: resolved.hint }) }),
|
|
19818
19828
|
/* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { gap: "sm", justify: "center", children: [
|
|
19819
19829
|
!submitted ? /* @__PURE__ */ jsxRuntime.jsxs(exports.Button, { variant: "primary", onClick: handleSubmit, disabled: !allAssigned, children: [
|
|
19820
19830
|
/* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { icon: LucideIcons2.Send, size: "sm" }),
|
|
@@ -31875,7 +31885,7 @@ var init_OptionConstraintGroup = __esm({
|
|
|
31875
31885
|
title,
|
|
31876
31886
|
description,
|
|
31877
31887
|
options,
|
|
31878
|
-
constraint,
|
|
31888
|
+
constraint = { type: "single" },
|
|
31879
31889
|
selected = [],
|
|
31880
31890
|
onChange,
|
|
31881
31891
|
changeEvent,
|
|
@@ -35117,7 +35127,7 @@ function DataTable({
|
|
|
35117
35127
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
35118
35128
|
exports.EmptyState,
|
|
35119
35129
|
{
|
|
35120
|
-
icon: emptyIcon,
|
|
35130
|
+
icon: typeof emptyIcon === "string" ? resolveIcon(emptyIcon) : emptyIcon,
|
|
35121
35131
|
title: resolvedEmptyTitle,
|
|
35122
35132
|
description: resolvedEmptyDescription,
|
|
35123
35133
|
actionLabel: emptyAction?.label,
|
|
@@ -35246,6 +35256,7 @@ var init_DataTable = __esm({
|
|
|
35246
35256
|
init_Stack();
|
|
35247
35257
|
init_Typography();
|
|
35248
35258
|
init_molecules();
|
|
35259
|
+
init_Icon();
|
|
35249
35260
|
init_useEventBus();
|
|
35250
35261
|
init_useTranslate();
|
|
35251
35262
|
init_types3();
|
|
@@ -35266,6 +35277,7 @@ function DebuggerBoard({
|
|
|
35266
35277
|
}) {
|
|
35267
35278
|
const { emit } = useEventBus();
|
|
35268
35279
|
const { t } = useTranslate();
|
|
35280
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
35269
35281
|
const [flaggedLines, setFlaggedLines] = React80.useState(/* @__PURE__ */ new Set());
|
|
35270
35282
|
const [headerError, setHeaderError] = React80.useState(false);
|
|
35271
35283
|
const [submitted, setSubmitted] = React80.useState(false);
|
|
@@ -35283,7 +35295,7 @@ function DebuggerBoard({
|
|
|
35283
35295
|
return next;
|
|
35284
35296
|
});
|
|
35285
35297
|
};
|
|
35286
|
-
const lines =
|
|
35298
|
+
const lines = resolved?.lines ?? [];
|
|
35287
35299
|
const bugLines = lines.filter((l) => l.isBug);
|
|
35288
35300
|
const correctFlags = lines.filter((l) => l.isBug && flaggedLines.has(l.id));
|
|
35289
35301
|
const falseFlags = lines.filter((l) => !l.isBug && flaggedLines.has(l.id));
|
|
@@ -35298,7 +35310,7 @@ function DebuggerBoard({
|
|
|
35298
35310
|
}, [correctFlags.length, bugLines.length, falseFlags.length, attempts, completeEvent, emit]);
|
|
35299
35311
|
const handleReset = () => {
|
|
35300
35312
|
setSubmitted(false);
|
|
35301
|
-
if (attempts >= 2 &&
|
|
35313
|
+
if (attempts >= 2 && resolved?.hint) {
|
|
35302
35314
|
setShowHint(true);
|
|
35303
35315
|
}
|
|
35304
35316
|
};
|
|
@@ -35308,24 +35320,25 @@ function DebuggerBoard({
|
|
|
35308
35320
|
setAttempts(0);
|
|
35309
35321
|
setShowHint(false);
|
|
35310
35322
|
};
|
|
35323
|
+
if (!resolved) return null;
|
|
35311
35324
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
35312
35325
|
exports.Box,
|
|
35313
35326
|
{
|
|
35314
35327
|
className,
|
|
35315
35328
|
style: {
|
|
35316
|
-
backgroundImage:
|
|
35329
|
+
backgroundImage: resolved.theme?.background ? `url(${resolved.theme.background})` : void 0,
|
|
35317
35330
|
backgroundSize: "cover",
|
|
35318
35331
|
backgroundPosition: "center"
|
|
35319
35332
|
},
|
|
35320
35333
|
children: /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "lg", className: "p-4", children: [
|
|
35321
|
-
|
|
35334
|
+
resolved.headerImage && !headerError ? /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: resolved.headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : resolved.headerImage && headerError ? /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
35322
35335
|
/* @__PURE__ */ jsxRuntime.jsx(exports.Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "sm", children: [
|
|
35323
35336
|
/* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { gap: "xs", align: "center", children: [
|
|
35324
35337
|
/* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { icon: LucideIcons2.Bug, size: "sm" }),
|
|
35325
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "h4", weight: "bold", children:
|
|
35338
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "h4", weight: "bold", children: resolved.title })
|
|
35326
35339
|
] }),
|
|
35327
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body", children:
|
|
35328
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "caption", className: "text-muted-foreground", children: t("debugger.findBugs", { count: String(
|
|
35340
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body", children: resolved.description }),
|
|
35341
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "caption", className: "text-muted-foreground", children: t("debugger.findBugs", { count: String(resolved.bugCount) }) })
|
|
35329
35342
|
] }) }),
|
|
35330
35343
|
/* @__PURE__ */ jsxRuntime.jsx(exports.Card, { className: "p-0 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(exports.VStack, { gap: "none", children: lines.map((line, i) => {
|
|
35331
35344
|
const isFlagged = flaggedLines.has(line.id);
|
|
@@ -35357,7 +35370,7 @@ function DebuggerBoard({
|
|
|
35357
35370
|
);
|
|
35358
35371
|
}) }) }),
|
|
35359
35372
|
submitted && /* @__PURE__ */ jsxRuntime.jsx(exports.Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "sm", children: [
|
|
35360
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body", weight: "bold", children: allCorrect ?
|
|
35373
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body", weight: "bold", children: allCorrect ? resolved.successMessage ?? t("debugger.allFound") : `${correctFlags.length}/${bugLines.length} ${t("debugger.bugsFound")}` }),
|
|
35361
35374
|
bugLines.map((line) => /* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { gap: "xs", align: "start", children: [
|
|
35362
35375
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
35363
35376
|
exports.Icon,
|
|
@@ -35373,7 +35386,7 @@ function DebuggerBoard({
|
|
|
35373
35386
|
] })
|
|
35374
35387
|
] }, line.id))
|
|
35375
35388
|
] }) }),
|
|
35376
|
-
showHint &&
|
|
35389
|
+
showHint && resolved.hint && /* @__PURE__ */ jsxRuntime.jsx(exports.Card, { className: "p-4 border-l-4 border-l-warning", children: /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body", children: resolved.hint }) }),
|
|
35377
35390
|
/* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { gap: "sm", justify: "center", children: [
|
|
35378
35391
|
!submitted ? /* @__PURE__ */ jsxRuntime.jsxs(exports.Button, { variant: "primary", onClick: handleSubmit, disabled: flaggedLines.size === 0, children: [
|
|
35379
35392
|
/* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { icon: LucideIcons2.Send, size: "sm" }),
|
|
@@ -36600,7 +36613,8 @@ function EventHandlerBoard({
|
|
|
36600
36613
|
}) {
|
|
36601
36614
|
const { emit } = useEventBus();
|
|
36602
36615
|
const { t } = useTranslate();
|
|
36603
|
-
const
|
|
36616
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
36617
|
+
const entityObjects = resolved?.objects ?? [];
|
|
36604
36618
|
const [objects, setObjects] = React80.useState(entityObjects);
|
|
36605
36619
|
const [selectedObjectId, setSelectedObjectId] = React80.useState(
|
|
36606
36620
|
entityObjects[0]?.id || null
|
|
@@ -36635,7 +36649,7 @@ function EventHandlerBoard({
|
|
|
36635
36649
|
allRules.push({ object: obj, rule });
|
|
36636
36650
|
});
|
|
36637
36651
|
});
|
|
36638
|
-
const triggers =
|
|
36652
|
+
const triggers = resolved?.triggerEvents || [];
|
|
36639
36653
|
const eventQueue = [...triggers];
|
|
36640
36654
|
const firedEvents = /* @__PURE__ */ new Set();
|
|
36641
36655
|
let stepIdx = 0;
|
|
@@ -36666,12 +36680,12 @@ function EventHandlerBoard({
|
|
|
36666
36680
|
matching.forEach(({ object, rule }) => {
|
|
36667
36681
|
addLogEntry(object.icon, t("eventHandler.heardEvent", { object: object.name, event: currentEvent, action: rule.thenAction }), "done");
|
|
36668
36682
|
eventQueue.push(rule.thenAction);
|
|
36669
|
-
if (rule.thenAction ===
|
|
36683
|
+
if (rule.thenAction === resolved?.goalEvent) {
|
|
36670
36684
|
goalReached = true;
|
|
36671
36685
|
}
|
|
36672
36686
|
});
|
|
36673
36687
|
}
|
|
36674
|
-
if (currentEvent ===
|
|
36688
|
+
if (currentEvent === resolved?.goalEvent) {
|
|
36675
36689
|
goalReached = true;
|
|
36676
36690
|
}
|
|
36677
36691
|
stepIdx++;
|
|
@@ -36681,7 +36695,7 @@ function EventHandlerBoard({
|
|
|
36681
36695
|
addLogEntry("\u{1F3AC}", t("eventHandler.simulationStarted", { events: triggers.join(", ") }), "active");
|
|
36682
36696
|
}
|
|
36683
36697
|
timerRef.current = setTimeout(processNext, stepDurationMs);
|
|
36684
|
-
}, [playState, objects,
|
|
36698
|
+
}, [playState, objects, resolved, stepDurationMs, playEvent, completeEvent, emit, addLogEntry, t]);
|
|
36685
36699
|
const handleTryAgain = React80.useCallback(() => {
|
|
36686
36700
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
36687
36701
|
setPlayState("editing");
|
|
@@ -36689,12 +36703,13 @@ function EventHandlerBoard({
|
|
|
36689
36703
|
}, []);
|
|
36690
36704
|
const handleReset = React80.useCallback(() => {
|
|
36691
36705
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
36692
|
-
setObjects(
|
|
36706
|
+
setObjects(resolved?.objects ?? []);
|
|
36693
36707
|
setPlayState("editing");
|
|
36694
36708
|
setEventLog([]);
|
|
36695
|
-
setSelectedObjectId((
|
|
36709
|
+
setSelectedObjectId((resolved?.objects ?? [])[0]?.id || null);
|
|
36696
36710
|
setAttempts(0);
|
|
36697
|
-
}, [
|
|
36711
|
+
}, [resolved?.objects]);
|
|
36712
|
+
if (!resolved) return null;
|
|
36698
36713
|
const objectViewers = objects.map((obj) => {
|
|
36699
36714
|
const machine = {
|
|
36700
36715
|
name: obj.name,
|
|
@@ -36708,25 +36723,25 @@ function EventHandlerBoard({
|
|
|
36708
36723
|
};
|
|
36709
36724
|
return { obj, machine };
|
|
36710
36725
|
});
|
|
36711
|
-
const showHint = attempts >= 3 &&
|
|
36726
|
+
const showHint = attempts >= 3 && resolved.hint;
|
|
36712
36727
|
const encourageKey = ENCOURAGEMENT_KEYS[Math.min(attempts - 1, ENCOURAGEMENT_KEYS.length - 1)] ?? ENCOURAGEMENT_KEYS[0];
|
|
36713
36728
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
36714
36729
|
exports.VStack,
|
|
36715
36730
|
{
|
|
36716
36731
|
className: cn("p-4 gap-6", className),
|
|
36717
36732
|
style: {
|
|
36718
|
-
backgroundImage:
|
|
36733
|
+
backgroundImage: resolved.theme?.background ? `url(${resolved.theme.background})` : void 0,
|
|
36719
36734
|
backgroundSize: "cover",
|
|
36720
36735
|
backgroundPosition: "center"
|
|
36721
36736
|
},
|
|
36722
36737
|
children: [
|
|
36723
|
-
|
|
36738
|
+
resolved.headerImage && !headerError ? /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: resolved.headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : resolved.headerImage && headerError ? /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
36724
36739
|
/* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "xs", children: [
|
|
36725
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "h4", className: "text-foreground", children:
|
|
36726
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body2", className: "text-muted-foreground", children:
|
|
36740
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "h4", className: "text-foreground", children: resolved.title }),
|
|
36741
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body2", className: "text-muted-foreground", children: resolved.description }),
|
|
36727
36742
|
/* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { className: "items-center p-2 rounded bg-primary/10 border border-primary/30", gap: "xs", children: [
|
|
36728
36743
|
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "caption", className: "text-primary font-bold", children: t("game.goal") + ":" }),
|
|
36729
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "caption", className: "text-foreground", children:
|
|
36744
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "caption", className: "text-foreground", children: resolved.goalCondition })
|
|
36730
36745
|
] })
|
|
36731
36746
|
] }),
|
|
36732
36747
|
/* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "sm", children: [
|
|
@@ -36757,12 +36772,12 @@ function EventHandlerBoard({
|
|
|
36757
36772
|
}
|
|
36758
36773
|
),
|
|
36759
36774
|
eventLog.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(EventLog, { entries: eventLog }),
|
|
36760
|
-
playState === "success" && /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "p-4 rounded-container bg-success/20 border border-success text-center", children: /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "h5", className: "text-success", children:
|
|
36775
|
+
playState === "success" && /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "p-4 rounded-container bg-success/20 border border-success text-center", children: /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "h5", className: "text-success", children: resolved.successMessage || t("eventHandler.chainComplete") }) }),
|
|
36761
36776
|
playState === "fail" && /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "sm", children: [
|
|
36762
36777
|
/* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "p-4 rounded-container bg-warning/10 border border-warning/30 text-center", children: /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body1", className: "text-foreground font-medium", children: t(encourageKey) }) }),
|
|
36763
36778
|
showHint && /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "p-3 rounded-container bg-accent/10 border border-accent/30", children: /* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { className: "items-start", gap: "xs", children: [
|
|
36764
36779
|
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body2", className: "text-accent font-bold shrink-0", children: "\u{1F4A1} " + t("game.hint") + ":" }),
|
|
36765
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body2", className: "text-foreground", children:
|
|
36780
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body2", className: "text-foreground", children: resolved.hint })
|
|
36766
36781
|
] }) })
|
|
36767
36782
|
] }),
|
|
36768
36783
|
/* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { gap: "sm", children: [
|
|
@@ -39976,19 +39991,20 @@ function NegotiatorBoard({
|
|
|
39976
39991
|
}) {
|
|
39977
39992
|
const { emit } = useEventBus();
|
|
39978
39993
|
const { t } = useTranslate();
|
|
39994
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
39979
39995
|
const [history, setHistory] = React80.useState([]);
|
|
39980
39996
|
const [headerError, setHeaderError] = React80.useState(false);
|
|
39981
39997
|
const [showHint, setShowHint] = React80.useState(false);
|
|
39982
39998
|
const currentRound = history.length;
|
|
39983
|
-
const isComplete = currentRound >=
|
|
39999
|
+
const isComplete = currentRound >= (resolved?.totalRounds ?? 0);
|
|
39984
40000
|
const playerTotal = history.reduce((s, r) => s + r.playerPayoff, 0);
|
|
39985
40001
|
const opponentTotal = history.reduce((s, r) => s + r.opponentPayoff, 0);
|
|
39986
|
-
const won = isComplete && playerTotal >=
|
|
39987
|
-
const actions =
|
|
39988
|
-
const payoffMatrix =
|
|
40002
|
+
const won = isComplete && playerTotal >= (resolved?.targetScore ?? 0);
|
|
40003
|
+
const actions = resolved?.actions ?? [];
|
|
40004
|
+
const payoffMatrix = resolved?.payoffMatrix ?? [];
|
|
39989
40005
|
const handleAction = React80.useCallback((actionId) => {
|
|
39990
40006
|
if (isComplete) return;
|
|
39991
|
-
const opponentAction = getOpponentAction(
|
|
40007
|
+
const opponentAction = getOpponentAction(resolved?.opponentStrategy ?? "random", actions, history);
|
|
39992
40008
|
const payoff = payoffMatrix.find(
|
|
39993
40009
|
(p2) => p2.playerAction === actionId && p2.opponentAction === opponentAction
|
|
39994
40010
|
);
|
|
@@ -40001,41 +40017,42 @@ function NegotiatorBoard({
|
|
|
40001
40017
|
};
|
|
40002
40018
|
const newHistory = [...history, result];
|
|
40003
40019
|
setHistory(newHistory);
|
|
40004
|
-
if (newHistory.length >=
|
|
40020
|
+
if (newHistory.length >= (resolved?.totalRounds ?? 0)) {
|
|
40005
40021
|
const total = newHistory.reduce((s, r) => s + r.playerPayoff, 0);
|
|
40006
|
-
if (total >=
|
|
40022
|
+
if (total >= (resolved?.targetScore ?? 0)) {
|
|
40007
40023
|
emit(`UI:${completeEvent}`, { success: true, score: total });
|
|
40008
40024
|
}
|
|
40009
|
-
if (newHistory.length >= 3 &&
|
|
40025
|
+
if (newHistory.length >= 3 && resolved?.hint) {
|
|
40010
40026
|
setShowHint(true);
|
|
40011
40027
|
}
|
|
40012
40028
|
}
|
|
40013
|
-
}, [isComplete,
|
|
40029
|
+
}, [isComplete, resolved, actions, payoffMatrix, history, currentRound, completeEvent, emit]);
|
|
40014
40030
|
const handleReset = () => {
|
|
40015
40031
|
setHistory([]);
|
|
40016
40032
|
setShowHint(false);
|
|
40017
40033
|
};
|
|
40018
40034
|
const getActionLabel = (id) => actions.find((a) => a.id === id)?.label ?? id;
|
|
40035
|
+
if (!resolved) return null;
|
|
40019
40036
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
40020
40037
|
exports.Box,
|
|
40021
40038
|
{
|
|
40022
40039
|
className,
|
|
40023
40040
|
style: {
|
|
40024
|
-
backgroundImage:
|
|
40041
|
+
backgroundImage: resolved.theme?.background ? `url(${resolved.theme.background})` : void 0,
|
|
40025
40042
|
backgroundSize: "cover",
|
|
40026
40043
|
backgroundPosition: "center"
|
|
40027
40044
|
},
|
|
40028
40045
|
children: /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "lg", className: "p-4", children: [
|
|
40029
|
-
|
|
40046
|
+
resolved.headerImage && !headerError ? /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: resolved.headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : resolved.headerImage && headerError ? /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
40030
40047
|
/* @__PURE__ */ jsxRuntime.jsx(exports.Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "sm", children: [
|
|
40031
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "h4", weight: "bold", children:
|
|
40032
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body", children:
|
|
40048
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "h4", weight: "bold", children: resolved.title }),
|
|
40049
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body", children: resolved.description }),
|
|
40033
40050
|
/* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { gap: "md", children: [
|
|
40034
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.Badge, { size: "sm", children: t("negotiator.round", { current: String(currentRound), total: String(
|
|
40051
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Badge, { size: "sm", children: t("negotiator.round", { current: String(currentRound), total: String(resolved.totalRounds) }) }),
|
|
40035
40052
|
/* @__PURE__ */ jsxRuntime.jsxs(exports.Badge, { size: "sm", children: [
|
|
40036
40053
|
t("negotiator.target"),
|
|
40037
40054
|
": ",
|
|
40038
|
-
|
|
40055
|
+
resolved.targetScore
|
|
40039
40056
|
] })
|
|
40040
40057
|
] })
|
|
40041
40058
|
] }) }),
|
|
@@ -40084,16 +40101,16 @@ function NegotiatorBoard({
|
|
|
40084
40101
|
] }) }),
|
|
40085
40102
|
isComplete && /* @__PURE__ */ jsxRuntime.jsx(exports.Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "sm", align: "center", children: [
|
|
40086
40103
|
/* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { icon: LucideIcons2.CheckCircle, size: "lg", className: won ? "text-success" : "text-error" }),
|
|
40087
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body", weight: "bold", children: won ?
|
|
40104
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body", weight: "bold", children: won ? resolved.successMessage ?? t("negotiator.success") : resolved.failMessage ?? t("negotiator.failed") }),
|
|
40088
40105
|
/* @__PURE__ */ jsxRuntime.jsxs(exports.Typography, { variant: "caption", className: "text-muted-foreground", children: [
|
|
40089
40106
|
t("negotiator.finalScore"),
|
|
40090
40107
|
": ",
|
|
40091
40108
|
playerTotal,
|
|
40092
40109
|
"/",
|
|
40093
|
-
|
|
40110
|
+
resolved.targetScore
|
|
40094
40111
|
] })
|
|
40095
40112
|
] }) }),
|
|
40096
|
-
showHint &&
|
|
40113
|
+
showHint && resolved.hint && !won && /* @__PURE__ */ jsxRuntime.jsx(exports.Card, { className: "p-4 border-l-4 border-l-warning", children: /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body", children: resolved.hint }) }),
|
|
40097
40114
|
isComplete && !won && /* @__PURE__ */ jsxRuntime.jsx(exports.HStack, { justify: "center", children: /* @__PURE__ */ jsxRuntime.jsx(exports.Button, { variant: "primary", onClick: handleReset, children: t("negotiator.playAgain") }) })
|
|
40098
40115
|
] })
|
|
40099
40116
|
}
|
|
@@ -42912,15 +42929,16 @@ function SequencerBoard({
|
|
|
42912
42929
|
}) {
|
|
42913
42930
|
const { emit } = useEventBus();
|
|
42914
42931
|
const { t } = useTranslate();
|
|
42932
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
42915
42933
|
const [headerError, setHeaderError] = React80.useState(false);
|
|
42916
42934
|
const [slots, setSlots] = React80.useState(
|
|
42917
|
-
() => Array.from({ length:
|
|
42935
|
+
() => Array.from({ length: resolved?.maxSlots ?? 0 }, () => void 0)
|
|
42918
42936
|
);
|
|
42919
42937
|
const [playState, setPlayState] = React80.useState("idle");
|
|
42920
42938
|
const [currentStep, setCurrentStep] = React80.useState(-1);
|
|
42921
42939
|
const [attempts, setAttempts] = React80.useState(0);
|
|
42922
42940
|
const [slotFeedback, setSlotFeedback] = React80.useState(
|
|
42923
|
-
() => Array.from({ length:
|
|
42941
|
+
() => Array.from({ length: resolved?.maxSlots ?? 0 }, () => null)
|
|
42924
42942
|
);
|
|
42925
42943
|
const timerRef = React80.useRef(null);
|
|
42926
42944
|
React80.useEffect(() => () => {
|
|
@@ -42954,17 +42972,17 @@ function SequencerBoard({
|
|
|
42954
42972
|
}, [emit]);
|
|
42955
42973
|
const handleReset = React80.useCallback(() => {
|
|
42956
42974
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
42957
|
-
setSlots(Array.from({ length:
|
|
42975
|
+
setSlots(Array.from({ length: resolved?.maxSlots ?? 0 }, () => void 0));
|
|
42958
42976
|
setPlayState("idle");
|
|
42959
42977
|
setCurrentStep(-1);
|
|
42960
42978
|
setAttempts(0);
|
|
42961
|
-
setSlotFeedback(Array.from({ length:
|
|
42962
|
-
}, [
|
|
42979
|
+
setSlotFeedback(Array.from({ length: resolved?.maxSlots ?? 0 }, () => null));
|
|
42980
|
+
}, [resolved?.maxSlots]);
|
|
42963
42981
|
const filledSlots = slots.filter((s) => !!s);
|
|
42964
42982
|
const canPlay = filledSlots.length > 0 && playState === "idle";
|
|
42965
42983
|
const handlePlay = React80.useCallback(() => {
|
|
42966
42984
|
if (!canPlay) return;
|
|
42967
|
-
setSlotFeedback(Array.from({ length:
|
|
42985
|
+
setSlotFeedback(Array.from({ length: resolved?.maxSlots ?? 0 }, () => null));
|
|
42968
42986
|
emit("UI:PLAY_SOUND", { key: "confirm" });
|
|
42969
42987
|
const sequence = slots.map((s) => s?.id || "");
|
|
42970
42988
|
if (playEvent) {
|
|
@@ -42975,10 +42993,10 @@ function SequencerBoard({
|
|
|
42975
42993
|
let step = 0;
|
|
42976
42994
|
const advance = () => {
|
|
42977
42995
|
step++;
|
|
42978
|
-
if (step >=
|
|
42996
|
+
if (step >= (resolved?.maxSlots ?? 0)) {
|
|
42979
42997
|
const playerSeq = slots.map((s) => s?.id);
|
|
42980
42998
|
const playerIds = slots.filter(Boolean).map((s) => s?.id || "");
|
|
42981
|
-
const success =
|
|
42999
|
+
const success = (resolved?.solutions ?? []).some(
|
|
42982
43000
|
(sol) => sol.length === playerIds.length && sol.every((id, i) => id === playerIds[i])
|
|
42983
43001
|
);
|
|
42984
43002
|
if (success) {
|
|
@@ -42990,7 +43008,7 @@ function SequencerBoard({
|
|
|
42990
43008
|
}
|
|
42991
43009
|
} else {
|
|
42992
43010
|
setAttempts((prev) => prev + 1);
|
|
42993
|
-
const feedback = computeSlotFeedback(playerSeq,
|
|
43011
|
+
const feedback = computeSlotFeedback(playerSeq, resolved?.solutions ?? []);
|
|
42994
43012
|
setSlotFeedback(feedback);
|
|
42995
43013
|
setPlayState("idle");
|
|
42996
43014
|
setCurrentStep(-1);
|
|
@@ -43008,10 +43026,10 @@ function SequencerBoard({
|
|
|
43008
43026
|
}
|
|
43009
43027
|
};
|
|
43010
43028
|
timerRef.current = setTimeout(advance, stepDurationMs);
|
|
43011
|
-
}, [canPlay, slots,
|
|
43029
|
+
}, [canPlay, slots, resolved?.maxSlots, resolved?.solutions, stepDurationMs, playEvent, completeEvent, emit]);
|
|
43012
43030
|
const machine = {
|
|
43013
|
-
name:
|
|
43014
|
-
description:
|
|
43031
|
+
name: resolved?.title ?? "",
|
|
43032
|
+
description: resolved?.description ?? "",
|
|
43015
43033
|
states: slots.map((s, i) => stepLabel(s, i)),
|
|
43016
43034
|
currentState: currentStep >= 0 ? stepLabel(slots[currentStep], currentStep) : "__idle__",
|
|
43017
43035
|
transitions: slots.slice(0, -1).map((s, i) => ({
|
|
@@ -43020,36 +43038,37 @@ function SequencerBoard({
|
|
|
43020
43038
|
event: "NEXT"
|
|
43021
43039
|
}))
|
|
43022
43040
|
};
|
|
43023
|
-
const usedIds =
|
|
43024
|
-
const showHint = attempts >= 3 && !!
|
|
43041
|
+
const usedIds = resolved?.allowDuplicates === false ? slots.filter(Boolean).map((s) => s?.id || "") : [];
|
|
43042
|
+
const showHint = attempts >= 3 && !!resolved?.hint;
|
|
43025
43043
|
const hasFeedback = slotFeedback.some((f3) => f3 !== null);
|
|
43026
43044
|
const correctCount = slotFeedback.filter((f3) => f3 === "correct").length;
|
|
43027
43045
|
const encourageKey = ENCOURAGEMENT_KEYS2[Math.min(attempts - 1, ENCOURAGEMENT_KEYS2.length - 1)] ?? ENCOURAGEMENT_KEYS2[0];
|
|
43046
|
+
if (!resolved) return null;
|
|
43028
43047
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
43029
43048
|
exports.VStack,
|
|
43030
43049
|
{
|
|
43031
43050
|
className: cn("p-4 gap-6", className),
|
|
43032
43051
|
style: {
|
|
43033
|
-
backgroundImage:
|
|
43052
|
+
backgroundImage: resolved.theme?.background ? `url(${resolved.theme.background})` : void 0,
|
|
43034
43053
|
backgroundSize: "cover",
|
|
43035
43054
|
backgroundPosition: "center"
|
|
43036
43055
|
},
|
|
43037
43056
|
children: [
|
|
43038
|
-
|
|
43057
|
+
resolved.headerImage && !headerError ? /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: resolved.headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : resolved.headerImage && headerError ? /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
43039
43058
|
/* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "xs", children: [
|
|
43040
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "h4", className: "text-foreground", children:
|
|
43041
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body2", className: "text-muted-foreground", children:
|
|
43059
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "h4", className: "text-foreground", children: resolved.title }),
|
|
43060
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body2", className: "text-muted-foreground", children: resolved.description })
|
|
43042
43061
|
] }),
|
|
43043
43062
|
showHint && /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "p-3 rounded-container bg-accent/10 border border-accent/30", children: /* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { className: "items-start", gap: "xs", children: [
|
|
43044
43063
|
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body2", className: "text-accent font-bold shrink-0", children: "\u{1F4A1} " + t("game.hint") + ":" }),
|
|
43045
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body2", className: "text-foreground", children:
|
|
43064
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body2", className: "text-foreground", children: resolved.hint })
|
|
43046
43065
|
] }) }),
|
|
43047
43066
|
filledSlots.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(TraitStateViewer, { trait: machine, variant: "linear", size: "md" }),
|
|
43048
43067
|
/* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "xs", children: [
|
|
43049
43068
|
/* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { className: "items-center justify-between", children: [
|
|
43050
43069
|
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body2", className: "text-muted-foreground font-medium", children: t("sequencer.yourSequence") + ":" }),
|
|
43051
43070
|
hasFeedback && playState === "idle" && /* @__PURE__ */ jsxRuntime.jsxs(exports.Typography, { variant: "caption", className: "text-muted-foreground", children: [
|
|
43052
|
-
`${correctCount}/${
|
|
43071
|
+
`${correctCount}/${resolved.maxSlots} `,
|
|
43053
43072
|
"\u2705"
|
|
43054
43073
|
] })
|
|
43055
43074
|
] }),
|
|
@@ -43057,7 +43076,7 @@ function SequencerBoard({
|
|
|
43057
43076
|
SequenceBar,
|
|
43058
43077
|
{
|
|
43059
43078
|
slots,
|
|
43060
|
-
maxSlots:
|
|
43079
|
+
maxSlots: resolved.maxSlots,
|
|
43061
43080
|
onSlotDrop: handleSlotDrop,
|
|
43062
43081
|
onSlotRemove: handleSlotRemove,
|
|
43063
43082
|
playing: playState === "playing",
|
|
@@ -43071,15 +43090,15 @@ function SequencerBoard({
|
|
|
43071
43090
|
playState !== "playing" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
43072
43091
|
ActionPalette,
|
|
43073
43092
|
{
|
|
43074
|
-
actions:
|
|
43093
|
+
actions: resolved.availableActions,
|
|
43075
43094
|
usedActionIds: usedIds,
|
|
43076
|
-
allowDuplicates:
|
|
43095
|
+
allowDuplicates: resolved.allowDuplicates !== false,
|
|
43077
43096
|
categoryColors,
|
|
43078
43097
|
label: t("sequencer.dragActions")
|
|
43079
43098
|
}
|
|
43080
43099
|
),
|
|
43081
43100
|
hasFeedback && playState === "idle" && attempts > 0 && /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "p-3 rounded-container bg-warning/10 border border-warning/30 text-center", children: /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body2", className: "text-foreground", children: t(encourageKey) }) }),
|
|
43082
|
-
playState === "success" && /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "p-4 rounded-container bg-success/20 border border-success text-center", children: /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "h5", className: "text-success", children:
|
|
43101
|
+
playState === "success" && /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "p-4 rounded-container bg-success/20 border border-success text-center", children: /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "h5", className: "text-success", children: resolved.successMessage || t("sequencer.levelComplete") }) }),
|
|
43083
43102
|
/* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { gap: "sm", children: [
|
|
43084
43103
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
43085
43104
|
exports.Button,
|
|
@@ -43902,7 +43921,8 @@ function SimulatorBoard({
|
|
|
43902
43921
|
}) {
|
|
43903
43922
|
const { emit } = useEventBus();
|
|
43904
43923
|
const { t } = useTranslate();
|
|
43905
|
-
const
|
|
43924
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
43925
|
+
const parameters = resolved?.parameters ?? [];
|
|
43906
43926
|
const [values, setValues] = React80.useState(() => {
|
|
43907
43927
|
const init = {};
|
|
43908
43928
|
for (const p2 of parameters) {
|
|
@@ -43916,15 +43936,15 @@ function SimulatorBoard({
|
|
|
43916
43936
|
const [showHint, setShowHint] = React80.useState(false);
|
|
43917
43937
|
const computeOutput = React80.useCallback((params) => {
|
|
43918
43938
|
try {
|
|
43919
|
-
const fn = new Function("params", `return (${
|
|
43939
|
+
const fn = new Function("params", `return (${resolved?.computeExpression})`);
|
|
43920
43940
|
return fn(params);
|
|
43921
43941
|
} catch {
|
|
43922
43942
|
return 0;
|
|
43923
43943
|
}
|
|
43924
|
-
}, [
|
|
43944
|
+
}, [resolved?.computeExpression]);
|
|
43925
43945
|
const output = React80.useMemo(() => computeOutput(values) ?? 0, [computeOutput, values]);
|
|
43926
|
-
const targetValue =
|
|
43927
|
-
const targetTolerance =
|
|
43946
|
+
const targetValue = resolved?.targetValue ?? 0;
|
|
43947
|
+
const targetTolerance = resolved?.targetTolerance ?? 0;
|
|
43928
43948
|
const isCorrect = Math.abs(output - targetValue) <= targetTolerance;
|
|
43929
43949
|
const handleParameterChange = (id, value) => {
|
|
43930
43950
|
if (submitted) return;
|
|
@@ -43939,7 +43959,7 @@ function SimulatorBoard({
|
|
|
43939
43959
|
};
|
|
43940
43960
|
const handleReset = () => {
|
|
43941
43961
|
setSubmitted(false);
|
|
43942
|
-
if (attempts >= 2 &&
|
|
43962
|
+
if (attempts >= 2 && resolved?.hint) {
|
|
43943
43963
|
setShowHint(true);
|
|
43944
43964
|
}
|
|
43945
43965
|
};
|
|
@@ -43953,20 +43973,21 @@ function SimulatorBoard({
|
|
|
43953
43973
|
setAttempts(0);
|
|
43954
43974
|
setShowHint(false);
|
|
43955
43975
|
};
|
|
43976
|
+
if (!resolved) return null;
|
|
43956
43977
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
43957
43978
|
exports.Box,
|
|
43958
43979
|
{
|
|
43959
43980
|
className,
|
|
43960
43981
|
style: {
|
|
43961
|
-
backgroundImage:
|
|
43982
|
+
backgroundImage: resolved.theme?.background ? `url(${resolved.theme.background})` : void 0,
|
|
43962
43983
|
backgroundSize: "cover",
|
|
43963
43984
|
backgroundPosition: "center"
|
|
43964
43985
|
},
|
|
43965
43986
|
children: /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "lg", className: "p-4", children: [
|
|
43966
|
-
|
|
43987
|
+
resolved.headerImage && !headerError ? /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: resolved.headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : resolved.headerImage && headerError ? /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
43967
43988
|
/* @__PURE__ */ jsxRuntime.jsx(exports.Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "sm", children: [
|
|
43968
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "h4", weight: "bold", children:
|
|
43969
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body", children:
|
|
43989
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "h4", weight: "bold", children: resolved.title }),
|
|
43990
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body", children: resolved.description })
|
|
43970
43991
|
] }) }),
|
|
43971
43992
|
/* @__PURE__ */ jsxRuntime.jsx(exports.Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "md", children: [
|
|
43972
43993
|
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: t("simulator.parameters") }),
|
|
@@ -44007,28 +44028,28 @@ function SimulatorBoard({
|
|
|
44007
44028
|
] }, param.id))
|
|
44008
44029
|
] }) }),
|
|
44009
44030
|
/* @__PURE__ */ jsxRuntime.jsx(exports.Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "sm", align: "center", children: [
|
|
44010
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children:
|
|
44031
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: resolved.outputLabel }),
|
|
44011
44032
|
/* @__PURE__ */ jsxRuntime.jsxs(exports.Typography, { variant: "h3", weight: "bold", children: [
|
|
44012
44033
|
output.toFixed(2),
|
|
44013
44034
|
" ",
|
|
44014
|
-
|
|
44035
|
+
resolved.outputUnit
|
|
44015
44036
|
] }),
|
|
44016
44037
|
submitted && /* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { gap: "xs", align: "center", children: [
|
|
44017
44038
|
/* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { icon: isCorrect ? LucideIcons2.CheckCircle : LucideIcons2.XCircle, size: "sm", className: isCorrect ? "text-success" : "text-error" }),
|
|
44018
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body", className: isCorrect ? "text-success" : "text-error", children: isCorrect ?
|
|
44039
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body", className: isCorrect ? "text-success" : "text-error", children: isCorrect ? resolved.successMessage ?? t("simulator.correct") : resolved.failMessage ?? t("simulator.incorrect") })
|
|
44019
44040
|
] }),
|
|
44020
44041
|
/* @__PURE__ */ jsxRuntime.jsxs(exports.Typography, { variant: "caption", className: "text-muted-foreground", children: [
|
|
44021
44042
|
t("simulator.target"),
|
|
44022
44043
|
": ",
|
|
44023
44044
|
targetValue,
|
|
44024
44045
|
" ",
|
|
44025
|
-
|
|
44046
|
+
resolved.outputUnit,
|
|
44026
44047
|
" (\xB1",
|
|
44027
44048
|
targetTolerance,
|
|
44028
44049
|
")"
|
|
44029
44050
|
] })
|
|
44030
44051
|
] }) }),
|
|
44031
|
-
showHint &&
|
|
44052
|
+
showHint && resolved.hint && /* @__PURE__ */ jsxRuntime.jsx(exports.Card, { className: "p-4 border-l-4 border-l-warning", children: /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body", children: resolved.hint }) }),
|
|
44032
44053
|
/* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { gap: "sm", justify: "center", children: [
|
|
44033
44054
|
!submitted ? /* @__PURE__ */ jsxRuntime.jsxs(exports.Button, { variant: "primary", onClick: handleSubmit, children: [
|
|
44034
44055
|
/* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { icon: LucideIcons2.Play, size: "sm" }),
|
|
@@ -44719,13 +44740,14 @@ function StateArchitectBoard({
|
|
|
44719
44740
|
}) {
|
|
44720
44741
|
const { emit } = useEventBus();
|
|
44721
44742
|
const { t } = useTranslate();
|
|
44722
|
-
const
|
|
44743
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
44744
|
+
const [transitions, setTransitions] = React80.useState(resolved?.transitions ?? []);
|
|
44723
44745
|
const [headerError, setHeaderError] = React80.useState(false);
|
|
44724
44746
|
const [playState, setPlayState] = React80.useState("editing");
|
|
44725
|
-
const [currentState, setCurrentState] = React80.useState(
|
|
44747
|
+
const [currentState, setCurrentState] = React80.useState(resolved?.initialState ?? "");
|
|
44726
44748
|
const [selectedState, setSelectedState] = React80.useState(null);
|
|
44727
44749
|
const [testResults, setTestResults] = React80.useState([]);
|
|
44728
|
-
const [variables, setVariables] = React80.useState(
|
|
44750
|
+
const [variables, setVariables] = React80.useState(resolved?.variables ?? []);
|
|
44729
44751
|
const [attempts, setAttempts] = React80.useState(0);
|
|
44730
44752
|
const timerRef = React80.useRef(null);
|
|
44731
44753
|
const [addingFrom, setAddingFrom] = React80.useState(null);
|
|
@@ -44734,12 +44756,12 @@ function StateArchitectBoard({
|
|
|
44734
44756
|
}, []);
|
|
44735
44757
|
const GRAPH_W = 500;
|
|
44736
44758
|
const GRAPH_H = 400;
|
|
44737
|
-
const positions = React80.useMemo(() => layoutStates(
|
|
44759
|
+
const positions = React80.useMemo(() => layoutStates(resolved?.states ?? [], GRAPH_W, GRAPH_H), [resolved?.states]);
|
|
44738
44760
|
const handleStateClick = React80.useCallback((state) => {
|
|
44739
44761
|
if (playState !== "editing") return;
|
|
44740
44762
|
if (addingFrom) {
|
|
44741
44763
|
if (addingFrom !== state) {
|
|
44742
|
-
const event =
|
|
44764
|
+
const event = resolved?.availableEvents[0] || "EVENT";
|
|
44743
44765
|
const newTrans = {
|
|
44744
44766
|
id: `t-${nextTransId++}`,
|
|
44745
44767
|
from: addingFrom,
|
|
@@ -44752,7 +44774,7 @@ function StateArchitectBoard({
|
|
|
44752
44774
|
} else {
|
|
44753
44775
|
setSelectedState(state);
|
|
44754
44776
|
}
|
|
44755
|
-
}, [playState, addingFrom,
|
|
44777
|
+
}, [playState, addingFrom, resolved?.availableEvents]);
|
|
44756
44778
|
const handleStartAddTransition = React80.useCallback(() => {
|
|
44757
44779
|
if (!selectedState) return;
|
|
44758
44780
|
setAddingFrom(selectedState);
|
|
@@ -44761,9 +44783,9 @@ function StateArchitectBoard({
|
|
|
44761
44783
|
setTransitions((prev) => prev.filter((t2) => t2.id !== transId));
|
|
44762
44784
|
}, []);
|
|
44763
44785
|
const machine = React80.useMemo(() => ({
|
|
44764
|
-
name:
|
|
44765
|
-
description:
|
|
44766
|
-
states:
|
|
44786
|
+
name: resolved?.entityName ?? "",
|
|
44787
|
+
description: resolved?.description ?? "",
|
|
44788
|
+
states: resolved?.states ?? [],
|
|
44767
44789
|
currentState,
|
|
44768
44790
|
transitions: transitions.map((t2) => ({
|
|
44769
44791
|
from: t2.from,
|
|
@@ -44771,7 +44793,7 @@ function StateArchitectBoard({
|
|
|
44771
44793
|
event: t2.event,
|
|
44772
44794
|
guardHint: t2.guardHint
|
|
44773
44795
|
}))
|
|
44774
|
-
}), [
|
|
44796
|
+
}), [resolved, currentState, transitions]);
|
|
44775
44797
|
const handleTest = React80.useCallback(() => {
|
|
44776
44798
|
if (playState !== "editing") return;
|
|
44777
44799
|
if (testEvent) emit(`UI:${testEvent}`, {});
|
|
@@ -44780,7 +44802,7 @@ function StateArchitectBoard({
|
|
|
44780
44802
|
const results = [];
|
|
44781
44803
|
let testIdx = 0;
|
|
44782
44804
|
const runNextTest = () => {
|
|
44783
|
-
if (testIdx >=
|
|
44805
|
+
if (testIdx >= (resolved?.testCases.length ?? 0)) {
|
|
44784
44806
|
const allPassed = results.every((r) => r.passed);
|
|
44785
44807
|
setPlayState(allPassed ? "success" : "fail");
|
|
44786
44808
|
setTestResults(results);
|
|
@@ -44795,8 +44817,9 @@ function StateArchitectBoard({
|
|
|
44795
44817
|
}
|
|
44796
44818
|
return;
|
|
44797
44819
|
}
|
|
44798
|
-
const testCase =
|
|
44799
|
-
|
|
44820
|
+
const testCase = resolved?.testCases[testIdx];
|
|
44821
|
+
if (!testCase) return;
|
|
44822
|
+
let state = resolved.initialState;
|
|
44800
44823
|
for (const event of testCase.events) {
|
|
44801
44824
|
const trans = transitions.find((t2) => t2.from === state && t2.event === event);
|
|
44802
44825
|
if (trans) {
|
|
@@ -44814,52 +44837,53 @@ function StateArchitectBoard({
|
|
|
44814
44837
|
timerRef.current = setTimeout(runNextTest, stepDurationMs);
|
|
44815
44838
|
};
|
|
44816
44839
|
timerRef.current = setTimeout(runNextTest, stepDurationMs);
|
|
44817
|
-
}, [playState, transitions,
|
|
44840
|
+
}, [playState, transitions, resolved, stepDurationMs, testEvent, completeEvent, emit]);
|
|
44818
44841
|
const handleTryAgain = React80.useCallback(() => {
|
|
44819
44842
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
44820
44843
|
setPlayState("editing");
|
|
44821
|
-
setCurrentState(
|
|
44844
|
+
setCurrentState(resolved?.initialState ?? "");
|
|
44822
44845
|
setTestResults([]);
|
|
44823
|
-
}, [
|
|
44846
|
+
}, [resolved?.initialState]);
|
|
44824
44847
|
const handleReset = React80.useCallback(() => {
|
|
44825
44848
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
44826
|
-
setTransitions(
|
|
44849
|
+
setTransitions(resolved?.transitions ?? []);
|
|
44827
44850
|
setPlayState("editing");
|
|
44828
|
-
setCurrentState(
|
|
44851
|
+
setCurrentState(resolved?.initialState ?? "");
|
|
44829
44852
|
setTestResults([]);
|
|
44830
|
-
setVariables(
|
|
44853
|
+
setVariables(resolved?.variables ?? []);
|
|
44831
44854
|
setSelectedState(null);
|
|
44832
44855
|
setAddingFrom(null);
|
|
44833
44856
|
setAttempts(0);
|
|
44834
|
-
}, [
|
|
44857
|
+
}, [resolved]);
|
|
44835
44858
|
const codeData = React80.useMemo(() => ({
|
|
44836
|
-
name:
|
|
44837
|
-
states:
|
|
44838
|
-
initialState:
|
|
44859
|
+
name: resolved?.entityName ?? "",
|
|
44860
|
+
states: resolved?.states ?? [],
|
|
44861
|
+
initialState: resolved?.initialState ?? "",
|
|
44839
44862
|
transitions: transitions.map((t2) => ({
|
|
44840
44863
|
from: t2.from,
|
|
44841
44864
|
to: t2.to,
|
|
44842
44865
|
event: t2.event,
|
|
44843
44866
|
...t2.guardHint ? { guard: t2.guardHint } : {}
|
|
44844
44867
|
}))
|
|
44845
|
-
}), [
|
|
44868
|
+
}), [resolved, transitions]);
|
|
44869
|
+
if (!resolved) return null;
|
|
44846
44870
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
44847
44871
|
exports.VStack,
|
|
44848
44872
|
{
|
|
44849
44873
|
className: cn("p-4 gap-6", className),
|
|
44850
44874
|
style: {
|
|
44851
|
-
backgroundImage:
|
|
44875
|
+
backgroundImage: resolved.theme?.background ? `url(${resolved.theme.background})` : void 0,
|
|
44852
44876
|
backgroundSize: "cover",
|
|
44853
44877
|
backgroundPosition: "center"
|
|
44854
44878
|
},
|
|
44855
44879
|
children: [
|
|
44856
|
-
|
|
44880
|
+
resolved.headerImage && !headerError ? /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: resolved.headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : resolved.headerImage && headerError ? /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
44857
44881
|
/* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "xs", children: [
|
|
44858
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "h4", className: "text-foreground", children:
|
|
44859
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body2", className: "text-muted-foreground", children:
|
|
44882
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "h4", className: "text-foreground", children: resolved.title }),
|
|
44883
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body2", className: "text-muted-foreground", children: resolved.description }),
|
|
44860
44884
|
/* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { className: "items-center p-2 rounded bg-warning/10 border border-warning/30", gap: "xs", children: [
|
|
44861
44885
|
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "caption", className: "text-warning font-bold", children: t("game.hint") + ":" }),
|
|
44862
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "caption", className: "text-foreground", children:
|
|
44886
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "caption", className: "text-foreground", children: resolved.hint })
|
|
44863
44887
|
] })
|
|
44864
44888
|
] }),
|
|
44865
44889
|
/* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { className: "flex-wrap items-start", gap: "lg", children: [
|
|
@@ -44907,14 +44931,14 @@ function StateArchitectBoard({
|
|
|
44907
44931
|
]
|
|
44908
44932
|
}
|
|
44909
44933
|
),
|
|
44910
|
-
|
|
44934
|
+
resolved.states.map((state) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
44911
44935
|
StateNode2,
|
|
44912
44936
|
{
|
|
44913
44937
|
name: state,
|
|
44914
44938
|
position: positions[state],
|
|
44915
44939
|
isCurrent: state === currentState,
|
|
44916
44940
|
isSelected: state === selectedState,
|
|
44917
|
-
isInitial: state ===
|
|
44941
|
+
isInitial: state === resolved.initialState,
|
|
44918
44942
|
onClick: () => handleStateClick(state)
|
|
44919
44943
|
},
|
|
44920
44944
|
state
|
|
@@ -44961,7 +44985,7 @@ function StateArchitectBoard({
|
|
|
44961
44985
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
44962
44986
|
VariablePanel,
|
|
44963
44987
|
{
|
|
44964
|
-
entityName:
|
|
44988
|
+
entityName: resolved.entityName,
|
|
44965
44989
|
variables
|
|
44966
44990
|
}
|
|
44967
44991
|
),
|
|
@@ -44973,15 +44997,15 @@ function StateArchitectBoard({
|
|
|
44973
44997
|
!r.passed && /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "caption", className: "text-error", children: t("stateArchitect.gotState", { state: r.actualState }) })
|
|
44974
44998
|
] }, i))
|
|
44975
44999
|
] }),
|
|
44976
|
-
|
|
45000
|
+
resolved.showCodeView !== false && /* @__PURE__ */ jsxRuntime.jsx(CodeView, { data: codeData, label: "View Code" })
|
|
44977
45001
|
] })
|
|
44978
45002
|
] }),
|
|
44979
|
-
playState === "success" && /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "p-4 rounded-container bg-success/20 border border-success text-center", children: /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "h5", className: "text-success", children:
|
|
45003
|
+
playState === "success" && /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "p-4 rounded-container bg-success/20 border border-success text-center", children: /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "h5", className: "text-success", children: resolved.successMessage || t("stateArchitect.allPassed") }) }),
|
|
44980
45004
|
playState === "fail" && /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "sm", children: [
|
|
44981
45005
|
/* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "p-4 rounded-container bg-warning/10 border border-warning/30 text-center", children: /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body1", className: "text-foreground font-medium", children: t(ENCOURAGEMENT_KEYS3[Math.min(attempts - 1, ENCOURAGEMENT_KEYS3.length - 1)] ?? ENCOURAGEMENT_KEYS3[0]) }) }),
|
|
44982
|
-
attempts >= 3 &&
|
|
45006
|
+
attempts >= 3 && resolved.hint && /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "p-3 rounded-container bg-accent/10 border border-accent/30", children: /* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { className: "items-start", gap: "xs", children: [
|
|
44983
45007
|
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body2", className: "text-accent font-bold shrink-0", children: "\u{1F4A1} " + t("game.hint") + ":" }),
|
|
44984
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body2", className: "text-foreground", children:
|
|
45008
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body2", className: "text-foreground", children: resolved.hint })
|
|
44985
45009
|
] }) })
|
|
44986
45010
|
] }),
|
|
44987
45011
|
/* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { gap: "sm", children: [
|
|
@@ -45958,8 +45982,9 @@ var init_useBattleState = __esm({
|
|
|
45958
45982
|
}
|
|
45959
45983
|
});
|
|
45960
45984
|
function UncontrolledBattleBoard({ entity, ...rest }) {
|
|
45985
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
45961
45986
|
const battleState = useBattleState(
|
|
45962
|
-
|
|
45987
|
+
resolved?.initialUnits ?? [],
|
|
45963
45988
|
{
|
|
45964
45989
|
tileClickEvent: rest.tileClickEvent,
|
|
45965
45990
|
unitClickEvent: rest.unitClickEvent,
|
|
@@ -45976,12 +46001,13 @@ function UncontrolledBattleBoard({ entity, ...rest }) {
|
|
|
45976
46001
|
calculateDamage: rest.calculateDamage
|
|
45977
46002
|
}
|
|
45978
46003
|
);
|
|
46004
|
+
if (!resolved) return null;
|
|
45979
46005
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
45980
46006
|
BattleBoard,
|
|
45981
46007
|
{
|
|
45982
46008
|
...rest,
|
|
45983
46009
|
entity: {
|
|
45984
|
-
...
|
|
46010
|
+
...resolved,
|
|
45985
46011
|
units: battleState.units,
|
|
45986
46012
|
phase: battleState.phase,
|
|
45987
46013
|
turn: battleState.turn,
|
|
@@ -46752,6 +46778,7 @@ var init_component_registry_generated = __esm({
|
|
|
46752
46778
|
init_StatsOrganism();
|
|
46753
46779
|
init_StatusDot();
|
|
46754
46780
|
init_StatusEffect();
|
|
46781
|
+
init_StepFlow();
|
|
46755
46782
|
init_StepFlowOrganism();
|
|
46756
46783
|
init_SvgBranch();
|
|
46757
46784
|
init_SvgConnection();
|
|
@@ -47070,6 +47097,7 @@ var init_component_registry_generated = __esm({
|
|
|
47070
47097
|
"StatsOrganism": exports.StatsOrganism,
|
|
47071
47098
|
"StatusDot": exports.StatusDot,
|
|
47072
47099
|
"StatusEffect": StatusEffect,
|
|
47100
|
+
"StepFlow": exports.StepFlow,
|
|
47073
47101
|
"StepFlowOrganism": exports.StepFlowOrganism,
|
|
47074
47102
|
"SvgBranch": exports.SvgBranch,
|
|
47075
47103
|
"SvgConnection": exports.SvgConnection,
|
|
@@ -47797,11 +47825,15 @@ function SlotContentRenderer({
|
|
|
47797
47825
|
}
|
|
47798
47826
|
if (propsSchema) {
|
|
47799
47827
|
for (const [propKey, propDef] of Object.entries(propsSchema)) {
|
|
47800
|
-
const
|
|
47801
|
-
if ((typeof v === "string" || typeof v === "number") && propDef.types?.some(
|
|
47828
|
+
const isDate = propDef.types?.some(
|
|
47802
47829
|
(t) => t === "date" || t === "datetime" || t === "timestamp"
|
|
47803
|
-
)
|
|
47830
|
+
);
|
|
47831
|
+
if (!isDate) continue;
|
|
47832
|
+
const v = renderedProps[propKey];
|
|
47833
|
+
if (typeof v === "string" || typeof v === "number") {
|
|
47804
47834
|
renderedProps[propKey] = new Date(v);
|
|
47835
|
+
} else if (v == null && propDef.required) {
|
|
47836
|
+
renderedProps[propKey] = /* @__PURE__ */ new Date();
|
|
47805
47837
|
}
|
|
47806
47838
|
}
|
|
47807
47839
|
}
|