@almadar/ui 5.35.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 +224 -202
- package/dist/avl/index.js +224 -202
- 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 +224 -202
- package/dist/components/index.js +224 -202
- package/dist/providers/index.cjs +224 -202
- package/dist/providers/index.js +224 -202
- package/dist/runtime/index.cjs +224 -202
- package/dist/runtime/index.js +224 -202
- package/package.json +1 -1
package/dist/runtime/index.js
CHANGED
|
@@ -16939,61 +16939,53 @@ var init_Breadcrumb = __esm({
|
|
|
16939
16939
|
function BuilderBoard({
|
|
16940
16940
|
entity,
|
|
16941
16941
|
completeEvent = "PUZZLE_COMPLETE",
|
|
16942
|
+
placeEvent,
|
|
16943
|
+
checkEvent,
|
|
16944
|
+
playAgainEvent,
|
|
16942
16945
|
className
|
|
16943
16946
|
}) {
|
|
16944
16947
|
const { emit } = useEventBus();
|
|
16945
16948
|
const { t } = useTranslate();
|
|
16946
16949
|
const resolved = boardEntity(entity);
|
|
16947
|
-
const [placements, setPlacements] = useState({});
|
|
16948
16950
|
const [headerError, setHeaderError] = useState(false);
|
|
16949
|
-
const [
|
|
16950
|
-
const [attempts, setAttempts] = useState(0);
|
|
16951
|
-
const [showHint, setShowHint] = useState(false);
|
|
16951
|
+
const [selectedComponent, setSelectedComponent] = useState(null);
|
|
16952
16952
|
const components = Array.isArray(resolved?.components) ? resolved.components : [];
|
|
16953
16953
|
const slots = Array.isArray(resolved?.slots) ? resolved.slots : [];
|
|
16954
|
+
const placements = {};
|
|
16955
|
+
for (const slot of slots) {
|
|
16956
|
+
if (slot.placedComponentId) placements[slot.id] = slot.placedComponentId;
|
|
16957
|
+
}
|
|
16958
|
+
const attempts = num(resolved?.attempts);
|
|
16959
|
+
const result = str(resolved?.result) || "none";
|
|
16960
|
+
const submitted = result === "win";
|
|
16954
16961
|
const usedComponentIds = new Set(Object.values(placements));
|
|
16955
16962
|
const availableComponents = components.filter((c) => !usedComponentIds.has(c.id));
|
|
16956
|
-
const
|
|
16957
|
-
const allPlaced = Object.keys(placements).length === slots.length;
|
|
16963
|
+
const allPlaced = slots.length > 0 && slots.every((s) => Boolean(placements[s.id]));
|
|
16958
16964
|
const results = submitted ? slots.map((slot) => ({
|
|
16959
16965
|
slot,
|
|
16960
16966
|
placed: placements[slot.id],
|
|
16961
|
-
correct: placements[slot.id] === slot.
|
|
16967
|
+
correct: placements[slot.id] === slot.requiredComponentId
|
|
16962
16968
|
})) : [];
|
|
16963
|
-
const
|
|
16969
|
+
const showHint = attempts >= 2 && Boolean(str(resolved?.hint));
|
|
16964
16970
|
const handlePlaceComponent = (slotId) => {
|
|
16965
16971
|
if (submitted || !selectedComponent) return;
|
|
16966
|
-
|
|
16972
|
+
if (placeEvent) emit(`UI:${placeEvent}`, { slotId, componentId: selectedComponent });
|
|
16967
16973
|
setSelectedComponent(null);
|
|
16968
16974
|
};
|
|
16969
16975
|
const handleRemoveFromSlot = (slotId) => {
|
|
16970
16976
|
if (submitted) return;
|
|
16971
|
-
|
|
16972
|
-
const next = { ...prev };
|
|
16973
|
-
delete next[slotId];
|
|
16974
|
-
return next;
|
|
16975
|
-
});
|
|
16977
|
+
if (placeEvent) emit(`UI:${placeEvent}`, { slotId, componentId: "" });
|
|
16976
16978
|
};
|
|
16977
|
-
const handleSubmit =
|
|
16978
|
-
|
|
16979
|
-
|
|
16980
|
-
|
|
16981
|
-
if (correct) {
|
|
16979
|
+
const handleSubmit = () => {
|
|
16980
|
+
if (checkEvent) emit(`UI:${checkEvent}`, {});
|
|
16981
|
+
const solved = slots.length > 0 && slots.every((s) => placements[s.id] === s.requiredComponentId);
|
|
16982
|
+
if (solved && completeEvent) {
|
|
16982
16983
|
emit(`UI:${completeEvent}`, { success: true, attempts: attempts + 1 });
|
|
16983
16984
|
}
|
|
16984
|
-
}, [slots, placements, attempts, completeEvent, emit]);
|
|
16985
|
-
const handleReset = () => {
|
|
16986
|
-
setSubmitted(false);
|
|
16987
|
-
if (attempts >= 2 && str(resolved?.hint)) {
|
|
16988
|
-
setShowHint(true);
|
|
16989
|
-
}
|
|
16990
16985
|
};
|
|
16991
|
-
const
|
|
16992
|
-
setPlacements({});
|
|
16993
|
-
setSubmitted(false);
|
|
16986
|
+
const handlePlayAgain = () => {
|
|
16994
16987
|
setSelectedComponent(null);
|
|
16995
|
-
|
|
16996
|
-
setShowHint(false);
|
|
16988
|
+
if (playAgainEvent) emit(`UI:${playAgainEvent}`, {});
|
|
16997
16989
|
};
|
|
16998
16990
|
const getComponentById = (id) => components.find((c) => c.id === id);
|
|
16999
16991
|
if (!resolved) return null;
|
|
@@ -17043,13 +17035,13 @@ function BuilderBoard({
|
|
|
17043
17035
|
/* @__PURE__ */ jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: t("builder.blueprint") }),
|
|
17044
17036
|
/* @__PURE__ */ jsx(VStack, { gap: "sm", children: slots.map((slot) => {
|
|
17045
17037
|
const placedComp = placements[slot.id] ? getComponentById(placements[slot.id]) : null;
|
|
17046
|
-
const
|
|
17038
|
+
const result2 = results.find((r) => r.slot.id === slot.id);
|
|
17047
17039
|
return /* @__PURE__ */ jsxs(
|
|
17048
17040
|
HStack,
|
|
17049
17041
|
{
|
|
17050
17042
|
gap: "sm",
|
|
17051
17043
|
align: "center",
|
|
17052
|
-
className: `p-3 border-2 rounded ${
|
|
17044
|
+
className: `p-3 border-2 rounded ${result2 ? result2.correct ? "border-success" : "border-error" : selectedComponent ? "border-dashed border-foreground cursor-pointer" : "border-border"}`,
|
|
17053
17045
|
onClick: () => handlePlaceComponent(slot.id),
|
|
17054
17046
|
children: [
|
|
17055
17047
|
/* @__PURE__ */ jsxs(VStack, { gap: "none", className: "flex-1", children: [
|
|
@@ -17064,7 +17056,7 @@ function BuilderBoard({
|
|
|
17064
17056
|
] }) : null,
|
|
17065
17057
|
placedComp.label
|
|
17066
17058
|
] }),
|
|
17067
|
-
|
|
17059
|
+
result2 && /* @__PURE__ */ jsx(Icon, { icon: result2.correct ? CheckCircle : XCircle, size: "sm", className: result2.correct ? "text-success" : "text-error" })
|
|
17068
17060
|
] }) : /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: t("builder.empty") })
|
|
17069
17061
|
]
|
|
17070
17062
|
},
|
|
@@ -17073,16 +17065,16 @@ function BuilderBoard({
|
|
|
17073
17065
|
}) })
|
|
17074
17066
|
] }) }),
|
|
17075
17067
|
submitted && /* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", children: [
|
|
17076
|
-
/* @__PURE__ */ jsx(Icon, { icon:
|
|
17077
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "bold", children:
|
|
17068
|
+
/* @__PURE__ */ jsx(Icon, { icon: CheckCircle, size: "lg", className: "text-success" }),
|
|
17069
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "bold", children: str(resolved.successMessage) || t("builder.success") })
|
|
17078
17070
|
] }) }),
|
|
17079
17071
|
showHint && hint && /* @__PURE__ */ jsx(Card, { className: "p-4 border-l-4 border-l-warning", children: /* @__PURE__ */ jsx(Typography, { variant: "body", children: hint }) }),
|
|
17080
17072
|
/* @__PURE__ */ jsxs(HStack, { gap: "sm", justify: "center", children: [
|
|
17081
|
-
!submitted
|
|
17073
|
+
!submitted && /* @__PURE__ */ jsxs(Button, { variant: "primary", onClick: handleSubmit, disabled: !allPlaced, children: [
|
|
17082
17074
|
/* @__PURE__ */ jsx(Icon, { icon: Wrench, size: "sm" }),
|
|
17083
17075
|
t("builder.build")
|
|
17084
|
-
] })
|
|
17085
|
-
/* @__PURE__ */ jsxs(Button, { variant: "secondary", onClick:
|
|
17076
|
+
] }),
|
|
17077
|
+
/* @__PURE__ */ jsxs(Button, { variant: "secondary", onClick: handlePlayAgain, children: [
|
|
17086
17078
|
/* @__PURE__ */ jsx(Icon, { icon: RotateCcw, size: "sm" }),
|
|
17087
17079
|
t("builder.reset")
|
|
17088
17080
|
] })
|
|
@@ -20538,57 +20530,84 @@ var init_ChartLegend = __esm({
|
|
|
20538
20530
|
function ClassifierBoard({
|
|
20539
20531
|
entity,
|
|
20540
20532
|
completeEvent = "PUZZLE_COMPLETE",
|
|
20533
|
+
assignEvent,
|
|
20534
|
+
checkEvent,
|
|
20535
|
+
playAgainEvent,
|
|
20541
20536
|
className
|
|
20542
20537
|
}) {
|
|
20543
20538
|
const { emit } = useEventBus();
|
|
20544
20539
|
const { t } = useTranslate();
|
|
20545
20540
|
const resolved = boardEntity(entity);
|
|
20546
|
-
const [
|
|
20541
|
+
const [localAssignments, setLocalAssignments] = useState({});
|
|
20547
20542
|
const [headerError, setHeaderError] = useState(false);
|
|
20548
|
-
const [
|
|
20549
|
-
const [
|
|
20543
|
+
const [localSubmitted, setLocalSubmitted] = useState(false);
|
|
20544
|
+
const [localAttempts, setLocalAttempts] = useState(0);
|
|
20550
20545
|
const [showHint, setShowHint] = useState(false);
|
|
20551
20546
|
const items = Array.isArray(resolved?.items) ? resolved.items : [];
|
|
20552
20547
|
const categories = Array.isArray(resolved?.categories) ? resolved.categories : [];
|
|
20548
|
+
const entityResult = str(resolved?.result);
|
|
20549
|
+
const entityDrivesResult = entityResult.length > 0;
|
|
20550
|
+
const entityHasAssignments = items.some((item) => item.assignedCategory != null);
|
|
20551
|
+
const assignments = entityHasAssignments ? items.reduce((acc, item) => {
|
|
20552
|
+
if (item.assignedCategory != null) acc[item.id] = item.assignedCategory;
|
|
20553
|
+
return acc;
|
|
20554
|
+
}, {}) : localAssignments;
|
|
20555
|
+
const attempts = entityDrivesResult ? num(resolved?.attempts) : localAttempts;
|
|
20556
|
+
const submitted = entityDrivesResult || localSubmitted;
|
|
20553
20557
|
const unassignedItems = items.filter((item) => !assignments[item.id]);
|
|
20554
|
-
const allAssigned = Object.keys(assignments).length === items.length;
|
|
20558
|
+
const allAssigned = items.length > 0 && Object.keys(assignments).length === items.length;
|
|
20555
20559
|
const results = submitted ? items.map((item) => ({
|
|
20556
20560
|
item,
|
|
20557
20561
|
assigned: assignments[item.id],
|
|
20558
20562
|
correct: assignments[item.id] === item.correctCategory
|
|
20559
20563
|
})) : [];
|
|
20560
|
-
const allCorrect = results.length > 0 && results.every((r) => r.correct);
|
|
20564
|
+
const allCorrect = entityDrivesResult ? entityResult === "success" : results.length > 0 && results.every((r) => r.correct);
|
|
20561
20565
|
const correctCount = results.filter((r) => r.correct).length;
|
|
20562
20566
|
const handleAssign = (itemId, categoryId) => {
|
|
20563
20567
|
if (submitted) return;
|
|
20564
|
-
|
|
20568
|
+
if (assignEvent) {
|
|
20569
|
+
emit(`UI:${assignEvent}`, { itemId, categoryId });
|
|
20570
|
+
}
|
|
20571
|
+
if (!entityHasAssignments) {
|
|
20572
|
+
setLocalAssignments((prev) => ({ ...prev, [itemId]: categoryId }));
|
|
20573
|
+
}
|
|
20565
20574
|
};
|
|
20566
20575
|
const handleUnassign = (itemId) => {
|
|
20567
20576
|
if (submitted) return;
|
|
20568
|
-
|
|
20569
|
-
|
|
20570
|
-
|
|
20571
|
-
|
|
20572
|
-
|
|
20577
|
+
if (!entityHasAssignments) {
|
|
20578
|
+
setLocalAssignments((prev) => {
|
|
20579
|
+
const next = { ...prev };
|
|
20580
|
+
delete next[itemId];
|
|
20581
|
+
return next;
|
|
20582
|
+
});
|
|
20583
|
+
}
|
|
20573
20584
|
};
|
|
20574
20585
|
const handleSubmit = useCallback(() => {
|
|
20575
|
-
|
|
20576
|
-
|
|
20577
|
-
|
|
20578
|
-
if (
|
|
20579
|
-
|
|
20586
|
+
if (checkEvent) {
|
|
20587
|
+
emit(`UI:${checkEvent}`, {});
|
|
20588
|
+
}
|
|
20589
|
+
if (!entityDrivesResult) {
|
|
20590
|
+
setLocalSubmitted(true);
|
|
20591
|
+
setLocalAttempts((a) => a + 1);
|
|
20592
|
+
const correct = items.every((item) => assignments[item.id] === item.correctCategory);
|
|
20593
|
+
if (correct) {
|
|
20594
|
+
emit(`UI:${completeEvent}`, { success: true, attempts: attempts + 1 });
|
|
20595
|
+
}
|
|
20580
20596
|
}
|
|
20581
|
-
}, [items, assignments, attempts, completeEvent, emit]);
|
|
20597
|
+
}, [checkEvent, entityDrivesResult, items, assignments, attempts, completeEvent, emit]);
|
|
20582
20598
|
const handleReset = () => {
|
|
20583
|
-
|
|
20599
|
+
if (!entityDrivesResult) setLocalSubmitted(false);
|
|
20584
20600
|
if (attempts >= 2 && str(resolved?.hint)) {
|
|
20585
20601
|
setShowHint(true);
|
|
20586
20602
|
}
|
|
20587
20603
|
};
|
|
20588
20604
|
const handleFullReset = () => {
|
|
20589
|
-
|
|
20590
|
-
|
|
20591
|
-
|
|
20605
|
+
if (playAgainEvent) {
|
|
20606
|
+
emit(`UI:${playAgainEvent}`, {});
|
|
20607
|
+
}
|
|
20608
|
+
setLocalAssignments({});
|
|
20609
|
+
setLocalSubmitted(false);
|
|
20610
|
+
setLocalAttempts(0);
|
|
20592
20611
|
setShowHint(false);
|
|
20593
20612
|
};
|
|
20594
20613
|
if (!resolved) return null;
|
|
@@ -28471,13 +28490,13 @@ var init_MapView = __esm({
|
|
|
28471
28490
|
shadowSize: [41, 41]
|
|
28472
28491
|
});
|
|
28473
28492
|
L.Marker.prototype.options.icon = defaultIcon;
|
|
28474
|
-
const { useEffect:
|
|
28493
|
+
const { useEffect: useEffect74, useRef: useRef68, useCallback: useCallback111, useState: useState107 } = React82__default;
|
|
28475
28494
|
const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
|
|
28476
28495
|
const { useEventBus: useEventBus3 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
|
|
28477
28496
|
function MapUpdater({ centerLat, centerLng, zoom }) {
|
|
28478
28497
|
const map = useMap();
|
|
28479
|
-
const prevRef =
|
|
28480
|
-
|
|
28498
|
+
const prevRef = useRef68({ centerLat, centerLng, zoom });
|
|
28499
|
+
useEffect74(() => {
|
|
28481
28500
|
const prev = prevRef.current;
|
|
28482
28501
|
if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
|
|
28483
28502
|
map.setView([centerLat, centerLng], zoom);
|
|
@@ -28488,7 +28507,7 @@ var init_MapView = __esm({
|
|
|
28488
28507
|
}
|
|
28489
28508
|
function MapClickHandler({ onMapClick }) {
|
|
28490
28509
|
const map = useMap();
|
|
28491
|
-
|
|
28510
|
+
useEffect74(() => {
|
|
28492
28511
|
if (!onMapClick) return;
|
|
28493
28512
|
const handler = (e) => {
|
|
28494
28513
|
onMapClick(e.latlng.lat, e.latlng.lng);
|
|
@@ -28517,7 +28536,7 @@ var init_MapView = __esm({
|
|
|
28517
28536
|
}) {
|
|
28518
28537
|
const eventBus = useEventBus3();
|
|
28519
28538
|
const [clickedPosition, setClickedPosition] = useState107(null);
|
|
28520
|
-
const handleMapClick =
|
|
28539
|
+
const handleMapClick = useCallback111((lat, lng) => {
|
|
28521
28540
|
if (showClickedPin) {
|
|
28522
28541
|
setClickedPosition({ lat, lng });
|
|
28523
28542
|
}
|
|
@@ -28526,7 +28545,7 @@ var init_MapView = __esm({
|
|
|
28526
28545
|
eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
|
|
28527
28546
|
}
|
|
28528
28547
|
}, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
|
|
28529
|
-
const handleMarkerClick =
|
|
28548
|
+
const handleMarkerClick = useCallback111((marker) => {
|
|
28530
28549
|
onMarkerClick?.(marker);
|
|
28531
28550
|
if (markerClickEvent) {
|
|
28532
28551
|
eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
|
|
@@ -37748,51 +37767,52 @@ var init_DataTable = __esm({
|
|
|
37748
37767
|
function DebuggerBoard({
|
|
37749
37768
|
entity,
|
|
37750
37769
|
completeEvent = "PUZZLE_COMPLETE",
|
|
37770
|
+
toggleFlagEvent,
|
|
37771
|
+
checkEvent,
|
|
37772
|
+
playAgainEvent,
|
|
37751
37773
|
className
|
|
37752
37774
|
}) {
|
|
37753
37775
|
const { emit } = useEventBus();
|
|
37754
37776
|
const { t } = useTranslate();
|
|
37755
37777
|
const resolved = boardEntity(entity);
|
|
37756
|
-
const [flaggedLines, setFlaggedLines] = useState(/* @__PURE__ */ new Set());
|
|
37757
37778
|
const [headerError, setHeaderError] = useState(false);
|
|
37758
|
-
const [submitted, setSubmitted] = useState(false);
|
|
37759
|
-
const [attempts, setAttempts] = useState(0);
|
|
37760
37779
|
const [showHint, setShowHint] = useState(false);
|
|
37780
|
+
const lines = Array.isArray(resolved?.lines) ? resolved.lines : [];
|
|
37781
|
+
const result = resolved?.result ?? null;
|
|
37782
|
+
const attempts = num(resolved?.attempts);
|
|
37783
|
+
const submitted = result != null;
|
|
37784
|
+
const bugLines = lines.filter((l) => l.isBug);
|
|
37785
|
+
const flaggedLines = lines.filter((l) => l.isFlagged);
|
|
37786
|
+
const correctFlags = lines.filter((l) => l.isBug && l.isFlagged);
|
|
37787
|
+
const falseFlags = lines.filter((l) => !l.isBug && l.isFlagged);
|
|
37788
|
+
const allCorrect = result === "win";
|
|
37761
37789
|
const toggleLine = (lineId) => {
|
|
37762
37790
|
if (submitted) return;
|
|
37763
|
-
|
|
37764
|
-
|
|
37765
|
-
|
|
37766
|
-
next.delete(lineId);
|
|
37767
|
-
} else {
|
|
37768
|
-
next.add(lineId);
|
|
37769
|
-
}
|
|
37770
|
-
return next;
|
|
37771
|
-
});
|
|
37791
|
+
if (toggleFlagEvent) {
|
|
37792
|
+
emit(`UI:${toggleFlagEvent}`, { lineId });
|
|
37793
|
+
}
|
|
37772
37794
|
};
|
|
37773
|
-
const lines = Array.isArray(resolved?.lines) ? resolved.lines : [];
|
|
37774
|
-
const bugLines = lines.filter((l) => l.isBug);
|
|
37775
|
-
const correctFlags = lines.filter((l) => l.isBug && flaggedLines.has(l.id));
|
|
37776
|
-
const falseFlags = lines.filter((l) => !l.isBug && flaggedLines.has(l.id));
|
|
37777
|
-
const allCorrect = submitted && correctFlags.length === bugLines.length && falseFlags.length === 0;
|
|
37778
37795
|
const handleSubmit = useCallback(() => {
|
|
37779
|
-
|
|
37780
|
-
|
|
37796
|
+
if (checkEvent) {
|
|
37797
|
+
emit(`UI:${checkEvent}`, {});
|
|
37798
|
+
}
|
|
37781
37799
|
const correct = correctFlags.length === bugLines.length && falseFlags.length === 0;
|
|
37782
37800
|
if (correct) {
|
|
37783
37801
|
emit(`UI:${completeEvent}`, { success: true, attempts: attempts + 1 });
|
|
37784
37802
|
}
|
|
37785
|
-
}, [correctFlags.length, bugLines.length, falseFlags.length, attempts, completeEvent, emit]);
|
|
37803
|
+
}, [checkEvent, correctFlags.length, bugLines.length, falseFlags.length, attempts, completeEvent, emit]);
|
|
37786
37804
|
const handleReset = () => {
|
|
37787
|
-
|
|
37805
|
+
if (playAgainEvent) {
|
|
37806
|
+
emit(`UI:${playAgainEvent}`, {});
|
|
37807
|
+
}
|
|
37788
37808
|
if (attempts >= 2 && str(resolved?.hint)) {
|
|
37789
37809
|
setShowHint(true);
|
|
37790
37810
|
}
|
|
37791
37811
|
};
|
|
37792
37812
|
const handleFullReset = () => {
|
|
37793
|
-
|
|
37794
|
-
|
|
37795
|
-
|
|
37813
|
+
if (playAgainEvent) {
|
|
37814
|
+
emit(`UI:${playAgainEvent}`, {});
|
|
37815
|
+
}
|
|
37796
37816
|
setShowHint(false);
|
|
37797
37817
|
};
|
|
37798
37818
|
if (!resolved) return null;
|
|
@@ -37820,7 +37840,7 @@ function DebuggerBoard({
|
|
|
37820
37840
|
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: t("debugger.findBugs", { count: String(num(resolved.bugCount)) }) })
|
|
37821
37841
|
] }) }),
|
|
37822
37842
|
/* @__PURE__ */ jsx(Card, { className: "p-0 overflow-hidden", children: /* @__PURE__ */ jsx(VStack, { gap: "none", children: lines.map((line, i) => {
|
|
37823
|
-
const isFlagged =
|
|
37843
|
+
const isFlagged = !!line.isFlagged;
|
|
37824
37844
|
let lineStyle = "";
|
|
37825
37845
|
if (submitted) {
|
|
37826
37846
|
if (line.isBug && isFlagged) lineStyle = "bg-success/10";
|
|
@@ -37854,9 +37874,9 @@ function DebuggerBoard({
|
|
|
37854
37874
|
/* @__PURE__ */ jsx(
|
|
37855
37875
|
Icon,
|
|
37856
37876
|
{
|
|
37857
|
-
icon:
|
|
37877
|
+
icon: line.isFlagged ? CheckCircle : XCircle,
|
|
37858
37878
|
size: "xs",
|
|
37859
|
-
className:
|
|
37879
|
+
className: line.isFlagged ? "text-success mt-0.5" : "text-warning mt-0.5"
|
|
37860
37880
|
}
|
|
37861
37881
|
),
|
|
37862
37882
|
/* @__PURE__ */ jsxs(VStack, { gap: "none", children: [
|
|
@@ -37867,7 +37887,7 @@ function DebuggerBoard({
|
|
|
37867
37887
|
] }) }),
|
|
37868
37888
|
showHint && hint && /* @__PURE__ */ jsx(Card, { className: "p-4 border-l-4 border-l-warning", children: /* @__PURE__ */ jsx(Typography, { variant: "body", children: hint }) }),
|
|
37869
37889
|
/* @__PURE__ */ jsxs(HStack, { gap: "sm", justify: "center", children: [
|
|
37870
|
-
!submitted ? /* @__PURE__ */ jsxs(Button, { variant: "primary", onClick: handleSubmit, disabled: flaggedLines.
|
|
37890
|
+
!submitted ? /* @__PURE__ */ jsxs(Button, { variant: "primary", onClick: handleSubmit, disabled: flaggedLines.length === 0, children: [
|
|
37871
37891
|
/* @__PURE__ */ jsx(Icon, { icon: Send, size: "sm" }),
|
|
37872
37892
|
t("debugger.submit")
|
|
37873
37893
|
] }) : !allCorrect ? /* @__PURE__ */ jsx(Button, { variant: "primary", onClick: handleReset, children: t("debugger.tryAgain") }) : null,
|
|
@@ -41631,6 +41651,9 @@ function getOpponentAction(strategy, actions, history) {
|
|
|
41631
41651
|
function NegotiatorBoard({
|
|
41632
41652
|
entity,
|
|
41633
41653
|
completeEvent = "PUZZLE_COMPLETE",
|
|
41654
|
+
playRoundEvent,
|
|
41655
|
+
finishEvent,
|
|
41656
|
+
playAgainEvent,
|
|
41634
41657
|
className
|
|
41635
41658
|
}) {
|
|
41636
41659
|
const { emit } = useEventBus();
|
|
@@ -41639,13 +41662,14 @@ function NegotiatorBoard({
|
|
|
41639
41662
|
const [history, setHistory] = useState([]);
|
|
41640
41663
|
const [headerError, setHeaderError] = useState(false);
|
|
41641
41664
|
const [showHint, setShowHint] = useState(false);
|
|
41642
|
-
const totalRounds = num(resolved?.
|
|
41665
|
+
const totalRounds = num(resolved?.maxRounds);
|
|
41643
41666
|
const targetScore = num(resolved?.targetScore);
|
|
41644
|
-
const currentRound =
|
|
41645
|
-
const
|
|
41646
|
-
const playerTotal =
|
|
41667
|
+
const currentRound = num(resolved?.round);
|
|
41668
|
+
const result = str(resolved?.result) || "none";
|
|
41669
|
+
const playerTotal = num(resolved?.score);
|
|
41670
|
+
const isComplete = result !== "none" || totalRounds > 0 && currentRound >= totalRounds;
|
|
41671
|
+
const won = result === "win";
|
|
41647
41672
|
const opponentTotal = history.reduce((s, r) => s + r.opponentPayoff, 0);
|
|
41648
|
-
const won = isComplete && playerTotal >= targetScore;
|
|
41649
41673
|
const actions = Array.isArray(resolved?.actions) ? resolved.actions : [];
|
|
41650
41674
|
const payoffMatrix = Array.isArray(resolved?.payoffMatrix) ? resolved.payoffMatrix : [];
|
|
41651
41675
|
const handleAction = useCallback((actionId) => {
|
|
@@ -41654,29 +41678,45 @@ function NegotiatorBoard({
|
|
|
41654
41678
|
const payoff = payoffMatrix.find(
|
|
41655
41679
|
(p2) => p2.playerAction === actionId && p2.opponentAction === opponentAction
|
|
41656
41680
|
);
|
|
41657
|
-
const
|
|
41658
|
-
|
|
41659
|
-
|
|
41660
|
-
|
|
41661
|
-
|
|
41662
|
-
|
|
41663
|
-
|
|
41664
|
-
|
|
41665
|
-
|
|
41666
|
-
|
|
41667
|
-
|
|
41668
|
-
|
|
41669
|
-
|
|
41670
|
-
|
|
41671
|
-
|
|
41681
|
+
const playerPayoff = payoff?.playerPayoff ?? 0;
|
|
41682
|
+
setHistory((prev) => [
|
|
41683
|
+
...prev,
|
|
41684
|
+
{
|
|
41685
|
+
round: prev.length + 1,
|
|
41686
|
+
playerAction: actionId,
|
|
41687
|
+
opponentAction,
|
|
41688
|
+
playerPayoff,
|
|
41689
|
+
opponentPayoff: payoff?.opponentPayoff ?? 0
|
|
41690
|
+
}
|
|
41691
|
+
]);
|
|
41692
|
+
if (playRoundEvent) {
|
|
41693
|
+
emit(`UI:${playRoundEvent}`, { playerAction: actionId, payoff: playerPayoff });
|
|
41694
|
+
}
|
|
41695
|
+
if (totalRounds > 0 && currentRound + 1 >= totalRounds) {
|
|
41696
|
+
if (finishEvent) {
|
|
41697
|
+
emit(`UI:${finishEvent}`, {});
|
|
41698
|
+
}
|
|
41699
|
+
if (str(resolved?.hint)) {
|
|
41672
41700
|
setShowHint(true);
|
|
41673
41701
|
}
|
|
41674
41702
|
}
|
|
41675
|
-
}, [isComplete, resolved, totalRounds,
|
|
41676
|
-
const handleReset = () => {
|
|
41703
|
+
}, [isComplete, resolved, totalRounds, currentRound, actions, payoffMatrix, history, playRoundEvent, finishEvent, emit]);
|
|
41704
|
+
const handleReset = useCallback(() => {
|
|
41677
41705
|
setHistory([]);
|
|
41678
41706
|
setShowHint(false);
|
|
41679
|
-
|
|
41707
|
+
if (playAgainEvent) {
|
|
41708
|
+
emit(`UI:${playAgainEvent}`, {});
|
|
41709
|
+
}
|
|
41710
|
+
}, [playAgainEvent, emit]);
|
|
41711
|
+
const completedRef = useRef(false);
|
|
41712
|
+
useEffect(() => {
|
|
41713
|
+
if (result === "win" && !completedRef.current) {
|
|
41714
|
+
completedRef.current = true;
|
|
41715
|
+
emit(`UI:${completeEvent}`, { success: true, score: playerTotal });
|
|
41716
|
+
} else if (result === "none") {
|
|
41717
|
+
completedRef.current = false;
|
|
41718
|
+
}
|
|
41719
|
+
}, [result, playerTotal, completeEvent, emit]);
|
|
41680
41720
|
const getActionLabel = (id) => actions.find((a) => a.id === id)?.label ?? id;
|
|
41681
41721
|
if (!resolved) return null;
|
|
41682
41722
|
const theme = resolved.theme ?? void 0;
|
|
@@ -44642,67 +44682,47 @@ var init_SimulationGraph = __esm({
|
|
|
44642
44682
|
function SimulatorBoard({
|
|
44643
44683
|
entity,
|
|
44644
44684
|
completeEvent = "PUZZLE_COMPLETE",
|
|
44685
|
+
setAEvent,
|
|
44686
|
+
setBEvent,
|
|
44687
|
+
checkEvent,
|
|
44688
|
+
playAgainEvent,
|
|
44645
44689
|
className
|
|
44646
44690
|
}) {
|
|
44647
44691
|
const { emit } = useEventBus();
|
|
44648
44692
|
const { t } = useTranslate();
|
|
44649
44693
|
const resolved = boardEntity(entity);
|
|
44650
44694
|
const parameters = Array.isArray(resolved?.parameters) ? resolved.parameters : [];
|
|
44651
|
-
const [values, setValues] = useState(() => {
|
|
44652
|
-
const init = {};
|
|
44653
|
-
for (const p2 of parameters) {
|
|
44654
|
-
init[p2.id] = p2.initial;
|
|
44655
|
-
}
|
|
44656
|
-
return init;
|
|
44657
|
-
});
|
|
44658
44695
|
const [headerError, setHeaderError] = useState(false);
|
|
44659
|
-
|
|
44660
|
-
const
|
|
44661
|
-
const
|
|
44662
|
-
const
|
|
44663
|
-
|
|
44664
|
-
|
|
44665
|
-
|
|
44666
|
-
|
|
44667
|
-
|
|
44668
|
-
|
|
44669
|
-
|
|
44670
|
-
const
|
|
44671
|
-
const
|
|
44672
|
-
const
|
|
44673
|
-
const
|
|
44674
|
-
|
|
44675
|
-
|
|
44676
|
-
|
|
44696
|
+
if (!resolved) return null;
|
|
44697
|
+
const paramA = num(resolved.paramA);
|
|
44698
|
+
const paramB = num(resolved.paramB);
|
|
44699
|
+
const output = num(resolved.output);
|
|
44700
|
+
const targetValue = num(resolved.target);
|
|
44701
|
+
const targetTolerance = num(resolved.tolerance);
|
|
44702
|
+
const attempts = num(resolved.attempts);
|
|
44703
|
+
const result = str(resolved.result);
|
|
44704
|
+
const isWin = result === "win";
|
|
44705
|
+
const isComplete = result !== "none" && result !== "";
|
|
44706
|
+
const paramAValue = parameters[0];
|
|
44707
|
+
const paramBValue = parameters[1];
|
|
44708
|
+
const sliderValues = [paramA, paramB];
|
|
44709
|
+
const sliderEvents = [setAEvent, setBEvent];
|
|
44710
|
+
const handleParameterChange = (index, value) => {
|
|
44711
|
+
if (isComplete) return;
|
|
44712
|
+
const ev = sliderEvents[index];
|
|
44713
|
+
if (ev) emit(`UI:${ev}`, { value });
|
|
44677
44714
|
};
|
|
44678
|
-
const
|
|
44679
|
-
|
|
44680
|
-
setAttempts((a) => a + 1);
|
|
44681
|
-
if (isCorrect) {
|
|
44682
|
-
emit(`UI:${completeEvent}`, { success: true, attempts: attempts + 1 });
|
|
44683
|
-
}
|
|
44715
|
+
const handleCheck = () => {
|
|
44716
|
+
if (checkEvent) emit(`UI:${checkEvent}`, {});
|
|
44684
44717
|
};
|
|
44685
|
-
const
|
|
44686
|
-
|
|
44687
|
-
if (attempts >= 2 && str(resolved?.hint)) {
|
|
44688
|
-
setShowHint(true);
|
|
44689
|
-
}
|
|
44718
|
+
const handlePlayAgain = () => {
|
|
44719
|
+
if (playAgainEvent) emit(`UI:${playAgainEvent}`, {});
|
|
44690
44720
|
};
|
|
44691
|
-
const handleFullReset = () => {
|
|
44692
|
-
const init = {};
|
|
44693
|
-
for (const p2 of parameters) {
|
|
44694
|
-
init[p2.id] = p2.initial;
|
|
44695
|
-
}
|
|
44696
|
-
setValues(init);
|
|
44697
|
-
setSubmitted(false);
|
|
44698
|
-
setAttempts(0);
|
|
44699
|
-
setShowHint(false);
|
|
44700
|
-
};
|
|
44701
|
-
if (!resolved) return null;
|
|
44702
44721
|
const theme = resolved.theme ?? void 0;
|
|
44703
44722
|
const themeBackground = theme?.background;
|
|
44704
44723
|
const headerImage = str(resolved.headerImage);
|
|
44705
44724
|
const hint = str(resolved.hint);
|
|
44725
|
+
const showHint = isComplete && !isWin && attempts >= 2 && Boolean(hint);
|
|
44706
44726
|
const outputLabel = str(resolved.outputLabel);
|
|
44707
44727
|
const outputUnit = str(resolved.outputUnit);
|
|
44708
44728
|
return /* @__PURE__ */ jsx(
|
|
@@ -44722,41 +44742,43 @@ function SimulatorBoard({
|
|
|
44722
44742
|
] }) }),
|
|
44723
44743
|
/* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "md", children: [
|
|
44724
44744
|
/* @__PURE__ */ jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: t("simulator.parameters") }),
|
|
44725
|
-
|
|
44726
|
-
/* @__PURE__ */ jsxs(
|
|
44727
|
-
/* @__PURE__ */
|
|
44728
|
-
|
|
44729
|
-
|
|
44730
|
-
|
|
44731
|
-
|
|
44732
|
-
|
|
44733
|
-
|
|
44734
|
-
/* @__PURE__ */ jsx(
|
|
44735
|
-
"input",
|
|
44736
|
-
{
|
|
44737
|
-
type: "range",
|
|
44738
|
-
min: param.min,
|
|
44739
|
-
max: param.max,
|
|
44740
|
-
step: param.step,
|
|
44741
|
-
value: values[param.id],
|
|
44742
|
-
onChange: (e) => handleParameterChange(param.id, Number(e.target.value)),
|
|
44743
|
-
disabled: submitted,
|
|
44744
|
-
className: "w-full accent-foreground"
|
|
44745
|
-
}
|
|
44746
|
-
),
|
|
44747
|
-
/* @__PURE__ */ jsxs(HStack, { justify: "between", children: [
|
|
44748
|
-
/* @__PURE__ */ jsxs(Typography, { variant: "caption", className: "text-muted-foreground", children: [
|
|
44749
|
-
param.min,
|
|
44750
|
-
" ",
|
|
44751
|
-
param.unit
|
|
44745
|
+
[paramAValue, paramBValue].map(
|
|
44746
|
+
(param, index) => param ? /* @__PURE__ */ jsxs(VStack, { gap: "xs", children: [
|
|
44747
|
+
/* @__PURE__ */ jsxs(HStack, { justify: "between", align: "center", children: [
|
|
44748
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "medium", children: param.label }),
|
|
44749
|
+
/* @__PURE__ */ jsxs(Badge, { size: "sm", children: [
|
|
44750
|
+
sliderValues[index],
|
|
44751
|
+
" ",
|
|
44752
|
+
param.unit
|
|
44753
|
+
] })
|
|
44752
44754
|
] }),
|
|
44753
|
-
/* @__PURE__ */
|
|
44754
|
-
|
|
44755
|
-
|
|
44756
|
-
|
|
44755
|
+
/* @__PURE__ */ jsx(
|
|
44756
|
+
"input",
|
|
44757
|
+
{
|
|
44758
|
+
type: "range",
|
|
44759
|
+
min: param.min,
|
|
44760
|
+
max: param.max,
|
|
44761
|
+
step: param.step,
|
|
44762
|
+
value: sliderValues[index],
|
|
44763
|
+
onChange: (e) => handleParameterChange(index, Number(e.target.value)),
|
|
44764
|
+
disabled: isComplete,
|
|
44765
|
+
className: "w-full accent-foreground"
|
|
44766
|
+
}
|
|
44767
|
+
),
|
|
44768
|
+
/* @__PURE__ */ jsxs(HStack, { justify: "between", children: [
|
|
44769
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "caption", className: "text-muted-foreground", children: [
|
|
44770
|
+
param.min,
|
|
44771
|
+
" ",
|
|
44772
|
+
param.unit
|
|
44773
|
+
] }),
|
|
44774
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "caption", className: "text-muted-foreground", children: [
|
|
44775
|
+
param.max,
|
|
44776
|
+
" ",
|
|
44777
|
+
param.unit
|
|
44778
|
+
] })
|
|
44757
44779
|
] })
|
|
44758
|
-
] })
|
|
44759
|
-
|
|
44780
|
+
] }, param.id ?? index) : null
|
|
44781
|
+
)
|
|
44760
44782
|
] }) }),
|
|
44761
44783
|
/* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", children: [
|
|
44762
44784
|
/* @__PURE__ */ jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: outputLabel }),
|
|
@@ -44765,9 +44787,9 @@ function SimulatorBoard({
|
|
|
44765
44787
|
" ",
|
|
44766
44788
|
outputUnit
|
|
44767
44789
|
] }),
|
|
44768
|
-
|
|
44769
|
-
/* @__PURE__ */ jsx(Icon, { icon:
|
|
44770
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body", className:
|
|
44790
|
+
isComplete && /* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
44791
|
+
/* @__PURE__ */ jsx(Icon, { icon: isWin ? CheckCircle : XCircle, size: "sm", className: isWin ? "text-success" : "text-error" }),
|
|
44792
|
+
/* @__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") })
|
|
44771
44793
|
] }),
|
|
44772
44794
|
/* @__PURE__ */ jsxs(Typography, { variant: "caption", className: "text-muted-foreground", children: [
|
|
44773
44795
|
t("simulator.target"),
|
|
@@ -44782,11 +44804,11 @@ function SimulatorBoard({
|
|
|
44782
44804
|
] }) }),
|
|
44783
44805
|
showHint && hint && /* @__PURE__ */ jsx(Card, { className: "p-4 border-l-4 border-l-warning", children: /* @__PURE__ */ jsx(Typography, { variant: "body", children: hint }) }),
|
|
44784
44806
|
/* @__PURE__ */ jsxs(HStack, { gap: "sm", justify: "center", children: [
|
|
44785
|
-
!
|
|
44807
|
+
!isComplete ? /* @__PURE__ */ jsxs(Button, { variant: "primary", onClick: handleCheck, children: [
|
|
44786
44808
|
/* @__PURE__ */ jsx(Icon, { icon: Play, size: "sm" }),
|
|
44787
44809
|
t("simulator.simulate")
|
|
44788
|
-
] }) :
|
|
44789
|
-
/* @__PURE__ */ jsxs(Button, { variant: "secondary", onClick:
|
|
44810
|
+
] }) : null,
|
|
44811
|
+
/* @__PURE__ */ jsxs(Button, { variant: "secondary", onClick: handlePlayAgain, children: [
|
|
44790
44812
|
/* @__PURE__ */ jsx(Icon, { icon: RotateCcw, size: "sm" }),
|
|
44791
44813
|
t("simulator.reset")
|
|
44792
44814
|
] })
|