@almadar/ui 5.17.0 → 5.17.1
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 +181 -153
- package/dist/avl/index.js +181 -153
- 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 +181 -153
- package/dist/components/index.js +181 -153
- 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 +181 -153
- package/dist/providers/index.js +181 -153
- package/dist/runtime/index.cjs +181 -153
- package/dist/runtime/index.js +181 -153
- package/package.json +1 -1
package/dist/runtime/index.cjs
CHANGED
|
@@ -1770,11 +1770,13 @@ var init_Icon = __esm({
|
|
|
1770
1770
|
strokeWidth,
|
|
1771
1771
|
style
|
|
1772
1772
|
}) => {
|
|
1773
|
+
const directIcon = typeof icon === "string" ? void 0 : icon;
|
|
1774
|
+
const effectiveName = typeof icon === "string" ? icon : name;
|
|
1773
1775
|
const family = useIconFamily();
|
|
1774
1776
|
const RenderedComponent = React85__namespace.default.useMemo(() => {
|
|
1775
|
-
if (
|
|
1776
|
-
return
|
|
1777
|
-
}, [
|
|
1777
|
+
if (directIcon) return null;
|
|
1778
|
+
return effectiveName ? resolveIconForFamily(effectiveName, family) : null;
|
|
1779
|
+
}, [directIcon, effectiveName, family]);
|
|
1778
1780
|
const effectiveStrokeWidth = strokeWidth ?? void 0;
|
|
1779
1781
|
const inlineStyle = {
|
|
1780
1782
|
...effectiveStrokeWidth === void 0 ? { strokeWidth: "var(--icon-stroke-width, 2)" } : {},
|
|
@@ -1786,8 +1788,8 @@ var init_Icon = __esm({
|
|
|
1786
1788
|
color ? color : "text-current",
|
|
1787
1789
|
className
|
|
1788
1790
|
);
|
|
1789
|
-
if (
|
|
1790
|
-
const Direct =
|
|
1791
|
+
if (directIcon) {
|
|
1792
|
+
const Direct = directIcon;
|
|
1791
1793
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1792
1794
|
Direct,
|
|
1793
1795
|
{
|
|
@@ -3660,7 +3662,7 @@ var init_Input = __esm({
|
|
|
3660
3662
|
error,
|
|
3661
3663
|
leftIcon,
|
|
3662
3664
|
rightIcon,
|
|
3663
|
-
icon:
|
|
3665
|
+
icon: iconProp,
|
|
3664
3666
|
clearable,
|
|
3665
3667
|
onClear,
|
|
3666
3668
|
value,
|
|
@@ -3670,6 +3672,7 @@ var init_Input = __esm({
|
|
|
3670
3672
|
...props
|
|
3671
3673
|
}, ref) => {
|
|
3672
3674
|
const type = inputType || htmlType || "text";
|
|
3675
|
+
const IconComponent = typeof iconProp === "string" ? resolveIcon(iconProp) : iconProp;
|
|
3673
3676
|
const resolvedLeftIcon = leftIcon || IconComponent && /* @__PURE__ */ jsxRuntime.jsx(IconComponent, { className: "h-icon-default w-icon-default" });
|
|
3674
3677
|
const showClearButton = clearable && value && String(value).length > 0;
|
|
3675
3678
|
const isMultiline = type === "textarea";
|
|
@@ -4217,7 +4220,7 @@ var init_Avatar = __esm({
|
|
|
4217
4220
|
alt,
|
|
4218
4221
|
name,
|
|
4219
4222
|
initials: providedInitials,
|
|
4220
|
-
icon:
|
|
4223
|
+
icon: iconProp,
|
|
4221
4224
|
size = "md",
|
|
4222
4225
|
status,
|
|
4223
4226
|
badge,
|
|
@@ -4228,6 +4231,7 @@ var init_Avatar = __esm({
|
|
|
4228
4231
|
}) => {
|
|
4229
4232
|
const eventBus = useEventBus();
|
|
4230
4233
|
const initials = providedInitials ?? (name ? generateInitials(name) : void 0);
|
|
4234
|
+
const IconComponent = typeof iconProp === "string" ? resolveIcon(iconProp) : iconProp;
|
|
4231
4235
|
const hasImage = !!src;
|
|
4232
4236
|
const hasInitials = !!initials;
|
|
4233
4237
|
const hasIcon = !!IconComponent;
|
|
@@ -15057,6 +15061,7 @@ var init_StateMachineView = __esm({
|
|
|
15057
15061
|
setTooltip((prev) => ({ ...prev, pinned: false, visible: false }));
|
|
15058
15062
|
}, []);
|
|
15059
15063
|
useEventListener("UI:TOOLTIP_CLOSE", handleCloseTooltip);
|
|
15064
|
+
if (!layoutData) return null;
|
|
15060
15065
|
const { width, height, title, states, labels, entity, outputs, config } = layoutData;
|
|
15061
15066
|
const bundles = React85.useMemo(() => {
|
|
15062
15067
|
const bundleMap = {};
|
|
@@ -17401,13 +17406,14 @@ function BuilderBoard({
|
|
|
17401
17406
|
}) {
|
|
17402
17407
|
const { emit } = useEventBus();
|
|
17403
17408
|
const { t } = useTranslate();
|
|
17409
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
17404
17410
|
const [placements, setPlacements] = React85.useState({});
|
|
17405
17411
|
const [headerError, setHeaderError] = React85.useState(false);
|
|
17406
17412
|
const [submitted, setSubmitted] = React85.useState(false);
|
|
17407
17413
|
const [attempts, setAttempts] = React85.useState(0);
|
|
17408
17414
|
const [showHint, setShowHint] = React85.useState(false);
|
|
17409
|
-
const components =
|
|
17410
|
-
const slots =
|
|
17415
|
+
const components = resolved?.components ?? [];
|
|
17416
|
+
const slots = resolved?.slots ?? [];
|
|
17411
17417
|
const usedComponentIds = new Set(Object.values(placements));
|
|
17412
17418
|
const availableComponents = components.filter((c) => !usedComponentIds.has(c.id));
|
|
17413
17419
|
const [selectedComponent, setSelectedComponent] = React85.useState(null);
|
|
@@ -17441,7 +17447,7 @@ function BuilderBoard({
|
|
|
17441
17447
|
}, [slots, placements, attempts, completeEvent, emit]);
|
|
17442
17448
|
const handleReset = () => {
|
|
17443
17449
|
setSubmitted(false);
|
|
17444
|
-
if (attempts >= 2 &&
|
|
17450
|
+
if (attempts >= 2 && resolved?.hint) {
|
|
17445
17451
|
setShowHint(true);
|
|
17446
17452
|
}
|
|
17447
17453
|
};
|
|
@@ -17453,20 +17459,21 @@ function BuilderBoard({
|
|
|
17453
17459
|
setShowHint(false);
|
|
17454
17460
|
};
|
|
17455
17461
|
const getComponentById = (id) => components.find((c) => c.id === id);
|
|
17462
|
+
if (!resolved) return null;
|
|
17456
17463
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
17457
17464
|
Box,
|
|
17458
17465
|
{
|
|
17459
17466
|
className,
|
|
17460
17467
|
style: {
|
|
17461
|
-
backgroundImage:
|
|
17468
|
+
backgroundImage: resolved.theme?.background ? `url(${resolved.theme.background})` : void 0,
|
|
17462
17469
|
backgroundSize: "cover",
|
|
17463
17470
|
backgroundPosition: "center"
|
|
17464
17471
|
},
|
|
17465
17472
|
children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "lg", className: "p-4", children: [
|
|
17466
|
-
|
|
17473
|
+
resolved.headerImage && !headerError ? /* @__PURE__ */ jsxRuntime.jsx(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(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
17467
17474
|
/* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", children: [
|
|
17468
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", weight: "bold", children:
|
|
17469
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", children:
|
|
17475
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", weight: "bold", children: resolved.title }),
|
|
17476
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", children: resolved.description })
|
|
17470
17477
|
] }) }),
|
|
17471
17478
|
/* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", children: [
|
|
17472
17479
|
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: t("builder.components") }),
|
|
@@ -17526,9 +17533,9 @@ function BuilderBoard({
|
|
|
17526
17533
|
] }) }),
|
|
17527
17534
|
submitted && /* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", align: "center", children: [
|
|
17528
17535
|
/* @__PURE__ */ jsxRuntime.jsx(Icon, { icon: allCorrect ? LucideIcons2.CheckCircle : LucideIcons2.XCircle, size: "lg", className: allCorrect ? "text-success" : "text-error" }),
|
|
17529
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", weight: "bold", children: allCorrect ?
|
|
17536
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", weight: "bold", children: allCorrect ? resolved.successMessage ?? t("builder.success") : resolved.failMessage ?? t("builder.incorrect") })
|
|
17530
17537
|
] }) }),
|
|
17531
|
-
showHint &&
|
|
17538
|
+
showHint && resolved.hint && /* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4 border-l-4 border-l-warning", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", children: resolved.hint }) }),
|
|
17532
17539
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", justify: "center", children: [
|
|
17533
17540
|
!submitted ? /* @__PURE__ */ jsxRuntime.jsxs(Button, { variant: "primary", onClick: handleSubmit, disabled: !allPlaced, children: [
|
|
17534
17541
|
/* @__PURE__ */ jsxRuntime.jsx(Icon, { icon: LucideIcons2.Wrench, size: "sm" }),
|
|
@@ -20002,11 +20009,12 @@ function CastleBoard({
|
|
|
20002
20009
|
className
|
|
20003
20010
|
}) {
|
|
20004
20011
|
const eventBus = useEventBus();
|
|
20005
|
-
const
|
|
20006
|
-
const
|
|
20007
|
-
const
|
|
20008
|
-
const
|
|
20009
|
-
const
|
|
20012
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
20013
|
+
const tiles = resolved?.tiles ?? [];
|
|
20014
|
+
const features = resolved?.features ?? [];
|
|
20015
|
+
const units = resolved?.units ?? [];
|
|
20016
|
+
const assetManifest = resolved?.assetManifest;
|
|
20017
|
+
const backgroundImage = resolved?.backgroundImage;
|
|
20010
20018
|
const [hoveredTile, setHoveredTile] = React85.useState(null);
|
|
20011
20019
|
const [selectedFeature, setSelectedFeature] = React85.useState(null);
|
|
20012
20020
|
const hoveredFeature = React85.useMemo(() => {
|
|
@@ -20911,13 +20919,14 @@ function ClassifierBoard({
|
|
|
20911
20919
|
}) {
|
|
20912
20920
|
const { emit } = useEventBus();
|
|
20913
20921
|
const { t } = useTranslate();
|
|
20922
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
20914
20923
|
const [assignments, setAssignments] = React85.useState({});
|
|
20915
20924
|
const [headerError, setHeaderError] = React85.useState(false);
|
|
20916
20925
|
const [submitted, setSubmitted] = React85.useState(false);
|
|
20917
20926
|
const [attempts, setAttempts] = React85.useState(0);
|
|
20918
20927
|
const [showHint, setShowHint] = React85.useState(false);
|
|
20919
|
-
const items =
|
|
20920
|
-
const categories =
|
|
20928
|
+
const items = resolved?.items ?? [];
|
|
20929
|
+
const categories = resolved?.categories ?? [];
|
|
20921
20930
|
const unassignedItems = items.filter((item) => !assignments[item.id]);
|
|
20922
20931
|
const allAssigned = Object.keys(assignments).length === items.length;
|
|
20923
20932
|
const results = submitted ? items.map((item) => ({
|
|
@@ -20949,7 +20958,7 @@ function ClassifierBoard({
|
|
|
20949
20958
|
}, [items, assignments, attempts, completeEvent, emit]);
|
|
20950
20959
|
const handleReset = () => {
|
|
20951
20960
|
setSubmitted(false);
|
|
20952
|
-
if (attempts >= 2 &&
|
|
20961
|
+
if (attempts >= 2 && resolved?.hint) {
|
|
20953
20962
|
setShowHint(true);
|
|
20954
20963
|
}
|
|
20955
20964
|
};
|
|
@@ -20959,20 +20968,21 @@ function ClassifierBoard({
|
|
|
20959
20968
|
setAttempts(0);
|
|
20960
20969
|
setShowHint(false);
|
|
20961
20970
|
};
|
|
20971
|
+
if (!resolved) return null;
|
|
20962
20972
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
20963
20973
|
Box,
|
|
20964
20974
|
{
|
|
20965
20975
|
className,
|
|
20966
20976
|
style: {
|
|
20967
|
-
backgroundImage:
|
|
20977
|
+
backgroundImage: resolved.theme?.background ? `url(${resolved.theme.background})` : void 0,
|
|
20968
20978
|
backgroundSize: "cover",
|
|
20969
20979
|
backgroundPosition: "center"
|
|
20970
20980
|
},
|
|
20971
20981
|
children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "lg", className: "p-4", children: [
|
|
20972
|
-
|
|
20982
|
+
resolved.headerImage && !headerError ? /* @__PURE__ */ jsxRuntime.jsx(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(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
20973
20983
|
/* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", children: [
|
|
20974
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", weight: "bold", children:
|
|
20975
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", children:
|
|
20984
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", weight: "bold", children: resolved.title }),
|
|
20985
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", children: resolved.description })
|
|
20976
20986
|
] }) }),
|
|
20977
20987
|
unassignedItems.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", children: [
|
|
20978
20988
|
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: t("classifier.itemsToSort") }),
|
|
@@ -21024,10 +21034,10 @@ function ClassifierBoard({
|
|
|
21024
21034
|
}) }),
|
|
21025
21035
|
submitted && /* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", align: "center", children: [
|
|
21026
21036
|
/* @__PURE__ */ jsxRuntime.jsx(Icon, { icon: allCorrect ? LucideIcons2.CheckCircle : LucideIcons2.XCircle, size: "lg", className: allCorrect ? "text-success" : "text-error" }),
|
|
21027
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", weight: "bold", children: allCorrect ?
|
|
21028
|
-
!allCorrect &&
|
|
21037
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", weight: "bold", children: allCorrect ? resolved.successMessage ?? t("classifier.allCorrect") : `${correctCount}/${items.length} ${t("classifier.correct")}` }),
|
|
21038
|
+
!allCorrect && resolved.failMessage && /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", className: "text-muted-foreground", children: resolved.failMessage })
|
|
21029
21039
|
] }) }),
|
|
21030
|
-
showHint &&
|
|
21040
|
+
showHint && resolved.hint && /* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4 border-l-4 border-l-warning", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", children: resolved.hint }) }),
|
|
21031
21041
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", justify: "center", children: [
|
|
21032
21042
|
!submitted ? /* @__PURE__ */ jsxRuntime.jsxs(Button, { variant: "primary", onClick: handleSubmit, disabled: !allAssigned, children: [
|
|
21033
21043
|
/* @__PURE__ */ jsxRuntime.jsx(Icon, { icon: LucideIcons2.Send, size: "sm" }),
|
|
@@ -32146,7 +32156,7 @@ var init_OptionConstraintGroup = __esm({
|
|
|
32146
32156
|
title,
|
|
32147
32157
|
description,
|
|
32148
32158
|
options,
|
|
32149
|
-
constraint,
|
|
32159
|
+
constraint = { type: "single" },
|
|
32150
32160
|
selected = [],
|
|
32151
32161
|
onChange,
|
|
32152
32162
|
changeEvent,
|
|
@@ -35284,7 +35294,7 @@ function DataTable({
|
|
|
35284
35294
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
35285
35295
|
EmptyState,
|
|
35286
35296
|
{
|
|
35287
|
-
icon: emptyIcon,
|
|
35297
|
+
icon: typeof emptyIcon === "string" ? resolveIcon(emptyIcon) : emptyIcon,
|
|
35288
35298
|
title: resolvedEmptyTitle,
|
|
35289
35299
|
description: resolvedEmptyDescription,
|
|
35290
35300
|
actionLabel: emptyAction?.label,
|
|
@@ -35413,6 +35423,7 @@ var init_DataTable = __esm({
|
|
|
35413
35423
|
init_Stack();
|
|
35414
35424
|
init_Typography();
|
|
35415
35425
|
init_molecules();
|
|
35426
|
+
init_Icon();
|
|
35416
35427
|
init_useEventBus();
|
|
35417
35428
|
init_useTranslate();
|
|
35418
35429
|
init_types3();
|
|
@@ -35433,6 +35444,7 @@ function DebuggerBoard({
|
|
|
35433
35444
|
}) {
|
|
35434
35445
|
const { emit } = useEventBus();
|
|
35435
35446
|
const { t } = useTranslate();
|
|
35447
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
35436
35448
|
const [flaggedLines, setFlaggedLines] = React85.useState(/* @__PURE__ */ new Set());
|
|
35437
35449
|
const [headerError, setHeaderError] = React85.useState(false);
|
|
35438
35450
|
const [submitted, setSubmitted] = React85.useState(false);
|
|
@@ -35450,7 +35462,7 @@ function DebuggerBoard({
|
|
|
35450
35462
|
return next;
|
|
35451
35463
|
});
|
|
35452
35464
|
};
|
|
35453
|
-
const lines =
|
|
35465
|
+
const lines = resolved?.lines ?? [];
|
|
35454
35466
|
const bugLines = lines.filter((l) => l.isBug);
|
|
35455
35467
|
const correctFlags = lines.filter((l) => l.isBug && flaggedLines.has(l.id));
|
|
35456
35468
|
const falseFlags = lines.filter((l) => !l.isBug && flaggedLines.has(l.id));
|
|
@@ -35465,7 +35477,7 @@ function DebuggerBoard({
|
|
|
35465
35477
|
}, [correctFlags.length, bugLines.length, falseFlags.length, attempts, completeEvent, emit]);
|
|
35466
35478
|
const handleReset = () => {
|
|
35467
35479
|
setSubmitted(false);
|
|
35468
|
-
if (attempts >= 2 &&
|
|
35480
|
+
if (attempts >= 2 && resolved?.hint) {
|
|
35469
35481
|
setShowHint(true);
|
|
35470
35482
|
}
|
|
35471
35483
|
};
|
|
@@ -35475,24 +35487,25 @@ function DebuggerBoard({
|
|
|
35475
35487
|
setAttempts(0);
|
|
35476
35488
|
setShowHint(false);
|
|
35477
35489
|
};
|
|
35490
|
+
if (!resolved) return null;
|
|
35478
35491
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
35479
35492
|
Box,
|
|
35480
35493
|
{
|
|
35481
35494
|
className,
|
|
35482
35495
|
style: {
|
|
35483
|
-
backgroundImage:
|
|
35496
|
+
backgroundImage: resolved.theme?.background ? `url(${resolved.theme.background})` : void 0,
|
|
35484
35497
|
backgroundSize: "cover",
|
|
35485
35498
|
backgroundPosition: "center"
|
|
35486
35499
|
},
|
|
35487
35500
|
children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "lg", className: "p-4", children: [
|
|
35488
|
-
|
|
35501
|
+
resolved.headerImage && !headerError ? /* @__PURE__ */ jsxRuntime.jsx(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(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
35489
35502
|
/* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", children: [
|
|
35490
35503
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
35491
35504
|
/* @__PURE__ */ jsxRuntime.jsx(Icon, { icon: LucideIcons2.Bug, size: "sm" }),
|
|
35492
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", weight: "bold", children:
|
|
35505
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", weight: "bold", children: resolved.title })
|
|
35493
35506
|
] }),
|
|
35494
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", children:
|
|
35495
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: t("debugger.findBugs", { count: String(
|
|
35507
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", children: resolved.description }),
|
|
35508
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: t("debugger.findBugs", { count: String(resolved.bugCount) }) })
|
|
35496
35509
|
] }) }),
|
|
35497
35510
|
/* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-0 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(VStack, { gap: "none", children: lines.map((line, i) => {
|
|
35498
35511
|
const isFlagged = flaggedLines.has(line.id);
|
|
@@ -35524,7 +35537,7 @@ function DebuggerBoard({
|
|
|
35524
35537
|
);
|
|
35525
35538
|
}) }) }),
|
|
35526
35539
|
submitted && /* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", children: [
|
|
35527
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", weight: "bold", children: allCorrect ?
|
|
35540
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", weight: "bold", children: allCorrect ? resolved.successMessage ?? t("debugger.allFound") : `${correctFlags.length}/${bugLines.length} ${t("debugger.bugsFound")}` }),
|
|
35528
35541
|
bugLines.map((line) => /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", align: "start", children: [
|
|
35529
35542
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
35530
35543
|
Icon,
|
|
@@ -35540,7 +35553,7 @@ function DebuggerBoard({
|
|
|
35540
35553
|
] })
|
|
35541
35554
|
] }, line.id))
|
|
35542
35555
|
] }) }),
|
|
35543
|
-
showHint &&
|
|
35556
|
+
showHint && resolved.hint && /* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4 border-l-4 border-l-warning", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", children: resolved.hint }) }),
|
|
35544
35557
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", justify: "center", children: [
|
|
35545
35558
|
!submitted ? /* @__PURE__ */ jsxRuntime.jsxs(Button, { variant: "primary", onClick: handleSubmit, disabled: flaggedLines.size === 0, children: [
|
|
35546
35559
|
/* @__PURE__ */ jsxRuntime.jsx(Icon, { icon: LucideIcons2.Send, size: "sm" }),
|
|
@@ -36672,7 +36685,8 @@ function EventHandlerBoard({
|
|
|
36672
36685
|
}) {
|
|
36673
36686
|
const { emit } = useEventBus();
|
|
36674
36687
|
const { t } = useTranslate();
|
|
36675
|
-
const
|
|
36688
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
36689
|
+
const entityObjects = resolved?.objects ?? [];
|
|
36676
36690
|
const [objects, setObjects] = React85.useState(entityObjects);
|
|
36677
36691
|
const [selectedObjectId, setSelectedObjectId] = React85.useState(
|
|
36678
36692
|
entityObjects[0]?.id || null
|
|
@@ -36707,7 +36721,7 @@ function EventHandlerBoard({
|
|
|
36707
36721
|
allRules.push({ object: obj, rule });
|
|
36708
36722
|
});
|
|
36709
36723
|
});
|
|
36710
|
-
const triggers =
|
|
36724
|
+
const triggers = resolved?.triggerEvents || [];
|
|
36711
36725
|
const eventQueue = [...triggers];
|
|
36712
36726
|
const firedEvents = /* @__PURE__ */ new Set();
|
|
36713
36727
|
let stepIdx = 0;
|
|
@@ -36738,12 +36752,12 @@ function EventHandlerBoard({
|
|
|
36738
36752
|
matching.forEach(({ object, rule }) => {
|
|
36739
36753
|
addLogEntry(object.icon, t("eventHandler.heardEvent", { object: object.name, event: currentEvent, action: rule.thenAction }), "done");
|
|
36740
36754
|
eventQueue.push(rule.thenAction);
|
|
36741
|
-
if (rule.thenAction ===
|
|
36755
|
+
if (rule.thenAction === resolved?.goalEvent) {
|
|
36742
36756
|
goalReached = true;
|
|
36743
36757
|
}
|
|
36744
36758
|
});
|
|
36745
36759
|
}
|
|
36746
|
-
if (currentEvent ===
|
|
36760
|
+
if (currentEvent === resolved?.goalEvent) {
|
|
36747
36761
|
goalReached = true;
|
|
36748
36762
|
}
|
|
36749
36763
|
stepIdx++;
|
|
@@ -36753,7 +36767,7 @@ function EventHandlerBoard({
|
|
|
36753
36767
|
addLogEntry("\u{1F3AC}", t("eventHandler.simulationStarted", { events: triggers.join(", ") }), "active");
|
|
36754
36768
|
}
|
|
36755
36769
|
timerRef.current = setTimeout(processNext, stepDurationMs);
|
|
36756
|
-
}, [playState, objects,
|
|
36770
|
+
}, [playState, objects, resolved, stepDurationMs, playEvent, completeEvent, emit, addLogEntry, t]);
|
|
36757
36771
|
const handleTryAgain = React85.useCallback(() => {
|
|
36758
36772
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
36759
36773
|
setPlayState("editing");
|
|
@@ -36761,12 +36775,13 @@ function EventHandlerBoard({
|
|
|
36761
36775
|
}, []);
|
|
36762
36776
|
const handleReset = React85.useCallback(() => {
|
|
36763
36777
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
36764
|
-
setObjects(
|
|
36778
|
+
setObjects(resolved?.objects ?? []);
|
|
36765
36779
|
setPlayState("editing");
|
|
36766
36780
|
setEventLog([]);
|
|
36767
|
-
setSelectedObjectId((
|
|
36781
|
+
setSelectedObjectId((resolved?.objects ?? [])[0]?.id || null);
|
|
36768
36782
|
setAttempts(0);
|
|
36769
|
-
}, [
|
|
36783
|
+
}, [resolved?.objects]);
|
|
36784
|
+
if (!resolved) return null;
|
|
36770
36785
|
const objectViewers = objects.map((obj) => {
|
|
36771
36786
|
const machine = {
|
|
36772
36787
|
name: obj.name,
|
|
@@ -36780,25 +36795,25 @@ function EventHandlerBoard({
|
|
|
36780
36795
|
};
|
|
36781
36796
|
return { obj, machine };
|
|
36782
36797
|
});
|
|
36783
|
-
const showHint = attempts >= 3 &&
|
|
36798
|
+
const showHint = attempts >= 3 && resolved.hint;
|
|
36784
36799
|
const encourageKey = ENCOURAGEMENT_KEYS[Math.min(attempts - 1, ENCOURAGEMENT_KEYS.length - 1)] ?? ENCOURAGEMENT_KEYS[0];
|
|
36785
36800
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
36786
36801
|
VStack,
|
|
36787
36802
|
{
|
|
36788
36803
|
className: cn("p-4 gap-6", className),
|
|
36789
36804
|
style: {
|
|
36790
|
-
backgroundImage:
|
|
36805
|
+
backgroundImage: resolved.theme?.background ? `url(${resolved.theme.background})` : void 0,
|
|
36791
36806
|
backgroundSize: "cover",
|
|
36792
36807
|
backgroundPosition: "center"
|
|
36793
36808
|
},
|
|
36794
36809
|
children: [
|
|
36795
|
-
|
|
36810
|
+
resolved.headerImage && !headerError ? /* @__PURE__ */ jsxRuntime.jsx(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(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
36796
36811
|
/* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "xs", children: [
|
|
36797
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", className: "text-foreground", children:
|
|
36798
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-muted-foreground", children:
|
|
36812
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", className: "text-foreground", children: resolved.title }),
|
|
36813
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-muted-foreground", children: resolved.description }),
|
|
36799
36814
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { className: "items-center p-2 rounded bg-primary/10 border border-primary/30", gap: "xs", children: [
|
|
36800
36815
|
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", className: "text-primary font-bold", children: t("game.goal") + ":" }),
|
|
36801
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", className: "text-foreground", children:
|
|
36816
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", className: "text-foreground", children: resolved.goalCondition })
|
|
36802
36817
|
] })
|
|
36803
36818
|
] }),
|
|
36804
36819
|
/* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", children: [
|
|
@@ -36829,12 +36844,12 @@ function EventHandlerBoard({
|
|
|
36829
36844
|
}
|
|
36830
36845
|
),
|
|
36831
36846
|
eventLog.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(EventLog, { entries: eventLog }),
|
|
36832
|
-
playState === "success" && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "p-4 rounded-container bg-success/20 border border-success text-center", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h5", className: "text-success", children:
|
|
36847
|
+
playState === "success" && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "p-4 rounded-container bg-success/20 border border-success text-center", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h5", className: "text-success", children: resolved.successMessage || t("eventHandler.chainComplete") }) }),
|
|
36833
36848
|
playState === "fail" && /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", children: [
|
|
36834
36849
|
/* @__PURE__ */ jsxRuntime.jsx(Box, { className: "p-4 rounded-container bg-warning/10 border border-warning/30 text-center", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body1", className: "text-foreground font-medium", children: t(encourageKey) }) }),
|
|
36835
36850
|
showHint && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "p-3 rounded-container bg-accent/10 border border-accent/30", children: /* @__PURE__ */ jsxRuntime.jsxs(HStack, { className: "items-start", gap: "xs", children: [
|
|
36836
36851
|
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-accent font-bold shrink-0", children: "\u{1F4A1} " + t("game.hint") + ":" }),
|
|
36837
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-foreground", children:
|
|
36852
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-foreground", children: resolved.hint })
|
|
36838
36853
|
] }) })
|
|
36839
36854
|
] }),
|
|
36840
36855
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", children: [
|
|
@@ -39955,19 +39970,20 @@ function NegotiatorBoard({
|
|
|
39955
39970
|
}) {
|
|
39956
39971
|
const { emit } = useEventBus();
|
|
39957
39972
|
const { t } = useTranslate();
|
|
39973
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
39958
39974
|
const [history, setHistory] = React85.useState([]);
|
|
39959
39975
|
const [headerError, setHeaderError] = React85.useState(false);
|
|
39960
39976
|
const [showHint, setShowHint] = React85.useState(false);
|
|
39961
39977
|
const currentRound = history.length;
|
|
39962
|
-
const isComplete = currentRound >=
|
|
39978
|
+
const isComplete = currentRound >= (resolved?.totalRounds ?? 0);
|
|
39963
39979
|
const playerTotal = history.reduce((s, r) => s + r.playerPayoff, 0);
|
|
39964
39980
|
const opponentTotal = history.reduce((s, r) => s + r.opponentPayoff, 0);
|
|
39965
|
-
const won = isComplete && playerTotal >=
|
|
39966
|
-
const actions =
|
|
39967
|
-
const payoffMatrix =
|
|
39981
|
+
const won = isComplete && playerTotal >= (resolved?.targetScore ?? 0);
|
|
39982
|
+
const actions = resolved?.actions ?? [];
|
|
39983
|
+
const payoffMatrix = resolved?.payoffMatrix ?? [];
|
|
39968
39984
|
const handleAction = React85.useCallback((actionId) => {
|
|
39969
39985
|
if (isComplete) return;
|
|
39970
|
-
const opponentAction = getOpponentAction(
|
|
39986
|
+
const opponentAction = getOpponentAction(resolved?.opponentStrategy ?? "random", actions, history);
|
|
39971
39987
|
const payoff = payoffMatrix.find(
|
|
39972
39988
|
(p2) => p2.playerAction === actionId && p2.opponentAction === opponentAction
|
|
39973
39989
|
);
|
|
@@ -39980,41 +39996,42 @@ function NegotiatorBoard({
|
|
|
39980
39996
|
};
|
|
39981
39997
|
const newHistory = [...history, result];
|
|
39982
39998
|
setHistory(newHistory);
|
|
39983
|
-
if (newHistory.length >=
|
|
39999
|
+
if (newHistory.length >= (resolved?.totalRounds ?? 0)) {
|
|
39984
40000
|
const total = newHistory.reduce((s, r) => s + r.playerPayoff, 0);
|
|
39985
|
-
if (total >=
|
|
40001
|
+
if (total >= (resolved?.targetScore ?? 0)) {
|
|
39986
40002
|
emit(`UI:${completeEvent}`, { success: true, score: total });
|
|
39987
40003
|
}
|
|
39988
|
-
if (newHistory.length >= 3 &&
|
|
40004
|
+
if (newHistory.length >= 3 && resolved?.hint) {
|
|
39989
40005
|
setShowHint(true);
|
|
39990
40006
|
}
|
|
39991
40007
|
}
|
|
39992
|
-
}, [isComplete,
|
|
40008
|
+
}, [isComplete, resolved, actions, payoffMatrix, history, currentRound, completeEvent, emit]);
|
|
39993
40009
|
const handleReset = () => {
|
|
39994
40010
|
setHistory([]);
|
|
39995
40011
|
setShowHint(false);
|
|
39996
40012
|
};
|
|
39997
40013
|
const getActionLabel = (id) => actions.find((a) => a.id === id)?.label ?? id;
|
|
40014
|
+
if (!resolved) return null;
|
|
39998
40015
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
39999
40016
|
Box,
|
|
40000
40017
|
{
|
|
40001
40018
|
className,
|
|
40002
40019
|
style: {
|
|
40003
|
-
backgroundImage:
|
|
40020
|
+
backgroundImage: resolved.theme?.background ? `url(${resolved.theme.background})` : void 0,
|
|
40004
40021
|
backgroundSize: "cover",
|
|
40005
40022
|
backgroundPosition: "center"
|
|
40006
40023
|
},
|
|
40007
40024
|
children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "lg", className: "p-4", children: [
|
|
40008
|
-
|
|
40025
|
+
resolved.headerImage && !headerError ? /* @__PURE__ */ jsxRuntime.jsx(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(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
40009
40026
|
/* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", children: [
|
|
40010
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", weight: "bold", children:
|
|
40011
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", children:
|
|
40027
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", weight: "bold", children: resolved.title }),
|
|
40028
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", children: resolved.description }),
|
|
40012
40029
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "md", children: [
|
|
40013
|
-
/* @__PURE__ */ jsxRuntime.jsx(Badge, { size: "sm", children: t("negotiator.round", { current: String(currentRound), total: String(
|
|
40030
|
+
/* @__PURE__ */ jsxRuntime.jsx(Badge, { size: "sm", children: t("negotiator.round", { current: String(currentRound), total: String(resolved.totalRounds) }) }),
|
|
40014
40031
|
/* @__PURE__ */ jsxRuntime.jsxs(Badge, { size: "sm", children: [
|
|
40015
40032
|
t("negotiator.target"),
|
|
40016
40033
|
": ",
|
|
40017
|
-
|
|
40034
|
+
resolved.targetScore
|
|
40018
40035
|
] })
|
|
40019
40036
|
] })
|
|
40020
40037
|
] }) }),
|
|
@@ -40063,16 +40080,16 @@ function NegotiatorBoard({
|
|
|
40063
40080
|
] }) }),
|
|
40064
40081
|
isComplete && /* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", align: "center", children: [
|
|
40065
40082
|
/* @__PURE__ */ jsxRuntime.jsx(Icon, { icon: LucideIcons2.CheckCircle, size: "lg", className: won ? "text-success" : "text-error" }),
|
|
40066
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", weight: "bold", children: won ?
|
|
40083
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", weight: "bold", children: won ? resolved.successMessage ?? t("negotiator.success") : resolved.failMessage ?? t("negotiator.failed") }),
|
|
40067
40084
|
/* @__PURE__ */ jsxRuntime.jsxs(Typography, { variant: "caption", className: "text-muted-foreground", children: [
|
|
40068
40085
|
t("negotiator.finalScore"),
|
|
40069
40086
|
": ",
|
|
40070
40087
|
playerTotal,
|
|
40071
40088
|
"/",
|
|
40072
|
-
|
|
40089
|
+
resolved.targetScore
|
|
40073
40090
|
] })
|
|
40074
40091
|
] }) }),
|
|
40075
|
-
showHint &&
|
|
40092
|
+
showHint && resolved.hint && !won && /* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4 border-l-4 border-l-warning", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", children: resolved.hint }) }),
|
|
40076
40093
|
isComplete && !won && /* @__PURE__ */ jsxRuntime.jsx(HStack, { justify: "center", children: /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "primary", onClick: handleReset, children: t("negotiator.playAgain") }) })
|
|
40077
40094
|
] })
|
|
40078
40095
|
}
|
|
@@ -42865,15 +42882,16 @@ function SequencerBoard({
|
|
|
42865
42882
|
}) {
|
|
42866
42883
|
const { emit } = useEventBus();
|
|
42867
42884
|
const { t } = useTranslate();
|
|
42885
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
42868
42886
|
const [headerError, setHeaderError] = React85.useState(false);
|
|
42869
42887
|
const [slots, setSlots] = React85.useState(
|
|
42870
|
-
() => Array.from({ length:
|
|
42888
|
+
() => Array.from({ length: resolved?.maxSlots ?? 0 }, () => void 0)
|
|
42871
42889
|
);
|
|
42872
42890
|
const [playState, setPlayState] = React85.useState("idle");
|
|
42873
42891
|
const [currentStep, setCurrentStep] = React85.useState(-1);
|
|
42874
42892
|
const [attempts, setAttempts] = React85.useState(0);
|
|
42875
42893
|
const [slotFeedback, setSlotFeedback] = React85.useState(
|
|
42876
|
-
() => Array.from({ length:
|
|
42894
|
+
() => Array.from({ length: resolved?.maxSlots ?? 0 }, () => null)
|
|
42877
42895
|
);
|
|
42878
42896
|
const timerRef = React85.useRef(null);
|
|
42879
42897
|
React85.useEffect(() => () => {
|
|
@@ -42907,17 +42925,17 @@ function SequencerBoard({
|
|
|
42907
42925
|
}, [emit]);
|
|
42908
42926
|
const handleReset = React85.useCallback(() => {
|
|
42909
42927
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
42910
|
-
setSlots(Array.from({ length:
|
|
42928
|
+
setSlots(Array.from({ length: resolved?.maxSlots ?? 0 }, () => void 0));
|
|
42911
42929
|
setPlayState("idle");
|
|
42912
42930
|
setCurrentStep(-1);
|
|
42913
42931
|
setAttempts(0);
|
|
42914
|
-
setSlotFeedback(Array.from({ length:
|
|
42915
|
-
}, [
|
|
42932
|
+
setSlotFeedback(Array.from({ length: resolved?.maxSlots ?? 0 }, () => null));
|
|
42933
|
+
}, [resolved?.maxSlots]);
|
|
42916
42934
|
const filledSlots = slots.filter((s) => !!s);
|
|
42917
42935
|
const canPlay = filledSlots.length > 0 && playState === "idle";
|
|
42918
42936
|
const handlePlay = React85.useCallback(() => {
|
|
42919
42937
|
if (!canPlay) return;
|
|
42920
|
-
setSlotFeedback(Array.from({ length:
|
|
42938
|
+
setSlotFeedback(Array.from({ length: resolved?.maxSlots ?? 0 }, () => null));
|
|
42921
42939
|
emit("UI:PLAY_SOUND", { key: "confirm" });
|
|
42922
42940
|
const sequence = slots.map((s) => s?.id || "");
|
|
42923
42941
|
if (playEvent) {
|
|
@@ -42928,10 +42946,10 @@ function SequencerBoard({
|
|
|
42928
42946
|
let step = 0;
|
|
42929
42947
|
const advance = () => {
|
|
42930
42948
|
step++;
|
|
42931
|
-
if (step >=
|
|
42949
|
+
if (step >= (resolved?.maxSlots ?? 0)) {
|
|
42932
42950
|
const playerSeq = slots.map((s) => s?.id);
|
|
42933
42951
|
const playerIds = slots.filter(Boolean).map((s) => s?.id || "");
|
|
42934
|
-
const success =
|
|
42952
|
+
const success = (resolved?.solutions ?? []).some(
|
|
42935
42953
|
(sol) => sol.length === playerIds.length && sol.every((id, i) => id === playerIds[i])
|
|
42936
42954
|
);
|
|
42937
42955
|
if (success) {
|
|
@@ -42943,7 +42961,7 @@ function SequencerBoard({
|
|
|
42943
42961
|
}
|
|
42944
42962
|
} else {
|
|
42945
42963
|
setAttempts((prev) => prev + 1);
|
|
42946
|
-
const feedback = computeSlotFeedback(playerSeq,
|
|
42964
|
+
const feedback = computeSlotFeedback(playerSeq, resolved?.solutions ?? []);
|
|
42947
42965
|
setSlotFeedback(feedback);
|
|
42948
42966
|
setPlayState("idle");
|
|
42949
42967
|
setCurrentStep(-1);
|
|
@@ -42961,10 +42979,10 @@ function SequencerBoard({
|
|
|
42961
42979
|
}
|
|
42962
42980
|
};
|
|
42963
42981
|
timerRef.current = setTimeout(advance, stepDurationMs);
|
|
42964
|
-
}, [canPlay, slots,
|
|
42982
|
+
}, [canPlay, slots, resolved?.maxSlots, resolved?.solutions, stepDurationMs, playEvent, completeEvent, emit]);
|
|
42965
42983
|
const machine = {
|
|
42966
|
-
name:
|
|
42967
|
-
description:
|
|
42984
|
+
name: resolved?.title ?? "",
|
|
42985
|
+
description: resolved?.description ?? "",
|
|
42968
42986
|
states: slots.map((s, i) => stepLabel(s, i)),
|
|
42969
42987
|
currentState: currentStep >= 0 ? stepLabel(slots[currentStep], currentStep) : "__idle__",
|
|
42970
42988
|
transitions: slots.slice(0, -1).map((s, i) => ({
|
|
@@ -42973,36 +42991,37 @@ function SequencerBoard({
|
|
|
42973
42991
|
event: "NEXT"
|
|
42974
42992
|
}))
|
|
42975
42993
|
};
|
|
42976
|
-
const usedIds =
|
|
42977
|
-
const showHint = attempts >= 3 && !!
|
|
42994
|
+
const usedIds = resolved?.allowDuplicates === false ? slots.filter(Boolean).map((s) => s?.id || "") : [];
|
|
42995
|
+
const showHint = attempts >= 3 && !!resolved?.hint;
|
|
42978
42996
|
const hasFeedback = slotFeedback.some((f3) => f3 !== null);
|
|
42979
42997
|
const correctCount = slotFeedback.filter((f3) => f3 === "correct").length;
|
|
42980
42998
|
const encourageKey = ENCOURAGEMENT_KEYS2[Math.min(attempts - 1, ENCOURAGEMENT_KEYS2.length - 1)] ?? ENCOURAGEMENT_KEYS2[0];
|
|
42999
|
+
if (!resolved) return null;
|
|
42981
43000
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
42982
43001
|
VStack,
|
|
42983
43002
|
{
|
|
42984
43003
|
className: cn("p-4 gap-6", className),
|
|
42985
43004
|
style: {
|
|
42986
|
-
backgroundImage:
|
|
43005
|
+
backgroundImage: resolved.theme?.background ? `url(${resolved.theme.background})` : void 0,
|
|
42987
43006
|
backgroundSize: "cover",
|
|
42988
43007
|
backgroundPosition: "center"
|
|
42989
43008
|
},
|
|
42990
43009
|
children: [
|
|
42991
|
-
|
|
43010
|
+
resolved.headerImage && !headerError ? /* @__PURE__ */ jsxRuntime.jsx(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(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
42992
43011
|
/* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "xs", children: [
|
|
42993
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", className: "text-foreground", children:
|
|
42994
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-muted-foreground", children:
|
|
43012
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", className: "text-foreground", children: resolved.title }),
|
|
43013
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-muted-foreground", children: resolved.description })
|
|
42995
43014
|
] }),
|
|
42996
43015
|
showHint && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "p-3 rounded-container bg-accent/10 border border-accent/30", children: /* @__PURE__ */ jsxRuntime.jsxs(HStack, { className: "items-start", gap: "xs", children: [
|
|
42997
43016
|
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-accent font-bold shrink-0", children: "\u{1F4A1} " + t("game.hint") + ":" }),
|
|
42998
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-foreground", children:
|
|
43017
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-foreground", children: resolved.hint })
|
|
42999
43018
|
] }) }),
|
|
43000
43019
|
filledSlots.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(TraitStateViewer, { trait: machine, variant: "linear", size: "md" }),
|
|
43001
43020
|
/* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "xs", children: [
|
|
43002
43021
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { className: "items-center justify-between", children: [
|
|
43003
43022
|
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-muted-foreground font-medium", children: t("sequencer.yourSequence") + ":" }),
|
|
43004
43023
|
hasFeedback && playState === "idle" && /* @__PURE__ */ jsxRuntime.jsxs(Typography, { variant: "caption", className: "text-muted-foreground", children: [
|
|
43005
|
-
`${correctCount}/${
|
|
43024
|
+
`${correctCount}/${resolved.maxSlots} `,
|
|
43006
43025
|
"\u2705"
|
|
43007
43026
|
] })
|
|
43008
43027
|
] }),
|
|
@@ -43010,7 +43029,7 @@ function SequencerBoard({
|
|
|
43010
43029
|
SequenceBar,
|
|
43011
43030
|
{
|
|
43012
43031
|
slots,
|
|
43013
|
-
maxSlots:
|
|
43032
|
+
maxSlots: resolved.maxSlots,
|
|
43014
43033
|
onSlotDrop: handleSlotDrop,
|
|
43015
43034
|
onSlotRemove: handleSlotRemove,
|
|
43016
43035
|
playing: playState === "playing",
|
|
@@ -43024,15 +43043,15 @@ function SequencerBoard({
|
|
|
43024
43043
|
playState !== "playing" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
43025
43044
|
ActionPalette,
|
|
43026
43045
|
{
|
|
43027
|
-
actions:
|
|
43046
|
+
actions: resolved.availableActions,
|
|
43028
43047
|
usedActionIds: usedIds,
|
|
43029
|
-
allowDuplicates:
|
|
43048
|
+
allowDuplicates: resolved.allowDuplicates !== false,
|
|
43030
43049
|
categoryColors,
|
|
43031
43050
|
label: t("sequencer.dragActions")
|
|
43032
43051
|
}
|
|
43033
43052
|
),
|
|
43034
43053
|
hasFeedback && playState === "idle" && attempts > 0 && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "p-3 rounded-container bg-warning/10 border border-warning/30 text-center", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-foreground", children: t(encourageKey) }) }),
|
|
43035
|
-
playState === "success" && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "p-4 rounded-container bg-success/20 border border-success text-center", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h5", className: "text-success", children:
|
|
43054
|
+
playState === "success" && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "p-4 rounded-container bg-success/20 border border-success text-center", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h5", className: "text-success", children: resolved.successMessage || t("sequencer.levelComplete") }) }),
|
|
43036
43055
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", children: [
|
|
43037
43056
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
43038
43057
|
Button,
|
|
@@ -43855,7 +43874,8 @@ function SimulatorBoard({
|
|
|
43855
43874
|
}) {
|
|
43856
43875
|
const { emit } = useEventBus();
|
|
43857
43876
|
const { t } = useTranslate();
|
|
43858
|
-
const
|
|
43877
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
43878
|
+
const parameters = resolved?.parameters ?? [];
|
|
43859
43879
|
const [values, setValues] = React85.useState(() => {
|
|
43860
43880
|
const init = {};
|
|
43861
43881
|
for (const p2 of parameters) {
|
|
@@ -43869,15 +43889,15 @@ function SimulatorBoard({
|
|
|
43869
43889
|
const [showHint, setShowHint] = React85.useState(false);
|
|
43870
43890
|
const computeOutput = React85.useCallback((params) => {
|
|
43871
43891
|
try {
|
|
43872
|
-
const fn = new Function("params", `return (${
|
|
43892
|
+
const fn = new Function("params", `return (${resolved?.computeExpression})`);
|
|
43873
43893
|
return fn(params);
|
|
43874
43894
|
} catch {
|
|
43875
43895
|
return 0;
|
|
43876
43896
|
}
|
|
43877
|
-
}, [
|
|
43897
|
+
}, [resolved?.computeExpression]);
|
|
43878
43898
|
const output = React85.useMemo(() => computeOutput(values) ?? 0, [computeOutput, values]);
|
|
43879
|
-
const targetValue =
|
|
43880
|
-
const targetTolerance =
|
|
43899
|
+
const targetValue = resolved?.targetValue ?? 0;
|
|
43900
|
+
const targetTolerance = resolved?.targetTolerance ?? 0;
|
|
43881
43901
|
const isCorrect = Math.abs(output - targetValue) <= targetTolerance;
|
|
43882
43902
|
const handleParameterChange = (id, value) => {
|
|
43883
43903
|
if (submitted) return;
|
|
@@ -43892,7 +43912,7 @@ function SimulatorBoard({
|
|
|
43892
43912
|
};
|
|
43893
43913
|
const handleReset = () => {
|
|
43894
43914
|
setSubmitted(false);
|
|
43895
|
-
if (attempts >= 2 &&
|
|
43915
|
+
if (attempts >= 2 && resolved?.hint) {
|
|
43896
43916
|
setShowHint(true);
|
|
43897
43917
|
}
|
|
43898
43918
|
};
|
|
@@ -43906,20 +43926,21 @@ function SimulatorBoard({
|
|
|
43906
43926
|
setAttempts(0);
|
|
43907
43927
|
setShowHint(false);
|
|
43908
43928
|
};
|
|
43929
|
+
if (!resolved) return null;
|
|
43909
43930
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
43910
43931
|
Box,
|
|
43911
43932
|
{
|
|
43912
43933
|
className,
|
|
43913
43934
|
style: {
|
|
43914
|
-
backgroundImage:
|
|
43935
|
+
backgroundImage: resolved.theme?.background ? `url(${resolved.theme.background})` : void 0,
|
|
43915
43936
|
backgroundSize: "cover",
|
|
43916
43937
|
backgroundPosition: "center"
|
|
43917
43938
|
},
|
|
43918
43939
|
children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "lg", className: "p-4", children: [
|
|
43919
|
-
|
|
43940
|
+
resolved.headerImage && !headerError ? /* @__PURE__ */ jsxRuntime.jsx(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(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
43920
43941
|
/* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", children: [
|
|
43921
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", weight: "bold", children:
|
|
43922
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", children:
|
|
43942
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", weight: "bold", children: resolved.title }),
|
|
43943
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", children: resolved.description })
|
|
43923
43944
|
] }) }),
|
|
43924
43945
|
/* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "md", children: [
|
|
43925
43946
|
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: t("simulator.parameters") }),
|
|
@@ -43960,28 +43981,28 @@ function SimulatorBoard({
|
|
|
43960
43981
|
] }, param.id))
|
|
43961
43982
|
] }) }),
|
|
43962
43983
|
/* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", align: "center", children: [
|
|
43963
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children:
|
|
43984
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: resolved.outputLabel }),
|
|
43964
43985
|
/* @__PURE__ */ jsxRuntime.jsxs(Typography, { variant: "h3", weight: "bold", children: [
|
|
43965
43986
|
output.toFixed(2),
|
|
43966
43987
|
" ",
|
|
43967
|
-
|
|
43988
|
+
resolved.outputUnit
|
|
43968
43989
|
] }),
|
|
43969
43990
|
submitted && /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
43970
43991
|
/* @__PURE__ */ jsxRuntime.jsx(Icon, { icon: isCorrect ? LucideIcons2.CheckCircle : LucideIcons2.XCircle, size: "sm", className: isCorrect ? "text-success" : "text-error" }),
|
|
43971
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", className: isCorrect ? "text-success" : "text-error", children: isCorrect ?
|
|
43992
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", className: isCorrect ? "text-success" : "text-error", children: isCorrect ? resolved.successMessage ?? t("simulator.correct") : resolved.failMessage ?? t("simulator.incorrect") })
|
|
43972
43993
|
] }),
|
|
43973
43994
|
/* @__PURE__ */ jsxRuntime.jsxs(Typography, { variant: "caption", className: "text-muted-foreground", children: [
|
|
43974
43995
|
t("simulator.target"),
|
|
43975
43996
|
": ",
|
|
43976
43997
|
targetValue,
|
|
43977
43998
|
" ",
|
|
43978
|
-
|
|
43999
|
+
resolved.outputUnit,
|
|
43979
44000
|
" (\xB1",
|
|
43980
44001
|
targetTolerance,
|
|
43981
44002
|
")"
|
|
43982
44003
|
] })
|
|
43983
44004
|
] }) }),
|
|
43984
|
-
showHint &&
|
|
44005
|
+
showHint && resolved.hint && /* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4 border-l-4 border-l-warning", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", children: resolved.hint }) }),
|
|
43985
44006
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", justify: "center", children: [
|
|
43986
44007
|
!submitted ? /* @__PURE__ */ jsxRuntime.jsxs(Button, { variant: "primary", onClick: handleSubmit, children: [
|
|
43987
44008
|
/* @__PURE__ */ jsxRuntime.jsx(Icon, { icon: LucideIcons2.Play, size: "sm" }),
|
|
@@ -44561,13 +44582,14 @@ function StateArchitectBoard({
|
|
|
44561
44582
|
}) {
|
|
44562
44583
|
const { emit } = useEventBus();
|
|
44563
44584
|
const { t } = useTranslate();
|
|
44564
|
-
const
|
|
44585
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
44586
|
+
const [transitions, setTransitions] = React85.useState(resolved?.transitions ?? []);
|
|
44565
44587
|
const [headerError, setHeaderError] = React85.useState(false);
|
|
44566
44588
|
const [playState, setPlayState] = React85.useState("editing");
|
|
44567
|
-
const [currentState, setCurrentState] = React85.useState(
|
|
44589
|
+
const [currentState, setCurrentState] = React85.useState(resolved?.initialState ?? "");
|
|
44568
44590
|
const [selectedState, setSelectedState] = React85.useState(null);
|
|
44569
44591
|
const [testResults, setTestResults] = React85.useState([]);
|
|
44570
|
-
const [variables, setVariables] = React85.useState(
|
|
44592
|
+
const [variables, setVariables] = React85.useState(resolved?.variables ?? []);
|
|
44571
44593
|
const [attempts, setAttempts] = React85.useState(0);
|
|
44572
44594
|
const timerRef = React85.useRef(null);
|
|
44573
44595
|
const [addingFrom, setAddingFrom] = React85.useState(null);
|
|
@@ -44576,12 +44598,12 @@ function StateArchitectBoard({
|
|
|
44576
44598
|
}, []);
|
|
44577
44599
|
const GRAPH_W = 500;
|
|
44578
44600
|
const GRAPH_H = 400;
|
|
44579
|
-
const positions = React85.useMemo(() => layoutStates(
|
|
44601
|
+
const positions = React85.useMemo(() => layoutStates(resolved?.states ?? [], GRAPH_W, GRAPH_H), [resolved?.states]);
|
|
44580
44602
|
const handleStateClick = React85.useCallback((state) => {
|
|
44581
44603
|
if (playState !== "editing") return;
|
|
44582
44604
|
if (addingFrom) {
|
|
44583
44605
|
if (addingFrom !== state) {
|
|
44584
|
-
const event =
|
|
44606
|
+
const event = resolved?.availableEvents[0] || "EVENT";
|
|
44585
44607
|
const newTrans = {
|
|
44586
44608
|
id: `t-${nextTransId++}`,
|
|
44587
44609
|
from: addingFrom,
|
|
@@ -44594,7 +44616,7 @@ function StateArchitectBoard({
|
|
|
44594
44616
|
} else {
|
|
44595
44617
|
setSelectedState(state);
|
|
44596
44618
|
}
|
|
44597
|
-
}, [playState, addingFrom,
|
|
44619
|
+
}, [playState, addingFrom, resolved?.availableEvents]);
|
|
44598
44620
|
const handleStartAddTransition = React85.useCallback(() => {
|
|
44599
44621
|
if (!selectedState) return;
|
|
44600
44622
|
setAddingFrom(selectedState);
|
|
@@ -44603,9 +44625,9 @@ function StateArchitectBoard({
|
|
|
44603
44625
|
setTransitions((prev) => prev.filter((t2) => t2.id !== transId));
|
|
44604
44626
|
}, []);
|
|
44605
44627
|
const machine = React85.useMemo(() => ({
|
|
44606
|
-
name:
|
|
44607
|
-
description:
|
|
44608
|
-
states:
|
|
44628
|
+
name: resolved?.entityName ?? "",
|
|
44629
|
+
description: resolved?.description ?? "",
|
|
44630
|
+
states: resolved?.states ?? [],
|
|
44609
44631
|
currentState,
|
|
44610
44632
|
transitions: transitions.map((t2) => ({
|
|
44611
44633
|
from: t2.from,
|
|
@@ -44613,7 +44635,7 @@ function StateArchitectBoard({
|
|
|
44613
44635
|
event: t2.event,
|
|
44614
44636
|
guardHint: t2.guardHint
|
|
44615
44637
|
}))
|
|
44616
|
-
}), [
|
|
44638
|
+
}), [resolved, currentState, transitions]);
|
|
44617
44639
|
const handleTest = React85.useCallback(() => {
|
|
44618
44640
|
if (playState !== "editing") return;
|
|
44619
44641
|
if (testEvent) emit(`UI:${testEvent}`, {});
|
|
@@ -44622,7 +44644,7 @@ function StateArchitectBoard({
|
|
|
44622
44644
|
const results = [];
|
|
44623
44645
|
let testIdx = 0;
|
|
44624
44646
|
const runNextTest = () => {
|
|
44625
|
-
if (testIdx >=
|
|
44647
|
+
if (testIdx >= (resolved?.testCases.length ?? 0)) {
|
|
44626
44648
|
const allPassed = results.every((r) => r.passed);
|
|
44627
44649
|
setPlayState(allPassed ? "success" : "fail");
|
|
44628
44650
|
setTestResults(results);
|
|
@@ -44637,8 +44659,9 @@ function StateArchitectBoard({
|
|
|
44637
44659
|
}
|
|
44638
44660
|
return;
|
|
44639
44661
|
}
|
|
44640
|
-
const testCase =
|
|
44641
|
-
|
|
44662
|
+
const testCase = resolved?.testCases[testIdx];
|
|
44663
|
+
if (!testCase) return;
|
|
44664
|
+
let state = resolved.initialState;
|
|
44642
44665
|
for (const event of testCase.events) {
|
|
44643
44666
|
const trans = transitions.find((t2) => t2.from === state && t2.event === event);
|
|
44644
44667
|
if (trans) {
|
|
@@ -44656,52 +44679,53 @@ function StateArchitectBoard({
|
|
|
44656
44679
|
timerRef.current = setTimeout(runNextTest, stepDurationMs);
|
|
44657
44680
|
};
|
|
44658
44681
|
timerRef.current = setTimeout(runNextTest, stepDurationMs);
|
|
44659
|
-
}, [playState, transitions,
|
|
44682
|
+
}, [playState, transitions, resolved, stepDurationMs, testEvent, completeEvent, emit]);
|
|
44660
44683
|
const handleTryAgain = React85.useCallback(() => {
|
|
44661
44684
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
44662
44685
|
setPlayState("editing");
|
|
44663
|
-
setCurrentState(
|
|
44686
|
+
setCurrentState(resolved?.initialState ?? "");
|
|
44664
44687
|
setTestResults([]);
|
|
44665
|
-
}, [
|
|
44688
|
+
}, [resolved?.initialState]);
|
|
44666
44689
|
const handleReset = React85.useCallback(() => {
|
|
44667
44690
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
44668
|
-
setTransitions(
|
|
44691
|
+
setTransitions(resolved?.transitions ?? []);
|
|
44669
44692
|
setPlayState("editing");
|
|
44670
|
-
setCurrentState(
|
|
44693
|
+
setCurrentState(resolved?.initialState ?? "");
|
|
44671
44694
|
setTestResults([]);
|
|
44672
|
-
setVariables(
|
|
44695
|
+
setVariables(resolved?.variables ?? []);
|
|
44673
44696
|
setSelectedState(null);
|
|
44674
44697
|
setAddingFrom(null);
|
|
44675
44698
|
setAttempts(0);
|
|
44676
|
-
}, [
|
|
44699
|
+
}, [resolved]);
|
|
44677
44700
|
const codeData = React85.useMemo(() => ({
|
|
44678
|
-
name:
|
|
44679
|
-
states:
|
|
44680
|
-
initialState:
|
|
44701
|
+
name: resolved?.entityName ?? "",
|
|
44702
|
+
states: resolved?.states ?? [],
|
|
44703
|
+
initialState: resolved?.initialState ?? "",
|
|
44681
44704
|
transitions: transitions.map((t2) => ({
|
|
44682
44705
|
from: t2.from,
|
|
44683
44706
|
to: t2.to,
|
|
44684
44707
|
event: t2.event,
|
|
44685
44708
|
...t2.guardHint ? { guard: t2.guardHint } : {}
|
|
44686
44709
|
}))
|
|
44687
|
-
}), [
|
|
44710
|
+
}), [resolved, transitions]);
|
|
44711
|
+
if (!resolved) return null;
|
|
44688
44712
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
44689
44713
|
VStack,
|
|
44690
44714
|
{
|
|
44691
44715
|
className: cn("p-4 gap-6", className),
|
|
44692
44716
|
style: {
|
|
44693
|
-
backgroundImage:
|
|
44717
|
+
backgroundImage: resolved.theme?.background ? `url(${resolved.theme.background})` : void 0,
|
|
44694
44718
|
backgroundSize: "cover",
|
|
44695
44719
|
backgroundPosition: "center"
|
|
44696
44720
|
},
|
|
44697
44721
|
children: [
|
|
44698
|
-
|
|
44722
|
+
resolved.headerImage && !headerError ? /* @__PURE__ */ jsxRuntime.jsx(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(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
44699
44723
|
/* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "xs", children: [
|
|
44700
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", className: "text-foreground", children:
|
|
44701
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-muted-foreground", children:
|
|
44724
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", className: "text-foreground", children: resolved.title }),
|
|
44725
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-muted-foreground", children: resolved.description }),
|
|
44702
44726
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { className: "items-center p-2 rounded bg-warning/10 border border-warning/30", gap: "xs", children: [
|
|
44703
44727
|
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", className: "text-warning font-bold", children: t("game.hint") + ":" }),
|
|
44704
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", className: "text-foreground", children:
|
|
44728
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", className: "text-foreground", children: resolved.hint })
|
|
44705
44729
|
] })
|
|
44706
44730
|
] }),
|
|
44707
44731
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { className: "flex-wrap items-start", gap: "lg", children: [
|
|
@@ -44749,14 +44773,14 @@ function StateArchitectBoard({
|
|
|
44749
44773
|
]
|
|
44750
44774
|
}
|
|
44751
44775
|
),
|
|
44752
|
-
|
|
44776
|
+
resolved.states.map((state) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
44753
44777
|
StateNode2,
|
|
44754
44778
|
{
|
|
44755
44779
|
name: state,
|
|
44756
44780
|
position: positions[state],
|
|
44757
44781
|
isCurrent: state === currentState,
|
|
44758
44782
|
isSelected: state === selectedState,
|
|
44759
|
-
isInitial: state ===
|
|
44783
|
+
isInitial: state === resolved.initialState,
|
|
44760
44784
|
onClick: () => handleStateClick(state)
|
|
44761
44785
|
},
|
|
44762
44786
|
state
|
|
@@ -44803,7 +44827,7 @@ function StateArchitectBoard({
|
|
|
44803
44827
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
44804
44828
|
VariablePanel,
|
|
44805
44829
|
{
|
|
44806
|
-
entityName:
|
|
44830
|
+
entityName: resolved.entityName,
|
|
44807
44831
|
variables
|
|
44808
44832
|
}
|
|
44809
44833
|
),
|
|
@@ -44815,15 +44839,15 @@ function StateArchitectBoard({
|
|
|
44815
44839
|
!r.passed && /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", className: "text-error", children: t("stateArchitect.gotState", { state: r.actualState }) })
|
|
44816
44840
|
] }, i))
|
|
44817
44841
|
] }),
|
|
44818
|
-
|
|
44842
|
+
resolved.showCodeView !== false && /* @__PURE__ */ jsxRuntime.jsx(CodeView, { data: codeData, label: "View Code" })
|
|
44819
44843
|
] })
|
|
44820
44844
|
] }),
|
|
44821
|
-
playState === "success" && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "p-4 rounded-container bg-success/20 border border-success text-center", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h5", className: "text-success", children:
|
|
44845
|
+
playState === "success" && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "p-4 rounded-container bg-success/20 border border-success text-center", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h5", className: "text-success", children: resolved.successMessage || t("stateArchitect.allPassed") }) }),
|
|
44822
44846
|
playState === "fail" && /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", children: [
|
|
44823
44847
|
/* @__PURE__ */ jsxRuntime.jsx(Box, { className: "p-4 rounded-container bg-warning/10 border border-warning/30 text-center", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body1", className: "text-foreground font-medium", children: t(ENCOURAGEMENT_KEYS3[Math.min(attempts - 1, ENCOURAGEMENT_KEYS3.length - 1)] ?? ENCOURAGEMENT_KEYS3[0]) }) }),
|
|
44824
|
-
attempts >= 3 &&
|
|
44848
|
+
attempts >= 3 && resolved.hint && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "p-3 rounded-container bg-accent/10 border border-accent/30", children: /* @__PURE__ */ jsxRuntime.jsxs(HStack, { className: "items-start", gap: "xs", children: [
|
|
44825
44849
|
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-accent font-bold shrink-0", children: "\u{1F4A1} " + t("game.hint") + ":" }),
|
|
44826
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-foreground", children:
|
|
44850
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-foreground", children: resolved.hint })
|
|
44827
44851
|
] }) })
|
|
44828
44852
|
] }),
|
|
44829
44853
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", children: [
|
|
@@ -45679,8 +45703,9 @@ var init_useBattleState = __esm({
|
|
|
45679
45703
|
}
|
|
45680
45704
|
});
|
|
45681
45705
|
function UncontrolledBattleBoard({ entity, ...rest }) {
|
|
45706
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
45682
45707
|
const battleState = useBattleState(
|
|
45683
|
-
|
|
45708
|
+
resolved?.initialUnits ?? [],
|
|
45684
45709
|
{
|
|
45685
45710
|
tileClickEvent: rest.tileClickEvent,
|
|
45686
45711
|
unitClickEvent: rest.unitClickEvent,
|
|
@@ -45697,12 +45722,13 @@ function UncontrolledBattleBoard({ entity, ...rest }) {
|
|
|
45697
45722
|
calculateDamage: rest.calculateDamage
|
|
45698
45723
|
}
|
|
45699
45724
|
);
|
|
45725
|
+
if (!resolved) return null;
|
|
45700
45726
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
45701
45727
|
BattleBoard,
|
|
45702
45728
|
{
|
|
45703
45729
|
...rest,
|
|
45704
45730
|
entity: {
|
|
45705
|
-
...
|
|
45731
|
+
...resolved,
|
|
45706
45732
|
units: battleState.units,
|
|
45707
45733
|
phase: battleState.phase,
|
|
45708
45734
|
turn: battleState.turn,
|
|
@@ -46405,6 +46431,7 @@ var init_component_registry_generated = __esm({
|
|
|
46405
46431
|
init_StatsOrganism();
|
|
46406
46432
|
init_StatusDot();
|
|
46407
46433
|
init_StatusEffect();
|
|
46434
|
+
init_StepFlow();
|
|
46408
46435
|
init_StepFlowOrganism();
|
|
46409
46436
|
init_SvgBranch();
|
|
46410
46437
|
init_SvgConnection();
|
|
@@ -46723,6 +46750,7 @@ var init_component_registry_generated = __esm({
|
|
|
46723
46750
|
"StatsOrganism": StatsOrganism,
|
|
46724
46751
|
"StatusDot": StatusDot,
|
|
46725
46752
|
"StatusEffect": StatusEffect,
|
|
46753
|
+
"StepFlow": StepFlow,
|
|
46726
46754
|
"StepFlowOrganism": StepFlowOrganism,
|
|
46727
46755
|
"SvgBranch": SvgBranch,
|
|
46728
46756
|
"SvgConnection": SvgConnection,
|