@almadar/ui 5.34.0 → 5.36.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 +228 -206
- package/dist/avl/index.js +228 -206
- package/dist/components/game/organisms/puzzles/builder/BuilderBoard.d.ts +18 -5
- package/dist/components/game/organisms/puzzles/classifier/ClassifierBoard.d.ts +21 -3
- package/dist/components/game/organisms/puzzles/debugger/DebuggerBoard.d.ts +12 -2
- package/dist/components/game/organisms/puzzles/negotiator/NegotiatorBoard.d.ts +13 -3
- package/dist/components/game/organisms/puzzles/simulator/SimulatorBoard.d.ts +22 -7
- package/dist/components/index.cjs +228 -206
- package/dist/components/index.js +228 -206
- package/dist/providers/index.cjs +228 -206
- package/dist/providers/index.js +228 -206
- package/dist/runtime/index.cjs +228 -206
- package/dist/runtime/index.js +228 -206
- package/package.json +1 -1
package/dist/components/index.js
CHANGED
|
@@ -7949,7 +7949,7 @@ var init_AboutPageTemplate = __esm({
|
|
|
7949
7949
|
const resolved = entity && typeof entity === "object" && !Array.isArray(entity) ? entity : void 0;
|
|
7950
7950
|
if (!resolved) return null;
|
|
7951
7951
|
return /* @__PURE__ */ jsxs(VStack, { gap: "none", className: cn("w-full", className), children: [
|
|
7952
|
-
/* @__PURE__ */ jsx(
|
|
7952
|
+
resolved.hero && /* @__PURE__ */ jsx(
|
|
7953
7953
|
HeroSection,
|
|
7954
7954
|
{
|
|
7955
7955
|
tag: resolved.hero.tag,
|
|
@@ -15929,61 +15929,53 @@ var init_Breadcrumb = __esm({
|
|
|
15929
15929
|
function BuilderBoard({
|
|
15930
15930
|
entity,
|
|
15931
15931
|
completeEvent = "PUZZLE_COMPLETE",
|
|
15932
|
+
placeEvent,
|
|
15933
|
+
checkEvent,
|
|
15934
|
+
playAgainEvent,
|
|
15932
15935
|
className
|
|
15933
15936
|
}) {
|
|
15934
15937
|
const { emit } = useEventBus();
|
|
15935
15938
|
const { t } = useTranslate();
|
|
15936
15939
|
const resolved = boardEntity(entity);
|
|
15937
|
-
const [placements, setPlacements] = useState({});
|
|
15938
15940
|
const [headerError, setHeaderError] = useState(false);
|
|
15939
|
-
const [
|
|
15940
|
-
const [attempts, setAttempts] = useState(0);
|
|
15941
|
-
const [showHint, setShowHint] = useState(false);
|
|
15941
|
+
const [selectedComponent, setSelectedComponent] = useState(null);
|
|
15942
15942
|
const components = Array.isArray(resolved?.components) ? resolved.components : [];
|
|
15943
15943
|
const slots = Array.isArray(resolved?.slots) ? resolved.slots : [];
|
|
15944
|
+
const placements = {};
|
|
15945
|
+
for (const slot of slots) {
|
|
15946
|
+
if (slot.placedComponentId) placements[slot.id] = slot.placedComponentId;
|
|
15947
|
+
}
|
|
15948
|
+
const attempts = num(resolved?.attempts);
|
|
15949
|
+
const result = str(resolved?.result) || "none";
|
|
15950
|
+
const submitted = result === "win";
|
|
15944
15951
|
const usedComponentIds = new Set(Object.values(placements));
|
|
15945
15952
|
const availableComponents = components.filter((c) => !usedComponentIds.has(c.id));
|
|
15946
|
-
const
|
|
15947
|
-
const allPlaced = Object.keys(placements).length === slots.length;
|
|
15953
|
+
const allPlaced = slots.length > 0 && slots.every((s) => Boolean(placements[s.id]));
|
|
15948
15954
|
const results = submitted ? slots.map((slot) => ({
|
|
15949
15955
|
slot,
|
|
15950
15956
|
placed: placements[slot.id],
|
|
15951
|
-
correct: placements[slot.id] === slot.
|
|
15957
|
+
correct: placements[slot.id] === slot.requiredComponentId
|
|
15952
15958
|
})) : [];
|
|
15953
|
-
const
|
|
15959
|
+
const showHint = attempts >= 2 && Boolean(str(resolved?.hint));
|
|
15954
15960
|
const handlePlaceComponent = (slotId) => {
|
|
15955
15961
|
if (submitted || !selectedComponent) return;
|
|
15956
|
-
|
|
15962
|
+
if (placeEvent) emit(`UI:${placeEvent}`, { slotId, componentId: selectedComponent });
|
|
15957
15963
|
setSelectedComponent(null);
|
|
15958
15964
|
};
|
|
15959
15965
|
const handleRemoveFromSlot = (slotId) => {
|
|
15960
15966
|
if (submitted) return;
|
|
15961
|
-
|
|
15962
|
-
const next = { ...prev };
|
|
15963
|
-
delete next[slotId];
|
|
15964
|
-
return next;
|
|
15965
|
-
});
|
|
15967
|
+
if (placeEvent) emit(`UI:${placeEvent}`, { slotId, componentId: "" });
|
|
15966
15968
|
};
|
|
15967
|
-
const handleSubmit =
|
|
15968
|
-
|
|
15969
|
-
|
|
15970
|
-
|
|
15971
|
-
if (correct) {
|
|
15969
|
+
const handleSubmit = () => {
|
|
15970
|
+
if (checkEvent) emit(`UI:${checkEvent}`, {});
|
|
15971
|
+
const solved = slots.length > 0 && slots.every((s) => placements[s.id] === s.requiredComponentId);
|
|
15972
|
+
if (solved && completeEvent) {
|
|
15972
15973
|
emit(`UI:${completeEvent}`, { success: true, attempts: attempts + 1 });
|
|
15973
15974
|
}
|
|
15974
|
-
}, [slots, placements, attempts, completeEvent, emit]);
|
|
15975
|
-
const handleReset = () => {
|
|
15976
|
-
setSubmitted(false);
|
|
15977
|
-
if (attempts >= 2 && str(resolved?.hint)) {
|
|
15978
|
-
setShowHint(true);
|
|
15979
|
-
}
|
|
15980
15975
|
};
|
|
15981
|
-
const
|
|
15982
|
-
setPlacements({});
|
|
15983
|
-
setSubmitted(false);
|
|
15976
|
+
const handlePlayAgain = () => {
|
|
15984
15977
|
setSelectedComponent(null);
|
|
15985
|
-
|
|
15986
|
-
setShowHint(false);
|
|
15978
|
+
if (playAgainEvent) emit(`UI:${playAgainEvent}`, {});
|
|
15987
15979
|
};
|
|
15988
15980
|
const getComponentById = (id) => components.find((c) => c.id === id);
|
|
15989
15981
|
if (!resolved) return null;
|
|
@@ -16033,13 +16025,13 @@ function BuilderBoard({
|
|
|
16033
16025
|
/* @__PURE__ */ jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: t("builder.blueprint") }),
|
|
16034
16026
|
/* @__PURE__ */ jsx(VStack, { gap: "sm", children: slots.map((slot) => {
|
|
16035
16027
|
const placedComp = placements[slot.id] ? getComponentById(placements[slot.id]) : null;
|
|
16036
|
-
const
|
|
16028
|
+
const result2 = results.find((r) => r.slot.id === slot.id);
|
|
16037
16029
|
return /* @__PURE__ */ jsxs(
|
|
16038
16030
|
HStack,
|
|
16039
16031
|
{
|
|
16040
16032
|
gap: "sm",
|
|
16041
16033
|
align: "center",
|
|
16042
|
-
className: `p-3 border-2 rounded ${
|
|
16034
|
+
className: `p-3 border-2 rounded ${result2 ? result2.correct ? "border-success" : "border-error" : selectedComponent ? "border-dashed border-foreground cursor-pointer" : "border-border"}`,
|
|
16043
16035
|
onClick: () => handlePlaceComponent(slot.id),
|
|
16044
16036
|
children: [
|
|
16045
16037
|
/* @__PURE__ */ jsxs(VStack, { gap: "none", className: "flex-1", children: [
|
|
@@ -16054,7 +16046,7 @@ function BuilderBoard({
|
|
|
16054
16046
|
] }) : null,
|
|
16055
16047
|
placedComp.label
|
|
16056
16048
|
] }),
|
|
16057
|
-
|
|
16049
|
+
result2 && /* @__PURE__ */ jsx(Icon, { icon: result2.correct ? CheckCircle : XCircle, size: "sm", className: result2.correct ? "text-success" : "text-error" })
|
|
16058
16050
|
] }) : /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: t("builder.empty") })
|
|
16059
16051
|
]
|
|
16060
16052
|
},
|
|
@@ -16063,16 +16055,16 @@ function BuilderBoard({
|
|
|
16063
16055
|
}) })
|
|
16064
16056
|
] }) }),
|
|
16065
16057
|
submitted && /* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", children: [
|
|
16066
|
-
/* @__PURE__ */ jsx(Icon, { icon:
|
|
16067
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "bold", children:
|
|
16058
|
+
/* @__PURE__ */ jsx(Icon, { icon: CheckCircle, size: "lg", className: "text-success" }),
|
|
16059
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "bold", children: str(resolved.successMessage) || t("builder.success") })
|
|
16068
16060
|
] }) }),
|
|
16069
16061
|
showHint && hint && /* @__PURE__ */ jsx(Card, { className: "p-4 border-l-4 border-l-warning", children: /* @__PURE__ */ jsx(Typography, { variant: "body", children: hint }) }),
|
|
16070
16062
|
/* @__PURE__ */ jsxs(HStack, { gap: "sm", justify: "center", children: [
|
|
16071
|
-
!submitted
|
|
16063
|
+
!submitted && /* @__PURE__ */ jsxs(Button, { variant: "primary", onClick: handleSubmit, disabled: !allPlaced, children: [
|
|
16072
16064
|
/* @__PURE__ */ jsx(Icon, { icon: Wrench, size: "sm" }),
|
|
16073
16065
|
t("builder.build")
|
|
16074
|
-
] })
|
|
16075
|
-
/* @__PURE__ */ jsxs(Button, { variant: "secondary", onClick:
|
|
16066
|
+
] }),
|
|
16067
|
+
/* @__PURE__ */ jsxs(Button, { variant: "secondary", onClick: handlePlayAgain, children: [
|
|
16076
16068
|
/* @__PURE__ */ jsx(Icon, { icon: RotateCcw, size: "sm" }),
|
|
16077
16069
|
t("builder.reset")
|
|
16078
16070
|
] })
|
|
@@ -19574,57 +19566,84 @@ var init_ChoiceButton = __esm({
|
|
|
19574
19566
|
function ClassifierBoard({
|
|
19575
19567
|
entity,
|
|
19576
19568
|
completeEvent = "PUZZLE_COMPLETE",
|
|
19569
|
+
assignEvent,
|
|
19570
|
+
checkEvent,
|
|
19571
|
+
playAgainEvent,
|
|
19577
19572
|
className
|
|
19578
19573
|
}) {
|
|
19579
19574
|
const { emit } = useEventBus();
|
|
19580
19575
|
const { t } = useTranslate();
|
|
19581
19576
|
const resolved = boardEntity(entity);
|
|
19582
|
-
const [
|
|
19577
|
+
const [localAssignments, setLocalAssignments] = useState({});
|
|
19583
19578
|
const [headerError, setHeaderError] = useState(false);
|
|
19584
|
-
const [
|
|
19585
|
-
const [
|
|
19579
|
+
const [localSubmitted, setLocalSubmitted] = useState(false);
|
|
19580
|
+
const [localAttempts, setLocalAttempts] = useState(0);
|
|
19586
19581
|
const [showHint, setShowHint] = useState(false);
|
|
19587
19582
|
const items = Array.isArray(resolved?.items) ? resolved.items : [];
|
|
19588
19583
|
const categories = Array.isArray(resolved?.categories) ? resolved.categories : [];
|
|
19584
|
+
const entityResult = str(resolved?.result);
|
|
19585
|
+
const entityDrivesResult = entityResult.length > 0;
|
|
19586
|
+
const entityHasAssignments = items.some((item) => item.assignedCategory != null);
|
|
19587
|
+
const assignments = entityHasAssignments ? items.reduce((acc, item) => {
|
|
19588
|
+
if (item.assignedCategory != null) acc[item.id] = item.assignedCategory;
|
|
19589
|
+
return acc;
|
|
19590
|
+
}, {}) : localAssignments;
|
|
19591
|
+
const attempts = entityDrivesResult ? num(resolved?.attempts) : localAttempts;
|
|
19592
|
+
const submitted = entityDrivesResult || localSubmitted;
|
|
19589
19593
|
const unassignedItems = items.filter((item) => !assignments[item.id]);
|
|
19590
|
-
const allAssigned = Object.keys(assignments).length === items.length;
|
|
19594
|
+
const allAssigned = items.length > 0 && Object.keys(assignments).length === items.length;
|
|
19591
19595
|
const results = submitted ? items.map((item) => ({
|
|
19592
19596
|
item,
|
|
19593
19597
|
assigned: assignments[item.id],
|
|
19594
19598
|
correct: assignments[item.id] === item.correctCategory
|
|
19595
19599
|
})) : [];
|
|
19596
|
-
const allCorrect = results.length > 0 && results.every((r) => r.correct);
|
|
19600
|
+
const allCorrect = entityDrivesResult ? entityResult === "success" : results.length > 0 && results.every((r) => r.correct);
|
|
19597
19601
|
const correctCount = results.filter((r) => r.correct).length;
|
|
19598
19602
|
const handleAssign = (itemId, categoryId) => {
|
|
19599
19603
|
if (submitted) return;
|
|
19600
|
-
|
|
19604
|
+
if (assignEvent) {
|
|
19605
|
+
emit(`UI:${assignEvent}`, { itemId, categoryId });
|
|
19606
|
+
}
|
|
19607
|
+
if (!entityHasAssignments) {
|
|
19608
|
+
setLocalAssignments((prev) => ({ ...prev, [itemId]: categoryId }));
|
|
19609
|
+
}
|
|
19601
19610
|
};
|
|
19602
19611
|
const handleUnassign = (itemId) => {
|
|
19603
19612
|
if (submitted) return;
|
|
19604
|
-
|
|
19605
|
-
|
|
19606
|
-
|
|
19607
|
-
|
|
19608
|
-
|
|
19613
|
+
if (!entityHasAssignments) {
|
|
19614
|
+
setLocalAssignments((prev) => {
|
|
19615
|
+
const next = { ...prev };
|
|
19616
|
+
delete next[itemId];
|
|
19617
|
+
return next;
|
|
19618
|
+
});
|
|
19619
|
+
}
|
|
19609
19620
|
};
|
|
19610
19621
|
const handleSubmit = useCallback(() => {
|
|
19611
|
-
|
|
19612
|
-
|
|
19613
|
-
|
|
19614
|
-
if (
|
|
19615
|
-
|
|
19622
|
+
if (checkEvent) {
|
|
19623
|
+
emit(`UI:${checkEvent}`, {});
|
|
19624
|
+
}
|
|
19625
|
+
if (!entityDrivesResult) {
|
|
19626
|
+
setLocalSubmitted(true);
|
|
19627
|
+
setLocalAttempts((a) => a + 1);
|
|
19628
|
+
const correct = items.every((item) => assignments[item.id] === item.correctCategory);
|
|
19629
|
+
if (correct) {
|
|
19630
|
+
emit(`UI:${completeEvent}`, { success: true, attempts: attempts + 1 });
|
|
19631
|
+
}
|
|
19616
19632
|
}
|
|
19617
|
-
}, [items, assignments, attempts, completeEvent, emit]);
|
|
19633
|
+
}, [checkEvent, entityDrivesResult, items, assignments, attempts, completeEvent, emit]);
|
|
19618
19634
|
const handleReset = () => {
|
|
19619
|
-
|
|
19635
|
+
if (!entityDrivesResult) setLocalSubmitted(false);
|
|
19620
19636
|
if (attempts >= 2 && str(resolved?.hint)) {
|
|
19621
19637
|
setShowHint(true);
|
|
19622
19638
|
}
|
|
19623
19639
|
};
|
|
19624
19640
|
const handleFullReset = () => {
|
|
19625
|
-
|
|
19626
|
-
|
|
19627
|
-
|
|
19641
|
+
if (playAgainEvent) {
|
|
19642
|
+
emit(`UI:${playAgainEvent}`, {});
|
|
19643
|
+
}
|
|
19644
|
+
setLocalAssignments({});
|
|
19645
|
+
setLocalSubmitted(false);
|
|
19646
|
+
setLocalAttempts(0);
|
|
19628
19647
|
setShowHint(false);
|
|
19629
19648
|
};
|
|
19630
19649
|
if (!resolved) return null;
|
|
@@ -29163,13 +29182,13 @@ var init_MapView = __esm({
|
|
|
29163
29182
|
shadowSize: [41, 41]
|
|
29164
29183
|
});
|
|
29165
29184
|
L.Marker.prototype.options.icon = defaultIcon;
|
|
29166
|
-
const { useEffect:
|
|
29185
|
+
const { useEffect: useEffect73, useRef: useRef70, useCallback: useCallback113, useState: useState105 } = React77__default;
|
|
29167
29186
|
const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
|
|
29168
29187
|
const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
|
|
29169
29188
|
function MapUpdater({ centerLat, centerLng, zoom }) {
|
|
29170
29189
|
const map = useMap();
|
|
29171
|
-
const prevRef =
|
|
29172
|
-
|
|
29190
|
+
const prevRef = useRef70({ centerLat, centerLng, zoom });
|
|
29191
|
+
useEffect73(() => {
|
|
29173
29192
|
const prev = prevRef.current;
|
|
29174
29193
|
if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
|
|
29175
29194
|
map.setView([centerLat, centerLng], zoom);
|
|
@@ -29180,7 +29199,7 @@ var init_MapView = __esm({
|
|
|
29180
29199
|
}
|
|
29181
29200
|
function MapClickHandler({ onMapClick }) {
|
|
29182
29201
|
const map = useMap();
|
|
29183
|
-
|
|
29202
|
+
useEffect73(() => {
|
|
29184
29203
|
if (!onMapClick) return;
|
|
29185
29204
|
const handler = (e) => {
|
|
29186
29205
|
onMapClick(e.latlng.lat, e.latlng.lng);
|
|
@@ -29209,7 +29228,7 @@ var init_MapView = __esm({
|
|
|
29209
29228
|
}) {
|
|
29210
29229
|
const eventBus = useEventBus2();
|
|
29211
29230
|
const [clickedPosition, setClickedPosition] = useState105(null);
|
|
29212
|
-
const handleMapClick =
|
|
29231
|
+
const handleMapClick = useCallback113((lat, lng) => {
|
|
29213
29232
|
if (showClickedPin) {
|
|
29214
29233
|
setClickedPosition({ lat, lng });
|
|
29215
29234
|
}
|
|
@@ -29218,7 +29237,7 @@ var init_MapView = __esm({
|
|
|
29218
29237
|
eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
|
|
29219
29238
|
}
|
|
29220
29239
|
}, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
|
|
29221
|
-
const handleMarkerClick =
|
|
29240
|
+
const handleMarkerClick = useCallback113((marker) => {
|
|
29222
29241
|
onMarkerClick?.(marker);
|
|
29223
29242
|
if (markerClickEvent) {
|
|
29224
29243
|
eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
|
|
@@ -38652,51 +38671,52 @@ var init_DataTable = __esm({
|
|
|
38652
38671
|
function DebuggerBoard({
|
|
38653
38672
|
entity,
|
|
38654
38673
|
completeEvent = "PUZZLE_COMPLETE",
|
|
38674
|
+
toggleFlagEvent,
|
|
38675
|
+
checkEvent,
|
|
38676
|
+
playAgainEvent,
|
|
38655
38677
|
className
|
|
38656
38678
|
}) {
|
|
38657
38679
|
const { emit } = useEventBus();
|
|
38658
38680
|
const { t } = useTranslate();
|
|
38659
38681
|
const resolved = boardEntity(entity);
|
|
38660
|
-
const [flaggedLines, setFlaggedLines] = useState(/* @__PURE__ */ new Set());
|
|
38661
38682
|
const [headerError, setHeaderError] = useState(false);
|
|
38662
|
-
const [submitted, setSubmitted] = useState(false);
|
|
38663
|
-
const [attempts, setAttempts] = useState(0);
|
|
38664
38683
|
const [showHint, setShowHint] = useState(false);
|
|
38684
|
+
const lines = Array.isArray(resolved?.lines) ? resolved.lines : [];
|
|
38685
|
+
const result = resolved?.result ?? null;
|
|
38686
|
+
const attempts = num(resolved?.attempts);
|
|
38687
|
+
const submitted = result != null;
|
|
38688
|
+
const bugLines = lines.filter((l) => l.isBug);
|
|
38689
|
+
const flaggedLines = lines.filter((l) => l.isFlagged);
|
|
38690
|
+
const correctFlags = lines.filter((l) => l.isBug && l.isFlagged);
|
|
38691
|
+
const falseFlags = lines.filter((l) => !l.isBug && l.isFlagged);
|
|
38692
|
+
const allCorrect = result === "win";
|
|
38665
38693
|
const toggleLine = (lineId) => {
|
|
38666
38694
|
if (submitted) return;
|
|
38667
|
-
|
|
38668
|
-
|
|
38669
|
-
|
|
38670
|
-
next.delete(lineId);
|
|
38671
|
-
} else {
|
|
38672
|
-
next.add(lineId);
|
|
38673
|
-
}
|
|
38674
|
-
return next;
|
|
38675
|
-
});
|
|
38695
|
+
if (toggleFlagEvent) {
|
|
38696
|
+
emit(`UI:${toggleFlagEvent}`, { lineId });
|
|
38697
|
+
}
|
|
38676
38698
|
};
|
|
38677
|
-
const lines = Array.isArray(resolved?.lines) ? resolved.lines : [];
|
|
38678
|
-
const bugLines = lines.filter((l) => l.isBug);
|
|
38679
|
-
const correctFlags = lines.filter((l) => l.isBug && flaggedLines.has(l.id));
|
|
38680
|
-
const falseFlags = lines.filter((l) => !l.isBug && flaggedLines.has(l.id));
|
|
38681
|
-
const allCorrect = submitted && correctFlags.length === bugLines.length && falseFlags.length === 0;
|
|
38682
38699
|
const handleSubmit = useCallback(() => {
|
|
38683
|
-
|
|
38684
|
-
|
|
38700
|
+
if (checkEvent) {
|
|
38701
|
+
emit(`UI:${checkEvent}`, {});
|
|
38702
|
+
}
|
|
38685
38703
|
const correct = correctFlags.length === bugLines.length && falseFlags.length === 0;
|
|
38686
38704
|
if (correct) {
|
|
38687
38705
|
emit(`UI:${completeEvent}`, { success: true, attempts: attempts + 1 });
|
|
38688
38706
|
}
|
|
38689
|
-
}, [correctFlags.length, bugLines.length, falseFlags.length, attempts, completeEvent, emit]);
|
|
38707
|
+
}, [checkEvent, correctFlags.length, bugLines.length, falseFlags.length, attempts, completeEvent, emit]);
|
|
38690
38708
|
const handleReset = () => {
|
|
38691
|
-
|
|
38709
|
+
if (playAgainEvent) {
|
|
38710
|
+
emit(`UI:${playAgainEvent}`, {});
|
|
38711
|
+
}
|
|
38692
38712
|
if (attempts >= 2 && str(resolved?.hint)) {
|
|
38693
38713
|
setShowHint(true);
|
|
38694
38714
|
}
|
|
38695
38715
|
};
|
|
38696
38716
|
const handleFullReset = () => {
|
|
38697
|
-
|
|
38698
|
-
|
|
38699
|
-
|
|
38717
|
+
if (playAgainEvent) {
|
|
38718
|
+
emit(`UI:${playAgainEvent}`, {});
|
|
38719
|
+
}
|
|
38700
38720
|
setShowHint(false);
|
|
38701
38721
|
};
|
|
38702
38722
|
if (!resolved) return null;
|
|
@@ -38724,7 +38744,7 @@ function DebuggerBoard({
|
|
|
38724
38744
|
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: t("debugger.findBugs", { count: String(num(resolved.bugCount)) }) })
|
|
38725
38745
|
] }) }),
|
|
38726
38746
|
/* @__PURE__ */ jsx(Card, { className: "p-0 overflow-hidden", children: /* @__PURE__ */ jsx(VStack, { gap: "none", children: lines.map((line, i) => {
|
|
38727
|
-
const isFlagged =
|
|
38747
|
+
const isFlagged = !!line.isFlagged;
|
|
38728
38748
|
let lineStyle = "";
|
|
38729
38749
|
if (submitted) {
|
|
38730
38750
|
if (line.isBug && isFlagged) lineStyle = "bg-success/10";
|
|
@@ -38758,9 +38778,9 @@ function DebuggerBoard({
|
|
|
38758
38778
|
/* @__PURE__ */ jsx(
|
|
38759
38779
|
Icon,
|
|
38760
38780
|
{
|
|
38761
|
-
icon:
|
|
38781
|
+
icon: line.isFlagged ? CheckCircle : XCircle,
|
|
38762
38782
|
size: "xs",
|
|
38763
|
-
className:
|
|
38783
|
+
className: line.isFlagged ? "text-success mt-0.5" : "text-warning mt-0.5"
|
|
38764
38784
|
}
|
|
38765
38785
|
),
|
|
38766
38786
|
/* @__PURE__ */ jsxs(VStack, { gap: "none", children: [
|
|
@@ -38771,7 +38791,7 @@ function DebuggerBoard({
|
|
|
38771
38791
|
] }) }),
|
|
38772
38792
|
showHint && hint && /* @__PURE__ */ jsx(Card, { className: "p-4 border-l-4 border-l-warning", children: /* @__PURE__ */ jsx(Typography, { variant: "body", children: hint }) }),
|
|
38773
38793
|
/* @__PURE__ */ jsxs(HStack, { gap: "sm", justify: "center", children: [
|
|
38774
|
-
!submitted ? /* @__PURE__ */ jsxs(Button, { variant: "primary", onClick: handleSubmit, disabled: flaggedLines.
|
|
38794
|
+
!submitted ? /* @__PURE__ */ jsxs(Button, { variant: "primary", onClick: handleSubmit, disabled: flaggedLines.length === 0, children: [
|
|
38775
38795
|
/* @__PURE__ */ jsx(Icon, { icon: Send, size: "sm" }),
|
|
38776
38796
|
t("debugger.submit")
|
|
38777
38797
|
] }) : !allCorrect ? /* @__PURE__ */ jsx(Button, { variant: "primary", onClick: handleReset, children: t("debugger.tryAgain") }) : null,
|
|
@@ -40104,7 +40124,7 @@ var init_FeatureDetailPageTemplate = __esm({
|
|
|
40104
40124
|
const resolved = entity && typeof entity === "object" && !Array.isArray(entity) ? entity : void 0;
|
|
40105
40125
|
if (!resolved) return null;
|
|
40106
40126
|
return /* @__PURE__ */ jsxs(VStack, { gap: "none", className: cn("w-full", className), children: [
|
|
40107
|
-
/* @__PURE__ */ jsx(
|
|
40127
|
+
resolved.hero && /* @__PURE__ */ jsx(
|
|
40108
40128
|
HeroSection,
|
|
40109
40129
|
{
|
|
40110
40130
|
tag: resolved.hero.tag,
|
|
@@ -41631,7 +41651,7 @@ var init_LandingPageTemplate = __esm({
|
|
|
41631
41651
|
const resolved = entity && typeof entity === "object" && !Array.isArray(entity) ? entity : void 0;
|
|
41632
41652
|
if (!resolved) return null;
|
|
41633
41653
|
return /* @__PURE__ */ jsxs(VStack, { gap: "none", className: cn("w-full", className), children: [
|
|
41634
|
-
/* @__PURE__ */ jsx(
|
|
41654
|
+
resolved.hero && /* @__PURE__ */ jsx(
|
|
41635
41655
|
HeroSection,
|
|
41636
41656
|
{
|
|
41637
41657
|
tag: resolved.hero.tag,
|
|
@@ -42731,6 +42751,9 @@ function getOpponentAction(strategy, actions, history) {
|
|
|
42731
42751
|
function NegotiatorBoard({
|
|
42732
42752
|
entity,
|
|
42733
42753
|
completeEvent = "PUZZLE_COMPLETE",
|
|
42754
|
+
playRoundEvent,
|
|
42755
|
+
finishEvent,
|
|
42756
|
+
playAgainEvent,
|
|
42734
42757
|
className
|
|
42735
42758
|
}) {
|
|
42736
42759
|
const { emit } = useEventBus();
|
|
@@ -42739,13 +42762,14 @@ function NegotiatorBoard({
|
|
|
42739
42762
|
const [history, setHistory] = useState([]);
|
|
42740
42763
|
const [headerError, setHeaderError] = useState(false);
|
|
42741
42764
|
const [showHint, setShowHint] = useState(false);
|
|
42742
|
-
const totalRounds = num(resolved?.
|
|
42765
|
+
const totalRounds = num(resolved?.maxRounds);
|
|
42743
42766
|
const targetScore = num(resolved?.targetScore);
|
|
42744
|
-
const currentRound =
|
|
42745
|
-
const
|
|
42746
|
-
const playerTotal =
|
|
42767
|
+
const currentRound = num(resolved?.round);
|
|
42768
|
+
const result = str(resolved?.result) || "none";
|
|
42769
|
+
const playerTotal = num(resolved?.score);
|
|
42770
|
+
const isComplete = result !== "none" || totalRounds > 0 && currentRound >= totalRounds;
|
|
42771
|
+
const won = result === "win";
|
|
42747
42772
|
const opponentTotal = history.reduce((s, r) => s + r.opponentPayoff, 0);
|
|
42748
|
-
const won = isComplete && playerTotal >= targetScore;
|
|
42749
42773
|
const actions = Array.isArray(resolved?.actions) ? resolved.actions : [];
|
|
42750
42774
|
const payoffMatrix = Array.isArray(resolved?.payoffMatrix) ? resolved.payoffMatrix : [];
|
|
42751
42775
|
const handleAction = useCallback((actionId) => {
|
|
@@ -42754,29 +42778,45 @@ function NegotiatorBoard({
|
|
|
42754
42778
|
const payoff = payoffMatrix.find(
|
|
42755
42779
|
(p2) => p2.playerAction === actionId && p2.opponentAction === opponentAction
|
|
42756
42780
|
);
|
|
42757
|
-
const
|
|
42758
|
-
|
|
42759
|
-
|
|
42760
|
-
|
|
42761
|
-
|
|
42762
|
-
|
|
42763
|
-
|
|
42764
|
-
|
|
42765
|
-
|
|
42766
|
-
|
|
42767
|
-
|
|
42768
|
-
|
|
42769
|
-
|
|
42770
|
-
|
|
42771
|
-
|
|
42781
|
+
const playerPayoff = payoff?.playerPayoff ?? 0;
|
|
42782
|
+
setHistory((prev) => [
|
|
42783
|
+
...prev,
|
|
42784
|
+
{
|
|
42785
|
+
round: prev.length + 1,
|
|
42786
|
+
playerAction: actionId,
|
|
42787
|
+
opponentAction,
|
|
42788
|
+
playerPayoff,
|
|
42789
|
+
opponentPayoff: payoff?.opponentPayoff ?? 0
|
|
42790
|
+
}
|
|
42791
|
+
]);
|
|
42792
|
+
if (playRoundEvent) {
|
|
42793
|
+
emit(`UI:${playRoundEvent}`, { playerAction: actionId, payoff: playerPayoff });
|
|
42794
|
+
}
|
|
42795
|
+
if (totalRounds > 0 && currentRound + 1 >= totalRounds) {
|
|
42796
|
+
if (finishEvent) {
|
|
42797
|
+
emit(`UI:${finishEvent}`, {});
|
|
42798
|
+
}
|
|
42799
|
+
if (str(resolved?.hint)) {
|
|
42772
42800
|
setShowHint(true);
|
|
42773
42801
|
}
|
|
42774
42802
|
}
|
|
42775
|
-
}, [isComplete, resolved, totalRounds,
|
|
42776
|
-
const handleReset = () => {
|
|
42803
|
+
}, [isComplete, resolved, totalRounds, currentRound, actions, payoffMatrix, history, playRoundEvent, finishEvent, emit]);
|
|
42804
|
+
const handleReset = useCallback(() => {
|
|
42777
42805
|
setHistory([]);
|
|
42778
42806
|
setShowHint(false);
|
|
42779
|
-
|
|
42807
|
+
if (playAgainEvent) {
|
|
42808
|
+
emit(`UI:${playAgainEvent}`, {});
|
|
42809
|
+
}
|
|
42810
|
+
}, [playAgainEvent, emit]);
|
|
42811
|
+
const completedRef = useRef(false);
|
|
42812
|
+
useEffect(() => {
|
|
42813
|
+
if (result === "win" && !completedRef.current) {
|
|
42814
|
+
completedRef.current = true;
|
|
42815
|
+
emit(`UI:${completeEvent}`, { success: true, score: playerTotal });
|
|
42816
|
+
} else if (result === "none") {
|
|
42817
|
+
completedRef.current = false;
|
|
42818
|
+
}
|
|
42819
|
+
}, [result, playerTotal, completeEvent, emit]);
|
|
42780
42820
|
const getActionLabel = (id) => actions.find((a) => a.id === id)?.label ?? id;
|
|
42781
42821
|
if (!resolved) return null;
|
|
42782
42822
|
const theme = resolved.theme ?? void 0;
|
|
@@ -42945,7 +42985,7 @@ var init_PricingPageTemplate = __esm({
|
|
|
42945
42985
|
const resolved = entity && typeof entity === "object" && !Array.isArray(entity) ? entity : void 0;
|
|
42946
42986
|
if (!resolved) return null;
|
|
42947
42987
|
return /* @__PURE__ */ jsxs(VStack, { gap: "none", className: cn("w-full", className), children: [
|
|
42948
|
-
/* @__PURE__ */ jsx(
|
|
42988
|
+
resolved.hero && /* @__PURE__ */ jsx(
|
|
42949
42989
|
HeroSection,
|
|
42950
42990
|
{
|
|
42951
42991
|
tag: resolved.hero.tag,
|
|
@@ -45777,67 +45817,47 @@ var init_SimulationGraph = __esm({
|
|
|
45777
45817
|
function SimulatorBoard({
|
|
45778
45818
|
entity,
|
|
45779
45819
|
completeEvent = "PUZZLE_COMPLETE",
|
|
45820
|
+
setAEvent,
|
|
45821
|
+
setBEvent,
|
|
45822
|
+
checkEvent,
|
|
45823
|
+
playAgainEvent,
|
|
45780
45824
|
className
|
|
45781
45825
|
}) {
|
|
45782
45826
|
const { emit } = useEventBus();
|
|
45783
45827
|
const { t } = useTranslate();
|
|
45784
45828
|
const resolved = boardEntity(entity);
|
|
45785
45829
|
const parameters = Array.isArray(resolved?.parameters) ? resolved.parameters : [];
|
|
45786
|
-
const [values, setValues] = useState(() => {
|
|
45787
|
-
const init = {};
|
|
45788
|
-
for (const p2 of parameters) {
|
|
45789
|
-
init[p2.id] = p2.initial;
|
|
45790
|
-
}
|
|
45791
|
-
return init;
|
|
45792
|
-
});
|
|
45793
45830
|
const [headerError, setHeaderError] = useState(false);
|
|
45794
|
-
|
|
45795
|
-
const
|
|
45796
|
-
const
|
|
45797
|
-
const
|
|
45798
|
-
|
|
45799
|
-
|
|
45800
|
-
|
|
45801
|
-
|
|
45802
|
-
|
|
45803
|
-
|
|
45804
|
-
|
|
45805
|
-
const
|
|
45806
|
-
const
|
|
45807
|
-
const
|
|
45808
|
-
const
|
|
45809
|
-
|
|
45810
|
-
|
|
45811
|
-
|
|
45812
|
-
};
|
|
45813
|
-
const handleSubmit = () => {
|
|
45814
|
-
setSubmitted(true);
|
|
45815
|
-
setAttempts((a) => a + 1);
|
|
45816
|
-
if (isCorrect) {
|
|
45817
|
-
emit(`UI:${completeEvent}`, { success: true, attempts: attempts + 1 });
|
|
45818
|
-
}
|
|
45831
|
+
if (!resolved) return null;
|
|
45832
|
+
const paramA = num(resolved.paramA);
|
|
45833
|
+
const paramB = num(resolved.paramB);
|
|
45834
|
+
const output = num(resolved.output);
|
|
45835
|
+
const targetValue = num(resolved.target);
|
|
45836
|
+
const targetTolerance = num(resolved.tolerance);
|
|
45837
|
+
const attempts = num(resolved.attempts);
|
|
45838
|
+
const result = str(resolved.result);
|
|
45839
|
+
const isWin = result === "win";
|
|
45840
|
+
const isComplete = result !== "none" && result !== "";
|
|
45841
|
+
const paramAValue = parameters[0];
|
|
45842
|
+
const paramBValue = parameters[1];
|
|
45843
|
+
const sliderValues = [paramA, paramB];
|
|
45844
|
+
const sliderEvents = [setAEvent, setBEvent];
|
|
45845
|
+
const handleParameterChange = (index, value) => {
|
|
45846
|
+
if (isComplete) return;
|
|
45847
|
+
const ev = sliderEvents[index];
|
|
45848
|
+
if (ev) emit(`UI:${ev}`, { value });
|
|
45819
45849
|
};
|
|
45820
|
-
const
|
|
45821
|
-
|
|
45822
|
-
if (attempts >= 2 && str(resolved?.hint)) {
|
|
45823
|
-
setShowHint(true);
|
|
45824
|
-
}
|
|
45850
|
+
const handleCheck = () => {
|
|
45851
|
+
if (checkEvent) emit(`UI:${checkEvent}`, {});
|
|
45825
45852
|
};
|
|
45826
|
-
const
|
|
45827
|
-
|
|
45828
|
-
for (const p2 of parameters) {
|
|
45829
|
-
init[p2.id] = p2.initial;
|
|
45830
|
-
}
|
|
45831
|
-
setValues(init);
|
|
45832
|
-
setSubmitted(false);
|
|
45833
|
-
setAttempts(0);
|
|
45834
|
-
setShowHint(false);
|
|
45853
|
+
const handlePlayAgain = () => {
|
|
45854
|
+
if (playAgainEvent) emit(`UI:${playAgainEvent}`, {});
|
|
45835
45855
|
};
|
|
45836
|
-
if (!resolved) return null;
|
|
45837
45856
|
const theme = resolved.theme ?? void 0;
|
|
45838
45857
|
const themeBackground = theme?.background;
|
|
45839
45858
|
const headerImage = str(resolved.headerImage);
|
|
45840
45859
|
const hint = str(resolved.hint);
|
|
45860
|
+
const showHint = isComplete && !isWin && attempts >= 2 && Boolean(hint);
|
|
45841
45861
|
const outputLabel = str(resolved.outputLabel);
|
|
45842
45862
|
const outputUnit = str(resolved.outputUnit);
|
|
45843
45863
|
return /* @__PURE__ */ jsx(
|
|
@@ -45857,41 +45877,43 @@ function SimulatorBoard({
|
|
|
45857
45877
|
] }) }),
|
|
45858
45878
|
/* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "md", children: [
|
|
45859
45879
|
/* @__PURE__ */ jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: t("simulator.parameters") }),
|
|
45860
|
-
|
|
45861
|
-
/* @__PURE__ */ jsxs(
|
|
45862
|
-
/* @__PURE__ */
|
|
45863
|
-
|
|
45864
|
-
|
|
45865
|
-
|
|
45866
|
-
|
|
45867
|
-
|
|
45868
|
-
|
|
45869
|
-
/* @__PURE__ */ jsx(
|
|
45870
|
-
"input",
|
|
45871
|
-
{
|
|
45872
|
-
type: "range",
|
|
45873
|
-
min: param.min,
|
|
45874
|
-
max: param.max,
|
|
45875
|
-
step: param.step,
|
|
45876
|
-
value: values[param.id],
|
|
45877
|
-
onChange: (e) => handleParameterChange(param.id, Number(e.target.value)),
|
|
45878
|
-
disabled: submitted,
|
|
45879
|
-
className: "w-full accent-foreground"
|
|
45880
|
-
}
|
|
45881
|
-
),
|
|
45882
|
-
/* @__PURE__ */ jsxs(HStack, { justify: "between", children: [
|
|
45883
|
-
/* @__PURE__ */ jsxs(Typography, { variant: "caption", className: "text-muted-foreground", children: [
|
|
45884
|
-
param.min,
|
|
45885
|
-
" ",
|
|
45886
|
-
param.unit
|
|
45880
|
+
[paramAValue, paramBValue].map(
|
|
45881
|
+
(param, index) => param ? /* @__PURE__ */ jsxs(VStack, { gap: "xs", children: [
|
|
45882
|
+
/* @__PURE__ */ jsxs(HStack, { justify: "between", align: "center", children: [
|
|
45883
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "medium", children: param.label }),
|
|
45884
|
+
/* @__PURE__ */ jsxs(Badge, { size: "sm", children: [
|
|
45885
|
+
sliderValues[index],
|
|
45886
|
+
" ",
|
|
45887
|
+
param.unit
|
|
45888
|
+
] })
|
|
45887
45889
|
] }),
|
|
45888
|
-
/* @__PURE__ */
|
|
45889
|
-
|
|
45890
|
-
|
|
45891
|
-
|
|
45890
|
+
/* @__PURE__ */ jsx(
|
|
45891
|
+
"input",
|
|
45892
|
+
{
|
|
45893
|
+
type: "range",
|
|
45894
|
+
min: param.min,
|
|
45895
|
+
max: param.max,
|
|
45896
|
+
step: param.step,
|
|
45897
|
+
value: sliderValues[index],
|
|
45898
|
+
onChange: (e) => handleParameterChange(index, Number(e.target.value)),
|
|
45899
|
+
disabled: isComplete,
|
|
45900
|
+
className: "w-full accent-foreground"
|
|
45901
|
+
}
|
|
45902
|
+
),
|
|
45903
|
+
/* @__PURE__ */ jsxs(HStack, { justify: "between", children: [
|
|
45904
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "caption", className: "text-muted-foreground", children: [
|
|
45905
|
+
param.min,
|
|
45906
|
+
" ",
|
|
45907
|
+
param.unit
|
|
45908
|
+
] }),
|
|
45909
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "caption", className: "text-muted-foreground", children: [
|
|
45910
|
+
param.max,
|
|
45911
|
+
" ",
|
|
45912
|
+
param.unit
|
|
45913
|
+
] })
|
|
45892
45914
|
] })
|
|
45893
|
-
] })
|
|
45894
|
-
|
|
45915
|
+
] }, param.id ?? index) : null
|
|
45916
|
+
)
|
|
45895
45917
|
] }) }),
|
|
45896
45918
|
/* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", children: [
|
|
45897
45919
|
/* @__PURE__ */ jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: outputLabel }),
|
|
@@ -45900,9 +45922,9 @@ function SimulatorBoard({
|
|
|
45900
45922
|
" ",
|
|
45901
45923
|
outputUnit
|
|
45902
45924
|
] }),
|
|
45903
|
-
|
|
45904
|
-
/* @__PURE__ */ jsx(Icon, { icon:
|
|
45905
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body", className:
|
|
45925
|
+
isComplete && /* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
45926
|
+
/* @__PURE__ */ jsx(Icon, { icon: isWin ? CheckCircle : XCircle, size: "sm", className: isWin ? "text-success" : "text-error" }),
|
|
45927
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", className: isWin ? "text-success" : "text-error", children: isWin ? str(resolved.successMessage) || t("simulator.correct") : str(resolved.failMessage) || t("simulator.incorrect") })
|
|
45906
45928
|
] }),
|
|
45907
45929
|
/* @__PURE__ */ jsxs(Typography, { variant: "caption", className: "text-muted-foreground", children: [
|
|
45908
45930
|
t("simulator.target"),
|
|
@@ -45917,11 +45939,11 @@ function SimulatorBoard({
|
|
|
45917
45939
|
] }) }),
|
|
45918
45940
|
showHint && hint && /* @__PURE__ */ jsx(Card, { className: "p-4 border-l-4 border-l-warning", children: /* @__PURE__ */ jsx(Typography, { variant: "body", children: hint }) }),
|
|
45919
45941
|
/* @__PURE__ */ jsxs(HStack, { gap: "sm", justify: "center", children: [
|
|
45920
|
-
!
|
|
45942
|
+
!isComplete ? /* @__PURE__ */ jsxs(Button, { variant: "primary", onClick: handleCheck, children: [
|
|
45921
45943
|
/* @__PURE__ */ jsx(Icon, { icon: Play, size: "sm" }),
|
|
45922
45944
|
t("simulator.simulate")
|
|
45923
|
-
] }) :
|
|
45924
|
-
/* @__PURE__ */ jsxs(Button, { variant: "secondary", onClick:
|
|
45945
|
+
] }) : null,
|
|
45946
|
+
/* @__PURE__ */ jsxs(Button, { variant: "secondary", onClick: handlePlayAgain, children: [
|
|
45925
45947
|
/* @__PURE__ */ jsx(Icon, { icon: RotateCcw, size: "sm" }),
|
|
45926
45948
|
t("simulator.reset")
|
|
45927
45949
|
] })
|