@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
package/dist/avl/index.js
CHANGED
|
@@ -6467,11 +6467,13 @@ var init_Icon = __esm({
|
|
|
6467
6467
|
strokeWidth,
|
|
6468
6468
|
style
|
|
6469
6469
|
}) => {
|
|
6470
|
+
const directIcon = typeof icon === "string" ? void 0 : icon;
|
|
6471
|
+
const effectiveName = typeof icon === "string" ? icon : name;
|
|
6470
6472
|
const family = useIconFamily();
|
|
6471
6473
|
const RenderedComponent = React98__default.useMemo(() => {
|
|
6472
|
-
if (
|
|
6473
|
-
return
|
|
6474
|
-
}, [
|
|
6474
|
+
if (directIcon) return null;
|
|
6475
|
+
return effectiveName ? resolveIconForFamily(effectiveName, family) : null;
|
|
6476
|
+
}, [directIcon, effectiveName, family]);
|
|
6475
6477
|
const effectiveStrokeWidth = strokeWidth ?? void 0;
|
|
6476
6478
|
const inlineStyle = {
|
|
6477
6479
|
...effectiveStrokeWidth === void 0 ? { strokeWidth: "var(--icon-stroke-width, 2)" } : {},
|
|
@@ -6483,8 +6485,8 @@ var init_Icon = __esm({
|
|
|
6483
6485
|
color ? color : "text-current",
|
|
6484
6486
|
className
|
|
6485
6487
|
);
|
|
6486
|
-
if (
|
|
6487
|
-
const Direct =
|
|
6488
|
+
if (directIcon) {
|
|
6489
|
+
const Direct = directIcon;
|
|
6488
6490
|
return /* @__PURE__ */ jsx(
|
|
6489
6491
|
Direct,
|
|
6490
6492
|
{
|
|
@@ -8196,7 +8198,7 @@ var init_Input = __esm({
|
|
|
8196
8198
|
error,
|
|
8197
8199
|
leftIcon,
|
|
8198
8200
|
rightIcon,
|
|
8199
|
-
icon:
|
|
8201
|
+
icon: iconProp,
|
|
8200
8202
|
clearable,
|
|
8201
8203
|
onClear,
|
|
8202
8204
|
value,
|
|
@@ -8206,6 +8208,7 @@ var init_Input = __esm({
|
|
|
8206
8208
|
...props
|
|
8207
8209
|
}, ref) => {
|
|
8208
8210
|
const type = inputType || htmlType || "text";
|
|
8211
|
+
const IconComponent = typeof iconProp === "string" ? resolveIcon(iconProp) : iconProp;
|
|
8209
8212
|
const resolvedLeftIcon = leftIcon || IconComponent && /* @__PURE__ */ jsx(IconComponent, { className: "h-icon-default w-icon-default" });
|
|
8210
8213
|
const showClearButton = clearable && value && String(value).length > 0;
|
|
8211
8214
|
const isMultiline = type === "textarea";
|
|
@@ -8753,7 +8756,7 @@ var init_Avatar = __esm({
|
|
|
8753
8756
|
alt,
|
|
8754
8757
|
name,
|
|
8755
8758
|
initials: providedInitials,
|
|
8756
|
-
icon:
|
|
8759
|
+
icon: iconProp,
|
|
8757
8760
|
size = "md",
|
|
8758
8761
|
status,
|
|
8759
8762
|
badge,
|
|
@@ -8764,6 +8767,7 @@ var init_Avatar = __esm({
|
|
|
8764
8767
|
}) => {
|
|
8765
8768
|
const eventBus = useEventBus();
|
|
8766
8769
|
const initials = providedInitials ?? (name ? generateInitials(name) : void 0);
|
|
8770
|
+
const IconComponent = typeof iconProp === "string" ? resolveIcon(iconProp) : iconProp;
|
|
8767
8771
|
const hasImage = !!src;
|
|
8768
8772
|
const hasInitials = !!initials;
|
|
8769
8773
|
const hasIcon = !!IconComponent;
|
|
@@ -18751,6 +18755,7 @@ var init_StateMachineView = __esm({
|
|
|
18751
18755
|
setTooltip((prev) => ({ ...prev, pinned: false, visible: false }));
|
|
18752
18756
|
}, []);
|
|
18753
18757
|
useEventListener("UI:TOOLTIP_CLOSE", handleCloseTooltip);
|
|
18758
|
+
if (!layoutData) return null;
|
|
18754
18759
|
const { width, height, title, states, labels, entity, outputs, config } = layoutData;
|
|
18755
18760
|
const bundles = useMemo(() => {
|
|
18756
18761
|
const bundleMap = {};
|
|
@@ -21095,13 +21100,14 @@ function BuilderBoard({
|
|
|
21095
21100
|
}) {
|
|
21096
21101
|
const { emit } = useEventBus();
|
|
21097
21102
|
const { t } = useTranslate();
|
|
21103
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
21098
21104
|
const [placements, setPlacements] = useState({});
|
|
21099
21105
|
const [headerError, setHeaderError] = useState(false);
|
|
21100
21106
|
const [submitted, setSubmitted] = useState(false);
|
|
21101
21107
|
const [attempts, setAttempts] = useState(0);
|
|
21102
21108
|
const [showHint, setShowHint] = useState(false);
|
|
21103
|
-
const components =
|
|
21104
|
-
const slots =
|
|
21109
|
+
const components = resolved?.components ?? [];
|
|
21110
|
+
const slots = resolved?.slots ?? [];
|
|
21105
21111
|
const usedComponentIds = new Set(Object.values(placements));
|
|
21106
21112
|
const availableComponents = components.filter((c) => !usedComponentIds.has(c.id));
|
|
21107
21113
|
const [selectedComponent, setSelectedComponent] = useState(null);
|
|
@@ -21135,7 +21141,7 @@ function BuilderBoard({
|
|
|
21135
21141
|
}, [slots, placements, attempts, completeEvent, emit]);
|
|
21136
21142
|
const handleReset = () => {
|
|
21137
21143
|
setSubmitted(false);
|
|
21138
|
-
if (attempts >= 2 &&
|
|
21144
|
+
if (attempts >= 2 && resolved?.hint) {
|
|
21139
21145
|
setShowHint(true);
|
|
21140
21146
|
}
|
|
21141
21147
|
};
|
|
@@ -21147,20 +21153,21 @@ function BuilderBoard({
|
|
|
21147
21153
|
setShowHint(false);
|
|
21148
21154
|
};
|
|
21149
21155
|
const getComponentById = (id) => components.find((c) => c.id === id);
|
|
21156
|
+
if (!resolved) return null;
|
|
21150
21157
|
return /* @__PURE__ */ jsx(
|
|
21151
21158
|
Box,
|
|
21152
21159
|
{
|
|
21153
21160
|
className,
|
|
21154
21161
|
style: {
|
|
21155
|
-
backgroundImage:
|
|
21162
|
+
backgroundImage: resolved.theme?.background ? `url(${resolved.theme.background})` : void 0,
|
|
21156
21163
|
backgroundSize: "cover",
|
|
21157
21164
|
backgroundPosition: "center"
|
|
21158
21165
|
},
|
|
21159
21166
|
children: /* @__PURE__ */ jsxs(VStack, { gap: "lg", className: "p-4", children: [
|
|
21160
|
-
|
|
21167
|
+
resolved.headerImage && !headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsx("img", { src: resolved.headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : resolved.headerImage && headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
21161
21168
|
/* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
21162
|
-
/* @__PURE__ */ jsx(Typography, { variant: "h4", weight: "bold", children:
|
|
21163
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body", children:
|
|
21169
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h4", weight: "bold", children: resolved.title }),
|
|
21170
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", children: resolved.description })
|
|
21164
21171
|
] }) }),
|
|
21165
21172
|
/* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
21166
21173
|
/* @__PURE__ */ jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: t("builder.components") }),
|
|
@@ -21220,9 +21227,9 @@ function BuilderBoard({
|
|
|
21220
21227
|
] }) }),
|
|
21221
21228
|
submitted && /* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", children: [
|
|
21222
21229
|
/* @__PURE__ */ jsx(Icon, { icon: allCorrect ? CheckCircle : XCircle, size: "lg", className: allCorrect ? "text-success" : "text-error" }),
|
|
21223
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "bold", children: allCorrect ?
|
|
21230
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "bold", children: allCorrect ? resolved.successMessage ?? t("builder.success") : resolved.failMessage ?? t("builder.incorrect") })
|
|
21224
21231
|
] }) }),
|
|
21225
|
-
showHint &&
|
|
21232
|
+
showHint && resolved.hint && /* @__PURE__ */ jsx(Card, { className: "p-4 border-l-4 border-l-warning", children: /* @__PURE__ */ jsx(Typography, { variant: "body", children: resolved.hint }) }),
|
|
21226
21233
|
/* @__PURE__ */ jsxs(HStack, { gap: "sm", justify: "center", children: [
|
|
21227
21234
|
!submitted ? /* @__PURE__ */ jsxs(Button, { variant: "primary", onClick: handleSubmit, disabled: !allPlaced, children: [
|
|
21228
21235
|
/* @__PURE__ */ jsx(Icon, { icon: Wrench, size: "sm" }),
|
|
@@ -23763,11 +23770,12 @@ function CastleBoard({
|
|
|
23763
23770
|
className
|
|
23764
23771
|
}) {
|
|
23765
23772
|
const eventBus = useEventBus();
|
|
23766
|
-
const
|
|
23767
|
-
const
|
|
23768
|
-
const
|
|
23769
|
-
const
|
|
23770
|
-
const
|
|
23773
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
23774
|
+
const tiles = resolved?.tiles ?? [];
|
|
23775
|
+
const features = resolved?.features ?? [];
|
|
23776
|
+
const units = resolved?.units ?? [];
|
|
23777
|
+
const assetManifest = resolved?.assetManifest;
|
|
23778
|
+
const backgroundImage = resolved?.backgroundImage;
|
|
23771
23779
|
const [hoveredTile, setHoveredTile] = useState(null);
|
|
23772
23780
|
const [selectedFeature, setSelectedFeature] = useState(null);
|
|
23773
23781
|
const hoveredFeature = useMemo(() => {
|
|
@@ -24672,13 +24680,14 @@ function ClassifierBoard({
|
|
|
24672
24680
|
}) {
|
|
24673
24681
|
const { emit } = useEventBus();
|
|
24674
24682
|
const { t } = useTranslate();
|
|
24683
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
24675
24684
|
const [assignments, setAssignments] = useState({});
|
|
24676
24685
|
const [headerError, setHeaderError] = useState(false);
|
|
24677
24686
|
const [submitted, setSubmitted] = useState(false);
|
|
24678
24687
|
const [attempts, setAttempts] = useState(0);
|
|
24679
24688
|
const [showHint, setShowHint] = useState(false);
|
|
24680
|
-
const items =
|
|
24681
|
-
const categories =
|
|
24689
|
+
const items = resolved?.items ?? [];
|
|
24690
|
+
const categories = resolved?.categories ?? [];
|
|
24682
24691
|
const unassignedItems = items.filter((item) => !assignments[item.id]);
|
|
24683
24692
|
const allAssigned = Object.keys(assignments).length === items.length;
|
|
24684
24693
|
const results = submitted ? items.map((item) => ({
|
|
@@ -24710,7 +24719,7 @@ function ClassifierBoard({
|
|
|
24710
24719
|
}, [items, assignments, attempts, completeEvent, emit]);
|
|
24711
24720
|
const handleReset = () => {
|
|
24712
24721
|
setSubmitted(false);
|
|
24713
|
-
if (attempts >= 2 &&
|
|
24722
|
+
if (attempts >= 2 && resolved?.hint) {
|
|
24714
24723
|
setShowHint(true);
|
|
24715
24724
|
}
|
|
24716
24725
|
};
|
|
@@ -24720,20 +24729,21 @@ function ClassifierBoard({
|
|
|
24720
24729
|
setAttempts(0);
|
|
24721
24730
|
setShowHint(false);
|
|
24722
24731
|
};
|
|
24732
|
+
if (!resolved) return null;
|
|
24723
24733
|
return /* @__PURE__ */ jsx(
|
|
24724
24734
|
Box,
|
|
24725
24735
|
{
|
|
24726
24736
|
className,
|
|
24727
24737
|
style: {
|
|
24728
|
-
backgroundImage:
|
|
24738
|
+
backgroundImage: resolved.theme?.background ? `url(${resolved.theme.background})` : void 0,
|
|
24729
24739
|
backgroundSize: "cover",
|
|
24730
24740
|
backgroundPosition: "center"
|
|
24731
24741
|
},
|
|
24732
24742
|
children: /* @__PURE__ */ jsxs(VStack, { gap: "lg", className: "p-4", children: [
|
|
24733
|
-
|
|
24743
|
+
resolved.headerImage && !headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsx("img", { src: resolved.headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : resolved.headerImage && headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
24734
24744
|
/* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
24735
|
-
/* @__PURE__ */ jsx(Typography, { variant: "h4", weight: "bold", children:
|
|
24736
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body", children:
|
|
24745
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h4", weight: "bold", children: resolved.title }),
|
|
24746
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", children: resolved.description })
|
|
24737
24747
|
] }) }),
|
|
24738
24748
|
unassignedItems.length > 0 && /* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
24739
24749
|
/* @__PURE__ */ jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: t("classifier.itemsToSort") }),
|
|
@@ -24785,10 +24795,10 @@ function ClassifierBoard({
|
|
|
24785
24795
|
}) }),
|
|
24786
24796
|
submitted && /* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", children: [
|
|
24787
24797
|
/* @__PURE__ */ jsx(Icon, { icon: allCorrect ? CheckCircle : XCircle, size: "lg", className: allCorrect ? "text-success" : "text-error" }),
|
|
24788
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "bold", children: allCorrect ?
|
|
24789
|
-
!allCorrect &&
|
|
24798
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "bold", children: allCorrect ? resolved.successMessage ?? t("classifier.allCorrect") : `${correctCount}/${items.length} ${t("classifier.correct")}` }),
|
|
24799
|
+
!allCorrect && resolved.failMessage && /* @__PURE__ */ jsx(Typography, { variant: "body", className: "text-muted-foreground", children: resolved.failMessage })
|
|
24790
24800
|
] }) }),
|
|
24791
|
-
showHint &&
|
|
24801
|
+
showHint && resolved.hint && /* @__PURE__ */ jsx(Card, { className: "p-4 border-l-4 border-l-warning", children: /* @__PURE__ */ jsx(Typography, { variant: "body", children: resolved.hint }) }),
|
|
24792
24802
|
/* @__PURE__ */ jsxs(HStack, { gap: "sm", justify: "center", children: [
|
|
24793
24803
|
!submitted ? /* @__PURE__ */ jsxs(Button, { variant: "primary", onClick: handleSubmit, disabled: !allAssigned, children: [
|
|
24794
24804
|
/* @__PURE__ */ jsx(Icon, { icon: Send, size: "sm" }),
|
|
@@ -36123,7 +36133,7 @@ var init_OptionConstraintGroup = __esm({
|
|
|
36123
36133
|
title,
|
|
36124
36134
|
description,
|
|
36125
36135
|
options,
|
|
36126
|
-
constraint,
|
|
36136
|
+
constraint = { type: "single" },
|
|
36127
36137
|
selected = [],
|
|
36128
36138
|
onChange,
|
|
36129
36139
|
changeEvent,
|
|
@@ -38858,7 +38868,7 @@ function DataTable({
|
|
|
38858
38868
|
children: /* @__PURE__ */ jsx(
|
|
38859
38869
|
EmptyState,
|
|
38860
38870
|
{
|
|
38861
|
-
icon: emptyIcon,
|
|
38871
|
+
icon: typeof emptyIcon === "string" ? resolveIcon(emptyIcon) : emptyIcon,
|
|
38862
38872
|
title: resolvedEmptyTitle,
|
|
38863
38873
|
description: resolvedEmptyDescription,
|
|
38864
38874
|
actionLabel: emptyAction?.label,
|
|
@@ -38987,6 +38997,7 @@ var init_DataTable = __esm({
|
|
|
38987
38997
|
init_Stack();
|
|
38988
38998
|
init_Typography();
|
|
38989
38999
|
init_molecules();
|
|
39000
|
+
init_Icon();
|
|
38990
39001
|
init_useEventBus();
|
|
38991
39002
|
init_useTranslate();
|
|
38992
39003
|
init_types3();
|
|
@@ -39007,6 +39018,7 @@ function DebuggerBoard({
|
|
|
39007
39018
|
}) {
|
|
39008
39019
|
const { emit } = useEventBus();
|
|
39009
39020
|
const { t } = useTranslate();
|
|
39021
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
39010
39022
|
const [flaggedLines, setFlaggedLines] = useState(/* @__PURE__ */ new Set());
|
|
39011
39023
|
const [headerError, setHeaderError] = useState(false);
|
|
39012
39024
|
const [submitted, setSubmitted] = useState(false);
|
|
@@ -39024,7 +39036,7 @@ function DebuggerBoard({
|
|
|
39024
39036
|
return next;
|
|
39025
39037
|
});
|
|
39026
39038
|
};
|
|
39027
|
-
const lines =
|
|
39039
|
+
const lines = resolved?.lines ?? [];
|
|
39028
39040
|
const bugLines = lines.filter((l) => l.isBug);
|
|
39029
39041
|
const correctFlags = lines.filter((l) => l.isBug && flaggedLines.has(l.id));
|
|
39030
39042
|
const falseFlags = lines.filter((l) => !l.isBug && flaggedLines.has(l.id));
|
|
@@ -39039,7 +39051,7 @@ function DebuggerBoard({
|
|
|
39039
39051
|
}, [correctFlags.length, bugLines.length, falseFlags.length, attempts, completeEvent, emit]);
|
|
39040
39052
|
const handleReset = () => {
|
|
39041
39053
|
setSubmitted(false);
|
|
39042
|
-
if (attempts >= 2 &&
|
|
39054
|
+
if (attempts >= 2 && resolved?.hint) {
|
|
39043
39055
|
setShowHint(true);
|
|
39044
39056
|
}
|
|
39045
39057
|
};
|
|
@@ -39049,24 +39061,25 @@ function DebuggerBoard({
|
|
|
39049
39061
|
setAttempts(0);
|
|
39050
39062
|
setShowHint(false);
|
|
39051
39063
|
};
|
|
39064
|
+
if (!resolved) return null;
|
|
39052
39065
|
return /* @__PURE__ */ jsx(
|
|
39053
39066
|
Box,
|
|
39054
39067
|
{
|
|
39055
39068
|
className,
|
|
39056
39069
|
style: {
|
|
39057
|
-
backgroundImage:
|
|
39070
|
+
backgroundImage: resolved.theme?.background ? `url(${resolved.theme.background})` : void 0,
|
|
39058
39071
|
backgroundSize: "cover",
|
|
39059
39072
|
backgroundPosition: "center"
|
|
39060
39073
|
},
|
|
39061
39074
|
children: /* @__PURE__ */ jsxs(VStack, { gap: "lg", className: "p-4", children: [
|
|
39062
|
-
|
|
39075
|
+
resolved.headerImage && !headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsx("img", { src: resolved.headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : resolved.headerImage && headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
39063
39076
|
/* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
39064
39077
|
/* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
39065
39078
|
/* @__PURE__ */ jsx(Icon, { icon: Bug, size: "sm" }),
|
|
39066
|
-
/* @__PURE__ */ jsx(Typography, { variant: "h4", weight: "bold", children:
|
|
39079
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h4", weight: "bold", children: resolved.title })
|
|
39067
39080
|
] }),
|
|
39068
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body", children:
|
|
39069
|
-
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: t("debugger.findBugs", { count: String(
|
|
39081
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", children: resolved.description }),
|
|
39082
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: t("debugger.findBugs", { count: String(resolved.bugCount) }) })
|
|
39070
39083
|
] }) }),
|
|
39071
39084
|
/* @__PURE__ */ jsx(Card, { className: "p-0 overflow-hidden", children: /* @__PURE__ */ jsx(VStack, { gap: "none", children: lines.map((line, i) => {
|
|
39072
39085
|
const isFlagged = flaggedLines.has(line.id);
|
|
@@ -39098,7 +39111,7 @@ function DebuggerBoard({
|
|
|
39098
39111
|
);
|
|
39099
39112
|
}) }) }),
|
|
39100
39113
|
submitted && /* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
39101
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "bold", children: allCorrect ?
|
|
39114
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "bold", children: allCorrect ? resolved.successMessage ?? t("debugger.allFound") : `${correctFlags.length}/${bugLines.length} ${t("debugger.bugsFound")}` }),
|
|
39102
39115
|
bugLines.map((line) => /* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "start", children: [
|
|
39103
39116
|
/* @__PURE__ */ jsx(
|
|
39104
39117
|
Icon,
|
|
@@ -39114,7 +39127,7 @@ function DebuggerBoard({
|
|
|
39114
39127
|
] })
|
|
39115
39128
|
] }, line.id))
|
|
39116
39129
|
] }) }),
|
|
39117
|
-
showHint &&
|
|
39130
|
+
showHint && resolved.hint && /* @__PURE__ */ jsx(Card, { className: "p-4 border-l-4 border-l-warning", children: /* @__PURE__ */ jsx(Typography, { variant: "body", children: resolved.hint }) }),
|
|
39118
39131
|
/* @__PURE__ */ jsxs(HStack, { gap: "sm", justify: "center", children: [
|
|
39119
39132
|
!submitted ? /* @__PURE__ */ jsxs(Button, { variant: "primary", onClick: handleSubmit, disabled: flaggedLines.size === 0, children: [
|
|
39120
39133
|
/* @__PURE__ */ jsx(Icon, { icon: Send, size: "sm" }),
|
|
@@ -40246,7 +40259,8 @@ function EventHandlerBoard({
|
|
|
40246
40259
|
}) {
|
|
40247
40260
|
const { emit } = useEventBus();
|
|
40248
40261
|
const { t } = useTranslate();
|
|
40249
|
-
const
|
|
40262
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
40263
|
+
const entityObjects = resolved?.objects ?? [];
|
|
40250
40264
|
const [objects, setObjects] = useState(entityObjects);
|
|
40251
40265
|
const [selectedObjectId, setSelectedObjectId] = useState(
|
|
40252
40266
|
entityObjects[0]?.id || null
|
|
@@ -40281,7 +40295,7 @@ function EventHandlerBoard({
|
|
|
40281
40295
|
allRules.push({ object: obj, rule });
|
|
40282
40296
|
});
|
|
40283
40297
|
});
|
|
40284
|
-
const triggers =
|
|
40298
|
+
const triggers = resolved?.triggerEvents || [];
|
|
40285
40299
|
const eventQueue = [...triggers];
|
|
40286
40300
|
const firedEvents = /* @__PURE__ */ new Set();
|
|
40287
40301
|
let stepIdx = 0;
|
|
@@ -40312,12 +40326,12 @@ function EventHandlerBoard({
|
|
|
40312
40326
|
matching.forEach(({ object, rule }) => {
|
|
40313
40327
|
addLogEntry(object.icon, t("eventHandler.heardEvent", { object: object.name, event: currentEvent, action: rule.thenAction }), "done");
|
|
40314
40328
|
eventQueue.push(rule.thenAction);
|
|
40315
|
-
if (rule.thenAction ===
|
|
40329
|
+
if (rule.thenAction === resolved?.goalEvent) {
|
|
40316
40330
|
goalReached = true;
|
|
40317
40331
|
}
|
|
40318
40332
|
});
|
|
40319
40333
|
}
|
|
40320
|
-
if (currentEvent ===
|
|
40334
|
+
if (currentEvent === resolved?.goalEvent) {
|
|
40321
40335
|
goalReached = true;
|
|
40322
40336
|
}
|
|
40323
40337
|
stepIdx++;
|
|
@@ -40327,7 +40341,7 @@ function EventHandlerBoard({
|
|
|
40327
40341
|
addLogEntry("\u{1F3AC}", t("eventHandler.simulationStarted", { events: triggers.join(", ") }), "active");
|
|
40328
40342
|
}
|
|
40329
40343
|
timerRef.current = setTimeout(processNext, stepDurationMs);
|
|
40330
|
-
}, [playState, objects,
|
|
40344
|
+
}, [playState, objects, resolved, stepDurationMs, playEvent, completeEvent, emit, addLogEntry, t]);
|
|
40331
40345
|
const handleTryAgain = useCallback(() => {
|
|
40332
40346
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
40333
40347
|
setPlayState("editing");
|
|
@@ -40335,12 +40349,13 @@ function EventHandlerBoard({
|
|
|
40335
40349
|
}, []);
|
|
40336
40350
|
const handleReset = useCallback(() => {
|
|
40337
40351
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
40338
|
-
setObjects(
|
|
40352
|
+
setObjects(resolved?.objects ?? []);
|
|
40339
40353
|
setPlayState("editing");
|
|
40340
40354
|
setEventLog([]);
|
|
40341
|
-
setSelectedObjectId((
|
|
40355
|
+
setSelectedObjectId((resolved?.objects ?? [])[0]?.id || null);
|
|
40342
40356
|
setAttempts(0);
|
|
40343
|
-
}, [
|
|
40357
|
+
}, [resolved?.objects]);
|
|
40358
|
+
if (!resolved) return null;
|
|
40344
40359
|
const objectViewers = objects.map((obj) => {
|
|
40345
40360
|
const machine = {
|
|
40346
40361
|
name: obj.name,
|
|
@@ -40354,25 +40369,25 @@ function EventHandlerBoard({
|
|
|
40354
40369
|
};
|
|
40355
40370
|
return { obj, machine };
|
|
40356
40371
|
});
|
|
40357
|
-
const showHint = attempts >= 3 &&
|
|
40372
|
+
const showHint = attempts >= 3 && resolved.hint;
|
|
40358
40373
|
const encourageKey = ENCOURAGEMENT_KEYS[Math.min(attempts - 1, ENCOURAGEMENT_KEYS.length - 1)] ?? ENCOURAGEMENT_KEYS[0];
|
|
40359
40374
|
return /* @__PURE__ */ jsxs(
|
|
40360
40375
|
VStack,
|
|
40361
40376
|
{
|
|
40362
40377
|
className: cn("p-4 gap-6", className),
|
|
40363
40378
|
style: {
|
|
40364
|
-
backgroundImage:
|
|
40379
|
+
backgroundImage: resolved.theme?.background ? `url(${resolved.theme.background})` : void 0,
|
|
40365
40380
|
backgroundSize: "cover",
|
|
40366
40381
|
backgroundPosition: "center"
|
|
40367
40382
|
},
|
|
40368
40383
|
children: [
|
|
40369
|
-
|
|
40384
|
+
resolved.headerImage && !headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsx("img", { src: resolved.headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : resolved.headerImage && headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
40370
40385
|
/* @__PURE__ */ jsxs(VStack, { gap: "xs", children: [
|
|
40371
|
-
/* @__PURE__ */ jsx(Typography, { variant: "h4", className: "text-foreground", children:
|
|
40372
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-muted-foreground", children:
|
|
40386
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h4", className: "text-foreground", children: resolved.title }),
|
|
40387
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-muted-foreground", children: resolved.description }),
|
|
40373
40388
|
/* @__PURE__ */ jsxs(HStack, { className: "items-center p-2 rounded bg-primary/10 border border-primary/30", gap: "xs", children: [
|
|
40374
40389
|
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-primary font-bold", children: t("game.goal") + ":" }),
|
|
40375
|
-
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-foreground", children:
|
|
40390
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-foreground", children: resolved.goalCondition })
|
|
40376
40391
|
] })
|
|
40377
40392
|
] }),
|
|
40378
40393
|
/* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
@@ -40403,12 +40418,12 @@ function EventHandlerBoard({
|
|
|
40403
40418
|
}
|
|
40404
40419
|
),
|
|
40405
40420
|
eventLog.length > 0 && /* @__PURE__ */ jsx(EventLog, { entries: eventLog }),
|
|
40406
|
-
playState === "success" && /* @__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:
|
|
40421
|
+
playState === "success" && /* @__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: resolved.successMessage || t("eventHandler.chainComplete") }) }),
|
|
40407
40422
|
playState === "fail" && /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
40408
40423
|
/* @__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) }) }),
|
|
40409
40424
|
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: [
|
|
40410
40425
|
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-accent font-bold shrink-0", children: "\u{1F4A1} " + t("game.hint") + ":" }),
|
|
40411
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-foreground", children:
|
|
40426
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-foreground", children: resolved.hint })
|
|
40412
40427
|
] }) })
|
|
40413
40428
|
] }),
|
|
40414
40429
|
/* @__PURE__ */ jsxs(HStack, { gap: "sm", children: [
|
|
@@ -43529,19 +43544,20 @@ function NegotiatorBoard({
|
|
|
43529
43544
|
}) {
|
|
43530
43545
|
const { emit } = useEventBus();
|
|
43531
43546
|
const { t } = useTranslate();
|
|
43547
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
43532
43548
|
const [history, setHistory] = useState([]);
|
|
43533
43549
|
const [headerError, setHeaderError] = useState(false);
|
|
43534
43550
|
const [showHint, setShowHint] = useState(false);
|
|
43535
43551
|
const currentRound = history.length;
|
|
43536
|
-
const isComplete = currentRound >=
|
|
43552
|
+
const isComplete = currentRound >= (resolved?.totalRounds ?? 0);
|
|
43537
43553
|
const playerTotal = history.reduce((s, r2) => s + r2.playerPayoff, 0);
|
|
43538
43554
|
const opponentTotal = history.reduce((s, r2) => s + r2.opponentPayoff, 0);
|
|
43539
|
-
const won = isComplete && playerTotal >=
|
|
43540
|
-
const actions =
|
|
43541
|
-
const payoffMatrix =
|
|
43555
|
+
const won = isComplete && playerTotal >= (resolved?.targetScore ?? 0);
|
|
43556
|
+
const actions = resolved?.actions ?? [];
|
|
43557
|
+
const payoffMatrix = resolved?.payoffMatrix ?? [];
|
|
43542
43558
|
const handleAction = useCallback((actionId) => {
|
|
43543
43559
|
if (isComplete) return;
|
|
43544
|
-
const opponentAction = getOpponentAction(
|
|
43560
|
+
const opponentAction = getOpponentAction(resolved?.opponentStrategy ?? "random", actions, history);
|
|
43545
43561
|
const payoff = payoffMatrix.find(
|
|
43546
43562
|
(p2) => p2.playerAction === actionId && p2.opponentAction === opponentAction
|
|
43547
43563
|
);
|
|
@@ -43554,41 +43570,42 @@ function NegotiatorBoard({
|
|
|
43554
43570
|
};
|
|
43555
43571
|
const newHistory = [...history, result];
|
|
43556
43572
|
setHistory(newHistory);
|
|
43557
|
-
if (newHistory.length >=
|
|
43573
|
+
if (newHistory.length >= (resolved?.totalRounds ?? 0)) {
|
|
43558
43574
|
const total = newHistory.reduce((s, r2) => s + r2.playerPayoff, 0);
|
|
43559
|
-
if (total >=
|
|
43575
|
+
if (total >= (resolved?.targetScore ?? 0)) {
|
|
43560
43576
|
emit(`UI:${completeEvent}`, { success: true, score: total });
|
|
43561
43577
|
}
|
|
43562
|
-
if (newHistory.length >= 3 &&
|
|
43578
|
+
if (newHistory.length >= 3 && resolved?.hint) {
|
|
43563
43579
|
setShowHint(true);
|
|
43564
43580
|
}
|
|
43565
43581
|
}
|
|
43566
|
-
}, [isComplete,
|
|
43582
|
+
}, [isComplete, resolved, actions, payoffMatrix, history, currentRound, completeEvent, emit]);
|
|
43567
43583
|
const handleReset = () => {
|
|
43568
43584
|
setHistory([]);
|
|
43569
43585
|
setShowHint(false);
|
|
43570
43586
|
};
|
|
43571
43587
|
const getActionLabel = (id) => actions.find((a) => a.id === id)?.label ?? id;
|
|
43588
|
+
if (!resolved) return null;
|
|
43572
43589
|
return /* @__PURE__ */ jsx(
|
|
43573
43590
|
Box,
|
|
43574
43591
|
{
|
|
43575
43592
|
className,
|
|
43576
43593
|
style: {
|
|
43577
|
-
backgroundImage:
|
|
43594
|
+
backgroundImage: resolved.theme?.background ? `url(${resolved.theme.background})` : void 0,
|
|
43578
43595
|
backgroundSize: "cover",
|
|
43579
43596
|
backgroundPosition: "center"
|
|
43580
43597
|
},
|
|
43581
43598
|
children: /* @__PURE__ */ jsxs(VStack, { gap: "lg", className: "p-4", children: [
|
|
43582
|
-
|
|
43599
|
+
resolved.headerImage && !headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsx("img", { src: resolved.headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : resolved.headerImage && headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
43583
43600
|
/* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
43584
|
-
/* @__PURE__ */ jsx(Typography, { variant: "h4", weight: "bold", children:
|
|
43585
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body", children:
|
|
43601
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h4", weight: "bold", children: resolved.title }),
|
|
43602
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", children: resolved.description }),
|
|
43586
43603
|
/* @__PURE__ */ jsxs(HStack, { gap: "md", children: [
|
|
43587
|
-
/* @__PURE__ */ jsx(Badge, { size: "sm", children: t("negotiator.round", { current: String(currentRound), total: String(
|
|
43604
|
+
/* @__PURE__ */ jsx(Badge, { size: "sm", children: t("negotiator.round", { current: String(currentRound), total: String(resolved.totalRounds) }) }),
|
|
43588
43605
|
/* @__PURE__ */ jsxs(Badge, { size: "sm", children: [
|
|
43589
43606
|
t("negotiator.target"),
|
|
43590
43607
|
": ",
|
|
43591
|
-
|
|
43608
|
+
resolved.targetScore
|
|
43592
43609
|
] })
|
|
43593
43610
|
] })
|
|
43594
43611
|
] }) }),
|
|
@@ -43637,16 +43654,16 @@ function NegotiatorBoard({
|
|
|
43637
43654
|
] }) }),
|
|
43638
43655
|
isComplete && /* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", children: [
|
|
43639
43656
|
/* @__PURE__ */ jsx(Icon, { icon: CheckCircle, size: "lg", className: won ? "text-success" : "text-error" }),
|
|
43640
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "bold", children: won ?
|
|
43657
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "bold", children: won ? resolved.successMessage ?? t("negotiator.success") : resolved.failMessage ?? t("negotiator.failed") }),
|
|
43641
43658
|
/* @__PURE__ */ jsxs(Typography, { variant: "caption", className: "text-muted-foreground", children: [
|
|
43642
43659
|
t("negotiator.finalScore"),
|
|
43643
43660
|
": ",
|
|
43644
43661
|
playerTotal,
|
|
43645
43662
|
"/",
|
|
43646
|
-
|
|
43663
|
+
resolved.targetScore
|
|
43647
43664
|
] })
|
|
43648
43665
|
] }) }),
|
|
43649
|
-
showHint &&
|
|
43666
|
+
showHint && resolved.hint && !won && /* @__PURE__ */ jsx(Card, { className: "p-4 border-l-4 border-l-warning", children: /* @__PURE__ */ jsx(Typography, { variant: "body", children: resolved.hint }) }),
|
|
43650
43667
|
isComplete && !won && /* @__PURE__ */ jsx(HStack, { justify: "center", children: /* @__PURE__ */ jsx(Button, { variant: "primary", onClick: handleReset, children: t("negotiator.playAgain") }) })
|
|
43651
43668
|
] })
|
|
43652
43669
|
}
|
|
@@ -46439,15 +46456,16 @@ function SequencerBoard({
|
|
|
46439
46456
|
}) {
|
|
46440
46457
|
const { emit } = useEventBus();
|
|
46441
46458
|
const { t } = useTranslate();
|
|
46459
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
46442
46460
|
const [headerError, setHeaderError] = useState(false);
|
|
46443
46461
|
const [slots, setSlots] = useState(
|
|
46444
|
-
() => Array.from({ length:
|
|
46462
|
+
() => Array.from({ length: resolved?.maxSlots ?? 0 }, () => void 0)
|
|
46445
46463
|
);
|
|
46446
46464
|
const [playState, setPlayState] = useState("idle");
|
|
46447
46465
|
const [currentStep, setCurrentStep] = useState(-1);
|
|
46448
46466
|
const [attempts, setAttempts] = useState(0);
|
|
46449
46467
|
const [slotFeedback, setSlotFeedback] = useState(
|
|
46450
|
-
() => Array.from({ length:
|
|
46468
|
+
() => Array.from({ length: resolved?.maxSlots ?? 0 }, () => null)
|
|
46451
46469
|
);
|
|
46452
46470
|
const timerRef = useRef(null);
|
|
46453
46471
|
useEffect(() => () => {
|
|
@@ -46481,17 +46499,17 @@ function SequencerBoard({
|
|
|
46481
46499
|
}, [emit]);
|
|
46482
46500
|
const handleReset = useCallback(() => {
|
|
46483
46501
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
46484
|
-
setSlots(Array.from({ length:
|
|
46502
|
+
setSlots(Array.from({ length: resolved?.maxSlots ?? 0 }, () => void 0));
|
|
46485
46503
|
setPlayState("idle");
|
|
46486
46504
|
setCurrentStep(-1);
|
|
46487
46505
|
setAttempts(0);
|
|
46488
|
-
setSlotFeedback(Array.from({ length:
|
|
46489
|
-
}, [
|
|
46506
|
+
setSlotFeedback(Array.from({ length: resolved?.maxSlots ?? 0 }, () => null));
|
|
46507
|
+
}, [resolved?.maxSlots]);
|
|
46490
46508
|
const filledSlots = slots.filter((s) => !!s);
|
|
46491
46509
|
const canPlay = filledSlots.length > 0 && playState === "idle";
|
|
46492
46510
|
const handlePlay = useCallback(() => {
|
|
46493
46511
|
if (!canPlay) return;
|
|
46494
|
-
setSlotFeedback(Array.from({ length:
|
|
46512
|
+
setSlotFeedback(Array.from({ length: resolved?.maxSlots ?? 0 }, () => null));
|
|
46495
46513
|
emit("UI:PLAY_SOUND", { key: "confirm" });
|
|
46496
46514
|
const sequence = slots.map((s) => s?.id || "");
|
|
46497
46515
|
if (playEvent) {
|
|
@@ -46502,10 +46520,10 @@ function SequencerBoard({
|
|
|
46502
46520
|
let step = 0;
|
|
46503
46521
|
const advance = () => {
|
|
46504
46522
|
step++;
|
|
46505
|
-
if (step >=
|
|
46523
|
+
if (step >= (resolved?.maxSlots ?? 0)) {
|
|
46506
46524
|
const playerSeq = slots.map((s) => s?.id);
|
|
46507
46525
|
const playerIds = slots.filter(Boolean).map((s) => s?.id || "");
|
|
46508
|
-
const success =
|
|
46526
|
+
const success = (resolved?.solutions ?? []).some(
|
|
46509
46527
|
(sol) => sol.length === playerIds.length && sol.every((id, i) => id === playerIds[i])
|
|
46510
46528
|
);
|
|
46511
46529
|
if (success) {
|
|
@@ -46517,7 +46535,7 @@ function SequencerBoard({
|
|
|
46517
46535
|
}
|
|
46518
46536
|
} else {
|
|
46519
46537
|
setAttempts((prev) => prev + 1);
|
|
46520
|
-
const feedback = computeSlotFeedback(playerSeq,
|
|
46538
|
+
const feedback = computeSlotFeedback(playerSeq, resolved?.solutions ?? []);
|
|
46521
46539
|
setSlotFeedback(feedback);
|
|
46522
46540
|
setPlayState("idle");
|
|
46523
46541
|
setCurrentStep(-1);
|
|
@@ -46535,10 +46553,10 @@ function SequencerBoard({
|
|
|
46535
46553
|
}
|
|
46536
46554
|
};
|
|
46537
46555
|
timerRef.current = setTimeout(advance, stepDurationMs);
|
|
46538
|
-
}, [canPlay, slots,
|
|
46556
|
+
}, [canPlay, slots, resolved?.maxSlots, resolved?.solutions, stepDurationMs, playEvent, completeEvent, emit]);
|
|
46539
46557
|
const machine = {
|
|
46540
|
-
name:
|
|
46541
|
-
description:
|
|
46558
|
+
name: resolved?.title ?? "",
|
|
46559
|
+
description: resolved?.description ?? "",
|
|
46542
46560
|
states: slots.map((s, i) => stepLabel(s, i)),
|
|
46543
46561
|
currentState: currentStep >= 0 ? stepLabel(slots[currentStep], currentStep) : "__idle__",
|
|
46544
46562
|
transitions: slots.slice(0, -1).map((s, i) => ({
|
|
@@ -46547,36 +46565,37 @@ function SequencerBoard({
|
|
|
46547
46565
|
event: "NEXT"
|
|
46548
46566
|
}))
|
|
46549
46567
|
};
|
|
46550
|
-
const usedIds =
|
|
46551
|
-
const showHint = attempts >= 3 && !!
|
|
46568
|
+
const usedIds = resolved?.allowDuplicates === false ? slots.filter(Boolean).map((s) => s?.id || "") : [];
|
|
46569
|
+
const showHint = attempts >= 3 && !!resolved?.hint;
|
|
46552
46570
|
const hasFeedback = slotFeedback.some((f3) => f3 !== null);
|
|
46553
46571
|
const correctCount = slotFeedback.filter((f3) => f3 === "correct").length;
|
|
46554
46572
|
const encourageKey = ENCOURAGEMENT_KEYS2[Math.min(attempts - 1, ENCOURAGEMENT_KEYS2.length - 1)] ?? ENCOURAGEMENT_KEYS2[0];
|
|
46573
|
+
if (!resolved) return null;
|
|
46555
46574
|
return /* @__PURE__ */ jsxs(
|
|
46556
46575
|
VStack,
|
|
46557
46576
|
{
|
|
46558
46577
|
className: cn("p-4 gap-6", className),
|
|
46559
46578
|
style: {
|
|
46560
|
-
backgroundImage:
|
|
46579
|
+
backgroundImage: resolved.theme?.background ? `url(${resolved.theme.background})` : void 0,
|
|
46561
46580
|
backgroundSize: "cover",
|
|
46562
46581
|
backgroundPosition: "center"
|
|
46563
46582
|
},
|
|
46564
46583
|
children: [
|
|
46565
|
-
|
|
46584
|
+
resolved.headerImage && !headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsx("img", { src: resolved.headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : resolved.headerImage && headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
46566
46585
|
/* @__PURE__ */ jsxs(VStack, { gap: "xs", children: [
|
|
46567
|
-
/* @__PURE__ */ jsx(Typography, { variant: "h4", className: "text-foreground", children:
|
|
46568
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-muted-foreground", children:
|
|
46586
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h4", className: "text-foreground", children: resolved.title }),
|
|
46587
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-muted-foreground", children: resolved.description })
|
|
46569
46588
|
] }),
|
|
46570
46589
|
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: [
|
|
46571
46590
|
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-accent font-bold shrink-0", children: "\u{1F4A1} " + t("game.hint") + ":" }),
|
|
46572
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-foreground", children:
|
|
46591
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-foreground", children: resolved.hint })
|
|
46573
46592
|
] }) }),
|
|
46574
46593
|
filledSlots.length > 0 && /* @__PURE__ */ jsx(TraitStateViewer, { trait: machine, variant: "linear", size: "md" }),
|
|
46575
46594
|
/* @__PURE__ */ jsxs(VStack, { gap: "xs", children: [
|
|
46576
46595
|
/* @__PURE__ */ jsxs(HStack, { className: "items-center justify-between", children: [
|
|
46577
46596
|
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-muted-foreground font-medium", children: t("sequencer.yourSequence") + ":" }),
|
|
46578
46597
|
hasFeedback && playState === "idle" && /* @__PURE__ */ jsxs(Typography, { variant: "caption", className: "text-muted-foreground", children: [
|
|
46579
|
-
`${correctCount}/${
|
|
46598
|
+
`${correctCount}/${resolved.maxSlots} `,
|
|
46580
46599
|
"\u2705"
|
|
46581
46600
|
] })
|
|
46582
46601
|
] }),
|
|
@@ -46584,7 +46603,7 @@ function SequencerBoard({
|
|
|
46584
46603
|
SequenceBar,
|
|
46585
46604
|
{
|
|
46586
46605
|
slots,
|
|
46587
|
-
maxSlots:
|
|
46606
|
+
maxSlots: resolved.maxSlots,
|
|
46588
46607
|
onSlotDrop: handleSlotDrop,
|
|
46589
46608
|
onSlotRemove: handleSlotRemove,
|
|
46590
46609
|
playing: playState === "playing",
|
|
@@ -46598,15 +46617,15 @@ function SequencerBoard({
|
|
|
46598
46617
|
playState !== "playing" && /* @__PURE__ */ jsx(
|
|
46599
46618
|
ActionPalette,
|
|
46600
46619
|
{
|
|
46601
|
-
actions:
|
|
46620
|
+
actions: resolved.availableActions,
|
|
46602
46621
|
usedActionIds: usedIds,
|
|
46603
|
-
allowDuplicates:
|
|
46622
|
+
allowDuplicates: resolved.allowDuplicates !== false,
|
|
46604
46623
|
categoryColors,
|
|
46605
46624
|
label: t("sequencer.dragActions")
|
|
46606
46625
|
}
|
|
46607
46626
|
),
|
|
46608
46627
|
hasFeedback && playState === "idle" && 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) }) }),
|
|
46609
|
-
playState === "success" && /* @__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:
|
|
46628
|
+
playState === "success" && /* @__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: resolved.successMessage || t("sequencer.levelComplete") }) }),
|
|
46610
46629
|
/* @__PURE__ */ jsxs(HStack, { gap: "sm", children: [
|
|
46611
46630
|
/* @__PURE__ */ jsx(
|
|
46612
46631
|
Button,
|
|
@@ -47429,7 +47448,8 @@ function SimulatorBoard({
|
|
|
47429
47448
|
}) {
|
|
47430
47449
|
const { emit } = useEventBus();
|
|
47431
47450
|
const { t } = useTranslate();
|
|
47432
|
-
const
|
|
47451
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
47452
|
+
const parameters = resolved?.parameters ?? [];
|
|
47433
47453
|
const [values, setValues] = useState(() => {
|
|
47434
47454
|
const init = {};
|
|
47435
47455
|
for (const p2 of parameters) {
|
|
@@ -47443,15 +47463,15 @@ function SimulatorBoard({
|
|
|
47443
47463
|
const [showHint, setShowHint] = useState(false);
|
|
47444
47464
|
const computeOutput = useCallback((params) => {
|
|
47445
47465
|
try {
|
|
47446
|
-
const fn = new Function("params", `return (${
|
|
47466
|
+
const fn = new Function("params", `return (${resolved?.computeExpression})`);
|
|
47447
47467
|
return fn(params);
|
|
47448
47468
|
} catch {
|
|
47449
47469
|
return 0;
|
|
47450
47470
|
}
|
|
47451
|
-
}, [
|
|
47471
|
+
}, [resolved?.computeExpression]);
|
|
47452
47472
|
const output = useMemo(() => computeOutput(values) ?? 0, [computeOutput, values]);
|
|
47453
|
-
const targetValue =
|
|
47454
|
-
const targetTolerance =
|
|
47473
|
+
const targetValue = resolved?.targetValue ?? 0;
|
|
47474
|
+
const targetTolerance = resolved?.targetTolerance ?? 0;
|
|
47455
47475
|
const isCorrect = Math.abs(output - targetValue) <= targetTolerance;
|
|
47456
47476
|
const handleParameterChange = (id, value) => {
|
|
47457
47477
|
if (submitted) return;
|
|
@@ -47466,7 +47486,7 @@ function SimulatorBoard({
|
|
|
47466
47486
|
};
|
|
47467
47487
|
const handleReset = () => {
|
|
47468
47488
|
setSubmitted(false);
|
|
47469
|
-
if (attempts >= 2 &&
|
|
47489
|
+
if (attempts >= 2 && resolved?.hint) {
|
|
47470
47490
|
setShowHint(true);
|
|
47471
47491
|
}
|
|
47472
47492
|
};
|
|
@@ -47480,20 +47500,21 @@ function SimulatorBoard({
|
|
|
47480
47500
|
setAttempts(0);
|
|
47481
47501
|
setShowHint(false);
|
|
47482
47502
|
};
|
|
47503
|
+
if (!resolved) return null;
|
|
47483
47504
|
return /* @__PURE__ */ jsx(
|
|
47484
47505
|
Box,
|
|
47485
47506
|
{
|
|
47486
47507
|
className,
|
|
47487
47508
|
style: {
|
|
47488
|
-
backgroundImage:
|
|
47509
|
+
backgroundImage: resolved.theme?.background ? `url(${resolved.theme.background})` : void 0,
|
|
47489
47510
|
backgroundSize: "cover",
|
|
47490
47511
|
backgroundPosition: "center"
|
|
47491
47512
|
},
|
|
47492
47513
|
children: /* @__PURE__ */ jsxs(VStack, { gap: "lg", className: "p-4", children: [
|
|
47493
|
-
|
|
47514
|
+
resolved.headerImage && !headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsx("img", { src: resolved.headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : resolved.headerImage && headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
47494
47515
|
/* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
47495
|
-
/* @__PURE__ */ jsx(Typography, { variant: "h4", weight: "bold", children:
|
|
47496
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body", children:
|
|
47516
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h4", weight: "bold", children: resolved.title }),
|
|
47517
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", children: resolved.description })
|
|
47497
47518
|
] }) }),
|
|
47498
47519
|
/* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "md", children: [
|
|
47499
47520
|
/* @__PURE__ */ jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: t("simulator.parameters") }),
|
|
@@ -47534,28 +47555,28 @@ function SimulatorBoard({
|
|
|
47534
47555
|
] }, param.id))
|
|
47535
47556
|
] }) }),
|
|
47536
47557
|
/* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", children: [
|
|
47537
|
-
/* @__PURE__ */ jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children:
|
|
47558
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: resolved.outputLabel }),
|
|
47538
47559
|
/* @__PURE__ */ jsxs(Typography, { variant: "h3", weight: "bold", children: [
|
|
47539
47560
|
output.toFixed(2),
|
|
47540
47561
|
" ",
|
|
47541
|
-
|
|
47562
|
+
resolved.outputUnit
|
|
47542
47563
|
] }),
|
|
47543
47564
|
submitted && /* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
47544
47565
|
/* @__PURE__ */ jsx(Icon, { icon: isCorrect ? CheckCircle : XCircle, size: "sm", className: isCorrect ? "text-success" : "text-error" }),
|
|
47545
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body", className: isCorrect ? "text-success" : "text-error", children: isCorrect ?
|
|
47566
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", className: isCorrect ? "text-success" : "text-error", children: isCorrect ? resolved.successMessage ?? t("simulator.correct") : resolved.failMessage ?? t("simulator.incorrect") })
|
|
47546
47567
|
] }),
|
|
47547
47568
|
/* @__PURE__ */ jsxs(Typography, { variant: "caption", className: "text-muted-foreground", children: [
|
|
47548
47569
|
t("simulator.target"),
|
|
47549
47570
|
": ",
|
|
47550
47571
|
targetValue,
|
|
47551
47572
|
" ",
|
|
47552
|
-
|
|
47573
|
+
resolved.outputUnit,
|
|
47553
47574
|
" (\xB1",
|
|
47554
47575
|
targetTolerance,
|
|
47555
47576
|
")"
|
|
47556
47577
|
] })
|
|
47557
47578
|
] }) }),
|
|
47558
|
-
showHint &&
|
|
47579
|
+
showHint && resolved.hint && /* @__PURE__ */ jsx(Card, { className: "p-4 border-l-4 border-l-warning", children: /* @__PURE__ */ jsx(Typography, { variant: "body", children: resolved.hint }) }),
|
|
47559
47580
|
/* @__PURE__ */ jsxs(HStack, { gap: "sm", justify: "center", children: [
|
|
47560
47581
|
!submitted ? /* @__PURE__ */ jsxs(Button, { variant: "primary", onClick: handleSubmit, children: [
|
|
47561
47582
|
/* @__PURE__ */ jsx(Icon, { icon: Play, size: "sm" }),
|
|
@@ -48135,13 +48156,14 @@ function StateArchitectBoard({
|
|
|
48135
48156
|
}) {
|
|
48136
48157
|
const { emit } = useEventBus();
|
|
48137
48158
|
const { t } = useTranslate();
|
|
48138
|
-
const
|
|
48159
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
48160
|
+
const [transitions, setTransitions] = useState(resolved?.transitions ?? []);
|
|
48139
48161
|
const [headerError, setHeaderError] = useState(false);
|
|
48140
48162
|
const [playState, setPlayState] = useState("editing");
|
|
48141
|
-
const [currentState, setCurrentState] = useState(
|
|
48163
|
+
const [currentState, setCurrentState] = useState(resolved?.initialState ?? "");
|
|
48142
48164
|
const [selectedState, setSelectedState] = useState(null);
|
|
48143
48165
|
const [testResults, setTestResults] = useState([]);
|
|
48144
|
-
const [variables, setVariables] = useState(
|
|
48166
|
+
const [variables, setVariables] = useState(resolved?.variables ?? []);
|
|
48145
48167
|
const [attempts, setAttempts] = useState(0);
|
|
48146
48168
|
const timerRef = useRef(null);
|
|
48147
48169
|
const [addingFrom, setAddingFrom] = useState(null);
|
|
@@ -48150,12 +48172,12 @@ function StateArchitectBoard({
|
|
|
48150
48172
|
}, []);
|
|
48151
48173
|
const GRAPH_W = 500;
|
|
48152
48174
|
const GRAPH_H = 400;
|
|
48153
|
-
const positions = useMemo(() => layoutStates(
|
|
48175
|
+
const positions = useMemo(() => layoutStates(resolved?.states ?? [], GRAPH_W, GRAPH_H), [resolved?.states]);
|
|
48154
48176
|
const handleStateClick = useCallback((state) => {
|
|
48155
48177
|
if (playState !== "editing") return;
|
|
48156
48178
|
if (addingFrom) {
|
|
48157
48179
|
if (addingFrom !== state) {
|
|
48158
|
-
const event =
|
|
48180
|
+
const event = resolved?.availableEvents[0] || "EVENT";
|
|
48159
48181
|
const newTrans = {
|
|
48160
48182
|
id: `t-${nextTransId++}`,
|
|
48161
48183
|
from: addingFrom,
|
|
@@ -48168,7 +48190,7 @@ function StateArchitectBoard({
|
|
|
48168
48190
|
} else {
|
|
48169
48191
|
setSelectedState(state);
|
|
48170
48192
|
}
|
|
48171
|
-
}, [playState, addingFrom,
|
|
48193
|
+
}, [playState, addingFrom, resolved?.availableEvents]);
|
|
48172
48194
|
const handleStartAddTransition = useCallback(() => {
|
|
48173
48195
|
if (!selectedState) return;
|
|
48174
48196
|
setAddingFrom(selectedState);
|
|
@@ -48177,9 +48199,9 @@ function StateArchitectBoard({
|
|
|
48177
48199
|
setTransitions((prev) => prev.filter((t2) => t2.id !== transId));
|
|
48178
48200
|
}, []);
|
|
48179
48201
|
const machine = useMemo(() => ({
|
|
48180
|
-
name:
|
|
48181
|
-
description:
|
|
48182
|
-
states:
|
|
48202
|
+
name: resolved?.entityName ?? "",
|
|
48203
|
+
description: resolved?.description ?? "",
|
|
48204
|
+
states: resolved?.states ?? [],
|
|
48183
48205
|
currentState,
|
|
48184
48206
|
transitions: transitions.map((t2) => ({
|
|
48185
48207
|
from: t2.from,
|
|
@@ -48187,7 +48209,7 @@ function StateArchitectBoard({
|
|
|
48187
48209
|
event: t2.event,
|
|
48188
48210
|
guardHint: t2.guardHint
|
|
48189
48211
|
}))
|
|
48190
|
-
}), [
|
|
48212
|
+
}), [resolved, currentState, transitions]);
|
|
48191
48213
|
const handleTest = useCallback(() => {
|
|
48192
48214
|
if (playState !== "editing") return;
|
|
48193
48215
|
if (testEvent) emit(`UI:${testEvent}`, {});
|
|
@@ -48196,7 +48218,7 @@ function StateArchitectBoard({
|
|
|
48196
48218
|
const results = [];
|
|
48197
48219
|
let testIdx = 0;
|
|
48198
48220
|
const runNextTest = () => {
|
|
48199
|
-
if (testIdx >=
|
|
48221
|
+
if (testIdx >= (resolved?.testCases.length ?? 0)) {
|
|
48200
48222
|
const allPassed = results.every((r2) => r2.passed);
|
|
48201
48223
|
setPlayState(allPassed ? "success" : "fail");
|
|
48202
48224
|
setTestResults(results);
|
|
@@ -48211,8 +48233,9 @@ function StateArchitectBoard({
|
|
|
48211
48233
|
}
|
|
48212
48234
|
return;
|
|
48213
48235
|
}
|
|
48214
|
-
const testCase =
|
|
48215
|
-
|
|
48236
|
+
const testCase = resolved?.testCases[testIdx];
|
|
48237
|
+
if (!testCase) return;
|
|
48238
|
+
let state = resolved.initialState;
|
|
48216
48239
|
for (const event of testCase.events) {
|
|
48217
48240
|
const trans = transitions.find((t2) => t2.from === state && t2.event === event);
|
|
48218
48241
|
if (trans) {
|
|
@@ -48230,52 +48253,53 @@ function StateArchitectBoard({
|
|
|
48230
48253
|
timerRef.current = setTimeout(runNextTest, stepDurationMs);
|
|
48231
48254
|
};
|
|
48232
48255
|
timerRef.current = setTimeout(runNextTest, stepDurationMs);
|
|
48233
|
-
}, [playState, transitions,
|
|
48256
|
+
}, [playState, transitions, resolved, stepDurationMs, testEvent, completeEvent, emit]);
|
|
48234
48257
|
const handleTryAgain = useCallback(() => {
|
|
48235
48258
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
48236
48259
|
setPlayState("editing");
|
|
48237
|
-
setCurrentState(
|
|
48260
|
+
setCurrentState(resolved?.initialState ?? "");
|
|
48238
48261
|
setTestResults([]);
|
|
48239
|
-
}, [
|
|
48262
|
+
}, [resolved?.initialState]);
|
|
48240
48263
|
const handleReset = useCallback(() => {
|
|
48241
48264
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
48242
|
-
setTransitions(
|
|
48265
|
+
setTransitions(resolved?.transitions ?? []);
|
|
48243
48266
|
setPlayState("editing");
|
|
48244
|
-
setCurrentState(
|
|
48267
|
+
setCurrentState(resolved?.initialState ?? "");
|
|
48245
48268
|
setTestResults([]);
|
|
48246
|
-
setVariables(
|
|
48269
|
+
setVariables(resolved?.variables ?? []);
|
|
48247
48270
|
setSelectedState(null);
|
|
48248
48271
|
setAddingFrom(null);
|
|
48249
48272
|
setAttempts(0);
|
|
48250
|
-
}, [
|
|
48273
|
+
}, [resolved]);
|
|
48251
48274
|
const codeData = useMemo(() => ({
|
|
48252
|
-
name:
|
|
48253
|
-
states:
|
|
48254
|
-
initialState:
|
|
48275
|
+
name: resolved?.entityName ?? "",
|
|
48276
|
+
states: resolved?.states ?? [],
|
|
48277
|
+
initialState: resolved?.initialState ?? "",
|
|
48255
48278
|
transitions: transitions.map((t2) => ({
|
|
48256
48279
|
from: t2.from,
|
|
48257
48280
|
to: t2.to,
|
|
48258
48281
|
event: t2.event,
|
|
48259
48282
|
...t2.guardHint ? { guard: t2.guardHint } : {}
|
|
48260
48283
|
}))
|
|
48261
|
-
}), [
|
|
48284
|
+
}), [resolved, transitions]);
|
|
48285
|
+
if (!resolved) return null;
|
|
48262
48286
|
return /* @__PURE__ */ jsxs(
|
|
48263
48287
|
VStack,
|
|
48264
48288
|
{
|
|
48265
48289
|
className: cn("p-4 gap-6", className),
|
|
48266
48290
|
style: {
|
|
48267
|
-
backgroundImage:
|
|
48291
|
+
backgroundImage: resolved.theme?.background ? `url(${resolved.theme.background})` : void 0,
|
|
48268
48292
|
backgroundSize: "cover",
|
|
48269
48293
|
backgroundPosition: "center"
|
|
48270
48294
|
},
|
|
48271
48295
|
children: [
|
|
48272
|
-
|
|
48296
|
+
resolved.headerImage && !headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsx("img", { src: resolved.headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : resolved.headerImage && headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
48273
48297
|
/* @__PURE__ */ jsxs(VStack, { gap: "xs", children: [
|
|
48274
|
-
/* @__PURE__ */ jsx(Typography, { variant: "h4", className: "text-foreground", children:
|
|
48275
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-muted-foreground", children:
|
|
48298
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h4", className: "text-foreground", children: resolved.title }),
|
|
48299
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-muted-foreground", children: resolved.description }),
|
|
48276
48300
|
/* @__PURE__ */ jsxs(HStack, { className: "items-center p-2 rounded bg-warning/10 border border-warning/30", gap: "xs", children: [
|
|
48277
48301
|
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-warning font-bold", children: t("game.hint") + ":" }),
|
|
48278
|
-
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-foreground", children:
|
|
48302
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-foreground", children: resolved.hint })
|
|
48279
48303
|
] })
|
|
48280
48304
|
] }),
|
|
48281
48305
|
/* @__PURE__ */ jsxs(HStack, { className: "flex-wrap items-start", gap: "lg", children: [
|
|
@@ -48323,14 +48347,14 @@ function StateArchitectBoard({
|
|
|
48323
48347
|
]
|
|
48324
48348
|
}
|
|
48325
48349
|
),
|
|
48326
|
-
|
|
48350
|
+
resolved.states.map((state) => /* @__PURE__ */ jsx(
|
|
48327
48351
|
StateNode2,
|
|
48328
48352
|
{
|
|
48329
48353
|
name: state,
|
|
48330
48354
|
position: positions[state],
|
|
48331
48355
|
isCurrent: state === currentState,
|
|
48332
48356
|
isSelected: state === selectedState,
|
|
48333
|
-
isInitial: state ===
|
|
48357
|
+
isInitial: state === resolved.initialState,
|
|
48334
48358
|
onClick: () => handleStateClick(state)
|
|
48335
48359
|
},
|
|
48336
48360
|
state
|
|
@@ -48377,7 +48401,7 @@ function StateArchitectBoard({
|
|
|
48377
48401
|
/* @__PURE__ */ jsx(
|
|
48378
48402
|
VariablePanel,
|
|
48379
48403
|
{
|
|
48380
|
-
entityName:
|
|
48404
|
+
entityName: resolved.entityName,
|
|
48381
48405
|
variables
|
|
48382
48406
|
}
|
|
48383
48407
|
),
|
|
@@ -48389,15 +48413,15 @@ function StateArchitectBoard({
|
|
|
48389
48413
|
!r2.passed && /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-error", children: t("stateArchitect.gotState", { state: r2.actualState }) })
|
|
48390
48414
|
] }, i))
|
|
48391
48415
|
] }),
|
|
48392
|
-
|
|
48416
|
+
resolved.showCodeView !== false && /* @__PURE__ */ jsx(CodeView, { data: codeData, label: "View Code" })
|
|
48393
48417
|
] })
|
|
48394
48418
|
] }),
|
|
48395
|
-
playState === "success" && /* @__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:
|
|
48419
|
+
playState === "success" && /* @__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: resolved.successMessage || t("stateArchitect.allPassed") }) }),
|
|
48396
48420
|
playState === "fail" && /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
48397
48421
|
/* @__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]) }) }),
|
|
48398
|
-
attempts >= 3 &&
|
|
48422
|
+
attempts >= 3 && 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: [
|
|
48399
48423
|
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-accent font-bold shrink-0", children: "\u{1F4A1} " + t("game.hint") + ":" }),
|
|
48400
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-foreground", children:
|
|
48424
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-foreground", children: resolved.hint })
|
|
48401
48425
|
] }) })
|
|
48402
48426
|
] }),
|
|
48403
48427
|
/* @__PURE__ */ jsxs(HStack, { gap: "sm", children: [
|
|
@@ -49253,8 +49277,9 @@ var init_useBattleState = __esm({
|
|
|
49253
49277
|
}
|
|
49254
49278
|
});
|
|
49255
49279
|
function UncontrolledBattleBoard({ entity, ...rest }) {
|
|
49280
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
49256
49281
|
const battleState = useBattleState(
|
|
49257
|
-
|
|
49282
|
+
resolved?.initialUnits ?? [],
|
|
49258
49283
|
{
|
|
49259
49284
|
tileClickEvent: rest.tileClickEvent,
|
|
49260
49285
|
unitClickEvent: rest.unitClickEvent,
|
|
@@ -49271,12 +49296,13 @@ function UncontrolledBattleBoard({ entity, ...rest }) {
|
|
|
49271
49296
|
calculateDamage: rest.calculateDamage
|
|
49272
49297
|
}
|
|
49273
49298
|
);
|
|
49299
|
+
if (!resolved) return null;
|
|
49274
49300
|
return /* @__PURE__ */ jsx(
|
|
49275
49301
|
BattleBoard,
|
|
49276
49302
|
{
|
|
49277
49303
|
...rest,
|
|
49278
49304
|
entity: {
|
|
49279
|
-
...
|
|
49305
|
+
...resolved,
|
|
49280
49306
|
units: battleState.units,
|
|
49281
49307
|
phase: battleState.phase,
|
|
49282
49308
|
turn: battleState.turn,
|
|
@@ -55468,6 +55494,7 @@ var init_component_registry_generated = __esm({
|
|
|
55468
55494
|
init_StatsOrganism();
|
|
55469
55495
|
init_StatusDot();
|
|
55470
55496
|
init_StatusEffect();
|
|
55497
|
+
init_StepFlow();
|
|
55471
55498
|
init_StepFlowOrganism();
|
|
55472
55499
|
init_SvgBranch();
|
|
55473
55500
|
init_SvgConnection();
|
|
@@ -55786,6 +55813,7 @@ var init_component_registry_generated = __esm({
|
|
|
55786
55813
|
"StatsOrganism": StatsOrganism,
|
|
55787
55814
|
"StatusDot": StatusDot,
|
|
55788
55815
|
"StatusEffect": StatusEffect,
|
|
55816
|
+
"StepFlow": StepFlow,
|
|
55789
55817
|
"StepFlowOrganism": StepFlowOrganism,
|
|
55790
55818
|
"SvgBranch": SvgBranch,
|
|
55791
55819
|
"SvgConnection": SvgConnection,
|
|
@@ -56513,11 +56541,15 @@ function SlotContentRenderer({
|
|
|
56513
56541
|
}
|
|
56514
56542
|
if (propsSchema) {
|
|
56515
56543
|
for (const [propKey, propDef] of Object.entries(propsSchema)) {
|
|
56516
|
-
const
|
|
56517
|
-
if ((typeof v === "string" || typeof v === "number") && propDef.types?.some(
|
|
56544
|
+
const isDate = propDef.types?.some(
|
|
56518
56545
|
(t) => t === "date" || t === "datetime" || t === "timestamp"
|
|
56519
|
-
)
|
|
56546
|
+
);
|
|
56547
|
+
if (!isDate) continue;
|
|
56548
|
+
const v = renderedProps[propKey];
|
|
56549
|
+
if (typeof v === "string" || typeof v === "number") {
|
|
56520
56550
|
renderedProps[propKey] = new Date(v);
|
|
56551
|
+
} else if (v == null && propDef.required) {
|
|
56552
|
+
renderedProps[propKey] = /* @__PURE__ */ new Date();
|
|
56521
56553
|
}
|
|
56522
56554
|
}
|
|
56523
56555
|
}
|
|
@@ -60209,12 +60241,26 @@ function collectEmbeddedTraits(schema) {
|
|
|
60209
60241
|
}
|
|
60210
60242
|
var lambdaLog = createLogger("almadar:ui:fn-form-lambda");
|
|
60211
60243
|
function isFnFormLambda(value) {
|
|
60212
|
-
|
|
60244
|
+
if (!Array.isArray(value)) return false;
|
|
60245
|
+
const arr = value;
|
|
60246
|
+
if (arr.length !== 3 || arr[0] !== "fn" || arr[2] === null || typeof arr[2] !== "object") {
|
|
60247
|
+
return false;
|
|
60248
|
+
}
|
|
60249
|
+
const params = arr[1];
|
|
60250
|
+
return typeof params === "string" || Array.isArray(params) && params.length > 0 && params.every((p2) => typeof p2 === "string");
|
|
60251
|
+
}
|
|
60252
|
+
function fnFormParams(value) {
|
|
60253
|
+
const p2 = value[1];
|
|
60254
|
+
if (typeof p2 === "string") return [p2];
|
|
60255
|
+
if (Array.isArray(p2)) return p2.filter((x) => typeof x === "string");
|
|
60256
|
+
return [];
|
|
60213
60257
|
}
|
|
60214
|
-
function resolveLambdaBindings(body,
|
|
60215
|
-
const
|
|
60258
|
+
function resolveLambdaBindings(body, params, item, index) {
|
|
60259
|
+
const itemName = params[0];
|
|
60260
|
+
const indexName = params[1];
|
|
60261
|
+
const itemPrefix = itemName ? `@${itemName}.` : null;
|
|
60216
60262
|
const lookup = (path) => {
|
|
60217
|
-
let cur =
|
|
60263
|
+
let cur = item;
|
|
60218
60264
|
for (const seg of path.split(".")) {
|
|
60219
60265
|
if (cur === null || cur === void 0) return void 0;
|
|
60220
60266
|
if (typeof cur !== "object" || Array.isArray(cur)) return void 0;
|
|
@@ -60222,21 +60268,23 @@ function resolveLambdaBindings(body, argName, arg) {
|
|
|
60222
60268
|
}
|
|
60223
60269
|
return cur;
|
|
60224
60270
|
};
|
|
60271
|
+
const recur = (b) => resolveLambdaBindings(b, params, item, index);
|
|
60225
60272
|
if (typeof body === "string") {
|
|
60226
|
-
if (body === `@${
|
|
60227
|
-
if (body
|
|
60228
|
-
|
|
60273
|
+
if (indexName && body === `@${indexName}`) return index;
|
|
60274
|
+
if (itemName && body === `@${itemName}`) return item;
|
|
60275
|
+
if (itemPrefix && body.startsWith(itemPrefix)) {
|
|
60276
|
+
const v = lookup(body.slice(itemPrefix.length));
|
|
60229
60277
|
return v === void 0 || v === null ? "" : v;
|
|
60230
60278
|
}
|
|
60231
60279
|
return body;
|
|
60232
60280
|
}
|
|
60233
60281
|
if (Array.isArray(body)) {
|
|
60234
|
-
return body.map((b) =>
|
|
60282
|
+
return body.map((b) => recur(b));
|
|
60235
60283
|
}
|
|
60236
60284
|
if (body !== null && typeof body === "object" && !React98__default.isValidElement(body) && !(body instanceof Date) && typeof body !== "function") {
|
|
60237
60285
|
const out = {};
|
|
60238
60286
|
for (const [k, v] of Object.entries(body)) {
|
|
60239
|
-
out[k] =
|
|
60287
|
+
out[k] = recur(v);
|
|
60240
60288
|
}
|
|
60241
60289
|
return out;
|
|
60242
60290
|
}
|
|
@@ -60249,9 +60297,9 @@ function getSlotContentRenderer2() {
|
|
|
60249
60297
|
_slotContentRenderer2 = mod.SlotContentRenderer;
|
|
60250
60298
|
return _slotContentRenderer2;
|
|
60251
60299
|
}
|
|
60252
|
-
function makeLambdaFn(
|
|
60300
|
+
function makeLambdaFn(params, lambdaBody, callerKey) {
|
|
60253
60301
|
return (item, index) => {
|
|
60254
|
-
const resolvedBody = resolveLambdaBindings(lambdaBody,
|
|
60302
|
+
const resolvedBody = resolveLambdaBindings(lambdaBody, params, item, index);
|
|
60255
60303
|
if (resolvedBody === null || typeof resolvedBody !== "object" || Array.isArray(resolvedBody) || typeof resolvedBody === "function" || React98__default.isValidElement(resolvedBody) || resolvedBody instanceof Date) {
|
|
60256
60304
|
return null;
|
|
60257
60305
|
}
|
|
@@ -60278,8 +60326,8 @@ function convertNode(node, callerKey) {
|
|
|
60278
60326
|
if (node === null || node === void 0) return node;
|
|
60279
60327
|
if (Array.isArray(node)) {
|
|
60280
60328
|
if (isFnFormLambda(node)) {
|
|
60281
|
-
const
|
|
60282
|
-
return makeLambdaFn(
|
|
60329
|
+
const arr2 = node;
|
|
60330
|
+
return makeLambdaFn(fnFormParams(arr2), arr2[2], callerKey);
|
|
60283
60331
|
}
|
|
60284
60332
|
const arr = node;
|
|
60285
60333
|
let anyChanged = false;
|
|
@@ -60301,9 +60349,9 @@ function convertObjectProps(props) {
|
|
|
60301
60349
|
for (const [key, value] of Object.entries(props)) {
|
|
60302
60350
|
if (isFnFormLambda(value)) {
|
|
60303
60351
|
convertedAny = true;
|
|
60304
|
-
const
|
|
60352
|
+
const arr = value;
|
|
60305
60353
|
const targetKey = key === "renderItem" ? "children" : key;
|
|
60306
|
-
out[targetKey] = makeLambdaFn(
|
|
60354
|
+
out[targetKey] = makeLambdaFn(fnFormParams(arr), arr[2], key);
|
|
60307
60355
|
lambdaLog.debug(`convert key=${key} \u2192 ${targetKey}`);
|
|
60308
60356
|
continue;
|
|
60309
60357
|
}
|