@almadar/ui 5.21.11 → 5.22.2
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 +939 -638
- package/dist/avl/index.js +939 -638
- package/dist/components/core/molecules/CalendarGrid.d.ts +3 -10
- package/dist/components/core/molecules/ContentRenderer.d.ts +2 -2
- package/dist/components/core/molecules/DataGrid.d.ts +11 -20
- package/dist/components/core/molecules/DataList.d.ts +9 -15
- package/dist/components/core/molecules/FormSection.d.ts +4 -4
- package/dist/components/core/molecules/PositionedCanvas.d.ts +4 -17
- package/dist/components/core/molecules/ReplyTree.d.ts +2 -13
- package/dist/components/core/molecules/RichBlockEditor.d.ts +3 -6
- package/dist/components/core/molecules/SortableList.d.ts +7 -5
- package/dist/components/core/molecules/TableView.d.ts +7 -7
- package/dist/components/core/molecules/index.d.ts +3 -3
- package/dist/components/core/molecules/useDataDnd.d.ts +5 -5
- package/dist/components/core/organisms/CardGrid.d.ts +5 -2
- package/dist/components/core/organisms/CaseStudyOrganism.d.ts +4 -3
- package/dist/components/core/organisms/DataTable.d.ts +4 -2
- package/dist/components/core/organisms/DetailPanel.d.ts +6 -6
- package/dist/components/core/organisms/FeatureGridOrganism.d.ts +4 -3
- package/dist/components/core/organisms/HeroOrganism.d.ts +4 -5
- package/dist/components/core/organisms/List.d.ts +5 -2
- package/dist/components/core/organisms/MasterDetail.d.ts +4 -2
- package/dist/components/core/organisms/MediaGallery.d.ts +4 -2
- package/dist/components/core/organisms/ShowcaseOrganism.d.ts +4 -3
- package/dist/components/core/organisms/StatCard.d.ts +5 -2
- package/dist/components/core/organisms/StepFlowOrganism.d.ts +4 -3
- package/dist/components/core/organisms/Timeline.d.ts +2 -2
- package/dist/components/core/organisms/book/index.d.ts +1 -1
- package/dist/components/core/organisms/book/types.d.ts +28 -48
- package/dist/components/core/organisms/index.d.ts +1 -2
- package/dist/components/core/organisms/layout/DashboardGrid.d.ts +2 -2
- package/dist/components/core/organisms/marketing-types.d.ts +5 -94
- package/dist/components/core/organisms/types.d.ts +9 -27
- package/dist/components/core/templates/index.d.ts +6 -6
- package/dist/components/game/organisms/BattleBoard.d.ts +14 -90
- package/dist/components/game/organisms/CastleBoard.d.ts +7 -21
- package/dist/components/game/organisms/UncontrolledBattleBoard.d.ts +2 -7
- package/dist/components/game/organisms/WorldMapBoard.d.ts +13 -59
- package/dist/components/game/organisms/boardEntity.d.ts +44 -0
- package/dist/components/game/organisms/hooks/useBattleState.d.ts +7 -7
- package/dist/components/game/organisms/index.d.ts +3 -3
- package/dist/components/game/organisms/puzzles/builder/BuilderBoard.d.ts +7 -20
- package/dist/components/game/organisms/puzzles/builder/index.d.ts +1 -1
- package/dist/components/game/organisms/puzzles/classifier/ClassifierBoard.d.ts +7 -20
- package/dist/components/game/organisms/puzzles/classifier/index.d.ts +1 -1
- package/dist/components/game/organisms/puzzles/debugger/DebuggerBoard.d.ts +6 -22
- package/dist/components/game/organisms/puzzles/debugger/index.d.ts +1 -1
- package/dist/components/game/organisms/puzzles/event-handler/EventHandlerBoard.d.ts +6 -33
- package/dist/components/game/organisms/puzzles/event-handler/ObjectRulePanel.d.ts +3 -21
- package/dist/components/game/organisms/puzzles/event-handler/index.d.ts +2 -2
- package/dist/components/game/organisms/puzzles/event-handler/puzzleObject.d.ts +21 -0
- package/dist/components/game/organisms/puzzles/negotiator/NegotiatorBoard.d.ts +8 -24
- package/dist/components/game/organisms/puzzles/negotiator/index.d.ts +1 -1
- package/dist/components/game/organisms/puzzles/sequencer/ActionTile.d.ts +2 -2
- package/dist/components/game/organisms/puzzles/sequencer/SequencerBoard.d.ts +7 -36
- package/dist/components/game/organisms/puzzles/sequencer/index.d.ts +1 -1
- package/dist/components/game/organisms/puzzles/simulator/SimulatorBoard.d.ts +6 -25
- package/dist/components/game/organisms/puzzles/simulator/index.d.ts +1 -1
- package/dist/components/game/organisms/puzzles/state-architect/StateArchitectBoard.d.ts +7 -40
- package/dist/components/game/organisms/puzzles/state-architect/VariablePanel.d.ts +3 -9
- package/dist/components/game/organisms/puzzles/state-architect/index.d.ts +2 -2
- package/dist/components/game/organisms/three/index.cjs +35 -21
- package/dist/components/game/organisms/three/index.js +35 -21
- package/dist/components/game/templates/BattleTemplate.d.ts +2 -3
- package/dist/components/game/templates/CastleTemplate.d.ts +2 -3
- package/dist/components/game/templates/GameCanvas3DBattleTemplate.d.ts +1 -16
- package/dist/components/game/templates/GameCanvas3DCastleTemplate.d.ts +1 -18
- package/dist/components/game/templates/GameCanvas3DWorldMapTemplate.d.ts +1 -14
- package/dist/components/game/templates/GameTemplate.d.ts +1 -6
- package/dist/components/game/templates/WorldMapTemplate.d.ts +2 -3
- package/dist/components/index.cjs +2036 -1675
- package/dist/components/index.js +1148 -787
- package/dist/components/marketing/organisms/PricingOrganism.d.ts +4 -3
- package/dist/components/marketing/organisms/StatsOrganism.d.ts +4 -3
- package/dist/components/marketing/organisms/TeamOrganism.d.ts +4 -3
- package/dist/components/marketing/organisms/book/BookChapterView.d.ts +5 -2
- package/dist/components/marketing/organisms/book/BookTableOfContents.d.ts +3 -2
- package/dist/components/marketing/organisms/book/BookViewer.d.ts +4 -4
- package/dist/components/marketing/templates/AboutPageTemplate.d.ts +32 -6
- package/dist/components/marketing/templates/FeatureDetailPageTemplate.d.ts +14 -4
- package/dist/components/marketing/templates/LandingPageTemplate.d.ts +47 -9
- package/dist/components/marketing/templates/PricingPageTemplate.d.ts +23 -5
- package/dist/providers/index.cjs +932 -631
- package/dist/providers/index.js +932 -631
- package/dist/runtime/index.cjs +934 -633
- package/dist/runtime/index.js +934 -633
- package/package.json +2 -2
package/dist/components/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
2
|
-
import * as
|
|
3
|
-
import
|
|
2
|
+
import * as React80 from 'react';
|
|
3
|
+
import React80__default, { useContext, useMemo, useRef, useEffect, useCallback, Suspense, useState, lazy, createContext, useLayoutEffect, useId, useSyncExternalStore } from 'react';
|
|
4
4
|
import { clsx } from 'clsx';
|
|
5
5
|
import { twMerge } from 'tailwind-merge';
|
|
6
6
|
import { EventBusContext, useTraitScope, TraitScopeProvider } from '@almadar/ui/providers';
|
|
@@ -211,7 +211,7 @@ var init_SvgFlow = __esm({
|
|
|
211
211
|
opacity = 1,
|
|
212
212
|
className
|
|
213
213
|
}) => {
|
|
214
|
-
const markerId =
|
|
214
|
+
const markerId = React80__default.useMemo(() => {
|
|
215
215
|
flowIdCounter += 1;
|
|
216
216
|
return `almadar-flow-arrow-${flowIdCounter}`;
|
|
217
217
|
}, []);
|
|
@@ -260,7 +260,7 @@ var init_SvgGrid = __esm({
|
|
|
260
260
|
x,
|
|
261
261
|
y,
|
|
262
262
|
cols = 4,
|
|
263
|
-
rows = 3,
|
|
263
|
+
rows: rows2 = 3,
|
|
264
264
|
spacing = 20,
|
|
265
265
|
nodeRadius = 3,
|
|
266
266
|
color = "var(--color-primary)",
|
|
@@ -269,7 +269,7 @@ var init_SvgGrid = __esm({
|
|
|
269
269
|
highlights = []
|
|
270
270
|
}) => {
|
|
271
271
|
const highlightSet = new Set(highlights);
|
|
272
|
-
return /* @__PURE__ */ jsx("g", { className, opacity, children: Array.from({ length:
|
|
272
|
+
return /* @__PURE__ */ jsx("g", { className, opacity, children: Array.from({ length: rows2 }).map(
|
|
273
273
|
(_, row) => Array.from({ length: cols }).map((_2, col) => {
|
|
274
274
|
const index = row * cols + col;
|
|
275
275
|
const isHighlighted = highlightSet.has(index);
|
|
@@ -754,7 +754,7 @@ var init_SvgRing = __esm({
|
|
|
754
754
|
className,
|
|
755
755
|
label
|
|
756
756
|
}) => {
|
|
757
|
-
const gradientId =
|
|
757
|
+
const gradientId = React80__default.useMemo(() => {
|
|
758
758
|
ringIdCounter += 1;
|
|
759
759
|
return `almadar-ring-glow-${ringIdCounter}`;
|
|
760
760
|
}, []);
|
|
@@ -1836,7 +1836,7 @@ var init_Icon = __esm({
|
|
|
1836
1836
|
const directIcon = typeof icon === "string" ? void 0 : icon;
|
|
1837
1837
|
const effectiveName = typeof icon === "string" ? icon : name;
|
|
1838
1838
|
const family = useIconFamily();
|
|
1839
|
-
const RenderedComponent =
|
|
1839
|
+
const RenderedComponent = React80__default.useMemo(() => {
|
|
1840
1840
|
if (directIcon) return null;
|
|
1841
1841
|
return effectiveName ? resolveIconForFamily(effectiveName, family) : null;
|
|
1842
1842
|
}, [directIcon, effectiveName, family]);
|
|
@@ -1894,7 +1894,7 @@ function resolveIconProp(value, sizeClass) {
|
|
|
1894
1894
|
const IconComp = value;
|
|
1895
1895
|
return /* @__PURE__ */ jsx(IconComp, { className: sizeClass });
|
|
1896
1896
|
}
|
|
1897
|
-
if (
|
|
1897
|
+
if (React80__default.isValidElement(value)) {
|
|
1898
1898
|
return value;
|
|
1899
1899
|
}
|
|
1900
1900
|
if (typeof value === "object" && value !== null && "render" in value) {
|
|
@@ -1970,7 +1970,7 @@ var init_Button = __esm({
|
|
|
1970
1970
|
md: "h-icon-default w-icon-default",
|
|
1971
1971
|
lg: "h-icon-default w-icon-default"
|
|
1972
1972
|
};
|
|
1973
|
-
Button =
|
|
1973
|
+
Button = React80__default.forwardRef(
|
|
1974
1974
|
({
|
|
1975
1975
|
className,
|
|
1976
1976
|
variant = "primary",
|
|
@@ -2036,7 +2036,7 @@ var init_Input = __esm({
|
|
|
2036
2036
|
"components/core/atoms/Input.tsx"() {
|
|
2037
2037
|
init_cn();
|
|
2038
2038
|
init_Icon();
|
|
2039
|
-
Input =
|
|
2039
|
+
Input = React80__default.forwardRef(
|
|
2040
2040
|
({
|
|
2041
2041
|
className,
|
|
2042
2042
|
inputType,
|
|
@@ -2049,7 +2049,7 @@ var init_Input = __esm({
|
|
|
2049
2049
|
onClear,
|
|
2050
2050
|
value,
|
|
2051
2051
|
options,
|
|
2052
|
-
rows = 3,
|
|
2052
|
+
rows: rows2 = 3,
|
|
2053
2053
|
onChange,
|
|
2054
2054
|
...props
|
|
2055
2055
|
}, ref) => {
|
|
@@ -2099,7 +2099,7 @@ var init_Input = __esm({
|
|
|
2099
2099
|
ref,
|
|
2100
2100
|
value,
|
|
2101
2101
|
onChange,
|
|
2102
|
-
rows,
|
|
2102
|
+
rows: rows2,
|
|
2103
2103
|
className: baseClassName,
|
|
2104
2104
|
...props
|
|
2105
2105
|
}
|
|
@@ -2157,7 +2157,7 @@ var Label;
|
|
|
2157
2157
|
var init_Label = __esm({
|
|
2158
2158
|
"components/core/atoms/Label.tsx"() {
|
|
2159
2159
|
init_cn();
|
|
2160
|
-
Label =
|
|
2160
|
+
Label = React80__default.forwardRef(
|
|
2161
2161
|
({ className, required, children, ...props }, ref) => {
|
|
2162
2162
|
return /* @__PURE__ */ jsxs(
|
|
2163
2163
|
"label",
|
|
@@ -2183,7 +2183,7 @@ var Textarea;
|
|
|
2183
2183
|
var init_Textarea = __esm({
|
|
2184
2184
|
"components/core/atoms/Textarea.tsx"() {
|
|
2185
2185
|
init_cn();
|
|
2186
|
-
Textarea =
|
|
2186
|
+
Textarea = React80__default.forwardRef(
|
|
2187
2187
|
({ className, error, ...props }, ref) => {
|
|
2188
2188
|
return /* @__PURE__ */ jsx(
|
|
2189
2189
|
"textarea",
|
|
@@ -2213,7 +2213,7 @@ var init_Select = __esm({
|
|
|
2213
2213
|
"components/core/atoms/Select.tsx"() {
|
|
2214
2214
|
init_cn();
|
|
2215
2215
|
init_Icon();
|
|
2216
|
-
Select =
|
|
2216
|
+
Select = React80__default.forwardRef(
|
|
2217
2217
|
({ className, options, placeholder, error, ...props }, ref) => {
|
|
2218
2218
|
return /* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
2219
2219
|
/* @__PURE__ */ jsxs(
|
|
@@ -2255,7 +2255,7 @@ var Checkbox;
|
|
|
2255
2255
|
var init_Checkbox = __esm({
|
|
2256
2256
|
"components/core/atoms/Checkbox.tsx"() {
|
|
2257
2257
|
init_cn();
|
|
2258
|
-
Checkbox =
|
|
2258
|
+
Checkbox = React80__default.forwardRef(
|
|
2259
2259
|
({ className, label, id, ...props }, ref) => {
|
|
2260
2260
|
const inputId = id || `checkbox-${Math.random().toString(36).substr(2, 9)}`;
|
|
2261
2261
|
return /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
|
|
@@ -2346,7 +2346,7 @@ var init_Card = __esm({
|
|
|
2346
2346
|
chip: "shadow-none rounded-pill border-[length:var(--border-width)] border-border",
|
|
2347
2347
|
"tile-image-first": "p-0 overflow-hidden"
|
|
2348
2348
|
};
|
|
2349
|
-
Card =
|
|
2349
|
+
Card = React80__default.forwardRef(
|
|
2350
2350
|
({
|
|
2351
2351
|
className,
|
|
2352
2352
|
variant = "bordered",
|
|
@@ -2384,9 +2384,9 @@ var init_Card = __esm({
|
|
|
2384
2384
|
}
|
|
2385
2385
|
);
|
|
2386
2386
|
Card.displayName = "Card";
|
|
2387
|
-
CardHeader =
|
|
2387
|
+
CardHeader = React80__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("mb-4", className), ...props }));
|
|
2388
2388
|
CardHeader.displayName = "CardHeader";
|
|
2389
|
-
CardTitle =
|
|
2389
|
+
CardTitle = React80__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
2390
2390
|
"h3",
|
|
2391
2391
|
{
|
|
2392
2392
|
ref,
|
|
@@ -2399,11 +2399,11 @@ var init_Card = __esm({
|
|
|
2399
2399
|
}
|
|
2400
2400
|
));
|
|
2401
2401
|
CardTitle.displayName = "CardTitle";
|
|
2402
|
-
CardContent =
|
|
2402
|
+
CardContent = React80__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("", className), ...props }));
|
|
2403
2403
|
CardContent.displayName = "CardContent";
|
|
2404
2404
|
CardBody = CardContent;
|
|
2405
2405
|
CardBody.displayName = "CardBody";
|
|
2406
|
-
CardFooter =
|
|
2406
|
+
CardFooter = React80__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
2407
2407
|
"div",
|
|
2408
2408
|
{
|
|
2409
2409
|
ref,
|
|
@@ -2456,7 +2456,7 @@ var init_Badge = __esm({
|
|
|
2456
2456
|
md: "px-2.5 py-1 text-sm",
|
|
2457
2457
|
lg: "px-3 py-1.5 text-base"
|
|
2458
2458
|
};
|
|
2459
|
-
Badge =
|
|
2459
|
+
Badge = React80__default.forwardRef(
|
|
2460
2460
|
({ className, variant = "default", size = "sm", amount, label, icon, children, onRemove, removeLabel, ...props }, ref) => {
|
|
2461
2461
|
const iconSizes3 = {
|
|
2462
2462
|
sm: "h-icon-default w-icon-default",
|
|
@@ -2549,7 +2549,7 @@ var init_FilterPill = __esm({
|
|
|
2549
2549
|
md: "w-3.5 h-3.5",
|
|
2550
2550
|
lg: "w-4 h-4"
|
|
2551
2551
|
};
|
|
2552
|
-
FilterPill =
|
|
2552
|
+
FilterPill = React80__default.forwardRef(
|
|
2553
2553
|
({
|
|
2554
2554
|
className,
|
|
2555
2555
|
variant = "default",
|
|
@@ -2626,7 +2626,7 @@ var init_Spinner = __esm({
|
|
|
2626
2626
|
md: "h-6 w-6",
|
|
2627
2627
|
lg: "h-8 w-8"
|
|
2628
2628
|
};
|
|
2629
|
-
Spinner =
|
|
2629
|
+
Spinner = React80__default.forwardRef(
|
|
2630
2630
|
({ className, size = "md", ...props }, ref) => {
|
|
2631
2631
|
return /* @__PURE__ */ jsx(
|
|
2632
2632
|
"div",
|
|
@@ -2910,7 +2910,7 @@ var init_Box = __esm({
|
|
|
2910
2910
|
fixed: "fixed",
|
|
2911
2911
|
sticky: "sticky"
|
|
2912
2912
|
};
|
|
2913
|
-
Box =
|
|
2913
|
+
Box = React80__default.forwardRef(
|
|
2914
2914
|
({
|
|
2915
2915
|
padding,
|
|
2916
2916
|
paddingX,
|
|
@@ -2960,7 +2960,7 @@ var init_Box = __esm({
|
|
|
2960
2960
|
onMouseLeave?.(e);
|
|
2961
2961
|
}, [hoverEvent, eventBus, onMouseLeave]);
|
|
2962
2962
|
const isClickable = action || onClick;
|
|
2963
|
-
return
|
|
2963
|
+
return React80__default.createElement(
|
|
2964
2964
|
Component,
|
|
2965
2965
|
{
|
|
2966
2966
|
ref,
|
|
@@ -3282,7 +3282,7 @@ var init_Radio = __esm({
|
|
|
3282
3282
|
md: "w-2.5 h-2.5",
|
|
3283
3283
|
lg: "w-3 h-3"
|
|
3284
3284
|
};
|
|
3285
|
-
Radio =
|
|
3285
|
+
Radio = React80__default.forwardRef(
|
|
3286
3286
|
({
|
|
3287
3287
|
label,
|
|
3288
3288
|
helperText,
|
|
@@ -3299,12 +3299,12 @@ var init_Radio = __esm({
|
|
|
3299
3299
|
onChange,
|
|
3300
3300
|
...props
|
|
3301
3301
|
}, ref) => {
|
|
3302
|
-
const reactId =
|
|
3302
|
+
const reactId = React80__default.useId();
|
|
3303
3303
|
const baseId = id || `radio-${reactId}`;
|
|
3304
3304
|
const hasError = !!error;
|
|
3305
3305
|
const eventBus = useEventBus();
|
|
3306
|
-
const [selected, setSelected] =
|
|
3307
|
-
|
|
3306
|
+
const [selected, setSelected] = React80__default.useState(value);
|
|
3307
|
+
React80__default.useEffect(() => {
|
|
3308
3308
|
if (value !== void 0) setSelected(value);
|
|
3309
3309
|
}, [value]);
|
|
3310
3310
|
const pick = (next, e) => {
|
|
@@ -3486,7 +3486,7 @@ var init_Switch = __esm({
|
|
|
3486
3486
|
"components/core/atoms/Switch.tsx"() {
|
|
3487
3487
|
"use client";
|
|
3488
3488
|
init_cn();
|
|
3489
|
-
Switch =
|
|
3489
|
+
Switch = React80.forwardRef(
|
|
3490
3490
|
({
|
|
3491
3491
|
checked,
|
|
3492
3492
|
defaultChecked = false,
|
|
@@ -3497,10 +3497,10 @@ var init_Switch = __esm({
|
|
|
3497
3497
|
name,
|
|
3498
3498
|
className
|
|
3499
3499
|
}, ref) => {
|
|
3500
|
-
const [isChecked, setIsChecked] =
|
|
3500
|
+
const [isChecked, setIsChecked] = React80.useState(
|
|
3501
3501
|
checked !== void 0 ? checked : defaultChecked
|
|
3502
3502
|
);
|
|
3503
|
-
|
|
3503
|
+
React80.useEffect(() => {
|
|
3504
3504
|
if (checked !== void 0) {
|
|
3505
3505
|
setIsChecked(checked);
|
|
3506
3506
|
}
|
|
@@ -4371,7 +4371,7 @@ var Dialog;
|
|
|
4371
4371
|
var init_Dialog = __esm({
|
|
4372
4372
|
"components/core/atoms/Dialog.tsx"() {
|
|
4373
4373
|
init_cn();
|
|
4374
|
-
Dialog =
|
|
4374
|
+
Dialog = React80__default.forwardRef(
|
|
4375
4375
|
({
|
|
4376
4376
|
role = "dialog",
|
|
4377
4377
|
"aria-modal": ariaModal = true,
|
|
@@ -4397,7 +4397,7 @@ var Aside;
|
|
|
4397
4397
|
var init_Aside = __esm({
|
|
4398
4398
|
"components/core/atoms/Aside.tsx"() {
|
|
4399
4399
|
init_cn();
|
|
4400
|
-
Aside =
|
|
4400
|
+
Aside = React80__default.forwardRef(
|
|
4401
4401
|
({ className, children, ...rest }, ref) => /* @__PURE__ */ jsx("aside", { ref, className: cn(className), ...rest, children })
|
|
4402
4402
|
);
|
|
4403
4403
|
Aside.displayName = "Aside";
|
|
@@ -4475,8 +4475,8 @@ var init_LawReferenceTooltip = __esm({
|
|
|
4475
4475
|
className
|
|
4476
4476
|
}) => {
|
|
4477
4477
|
const { t } = useTranslate();
|
|
4478
|
-
const [isVisible, setIsVisible] =
|
|
4479
|
-
const timeoutRef =
|
|
4478
|
+
const [isVisible, setIsVisible] = React80__default.useState(false);
|
|
4479
|
+
const timeoutRef = React80__default.useRef(null);
|
|
4480
4480
|
const handleMouseEnter = () => {
|
|
4481
4481
|
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
4482
4482
|
timeoutRef.current = setTimeout(() => setIsVisible(true), 200);
|
|
@@ -4485,7 +4485,7 @@ var init_LawReferenceTooltip = __esm({
|
|
|
4485
4485
|
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
4486
4486
|
setIsVisible(false);
|
|
4487
4487
|
};
|
|
4488
|
-
|
|
4488
|
+
React80__default.useEffect(() => {
|
|
4489
4489
|
return () => {
|
|
4490
4490
|
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
4491
4491
|
};
|
|
@@ -4695,7 +4695,7 @@ var init_StatusDot = __esm({
|
|
|
4695
4695
|
md: "w-2.5 h-2.5",
|
|
4696
4696
|
lg: "w-3 h-3"
|
|
4697
4697
|
};
|
|
4698
|
-
StatusDot =
|
|
4698
|
+
StatusDot = React80__default.forwardRef(
|
|
4699
4699
|
({ className, status = "offline", pulse = false, size = "md", label, ...props }, ref) => {
|
|
4700
4700
|
return /* @__PURE__ */ jsx(
|
|
4701
4701
|
"span",
|
|
@@ -4749,7 +4749,7 @@ var init_TrendIndicator = __esm({
|
|
|
4749
4749
|
down: "trending-down",
|
|
4750
4750
|
flat: "arrow-right"
|
|
4751
4751
|
};
|
|
4752
|
-
TrendIndicator =
|
|
4752
|
+
TrendIndicator = React80__default.forwardRef(
|
|
4753
4753
|
({
|
|
4754
4754
|
className,
|
|
4755
4755
|
value,
|
|
@@ -4816,7 +4816,7 @@ var init_RangeSlider = __esm({
|
|
|
4816
4816
|
md: "w-4 h-4",
|
|
4817
4817
|
lg: "w-5 h-5"
|
|
4818
4818
|
};
|
|
4819
|
-
RangeSlider =
|
|
4819
|
+
RangeSlider = React80__default.forwardRef(
|
|
4820
4820
|
({
|
|
4821
4821
|
className,
|
|
4822
4822
|
min = 0,
|
|
@@ -5412,7 +5412,7 @@ var init_ContentSection = __esm({
|
|
|
5412
5412
|
md: "py-16",
|
|
5413
5413
|
lg: "py-24"
|
|
5414
5414
|
};
|
|
5415
|
-
ContentSection =
|
|
5415
|
+
ContentSection = React80__default.forwardRef(
|
|
5416
5416
|
({ children, background = "default", padding = "lg", id, className }, ref) => {
|
|
5417
5417
|
return /* @__PURE__ */ jsx(
|
|
5418
5418
|
Box,
|
|
@@ -5946,7 +5946,7 @@ var init_AnimatedReveal = __esm({
|
|
|
5946
5946
|
"scale-up": { opacity: 1, transform: "scale(1) translateY(0)" },
|
|
5947
5947
|
"none": {}
|
|
5948
5948
|
};
|
|
5949
|
-
AnimatedReveal =
|
|
5949
|
+
AnimatedReveal = React80__default.forwardRef(
|
|
5950
5950
|
({
|
|
5951
5951
|
trigger = "scroll",
|
|
5952
5952
|
animation = "fade-up",
|
|
@@ -6106,7 +6106,7 @@ var init_AnimatedGraphic = __esm({
|
|
|
6106
6106
|
"components/marketing/atoms/AnimatedGraphic.tsx"() {
|
|
6107
6107
|
"use client";
|
|
6108
6108
|
init_cn();
|
|
6109
|
-
AnimatedGraphic =
|
|
6109
|
+
AnimatedGraphic = React80__default.forwardRef(
|
|
6110
6110
|
({
|
|
6111
6111
|
src,
|
|
6112
6112
|
svgContent,
|
|
@@ -6129,7 +6129,7 @@ var init_AnimatedGraphic = __esm({
|
|
|
6129
6129
|
const fetchedSvg = useFetchedSvg(svgContent ? void 0 : src);
|
|
6130
6130
|
const resolvedSvg = svgContent ?? fetchedSvg;
|
|
6131
6131
|
const prevAnimateRef = useRef(animate);
|
|
6132
|
-
const setRef =
|
|
6132
|
+
const setRef = React80__default.useCallback(
|
|
6133
6133
|
(node) => {
|
|
6134
6134
|
containerRef.current = node;
|
|
6135
6135
|
if (typeof ref === "function") ref(node);
|
|
@@ -6819,7 +6819,7 @@ var init_ErrorBoundary = __esm({
|
|
|
6819
6819
|
}
|
|
6820
6820
|
);
|
|
6821
6821
|
};
|
|
6822
|
-
ErrorBoundary = class extends
|
|
6822
|
+
ErrorBoundary = class extends React80__default.Component {
|
|
6823
6823
|
constructor(props) {
|
|
6824
6824
|
super(props);
|
|
6825
6825
|
__publicField(this, "reset", () => {
|
|
@@ -6864,15 +6864,15 @@ function HeaderSkeleton({ className }) {
|
|
|
6864
6864
|
] })
|
|
6865
6865
|
] });
|
|
6866
6866
|
}
|
|
6867
|
-
function TableSkeleton({ rows = 5, columns = 4, className }) {
|
|
6867
|
+
function TableSkeleton({ rows: rows2 = 5, columns = 4, className }) {
|
|
6868
6868
|
return /* @__PURE__ */ jsxs(VStack, { gap: "none", className: cn("border border-border rounded-lg overflow-hidden", className), children: [
|
|
6869
6869
|
/* @__PURE__ */ jsx(HStack, { className: "px-4 py-3 bg-muted/30 border-b border-border", children: Array.from({ length: columns }).map((_, i) => /* @__PURE__ */ jsx(SkeletonBlock, { className: "h-4 flex-1 mx-2" }, i)) }),
|
|
6870
|
-
Array.from({ length:
|
|
6870
|
+
Array.from({ length: rows2 }).map((_, rowIdx) => /* @__PURE__ */ jsx(
|
|
6871
6871
|
HStack,
|
|
6872
6872
|
{
|
|
6873
6873
|
className: cn(
|
|
6874
6874
|
"px-4 py-3",
|
|
6875
|
-
rowIdx <
|
|
6875
|
+
rowIdx < rows2 - 1 && "border-b border-border"
|
|
6876
6876
|
),
|
|
6877
6877
|
children: Array.from({ length: columns }).map((_2, colIdx) => /* @__PURE__ */ jsx(SkeletonLine, { className: "flex-1 mx-2" }, colIdx))
|
|
6878
6878
|
},
|
|
@@ -6920,18 +6920,18 @@ function CardSkeleton({ className }) {
|
|
|
6920
6920
|
}
|
|
6921
6921
|
);
|
|
6922
6922
|
}
|
|
6923
|
-
function TextSkeleton({ rows = 3, className }) {
|
|
6924
|
-
return /* @__PURE__ */ jsx(VStack, { gap: "sm", className, children: Array.from({ length:
|
|
6923
|
+
function TextSkeleton({ rows: rows2 = 3, className }) {
|
|
6924
|
+
return /* @__PURE__ */ jsx(VStack, { gap: "sm", className, children: Array.from({ length: rows2 }).map((_, i) => /* @__PURE__ */ jsx(
|
|
6925
6925
|
SkeletonLine,
|
|
6926
6926
|
{
|
|
6927
|
-
className: i ===
|
|
6927
|
+
className: i === rows2 - 1 ? "w-2/3" : "w-full"
|
|
6928
6928
|
},
|
|
6929
6929
|
i
|
|
6930
6930
|
)) });
|
|
6931
6931
|
}
|
|
6932
6932
|
function Skeleton({
|
|
6933
6933
|
variant = "text",
|
|
6934
|
-
rows,
|
|
6934
|
+
rows: rows2,
|
|
6935
6935
|
columns,
|
|
6936
6936
|
fields,
|
|
6937
6937
|
className
|
|
@@ -6941,15 +6941,15 @@ function Skeleton({
|
|
|
6941
6941
|
case "header":
|
|
6942
6942
|
return /* @__PURE__ */ jsx(HeaderSkeleton, { className });
|
|
6943
6943
|
case "table":
|
|
6944
|
-
return /* @__PURE__ */ jsx(TableSkeleton, { rows, columns, className });
|
|
6944
|
+
return /* @__PURE__ */ jsx(TableSkeleton, { rows: rows2, columns, className });
|
|
6945
6945
|
case "form":
|
|
6946
6946
|
return /* @__PURE__ */ jsx(FormSkeleton, { fields, className });
|
|
6947
6947
|
case "card":
|
|
6948
6948
|
return /* @__PURE__ */ jsx(CardSkeleton, { className });
|
|
6949
6949
|
case "text":
|
|
6950
|
-
return /* @__PURE__ */ jsx(TextSkeleton, { rows, className });
|
|
6950
|
+
return /* @__PURE__ */ jsx(TextSkeleton, { rows: rows2, className });
|
|
6951
6951
|
default:
|
|
6952
|
-
return /* @__PURE__ */ jsx(TextSkeleton, { rows, className });
|
|
6952
|
+
return /* @__PURE__ */ jsx(TextSkeleton, { rows: rows2, className });
|
|
6953
6953
|
}
|
|
6954
6954
|
}
|
|
6955
6955
|
var pulseClass;
|
|
@@ -7858,8 +7858,8 @@ var init_Tooltip = __esm({
|
|
|
7858
7858
|
if (hideTimeoutRef.current) clearTimeout(hideTimeoutRef.current);
|
|
7859
7859
|
};
|
|
7860
7860
|
}, []);
|
|
7861
|
-
const triggerElement =
|
|
7862
|
-
const trigger =
|
|
7861
|
+
const triggerElement = React80__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
|
|
7862
|
+
const trigger = React80__default.cloneElement(triggerElement, {
|
|
7863
7863
|
ref: triggerRef,
|
|
7864
7864
|
onMouseEnter: handleMouseEnter,
|
|
7865
7865
|
onMouseLeave: handleMouseLeave,
|
|
@@ -8014,8 +8014,8 @@ var init_Popover = __esm({
|
|
|
8014
8014
|
onMouseEnter: handleOpen,
|
|
8015
8015
|
onMouseLeave: handleClose
|
|
8016
8016
|
};
|
|
8017
|
-
const childElement =
|
|
8018
|
-
const triggerElement =
|
|
8017
|
+
const childElement = React80__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
|
|
8018
|
+
const triggerElement = React80__default.cloneElement(
|
|
8019
8019
|
childElement,
|
|
8020
8020
|
{
|
|
8021
8021
|
ref: triggerRef,
|
|
@@ -8076,7 +8076,7 @@ var init_Menu = __esm({
|
|
|
8076
8076
|
className
|
|
8077
8077
|
}) => {
|
|
8078
8078
|
const eventBus = useEventBus();
|
|
8079
|
-
const { t } = useTranslate();
|
|
8079
|
+
const { t, direction } = useTranslate();
|
|
8080
8080
|
const [isOpen, setIsOpen] = useState(false);
|
|
8081
8081
|
const [activeSubMenu, setActiveSubMenu] = useState(null);
|
|
8082
8082
|
const [triggerRect, setTriggerRect] = useState(null);
|
|
@@ -8130,8 +8130,20 @@ var init_Menu = __esm({
|
|
|
8130
8130
|
"bottom-start": "top-full left-0 mt-2",
|
|
8131
8131
|
"bottom-end": "top-full right-0 mt-2"
|
|
8132
8132
|
};
|
|
8133
|
-
const
|
|
8134
|
-
|
|
8133
|
+
const rtlMirror = {
|
|
8134
|
+
"top-left": "top-right",
|
|
8135
|
+
"top-right": "top-left",
|
|
8136
|
+
"bottom-left": "bottom-right",
|
|
8137
|
+
"bottom-right": "bottom-left",
|
|
8138
|
+
"top-start": "top-end",
|
|
8139
|
+
"top-end": "top-start",
|
|
8140
|
+
"bottom-start": "bottom-end",
|
|
8141
|
+
"bottom-end": "bottom-start"
|
|
8142
|
+
};
|
|
8143
|
+
const effectivePosition = direction === "rtl" ? rtlMirror[position] ?? position : position;
|
|
8144
|
+
const subMenuSideClass = direction === "rtl" ? "right-full mr-2" : "left-full ml-2";
|
|
8145
|
+
const triggerChild = React80__default.isValidElement(trigger) ? trigger : /* @__PURE__ */ jsx(Typography, { variant: "small", as: "span", children: trigger });
|
|
8146
|
+
const triggerElement = React80__default.cloneElement(
|
|
8135
8147
|
triggerChild,
|
|
8136
8148
|
{
|
|
8137
8149
|
ref: triggerRef,
|
|
@@ -8157,7 +8169,7 @@ var init_Menu = __esm({
|
|
|
8157
8169
|
onMouseEnter: () => hasSubMenu && setActiveSubMenu(itemId),
|
|
8158
8170
|
"data-testid": item.event ? `action-${item.event}` : void 0,
|
|
8159
8171
|
className: cn(
|
|
8160
|
-
"w-full flex items-center justify-between gap-3 px-4 py-2 text-
|
|
8172
|
+
"w-full flex items-center justify-between gap-3 px-4 py-2 text-start",
|
|
8161
8173
|
"text-sm transition-colors",
|
|
8162
8174
|
"hover:bg-muted",
|
|
8163
8175
|
"focus:outline-none focus:bg-muted",
|
|
@@ -8176,7 +8188,7 @@ var init_Menu = __esm({
|
|
|
8176
8188
|
}
|
|
8177
8189
|
),
|
|
8178
8190
|
item.badge !== void 0 && /* @__PURE__ */ jsx(Badge, { variant: "default", size: "sm", children: item.badge }),
|
|
8179
|
-
hasSubMenu && /* @__PURE__ */ jsx(Icon, { name: "chevron-right", size: "sm", className: "flex-shrink-0" })
|
|
8191
|
+
hasSubMenu && /* @__PURE__ */ jsx(Icon, { name: direction === "rtl" ? "chevron-left" : "chevron-right", size: "sm", className: "flex-shrink-0" })
|
|
8180
8192
|
] })
|
|
8181
8193
|
},
|
|
8182
8194
|
itemId
|
|
@@ -8196,7 +8208,8 @@ var init_Menu = __esm({
|
|
|
8196
8208
|
Box,
|
|
8197
8209
|
{
|
|
8198
8210
|
className: cn(
|
|
8199
|
-
"absolute
|
|
8211
|
+
"absolute top-0 z-50",
|
|
8212
|
+
subMenuSideClass,
|
|
8200
8213
|
menuContainerStyles
|
|
8201
8214
|
),
|
|
8202
8215
|
children: renderMenuItems(item.subMenu)
|
|
@@ -8214,12 +8227,12 @@ var init_Menu = __esm({
|
|
|
8214
8227
|
className: cn(
|
|
8215
8228
|
"absolute z-50",
|
|
8216
8229
|
menuContainerStyles,
|
|
8217
|
-
positionClasses3[
|
|
8230
|
+
positionClasses3[effectivePosition],
|
|
8218
8231
|
className
|
|
8219
8232
|
),
|
|
8220
8233
|
style: {
|
|
8221
|
-
left:
|
|
8222
|
-
right:
|
|
8234
|
+
left: effectivePosition.includes("left") ? 0 : "auto",
|
|
8235
|
+
right: effectivePosition.includes("right") ? 0 : "auto"
|
|
8223
8236
|
},
|
|
8224
8237
|
role: "menu",
|
|
8225
8238
|
children: renderMenuItems(items)
|
|
@@ -8537,13 +8550,13 @@ var init_MapView = __esm({
|
|
|
8537
8550
|
shadowSize: [41, 41]
|
|
8538
8551
|
});
|
|
8539
8552
|
L.Marker.prototype.options.icon = defaultIcon;
|
|
8540
|
-
const { useEffect:
|
|
8553
|
+
const { useEffect: useEffect70, useRef: useRef67, useCallback: useCallback114, useState: useState100 } = React80__default;
|
|
8541
8554
|
const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
|
|
8542
8555
|
const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
|
|
8543
8556
|
function MapUpdater({ centerLat, centerLng, zoom }) {
|
|
8544
8557
|
const map = useMap();
|
|
8545
|
-
const prevRef =
|
|
8546
|
-
|
|
8558
|
+
const prevRef = useRef67({ centerLat, centerLng, zoom });
|
|
8559
|
+
useEffect70(() => {
|
|
8547
8560
|
const prev = prevRef.current;
|
|
8548
8561
|
if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
|
|
8549
8562
|
map.setView([centerLat, centerLng], zoom);
|
|
@@ -8554,7 +8567,7 @@ var init_MapView = __esm({
|
|
|
8554
8567
|
}
|
|
8555
8568
|
function MapClickHandler({ onMapClick }) {
|
|
8556
8569
|
const map = useMap();
|
|
8557
|
-
|
|
8570
|
+
useEffect70(() => {
|
|
8558
8571
|
if (!onMapClick) return;
|
|
8559
8572
|
const handler = (e) => {
|
|
8560
8573
|
onMapClick(e.latlng.lat, e.latlng.lng);
|
|
@@ -8582,8 +8595,8 @@ var init_MapView = __esm({
|
|
|
8582
8595
|
showAttribution = true
|
|
8583
8596
|
}) {
|
|
8584
8597
|
const eventBus = useEventBus2();
|
|
8585
|
-
const [clickedPosition, setClickedPosition] =
|
|
8586
|
-
const handleMapClick =
|
|
8598
|
+
const [clickedPosition, setClickedPosition] = useState100(null);
|
|
8599
|
+
const handleMapClick = useCallback114((lat, lng) => {
|
|
8587
8600
|
if (showClickedPin) {
|
|
8588
8601
|
setClickedPosition({ lat, lng });
|
|
8589
8602
|
}
|
|
@@ -8592,7 +8605,7 @@ var init_MapView = __esm({
|
|
|
8592
8605
|
eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
|
|
8593
8606
|
}
|
|
8594
8607
|
}, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
|
|
8595
|
-
const handleMarkerClick =
|
|
8608
|
+
const handleMarkerClick = useCallback114((marker) => {
|
|
8596
8609
|
onMarkerClick?.(marker);
|
|
8597
8610
|
if (markerClickEvent) {
|
|
8598
8611
|
eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
|
|
@@ -8783,7 +8796,7 @@ function InputPattern({
|
|
|
8783
8796
|
fieldName
|
|
8784
8797
|
}) {
|
|
8785
8798
|
const { emit } = useEventBus();
|
|
8786
|
-
const [localValue, setLocalValue] =
|
|
8799
|
+
const [localValue, setLocalValue] = React80__default.useState(value);
|
|
8787
8800
|
const handleChange = (e) => {
|
|
8788
8801
|
setLocalValue(e.target.value);
|
|
8789
8802
|
if (onChange) {
|
|
@@ -8813,7 +8826,7 @@ function InputPattern({
|
|
|
8813
8826
|
function TextareaPattern({
|
|
8814
8827
|
value = "",
|
|
8815
8828
|
placeholder,
|
|
8816
|
-
rows = 4,
|
|
8829
|
+
rows: rows2 = 4,
|
|
8817
8830
|
disabled = false,
|
|
8818
8831
|
fieldError,
|
|
8819
8832
|
onChange,
|
|
@@ -8821,7 +8834,7 @@ function TextareaPattern({
|
|
|
8821
8834
|
fieldName
|
|
8822
8835
|
}) {
|
|
8823
8836
|
const { emit } = useEventBus();
|
|
8824
|
-
const [localValue, setLocalValue] =
|
|
8837
|
+
const [localValue, setLocalValue] = React80__default.useState(value);
|
|
8825
8838
|
const handleChange = (e) => {
|
|
8826
8839
|
setLocalValue(e.target.value);
|
|
8827
8840
|
if (onChange) {
|
|
@@ -8833,7 +8846,7 @@ function TextareaPattern({
|
|
|
8833
8846
|
{
|
|
8834
8847
|
value: localValue,
|
|
8835
8848
|
placeholder,
|
|
8836
|
-
rows,
|
|
8849
|
+
rows: rows2,
|
|
8837
8850
|
disabled,
|
|
8838
8851
|
error: fieldError,
|
|
8839
8852
|
onChange: handleChange,
|
|
@@ -8853,7 +8866,7 @@ function SelectPattern({
|
|
|
8853
8866
|
fieldName
|
|
8854
8867
|
}) {
|
|
8855
8868
|
const { emit } = useEventBus();
|
|
8856
|
-
const [localValue, setLocalValue] =
|
|
8869
|
+
const [localValue, setLocalValue] = React80__default.useState(value);
|
|
8857
8870
|
const handleChange = (e) => {
|
|
8858
8871
|
setLocalValue(e.target.value);
|
|
8859
8872
|
if (onChange) {
|
|
@@ -8882,7 +8895,7 @@ function CheckboxPattern({
|
|
|
8882
8895
|
className
|
|
8883
8896
|
}) {
|
|
8884
8897
|
const { emit } = useEventBus();
|
|
8885
|
-
const [localChecked, setLocalChecked] =
|
|
8898
|
+
const [localChecked, setLocalChecked] = React80__default.useState(checked);
|
|
8886
8899
|
const handleChange = (e) => {
|
|
8887
8900
|
setLocalChecked(e.target.checked);
|
|
8888
8901
|
if (onChange) {
|
|
@@ -9195,9 +9208,9 @@ function ControlButton({
|
|
|
9195
9208
|
className
|
|
9196
9209
|
}) {
|
|
9197
9210
|
const eventBus = useEventBus();
|
|
9198
|
-
const [isPressed, setIsPressed] =
|
|
9211
|
+
const [isPressed, setIsPressed] = React80.useState(false);
|
|
9199
9212
|
const actualPressed = pressed ?? isPressed;
|
|
9200
|
-
const handlePointerDown =
|
|
9213
|
+
const handlePointerDown = React80.useCallback(
|
|
9201
9214
|
(e) => {
|
|
9202
9215
|
e.preventDefault();
|
|
9203
9216
|
if (disabled) return;
|
|
@@ -9207,7 +9220,7 @@ function ControlButton({
|
|
|
9207
9220
|
},
|
|
9208
9221
|
[disabled, pressEvent, eventBus, onPress]
|
|
9209
9222
|
);
|
|
9210
|
-
const handlePointerUp =
|
|
9223
|
+
const handlePointerUp = React80.useCallback(
|
|
9211
9224
|
(e) => {
|
|
9212
9225
|
e.preventDefault();
|
|
9213
9226
|
if (disabled) return;
|
|
@@ -9217,7 +9230,7 @@ function ControlButton({
|
|
|
9217
9230
|
},
|
|
9218
9231
|
[disabled, releaseEvent, eventBus, onRelease]
|
|
9219
9232
|
);
|
|
9220
|
-
const handlePointerLeave =
|
|
9233
|
+
const handlePointerLeave = React80.useCallback(
|
|
9221
9234
|
(e) => {
|
|
9222
9235
|
if (isPressed) {
|
|
9223
9236
|
setIsPressed(false);
|
|
@@ -9294,8 +9307,8 @@ function ActionButtons({
|
|
|
9294
9307
|
disabled
|
|
9295
9308
|
}) {
|
|
9296
9309
|
const eventBus = useEventBus();
|
|
9297
|
-
const [activeButtons, setActiveButtons] =
|
|
9298
|
-
const handlePress =
|
|
9310
|
+
const [activeButtons, setActiveButtons] = React80.useState(/* @__PURE__ */ new Set());
|
|
9311
|
+
const handlePress = React80.useCallback(
|
|
9299
9312
|
(id) => {
|
|
9300
9313
|
setActiveButtons((prev) => new Set(prev).add(id));
|
|
9301
9314
|
if (actionEvent) eventBus.emit(`UI:${actionEvent}`, { id, pressed: true });
|
|
@@ -9303,7 +9316,7 @@ function ActionButtons({
|
|
|
9303
9316
|
},
|
|
9304
9317
|
[actionEvent, eventBus, onAction]
|
|
9305
9318
|
);
|
|
9306
|
-
const handleRelease =
|
|
9319
|
+
const handleRelease = React80.useCallback(
|
|
9307
9320
|
(id) => {
|
|
9308
9321
|
setActiveButtons((prev) => {
|
|
9309
9322
|
const next = new Set(prev);
|
|
@@ -9499,6 +9512,91 @@ var init_ActionPalette = __esm({
|
|
|
9499
9512
|
ActionPalette.displayName = "ActionPalette";
|
|
9500
9513
|
}
|
|
9501
9514
|
});
|
|
9515
|
+
function parseValue(value) {
|
|
9516
|
+
if (value === "" || value == null) return { num: 0, prefix: "", suffix: "", decimals: 0 };
|
|
9517
|
+
const match = String(value).match(/^([^0-9]*)([0-9]+(?:\.[0-9]+)?)(.*)$/);
|
|
9518
|
+
if (!match) {
|
|
9519
|
+
return { num: 0, prefix: "", suffix: String(value), decimals: 0 };
|
|
9520
|
+
}
|
|
9521
|
+
const numStr = match[2];
|
|
9522
|
+
const decimalIdx = numStr.indexOf(".");
|
|
9523
|
+
const decimals = decimalIdx >= 0 ? numStr.length - decimalIdx - 1 : 0;
|
|
9524
|
+
return {
|
|
9525
|
+
prefix: match[1],
|
|
9526
|
+
num: parseFloat(numStr),
|
|
9527
|
+
suffix: match[3],
|
|
9528
|
+
decimals
|
|
9529
|
+
};
|
|
9530
|
+
}
|
|
9531
|
+
var AnimatedCounter2;
|
|
9532
|
+
var init_AnimatedCounter2 = __esm({
|
|
9533
|
+
"components/core/molecules/AnimatedCounter.tsx"() {
|
|
9534
|
+
"use client";
|
|
9535
|
+
init_cn();
|
|
9536
|
+
init_Box();
|
|
9537
|
+
init_Typography();
|
|
9538
|
+
AnimatedCounter2 = ({
|
|
9539
|
+
value,
|
|
9540
|
+
label,
|
|
9541
|
+
duration = 1500,
|
|
9542
|
+
className
|
|
9543
|
+
}) => {
|
|
9544
|
+
const ref = useRef(null);
|
|
9545
|
+
const [displayValue, setDisplayValue] = useState("0");
|
|
9546
|
+
const [hasAnimated, setHasAnimated] = useState(false);
|
|
9547
|
+
const animate = useCallback(() => {
|
|
9548
|
+
const { num: num2, prefix, suffix, decimals } = parseValue(value);
|
|
9549
|
+
if (num2 === 0) {
|
|
9550
|
+
setDisplayValue(String(value));
|
|
9551
|
+
return;
|
|
9552
|
+
}
|
|
9553
|
+
const startTime = performance.now();
|
|
9554
|
+
const tick = (now) => {
|
|
9555
|
+
const elapsed = now - startTime;
|
|
9556
|
+
const progress = Math.min(elapsed / duration, 1);
|
|
9557
|
+
const eased = 1 - Math.pow(1 - progress, 3);
|
|
9558
|
+
const current = eased * num2;
|
|
9559
|
+
setDisplayValue(`${prefix}${current.toFixed(decimals)}${suffix}`);
|
|
9560
|
+
if (progress < 1) {
|
|
9561
|
+
requestAnimationFrame(tick);
|
|
9562
|
+
} else {
|
|
9563
|
+
setDisplayValue(String(value));
|
|
9564
|
+
}
|
|
9565
|
+
};
|
|
9566
|
+
requestAnimationFrame(tick);
|
|
9567
|
+
}, [value, duration]);
|
|
9568
|
+
useEffect(() => {
|
|
9569
|
+
if (hasAnimated) return;
|
|
9570
|
+
const el = ref.current;
|
|
9571
|
+
if (!el) return;
|
|
9572
|
+
const observer2 = new IntersectionObserver(
|
|
9573
|
+
(entries) => {
|
|
9574
|
+
if (entries[0].isIntersecting) {
|
|
9575
|
+
setHasAnimated(true);
|
|
9576
|
+
animate();
|
|
9577
|
+
observer2.disconnect();
|
|
9578
|
+
}
|
|
9579
|
+
},
|
|
9580
|
+
{ threshold: 0.3 }
|
|
9581
|
+
);
|
|
9582
|
+
observer2.observe(el);
|
|
9583
|
+
return () => observer2.disconnect();
|
|
9584
|
+
}, [hasAnimated, animate]);
|
|
9585
|
+
return /* @__PURE__ */ jsxs(Box, { ref, className: cn("flex flex-col items-center gap-1 p-4", className), children: [
|
|
9586
|
+
/* @__PURE__ */ jsx(
|
|
9587
|
+
Typography,
|
|
9588
|
+
{
|
|
9589
|
+
variant: "h2",
|
|
9590
|
+
className: "text-primary font-bold tabular-nums",
|
|
9591
|
+
children: hasAnimated ? displayValue : "0"
|
|
9592
|
+
}
|
|
9593
|
+
),
|
|
9594
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", color: "muted", className: "text-center", children: label })
|
|
9595
|
+
] });
|
|
9596
|
+
};
|
|
9597
|
+
AnimatedCounter2.displayName = "AnimatedCounter";
|
|
9598
|
+
}
|
|
9599
|
+
});
|
|
9502
9600
|
var AuthLayout;
|
|
9503
9601
|
var init_AuthLayout = __esm({
|
|
9504
9602
|
"components/core/templates/AuthLayout.tsx"() {
|
|
@@ -10751,6 +10849,39 @@ var init_IsometricCanvas2 = __esm({
|
|
|
10751
10849
|
init_IsometricCanvas();
|
|
10752
10850
|
}
|
|
10753
10851
|
});
|
|
10852
|
+
|
|
10853
|
+
// components/game/organisms/boardEntity.ts
|
|
10854
|
+
function boardEntity(entity) {
|
|
10855
|
+
if (!entity) return void 0;
|
|
10856
|
+
return Array.isArray(entity) ? entity[0] : entity;
|
|
10857
|
+
}
|
|
10858
|
+
function str(v) {
|
|
10859
|
+
return v == null ? "" : String(v);
|
|
10860
|
+
}
|
|
10861
|
+
function num(v, fallback = 0) {
|
|
10862
|
+
const n = Number(v);
|
|
10863
|
+
return Number.isFinite(n) ? n : fallback;
|
|
10864
|
+
}
|
|
10865
|
+
function rows(v) {
|
|
10866
|
+
return Array.isArray(v) ? v : [];
|
|
10867
|
+
}
|
|
10868
|
+
function vec2(v) {
|
|
10869
|
+
const o = v ?? {};
|
|
10870
|
+
return { x: num(o.x), y: num(o.y) };
|
|
10871
|
+
}
|
|
10872
|
+
function unitPosition(u) {
|
|
10873
|
+
return vec2(u.position);
|
|
10874
|
+
}
|
|
10875
|
+
function unitTeam(u) {
|
|
10876
|
+
return str(u.team);
|
|
10877
|
+
}
|
|
10878
|
+
function unitHealth(u) {
|
|
10879
|
+
return num(u.health);
|
|
10880
|
+
}
|
|
10881
|
+
var init_boardEntity = __esm({
|
|
10882
|
+
"components/game/organisms/boardEntity.ts"() {
|
|
10883
|
+
}
|
|
10884
|
+
});
|
|
10754
10885
|
function BattleBoard({
|
|
10755
10886
|
entity,
|
|
10756
10887
|
scale = 0.45,
|
|
@@ -10777,43 +10908,49 @@ function BattleBoard({
|
|
|
10777
10908
|
attackEvent,
|
|
10778
10909
|
className
|
|
10779
10910
|
}) {
|
|
10780
|
-
const
|
|
10781
|
-
const
|
|
10782
|
-
const
|
|
10783
|
-
const
|
|
10784
|
-
const
|
|
10785
|
-
const
|
|
10786
|
-
const
|
|
10787
|
-
const
|
|
10788
|
-
const
|
|
10789
|
-
const
|
|
10790
|
-
const
|
|
10911
|
+
const board = boardEntity(entity) ?? {};
|
|
10912
|
+
const tiles = Array.isArray(board.tiles) ? board.tiles : [];
|
|
10913
|
+
const features = Array.isArray(board.features) ? board.features : [];
|
|
10914
|
+
const boardWidth = num(board.boardWidth, 8);
|
|
10915
|
+
const boardHeight = num(board.boardHeight, 6);
|
|
10916
|
+
const assetManifest = board.assetManifest;
|
|
10917
|
+
const backgroundImage = board.backgroundImage;
|
|
10918
|
+
const units = rows(board.units);
|
|
10919
|
+
const selectedUnitId = board.selectedUnitId ?? null;
|
|
10920
|
+
const currentPhase = str(board.phase) || "observation";
|
|
10921
|
+
const currentTurn = num(board.turn, 1);
|
|
10922
|
+
const gameResult = board.gameResult ?? null;
|
|
10791
10923
|
const eventBus = useEventBus();
|
|
10792
10924
|
const { t } = useTranslate();
|
|
10793
10925
|
const [hoveredTile, setHoveredTile] = useState(null);
|
|
10794
10926
|
const [isShaking, setIsShaking] = useState(false);
|
|
10795
10927
|
const selectedUnit = useMemo(
|
|
10796
|
-
() => units.find((u) => u.id === selectedUnitId) ?? null,
|
|
10928
|
+
() => units.find((u) => str(u.id) === selectedUnitId) ?? null,
|
|
10797
10929
|
[units, selectedUnitId]
|
|
10798
10930
|
);
|
|
10799
10931
|
const hoveredUnit = useMemo(() => {
|
|
10800
10932
|
if (!hoveredTile) return null;
|
|
10801
|
-
return units.find(
|
|
10802
|
-
|
|
10803
|
-
|
|
10933
|
+
return units.find((u) => {
|
|
10934
|
+
const p2 = unitPosition(u);
|
|
10935
|
+
return p2.x === hoveredTile.x && p2.y === hoveredTile.y && unitHealth(u) > 0;
|
|
10936
|
+
}) ?? null;
|
|
10804
10937
|
}, [hoveredTile, units]);
|
|
10805
|
-
const playerUnits = useMemo(() => units.filter((u) => u
|
|
10806
|
-
const enemyUnits = useMemo(() => units.filter((u) => u
|
|
10938
|
+
const playerUnits = useMemo(() => units.filter((u) => unitTeam(u) === "player" && unitHealth(u) > 0), [units]);
|
|
10939
|
+
const enemyUnits = useMemo(() => units.filter((u) => unitTeam(u) === "enemy" && unitHealth(u) > 0), [units]);
|
|
10807
10940
|
const validMoves = useMemo(() => {
|
|
10808
10941
|
if (!selectedUnit || currentPhase !== "movement") return [];
|
|
10809
10942
|
const moves = [];
|
|
10810
|
-
const range = selectedUnit.movement;
|
|
10943
|
+
const range = num(selectedUnit.movement);
|
|
10944
|
+
const origin = unitPosition(selectedUnit);
|
|
10811
10945
|
for (let dy = -range; dy <= range; dy++) {
|
|
10812
10946
|
for (let dx = -range; dx <= range; dx++) {
|
|
10813
|
-
const nx =
|
|
10814
|
-
const ny =
|
|
10947
|
+
const nx = origin.x + dx;
|
|
10948
|
+
const ny = origin.y + dy;
|
|
10815
10949
|
const dist = Math.abs(dx) + Math.abs(dy);
|
|
10816
|
-
if (dist > 0 && dist <= range && nx >= 0 && nx < boardWidth && ny >= 0 && ny < boardHeight && !units.some((u) =>
|
|
10950
|
+
if (dist > 0 && dist <= range && nx >= 0 && nx < boardWidth && ny >= 0 && ny < boardHeight && !units.some((u) => {
|
|
10951
|
+
const p2 = unitPosition(u);
|
|
10952
|
+
return p2.x === nx && p2.y === ny && unitHealth(u) > 0;
|
|
10953
|
+
})) {
|
|
10817
10954
|
moves.push({ x: nx, y: ny });
|
|
10818
10955
|
}
|
|
10819
10956
|
}
|
|
@@ -10822,11 +10959,14 @@ function BattleBoard({
|
|
|
10822
10959
|
}, [selectedUnit, currentPhase, units, boardWidth, boardHeight]);
|
|
10823
10960
|
const attackTargets = useMemo(() => {
|
|
10824
10961
|
if (!selectedUnit || currentPhase !== "action") return [];
|
|
10825
|
-
|
|
10826
|
-
|
|
10827
|
-
|
|
10962
|
+
const sp = unitPosition(selectedUnit);
|
|
10963
|
+
const sTeam = unitTeam(selectedUnit);
|
|
10964
|
+
return units.filter((u) => unitTeam(u) !== sTeam && unitHealth(u) > 0).filter((u) => {
|
|
10965
|
+
const p2 = unitPosition(u);
|
|
10966
|
+
const dx = Math.abs(p2.x - sp.x);
|
|
10967
|
+
const dy = Math.abs(p2.y - sp.y);
|
|
10828
10968
|
return dx <= 1 && dy <= 1 && dx + dy > 0;
|
|
10829
|
-
}).map((u) => u
|
|
10969
|
+
}).map((u) => unitPosition(u));
|
|
10830
10970
|
}, [selectedUnit, currentPhase, units]);
|
|
10831
10971
|
const MOVE_SPEED_MS_PER_TILE = 300;
|
|
10832
10972
|
const movementAnimRef = useRef(null);
|
|
@@ -10866,23 +11006,25 @@ function BattleBoard({
|
|
|
10866
11006
|
return () => clearInterval(interval);
|
|
10867
11007
|
}, []);
|
|
10868
11008
|
const isoUnits = useMemo(() => {
|
|
10869
|
-
return units.filter((u) => u
|
|
10870
|
-
const
|
|
11009
|
+
return units.filter((u) => unitHealth(u) > 0).map((unit) => {
|
|
11010
|
+
const id = str(unit.id);
|
|
11011
|
+
const pos = movingPositions.get(id) ?? unitPosition(unit);
|
|
11012
|
+
const unitTraits = Array.isArray(unit.traits) ? unit.traits : void 0;
|
|
10871
11013
|
return {
|
|
10872
|
-
id
|
|
11014
|
+
id,
|
|
10873
11015
|
position: pos,
|
|
10874
|
-
name: unit.name,
|
|
10875
|
-
team: unit
|
|
10876
|
-
health: unit
|
|
10877
|
-
maxHealth: unit.maxHealth,
|
|
10878
|
-
unitType: unit.unitType,
|
|
10879
|
-
heroId: unit.heroId,
|
|
10880
|
-
sprite: unit.sprite,
|
|
10881
|
-
traits:
|
|
10882
|
-
name:
|
|
10883
|
-
currentState:
|
|
10884
|
-
states:
|
|
10885
|
-
cooldown:
|
|
11016
|
+
name: str(unit.name),
|
|
11017
|
+
team: unitTeam(unit),
|
|
11018
|
+
health: unitHealth(unit),
|
|
11019
|
+
maxHealth: num(unit.maxHealth),
|
|
11020
|
+
unitType: unit.unitType == null ? void 0 : str(unit.unitType),
|
|
11021
|
+
heroId: unit.heroId == null ? void 0 : str(unit.heroId),
|
|
11022
|
+
sprite: unit.sprite == null ? void 0 : str(unit.sprite),
|
|
11023
|
+
traits: unitTraits?.map((tr) => ({
|
|
11024
|
+
name: tr.name,
|
|
11025
|
+
currentState: tr.currentState,
|
|
11026
|
+
states: tr.states,
|
|
11027
|
+
cooldown: tr.cooldown ?? 0
|
|
10886
11028
|
}))
|
|
10887
11029
|
};
|
|
10888
11030
|
});
|
|
@@ -10894,8 +11036,8 @@ function BattleBoard({
|
|
|
10894
11036
|
[scale, baseOffsetX]
|
|
10895
11037
|
);
|
|
10896
11038
|
const checkGameEnd = useCallback(() => {
|
|
10897
|
-
const pa = units.filter((u) => u
|
|
10898
|
-
const ea = units.filter((u) => u
|
|
11039
|
+
const pa = units.filter((u) => unitTeam(u) === "player" && unitHealth(u) > 0);
|
|
11040
|
+
const ea = units.filter((u) => unitTeam(u) === "enemy" && unitHealth(u) > 0);
|
|
10899
11041
|
if (pa.length === 0) {
|
|
10900
11042
|
onGameEnd?.("defeat");
|
|
10901
11043
|
if (gameEndEvent) {
|
|
@@ -10909,21 +11051,22 @@ function BattleBoard({
|
|
|
10909
11051
|
}
|
|
10910
11052
|
}, [units, onGameEnd, gameEndEvent, eventBus]);
|
|
10911
11053
|
const handleUnitClick = useCallback((unitId) => {
|
|
10912
|
-
const unit = units.find((u) => u.id === unitId);
|
|
11054
|
+
const unit = units.find((u) => str(u.id) === unitId);
|
|
10913
11055
|
if (!unit) return;
|
|
10914
11056
|
if (unitClickEvent) {
|
|
10915
11057
|
eventBus.emit(`UI:${unitClickEvent}`, { unitId });
|
|
10916
11058
|
}
|
|
10917
11059
|
if (currentPhase === "action" && selectedUnit) {
|
|
10918
|
-
|
|
10919
|
-
|
|
11060
|
+
const up = unitPosition(unit);
|
|
11061
|
+
if (unitTeam(unit) === "enemy" && attackTargets.some((t2) => t2.x === up.x && t2.y === up.y)) {
|
|
11062
|
+
const damage = calculateDamage2 ? calculateDamage2(selectedUnit, unit) : Math.max(1, num(selectedUnit.attack) - num(unit.defense));
|
|
10920
11063
|
setIsShaking(true);
|
|
10921
11064
|
setTimeout(() => setIsShaking(false), 300);
|
|
10922
11065
|
onAttack?.(selectedUnit, unit, damage);
|
|
10923
11066
|
if (attackEvent) {
|
|
10924
11067
|
eventBus.emit(`UI:${attackEvent}`, {
|
|
10925
|
-
attackerId: selectedUnit.id,
|
|
10926
|
-
targetId: unit.id,
|
|
11068
|
+
attackerId: str(selectedUnit.id),
|
|
11069
|
+
targetId: str(unit.id),
|
|
10927
11070
|
damage
|
|
10928
11071
|
});
|
|
10929
11072
|
}
|
|
@@ -10938,9 +11081,9 @@ function BattleBoard({
|
|
|
10938
11081
|
if (currentPhase === "movement" && selectedUnit) {
|
|
10939
11082
|
if (movementAnimRef.current) return;
|
|
10940
11083
|
if (validMoves.some((m) => m.x === x && m.y === y)) {
|
|
10941
|
-
const from = { ...selectedUnit
|
|
11084
|
+
const from = { ...unitPosition(selectedUnit) };
|
|
10942
11085
|
const to = { x, y };
|
|
10943
|
-
startMoveAnimation(selectedUnit.id, from, to, () => {
|
|
11086
|
+
startMoveAnimation(str(selectedUnit.id), from, to, () => {
|
|
10944
11087
|
onUnitMove?.(selectedUnit, to);
|
|
10945
11088
|
});
|
|
10946
11089
|
}
|
|
@@ -11098,6 +11241,7 @@ var init_BattleBoard = __esm({
|
|
|
11098
11241
|
init_Typography();
|
|
11099
11242
|
init_Stack();
|
|
11100
11243
|
init_IsometricCanvas2();
|
|
11244
|
+
init_boardEntity();
|
|
11101
11245
|
init_isometric();
|
|
11102
11246
|
BattleBoard.displayName = "BattleBoard";
|
|
11103
11247
|
}
|
|
@@ -12178,7 +12322,7 @@ var init_CodeBlock = __esm({
|
|
|
12178
12322
|
log5 = createLogger("almadar:ui:markdown-code");
|
|
12179
12323
|
LINE_PROPS_FN = (n) => ({ "data-line": String(n - 1) });
|
|
12180
12324
|
HIDDEN_LINE_NUMBERS = { display: "none" };
|
|
12181
|
-
CodeBlock =
|
|
12325
|
+
CodeBlock = React80__default.memo(
|
|
12182
12326
|
({
|
|
12183
12327
|
code: rawCode,
|
|
12184
12328
|
language = "text",
|
|
@@ -12320,24 +12464,24 @@ var init_CodeBlock = __esm({
|
|
|
12320
12464
|
return;
|
|
12321
12465
|
}
|
|
12322
12466
|
lineEls.forEach((el) => {
|
|
12323
|
-
const
|
|
12324
|
-
if (hiddenLines.has(
|
|
12467
|
+
const num2 = parseInt(el.getAttribute("data-line") ?? "-1", 10);
|
|
12468
|
+
if (hiddenLines.has(num2)) {
|
|
12325
12469
|
el.style.display = "none";
|
|
12326
12470
|
return;
|
|
12327
12471
|
}
|
|
12328
12472
|
el.style.display = "";
|
|
12329
12473
|
el.style.position = "relative";
|
|
12330
12474
|
el.style.paddingLeft = "1.2em";
|
|
12331
|
-
const region = foldStartMap.get(
|
|
12475
|
+
const region = foldStartMap.get(num2);
|
|
12332
12476
|
if (!region) return;
|
|
12333
|
-
const isCollapsed = collapsed.has(
|
|
12477
|
+
const isCollapsed = collapsed.has(num2);
|
|
12334
12478
|
const toggle = document.createElement("span");
|
|
12335
12479
|
toggle.className = "fold-toggle";
|
|
12336
12480
|
toggle.textContent = isCollapsed ? "\u25B6" : "\u25BC";
|
|
12337
12481
|
toggle.style.cssText = "position:absolute;left:0;top:0;width:1.2em;text-align:center;cursor:pointer;color:#858585;font-size:10px;user-select:none;line-height:inherit;height:100%";
|
|
12338
12482
|
toggle.addEventListener("click", (e) => {
|
|
12339
12483
|
e.stopPropagation();
|
|
12340
|
-
toggleFoldRef.current(
|
|
12484
|
+
toggleFoldRef.current(num2);
|
|
12341
12485
|
});
|
|
12342
12486
|
el.insertBefore(toggle, el.firstChild);
|
|
12343
12487
|
if (isCollapsed) {
|
|
@@ -12615,7 +12759,7 @@ var init_MarkdownContent = __esm({
|
|
|
12615
12759
|
init_Box();
|
|
12616
12760
|
init_CodeBlock();
|
|
12617
12761
|
init_cn();
|
|
12618
|
-
MarkdownContent =
|
|
12762
|
+
MarkdownContent = React80__default.memo(
|
|
12619
12763
|
({ content, direction, className }) => {
|
|
12620
12764
|
const { t: _t } = useTranslate();
|
|
12621
12765
|
const safeContent = typeof content === "string" ? content : String(content ?? "");
|
|
@@ -13711,7 +13855,7 @@ var init_StateMachineView = __esm({
|
|
|
13711
13855
|
style: { top: title ? 30 : 0 },
|
|
13712
13856
|
children: [
|
|
13713
13857
|
entity && /* @__PURE__ */ jsx(EntityBox, { entity, config }),
|
|
13714
|
-
states.map((state) => renderStateNode ? /* @__PURE__ */ jsx(
|
|
13858
|
+
states.map((state) => renderStateNode ? /* @__PURE__ */ jsx(React80__default.Fragment, { children: renderStateNode(state, config) }, state.id) : /* @__PURE__ */ jsx(
|
|
13715
13859
|
StateNode,
|
|
13716
13860
|
{
|
|
13717
13861
|
state,
|
|
@@ -14590,10 +14734,13 @@ var init_BookChapterView = __esm({
|
|
|
14590
14734
|
init_cn();
|
|
14591
14735
|
BookChapterView = ({
|
|
14592
14736
|
chapter,
|
|
14737
|
+
orbitalSchema,
|
|
14593
14738
|
direction,
|
|
14594
14739
|
className
|
|
14595
14740
|
}) => {
|
|
14596
14741
|
const { t: _t } = useTranslate();
|
|
14742
|
+
const title = String(chapter.title ?? "");
|
|
14743
|
+
const content = String(chapter.content ?? "");
|
|
14597
14744
|
return /* @__PURE__ */ jsxs(
|
|
14598
14745
|
VStack,
|
|
14599
14746
|
{
|
|
@@ -14601,16 +14748,16 @@ var init_BookChapterView = __esm({
|
|
|
14601
14748
|
className: cn("px-6 py-8 max-w-4xl mx-auto w-full", className),
|
|
14602
14749
|
style: { direction },
|
|
14603
14750
|
children: [
|
|
14604
|
-
/* @__PURE__ */ jsx(Typography, { variant: "h1", className: "text-3xl font-bold", children:
|
|
14751
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h1", className: "text-3xl font-bold", children: title }),
|
|
14605
14752
|
/* @__PURE__ */ jsx(Divider, {}),
|
|
14606
|
-
!!
|
|
14753
|
+
!!orbitalSchema && /* @__PURE__ */ jsx(ScaledDiagram, { children: /* @__PURE__ */ jsx(
|
|
14607
14754
|
JazariStateMachine,
|
|
14608
14755
|
{
|
|
14609
|
-
schema:
|
|
14756
|
+
schema: orbitalSchema,
|
|
14610
14757
|
direction
|
|
14611
14758
|
}
|
|
14612
14759
|
) }),
|
|
14613
|
-
/* @__PURE__ */ jsx(ContentRenderer, { content
|
|
14760
|
+
/* @__PURE__ */ jsx(ContentRenderer, { content, direction })
|
|
14614
14761
|
]
|
|
14615
14762
|
}
|
|
14616
14763
|
);
|
|
@@ -14708,7 +14855,7 @@ var init_BookNavBar = __esm({
|
|
|
14708
14855
|
BookNavBar = ({
|
|
14709
14856
|
currentPage,
|
|
14710
14857
|
totalPages,
|
|
14711
|
-
chapterTitle,
|
|
14858
|
+
chapterTitle: chapterTitle2,
|
|
14712
14859
|
direction,
|
|
14713
14860
|
className
|
|
14714
14861
|
}) => {
|
|
@@ -14749,12 +14896,12 @@ var init_BookNavBar = __esm({
|
|
|
14749
14896
|
)
|
|
14750
14897
|
] }),
|
|
14751
14898
|
/* @__PURE__ */ jsxs(Box, { className: "flex-1 mx-4 max-w-md", children: [
|
|
14752
|
-
|
|
14899
|
+
chapterTitle2 && /* @__PURE__ */ jsx(
|
|
14753
14900
|
Typography,
|
|
14754
14901
|
{
|
|
14755
14902
|
variant: "caption",
|
|
14756
14903
|
className: "text-center block truncate text-muted-foreground",
|
|
14757
|
-
children:
|
|
14904
|
+
children: chapterTitle2
|
|
14758
14905
|
}
|
|
14759
14906
|
),
|
|
14760
14907
|
/* @__PURE__ */ jsx(ProgressBar, { value: progress, size: "sm", variant: "primary" })
|
|
@@ -14821,31 +14968,35 @@ var init_BookTableOfContents = __esm({
|
|
|
14821
14968
|
style: { direction },
|
|
14822
14969
|
children: [
|
|
14823
14970
|
/* @__PURE__ */ jsx(Typography, { variant: "h1", className: "text-3xl font-bold text-center mb-4", children: t("book.tableOfContents") }),
|
|
14824
|
-
parts.map((part, partIdx) =>
|
|
14825
|
-
|
|
14826
|
-
|
|
14827
|
-
/* @__PURE__ */
|
|
14828
|
-
|
|
14829
|
-
|
|
14830
|
-
|
|
14831
|
-
|
|
14832
|
-
|
|
14833
|
-
|
|
14834
|
-
|
|
14835
|
-
|
|
14836
|
-
|
|
14837
|
-
|
|
14838
|
-
|
|
14839
|
-
|
|
14840
|
-
|
|
14841
|
-
|
|
14842
|
-
|
|
14843
|
-
|
|
14844
|
-
|
|
14845
|
-
|
|
14846
|
-
|
|
14847
|
-
|
|
14848
|
-
|
|
14971
|
+
parts.map((part, partIdx) => {
|
|
14972
|
+
const chapters = Array.isArray(part.chapters) ? part.chapters : [];
|
|
14973
|
+
return /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
14974
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "sm", align: "center", children: [
|
|
14975
|
+
/* @__PURE__ */ jsx(Badge, { variant: "default", size: "sm", children: t("book.partNumber", { number: String(partIdx + 1) }) }),
|
|
14976
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h3", className: "font-semibold", children: String(part.title ?? "") })
|
|
14977
|
+
] }),
|
|
14978
|
+
/* @__PURE__ */ jsx(VStack, { gap: "xs", className: direction === "rtl" ? "pr-6" : "pl-6", children: chapters.map((chapter) => {
|
|
14979
|
+
const id = chapter.id == null ? "" : String(chapter.id);
|
|
14980
|
+
const isCurrent = id === currentChapterId;
|
|
14981
|
+
return /* @__PURE__ */ jsx(
|
|
14982
|
+
Button,
|
|
14983
|
+
{
|
|
14984
|
+
variant: "ghost",
|
|
14985
|
+
size: "sm",
|
|
14986
|
+
action: "BOOK_NAVIGATE",
|
|
14987
|
+
actionPayload: { chapterId: id },
|
|
14988
|
+
className: cn(
|
|
14989
|
+
"justify-start text-left w-full",
|
|
14990
|
+
direction === "rtl" && "text-right",
|
|
14991
|
+
isCurrent && "bg-blue-50 dark:bg-blue-950 text-blue-600 dark:text-blue-400"
|
|
14992
|
+
),
|
|
14993
|
+
children: /* @__PURE__ */ jsx(Box, { className: "truncate", children: /* @__PURE__ */ jsx(Typography, { variant: "body", children: String(chapter.title ?? "") }) })
|
|
14994
|
+
},
|
|
14995
|
+
id
|
|
14996
|
+
);
|
|
14997
|
+
}) })
|
|
14998
|
+
] }, partIdx);
|
|
14999
|
+
})
|
|
14849
15000
|
]
|
|
14850
15001
|
}
|
|
14851
15002
|
);
|
|
@@ -14967,27 +15118,41 @@ function resolveFieldMap(fieldMap) {
|
|
|
14967
15118
|
function get(obj, key) {
|
|
14968
15119
|
return obj[key];
|
|
14969
15120
|
}
|
|
15121
|
+
function asStr(v) {
|
|
15122
|
+
return v == null ? "" : String(v);
|
|
15123
|
+
}
|
|
14970
15124
|
function mapBookData(raw, fields = IDENTITY_BOOK_FIELDS) {
|
|
14971
15125
|
const rawParts = get(raw, fields.parts) ?? [];
|
|
14972
|
-
|
|
14973
|
-
|
|
14974
|
-
|
|
14975
|
-
|
|
14976
|
-
|
|
14977
|
-
|
|
14978
|
-
|
|
14979
|
-
const rawChapters = get(part, fields.chapters) ?? [];
|
|
14980
|
-
return {
|
|
14981
|
-
title: get(part, fields.partTitle) ?? "",
|
|
14982
|
-
chapters: rawChapters.map((ch) => ({
|
|
14983
|
-
id: get(ch, fields.chapterId) ?? "",
|
|
14984
|
-
title: get(ch, fields.chapterTitle) ?? "",
|
|
14985
|
-
content: get(ch, fields.chapterContent) ?? "",
|
|
14986
|
-
orbitalSchema: get(ch, fields.chapterOrbitalSchema)
|
|
14987
|
-
}))
|
|
14988
|
-
};
|
|
14989
|
-
})
|
|
15126
|
+
const direction = get(raw, fields.direction) ?? "ltr";
|
|
15127
|
+
const cover = {
|
|
15128
|
+
title: asStr(get(raw, fields.title)),
|
|
15129
|
+
subtitle: asStr(get(raw, fields.subtitle)),
|
|
15130
|
+
author: asStr(get(raw, fields.author)),
|
|
15131
|
+
coverImageUrl: asStr(get(raw, fields.coverImageUrl)),
|
|
15132
|
+
direction
|
|
14990
15133
|
};
|
|
15134
|
+
const schemaByChapterId = {};
|
|
15135
|
+
const chapters = [];
|
|
15136
|
+
const parts = rawParts.map((part) => {
|
|
15137
|
+
const rawChapters = get(part, fields.chapters) ?? [];
|
|
15138
|
+
const chapterRows = rawChapters.map((ch) => {
|
|
15139
|
+
const id = asStr(get(ch, fields.chapterId));
|
|
15140
|
+
const schema = get(ch, fields.chapterOrbitalSchema);
|
|
15141
|
+
if (schema) schemaByChapterId[id] = schema;
|
|
15142
|
+
const row = {
|
|
15143
|
+
id,
|
|
15144
|
+
title: asStr(get(ch, fields.chapterTitle)),
|
|
15145
|
+
content: asStr(get(ch, fields.chapterContent))
|
|
15146
|
+
};
|
|
15147
|
+
chapters.push(row);
|
|
15148
|
+
return row;
|
|
15149
|
+
});
|
|
15150
|
+
return {
|
|
15151
|
+
title: asStr(get(part, fields.partTitle)),
|
|
15152
|
+
chapters: chapterRows
|
|
15153
|
+
};
|
|
15154
|
+
});
|
|
15155
|
+
return { cover, direction, parts, chapters, schemaByChapterId };
|
|
14991
15156
|
}
|
|
14992
15157
|
var IDENTITY_BOOK_FIELDS, AR_BOOK_FIELDS, FIELD_MAP_REGISTRY;
|
|
14993
15158
|
var init_types2 = __esm({
|
|
@@ -15025,10 +15190,7 @@ var init_types2 = __esm({
|
|
|
15025
15190
|
};
|
|
15026
15191
|
}
|
|
15027
15192
|
});
|
|
15028
|
-
|
|
15029
|
-
return book.parts.flatMap((part) => part.chapters);
|
|
15030
|
-
}
|
|
15031
|
-
var PRINT_STYLES, BookViewer;
|
|
15193
|
+
var chapterId, chapterTitle, PRINT_STYLES, BookViewer;
|
|
15032
15194
|
var init_BookViewer = __esm({
|
|
15033
15195
|
"components/marketing/organisms/book/BookViewer.tsx"() {
|
|
15034
15196
|
init_Box();
|
|
@@ -15041,6 +15203,8 @@ var init_BookViewer = __esm({
|
|
|
15041
15203
|
init_BookNavBar();
|
|
15042
15204
|
init_EmptyState();
|
|
15043
15205
|
init_types2();
|
|
15206
|
+
chapterId = (ch) => ch?.id == null ? void 0 : String(ch.id);
|
|
15207
|
+
chapterTitle = (ch) => ch?.title == null ? void 0 : String(ch.title);
|
|
15044
15208
|
PRINT_STYLES = `
|
|
15045
15209
|
@media print {
|
|
15046
15210
|
.book-viewer-page {
|
|
@@ -15069,14 +15233,14 @@ var init_BookViewer = __esm({
|
|
|
15069
15233
|
return mapBookData(raw, resolvedFieldMap);
|
|
15070
15234
|
}, [entity, resolvedFieldMap]);
|
|
15071
15235
|
const direction = book?.direction ?? "ltr";
|
|
15072
|
-
const chapters = useMemo(() => book ?
|
|
15236
|
+
const chapters = useMemo(() => book ? book.chapters : [], [book]);
|
|
15073
15237
|
const totalPages = 2 + chapters.length;
|
|
15074
15238
|
const navigateTo = useCallback(
|
|
15075
15239
|
(page) => {
|
|
15076
15240
|
const clamped = Math.max(0, Math.min(page, totalPages - 1));
|
|
15077
15241
|
setCurrentPage(clamped);
|
|
15078
|
-
const
|
|
15079
|
-
eventBus.emit("UI:BOOK_PAGE_CHANGE", { pageIndex: clamped, chapterId });
|
|
15242
|
+
const id = clamped >= 2 ? chapterId(chapters[clamped - 2]) : void 0;
|
|
15243
|
+
eventBus.emit("UI:BOOK_PAGE_CHANGE", { pageIndex: clamped, chapterId: id });
|
|
15080
15244
|
},
|
|
15081
15245
|
[totalPages, chapters, eventBus]
|
|
15082
15246
|
);
|
|
@@ -15088,8 +15252,8 @@ var init_BookViewer = __esm({
|
|
|
15088
15252
|
eventBus.on("UI:BOOK_PAGE_NEXT", () => navigateTo(currentPage + 1)),
|
|
15089
15253
|
eventBus.on("UI:BOOK_PRINT", () => window.print()),
|
|
15090
15254
|
eventBus.on("UI:BOOK_NAVIGATE", (event) => {
|
|
15091
|
-
const
|
|
15092
|
-
const idx = chapters.findIndex((ch) => ch
|
|
15255
|
+
const targetId = event.payload?.chapterId;
|
|
15256
|
+
const idx = chapters.findIndex((ch) => chapterId(ch) === targetId);
|
|
15093
15257
|
if (idx >= 0) navigateTo(idx + 2);
|
|
15094
15258
|
})
|
|
15095
15259
|
];
|
|
@@ -15106,9 +15270,11 @@ var init_BookViewer = __esm({
|
|
|
15106
15270
|
style.remove();
|
|
15107
15271
|
};
|
|
15108
15272
|
}, []);
|
|
15109
|
-
const currentChapterId = currentPage >= 2 ? chapters[currentPage - 2]
|
|
15110
|
-
const currentChapterTitle = currentPage >= 2 ? chapters[currentPage - 2]
|
|
15273
|
+
const currentChapterId = currentPage >= 2 ? chapterId(chapters[currentPage - 2]) : void 0;
|
|
15274
|
+
const currentChapterTitle = currentPage >= 2 ? chapterTitle(chapters[currentPage - 2]) : void 0;
|
|
15111
15275
|
if (!book) return /* @__PURE__ */ jsx(EmptyState, { message: t("book.noData") });
|
|
15276
|
+
const cover = book.cover;
|
|
15277
|
+
const coverTitle = String(cover.title ?? "");
|
|
15112
15278
|
return /* @__PURE__ */ jsxs(VStack, { className: cn("relative h-full overflow-hidden bg-background", className), children: [
|
|
15113
15279
|
/* @__PURE__ */ jsxs(
|
|
15114
15280
|
Box,
|
|
@@ -15120,10 +15286,10 @@ var init_BookViewer = __esm({
|
|
|
15120
15286
|
/* @__PURE__ */ jsx(
|
|
15121
15287
|
BookCoverPage,
|
|
15122
15288
|
{
|
|
15123
|
-
title:
|
|
15124
|
-
subtitle:
|
|
15125
|
-
author:
|
|
15126
|
-
coverImageUrl:
|
|
15289
|
+
title: coverTitle,
|
|
15290
|
+
subtitle: String(cover.subtitle ?? "") || void 0,
|
|
15291
|
+
author: String(cover.author ?? "") || void 0,
|
|
15292
|
+
coverImageUrl: String(cover.coverImageUrl ?? "") || void 0,
|
|
15127
15293
|
direction
|
|
15128
15294
|
}
|
|
15129
15295
|
),
|
|
@@ -15134,23 +15300,27 @@ var init_BookViewer = __esm({
|
|
|
15134
15300
|
direction
|
|
15135
15301
|
}
|
|
15136
15302
|
),
|
|
15137
|
-
chapters.map((chapter) =>
|
|
15138
|
-
|
|
15139
|
-
|
|
15140
|
-
|
|
15141
|
-
|
|
15142
|
-
|
|
15143
|
-
|
|
15144
|
-
|
|
15303
|
+
chapters.map((chapter) => {
|
|
15304
|
+
const id = chapterId(chapter);
|
|
15305
|
+
return /* @__PURE__ */ jsx(
|
|
15306
|
+
BookChapterView,
|
|
15307
|
+
{
|
|
15308
|
+
chapter,
|
|
15309
|
+
orbitalSchema: id ? book.schemaByChapterId[id] : void 0,
|
|
15310
|
+
direction
|
|
15311
|
+
},
|
|
15312
|
+
id
|
|
15313
|
+
);
|
|
15314
|
+
})
|
|
15145
15315
|
] }),
|
|
15146
15316
|
/* @__PURE__ */ jsxs(Box, { className: "print:hidden", children: [
|
|
15147
15317
|
currentPage === 0 && /* @__PURE__ */ jsx(
|
|
15148
15318
|
BookCoverPage,
|
|
15149
15319
|
{
|
|
15150
|
-
title:
|
|
15151
|
-
subtitle:
|
|
15152
|
-
author:
|
|
15153
|
-
coverImageUrl:
|
|
15320
|
+
title: coverTitle,
|
|
15321
|
+
subtitle: String(cover.subtitle ?? "") || void 0,
|
|
15322
|
+
author: String(cover.author ?? "") || void 0,
|
|
15323
|
+
coverImageUrl: String(cover.coverImageUrl ?? "") || void 0,
|
|
15154
15324
|
direction
|
|
15155
15325
|
}
|
|
15156
15326
|
),
|
|
@@ -15166,6 +15336,7 @@ var init_BookViewer = __esm({
|
|
|
15166
15336
|
BookChapterView,
|
|
15167
15337
|
{
|
|
15168
15338
|
chapter: chapters[currentPage - 2],
|
|
15339
|
+
orbitalSchema: currentChapterId ? book.schemaByChapterId[currentChapterId] : void 0,
|
|
15169
15340
|
direction
|
|
15170
15341
|
}
|
|
15171
15342
|
)
|
|
@@ -15178,7 +15349,7 @@ var init_BookViewer = __esm({
|
|
|
15178
15349
|
{
|
|
15179
15350
|
currentPage,
|
|
15180
15351
|
totalPages,
|
|
15181
|
-
chapterTitle: currentPage === 0 ?
|
|
15352
|
+
chapterTitle: currentPage === 0 ? coverTitle : currentPage === 1 ? t("book.tableOfContents") : currentChapterTitle,
|
|
15182
15353
|
direction
|
|
15183
15354
|
}
|
|
15184
15355
|
)
|
|
@@ -15276,7 +15447,7 @@ var init_Grid = __esm({
|
|
|
15276
15447
|
};
|
|
15277
15448
|
Grid = ({
|
|
15278
15449
|
cols = 1,
|
|
15279
|
-
rows,
|
|
15450
|
+
rows: rows2,
|
|
15280
15451
|
gap = "md",
|
|
15281
15452
|
rowGap,
|
|
15282
15453
|
colGap,
|
|
@@ -15288,8 +15459,8 @@ var init_Grid = __esm({
|
|
|
15288
15459
|
children,
|
|
15289
15460
|
as: Component = "div"
|
|
15290
15461
|
}) => {
|
|
15291
|
-
const mergedStyle =
|
|
15292
|
-
return
|
|
15462
|
+
const mergedStyle = rows2 ? { gridTemplateRows: `repeat(${rows2}, minmax(0, 1fr))`, ...style } : style;
|
|
15463
|
+
return React80__default.createElement(
|
|
15293
15464
|
Component,
|
|
15294
15465
|
{
|
|
15295
15466
|
className: cn(
|
|
@@ -16004,14 +16175,14 @@ function BuilderBoard({
|
|
|
16004
16175
|
}) {
|
|
16005
16176
|
const { emit } = useEventBus();
|
|
16006
16177
|
const { t } = useTranslate();
|
|
16007
|
-
const resolved =
|
|
16178
|
+
const resolved = boardEntity(entity);
|
|
16008
16179
|
const [placements, setPlacements] = useState({});
|
|
16009
16180
|
const [headerError, setHeaderError] = useState(false);
|
|
16010
16181
|
const [submitted, setSubmitted] = useState(false);
|
|
16011
16182
|
const [attempts, setAttempts] = useState(0);
|
|
16012
16183
|
const [showHint, setShowHint] = useState(false);
|
|
16013
|
-
const components = resolved?.components
|
|
16014
|
-
const slots = resolved?.slots
|
|
16184
|
+
const components = Array.isArray(resolved?.components) ? resolved.components : [];
|
|
16185
|
+
const slots = Array.isArray(resolved?.slots) ? resolved.slots : [];
|
|
16015
16186
|
const usedComponentIds = new Set(Object.values(placements));
|
|
16016
16187
|
const availableComponents = components.filter((c) => !usedComponentIds.has(c.id));
|
|
16017
16188
|
const [selectedComponent, setSelectedComponent] = useState(null);
|
|
@@ -16045,7 +16216,7 @@ function BuilderBoard({
|
|
|
16045
16216
|
}, [slots, placements, attempts, completeEvent, emit]);
|
|
16046
16217
|
const handleReset = () => {
|
|
16047
16218
|
setSubmitted(false);
|
|
16048
|
-
if (attempts >= 2 && resolved?.hint) {
|
|
16219
|
+
if (attempts >= 2 && str(resolved?.hint)) {
|
|
16049
16220
|
setShowHint(true);
|
|
16050
16221
|
}
|
|
16051
16222
|
};
|
|
@@ -16058,20 +16229,24 @@ function BuilderBoard({
|
|
|
16058
16229
|
};
|
|
16059
16230
|
const getComponentById = (id) => components.find((c) => c.id === id);
|
|
16060
16231
|
if (!resolved) return null;
|
|
16232
|
+
const theme = resolved.theme ?? void 0;
|
|
16233
|
+
const themeBackground = theme?.background;
|
|
16234
|
+
const headerImage = str(resolved.headerImage);
|
|
16235
|
+
const hint = str(resolved.hint);
|
|
16061
16236
|
return /* @__PURE__ */ jsx(
|
|
16062
16237
|
Box,
|
|
16063
16238
|
{
|
|
16064
16239
|
className,
|
|
16065
16240
|
style: {
|
|
16066
|
-
backgroundImage:
|
|
16241
|
+
backgroundImage: themeBackground ? `url(${themeBackground})` : void 0,
|
|
16067
16242
|
backgroundSize: "cover",
|
|
16068
16243
|
backgroundPosition: "center"
|
|
16069
16244
|
},
|
|
16070
16245
|
children: /* @__PURE__ */ jsxs(VStack, { gap: "lg", className: "p-4", children: [
|
|
16071
|
-
|
|
16246
|
+
headerImage && !headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsx("img", { src: headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : headerImage && headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
16072
16247
|
/* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
16073
|
-
/* @__PURE__ */ jsx(Typography, { variant: "h4", weight: "bold", children: resolved.title }),
|
|
16074
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body", children: resolved.description })
|
|
16248
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h4", weight: "bold", children: str(resolved.title) }),
|
|
16249
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", children: str(resolved.description) })
|
|
16075
16250
|
] }) }),
|
|
16076
16251
|
/* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
16077
16252
|
/* @__PURE__ */ jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: t("builder.components") }),
|
|
@@ -16131,9 +16306,9 @@ function BuilderBoard({
|
|
|
16131
16306
|
] }) }),
|
|
16132
16307
|
submitted && /* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", children: [
|
|
16133
16308
|
/* @__PURE__ */ jsx(Icon, { icon: allCorrect ? CheckCircle : XCircle, size: "lg", className: allCorrect ? "text-success" : "text-error" }),
|
|
16134
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "bold", children: allCorrect ? resolved.successMessage
|
|
16309
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "bold", children: allCorrect ? str(resolved.successMessage) || t("builder.success") : str(resolved.failMessage) || t("builder.incorrect") })
|
|
16135
16310
|
] }) }),
|
|
16136
|
-
showHint &&
|
|
16311
|
+
showHint && hint && /* @__PURE__ */ jsx(Card, { className: "p-4 border-l-4 border-l-warning", children: /* @__PURE__ */ jsx(Typography, { variant: "body", children: hint }) }),
|
|
16137
16312
|
/* @__PURE__ */ jsxs(HStack, { gap: "sm", justify: "center", children: [
|
|
16138
16313
|
!submitted ? /* @__PURE__ */ jsxs(Button, { variant: "primary", onClick: handleSubmit, disabled: !allPlaced, children: [
|
|
16139
16314
|
/* @__PURE__ */ jsx(Icon, { icon: Wrench, size: "sm" }),
|
|
@@ -16152,6 +16327,7 @@ var init_BuilderBoard = __esm({
|
|
|
16152
16327
|
"components/game/organisms/puzzles/builder/BuilderBoard.tsx"() {
|
|
16153
16328
|
init_atoms2();
|
|
16154
16329
|
init_useEventBus();
|
|
16330
|
+
init_boardEntity();
|
|
16155
16331
|
BuilderBoard.displayName = "BuilderBoard";
|
|
16156
16332
|
}
|
|
16157
16333
|
});
|
|
@@ -16489,21 +16665,24 @@ function CalendarGrid({
|
|
|
16489
16665
|
eventBus.emit(`UI:${longPressEvent}`, { date: day.toISOString(), time, ...longPressPayload });
|
|
16490
16666
|
}, 500);
|
|
16491
16667
|
}, [longPressEvent, longPressPayload, eventBus]);
|
|
16492
|
-
const renderEvent = (event) =>
|
|
16493
|
-
|
|
16494
|
-
|
|
16495
|
-
|
|
16496
|
-
|
|
16497
|
-
|
|
16498
|
-
|
|
16499
|
-
|
|
16500
|
-
|
|
16501
|
-
|
|
16502
|
-
|
|
16503
|
-
|
|
16504
|
-
|
|
16505
|
-
|
|
16506
|
-
|
|
16668
|
+
const renderEvent = (event) => {
|
|
16669
|
+
const color = event.color;
|
|
16670
|
+
return /* @__PURE__ */ jsx(
|
|
16671
|
+
Box,
|
|
16672
|
+
{
|
|
16673
|
+
rounded: "md",
|
|
16674
|
+
padding: "xs",
|
|
16675
|
+
border: true,
|
|
16676
|
+
className: cn(
|
|
16677
|
+
"cursor-pointer hover:shadow-sm transition-shadow text-xs truncate",
|
|
16678
|
+
color ? color : "bg-blue-500/15 border-blue-500/30 text-blue-600"
|
|
16679
|
+
),
|
|
16680
|
+
onClick: (e) => handleEventClick(event, e),
|
|
16681
|
+
children: /* @__PURE__ */ jsx(Typography, { variant: "small", className: "truncate font-medium", children: event.title })
|
|
16682
|
+
},
|
|
16683
|
+
event.id
|
|
16684
|
+
);
|
|
16685
|
+
};
|
|
16507
16686
|
return /* @__PURE__ */ jsxs(
|
|
16508
16687
|
Box,
|
|
16509
16688
|
{
|
|
@@ -18167,7 +18346,6 @@ var init_CardGrid = __esm({
|
|
|
18167
18346
|
alignItems = "stretch",
|
|
18168
18347
|
className,
|
|
18169
18348
|
children,
|
|
18170
|
-
// EntityDisplayProps
|
|
18171
18349
|
entity,
|
|
18172
18350
|
isLoading = false,
|
|
18173
18351
|
error = null,
|
|
@@ -18639,14 +18817,14 @@ var init_CaseStudyOrganism = __esm({
|
|
|
18639
18817
|
/* @__PURE__ */ jsx(SimpleGrid, { cols: cols > 0 ? cols : 1, gap: "lg", children: items.map((study) => /* @__PURE__ */ jsx(
|
|
18640
18818
|
CaseStudyCard,
|
|
18641
18819
|
{
|
|
18642
|
-
title: study.title,
|
|
18643
|
-
description: study.description,
|
|
18644
|
-
category: study.category,
|
|
18645
|
-
categoryColor: study.categoryColor,
|
|
18646
|
-
href: study.href,
|
|
18647
|
-
linkLabel: study.linkLabel
|
|
18820
|
+
title: String(study.title ?? ""),
|
|
18821
|
+
description: String(study.description ?? ""),
|
|
18822
|
+
category: String(study.category ?? ""),
|
|
18823
|
+
categoryColor: study.categoryColor != null ? String(study.categoryColor) : void 0,
|
|
18824
|
+
href: String(study.href ?? ""),
|
|
18825
|
+
linkLabel: study.linkLabel != null ? String(study.linkLabel) : void 0
|
|
18648
18826
|
},
|
|
18649
|
-
study.id
|
|
18827
|
+
String(study.id ?? "")
|
|
18650
18828
|
)) })
|
|
18651
18829
|
] });
|
|
18652
18830
|
};
|
|
@@ -18669,10 +18847,10 @@ function CastleBoard({
|
|
|
18669
18847
|
className
|
|
18670
18848
|
}) {
|
|
18671
18849
|
const eventBus = useEventBus();
|
|
18672
|
-
const resolved =
|
|
18673
|
-
const tiles = resolved?.tiles
|
|
18674
|
-
const features = resolved?.features
|
|
18675
|
-
const units = resolved?.units
|
|
18850
|
+
const resolved = boardEntity(entity);
|
|
18851
|
+
const tiles = Array.isArray(resolved?.tiles) ? resolved.tiles : [];
|
|
18852
|
+
const features = Array.isArray(resolved?.features) ? resolved.features : [];
|
|
18853
|
+
const units = Array.isArray(resolved?.units) ? resolved.units : [];
|
|
18676
18854
|
const assetManifest = resolved?.assetManifest;
|
|
18677
18855
|
const backgroundImage = resolved?.backgroundImage;
|
|
18678
18856
|
const [hoveredTile, setHoveredTile] = useState(null);
|
|
@@ -18700,7 +18878,7 @@ function CastleBoard({
|
|
|
18700
18878
|
onFeatureClick?.(feature);
|
|
18701
18879
|
if (featureClickEvent) {
|
|
18702
18880
|
eventBus.emit(`UI:${featureClickEvent}`, {
|
|
18703
|
-
featureId: feature.id,
|
|
18881
|
+
featureId: feature.id ?? "",
|
|
18704
18882
|
featureType: feature.type,
|
|
18705
18883
|
x: feature.x,
|
|
18706
18884
|
y: feature.y
|
|
@@ -18768,6 +18946,7 @@ var init_CastleBoard = __esm({
|
|
|
18768
18946
|
init_cn();
|
|
18769
18947
|
init_useEventBus();
|
|
18770
18948
|
init_IsometricCanvas2();
|
|
18949
|
+
init_boardEntity();
|
|
18771
18950
|
init_isometric();
|
|
18772
18951
|
CastleBoard.displayName = "CastleBoard";
|
|
18773
18952
|
}
|
|
@@ -19624,14 +19803,14 @@ function ClassifierBoard({
|
|
|
19624
19803
|
}) {
|
|
19625
19804
|
const { emit } = useEventBus();
|
|
19626
19805
|
const { t } = useTranslate();
|
|
19627
|
-
const resolved =
|
|
19806
|
+
const resolved = boardEntity(entity);
|
|
19628
19807
|
const [assignments, setAssignments] = useState({});
|
|
19629
19808
|
const [headerError, setHeaderError] = useState(false);
|
|
19630
19809
|
const [submitted, setSubmitted] = useState(false);
|
|
19631
19810
|
const [attempts, setAttempts] = useState(0);
|
|
19632
19811
|
const [showHint, setShowHint] = useState(false);
|
|
19633
|
-
const items = resolved?.items
|
|
19634
|
-
const categories = resolved?.categories
|
|
19812
|
+
const items = Array.isArray(resolved?.items) ? resolved.items : [];
|
|
19813
|
+
const categories = Array.isArray(resolved?.categories) ? resolved.categories : [];
|
|
19635
19814
|
const unassignedItems = items.filter((item) => !assignments[item.id]);
|
|
19636
19815
|
const allAssigned = Object.keys(assignments).length === items.length;
|
|
19637
19816
|
const results = submitted ? items.map((item) => ({
|
|
@@ -19663,7 +19842,7 @@ function ClassifierBoard({
|
|
|
19663
19842
|
}, [items, assignments, attempts, completeEvent, emit]);
|
|
19664
19843
|
const handleReset = () => {
|
|
19665
19844
|
setSubmitted(false);
|
|
19666
|
-
if (attempts >= 2 && resolved?.hint) {
|
|
19845
|
+
if (attempts >= 2 && str(resolved?.hint)) {
|
|
19667
19846
|
setShowHint(true);
|
|
19668
19847
|
}
|
|
19669
19848
|
};
|
|
@@ -19674,20 +19853,25 @@ function ClassifierBoard({
|
|
|
19674
19853
|
setShowHint(false);
|
|
19675
19854
|
};
|
|
19676
19855
|
if (!resolved) return null;
|
|
19856
|
+
const theme = resolved.theme ?? void 0;
|
|
19857
|
+
const themeBackground = theme?.background;
|
|
19858
|
+
const headerImage = str(resolved.headerImage);
|
|
19859
|
+
const hint = str(resolved.hint);
|
|
19860
|
+
const failMessage = str(resolved.failMessage);
|
|
19677
19861
|
return /* @__PURE__ */ jsx(
|
|
19678
19862
|
Box,
|
|
19679
19863
|
{
|
|
19680
19864
|
className,
|
|
19681
19865
|
style: {
|
|
19682
|
-
backgroundImage:
|
|
19866
|
+
backgroundImage: themeBackground ? `url(${themeBackground})` : void 0,
|
|
19683
19867
|
backgroundSize: "cover",
|
|
19684
19868
|
backgroundPosition: "center"
|
|
19685
19869
|
},
|
|
19686
19870
|
children: /* @__PURE__ */ jsxs(VStack, { gap: "lg", className: "p-4", children: [
|
|
19687
|
-
|
|
19871
|
+
headerImage && !headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsx("img", { src: headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : headerImage && headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
19688
19872
|
/* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
19689
|
-
/* @__PURE__ */ jsx(Typography, { variant: "h4", weight: "bold", children: resolved.title }),
|
|
19690
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body", children: resolved.description })
|
|
19873
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h4", weight: "bold", children: str(resolved.title) }),
|
|
19874
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", children: str(resolved.description) })
|
|
19691
19875
|
] }) }),
|
|
19692
19876
|
unassignedItems.length > 0 && /* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
19693
19877
|
/* @__PURE__ */ jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: t("classifier.itemsToSort") }),
|
|
@@ -19739,10 +19923,10 @@ function ClassifierBoard({
|
|
|
19739
19923
|
}) }),
|
|
19740
19924
|
submitted && /* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", children: [
|
|
19741
19925
|
/* @__PURE__ */ jsx(Icon, { icon: allCorrect ? CheckCircle : XCircle, size: "lg", className: allCorrect ? "text-success" : "text-error" }),
|
|
19742
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "bold", children: allCorrect ? resolved.successMessage
|
|
19743
|
-
!allCorrect &&
|
|
19926
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "bold", children: allCorrect ? str(resolved.successMessage) || t("classifier.allCorrect") : `${correctCount}/${items.length} ${t("classifier.correct")}` }),
|
|
19927
|
+
!allCorrect && failMessage && /* @__PURE__ */ jsx(Typography, { variant: "body", className: "text-muted-foreground", children: failMessage })
|
|
19744
19928
|
] }) }),
|
|
19745
|
-
showHint &&
|
|
19929
|
+
showHint && hint && /* @__PURE__ */ jsx(Card, { className: "p-4 border-l-4 border-l-warning", children: /* @__PURE__ */ jsx(Typography, { variant: "body", children: hint }) }),
|
|
19746
19930
|
/* @__PURE__ */ jsxs(HStack, { gap: "sm", justify: "center", children: [
|
|
19747
19931
|
!submitted ? /* @__PURE__ */ jsxs(Button, { variant: "primary", onClick: handleSubmit, disabled: !allAssigned, children: [
|
|
19748
19932
|
/* @__PURE__ */ jsx(Icon, { icon: Send, size: "sm" }),
|
|
@@ -19761,6 +19945,7 @@ var init_ClassifierBoard = __esm({
|
|
|
19761
19945
|
"components/game/organisms/puzzles/classifier/ClassifierBoard.tsx"() {
|
|
19762
19946
|
init_atoms2();
|
|
19763
19947
|
init_useEventBus();
|
|
19948
|
+
init_boardEntity();
|
|
19764
19949
|
ClassifierBoard.displayName = "ClassifierBoard";
|
|
19765
19950
|
}
|
|
19766
19951
|
});
|
|
@@ -20813,7 +20998,7 @@ function CraftingRecipe({
|
|
|
20813
20998
|
className
|
|
20814
20999
|
}) {
|
|
20815
21000
|
const eventBus = useEventBus();
|
|
20816
|
-
const handleCraft =
|
|
21001
|
+
const handleCraft = React80.useCallback(() => {
|
|
20817
21002
|
onCraft?.();
|
|
20818
21003
|
if (craftEvent) {
|
|
20819
21004
|
eventBus.emit(craftEvent, { output: output.label });
|
|
@@ -20830,7 +21015,7 @@ function CraftingRecipe({
|
|
|
20830
21015
|
children: [
|
|
20831
21016
|
/* @__PURE__ */ jsx(HStack, { gap: "xs", className: "flex-wrap items-center", children: inputs.map((ingredient, index) => {
|
|
20832
21017
|
const hasSufficient = ingredient.available >= ingredient.required;
|
|
20833
|
-
return /* @__PURE__ */ jsxs(
|
|
21018
|
+
return /* @__PURE__ */ jsxs(React80.Fragment, { children: [
|
|
20834
21019
|
/* @__PURE__ */ jsx(Box, { className: "relative", children: /* @__PURE__ */ jsx(
|
|
20835
21020
|
ItemSlot,
|
|
20836
21021
|
{
|
|
@@ -20893,8 +21078,8 @@ function DPad({
|
|
|
20893
21078
|
}) {
|
|
20894
21079
|
const eventBus = useEventBus();
|
|
20895
21080
|
const sizes = sizeMap6[size];
|
|
20896
|
-
const [activeDirections, setActiveDirections] =
|
|
20897
|
-
const handlePress =
|
|
21081
|
+
const [activeDirections, setActiveDirections] = React80.useState(/* @__PURE__ */ new Set());
|
|
21082
|
+
const handlePress = React80.useCallback(
|
|
20898
21083
|
(direction) => {
|
|
20899
21084
|
setActiveDirections((prev) => new Set(prev).add(direction));
|
|
20900
21085
|
if (directionEvent) eventBus.emit(`UI:${directionEvent}`, { direction, pressed: true });
|
|
@@ -20902,7 +21087,7 @@ function DPad({
|
|
|
20902
21087
|
},
|
|
20903
21088
|
[directionEvent, eventBus, onDirection]
|
|
20904
21089
|
);
|
|
20905
|
-
const handleRelease =
|
|
21090
|
+
const handleRelease = React80.useCallback(
|
|
20906
21091
|
(direction) => {
|
|
20907
21092
|
setActiveDirections((prev) => {
|
|
20908
21093
|
const next = new Set(prev);
|
|
@@ -21637,14 +21822,14 @@ function useDataDnd(args) {
|
|
|
21637
21822
|
const isZone = Boolean(dragGroup || accepts || sortable);
|
|
21638
21823
|
const enabled = isZone || Boolean(dndRoot);
|
|
21639
21824
|
const eventBus = useEventBus();
|
|
21640
|
-
const parentRoot =
|
|
21825
|
+
const parentRoot = React80__default.useContext(RootCtx);
|
|
21641
21826
|
const isRoot = enabled && parentRoot === null;
|
|
21642
|
-
const zoneId =
|
|
21827
|
+
const zoneId = React80__default.useId();
|
|
21643
21828
|
const ownGroup = dragGroup ?? accepts ?? zoneId;
|
|
21644
|
-
const [optimisticOrders, setOptimisticOrders] =
|
|
21645
|
-
const optimisticOrdersRef =
|
|
21829
|
+
const [optimisticOrders, setOptimisticOrders] = React80__default.useState(() => /* @__PURE__ */ new Map());
|
|
21830
|
+
const optimisticOrdersRef = React80__default.useRef(optimisticOrders);
|
|
21646
21831
|
optimisticOrdersRef.current = optimisticOrders;
|
|
21647
|
-
const clearOptimisticOrder =
|
|
21832
|
+
const clearOptimisticOrder = React80__default.useCallback((group) => {
|
|
21648
21833
|
setOptimisticOrders((prev) => {
|
|
21649
21834
|
if (!prev.has(group)) return prev;
|
|
21650
21835
|
const next = new Map(prev);
|
|
@@ -21669,7 +21854,7 @@ function useDataDnd(args) {
|
|
|
21669
21854
|
const raw = it[dndItemIdField];
|
|
21670
21855
|
return String(raw ?? `__idx_${idx}`);
|
|
21671
21856
|
}).join("|");
|
|
21672
|
-
const itemIds =
|
|
21857
|
+
const itemIds = React80__default.useMemo(
|
|
21673
21858
|
() => orderedItems.map((it, idx) => {
|
|
21674
21859
|
const raw = it[dndItemIdField];
|
|
21675
21860
|
return raw ?? `__idx_${idx}`;
|
|
@@ -21677,7 +21862,7 @@ function useDataDnd(args) {
|
|
|
21677
21862
|
[itemIdsSignature]
|
|
21678
21863
|
);
|
|
21679
21864
|
const itemsContentSig = items.map((it, idx) => String(it[dndItemIdField] ?? `__${idx}`)).join("|");
|
|
21680
|
-
|
|
21865
|
+
React80__default.useEffect(() => {
|
|
21681
21866
|
const root = isRoot ? null : parentRoot;
|
|
21682
21867
|
if (root) {
|
|
21683
21868
|
root.clearOptimisticOrder(ownGroup);
|
|
@@ -21685,20 +21870,20 @@ function useDataDnd(args) {
|
|
|
21685
21870
|
clearOptimisticOrder(ownGroup);
|
|
21686
21871
|
}
|
|
21687
21872
|
}, [itemsContentSig, ownGroup]);
|
|
21688
|
-
const zonesRef =
|
|
21689
|
-
const registerZone =
|
|
21873
|
+
const zonesRef = React80__default.useRef(/* @__PURE__ */ new Map());
|
|
21874
|
+
const registerZone = React80__default.useCallback((zoneId2, meta2) => {
|
|
21690
21875
|
zonesRef.current.set(zoneId2, meta2);
|
|
21691
21876
|
}, []);
|
|
21692
|
-
const unregisterZone =
|
|
21877
|
+
const unregisterZone = React80__default.useCallback((zoneId2) => {
|
|
21693
21878
|
zonesRef.current.delete(zoneId2);
|
|
21694
21879
|
}, []);
|
|
21695
|
-
const [activeDrag, setActiveDrag] =
|
|
21696
|
-
const [overZoneGroup, setOverZoneGroup] =
|
|
21697
|
-
const meta =
|
|
21880
|
+
const [activeDrag, setActiveDrag] = React80__default.useState(null);
|
|
21881
|
+
const [overZoneGroup, setOverZoneGroup] = React80__default.useState(null);
|
|
21882
|
+
const meta = React80__default.useMemo(
|
|
21698
21883
|
() => ({ group: ownGroup, dropEvent, reorderEvent, positionEvent, itemIds, rawItems: items, idField: dndItemIdField }),
|
|
21699
21884
|
[ownGroup, dropEvent, reorderEvent, positionEvent, itemIds, items, dndItemIdField]
|
|
21700
21885
|
);
|
|
21701
|
-
|
|
21886
|
+
React80__default.useEffect(() => {
|
|
21702
21887
|
const target = isRoot ? null : parentRoot;
|
|
21703
21888
|
if (!target) {
|
|
21704
21889
|
zonesRef.current.set(zoneId, meta);
|
|
@@ -21717,7 +21902,7 @@ function useDataDnd(args) {
|
|
|
21717
21902
|
}, [parentRoot, isRoot, zoneId, meta]);
|
|
21718
21903
|
const sensors = useAlmadarDndSensors(true);
|
|
21719
21904
|
const collisionDetection = almadarDndCollisionDetection;
|
|
21720
|
-
const findZoneByItem =
|
|
21905
|
+
const findZoneByItem = React80__default.useCallback(
|
|
21721
21906
|
(id) => {
|
|
21722
21907
|
for (const z of zonesRef.current.values()) {
|
|
21723
21908
|
if (z.itemIds.includes(id)) return z;
|
|
@@ -21726,7 +21911,7 @@ function useDataDnd(args) {
|
|
|
21726
21911
|
},
|
|
21727
21912
|
[]
|
|
21728
21913
|
);
|
|
21729
|
-
|
|
21914
|
+
React80__default.useCallback(
|
|
21730
21915
|
(group) => {
|
|
21731
21916
|
for (const z of zonesRef.current.values()) {
|
|
21732
21917
|
if (z.group === group) return z;
|
|
@@ -21735,7 +21920,7 @@ function useDataDnd(args) {
|
|
|
21735
21920
|
},
|
|
21736
21921
|
[]
|
|
21737
21922
|
);
|
|
21738
|
-
const handleDragEnd =
|
|
21923
|
+
const handleDragEnd = React80__default.useCallback(
|
|
21739
21924
|
(event) => {
|
|
21740
21925
|
const { active, over } = event;
|
|
21741
21926
|
const activeIdStr = String(active.id);
|
|
@@ -21826,8 +22011,8 @@ function useDataDnd(args) {
|
|
|
21826
22011
|
},
|
|
21827
22012
|
[eventBus]
|
|
21828
22013
|
);
|
|
21829
|
-
const sortableData =
|
|
21830
|
-
const SortableItem =
|
|
22014
|
+
const sortableData = React80__default.useMemo(() => ({ dndGroup: ownGroup }), [ownGroup]);
|
|
22015
|
+
const SortableItem = React80__default.useCallback(
|
|
21831
22016
|
({ id, children }) => {
|
|
21832
22017
|
const {
|
|
21833
22018
|
attributes,
|
|
@@ -21867,7 +22052,7 @@ function useDataDnd(args) {
|
|
|
21867
22052
|
id: droppableId,
|
|
21868
22053
|
data: sortableData
|
|
21869
22054
|
});
|
|
21870
|
-
const ctx =
|
|
22055
|
+
const ctx = React80__default.useContext(RootCtx);
|
|
21871
22056
|
const activeDrag2 = ctx?.activeDrag ?? null;
|
|
21872
22057
|
const overZoneGroup2 = ctx?.overZoneGroup ?? null;
|
|
21873
22058
|
const isThisZoneOver = overZoneGroup2 === ownGroup;
|
|
@@ -21882,7 +22067,7 @@ function useDataDnd(args) {
|
|
|
21882
22067
|
showForeignPlaceholder,
|
|
21883
22068
|
ctxAvailable: ctx != null
|
|
21884
22069
|
});
|
|
21885
|
-
|
|
22070
|
+
React80__default.useEffect(() => {
|
|
21886
22071
|
dndLog.info("dropzone:isOver:change", { droppableId, group: ownGroup, isOver, isThisZoneOver, showForeignPlaceholder, activeDragSourceGroup: activeDrag2?.sourceGroup ?? null });
|
|
21887
22072
|
}, [droppableId, isOver, isThisZoneOver, showForeignPlaceholder]);
|
|
21888
22073
|
return /* @__PURE__ */ jsx(
|
|
@@ -21896,11 +22081,11 @@ function useDataDnd(args) {
|
|
|
21896
22081
|
}
|
|
21897
22082
|
);
|
|
21898
22083
|
};
|
|
21899
|
-
const rootContextValue =
|
|
22084
|
+
const rootContextValue = React80__default.useMemo(
|
|
21900
22085
|
() => ({ registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder }),
|
|
21901
22086
|
[registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder]
|
|
21902
22087
|
);
|
|
21903
|
-
const handleDragStart =
|
|
22088
|
+
const handleDragStart = React80__default.useCallback((event) => {
|
|
21904
22089
|
const sourceZone = findZoneByItem(event.active.id);
|
|
21905
22090
|
const rect = event.active.rect.current.initial;
|
|
21906
22091
|
const height = rect?.height && rect.height > 0 ? rect.height : 64;
|
|
@@ -21919,7 +22104,7 @@ function useDataDnd(args) {
|
|
|
21919
22104
|
isRoot
|
|
21920
22105
|
});
|
|
21921
22106
|
}, [findZoneByItem, isRoot, zoneId]);
|
|
21922
|
-
const handleDragOver =
|
|
22107
|
+
const handleDragOver = React80__default.useCallback((event) => {
|
|
21923
22108
|
const { active, over } = event;
|
|
21924
22109
|
const overData = over?.data?.current;
|
|
21925
22110
|
const overGroup = overData?.dndGroup ?? null;
|
|
@@ -21989,7 +22174,7 @@ function useDataDnd(args) {
|
|
|
21989
22174
|
return next;
|
|
21990
22175
|
});
|
|
21991
22176
|
}, []);
|
|
21992
|
-
const handleDragCancel =
|
|
22177
|
+
const handleDragCancel = React80__default.useCallback((event) => {
|
|
21993
22178
|
setActiveDrag(null);
|
|
21994
22179
|
setOverZoneGroup(null);
|
|
21995
22180
|
dndLog.warn("dragCancel", {
|
|
@@ -21997,12 +22182,12 @@ function useDataDnd(args) {
|
|
|
21997
22182
|
reason: "dnd-kit cancelled the drag (escape key, pointer interrupted, or external)"
|
|
21998
22183
|
});
|
|
21999
22184
|
}, []);
|
|
22000
|
-
const handleDragEndWithCleanup =
|
|
22185
|
+
const handleDragEndWithCleanup = React80__default.useCallback((event) => {
|
|
22001
22186
|
handleDragEnd(event);
|
|
22002
22187
|
setActiveDrag(null);
|
|
22003
22188
|
setOverZoneGroup(null);
|
|
22004
22189
|
}, [handleDragEnd]);
|
|
22005
|
-
const wrapContainer =
|
|
22190
|
+
const wrapContainer = React80__default.useCallback(
|
|
22006
22191
|
(children) => {
|
|
22007
22192
|
if (!enabled) return children;
|
|
22008
22193
|
const strategy = layout === "grid" ? rectSortingStrategy : verticalListSortingStrategy;
|
|
@@ -22056,7 +22241,7 @@ var init_useDataDnd = __esm({
|
|
|
22056
22241
|
init_useAlmadarDndCollision();
|
|
22057
22242
|
init_Box();
|
|
22058
22243
|
dndLog = createLogger("almadar:ui:dnd");
|
|
22059
|
-
RootCtx =
|
|
22244
|
+
RootCtx = React80__default.createContext(null);
|
|
22060
22245
|
}
|
|
22061
22246
|
});
|
|
22062
22247
|
function fieldLabel2(key) {
|
|
@@ -22576,7 +22761,7 @@ function DataList({
|
|
|
22576
22761
|
}) {
|
|
22577
22762
|
const eventBus = useEventBus();
|
|
22578
22763
|
const { t } = useTranslate();
|
|
22579
|
-
const [visibleCount, setVisibleCount] =
|
|
22764
|
+
const [visibleCount, setVisibleCount] = React80__default.useState(pageSize || Infinity);
|
|
22580
22765
|
const fieldDefs = fields ?? columns ?? [];
|
|
22581
22766
|
const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
|
|
22582
22767
|
const dnd = useDataDnd({
|
|
@@ -22595,7 +22780,7 @@ function DataList({
|
|
|
22595
22780
|
const data = pageSize > 0 ? allData.slice(0, visibleCount) : allData;
|
|
22596
22781
|
const hasMoreLocal = pageSize > 0 && visibleCount < allData.length;
|
|
22597
22782
|
const hasRenderProp = typeof children === "function";
|
|
22598
|
-
|
|
22783
|
+
React80__default.useEffect(() => {
|
|
22599
22784
|
const renderItemTypeOf = typeof schemaRenderItem;
|
|
22600
22785
|
const childrenTypeOf = typeof children;
|
|
22601
22786
|
if (data.length > 0 && !hasRenderProp) {
|
|
@@ -22700,7 +22885,7 @@ function DataList({
|
|
|
22700
22885
|
const items2 = data.map((item) => item);
|
|
22701
22886
|
const groups2 = groupBy ? groupData(items2, groupBy) : [{ label: "", items: items2 }];
|
|
22702
22887
|
const contentField = titleField?.name ?? fieldDefs[0]?.name ?? "";
|
|
22703
|
-
return /* @__PURE__ */ jsx(VStack, { gap: "sm", className: cn("py-2", className), children: groups2.map((group, gi) => /* @__PURE__ */ jsxs(
|
|
22888
|
+
return /* @__PURE__ */ jsx(VStack, { gap: "sm", className: cn("py-2", className), children: groups2.map((group, gi) => /* @__PURE__ */ jsxs(React80__default.Fragment, { children: [
|
|
22704
22889
|
group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: "my-2" }),
|
|
22705
22890
|
group.items.map((itemData, index) => {
|
|
22706
22891
|
const id = itemData.id || `${gi}-${index}`;
|
|
@@ -22848,7 +23033,7 @@ function DataList({
|
|
|
22848
23033
|
className
|
|
22849
23034
|
),
|
|
22850
23035
|
children: [
|
|
22851
|
-
groups.map((group, gi) => /* @__PURE__ */ jsxs(
|
|
23036
|
+
groups.map((group, gi) => /* @__PURE__ */ jsxs(React80__default.Fragment, { children: [
|
|
22852
23037
|
group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: gi > 0 ? "mt-4" : "mt-0" }),
|
|
22853
23038
|
group.items.map(
|
|
22854
23039
|
(itemData, index) => renderItem(itemData, index, gi === groups.length - 1 && index === group.items.length - 1)
|
|
@@ -24472,7 +24657,7 @@ var init_WizardProgress = __esm({
|
|
|
24472
24657
|
children: /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", children: normalizedSteps.map((step, index) => {
|
|
24473
24658
|
const isActive = index === currentStep;
|
|
24474
24659
|
const isCompleted = index < currentStep;
|
|
24475
|
-
return /* @__PURE__ */ jsxs(
|
|
24660
|
+
return /* @__PURE__ */ jsxs(React80__default.Fragment, { children: [
|
|
24476
24661
|
/* @__PURE__ */ jsx(
|
|
24477
24662
|
"button",
|
|
24478
24663
|
{
|
|
@@ -25519,9 +25704,9 @@ function ScoreDisplay({
|
|
|
25519
25704
|
...rest
|
|
25520
25705
|
}) {
|
|
25521
25706
|
const resolvedValue = typeof value === "number" && !Number.isNaN(value) ? value : typeof rest.score === "number" && !Number.isNaN(rest.score) ? rest.score : 0;
|
|
25522
|
-
const [displayValue, setDisplayValue] =
|
|
25523
|
-
const [isAnimating, setIsAnimating] =
|
|
25524
|
-
|
|
25707
|
+
const [displayValue, setDisplayValue] = React80.useState(resolvedValue);
|
|
25708
|
+
const [isAnimating, setIsAnimating] = React80.useState(false);
|
|
25709
|
+
React80.useEffect(() => {
|
|
25525
25710
|
if (!animated || displayValue === resolvedValue) {
|
|
25526
25711
|
setDisplayValue(resolvedValue);
|
|
25527
25712
|
return;
|
|
@@ -25668,7 +25853,7 @@ function InventoryGrid({
|
|
|
25668
25853
|
const eventBus = useEventBus();
|
|
25669
25854
|
const slotCount = totalSlots ?? items.length;
|
|
25670
25855
|
const emptySlotCount = Math.max(0, slotCount - items.length);
|
|
25671
|
-
const handleSelect =
|
|
25856
|
+
const handleSelect = React80.useCallback(
|
|
25672
25857
|
(id) => {
|
|
25673
25858
|
onSelect?.(id);
|
|
25674
25859
|
if (selectEvent) {
|
|
@@ -25954,31 +26139,31 @@ function GameCanvas2D({
|
|
|
25954
26139
|
assetBaseUrl = "",
|
|
25955
26140
|
className
|
|
25956
26141
|
}) {
|
|
25957
|
-
const canvasRef =
|
|
25958
|
-
const rafRef =
|
|
25959
|
-
const frameRef =
|
|
25960
|
-
const lastTimeRef =
|
|
25961
|
-
const imageCache =
|
|
26142
|
+
const canvasRef = React80.useRef(null);
|
|
26143
|
+
const rafRef = React80.useRef(0);
|
|
26144
|
+
const frameRef = React80.useRef(0);
|
|
26145
|
+
const lastTimeRef = React80.useRef(0);
|
|
26146
|
+
const imageCache = React80.useRef(/* @__PURE__ */ new Map());
|
|
25962
26147
|
const emit = useEmitEvent();
|
|
25963
|
-
const onDrawRef =
|
|
26148
|
+
const onDrawRef = React80.useRef(onDraw);
|
|
25964
26149
|
onDrawRef.current = onDraw;
|
|
25965
|
-
const onTickRef =
|
|
26150
|
+
const onTickRef = React80.useRef(onTick);
|
|
25966
26151
|
onTickRef.current = onTick;
|
|
25967
|
-
const tickEventRef =
|
|
26152
|
+
const tickEventRef = React80.useRef(tickEvent);
|
|
25968
26153
|
tickEventRef.current = tickEvent;
|
|
25969
|
-
const drawEventRef =
|
|
26154
|
+
const drawEventRef = React80.useRef(drawEvent);
|
|
25970
26155
|
drawEventRef.current = drawEvent;
|
|
25971
|
-
const emitRef =
|
|
26156
|
+
const emitRef = React80.useRef(emit);
|
|
25972
26157
|
emitRef.current = emit;
|
|
25973
|
-
const assetBaseUrlRef =
|
|
26158
|
+
const assetBaseUrlRef = React80.useRef(assetBaseUrl);
|
|
25974
26159
|
assetBaseUrlRef.current = assetBaseUrl;
|
|
25975
|
-
const backgroundImageRef =
|
|
26160
|
+
const backgroundImageRef = React80.useRef(backgroundImage);
|
|
25976
26161
|
backgroundImageRef.current = backgroundImage;
|
|
25977
|
-
const widthRef =
|
|
26162
|
+
const widthRef = React80.useRef(width);
|
|
25978
26163
|
widthRef.current = width;
|
|
25979
|
-
const heightRef =
|
|
26164
|
+
const heightRef = React80.useRef(height);
|
|
25980
26165
|
heightRef.current = height;
|
|
25981
|
-
const loadImage =
|
|
26166
|
+
const loadImage = React80.useCallback((url) => {
|
|
25982
26167
|
const fullUrl = url.startsWith("http") ? url : `${assetBaseUrlRef.current}${url}`;
|
|
25983
26168
|
const cached = imageCache.current.get(fullUrl);
|
|
25984
26169
|
if (cached?.complete && cached.naturalWidth > 0) return cached;
|
|
@@ -25990,7 +26175,7 @@ function GameCanvas2D({
|
|
|
25990
26175
|
}
|
|
25991
26176
|
return null;
|
|
25992
26177
|
}, []);
|
|
25993
|
-
|
|
26178
|
+
React80.useEffect(() => {
|
|
25994
26179
|
const canvas = canvasRef.current;
|
|
25995
26180
|
if (!canvas) return;
|
|
25996
26181
|
const ctx = canvas.getContext("2d");
|
|
@@ -26345,7 +26530,7 @@ function TurnPanel({
|
|
|
26345
26530
|
className
|
|
26346
26531
|
}) {
|
|
26347
26532
|
const eventBus = useEventBus();
|
|
26348
|
-
const handleAction =
|
|
26533
|
+
const handleAction = React80.useCallback(
|
|
26349
26534
|
(event) => {
|
|
26350
26535
|
if (event) {
|
|
26351
26536
|
eventBus.emit(event, { turn: currentTurn, phase, activeTeam });
|
|
@@ -26491,7 +26676,7 @@ function UnitCommandBar({
|
|
|
26491
26676
|
className
|
|
26492
26677
|
}) {
|
|
26493
26678
|
const eventBus = useEventBus();
|
|
26494
|
-
const handleCommand =
|
|
26679
|
+
const handleCommand = React80.useCallback(
|
|
26495
26680
|
(event) => {
|
|
26496
26681
|
if (event) {
|
|
26497
26682
|
eventBus.emit(event, { unitId: selectedUnitId });
|
|
@@ -26824,7 +27009,7 @@ function InventoryPanel({
|
|
|
26824
27009
|
const slotArray = Array.from({ length: safeSlots }, (_, index) => {
|
|
26825
27010
|
return safeItems[index] ?? null;
|
|
26826
27011
|
});
|
|
26827
|
-
const
|
|
27012
|
+
const rows2 = Math.ceil(safeSlots / safeColumns);
|
|
26828
27013
|
const handleSlotClick = useCallback((index) => {
|
|
26829
27014
|
if (selectSlotEvent) eventBus.emit(`UI:${selectSlotEvent}`, { index });
|
|
26830
27015
|
onSelectSlot?.(index);
|
|
@@ -26893,7 +27078,7 @@ function InventoryPanel({
|
|
|
26893
27078
|
className: "grid gap-1 bg-[var(--color-card)] p-2 rounded-container border border-border",
|
|
26894
27079
|
style: {
|
|
26895
27080
|
gridTemplateColumns: `repeat(${safeColumns}, ${slotSize}px)`,
|
|
26896
|
-
gridTemplateRows: `repeat(${
|
|
27081
|
+
gridTemplateRows: `repeat(${rows2}, ${slotSize}px)`
|
|
26897
27082
|
},
|
|
26898
27083
|
children: slotArray.map((item, index) => /* @__PURE__ */ jsx(
|
|
26899
27084
|
"button",
|
|
@@ -26976,7 +27161,7 @@ function GameMenu({
|
|
|
26976
27161
|
} catch {
|
|
26977
27162
|
}
|
|
26978
27163
|
const eventBus = eventBusProp || eventBusFromHook;
|
|
26979
|
-
const handleOptionClick =
|
|
27164
|
+
const handleOptionClick = React80.useCallback(
|
|
26980
27165
|
(option) => {
|
|
26981
27166
|
if (option.event && eventBus) {
|
|
26982
27167
|
eventBus.emit(`UI:${option.event}`, { option });
|
|
@@ -27090,7 +27275,7 @@ function GameOverScreen({
|
|
|
27090
27275
|
} catch {
|
|
27091
27276
|
}
|
|
27092
27277
|
const eventBus = eventBusProp || eventBusFromHook;
|
|
27093
|
-
const handleActionClick =
|
|
27278
|
+
const handleActionClick = React80.useCallback(
|
|
27094
27279
|
(action) => {
|
|
27095
27280
|
if (action.event && eventBus) {
|
|
27096
27281
|
eventBus.emit(`UI:${action.event}`, { action });
|
|
@@ -28589,8 +28774,8 @@ function TableView({
|
|
|
28589
28774
|
}) {
|
|
28590
28775
|
const eventBus = useEventBus();
|
|
28591
28776
|
const { t } = useTranslate();
|
|
28592
|
-
const [visibleCount, setVisibleCount] =
|
|
28593
|
-
const [localSelected, setLocalSelected] =
|
|
28777
|
+
const [visibleCount, setVisibleCount] = React80__default.useState(pageSize > 0 ? pageSize : Infinity);
|
|
28778
|
+
const [localSelected, setLocalSelected] = React80__default.useState(/* @__PURE__ */ new Set());
|
|
28594
28779
|
const colDefs = columns ?? fields ?? [];
|
|
28595
28780
|
const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
|
|
28596
28781
|
const dnd = useDataDnd({
|
|
@@ -28785,12 +28970,12 @@ function TableView({
|
|
|
28785
28970
|
]
|
|
28786
28971
|
}
|
|
28787
28972
|
);
|
|
28788
|
-
return dnd.isZone ? /* @__PURE__ */ jsx(dnd.SortableItem, { id: row[idField] ?? id, children: rowInner }, id) : /* @__PURE__ */ jsx(
|
|
28973
|
+
return dnd.isZone ? /* @__PURE__ */ jsx(dnd.SortableItem, { id: row[idField] ?? id, children: rowInner }, id) : /* @__PURE__ */ jsx(React80__default.Fragment, { children: rowInner }, id);
|
|
28789
28974
|
};
|
|
28790
28975
|
const items = data.map((row) => row);
|
|
28791
28976
|
const groups = groupBy ? groupData2(items, groupBy) : [{ label: "", items }];
|
|
28792
28977
|
let runningIndex = 0;
|
|
28793
|
-
const body = /* @__PURE__ */ jsx(Box, { role: "rowgroup", children: groups.map((group, gi) => /* @__PURE__ */ jsxs(
|
|
28978
|
+
const body = /* @__PURE__ */ jsx(Box, { role: "rowgroup", children: groups.map((group, gi) => /* @__PURE__ */ jsxs(React80__default.Fragment, { children: [
|
|
28794
28979
|
group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: gi > 0 ? "mt-3" : "mt-0" }),
|
|
28795
28980
|
group.items.map((row) => renderRow(row, runningIndex++))
|
|
28796
28981
|
] }, gi)) });
|
|
@@ -30142,7 +30327,7 @@ var init_StepFlow = __esm({
|
|
|
30142
30327
|
className
|
|
30143
30328
|
}) => {
|
|
30144
30329
|
if (orientation === "vertical") {
|
|
30145
|
-
return /* @__PURE__ */ jsx(VStack, { gap: "none", className: cn("w-full", className), children: steps.map((step, index) => /* @__PURE__ */ jsx(
|
|
30330
|
+
return /* @__PURE__ */ jsx(VStack, { gap: "none", className: cn("w-full", className), children: steps.map((step, index) => /* @__PURE__ */ jsx(React80__default.Fragment, { children: /* @__PURE__ */ jsxs(HStack, { gap: "md", align: "start", className: "w-full", children: [
|
|
30146
30331
|
/* @__PURE__ */ jsxs(VStack, { gap: "none", align: "center", children: [
|
|
30147
30332
|
/* @__PURE__ */ jsx(StepCircle, { step, index }),
|
|
30148
30333
|
showConnectors && index < steps.length - 1 && /* @__PURE__ */ jsx(Box, { className: "w-px h-8 bg-border" })
|
|
@@ -30153,7 +30338,7 @@ var init_StepFlow = __esm({
|
|
|
30153
30338
|
] })
|
|
30154
30339
|
] }) }, index)) });
|
|
30155
30340
|
}
|
|
30156
|
-
return /* @__PURE__ */ jsx(Box, { className: cn("w-full flex flex-col md:flex-row items-start gap-0", className), children: steps.map((step, index) => /* @__PURE__ */ jsxs(
|
|
30341
|
+
return /* @__PURE__ */ jsx(Box, { className: cn("w-full flex flex-col md:flex-row items-start gap-0", className), children: steps.map((step, index) => /* @__PURE__ */ jsxs(React80__default.Fragment, { children: [
|
|
30157
30342
|
/* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", className: "flex-1 w-full md:w-auto", children: [
|
|
30158
30343
|
/* @__PURE__ */ jsx(StepCircle, { step, index }),
|
|
30159
30344
|
/* @__PURE__ */ jsx(Typography, { variant: "h4", className: "text-center", children: step.title }),
|
|
@@ -30879,11 +31064,11 @@ function LatticeSVG({
|
|
|
30879
31064
|
}) {
|
|
30880
31065
|
const paths = [];
|
|
30881
31066
|
const cols = 5;
|
|
30882
|
-
const
|
|
31067
|
+
const rows2 = Math.ceil(h / (w / cols));
|
|
30883
31068
|
const cellW = w / cols;
|
|
30884
31069
|
const cellH = cellW;
|
|
30885
31070
|
const bulge = cellW * 0.3;
|
|
30886
|
-
for (let row = 0; row <
|
|
31071
|
+
for (let row = 0; row < rows2; row++) {
|
|
30887
31072
|
for (let col = 0; col < cols; col++) {
|
|
30888
31073
|
const cx = col * cellW + cellW / 2;
|
|
30889
31074
|
const cy = row * cellH + cellH / 2;
|
|
@@ -31129,7 +31314,7 @@ var init_LikertScale = __esm({
|
|
|
31129
31314
|
md: "text-base",
|
|
31130
31315
|
lg: "text-lg"
|
|
31131
31316
|
};
|
|
31132
|
-
LikertScale =
|
|
31317
|
+
LikertScale = React80__default.forwardRef(
|
|
31133
31318
|
({
|
|
31134
31319
|
question,
|
|
31135
31320
|
options = DEFAULT_LIKERT_OPTIONS,
|
|
@@ -31141,7 +31326,7 @@ var init_LikertScale = __esm({
|
|
|
31141
31326
|
variant = "radios",
|
|
31142
31327
|
className
|
|
31143
31328
|
}, ref) => {
|
|
31144
|
-
const groupId =
|
|
31329
|
+
const groupId = React80__default.useId();
|
|
31145
31330
|
const eventBus = useEventBus();
|
|
31146
31331
|
const handleSelect = useCallback(
|
|
31147
31332
|
(next) => {
|
|
@@ -31295,7 +31480,7 @@ var init_MatrixQuestion = __esm({
|
|
|
31295
31480
|
};
|
|
31296
31481
|
MatrixQuestion = ({
|
|
31297
31482
|
title,
|
|
31298
|
-
rows,
|
|
31483
|
+
rows: rows2,
|
|
31299
31484
|
columns = DEFAULT_MATRIX_COLUMNS,
|
|
31300
31485
|
values,
|
|
31301
31486
|
onChange,
|
|
@@ -31305,7 +31490,7 @@ var init_MatrixQuestion = __esm({
|
|
|
31305
31490
|
className
|
|
31306
31491
|
}) => {
|
|
31307
31492
|
const styles = sizeStyles13[size];
|
|
31308
|
-
const safeRows =
|
|
31493
|
+
const safeRows = rows2 ?? [];
|
|
31309
31494
|
const safeValues = values ?? {};
|
|
31310
31495
|
const eventBus = useEventBus();
|
|
31311
31496
|
const handleChange = useCallback(
|
|
@@ -31933,7 +32118,8 @@ var init_PositionedCanvas = __esm({
|
|
|
31933
32118
|
dragRef.current = null;
|
|
31934
32119
|
setDraggingId(null);
|
|
31935
32120
|
if (!wasDrag) {
|
|
31936
|
-
const
|
|
32121
|
+
const itemId = item.id;
|
|
32122
|
+
const next = selectedId === itemId ? null : itemId;
|
|
31937
32123
|
onSelect?.(next);
|
|
31938
32124
|
if (selectEvent) {
|
|
31939
32125
|
eventBus.emit(`UI:${selectEvent}`, { id: next });
|
|
@@ -31968,15 +32154,22 @@ var init_PositionedCanvas = __esm({
|
|
|
31968
32154
|
style: { width, height },
|
|
31969
32155
|
onClick: handleContainerClick,
|
|
31970
32156
|
children: items.map((item) => {
|
|
32157
|
+
const itemId = item.id;
|
|
32158
|
+
const label = item.label;
|
|
32159
|
+
const x = item.x;
|
|
32160
|
+
const y = item.y;
|
|
32161
|
+
const capacity = item.capacity;
|
|
32162
|
+
const partySize = item.partySize;
|
|
32163
|
+
const serverName = item.serverName;
|
|
31971
32164
|
const status = item.status ?? "empty";
|
|
31972
32165
|
const shape = item.shape ?? "round";
|
|
31973
|
-
const isSelected = selectedId ===
|
|
31974
|
-
const isDragging = draggingId ===
|
|
32166
|
+
const isSelected = selectedId === itemId;
|
|
32167
|
+
const isDragging = draggingId === itemId;
|
|
31975
32168
|
const statusBadge = STATUS_BADGE[status];
|
|
31976
32169
|
return /* @__PURE__ */ jsxs(
|
|
31977
32170
|
Box,
|
|
31978
32171
|
{
|
|
31979
|
-
"data-testid": `item-node-${
|
|
32172
|
+
"data-testid": `item-node-${itemId}`,
|
|
31980
32173
|
"data-status": status,
|
|
31981
32174
|
className: cn(
|
|
31982
32175
|
"absolute flex flex-col items-center justify-center gap-1 border-2 select-none",
|
|
@@ -31987,7 +32180,7 @@ var init_PositionedCanvas = __esm({
|
|
|
31987
32180
|
isSelected && "outline outline-2 outline-offset-2 outline-primary shadow-md",
|
|
31988
32181
|
isDragging && "shadow-lg z-10"
|
|
31989
32182
|
),
|
|
31990
|
-
style: { left:
|
|
32183
|
+
style: { left: x, top: y, touchAction: "none" },
|
|
31991
32184
|
onPointerDown: (e) => handlePointerDown(e, item),
|
|
31992
32185
|
onPointerMove: handlePointerMove,
|
|
31993
32186
|
onPointerUp: (e) => handlePointerUp(e, item),
|
|
@@ -31995,10 +32188,10 @@ var init_PositionedCanvas = __esm({
|
|
|
31995
32188
|
children: [
|
|
31996
32189
|
/* @__PURE__ */ jsxs(Box, { className: "flex items-center gap-1", children: [
|
|
31997
32190
|
getStatusIcon(status),
|
|
31998
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body2", weight: "semibold", children:
|
|
32191
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", weight: "semibold", children: label })
|
|
31999
32192
|
] }),
|
|
32000
|
-
/* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children:
|
|
32001
|
-
status === "seated" &&
|
|
32193
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: partySize !== void 0 && status === "seated" ? `${partySize}/${capacity}` : `Cap ${capacity}` }),
|
|
32194
|
+
status === "seated" && serverName && /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", className: "truncate max-w-[80%]", children: serverName }),
|
|
32002
32195
|
isSelected && /* @__PURE__ */ jsx(
|
|
32003
32196
|
Badge,
|
|
32004
32197
|
{
|
|
@@ -32010,7 +32203,7 @@ var init_PositionedCanvas = __esm({
|
|
|
32010
32203
|
)
|
|
32011
32204
|
]
|
|
32012
32205
|
},
|
|
32013
|
-
|
|
32206
|
+
itemId
|
|
32014
32207
|
);
|
|
32015
32208
|
})
|
|
32016
32209
|
}
|
|
@@ -32782,9 +32975,10 @@ var init_RichBlockEditor = __esm({
|
|
|
32782
32975
|
});
|
|
32783
32976
|
function collectInitiallyCollapsed(nodes, acc) {
|
|
32784
32977
|
for (const n of nodes) {
|
|
32978
|
+
const replies = n.replies;
|
|
32785
32979
|
if (n.collapsed) acc.add(n.id);
|
|
32786
|
-
if (
|
|
32787
|
-
collectInitiallyCollapsed(
|
|
32980
|
+
if (replies && replies.length > 0) {
|
|
32981
|
+
collectInitiallyCollapsed(replies, acc);
|
|
32788
32982
|
}
|
|
32789
32983
|
}
|
|
32790
32984
|
}
|
|
@@ -32814,44 +33008,52 @@ var init_ReplyTree = __esm({
|
|
|
32814
33008
|
}) => {
|
|
32815
33009
|
const eventBus = useEventBus();
|
|
32816
33010
|
const { t } = useTranslate();
|
|
32817
|
-
const
|
|
32818
|
-
const
|
|
33011
|
+
const nodeId = node.id;
|
|
33012
|
+
const authorName = node.authorName;
|
|
33013
|
+
const authorAvatarUrl = node.authorAvatarUrl;
|
|
33014
|
+
const content = node.content;
|
|
33015
|
+
const postedAt = node.postedAt;
|
|
33016
|
+
const voteCount = node.voteCount;
|
|
33017
|
+
const userVote = node.userVote;
|
|
33018
|
+
const replies = node.replies;
|
|
33019
|
+
const hasReplies = !!replies && replies.length > 0;
|
|
33020
|
+
const isCollapsed = collapsedSet.has(nodeId);
|
|
32819
33021
|
const atMaxDepth = depth >= maxDepth;
|
|
32820
33022
|
const [replyOpen, setReplyOpen] = useState(false);
|
|
32821
33023
|
const [draft, setDraft] = useState("");
|
|
32822
33024
|
const handleVote = useCallback(
|
|
32823
33025
|
(next) => {
|
|
32824
|
-
onVote?.(
|
|
32825
|
-
if (voteEvent) eventBus.emit(`UI:${voteEvent}`, { nodeId
|
|
33026
|
+
onVote?.(nodeId, next);
|
|
33027
|
+
if (voteEvent) eventBus.emit(`UI:${voteEvent}`, { nodeId, vote: next });
|
|
32826
33028
|
},
|
|
32827
|
-
[
|
|
33029
|
+
[nodeId, onVote, voteEvent, eventBus]
|
|
32828
33030
|
);
|
|
32829
33031
|
const handleReply = useCallback(() => {
|
|
32830
|
-
onReply?.(
|
|
33032
|
+
onReply?.(nodeId);
|
|
32831
33033
|
setReplyOpen((open) => !open);
|
|
32832
|
-
}, [
|
|
33034
|
+
}, [nodeId, onReply]);
|
|
32833
33035
|
const handleSubmitReply = useCallback(() => {
|
|
32834
|
-
const
|
|
32835
|
-
if (!
|
|
32836
|
-
if (replyEvent) eventBus.emit(`UI:${replyEvent}`, { parentNodeId:
|
|
33036
|
+
const text = draft.trim();
|
|
33037
|
+
if (!text) return;
|
|
33038
|
+
if (replyEvent) eventBus.emit(`UI:${replyEvent}`, { parentNodeId: nodeId, content: text });
|
|
32837
33039
|
setDraft("");
|
|
32838
33040
|
setReplyOpen(false);
|
|
32839
|
-
}, [
|
|
33041
|
+
}, [nodeId, draft, replyEvent, eventBus]);
|
|
32840
33042
|
const handleCancelReply = useCallback(() => {
|
|
32841
33043
|
setDraft("");
|
|
32842
33044
|
setReplyOpen(false);
|
|
32843
33045
|
}, []);
|
|
32844
33046
|
const handleFlag = useCallback(() => {
|
|
32845
|
-
onFlag?.(
|
|
32846
|
-
if (flagEvent) eventBus.emit(`UI:${flagEvent}`, { nodeId
|
|
32847
|
-
}, [
|
|
33047
|
+
onFlag?.(nodeId);
|
|
33048
|
+
if (flagEvent) eventBus.emit(`UI:${flagEvent}`, { nodeId });
|
|
33049
|
+
}, [nodeId, onFlag, flagEvent, eventBus]);
|
|
32848
33050
|
const handleContinue = useCallback(() => {
|
|
32849
|
-
onContinueThread?.(
|
|
32850
|
-
if (continueThreadEvent) eventBus.emit(`UI:${continueThreadEvent}`, { nodeId
|
|
32851
|
-
}, [
|
|
33051
|
+
onContinueThread?.(nodeId);
|
|
33052
|
+
if (continueThreadEvent) eventBus.emit(`UI:${continueThreadEvent}`, { nodeId });
|
|
33053
|
+
}, [nodeId, onContinueThread, continueThreadEvent, eventBus]);
|
|
32852
33054
|
const handleToggle = useCallback(() => {
|
|
32853
|
-
toggleCollapse(
|
|
32854
|
-
}, [
|
|
33055
|
+
toggleCollapse(nodeId);
|
|
33056
|
+
}, [nodeId, toggleCollapse]);
|
|
32855
33057
|
return /* @__PURE__ */ jsxs(Box, { className: "flex flex-row gap-2 items-stretch min-w-0", children: [
|
|
32856
33058
|
/* @__PURE__ */ jsxs(Box, { className: "flex flex-col items-center flex-shrink-0 w-6", children: [
|
|
32857
33059
|
hasReplies ? /* @__PURE__ */ jsx(
|
|
@@ -32883,25 +33085,25 @@ var init_ReplyTree = __esm({
|
|
|
32883
33085
|
/* @__PURE__ */ jsx(
|
|
32884
33086
|
Avatar,
|
|
32885
33087
|
{
|
|
32886
|
-
src:
|
|
32887
|
-
name:
|
|
33088
|
+
src: authorAvatarUrl,
|
|
33089
|
+
name: authorName,
|
|
32888
33090
|
size: "sm"
|
|
32889
33091
|
}
|
|
32890
33092
|
),
|
|
32891
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "semibold", children:
|
|
32892
|
-
/* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children:
|
|
33093
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "semibold", children: authorName }),
|
|
33094
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: postedAt })
|
|
32893
33095
|
] }),
|
|
32894
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body", className: "whitespace-pre-wrap break-words", children:
|
|
33096
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", className: "whitespace-pre-wrap break-words", children: content }),
|
|
32895
33097
|
showActions && /* @__PURE__ */ jsxs(Box, { className: "flex flex-row gap-2 items-center", children: [
|
|
32896
33098
|
/* @__PURE__ */ jsx(
|
|
32897
33099
|
VoteStack,
|
|
32898
33100
|
{
|
|
32899
|
-
count:
|
|
32900
|
-
userVote:
|
|
33101
|
+
count: voteCount ?? 0,
|
|
33102
|
+
userVote: userVote ?? null,
|
|
32901
33103
|
onVote: handleVote,
|
|
32902
33104
|
size: "sm",
|
|
32903
33105
|
variant: "horizontal",
|
|
32904
|
-
label: t("replyTree.voteOnReplyBy", { author:
|
|
33106
|
+
label: t("replyTree.voteOnReplyBy", { author: authorName })
|
|
32905
33107
|
}
|
|
32906
33108
|
),
|
|
32907
33109
|
/* @__PURE__ */ jsx(
|
|
@@ -32911,7 +33113,7 @@ var init_ReplyTree = __esm({
|
|
|
32911
33113
|
size: "sm",
|
|
32912
33114
|
leftIcon: "message-square",
|
|
32913
33115
|
onClick: handleReply,
|
|
32914
|
-
"aria-label": t("replyTree.replyTo", { author:
|
|
33116
|
+
"aria-label": t("replyTree.replyTo", { author: authorName }),
|
|
32915
33117
|
children: t("replyTree.reply")
|
|
32916
33118
|
}
|
|
32917
33119
|
),
|
|
@@ -32922,7 +33124,7 @@ var init_ReplyTree = __esm({
|
|
|
32922
33124
|
size: "sm",
|
|
32923
33125
|
leftIcon: "flag",
|
|
32924
33126
|
onClick: handleFlag,
|
|
32925
|
-
"aria-label": t("replyTree.flagReplyBy", { author:
|
|
33127
|
+
"aria-label": t("replyTree.flagReplyBy", { author: authorName }),
|
|
32926
33128
|
children: t("replyTree.flag")
|
|
32927
33129
|
}
|
|
32928
33130
|
)
|
|
@@ -32934,9 +33136,9 @@ var init_ReplyTree = __esm({
|
|
|
32934
33136
|
inputType: "textarea",
|
|
32935
33137
|
rows: 2,
|
|
32936
33138
|
value: draft,
|
|
32937
|
-
placeholder: t("replyTree.replyToPlaceholder", { author:
|
|
33139
|
+
placeholder: t("replyTree.replyToPlaceholder", { author: authorName }),
|
|
32938
33140
|
onChange: (e) => setDraft(e.target.value),
|
|
32939
|
-
"aria-label": t("replyTree.replyTo", { author:
|
|
33141
|
+
"aria-label": t("replyTree.replyTo", { author: authorName })
|
|
32940
33142
|
}
|
|
32941
33143
|
),
|
|
32942
33144
|
/* @__PURE__ */ jsxs(Box, { className: "flex flex-row gap-2 items-center", children: [
|
|
@@ -32967,7 +33169,7 @@ var init_ReplyTree = __esm({
|
|
|
32967
33169
|
),
|
|
32968
33170
|
children: t("replyTree.continueThread")
|
|
32969
33171
|
}
|
|
32970
|
-
) : /* @__PURE__ */ jsx(Box, { className: "flex flex-col gap-2 mt-1", children:
|
|
33172
|
+
) : /* @__PURE__ */ jsx(Box, { className: "flex flex-col gap-2 mt-1", children: replies.map((child) => /* @__PURE__ */ jsx(
|
|
32971
33173
|
ReplyTreeNode,
|
|
32972
33174
|
{
|
|
32973
33175
|
node: child,
|
|
@@ -33429,7 +33631,7 @@ var init_DocBreadcrumb = __esm({
|
|
|
33429
33631
|
"aria-label": t("aria.breadcrumb"),
|
|
33430
33632
|
children: /* @__PURE__ */ jsx(HStack, { gap: "xs", align: "center", wrap: true, children: items.map((item, idx) => {
|
|
33431
33633
|
const isLast = idx === items.length - 1;
|
|
33432
|
-
return /* @__PURE__ */ jsxs(
|
|
33634
|
+
return /* @__PURE__ */ jsxs(React80__default.Fragment, { children: [
|
|
33433
33635
|
idx > 0 && /* @__PURE__ */ jsx(
|
|
33434
33636
|
Icon,
|
|
33435
33637
|
{
|
|
@@ -34393,7 +34595,7 @@ var init_MiniStateMachine = __esm({
|
|
|
34393
34595
|
const x = 2 + i * (NODE_W + GAP2 + ARROW_W + GAP2);
|
|
34394
34596
|
const tc = transitionCounts[s.name] ?? 0;
|
|
34395
34597
|
const role = getStateRole(s.name, s.isInitial, s.isTerminal, tc, maxTC);
|
|
34396
|
-
return /* @__PURE__ */ jsxs(
|
|
34598
|
+
return /* @__PURE__ */ jsxs(React80__default.Fragment, { children: [
|
|
34397
34599
|
/* @__PURE__ */ jsx(
|
|
34398
34600
|
AvlState,
|
|
34399
34601
|
{
|
|
@@ -34597,7 +34799,7 @@ var init_PageHeader = __esm({
|
|
|
34597
34799
|
info: "bg-info/10 text-info"
|
|
34598
34800
|
};
|
|
34599
34801
|
return /* @__PURE__ */ jsxs(Box, { className: cn("mb-6", className), children: [
|
|
34600
|
-
breadcrumbs && breadcrumbs.length > 0 && /* @__PURE__ */ jsx(Box, { as: "nav", className: "mb-4", children: /* @__PURE__ */ jsx(Box, { as: "ol", className: "flex items-center gap-2 text-sm", children: breadcrumbs.map((crumb, idx) => /* @__PURE__ */ jsxs(
|
|
34802
|
+
breadcrumbs && breadcrumbs.length > 0 && /* @__PURE__ */ jsx(Box, { as: "nav", className: "mb-4", children: /* @__PURE__ */ jsx(Box, { as: "ol", className: "flex items-center gap-2 text-sm", children: breadcrumbs.map((crumb, idx) => /* @__PURE__ */ jsxs(React80__default.Fragment, { children: [
|
|
34601
34803
|
idx > 0 && /* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", children: "/" }),
|
|
34602
34804
|
crumb.href ? /* @__PURE__ */ jsx(
|
|
34603
34805
|
"a",
|
|
@@ -34706,7 +34908,7 @@ var init_FormSection = __esm({
|
|
|
34706
34908
|
columns = 1,
|
|
34707
34909
|
className
|
|
34708
34910
|
}) => {
|
|
34709
|
-
const [collapsed, setCollapsed] =
|
|
34911
|
+
const [collapsed, setCollapsed] = React80__default.useState(defaultCollapsed);
|
|
34710
34912
|
const { t } = useTranslate();
|
|
34711
34913
|
const eventBus = useEventBus();
|
|
34712
34914
|
const gridClass = {
|
|
@@ -34714,7 +34916,7 @@ var init_FormSection = __esm({
|
|
|
34714
34916
|
2: "grid-cols-1 md:grid-cols-2",
|
|
34715
34917
|
3: "grid-cols-1 md:grid-cols-2 lg:grid-cols-3"
|
|
34716
34918
|
}[columns];
|
|
34717
|
-
|
|
34919
|
+
React80__default.useCallback(() => {
|
|
34718
34920
|
if (collapsible) {
|
|
34719
34921
|
setCollapsed((prev) => !prev);
|
|
34720
34922
|
eventBus.emit("UI:TOGGLE_COLLAPSE", { collapsed: !collapsed });
|
|
@@ -35414,8 +35616,8 @@ var init_WizardContainer = __esm({
|
|
|
35414
35616
|
return void 0;
|
|
35415
35617
|
if (typeof controlledStep === "number") return controlledStep;
|
|
35416
35618
|
if (typeof controlledStep === "string") return parseInt(controlledStep, 10);
|
|
35417
|
-
const
|
|
35418
|
-
return isNaN(
|
|
35619
|
+
const num2 = Number(controlledStep);
|
|
35620
|
+
return isNaN(num2) ? void 0 : num2;
|
|
35419
35621
|
})();
|
|
35420
35622
|
const currentStep = normalizedControlledStep !== void 0 ? normalizedControlledStep : internalStep;
|
|
35421
35623
|
const totalSteps = steps.length;
|
|
@@ -35461,7 +35663,7 @@ var init_WizardContainer = __esm({
|
|
|
35461
35663
|
const isCompleted = index < currentStep;
|
|
35462
35664
|
const stepKey = step.id ?? step.tabId ?? `step-${index}`;
|
|
35463
35665
|
const stepTitle = step.title ?? step.name ?? `Step ${index + 1}`;
|
|
35464
|
-
return /* @__PURE__ */ jsxs(
|
|
35666
|
+
return /* @__PURE__ */ jsxs(React80__default.Fragment, { children: [
|
|
35465
35667
|
/* @__PURE__ */ jsx(
|
|
35466
35668
|
Button,
|
|
35467
35669
|
{
|
|
@@ -37240,7 +37442,7 @@ function DebuggerBoard({
|
|
|
37240
37442
|
}) {
|
|
37241
37443
|
const { emit } = useEventBus();
|
|
37242
37444
|
const { t } = useTranslate();
|
|
37243
|
-
const resolved =
|
|
37445
|
+
const resolved = boardEntity(entity);
|
|
37244
37446
|
const [flaggedLines, setFlaggedLines] = useState(/* @__PURE__ */ new Set());
|
|
37245
37447
|
const [headerError, setHeaderError] = useState(false);
|
|
37246
37448
|
const [submitted, setSubmitted] = useState(false);
|
|
@@ -37258,7 +37460,7 @@ function DebuggerBoard({
|
|
|
37258
37460
|
return next;
|
|
37259
37461
|
});
|
|
37260
37462
|
};
|
|
37261
|
-
const lines = resolved?.lines
|
|
37463
|
+
const lines = Array.isArray(resolved?.lines) ? resolved.lines : [];
|
|
37262
37464
|
const bugLines = lines.filter((l) => l.isBug);
|
|
37263
37465
|
const correctFlags = lines.filter((l) => l.isBug && flaggedLines.has(l.id));
|
|
37264
37466
|
const falseFlags = lines.filter((l) => !l.isBug && flaggedLines.has(l.id));
|
|
@@ -37273,7 +37475,7 @@ function DebuggerBoard({
|
|
|
37273
37475
|
}, [correctFlags.length, bugLines.length, falseFlags.length, attempts, completeEvent, emit]);
|
|
37274
37476
|
const handleReset = () => {
|
|
37275
37477
|
setSubmitted(false);
|
|
37276
|
-
if (attempts >= 2 && resolved?.hint) {
|
|
37478
|
+
if (attempts >= 2 && str(resolved?.hint)) {
|
|
37277
37479
|
setShowHint(true);
|
|
37278
37480
|
}
|
|
37279
37481
|
};
|
|
@@ -37284,24 +37486,28 @@ function DebuggerBoard({
|
|
|
37284
37486
|
setShowHint(false);
|
|
37285
37487
|
};
|
|
37286
37488
|
if (!resolved) return null;
|
|
37489
|
+
const theme = resolved.theme ?? void 0;
|
|
37490
|
+
const themeBackground = theme?.background;
|
|
37491
|
+
const headerImage = str(resolved.headerImage);
|
|
37492
|
+
const hint = str(resolved.hint);
|
|
37287
37493
|
return /* @__PURE__ */ jsx(
|
|
37288
37494
|
Box,
|
|
37289
37495
|
{
|
|
37290
37496
|
className,
|
|
37291
37497
|
style: {
|
|
37292
|
-
backgroundImage:
|
|
37498
|
+
backgroundImage: themeBackground ? `url(${themeBackground})` : void 0,
|
|
37293
37499
|
backgroundSize: "cover",
|
|
37294
37500
|
backgroundPosition: "center"
|
|
37295
37501
|
},
|
|
37296
37502
|
children: /* @__PURE__ */ jsxs(VStack, { gap: "lg", className: "p-4", children: [
|
|
37297
|
-
|
|
37503
|
+
headerImage && !headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsx("img", { src: headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : headerImage && headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
37298
37504
|
/* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
37299
37505
|
/* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
37300
37506
|
/* @__PURE__ */ jsx(Icon, { icon: Bug, size: "sm" }),
|
|
37301
|
-
/* @__PURE__ */ jsx(Typography, { variant: "h4", weight: "bold", children: resolved.title })
|
|
37507
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h4", weight: "bold", children: str(resolved.title) })
|
|
37302
37508
|
] }),
|
|
37303
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body", children: resolved.description }),
|
|
37304
|
-
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: t("debugger.findBugs", { count: String(resolved.bugCount) }) })
|
|
37509
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", children: str(resolved.description) }),
|
|
37510
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: t("debugger.findBugs", { count: String(num(resolved.bugCount)) }) })
|
|
37305
37511
|
] }) }),
|
|
37306
37512
|
/* @__PURE__ */ jsx(Card, { className: "p-0 overflow-hidden", children: /* @__PURE__ */ jsx(VStack, { gap: "none", children: lines.map((line, i) => {
|
|
37307
37513
|
const isFlagged = flaggedLines.has(line.id);
|
|
@@ -37333,7 +37539,7 @@ function DebuggerBoard({
|
|
|
37333
37539
|
);
|
|
37334
37540
|
}) }) }),
|
|
37335
37541
|
submitted && /* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
37336
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "bold", children: allCorrect ? resolved.successMessage
|
|
37542
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "bold", children: allCorrect ? str(resolved.successMessage) || t("debugger.allFound") : `${correctFlags.length}/${bugLines.length} ${t("debugger.bugsFound")}` }),
|
|
37337
37543
|
bugLines.map((line) => /* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "start", children: [
|
|
37338
37544
|
/* @__PURE__ */ jsx(
|
|
37339
37545
|
Icon,
|
|
@@ -37349,7 +37555,7 @@ function DebuggerBoard({
|
|
|
37349
37555
|
] })
|
|
37350
37556
|
] }, line.id))
|
|
37351
37557
|
] }) }),
|
|
37352
|
-
showHint &&
|
|
37558
|
+
showHint && hint && /* @__PURE__ */ jsx(Card, { className: "p-4 border-l-4 border-l-warning", children: /* @__PURE__ */ jsx(Typography, { variant: "body", children: hint }) }),
|
|
37353
37559
|
/* @__PURE__ */ jsxs(HStack, { gap: "sm", justify: "center", children: [
|
|
37354
37560
|
!submitted ? /* @__PURE__ */ jsxs(Button, { variant: "primary", onClick: handleSubmit, disabled: flaggedLines.size === 0, children: [
|
|
37355
37561
|
/* @__PURE__ */ jsx(Icon, { icon: Send, size: "sm" }),
|
|
@@ -37368,6 +37574,7 @@ var init_DebuggerBoard = __esm({
|
|
|
37368
37574
|
"components/game/organisms/puzzles/debugger/DebuggerBoard.tsx"() {
|
|
37369
37575
|
init_atoms2();
|
|
37370
37576
|
init_useEventBus();
|
|
37577
|
+
init_boardEntity();
|
|
37371
37578
|
DebuggerBoard.displayName = "DebuggerBoard";
|
|
37372
37579
|
}
|
|
37373
37580
|
});
|
|
@@ -37405,7 +37612,7 @@ function getBadgeVariant(fieldName, value) {
|
|
|
37405
37612
|
return "default";
|
|
37406
37613
|
}
|
|
37407
37614
|
function formatFieldLabel(fieldName) {
|
|
37408
|
-
return fieldName.replace(/([A-Z])/g, " $1").replace(/^./, (
|
|
37615
|
+
return fieldName.replace(/([A-Z])/g, " $1").replace(/^./, (str2) => str2.toUpperCase());
|
|
37409
37616
|
}
|
|
37410
37617
|
function formatFieldValue(value, fieldName) {
|
|
37411
37618
|
if (typeof value === "number") {
|
|
@@ -37424,26 +37631,26 @@ function formatFieldValue(value, fieldName) {
|
|
|
37424
37631
|
}
|
|
37425
37632
|
function renderRichFieldValue(value, fieldName, fieldType) {
|
|
37426
37633
|
if (value === void 0 || value === null) return "\u2014";
|
|
37427
|
-
const
|
|
37634
|
+
const str2 = String(value);
|
|
37428
37635
|
switch (fieldType) {
|
|
37429
37636
|
case "image":
|
|
37430
37637
|
case "url": {
|
|
37431
|
-
if (
|
|
37638
|
+
if (str2.match(/\.(png|jpe?g|gif|svg|webp|avif)(\?|$)/i) || str2.startsWith("data:image/")) {
|
|
37432
37639
|
return /* @__PURE__ */ jsx(Box, { className: "mt-1 max-w-full", children: /* @__PURE__ */ jsx(
|
|
37433
37640
|
"img",
|
|
37434
37641
|
{
|
|
37435
|
-
src:
|
|
37642
|
+
src: str2,
|
|
37436
37643
|
alt: formatFieldLabel(fieldName),
|
|
37437
37644
|
className: "max-w-full max-h-64 rounded-md object-contain",
|
|
37438
37645
|
loading: "lazy"
|
|
37439
37646
|
}
|
|
37440
37647
|
) });
|
|
37441
37648
|
}
|
|
37442
|
-
return
|
|
37649
|
+
return str2;
|
|
37443
37650
|
}
|
|
37444
37651
|
case "markdown":
|
|
37445
37652
|
case "richtext":
|
|
37446
|
-
return /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(Typography, { variant: "body", className: "break-words", children:
|
|
37653
|
+
return /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(Typography, { variant: "body", className: "break-words", children: str2 }), children: /* @__PURE__ */ jsx(
|
|
37447
37654
|
Box,
|
|
37448
37655
|
{
|
|
37449
37656
|
className: "prose prose-sm max-w-none",
|
|
@@ -37461,11 +37668,11 @@ function renderRichFieldValue(value, fieldName, fieldType) {
|
|
|
37461
37668
|
"--tw-prose-th-borders": "var(--color-border)",
|
|
37462
37669
|
"--tw-prose-td-borders": "var(--color-border)"
|
|
37463
37670
|
},
|
|
37464
|
-
children: /* @__PURE__ */ jsx(ReactMarkdown2, { children:
|
|
37671
|
+
children: /* @__PURE__ */ jsx(ReactMarkdown2, { children: str2 })
|
|
37465
37672
|
}
|
|
37466
37673
|
) });
|
|
37467
37674
|
case "code":
|
|
37468
|
-
return /* @__PURE__ */ jsx(Box, { className: "mt-1 rounded-md bg-muted p-3 overflow-x-auto", children: /* @__PURE__ */ jsx("pre", { className: "text-sm font-mono whitespace-pre-wrap break-words m-0", children: /* @__PURE__ */ jsx("code", { children:
|
|
37675
|
+
return /* @__PURE__ */ jsx(Box, { className: "mt-1 rounded-md bg-muted p-3 overflow-x-auto", children: /* @__PURE__ */ jsx("pre", { className: "text-sm font-mono whitespace-pre-wrap break-words m-0", children: /* @__PURE__ */ jsx("code", { children: str2 }) }) });
|
|
37469
37676
|
case "html":
|
|
37470
37677
|
return /* @__PURE__ */ jsx(
|
|
37471
37678
|
Box,
|
|
@@ -37485,12 +37692,12 @@ function renderRichFieldValue(value, fieldName, fieldType) {
|
|
|
37485
37692
|
"--tw-prose-th-borders": "var(--color-border)",
|
|
37486
37693
|
"--tw-prose-td-borders": "var(--color-border)"
|
|
37487
37694
|
},
|
|
37488
|
-
children: /* @__PURE__ */ jsx(Typography, { variant: "body", children:
|
|
37695
|
+
children: /* @__PURE__ */ jsx(Typography, { variant: "body", children: str2 })
|
|
37489
37696
|
}
|
|
37490
37697
|
);
|
|
37491
37698
|
case "date":
|
|
37492
37699
|
case "datetime": {
|
|
37493
|
-
const d = new Date(
|
|
37700
|
+
const d = new Date(str2);
|
|
37494
37701
|
if (!isNaN(d.getTime())) {
|
|
37495
37702
|
return d.toLocaleDateString(void 0, {
|
|
37496
37703
|
year: "numeric",
|
|
@@ -37499,7 +37706,7 @@ function renderRichFieldValue(value, fieldName, fieldType) {
|
|
|
37499
37706
|
...fieldType === "datetime" ? { hour: "2-digit", minute: "2-digit" } : {}
|
|
37500
37707
|
});
|
|
37501
37708
|
}
|
|
37502
|
-
return
|
|
37709
|
+
return str2;
|
|
37503
37710
|
}
|
|
37504
37711
|
default:
|
|
37505
37712
|
return formatFieldValue(value, fieldName);
|
|
@@ -37899,7 +38106,7 @@ var init_DialogueBubble = __esm({
|
|
|
37899
38106
|
}
|
|
37900
38107
|
});
|
|
37901
38108
|
function extractTitle(children) {
|
|
37902
|
-
if (!
|
|
38109
|
+
if (!React80__default.isValidElement(children)) return void 0;
|
|
37903
38110
|
const props = children.props;
|
|
37904
38111
|
if (typeof props.title === "string") {
|
|
37905
38112
|
return props.title;
|
|
@@ -38011,7 +38218,7 @@ function LinearView({
|
|
|
38011
38218
|
/* @__PURE__ */ jsx(HStack, { className: "flex-wrap items-center", gap: "xs", children: trait.states.map((state, i) => {
|
|
38012
38219
|
const isDone = i < currentIdx;
|
|
38013
38220
|
const isCurrent = i === currentIdx;
|
|
38014
|
-
return /* @__PURE__ */ jsxs(
|
|
38221
|
+
return /* @__PURE__ */ jsxs(React80__default.Fragment, { children: [
|
|
38015
38222
|
i > 0 && /* @__PURE__ */ jsx(
|
|
38016
38223
|
Typography,
|
|
38017
38224
|
{
|
|
@@ -38272,6 +38479,40 @@ var init_RuleEditor = __esm({
|
|
|
38272
38479
|
RuleEditor.displayName = "RuleEditor";
|
|
38273
38480
|
}
|
|
38274
38481
|
});
|
|
38482
|
+
|
|
38483
|
+
// components/game/organisms/puzzles/event-handler/puzzleObject.ts
|
|
38484
|
+
function objId(o) {
|
|
38485
|
+
return o.id == null ? "" : String(o.id);
|
|
38486
|
+
}
|
|
38487
|
+
function objName(o) {
|
|
38488
|
+
return o.name == null ? "" : String(o.name);
|
|
38489
|
+
}
|
|
38490
|
+
function objIcon(o) {
|
|
38491
|
+
return o.icon == null ? "" : String(o.icon);
|
|
38492
|
+
}
|
|
38493
|
+
function objStates(o) {
|
|
38494
|
+
return Array.isArray(o.states) ? o.states : [];
|
|
38495
|
+
}
|
|
38496
|
+
function objCurrentState(o) {
|
|
38497
|
+
return o.currentState == null ? "" : String(o.currentState);
|
|
38498
|
+
}
|
|
38499
|
+
function objAvailableEvents(o) {
|
|
38500
|
+
return Array.isArray(o.availableEvents) ? o.availableEvents : [];
|
|
38501
|
+
}
|
|
38502
|
+
function objAvailableActions(o) {
|
|
38503
|
+
return Array.isArray(o.availableActions) ? o.availableActions : [];
|
|
38504
|
+
}
|
|
38505
|
+
function objRules(o) {
|
|
38506
|
+
return Array.isArray(o.rules) ? o.rules : [];
|
|
38507
|
+
}
|
|
38508
|
+
function objMaxRules(o) {
|
|
38509
|
+
const n = Number(o.maxRules);
|
|
38510
|
+
return Number.isFinite(n) && n > 0 ? n : 3;
|
|
38511
|
+
}
|
|
38512
|
+
var init_puzzleObject = __esm({
|
|
38513
|
+
"components/game/organisms/puzzles/event-handler/puzzleObject.ts"() {
|
|
38514
|
+
}
|
|
38515
|
+
});
|
|
38275
38516
|
function ObjectRulePanel({
|
|
38276
38517
|
object,
|
|
38277
38518
|
onRulesChange,
|
|
@@ -38279,55 +38520,63 @@ function ObjectRulePanel({
|
|
|
38279
38520
|
className
|
|
38280
38521
|
}) {
|
|
38281
38522
|
const { t } = useTranslate();
|
|
38282
|
-
const
|
|
38283
|
-
const
|
|
38523
|
+
const id = objId(object);
|
|
38524
|
+
const name = objName(object);
|
|
38525
|
+
const icon = objIcon(object);
|
|
38526
|
+
const states = objStates(object);
|
|
38527
|
+
const currentState = objCurrentState(object);
|
|
38528
|
+
const availableEvents = objAvailableEvents(object);
|
|
38529
|
+
const availableActions = objAvailableActions(object);
|
|
38530
|
+
const rules = objRules(object);
|
|
38531
|
+
const maxRules = objMaxRules(object);
|
|
38532
|
+
const canAdd = rules.length < maxRules;
|
|
38284
38533
|
const handleRuleChange = useCallback((index, updatedRule) => {
|
|
38285
|
-
const newRules = [...
|
|
38534
|
+
const newRules = [...rules];
|
|
38286
38535
|
newRules[index] = updatedRule;
|
|
38287
|
-
onRulesChange(
|
|
38288
|
-
}, [
|
|
38536
|
+
onRulesChange(id, newRules);
|
|
38537
|
+
}, [id, rules, onRulesChange]);
|
|
38289
38538
|
const handleRuleRemove = useCallback((index) => {
|
|
38290
|
-
const newRules =
|
|
38291
|
-
onRulesChange(
|
|
38292
|
-
}, [
|
|
38539
|
+
const newRules = rules.filter((_, i) => i !== index);
|
|
38540
|
+
onRulesChange(id, newRules);
|
|
38541
|
+
}, [id, rules, onRulesChange]);
|
|
38293
38542
|
const handleAddRule = useCallback(() => {
|
|
38294
38543
|
if (!canAdd || disabled) return;
|
|
38295
|
-
const firstEvent =
|
|
38296
|
-
const firstAction =
|
|
38544
|
+
const firstEvent = availableEvents[0]?.value || "";
|
|
38545
|
+
const firstAction = availableActions[0]?.value || "";
|
|
38297
38546
|
const newRule = {
|
|
38298
38547
|
id: `rule-${nextRuleId++}`,
|
|
38299
38548
|
whenEvent: firstEvent,
|
|
38300
38549
|
thenAction: firstAction
|
|
38301
38550
|
};
|
|
38302
|
-
onRulesChange(
|
|
38303
|
-
}, [canAdd, disabled,
|
|
38551
|
+
onRulesChange(id, [...rules, newRule]);
|
|
38552
|
+
}, [canAdd, disabled, id, rules, availableEvents, availableActions, onRulesChange]);
|
|
38304
38553
|
const machine = {
|
|
38305
|
-
name
|
|
38306
|
-
states
|
|
38307
|
-
currentState
|
|
38308
|
-
transitions:
|
|
38309
|
-
from:
|
|
38310
|
-
to:
|
|
38554
|
+
name,
|
|
38555
|
+
states,
|
|
38556
|
+
currentState,
|
|
38557
|
+
transitions: rules.map((r) => ({
|
|
38558
|
+
from: currentState,
|
|
38559
|
+
to: states.find((s) => s !== currentState) || currentState,
|
|
38311
38560
|
event: r.whenEvent
|
|
38312
38561
|
}))
|
|
38313
38562
|
};
|
|
38314
38563
|
return /* @__PURE__ */ jsxs(VStack, { className: cn("p-4 rounded-lg bg-card border border-border", className), gap: "sm", children: [
|
|
38315
38564
|
/* @__PURE__ */ jsxs(HStack, { className: "items-center", gap: "sm", children: [
|
|
38316
|
-
/* @__PURE__ */ jsx(Typography, { variant: "h5", children:
|
|
38565
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h5", children: icon }),
|
|
38317
38566
|
/* @__PURE__ */ jsxs(VStack, { gap: "none", children: [
|
|
38318
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body1", className: "text-foreground font-bold", children:
|
|
38319
|
-
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: t("eventHandler.state") + ": " +
|
|
38567
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body1", className: "text-foreground font-bold", children: name }),
|
|
38568
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: t("eventHandler.state") + ": " + currentState })
|
|
38320
38569
|
] })
|
|
38321
38570
|
] }),
|
|
38322
38571
|
/* @__PURE__ */ jsx(TraitStateViewer, { trait: machine, variant: "compact", size: "sm" }),
|
|
38323
38572
|
/* @__PURE__ */ jsxs(VStack, { gap: "xs", children: [
|
|
38324
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-muted-foreground font-medium", children: t("eventHandler.rules", { count:
|
|
38325
|
-
|
|
38573
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-muted-foreground font-medium", children: t("eventHandler.rules", { count: rules.length, max: maxRules }) + ":" }),
|
|
38574
|
+
rules.map((rule, i) => /* @__PURE__ */ jsx(
|
|
38326
38575
|
RuleEditor,
|
|
38327
38576
|
{
|
|
38328
38577
|
rule,
|
|
38329
|
-
availableEvents
|
|
38330
|
-
availableActions
|
|
38578
|
+
availableEvents,
|
|
38579
|
+
availableActions,
|
|
38331
38580
|
onChange: (r) => handleRuleChange(i, r),
|
|
38332
38581
|
onRemove: () => handleRuleRemove(i),
|
|
38333
38582
|
disabled
|
|
@@ -38345,6 +38594,7 @@ var init_ObjectRulePanel = __esm({
|
|
|
38345
38594
|
init_cn();
|
|
38346
38595
|
init_TraitStateViewer();
|
|
38347
38596
|
init_RuleEditor();
|
|
38597
|
+
init_puzzleObject();
|
|
38348
38598
|
nextRuleId = 1;
|
|
38349
38599
|
ObjectRulePanel.displayName = "ObjectRulePanel";
|
|
38350
38600
|
}
|
|
@@ -38411,11 +38661,11 @@ function EventHandlerBoard({
|
|
|
38411
38661
|
}) {
|
|
38412
38662
|
const { emit } = useEventBus();
|
|
38413
38663
|
const { t } = useTranslate();
|
|
38414
|
-
const resolved =
|
|
38415
|
-
const entityObjects = resolved?.objects
|
|
38416
|
-
const [objects, setObjects] = useState(entityObjects);
|
|
38664
|
+
const resolved = boardEntity(entity);
|
|
38665
|
+
const entityObjects = rows(resolved?.objects);
|
|
38666
|
+
const [objects, setObjects] = useState(() => [...entityObjects]);
|
|
38417
38667
|
const [selectedObjectId, setSelectedObjectId] = useState(
|
|
38418
|
-
entityObjects[0]
|
|
38668
|
+
entityObjects[0] ? objId(entityObjects[0]) : null
|
|
38419
38669
|
);
|
|
38420
38670
|
const [headerError, setHeaderError] = useState(false);
|
|
38421
38671
|
const [playState, setPlayState] = useState("editing");
|
|
@@ -38426,10 +38676,10 @@ function EventHandlerBoard({
|
|
|
38426
38676
|
useEffect(() => () => {
|
|
38427
38677
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
38428
38678
|
}, []);
|
|
38429
|
-
const selectedObject = objects.find((o) => o
|
|
38679
|
+
const selectedObject = objects.find((o) => objId(o) === selectedObjectId) || null;
|
|
38430
38680
|
const handleRulesChange = useCallback((objectId, rules) => {
|
|
38431
38681
|
setObjects((prev) => prev.map(
|
|
38432
|
-
(o) => o
|
|
38682
|
+
(o) => objId(o) === objectId ? { ...o, rules } : o
|
|
38433
38683
|
));
|
|
38434
38684
|
}, []);
|
|
38435
38685
|
const addLogEntry = useCallback((icon, message, status = "done") => {
|
|
@@ -38443,11 +38693,12 @@ function EventHandlerBoard({
|
|
|
38443
38693
|
setEventLog([]);
|
|
38444
38694
|
const allRules = [];
|
|
38445
38695
|
objects.forEach((obj) => {
|
|
38446
|
-
obj.
|
|
38696
|
+
objRules(obj).forEach((rule) => {
|
|
38447
38697
|
allRules.push({ object: obj, rule });
|
|
38448
38698
|
});
|
|
38449
38699
|
});
|
|
38450
|
-
const triggers = resolved?.triggerEvents
|
|
38700
|
+
const triggers = Array.isArray(resolved?.triggerEvents) ? resolved.triggerEvents : [];
|
|
38701
|
+
const goalEvent = str(resolved?.goalEvent);
|
|
38451
38702
|
const eventQueue = [...triggers];
|
|
38452
38703
|
const firedEvents = /* @__PURE__ */ new Set();
|
|
38453
38704
|
let stepIdx = 0;
|
|
@@ -38476,14 +38727,14 @@ function EventHandlerBoard({
|
|
|
38476
38727
|
addLogEntry("\u26A1", t("eventHandler.noListeners", { event: currentEvent }), "done");
|
|
38477
38728
|
} else {
|
|
38478
38729
|
matching.forEach(({ object, rule }) => {
|
|
38479
|
-
addLogEntry(object
|
|
38730
|
+
addLogEntry(objIcon(object), t("eventHandler.heardEvent", { object: objName(object), event: currentEvent, action: rule.thenAction }), "done");
|
|
38480
38731
|
eventQueue.push(rule.thenAction);
|
|
38481
|
-
if (rule.thenAction ===
|
|
38732
|
+
if (rule.thenAction === goalEvent) {
|
|
38482
38733
|
goalReached = true;
|
|
38483
38734
|
}
|
|
38484
38735
|
});
|
|
38485
38736
|
}
|
|
38486
|
-
if (currentEvent ===
|
|
38737
|
+
if (currentEvent === goalEvent) {
|
|
38487
38738
|
goalReached = true;
|
|
38488
38739
|
}
|
|
38489
38740
|
stepIdx++;
|
|
@@ -38501,65 +38752,75 @@ function EventHandlerBoard({
|
|
|
38501
38752
|
}, []);
|
|
38502
38753
|
const handleReset = useCallback(() => {
|
|
38503
38754
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
38504
|
-
|
|
38755
|
+
const resetObjects = rows(resolved?.objects);
|
|
38756
|
+
setObjects([...resetObjects]);
|
|
38505
38757
|
setPlayState("editing");
|
|
38506
38758
|
setEventLog([]);
|
|
38507
|
-
setSelectedObjectId(
|
|
38759
|
+
setSelectedObjectId(resetObjects[0] ? objId(resetObjects[0]) : null);
|
|
38508
38760
|
setAttempts(0);
|
|
38509
38761
|
}, [resolved?.objects]);
|
|
38510
38762
|
if (!resolved) return null;
|
|
38511
38763
|
const objectViewers = objects.map((obj) => {
|
|
38764
|
+
const states = objStates(obj);
|
|
38765
|
+
const currentState = objCurrentState(obj);
|
|
38512
38766
|
const machine = {
|
|
38513
|
-
name: obj
|
|
38514
|
-
states
|
|
38515
|
-
currentState
|
|
38516
|
-
transitions: obj.
|
|
38517
|
-
from:
|
|
38518
|
-
to:
|
|
38767
|
+
name: objName(obj),
|
|
38768
|
+
states,
|
|
38769
|
+
currentState,
|
|
38770
|
+
transitions: objRules(obj).map((r) => ({
|
|
38771
|
+
from: currentState,
|
|
38772
|
+
to: states.find((s) => s !== currentState) || currentState,
|
|
38519
38773
|
event: r.whenEvent
|
|
38520
38774
|
}))
|
|
38521
38775
|
};
|
|
38522
38776
|
return { obj, machine };
|
|
38523
38777
|
});
|
|
38524
|
-
const
|
|
38778
|
+
const hint = str(resolved.hint);
|
|
38779
|
+
const showHint = attempts >= 3 && hint;
|
|
38780
|
+
const theme = resolved.theme ?? void 0;
|
|
38781
|
+
const themeBackground = theme?.background;
|
|
38782
|
+
const headerImage = str(resolved.headerImage);
|
|
38525
38783
|
const encourageKey = ENCOURAGEMENT_KEYS[Math.min(attempts - 1, ENCOURAGEMENT_KEYS.length - 1)] ?? ENCOURAGEMENT_KEYS[0];
|
|
38526
38784
|
return /* @__PURE__ */ jsxs(
|
|
38527
38785
|
VStack,
|
|
38528
38786
|
{
|
|
38529
38787
|
className: cn("p-4 gap-6", className),
|
|
38530
38788
|
style: {
|
|
38531
|
-
backgroundImage:
|
|
38789
|
+
backgroundImage: themeBackground ? `url(${themeBackground})` : void 0,
|
|
38532
38790
|
backgroundSize: "cover",
|
|
38533
38791
|
backgroundPosition: "center"
|
|
38534
38792
|
},
|
|
38535
38793
|
children: [
|
|
38536
|
-
|
|
38794
|
+
headerImage && !headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsx("img", { src: headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : headerImage && headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
38537
38795
|
/* @__PURE__ */ jsxs(VStack, { gap: "xs", children: [
|
|
38538
|
-
/* @__PURE__ */ jsx(Typography, { variant: "h4", className: "text-foreground", children: resolved.title }),
|
|
38539
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-muted-foreground", children: resolved.description }),
|
|
38796
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h4", className: "text-foreground", children: str(resolved.title) }),
|
|
38797
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-muted-foreground", children: str(resolved.description) }),
|
|
38540
38798
|
/* @__PURE__ */ jsxs(HStack, { className: "items-center p-2 rounded bg-primary/10 border border-primary/30", gap: "xs", children: [
|
|
38541
38799
|
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-primary font-bold", children: t("game.goal") + ":" }),
|
|
38542
|
-
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-foreground", children: resolved.goalCondition })
|
|
38800
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-foreground", children: str(resolved.goalCondition) })
|
|
38543
38801
|
] })
|
|
38544
38802
|
] }),
|
|
38545
38803
|
/* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
38546
38804
|
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-muted-foreground font-medium", children: t("eventHandler.clickObject") + ":" }),
|
|
38547
|
-
/* @__PURE__ */ jsx(HStack, { className: "flex-wrap", gap: "sm", children: objectViewers.map(({ obj, machine }) =>
|
|
38548
|
-
|
|
38549
|
-
|
|
38550
|
-
|
|
38551
|
-
|
|
38552
|
-
|
|
38553
|
-
|
|
38554
|
-
|
|
38555
|
-
|
|
38556
|
-
|
|
38557
|
-
/* @__PURE__ */
|
|
38558
|
-
|
|
38559
|
-
|
|
38560
|
-
|
|
38561
|
-
|
|
38562
|
-
|
|
38805
|
+
/* @__PURE__ */ jsx(HStack, { className: "flex-wrap", gap: "sm", children: objectViewers.map(({ obj, machine }) => {
|
|
38806
|
+
const oid = objId(obj);
|
|
38807
|
+
return /* @__PURE__ */ jsx(
|
|
38808
|
+
Box,
|
|
38809
|
+
{
|
|
38810
|
+
className: cn(
|
|
38811
|
+
"p-3 rounded-container border-2 cursor-pointer transition-all hover:scale-105",
|
|
38812
|
+
selectedObjectId === oid ? "border-primary bg-primary/10" : "border-border bg-card hover:border-muted-foreground"
|
|
38813
|
+
),
|
|
38814
|
+
onClick: () => setSelectedObjectId(oid),
|
|
38815
|
+
children: /* @__PURE__ */ jsxs(VStack, { gap: "xs", className: "items-center min-w-[120px]", children: [
|
|
38816
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h5", children: objIcon(obj) }),
|
|
38817
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-foreground font-medium", children: objName(obj) }),
|
|
38818
|
+
/* @__PURE__ */ jsx(TraitStateViewer, { trait: machine, variant: "compact", size: "sm" })
|
|
38819
|
+
] })
|
|
38820
|
+
},
|
|
38821
|
+
oid
|
|
38822
|
+
);
|
|
38823
|
+
}) })
|
|
38563
38824
|
] }),
|
|
38564
38825
|
selectedObject && /* @__PURE__ */ jsx(
|
|
38565
38826
|
ObjectRulePanel,
|
|
@@ -38570,12 +38831,12 @@ function EventHandlerBoard({
|
|
|
38570
38831
|
}
|
|
38571
38832
|
),
|
|
38572
38833
|
eventLog.length > 0 && /* @__PURE__ */ jsx(EventLog, { entries: eventLog }),
|
|
38573
|
-
playState === "success" && /* @__PURE__ */ jsx(Box, { className: "p-4 rounded-container bg-success/20 border border-success text-center", children: /* @__PURE__ */ jsx(Typography, { variant: "h5", className: "text-success", children: resolved.successMessage || t("eventHandler.chainComplete") }) }),
|
|
38834
|
+
playState === "success" && /* @__PURE__ */ jsx(Box, { className: "p-4 rounded-container bg-success/20 border border-success text-center", children: /* @__PURE__ */ jsx(Typography, { variant: "h5", className: "text-success", children: str(resolved.successMessage) || t("eventHandler.chainComplete") }) }),
|
|
38574
38835
|
playState === "fail" && /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
38575
38836
|
/* @__PURE__ */ jsx(Box, { className: "p-4 rounded-container bg-warning/10 border border-warning/30 text-center", children: /* @__PURE__ */ jsx(Typography, { variant: "body1", className: "text-foreground font-medium", children: t(encourageKey) }) }),
|
|
38576
38837
|
showHint && /* @__PURE__ */ jsx(Box, { className: "p-3 rounded-container bg-accent/10 border border-accent/30", children: /* @__PURE__ */ jsxs(HStack, { className: "items-start", gap: "xs", children: [
|
|
38577
38838
|
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-accent font-bold shrink-0", children: "\u{1F4A1} " + t("game.hint") + ":" }),
|
|
38578
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-foreground", children:
|
|
38839
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-foreground", children: hint })
|
|
38579
38840
|
] }) })
|
|
38580
38841
|
] }),
|
|
38581
38842
|
/* @__PURE__ */ jsxs(HStack, { gap: "sm", children: [
|
|
@@ -38603,6 +38864,8 @@ var init_EventHandlerBoard = __esm({
|
|
|
38603
38864
|
init_TraitStateViewer();
|
|
38604
38865
|
init_ObjectRulePanel();
|
|
38605
38866
|
init_EventLog();
|
|
38867
|
+
init_puzzleObject();
|
|
38868
|
+
init_boardEntity();
|
|
38606
38869
|
ENCOURAGEMENT_KEYS = [
|
|
38607
38870
|
"puzzle.tryAgain1",
|
|
38608
38871
|
"puzzle.tryAgain2",
|
|
@@ -38691,7 +38954,10 @@ var init_FeatureGridOrganism = __esm({
|
|
|
38691
38954
|
);
|
|
38692
38955
|
useCallback(
|
|
38693
38956
|
(feature) => {
|
|
38694
|
-
eventBus.emit("UI:FEATURE_CLICK", {
|
|
38957
|
+
eventBus.emit("UI:FEATURE_CLICK", {
|
|
38958
|
+
id: String(feature.id ?? ""),
|
|
38959
|
+
href: String(feature.href ?? "")
|
|
38960
|
+
});
|
|
38695
38961
|
},
|
|
38696
38962
|
[eventBus]
|
|
38697
38963
|
);
|
|
@@ -38701,14 +38967,17 @@ var init_FeatureGridOrganism = __esm({
|
|
|
38701
38967
|
if (error) {
|
|
38702
38968
|
return /* @__PURE__ */ jsx(ErrorState, { message: error.message, className });
|
|
38703
38969
|
}
|
|
38704
|
-
const featureCards = items.map((feature) =>
|
|
38705
|
-
|
|
38706
|
-
|
|
38707
|
-
|
|
38708
|
-
|
|
38709
|
-
|
|
38710
|
-
|
|
38711
|
-
|
|
38970
|
+
const featureCards = items.map((feature) => {
|
|
38971
|
+
const href = feature.href != null ? String(feature.href) : void 0;
|
|
38972
|
+
return {
|
|
38973
|
+
icon: feature.icon != null ? String(feature.icon) : void 0,
|
|
38974
|
+
title: String(feature.title ?? ""),
|
|
38975
|
+
description: String(feature.description ?? ""),
|
|
38976
|
+
href,
|
|
38977
|
+
linkLabel: feature.linkLabel != null ? String(feature.linkLabel) : void 0,
|
|
38978
|
+
variant: href ? "interactive" : "bordered"
|
|
38979
|
+
};
|
|
38980
|
+
});
|
|
38712
38981
|
return /* @__PURE__ */ jsxs(VStack, { gap: "lg", className: cn("w-full", className), children: [
|
|
38713
38982
|
(heading || subtitle) && /* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", className: "w-full", children: [
|
|
38714
38983
|
heading && /* @__PURE__ */ jsx(Typography, { variant: "h2", align: "center", children: heading }),
|
|
@@ -38907,12 +39176,12 @@ var init_Form = __esm({
|
|
|
38907
39176
|
const isSchemaEntity = isOrbitalEntitySchema(entity);
|
|
38908
39177
|
const resolvedEntity = isSchemaEntity ? entity : void 0;
|
|
38909
39178
|
const entityName = typeof entity === "string" ? entity : resolvedEntity?.name;
|
|
38910
|
-
const normalizedInitialData =
|
|
39179
|
+
const normalizedInitialData = React80__default.useMemo(() => {
|
|
38911
39180
|
const entityRowAsInitial = isPlainEntityRow(entity) ? entity : void 0;
|
|
38912
39181
|
const callerInitial = initialData !== null && typeof initialData === "object" && !Array.isArray(initialData) ? initialData : {};
|
|
38913
39182
|
return entityRowAsInitial !== void 0 ? { ...entityRowAsInitial, ...callerInitial } : callerInitial;
|
|
38914
39183
|
}, [entity, initialData]);
|
|
38915
|
-
const entityDerivedFields =
|
|
39184
|
+
const entityDerivedFields = React80__default.useMemo(() => {
|
|
38916
39185
|
if (fields && fields.length > 0) return void 0;
|
|
38917
39186
|
if (!resolvedEntity) return void 0;
|
|
38918
39187
|
return resolvedEntity.fields.map(
|
|
@@ -38932,16 +39201,16 @@ var init_Form = __esm({
|
|
|
38932
39201
|
const conditionalFields = typeof conditionalFieldsRaw === "boolean" ? {} : conditionalFieldsRaw;
|
|
38933
39202
|
const hiddenCalculations = typeof hiddenCalculationsRaw === "boolean" ? [] : hiddenCalculationsRaw;
|
|
38934
39203
|
const violationTriggers = typeof violationTriggersRaw === "boolean" ? [] : violationTriggersRaw;
|
|
38935
|
-
const [formData, setFormData] =
|
|
39204
|
+
const [formData, setFormData] = React80__default.useState(
|
|
38936
39205
|
normalizedInitialData
|
|
38937
39206
|
);
|
|
38938
|
-
const [collapsedSections, setCollapsedSections] =
|
|
39207
|
+
const [collapsedSections, setCollapsedSections] = React80__default.useState(
|
|
38939
39208
|
/* @__PURE__ */ new Set()
|
|
38940
39209
|
);
|
|
38941
|
-
const [submitError, setSubmitError] =
|
|
38942
|
-
const formRef =
|
|
39210
|
+
const [submitError, setSubmitError] = React80__default.useState(null);
|
|
39211
|
+
const formRef = React80__default.useRef(null);
|
|
38943
39212
|
const formMode = props.mode;
|
|
38944
|
-
const mountedRef =
|
|
39213
|
+
const mountedRef = React80__default.useRef(false);
|
|
38945
39214
|
if (!mountedRef.current) {
|
|
38946
39215
|
mountedRef.current = true;
|
|
38947
39216
|
debug("forms", "mount", {
|
|
@@ -38954,7 +39223,7 @@ var init_Form = __esm({
|
|
|
38954
39223
|
});
|
|
38955
39224
|
}
|
|
38956
39225
|
const shouldShowCancel = showCancel ?? (fields && fields.length > 0);
|
|
38957
|
-
const evalContext =
|
|
39226
|
+
const evalContext = React80__default.useMemo(
|
|
38958
39227
|
() => ({
|
|
38959
39228
|
formValues: formData,
|
|
38960
39229
|
globalVariables: externalContext?.globalVariables ?? {},
|
|
@@ -38963,7 +39232,7 @@ var init_Form = __esm({
|
|
|
38963
39232
|
}),
|
|
38964
39233
|
[formData, externalContext]
|
|
38965
39234
|
);
|
|
38966
|
-
|
|
39235
|
+
React80__default.useEffect(() => {
|
|
38967
39236
|
debug("forms", "initialData-sync", {
|
|
38968
39237
|
mode: formMode,
|
|
38969
39238
|
normalizedInitialData,
|
|
@@ -38974,7 +39243,7 @@ var init_Form = __esm({
|
|
|
38974
39243
|
setFormData(normalizedInitialData);
|
|
38975
39244
|
}
|
|
38976
39245
|
}, [normalizedInitialData]);
|
|
38977
|
-
const processCalculations =
|
|
39246
|
+
const processCalculations = React80__default.useCallback(
|
|
38978
39247
|
(changedFieldId, newFormData) => {
|
|
38979
39248
|
if (!hiddenCalculations.length) return;
|
|
38980
39249
|
const context = {
|
|
@@ -38999,7 +39268,7 @@ var init_Form = __esm({
|
|
|
38999
39268
|
},
|
|
39000
39269
|
[hiddenCalculations, externalContext, eventBus]
|
|
39001
39270
|
);
|
|
39002
|
-
const checkViolations =
|
|
39271
|
+
const checkViolations = React80__default.useCallback(
|
|
39003
39272
|
(changedFieldId, newFormData) => {
|
|
39004
39273
|
if (!violationTriggers.length) return;
|
|
39005
39274
|
const context = {
|
|
@@ -39037,7 +39306,7 @@ var init_Form = __esm({
|
|
|
39037
39306
|
processCalculations(name, newFormData);
|
|
39038
39307
|
checkViolations(name, newFormData);
|
|
39039
39308
|
};
|
|
39040
|
-
const isFieldVisible =
|
|
39309
|
+
const isFieldVisible = React80__default.useCallback(
|
|
39041
39310
|
(fieldName) => {
|
|
39042
39311
|
const condition = conditionalFields[fieldName];
|
|
39043
39312
|
if (!condition) return true;
|
|
@@ -39045,7 +39314,7 @@ var init_Form = __esm({
|
|
|
39045
39314
|
},
|
|
39046
39315
|
[conditionalFields, evalContext]
|
|
39047
39316
|
);
|
|
39048
|
-
const isSectionVisible =
|
|
39317
|
+
const isSectionVisible = React80__default.useCallback(
|
|
39049
39318
|
(section) => {
|
|
39050
39319
|
if (!section.condition) return true;
|
|
39051
39320
|
return Boolean(evaluateFormExpression(section.condition, evalContext));
|
|
@@ -39121,7 +39390,7 @@ var init_Form = __esm({
|
|
|
39121
39390
|
eventBus.emit(`UI:${onCancel}`);
|
|
39122
39391
|
}
|
|
39123
39392
|
};
|
|
39124
|
-
const renderField =
|
|
39393
|
+
const renderField = React80__default.useCallback(
|
|
39125
39394
|
(field) => {
|
|
39126
39395
|
const fieldName = field.name || field.field;
|
|
39127
39396
|
if (!fieldName) return null;
|
|
@@ -39142,7 +39411,7 @@ var init_Form = __esm({
|
|
|
39142
39411
|
[formData, isFieldVisible, relationsData, relationsLoading, isLoading]
|
|
39143
39412
|
);
|
|
39144
39413
|
const effectiveFields = entityDerivedFields ?? fields;
|
|
39145
|
-
const normalizedFields =
|
|
39414
|
+
const normalizedFields = React80__default.useMemo(() => {
|
|
39146
39415
|
if (!effectiveFields || effectiveFields.length === 0) return [];
|
|
39147
39416
|
return effectiveFields.map((field) => {
|
|
39148
39417
|
if (typeof field === "string") {
|
|
@@ -39165,7 +39434,7 @@ var init_Form = __esm({
|
|
|
39165
39434
|
return field;
|
|
39166
39435
|
});
|
|
39167
39436
|
}, [effectiveFields, resolvedEntity]);
|
|
39168
|
-
const schemaFields =
|
|
39437
|
+
const schemaFields = React80__default.useMemo(() => {
|
|
39169
39438
|
if (normalizedFields.length === 0) return null;
|
|
39170
39439
|
if (isDebugEnabled()) {
|
|
39171
39440
|
debugGroup(`Form: ${entityName || "unknown"}`);
|
|
@@ -39175,7 +39444,7 @@ var init_Form = __esm({
|
|
|
39175
39444
|
}
|
|
39176
39445
|
return normalizedFields.map(renderField).filter(Boolean);
|
|
39177
39446
|
}, [normalizedFields, renderField, entityName, conditionalFields]);
|
|
39178
|
-
const sectionElements =
|
|
39447
|
+
const sectionElements = React80__default.useMemo(() => {
|
|
39179
39448
|
if (!sections || sections.length === 0) return null;
|
|
39180
39449
|
return sections.map((section) => {
|
|
39181
39450
|
if (!isSectionVisible(section)) {
|
|
@@ -40033,22 +40302,24 @@ var init_HeroOrganism = __esm({
|
|
|
40033
40302
|
() => Array.isArray(entity) ? entity[0] : entity && typeof entity === "object" ? entity : void 0,
|
|
40034
40303
|
[entity]
|
|
40035
40304
|
);
|
|
40305
|
+
const primaryAction = resolved?.primaryAction;
|
|
40306
|
+
const secondaryAction = resolved?.secondaryAction;
|
|
40036
40307
|
const handlePrimaryClick = useCallback(() => {
|
|
40037
|
-
if (
|
|
40308
|
+
if (primaryAction) {
|
|
40038
40309
|
eventBus.emit("UI:CTA_PRIMARY", {
|
|
40039
|
-
label:
|
|
40040
|
-
href:
|
|
40310
|
+
label: String(primaryAction.label ?? ""),
|
|
40311
|
+
href: String(primaryAction.href ?? "")
|
|
40041
40312
|
});
|
|
40042
40313
|
}
|
|
40043
|
-
}, [eventBus,
|
|
40314
|
+
}, [eventBus, primaryAction]);
|
|
40044
40315
|
const handleSecondaryClick = useCallback(() => {
|
|
40045
|
-
if (
|
|
40316
|
+
if (secondaryAction) {
|
|
40046
40317
|
eventBus.emit("UI:CTA_SECONDARY", {
|
|
40047
|
-
label:
|
|
40048
|
-
href:
|
|
40318
|
+
label: String(secondaryAction.label ?? ""),
|
|
40319
|
+
href: String(secondaryAction.href ?? "")
|
|
40049
40320
|
});
|
|
40050
40321
|
}
|
|
40051
|
-
}, [eventBus,
|
|
40322
|
+
}, [eventBus, secondaryAction]);
|
|
40052
40323
|
if (isLoading) {
|
|
40053
40324
|
return /* @__PURE__ */ jsx(LoadingState, { message: t("common.loading"), className });
|
|
40054
40325
|
}
|
|
@@ -40058,17 +40329,19 @@ var init_HeroOrganism = __esm({
|
|
|
40058
40329
|
if (!resolved) {
|
|
40059
40330
|
return null;
|
|
40060
40331
|
}
|
|
40332
|
+
const imageRaw = resolved.image;
|
|
40333
|
+
const image = imageRaw ? { src: String(imageRaw.src ?? ""), alt: String(imageRaw.alt ?? "") } : void 0;
|
|
40061
40334
|
return /* @__PURE__ */ jsxs(
|
|
40062
40335
|
HeroSection,
|
|
40063
40336
|
{
|
|
40064
|
-
tag: resolved.tag,
|
|
40065
|
-
title: resolved.title,
|
|
40066
|
-
titleAccent: resolved.titleAccent,
|
|
40067
|
-
subtitle: resolved.subtitle,
|
|
40068
|
-
primaryAction:
|
|
40069
|
-
secondaryAction:
|
|
40070
|
-
installCommand: resolved.installCommand,
|
|
40071
|
-
image
|
|
40337
|
+
tag: resolved.tag != null ? String(resolved.tag) : void 0,
|
|
40338
|
+
title: String(resolved.title ?? ""),
|
|
40339
|
+
titleAccent: resolved.titleAccent != null ? String(resolved.titleAccent) : void 0,
|
|
40340
|
+
subtitle: String(resolved.subtitle ?? ""),
|
|
40341
|
+
primaryAction: primaryAction ? { label: String(primaryAction.label ?? ""), href: String(primaryAction.href ?? "") } : void 0,
|
|
40342
|
+
secondaryAction: secondaryAction ? { label: String(secondaryAction.label ?? ""), href: String(secondaryAction.href ?? "") } : void 0,
|
|
40343
|
+
installCommand: resolved.installCommand != null ? String(resolved.installCommand) : void 0,
|
|
40344
|
+
image,
|
|
40072
40345
|
imagePosition: resolved.imagePosition,
|
|
40073
40346
|
background: resolved.background,
|
|
40074
40347
|
className: cn(className),
|
|
@@ -40077,8 +40350,8 @@ var init_HeroOrganism = __esm({
|
|
|
40077
40350
|
/* @__PURE__ */ jsx(
|
|
40078
40351
|
_HeroClickInterceptor,
|
|
40079
40352
|
{
|
|
40080
|
-
hasPrimary: !!
|
|
40081
|
-
hasSecondary: !!
|
|
40353
|
+
hasPrimary: !!primaryAction,
|
|
40354
|
+
hasSecondary: !!secondaryAction,
|
|
40082
40355
|
onPrimaryClick: handlePrimaryClick,
|
|
40083
40356
|
onSecondaryClick: handleSecondaryClick
|
|
40084
40357
|
}
|
|
@@ -40307,7 +40580,7 @@ function formatValue3(value, fieldName) {
|
|
|
40307
40580
|
return String(value);
|
|
40308
40581
|
}
|
|
40309
40582
|
function formatFieldLabel2(fieldName) {
|
|
40310
|
-
return fieldName.replace(/([A-Z])/g, " $1").replace(/^./, (
|
|
40583
|
+
return fieldName.replace(/([A-Z])/g, " $1").replace(/^./, (str2) => str2.toUpperCase()).replace(/Id$/, "").trim();
|
|
40311
40584
|
}
|
|
40312
40585
|
var STATUS_STYLES2, StatusBadge, ProgressIndicator, List3;
|
|
40313
40586
|
var init_List = __esm({
|
|
@@ -40453,7 +40726,7 @@ var init_List = __esm({
|
|
|
40453
40726
|
if (entity && typeof entity === "object" && "id" in entity) return [entity];
|
|
40454
40727
|
return [];
|
|
40455
40728
|
}, [entity]);
|
|
40456
|
-
const getItemActions =
|
|
40729
|
+
const getItemActions = React80__default.useCallback(
|
|
40457
40730
|
(item) => {
|
|
40458
40731
|
if (!itemActions) return [];
|
|
40459
40732
|
if (typeof itemActions === "function") {
|
|
@@ -40929,7 +41202,7 @@ var init_MediaGallery = __esm({
|
|
|
40929
41202
|
[selectable, selectedItems, selectionEvent, eventBus]
|
|
40930
41203
|
);
|
|
40931
41204
|
const entityData = Array.isArray(entity) ? entity : [];
|
|
40932
|
-
const items =
|
|
41205
|
+
const items = React80__default.useMemo(() => {
|
|
40933
41206
|
if (propItems) return propItems;
|
|
40934
41207
|
if (entityData.length === 0) return [];
|
|
40935
41208
|
return entityData.map((record, idx) => ({
|
|
@@ -41099,9 +41372,9 @@ function MiniMap({
|
|
|
41099
41372
|
viewportRect,
|
|
41100
41373
|
className
|
|
41101
41374
|
}) {
|
|
41102
|
-
const canvasRef =
|
|
41103
|
-
const frameRef =
|
|
41104
|
-
|
|
41375
|
+
const canvasRef = React80.useRef(null);
|
|
41376
|
+
const frameRef = React80.useRef(0);
|
|
41377
|
+
React80.useEffect(() => {
|
|
41105
41378
|
const canvas = canvasRef.current;
|
|
41106
41379
|
if (!canvas) return;
|
|
41107
41380
|
const ctx = canvas.getContext("2d");
|
|
@@ -41183,7 +41456,7 @@ var init_MiniMap = __esm({
|
|
|
41183
41456
|
}
|
|
41184
41457
|
});
|
|
41185
41458
|
function extractTitle2(children) {
|
|
41186
|
-
if (!
|
|
41459
|
+
if (!React80__default.isValidElement(children)) return void 0;
|
|
41187
41460
|
const props = children.props;
|
|
41188
41461
|
if (typeof props.title === "string") {
|
|
41189
41462
|
return props.title;
|
|
@@ -41247,20 +41520,22 @@ function NegotiatorBoard({
|
|
|
41247
41520
|
}) {
|
|
41248
41521
|
const { emit } = useEventBus();
|
|
41249
41522
|
const { t } = useTranslate();
|
|
41250
|
-
const resolved =
|
|
41523
|
+
const resolved = boardEntity(entity);
|
|
41251
41524
|
const [history, setHistory] = useState([]);
|
|
41252
41525
|
const [headerError, setHeaderError] = useState(false);
|
|
41253
41526
|
const [showHint, setShowHint] = useState(false);
|
|
41527
|
+
const totalRounds = num(resolved?.totalRounds);
|
|
41528
|
+
const targetScore = num(resolved?.targetScore);
|
|
41254
41529
|
const currentRound = history.length;
|
|
41255
|
-
const isComplete = currentRound >=
|
|
41530
|
+
const isComplete = currentRound >= totalRounds;
|
|
41256
41531
|
const playerTotal = history.reduce((s, r) => s + r.playerPayoff, 0);
|
|
41257
41532
|
const opponentTotal = history.reduce((s, r) => s + r.opponentPayoff, 0);
|
|
41258
|
-
const won = isComplete && playerTotal >=
|
|
41259
|
-
const actions = resolved?.actions
|
|
41260
|
-
const payoffMatrix = resolved?.payoffMatrix
|
|
41533
|
+
const won = isComplete && playerTotal >= targetScore;
|
|
41534
|
+
const actions = Array.isArray(resolved?.actions) ? resolved.actions : [];
|
|
41535
|
+
const payoffMatrix = Array.isArray(resolved?.payoffMatrix) ? resolved.payoffMatrix : [];
|
|
41261
41536
|
const handleAction = useCallback((actionId) => {
|
|
41262
41537
|
if (isComplete) return;
|
|
41263
|
-
const opponentAction = getOpponentAction(resolved?.opponentStrategy
|
|
41538
|
+
const opponentAction = getOpponentAction(str(resolved?.opponentStrategy) || "random", actions, history);
|
|
41264
41539
|
const payoff = payoffMatrix.find(
|
|
41265
41540
|
(p2) => p2.playerAction === actionId && p2.opponentAction === opponentAction
|
|
41266
41541
|
);
|
|
@@ -41273,42 +41548,46 @@ function NegotiatorBoard({
|
|
|
41273
41548
|
};
|
|
41274
41549
|
const newHistory = [...history, result];
|
|
41275
41550
|
setHistory(newHistory);
|
|
41276
|
-
if (newHistory.length >=
|
|
41551
|
+
if (newHistory.length >= totalRounds) {
|
|
41277
41552
|
const total = newHistory.reduce((s, r) => s + r.playerPayoff, 0);
|
|
41278
|
-
if (total >=
|
|
41553
|
+
if (total >= targetScore) {
|
|
41279
41554
|
emit(`UI:${completeEvent}`, { success: true, score: total });
|
|
41280
41555
|
}
|
|
41281
|
-
if (newHistory.length >= 3 && resolved?.hint) {
|
|
41556
|
+
if (newHistory.length >= 3 && str(resolved?.hint)) {
|
|
41282
41557
|
setShowHint(true);
|
|
41283
41558
|
}
|
|
41284
41559
|
}
|
|
41285
|
-
}, [isComplete, resolved, actions, payoffMatrix, history, currentRound, completeEvent, emit]);
|
|
41560
|
+
}, [isComplete, resolved, totalRounds, targetScore, actions, payoffMatrix, history, currentRound, completeEvent, emit]);
|
|
41286
41561
|
const handleReset = () => {
|
|
41287
41562
|
setHistory([]);
|
|
41288
41563
|
setShowHint(false);
|
|
41289
41564
|
};
|
|
41290
41565
|
const getActionLabel = (id) => actions.find((a) => a.id === id)?.label ?? id;
|
|
41291
41566
|
if (!resolved) return null;
|
|
41567
|
+
const theme = resolved.theme ?? void 0;
|
|
41568
|
+
const themeBackground = theme?.background;
|
|
41569
|
+
const headerImage = str(resolved.headerImage);
|
|
41570
|
+
const hint = str(resolved.hint);
|
|
41292
41571
|
return /* @__PURE__ */ jsx(
|
|
41293
41572
|
Box,
|
|
41294
41573
|
{
|
|
41295
41574
|
className,
|
|
41296
41575
|
style: {
|
|
41297
|
-
backgroundImage:
|
|
41576
|
+
backgroundImage: themeBackground ? `url(${themeBackground})` : void 0,
|
|
41298
41577
|
backgroundSize: "cover",
|
|
41299
41578
|
backgroundPosition: "center"
|
|
41300
41579
|
},
|
|
41301
41580
|
children: /* @__PURE__ */ jsxs(VStack, { gap: "lg", className: "p-4", children: [
|
|
41302
|
-
|
|
41581
|
+
headerImage && !headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsx("img", { src: headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : headerImage && headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
41303
41582
|
/* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
41304
|
-
/* @__PURE__ */ jsx(Typography, { variant: "h4", weight: "bold", children: resolved.title }),
|
|
41305
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body", children: resolved.description }),
|
|
41583
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h4", weight: "bold", children: str(resolved.title) }),
|
|
41584
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", children: str(resolved.description) }),
|
|
41306
41585
|
/* @__PURE__ */ jsxs(HStack, { gap: "md", children: [
|
|
41307
|
-
/* @__PURE__ */ jsx(Badge, { size: "sm", children: t("negotiator.round", { current: String(currentRound), total: String(
|
|
41586
|
+
/* @__PURE__ */ jsx(Badge, { size: "sm", children: t("negotiator.round", { current: String(currentRound), total: String(totalRounds) }) }),
|
|
41308
41587
|
/* @__PURE__ */ jsxs(Badge, { size: "sm", children: [
|
|
41309
41588
|
t("negotiator.target"),
|
|
41310
41589
|
": ",
|
|
41311
|
-
|
|
41590
|
+
targetScore
|
|
41312
41591
|
] })
|
|
41313
41592
|
] })
|
|
41314
41593
|
] }) }),
|
|
@@ -41357,16 +41636,16 @@ function NegotiatorBoard({
|
|
|
41357
41636
|
] }) }),
|
|
41358
41637
|
isComplete && /* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", children: [
|
|
41359
41638
|
/* @__PURE__ */ jsx(Icon, { icon: CheckCircle, size: "lg", className: won ? "text-success" : "text-error" }),
|
|
41360
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "bold", children: won ? resolved.successMessage
|
|
41639
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "bold", children: won ? str(resolved.successMessage) || t("negotiator.success") : str(resolved.failMessage) || t("negotiator.failed") }),
|
|
41361
41640
|
/* @__PURE__ */ jsxs(Typography, { variant: "caption", className: "text-muted-foreground", children: [
|
|
41362
41641
|
t("negotiator.finalScore"),
|
|
41363
41642
|
": ",
|
|
41364
41643
|
playerTotal,
|
|
41365
41644
|
"/",
|
|
41366
|
-
|
|
41645
|
+
targetScore
|
|
41367
41646
|
] })
|
|
41368
41647
|
] }) }),
|
|
41369
|
-
showHint &&
|
|
41648
|
+
showHint && hint && !won && /* @__PURE__ */ jsx(Card, { className: "p-4 border-l-4 border-l-warning", children: /* @__PURE__ */ jsx(Typography, { variant: "body", children: hint }) }),
|
|
41370
41649
|
isComplete && !won && /* @__PURE__ */ jsx(HStack, { justify: "center", children: /* @__PURE__ */ jsx(Button, { variant: "primary", onClick: handleReset, children: t("negotiator.playAgain") }) })
|
|
41371
41650
|
] })
|
|
41372
41651
|
}
|
|
@@ -41376,6 +41655,7 @@ var init_NegotiatorBoard = __esm({
|
|
|
41376
41655
|
"components/game/organisms/puzzles/negotiator/NegotiatorBoard.tsx"() {
|
|
41377
41656
|
init_atoms2();
|
|
41378
41657
|
init_useEventBus();
|
|
41658
|
+
init_boardEntity();
|
|
41379
41659
|
NegotiatorBoard.displayName = "NegotiatorBoard";
|
|
41380
41660
|
}
|
|
41381
41661
|
});
|
|
@@ -41411,13 +41691,13 @@ var init_PricingOrganism = __esm({
|
|
|
41411
41691
|
return /* @__PURE__ */ jsx(ErrorState, { message: error.message, className });
|
|
41412
41692
|
}
|
|
41413
41693
|
const plans = items.map((plan) => ({
|
|
41414
|
-
name: plan.name,
|
|
41415
|
-
price: plan.price,
|
|
41416
|
-
description: plan.description,
|
|
41417
|
-
features: plan.features,
|
|
41418
|
-
action: { label: plan.actionLabel, href: plan.actionHref },
|
|
41419
|
-
highlighted: plan.highlighted,
|
|
41420
|
-
badge: plan.badge
|
|
41694
|
+
name: String(plan.name ?? ""),
|
|
41695
|
+
price: String(plan.price ?? ""),
|
|
41696
|
+
description: plan.description != null ? String(plan.description) : void 0,
|
|
41697
|
+
features: (plan.features ?? []).map((f3) => String(f3)),
|
|
41698
|
+
action: { label: String(plan.actionLabel ?? ""), href: String(plan.actionHref ?? "") },
|
|
41699
|
+
highlighted: Boolean(plan.highlighted),
|
|
41700
|
+
badge: plan.badge != null ? String(plan.badge) : void 0
|
|
41421
41701
|
}));
|
|
41422
41702
|
return /* @__PURE__ */ jsxs(VStack, { gap: "lg", className: cn("w-full", className), children: [
|
|
41423
41703
|
(heading || subtitle) && /* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", className: "w-full", children: [
|
|
@@ -41633,7 +41913,7 @@ var init_debugRegistry = __esm({
|
|
|
41633
41913
|
}
|
|
41634
41914
|
});
|
|
41635
41915
|
function useDebugData() {
|
|
41636
|
-
const [data, setData] =
|
|
41916
|
+
const [data, setData] = React80.useState(() => ({
|
|
41637
41917
|
traits: [],
|
|
41638
41918
|
ticks: [],
|
|
41639
41919
|
guards: [],
|
|
@@ -41647,7 +41927,7 @@ function useDebugData() {
|
|
|
41647
41927
|
},
|
|
41648
41928
|
lastUpdate: Date.now()
|
|
41649
41929
|
}));
|
|
41650
|
-
|
|
41930
|
+
React80.useEffect(() => {
|
|
41651
41931
|
const updateData = () => {
|
|
41652
41932
|
setData({
|
|
41653
41933
|
traits: getAllTraits(),
|
|
@@ -41756,12 +42036,12 @@ function layoutGraph(states, transitions, initialState, width, height) {
|
|
|
41756
42036
|
return positions;
|
|
41757
42037
|
}
|
|
41758
42038
|
function WalkMinimap() {
|
|
41759
|
-
const [walkStep, setWalkStep] =
|
|
41760
|
-
const [traits2, setTraits] =
|
|
41761
|
-
const [coveredEdges, setCoveredEdges] =
|
|
41762
|
-
const [completedTraits, setCompletedTraits] =
|
|
41763
|
-
const prevTraitRef =
|
|
41764
|
-
|
|
42039
|
+
const [walkStep, setWalkStep] = React80.useState(null);
|
|
42040
|
+
const [traits2, setTraits] = React80.useState([]);
|
|
42041
|
+
const [coveredEdges, setCoveredEdges] = React80.useState([]);
|
|
42042
|
+
const [completedTraits, setCompletedTraits] = React80.useState(/* @__PURE__ */ new Set());
|
|
42043
|
+
const prevTraitRef = React80.useRef(null);
|
|
42044
|
+
React80.useEffect(() => {
|
|
41765
42045
|
const interval = setInterval(() => {
|
|
41766
42046
|
const w = window;
|
|
41767
42047
|
const step = w.__orbitalWalkStep;
|
|
@@ -42197,15 +42477,15 @@ var init_EntitiesTab = __esm({
|
|
|
42197
42477
|
});
|
|
42198
42478
|
function EventFlowTab({ events: events2 }) {
|
|
42199
42479
|
const { t } = useTranslate();
|
|
42200
|
-
const [filter, setFilter] =
|
|
42201
|
-
const containerRef =
|
|
42202
|
-
const [autoScroll, setAutoScroll] =
|
|
42203
|
-
|
|
42480
|
+
const [filter, setFilter] = React80.useState("all");
|
|
42481
|
+
const containerRef = React80.useRef(null);
|
|
42482
|
+
const [autoScroll, setAutoScroll] = React80.useState(true);
|
|
42483
|
+
React80.useEffect(() => {
|
|
42204
42484
|
if (autoScroll && containerRef.current) {
|
|
42205
42485
|
containerRef.current.scrollTop = containerRef.current.scrollHeight;
|
|
42206
42486
|
}
|
|
42207
42487
|
}, [events2.length, autoScroll]);
|
|
42208
|
-
const filteredEvents =
|
|
42488
|
+
const filteredEvents = React80.useMemo(() => {
|
|
42209
42489
|
if (filter === "all") return events2;
|
|
42210
42490
|
return events2.filter((e) => e.type === filter);
|
|
42211
42491
|
}, [events2, filter]);
|
|
@@ -42321,7 +42601,7 @@ var init_EventFlowTab = __esm({
|
|
|
42321
42601
|
});
|
|
42322
42602
|
function GuardsPanel({ guards }) {
|
|
42323
42603
|
const { t } = useTranslate();
|
|
42324
|
-
const [filter, setFilter] =
|
|
42604
|
+
const [filter, setFilter] = React80.useState("all");
|
|
42325
42605
|
if (guards.length === 0) {
|
|
42326
42606
|
return /* @__PURE__ */ jsx(
|
|
42327
42607
|
EmptyState,
|
|
@@ -42334,7 +42614,7 @@ function GuardsPanel({ guards }) {
|
|
|
42334
42614
|
}
|
|
42335
42615
|
const passedCount = guards.filter((g) => g.result).length;
|
|
42336
42616
|
const failedCount = guards.length - passedCount;
|
|
42337
|
-
const filteredGuards =
|
|
42617
|
+
const filteredGuards = React80.useMemo(() => {
|
|
42338
42618
|
if (filter === "all") return guards;
|
|
42339
42619
|
if (filter === "passed") return guards.filter((g) => g.result);
|
|
42340
42620
|
return guards.filter((g) => !g.result);
|
|
@@ -42497,10 +42777,10 @@ function EffectBadge({ effect }) {
|
|
|
42497
42777
|
}
|
|
42498
42778
|
function TransitionTimeline({ transitions }) {
|
|
42499
42779
|
const { t } = useTranslate();
|
|
42500
|
-
const containerRef =
|
|
42501
|
-
const [autoScroll, setAutoScroll] =
|
|
42502
|
-
const [expandedId, setExpandedId] =
|
|
42503
|
-
|
|
42780
|
+
const containerRef = React80.useRef(null);
|
|
42781
|
+
const [autoScroll, setAutoScroll] = React80.useState(true);
|
|
42782
|
+
const [expandedId, setExpandedId] = React80.useState(null);
|
|
42783
|
+
React80.useEffect(() => {
|
|
42504
42784
|
if (autoScroll && containerRef.current) {
|
|
42505
42785
|
containerRef.current.scrollTop = containerRef.current.scrollHeight;
|
|
42506
42786
|
}
|
|
@@ -42780,9 +43060,9 @@ function getAllEvents(traits2) {
|
|
|
42780
43060
|
function EventDispatcherTab({ traits: traits2, schema }) {
|
|
42781
43061
|
const eventBus = useEventBus();
|
|
42782
43062
|
const { t } = useTranslate();
|
|
42783
|
-
const [log8, setLog] =
|
|
42784
|
-
const prevStatesRef =
|
|
42785
|
-
|
|
43063
|
+
const [log8, setLog] = React80.useState([]);
|
|
43064
|
+
const prevStatesRef = React80.useRef(/* @__PURE__ */ new Map());
|
|
43065
|
+
React80.useEffect(() => {
|
|
42786
43066
|
for (const trait of traits2) {
|
|
42787
43067
|
const prev = prevStatesRef.current.get(trait.id);
|
|
42788
43068
|
if (prev && prev !== trait.currentState) {
|
|
@@ -42951,10 +43231,10 @@ function VerifyModePanel({
|
|
|
42951
43231
|
localCount
|
|
42952
43232
|
}) {
|
|
42953
43233
|
const { t } = useTranslate();
|
|
42954
|
-
const [expanded, setExpanded] =
|
|
42955
|
-
const scrollRef =
|
|
42956
|
-
const prevCountRef =
|
|
42957
|
-
|
|
43234
|
+
const [expanded, setExpanded] = React80.useState(true);
|
|
43235
|
+
const scrollRef = React80.useRef(null);
|
|
43236
|
+
const prevCountRef = React80.useRef(0);
|
|
43237
|
+
React80.useEffect(() => {
|
|
42958
43238
|
if (expanded && transitions.length > prevCountRef.current && scrollRef.current) {
|
|
42959
43239
|
scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
|
|
42960
43240
|
}
|
|
@@ -43011,10 +43291,10 @@ function RuntimeDebugger({
|
|
|
43011
43291
|
schema
|
|
43012
43292
|
}) {
|
|
43013
43293
|
const { t } = useTranslate();
|
|
43014
|
-
const [isCollapsed, setIsCollapsed] =
|
|
43015
|
-
const [isVisible, setIsVisible] =
|
|
43294
|
+
const [isCollapsed, setIsCollapsed] = React80.useState(mode === "verify" ? true : defaultCollapsed);
|
|
43295
|
+
const [isVisible, setIsVisible] = React80.useState(mode === "inline" || mode === "verify" || isDebugEnabled2());
|
|
43016
43296
|
const debugData = useDebugData();
|
|
43017
|
-
|
|
43297
|
+
React80.useEffect(() => {
|
|
43018
43298
|
if (mode === "inline") return;
|
|
43019
43299
|
return onDebugToggle((enabled) => {
|
|
43020
43300
|
setIsVisible(enabled);
|
|
@@ -43023,7 +43303,7 @@ function RuntimeDebugger({
|
|
|
43023
43303
|
}
|
|
43024
43304
|
});
|
|
43025
43305
|
}, [mode]);
|
|
43026
|
-
|
|
43306
|
+
React80.useEffect(() => {
|
|
43027
43307
|
if (mode === "inline") return;
|
|
43028
43308
|
const handleKeyDown = (e) => {
|
|
43029
43309
|
if (e.key === "`" && isVisible) {
|
|
@@ -43472,7 +43752,7 @@ function SequenceBar({
|
|
|
43472
43752
|
onSlotRemove(index);
|
|
43473
43753
|
}, [onSlotRemove, playing]);
|
|
43474
43754
|
const paddedSlots = Array.from({ length: maxSlots }, (_, i) => slots[i]);
|
|
43475
|
-
return /* @__PURE__ */ jsx(HStack, { className: cn("items-center", className), gap: "sm", children: paddedSlots.map((slot, i) => /* @__PURE__ */ jsxs(
|
|
43755
|
+
return /* @__PURE__ */ jsx(HStack, { className: cn("items-center", className), gap: "sm", children: paddedSlots.map((slot, i) => /* @__PURE__ */ jsxs(React80__default.Fragment, { children: [
|
|
43476
43756
|
i > 0 && /* @__PURE__ */ jsx(
|
|
43477
43757
|
Typography,
|
|
43478
43758
|
{
|
|
@@ -43533,16 +43813,20 @@ function SequencerBoard({
|
|
|
43533
43813
|
}) {
|
|
43534
43814
|
const { emit } = useEventBus();
|
|
43535
43815
|
const { t } = useTranslate();
|
|
43536
|
-
const resolved =
|
|
43816
|
+
const resolved = boardEntity(entity);
|
|
43817
|
+
const maxSlots = num(resolved?.maxSlots);
|
|
43818
|
+
const solutions = Array.isArray(resolved?.solutions) ? resolved.solutions : [];
|
|
43819
|
+
const availableActions = Array.isArray(resolved?.availableActions) ? resolved.availableActions : [];
|
|
43820
|
+
const allowDuplicates = resolved?.allowDuplicates !== false;
|
|
43537
43821
|
const [headerError, setHeaderError] = useState(false);
|
|
43538
43822
|
const [slots, setSlots] = useState(
|
|
43539
|
-
() => Array.from({ length:
|
|
43823
|
+
() => Array.from({ length: maxSlots }, () => void 0)
|
|
43540
43824
|
);
|
|
43541
43825
|
const [playState, setPlayState] = useState("idle");
|
|
43542
43826
|
const [currentStep, setCurrentStep] = useState(-1);
|
|
43543
43827
|
const [attempts, setAttempts] = useState(0);
|
|
43544
43828
|
const [slotFeedback, setSlotFeedback] = useState(
|
|
43545
|
-
() => Array.from({ length:
|
|
43829
|
+
() => Array.from({ length: maxSlots }, () => null)
|
|
43546
43830
|
);
|
|
43547
43831
|
const timerRef = useRef(null);
|
|
43548
43832
|
useEffect(() => () => {
|
|
@@ -43576,17 +43860,17 @@ function SequencerBoard({
|
|
|
43576
43860
|
}, [emit]);
|
|
43577
43861
|
const handleReset = useCallback(() => {
|
|
43578
43862
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
43579
|
-
setSlots(Array.from({ length:
|
|
43863
|
+
setSlots(Array.from({ length: maxSlots }, () => void 0));
|
|
43580
43864
|
setPlayState("idle");
|
|
43581
43865
|
setCurrentStep(-1);
|
|
43582
43866
|
setAttempts(0);
|
|
43583
|
-
setSlotFeedback(Array.from({ length:
|
|
43584
|
-
}, [
|
|
43867
|
+
setSlotFeedback(Array.from({ length: maxSlots }, () => null));
|
|
43868
|
+
}, [maxSlots]);
|
|
43585
43869
|
const filledSlots = slots.filter((s) => !!s);
|
|
43586
43870
|
const canPlay = filledSlots.length > 0 && playState === "idle";
|
|
43587
43871
|
const handlePlay = useCallback(() => {
|
|
43588
43872
|
if (!canPlay) return;
|
|
43589
|
-
setSlotFeedback(Array.from({ length:
|
|
43873
|
+
setSlotFeedback(Array.from({ length: maxSlots }, () => null));
|
|
43590
43874
|
emit("UI:PLAY_SOUND", { key: "confirm" });
|
|
43591
43875
|
const sequence = slots.map((s) => s?.id || "");
|
|
43592
43876
|
if (playEvent) {
|
|
@@ -43597,10 +43881,10 @@ function SequencerBoard({
|
|
|
43597
43881
|
let step = 0;
|
|
43598
43882
|
const advance = () => {
|
|
43599
43883
|
step++;
|
|
43600
|
-
if (step >=
|
|
43884
|
+
if (step >= maxSlots) {
|
|
43601
43885
|
const playerSeq = slots.map((s) => s?.id);
|
|
43602
43886
|
const playerIds = slots.filter(Boolean).map((s) => s?.id || "");
|
|
43603
|
-
const success =
|
|
43887
|
+
const success = solutions.some(
|
|
43604
43888
|
(sol) => sol.length === playerIds.length && sol.every((id, i) => id === playerIds[i])
|
|
43605
43889
|
);
|
|
43606
43890
|
if (success) {
|
|
@@ -43612,7 +43896,7 @@ function SequencerBoard({
|
|
|
43612
43896
|
}
|
|
43613
43897
|
} else {
|
|
43614
43898
|
setAttempts((prev) => prev + 1);
|
|
43615
|
-
const feedback = computeSlotFeedback(playerSeq,
|
|
43899
|
+
const feedback = computeSlotFeedback(playerSeq, solutions);
|
|
43616
43900
|
setSlotFeedback(feedback);
|
|
43617
43901
|
setPlayState("idle");
|
|
43618
43902
|
setCurrentStep(-1);
|
|
@@ -43630,10 +43914,10 @@ function SequencerBoard({
|
|
|
43630
43914
|
}
|
|
43631
43915
|
};
|
|
43632
43916
|
timerRef.current = setTimeout(advance, stepDurationMs);
|
|
43633
|
-
}, [canPlay, slots,
|
|
43917
|
+
}, [canPlay, slots, maxSlots, solutions, stepDurationMs, playEvent, completeEvent, emit]);
|
|
43634
43918
|
const machine = {
|
|
43635
|
-
name: resolved?.title
|
|
43636
|
-
description: resolved?.description
|
|
43919
|
+
name: str(resolved?.title),
|
|
43920
|
+
description: str(resolved?.description),
|
|
43637
43921
|
states: slots.map((s, i) => stepLabel(s, i)),
|
|
43638
43922
|
currentState: currentStep >= 0 ? stepLabel(slots[currentStep], currentStep) : "__idle__",
|
|
43639
43923
|
transitions: slots.slice(0, -1).map((s, i) => ({
|
|
@@ -43642,37 +43926,41 @@ function SequencerBoard({
|
|
|
43642
43926
|
event: "NEXT"
|
|
43643
43927
|
}))
|
|
43644
43928
|
};
|
|
43645
|
-
const usedIds =
|
|
43646
|
-
const
|
|
43929
|
+
const usedIds = !allowDuplicates ? slots.filter(Boolean).map((s) => s?.id || "") : [];
|
|
43930
|
+
const hint = str(resolved?.hint);
|
|
43931
|
+
const showHint = attempts >= 3 && !!hint;
|
|
43647
43932
|
const hasFeedback = slotFeedback.some((f3) => f3 !== null);
|
|
43648
43933
|
const correctCount = slotFeedback.filter((f3) => f3 === "correct").length;
|
|
43649
43934
|
const encourageKey = ENCOURAGEMENT_KEYS2[Math.min(attempts - 1, ENCOURAGEMENT_KEYS2.length - 1)] ?? ENCOURAGEMENT_KEYS2[0];
|
|
43650
43935
|
if (!resolved) return null;
|
|
43936
|
+
const theme = resolved.theme ?? void 0;
|
|
43937
|
+
const themeBackground = theme?.background;
|
|
43938
|
+
const headerImage = str(resolved.headerImage);
|
|
43651
43939
|
return /* @__PURE__ */ jsxs(
|
|
43652
43940
|
VStack,
|
|
43653
43941
|
{
|
|
43654
43942
|
className: cn("p-4 gap-6", className),
|
|
43655
43943
|
style: {
|
|
43656
|
-
backgroundImage:
|
|
43944
|
+
backgroundImage: themeBackground ? `url(${themeBackground})` : void 0,
|
|
43657
43945
|
backgroundSize: "cover",
|
|
43658
43946
|
backgroundPosition: "center"
|
|
43659
43947
|
},
|
|
43660
43948
|
children: [
|
|
43661
|
-
|
|
43949
|
+
headerImage && !headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsx("img", { src: headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : headerImage && headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
43662
43950
|
/* @__PURE__ */ jsxs(VStack, { gap: "xs", children: [
|
|
43663
|
-
/* @__PURE__ */ jsx(Typography, { variant: "h4", className: "text-foreground", children: resolved.title }),
|
|
43664
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-muted-foreground", children: resolved.description })
|
|
43951
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h4", className: "text-foreground", children: str(resolved.title) }),
|
|
43952
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-muted-foreground", children: str(resolved.description) })
|
|
43665
43953
|
] }),
|
|
43666
43954
|
showHint && /* @__PURE__ */ jsx(Box, { className: "p-3 rounded-container bg-accent/10 border border-accent/30", children: /* @__PURE__ */ jsxs(HStack, { className: "items-start", gap: "xs", children: [
|
|
43667
43955
|
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-accent font-bold shrink-0", children: "\u{1F4A1} " + t("game.hint") + ":" }),
|
|
43668
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-foreground", children:
|
|
43956
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-foreground", children: hint })
|
|
43669
43957
|
] }) }),
|
|
43670
43958
|
filledSlots.length > 0 && /* @__PURE__ */ jsx(TraitStateViewer, { trait: machine, variant: "linear", size: "md" }),
|
|
43671
43959
|
/* @__PURE__ */ jsxs(VStack, { gap: "xs", children: [
|
|
43672
43960
|
/* @__PURE__ */ jsxs(HStack, { className: "items-center justify-between", children: [
|
|
43673
43961
|
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-muted-foreground font-medium", children: t("sequencer.yourSequence") + ":" }),
|
|
43674
43962
|
hasFeedback && playState === "idle" && /* @__PURE__ */ jsxs(Typography, { variant: "caption", className: "text-muted-foreground", children: [
|
|
43675
|
-
`${correctCount}/${
|
|
43963
|
+
`${correctCount}/${maxSlots} `,
|
|
43676
43964
|
"\u2705"
|
|
43677
43965
|
] })
|
|
43678
43966
|
] }),
|
|
@@ -43680,7 +43968,7 @@ function SequencerBoard({
|
|
|
43680
43968
|
SequenceBar,
|
|
43681
43969
|
{
|
|
43682
43970
|
slots,
|
|
43683
|
-
maxSlots
|
|
43971
|
+
maxSlots,
|
|
43684
43972
|
onSlotDrop: handleSlotDrop,
|
|
43685
43973
|
onSlotRemove: handleSlotRemove,
|
|
43686
43974
|
playing: playState === "playing",
|
|
@@ -43694,15 +43982,15 @@ function SequencerBoard({
|
|
|
43694
43982
|
playState !== "playing" && /* @__PURE__ */ jsx(
|
|
43695
43983
|
ActionPalette,
|
|
43696
43984
|
{
|
|
43697
|
-
actions:
|
|
43985
|
+
actions: availableActions,
|
|
43698
43986
|
usedActionIds: usedIds,
|
|
43699
|
-
allowDuplicates
|
|
43987
|
+
allowDuplicates,
|
|
43700
43988
|
categoryColors,
|
|
43701
43989
|
label: t("sequencer.dragActions")
|
|
43702
43990
|
}
|
|
43703
43991
|
),
|
|
43704
43992
|
hasFeedback && playState === "idle" && attempts > 0 && /* @__PURE__ */ jsx(Box, { className: "p-3 rounded-container bg-warning/10 border border-warning/30 text-center", children: /* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-foreground", children: t(encourageKey) }) }),
|
|
43705
|
-
playState === "success" && /* @__PURE__ */ jsx(Box, { className: "p-4 rounded-container bg-success/20 border border-success text-center", children: /* @__PURE__ */ jsx(Typography, { variant: "h5", className: "text-success", children: resolved.successMessage || t("sequencer.levelComplete") }) }),
|
|
43993
|
+
playState === "success" && /* @__PURE__ */ jsx(Box, { className: "p-4 rounded-container bg-success/20 border border-success text-center", children: /* @__PURE__ */ jsx(Typography, { variant: "h5", className: "text-success", children: str(resolved.successMessage) || t("sequencer.levelComplete") }) }),
|
|
43706
43994
|
/* @__PURE__ */ jsxs(HStack, { gap: "sm", children: [
|
|
43707
43995
|
/* @__PURE__ */ jsx(
|
|
43708
43996
|
Button,
|
|
@@ -43726,6 +44014,7 @@ var init_SequencerBoard = __esm({
|
|
|
43726
44014
|
init_cn();
|
|
43727
44015
|
init_useEventBus();
|
|
43728
44016
|
init_TraitStateViewer();
|
|
44017
|
+
init_boardEntity();
|
|
43729
44018
|
init_SequenceBar();
|
|
43730
44019
|
init_ActionPalette();
|
|
43731
44020
|
ENCOURAGEMENT_KEYS2 = [
|
|
@@ -43775,18 +44064,21 @@ var init_ShowcaseOrganism = __esm({
|
|
|
43775
44064
|
heading && /* @__PURE__ */ jsx(Typography, { variant: "h2", align: "center", children: heading }),
|
|
43776
44065
|
subtitle && /* @__PURE__ */ jsx(Typography, { variant: "body1", color: "muted", align: "center", className: "max-w-2xl", children: subtitle })
|
|
43777
44066
|
] }),
|
|
43778
|
-
/* @__PURE__ */ jsx(SimpleGrid, { cols: columns, gap: "lg", children: items.map((item) =>
|
|
43779
|
-
|
|
43780
|
-
|
|
43781
|
-
|
|
43782
|
-
|
|
43783
|
-
|
|
43784
|
-
|
|
43785
|
-
|
|
43786
|
-
|
|
43787
|
-
|
|
43788
|
-
|
|
43789
|
-
|
|
44067
|
+
/* @__PURE__ */ jsx(SimpleGrid, { cols: columns, gap: "lg", children: items.map((item) => {
|
|
44068
|
+
const imageRaw = item.image;
|
|
44069
|
+
return /* @__PURE__ */ jsx(
|
|
44070
|
+
ShowcaseCard,
|
|
44071
|
+
{
|
|
44072
|
+
title: String(item.title ?? ""),
|
|
44073
|
+
description: item.description != null ? String(item.description) : void 0,
|
|
44074
|
+
image: { src: String(imageRaw?.src ?? ""), alt: String(imageRaw?.alt ?? "") },
|
|
44075
|
+
href: item.href != null ? String(item.href) : void 0,
|
|
44076
|
+
badge: item.badge != null ? String(item.badge) : void 0,
|
|
44077
|
+
accentColor: item.accentColor != null ? String(item.accentColor) : void 0
|
|
44078
|
+
},
|
|
44079
|
+
String(item.id ?? "")
|
|
44080
|
+
);
|
|
44081
|
+
}) })
|
|
43790
44082
|
] });
|
|
43791
44083
|
};
|
|
43792
44084
|
ShowcaseOrganism.displayName = "ShowcaseOrganism";
|
|
@@ -44154,8 +44446,8 @@ function SimulatorBoard({
|
|
|
44154
44446
|
}) {
|
|
44155
44447
|
const { emit } = useEventBus();
|
|
44156
44448
|
const { t } = useTranslate();
|
|
44157
|
-
const resolved =
|
|
44158
|
-
const parameters = resolved?.parameters
|
|
44449
|
+
const resolved = boardEntity(entity);
|
|
44450
|
+
const parameters = Array.isArray(resolved?.parameters) ? resolved.parameters : [];
|
|
44159
44451
|
const [values, setValues] = useState(() => {
|
|
44160
44452
|
const init = {};
|
|
44161
44453
|
for (const p2 of parameters) {
|
|
@@ -44169,15 +44461,15 @@ function SimulatorBoard({
|
|
|
44169
44461
|
const [showHint, setShowHint] = useState(false);
|
|
44170
44462
|
const computeOutput = useCallback((params) => {
|
|
44171
44463
|
try {
|
|
44172
|
-
const fn = new Function("params", `return (${resolved?.computeExpression})`);
|
|
44464
|
+
const fn = new Function("params", `return (${str(resolved?.computeExpression)})`);
|
|
44173
44465
|
return fn(params);
|
|
44174
44466
|
} catch {
|
|
44175
44467
|
return 0;
|
|
44176
44468
|
}
|
|
44177
44469
|
}, [resolved?.computeExpression]);
|
|
44178
44470
|
const output = useMemo(() => computeOutput(values) ?? 0, [computeOutput, values]);
|
|
44179
|
-
const targetValue = resolved?.targetValue
|
|
44180
|
-
const targetTolerance = resolved?.targetTolerance
|
|
44471
|
+
const targetValue = num(resolved?.targetValue);
|
|
44472
|
+
const targetTolerance = num(resolved?.targetTolerance);
|
|
44181
44473
|
const isCorrect = Math.abs(output - targetValue) <= targetTolerance;
|
|
44182
44474
|
const handleParameterChange = (id, value) => {
|
|
44183
44475
|
if (submitted) return;
|
|
@@ -44192,7 +44484,7 @@ function SimulatorBoard({
|
|
|
44192
44484
|
};
|
|
44193
44485
|
const handleReset = () => {
|
|
44194
44486
|
setSubmitted(false);
|
|
44195
|
-
if (attempts >= 2 && resolved?.hint) {
|
|
44487
|
+
if (attempts >= 2 && str(resolved?.hint)) {
|
|
44196
44488
|
setShowHint(true);
|
|
44197
44489
|
}
|
|
44198
44490
|
};
|
|
@@ -44207,20 +44499,26 @@ function SimulatorBoard({
|
|
|
44207
44499
|
setShowHint(false);
|
|
44208
44500
|
};
|
|
44209
44501
|
if (!resolved) return null;
|
|
44502
|
+
const theme = resolved.theme ?? void 0;
|
|
44503
|
+
const themeBackground = theme?.background;
|
|
44504
|
+
const headerImage = str(resolved.headerImage);
|
|
44505
|
+
const hint = str(resolved.hint);
|
|
44506
|
+
const outputLabel = str(resolved.outputLabel);
|
|
44507
|
+
const outputUnit = str(resolved.outputUnit);
|
|
44210
44508
|
return /* @__PURE__ */ jsx(
|
|
44211
44509
|
Box,
|
|
44212
44510
|
{
|
|
44213
44511
|
className,
|
|
44214
44512
|
style: {
|
|
44215
|
-
backgroundImage:
|
|
44513
|
+
backgroundImage: themeBackground ? `url(${themeBackground})` : void 0,
|
|
44216
44514
|
backgroundSize: "cover",
|
|
44217
44515
|
backgroundPosition: "center"
|
|
44218
44516
|
},
|
|
44219
44517
|
children: /* @__PURE__ */ jsxs(VStack, { gap: "lg", className: "p-4", children: [
|
|
44220
|
-
|
|
44518
|
+
headerImage && !headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsx("img", { src: headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : headerImage && headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
44221
44519
|
/* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
44222
|
-
/* @__PURE__ */ jsx(Typography, { variant: "h4", weight: "bold", children: resolved.title }),
|
|
44223
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body", children: resolved.description })
|
|
44520
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h4", weight: "bold", children: str(resolved.title) }),
|
|
44521
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", children: str(resolved.description) })
|
|
44224
44522
|
] }) }),
|
|
44225
44523
|
/* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "md", children: [
|
|
44226
44524
|
/* @__PURE__ */ jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: t("simulator.parameters") }),
|
|
@@ -44261,28 +44559,28 @@ function SimulatorBoard({
|
|
|
44261
44559
|
] }, param.id))
|
|
44262
44560
|
] }) }),
|
|
44263
44561
|
/* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", children: [
|
|
44264
|
-
/* @__PURE__ */ jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children:
|
|
44562
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: outputLabel }),
|
|
44265
44563
|
/* @__PURE__ */ jsxs(Typography, { variant: "h3", weight: "bold", children: [
|
|
44266
44564
|
output.toFixed(2),
|
|
44267
44565
|
" ",
|
|
44268
|
-
|
|
44566
|
+
outputUnit
|
|
44269
44567
|
] }),
|
|
44270
44568
|
submitted && /* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
44271
44569
|
/* @__PURE__ */ jsx(Icon, { icon: isCorrect ? CheckCircle : XCircle, size: "sm", className: isCorrect ? "text-success" : "text-error" }),
|
|
44272
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body", className: isCorrect ? "text-success" : "text-error", children: isCorrect ? resolved.successMessage
|
|
44570
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", className: isCorrect ? "text-success" : "text-error", children: isCorrect ? str(resolved.successMessage) || t("simulator.correct") : str(resolved.failMessage) || t("simulator.incorrect") })
|
|
44273
44571
|
] }),
|
|
44274
44572
|
/* @__PURE__ */ jsxs(Typography, { variant: "caption", className: "text-muted-foreground", children: [
|
|
44275
44573
|
t("simulator.target"),
|
|
44276
44574
|
": ",
|
|
44277
44575
|
targetValue,
|
|
44278
44576
|
" ",
|
|
44279
|
-
|
|
44577
|
+
outputUnit,
|
|
44280
44578
|
" (\xB1",
|
|
44281
44579
|
targetTolerance,
|
|
44282
44580
|
")"
|
|
44283
44581
|
] })
|
|
44284
44582
|
] }) }),
|
|
44285
|
-
showHint &&
|
|
44583
|
+
showHint && hint && /* @__PURE__ */ jsx(Card, { className: "p-4 border-l-4 border-l-warning", children: /* @__PURE__ */ jsx(Typography, { variant: "body", children: hint }) }),
|
|
44286
44584
|
/* @__PURE__ */ jsxs(HStack, { gap: "sm", justify: "center", children: [
|
|
44287
44585
|
!submitted ? /* @__PURE__ */ jsxs(Button, { variant: "primary", onClick: handleSubmit, children: [
|
|
44288
44586
|
/* @__PURE__ */ jsx(Icon, { icon: Play, size: "sm" }),
|
|
@@ -44301,6 +44599,7 @@ var init_SimulatorBoard = __esm({
|
|
|
44301
44599
|
"components/game/organisms/puzzles/simulator/SimulatorBoard.tsx"() {
|
|
44302
44600
|
init_atoms2();
|
|
44303
44601
|
init_useEventBus();
|
|
44602
|
+
init_boardEntity();
|
|
44304
44603
|
SimulatorBoard.displayName = "SimulatorBoard";
|
|
44305
44604
|
}
|
|
44306
44605
|
});
|
|
@@ -44543,7 +44842,7 @@ var init_StatCard = __esm({
|
|
|
44543
44842
|
const labelToUse = propLabel ?? propTitle;
|
|
44544
44843
|
const eventBus = useEventBus();
|
|
44545
44844
|
const { t } = useTranslate();
|
|
44546
|
-
const handleActionClick =
|
|
44845
|
+
const handleActionClick = React80__default.useCallback(() => {
|
|
44547
44846
|
if (action?.event) {
|
|
44548
44847
|
eventBus.emit(`UI:${action.event}`, {});
|
|
44549
44848
|
}
|
|
@@ -44554,7 +44853,7 @@ var init_StatCard = __esm({
|
|
|
44554
44853
|
const data = Array.isArray(entity) ? entity : entity ? [entity] : [];
|
|
44555
44854
|
const isLoading = externalLoading ?? false;
|
|
44556
44855
|
const error = externalError;
|
|
44557
|
-
const computeMetricValue =
|
|
44856
|
+
const computeMetricValue = React80__default.useCallback(
|
|
44558
44857
|
(metric, items) => {
|
|
44559
44858
|
if (metric.value !== void 0) {
|
|
44560
44859
|
return metric.value;
|
|
@@ -44593,7 +44892,7 @@ var init_StatCard = __esm({
|
|
|
44593
44892
|
},
|
|
44594
44893
|
[]
|
|
44595
44894
|
);
|
|
44596
|
-
const schemaStats =
|
|
44895
|
+
const schemaStats = React80__default.useMemo(() => {
|
|
44597
44896
|
if (!metrics || metrics.length === 0) return null;
|
|
44598
44897
|
return metrics.map((metric) => ({
|
|
44599
44898
|
label: metric.label,
|
|
@@ -44601,7 +44900,7 @@ var init_StatCard = __esm({
|
|
|
44601
44900
|
format: metric.format
|
|
44602
44901
|
}));
|
|
44603
44902
|
}, [metrics, data, computeMetricValue]);
|
|
44604
|
-
const calculatedTrend =
|
|
44903
|
+
const calculatedTrend = React80__default.useMemo(() => {
|
|
44605
44904
|
if (manualTrend !== void 0) return manualTrend;
|
|
44606
44905
|
if (previousValue === void 0 || currentValue === void 0)
|
|
44607
44906
|
return void 0;
|
|
@@ -44837,22 +45136,25 @@ function VariablePanel({
|
|
|
44837
45136
|
return /* @__PURE__ */ jsxs(VStack, { className: cn("p-3 rounded-lg bg-card border border-border", className), gap: "sm", children: [
|
|
44838
45137
|
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-muted-foreground font-medium", children: t("stateArchitect.variables", { name: entityName }) }),
|
|
44839
45138
|
variables.map((v) => {
|
|
44840
|
-
const
|
|
44841
|
-
const
|
|
44842
|
-
const
|
|
45139
|
+
const name = v.name == null ? "" : String(v.name);
|
|
45140
|
+
const value = numField(v.value);
|
|
45141
|
+
const max = numField(v.max, 100);
|
|
45142
|
+
const min = numField(v.min, 0);
|
|
45143
|
+
const unit = v.unit == null ? "" : String(v.unit);
|
|
45144
|
+
const pct = Math.round((value - min) / (max - min) * 100);
|
|
44843
45145
|
const isHigh = pct > 80;
|
|
44844
45146
|
const isLow = pct < 20;
|
|
44845
45147
|
return /* @__PURE__ */ jsxs(VStack, { gap: "none", children: [
|
|
44846
45148
|
/* @__PURE__ */ jsxs(HStack, { className: "items-center justify-between", children: [
|
|
44847
|
-
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-foreground font-medium", children:
|
|
45149
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-foreground font-medium", children: name }),
|
|
44848
45150
|
/* @__PURE__ */ jsxs(Typography, { variant: "caption", className: cn(
|
|
44849
45151
|
isHigh ? "text-error" : isLow ? "text-warning" : "text-foreground"
|
|
44850
45152
|
), children: [
|
|
44851
|
-
|
|
44852
|
-
|
|
45153
|
+
value,
|
|
45154
|
+
unit,
|
|
44853
45155
|
" / ",
|
|
44854
45156
|
max,
|
|
44855
|
-
|
|
45157
|
+
unit
|
|
44856
45158
|
] })
|
|
44857
45159
|
] }),
|
|
44858
45160
|
/* @__PURE__ */ jsx(
|
|
@@ -44863,14 +45165,19 @@ function VariablePanel({
|
|
|
44863
45165
|
size: "sm"
|
|
44864
45166
|
}
|
|
44865
45167
|
)
|
|
44866
|
-
] },
|
|
45168
|
+
] }, name);
|
|
44867
45169
|
})
|
|
44868
45170
|
] });
|
|
44869
45171
|
}
|
|
45172
|
+
var numField;
|
|
44870
45173
|
var init_VariablePanel = __esm({
|
|
44871
45174
|
"components/game/organisms/puzzles/state-architect/VariablePanel.tsx"() {
|
|
44872
45175
|
init_atoms2();
|
|
44873
45176
|
init_cn();
|
|
45177
|
+
numField = (v, fallback = 0) => {
|
|
45178
|
+
const n = Number(v);
|
|
45179
|
+
return Number.isFinite(n) ? n : fallback;
|
|
45180
|
+
};
|
|
44874
45181
|
VariablePanel.displayName = "VariablePanel";
|
|
44875
45182
|
}
|
|
44876
45183
|
});
|
|
@@ -44897,14 +45204,21 @@ function StateArchitectBoard({
|
|
|
44897
45204
|
}) {
|
|
44898
45205
|
const { emit } = useEventBus();
|
|
44899
45206
|
const { t } = useTranslate();
|
|
44900
|
-
const resolved =
|
|
44901
|
-
const
|
|
45207
|
+
const resolved = boardEntity(entity);
|
|
45208
|
+
const entityStates = Array.isArray(resolved?.states) ? resolved.states : [];
|
|
45209
|
+
const initialState = str(resolved?.initialState);
|
|
45210
|
+
const entityName = str(resolved?.entityName);
|
|
45211
|
+
const availableEvents = Array.isArray(resolved?.availableEvents) ? resolved.availableEvents : [];
|
|
45212
|
+
const testCases = Array.isArray(resolved?.testCases) ? resolved.testCases : [];
|
|
45213
|
+
const entityTransitions = Array.isArray(resolved?.transitions) ? resolved.transitions : [];
|
|
45214
|
+
const entityVariables = rows(resolved?.variables);
|
|
45215
|
+
const [transitions, setTransitions] = useState(entityTransitions);
|
|
44902
45216
|
const [headerError, setHeaderError] = useState(false);
|
|
44903
45217
|
const [playState, setPlayState] = useState("editing");
|
|
44904
|
-
const [currentState, setCurrentState] = useState(
|
|
45218
|
+
const [currentState, setCurrentState] = useState(initialState);
|
|
44905
45219
|
const [selectedState, setSelectedState] = useState(null);
|
|
44906
45220
|
const [testResults, setTestResults] = useState([]);
|
|
44907
|
-
const [variables, setVariables] = useState(
|
|
45221
|
+
const [variables, setVariables] = useState(() => [...entityVariables]);
|
|
44908
45222
|
const [attempts, setAttempts] = useState(0);
|
|
44909
45223
|
const timerRef = useRef(null);
|
|
44910
45224
|
const [addingFrom, setAddingFrom] = useState(null);
|
|
@@ -44913,12 +45227,12 @@ function StateArchitectBoard({
|
|
|
44913
45227
|
}, []);
|
|
44914
45228
|
const GRAPH_W = 500;
|
|
44915
45229
|
const GRAPH_H = 400;
|
|
44916
|
-
const positions = useMemo(() => layoutStates(
|
|
45230
|
+
const positions = useMemo(() => layoutStates(entityStates, GRAPH_W, GRAPH_H), [entityStates]);
|
|
44917
45231
|
const handleStateClick = useCallback((state) => {
|
|
44918
45232
|
if (playState !== "editing") return;
|
|
44919
45233
|
if (addingFrom) {
|
|
44920
45234
|
if (addingFrom !== state) {
|
|
44921
|
-
const event =
|
|
45235
|
+
const event = availableEvents[0] || "EVENT";
|
|
44922
45236
|
const newTrans = {
|
|
44923
45237
|
id: `t-${nextTransId++}`,
|
|
44924
45238
|
from: addingFrom,
|
|
@@ -44931,7 +45245,7 @@ function StateArchitectBoard({
|
|
|
44931
45245
|
} else {
|
|
44932
45246
|
setSelectedState(state);
|
|
44933
45247
|
}
|
|
44934
|
-
}, [playState, addingFrom,
|
|
45248
|
+
}, [playState, addingFrom, availableEvents]);
|
|
44935
45249
|
const handleStartAddTransition = useCallback(() => {
|
|
44936
45250
|
if (!selectedState) return;
|
|
44937
45251
|
setAddingFrom(selectedState);
|
|
@@ -44940,9 +45254,9 @@ function StateArchitectBoard({
|
|
|
44940
45254
|
setTransitions((prev) => prev.filter((t2) => t2.id !== transId));
|
|
44941
45255
|
}, []);
|
|
44942
45256
|
const machine = useMemo(() => ({
|
|
44943
|
-
name:
|
|
44944
|
-
description: resolved?.description
|
|
44945
|
-
states:
|
|
45257
|
+
name: entityName,
|
|
45258
|
+
description: str(resolved?.description),
|
|
45259
|
+
states: entityStates,
|
|
44946
45260
|
currentState,
|
|
44947
45261
|
transitions: transitions.map((t2) => ({
|
|
44948
45262
|
from: t2.from,
|
|
@@ -44950,7 +45264,7 @@ function StateArchitectBoard({
|
|
|
44950
45264
|
event: t2.event,
|
|
44951
45265
|
guardHint: t2.guardHint
|
|
44952
45266
|
}))
|
|
44953
|
-
}), [resolved, currentState, transitions]);
|
|
45267
|
+
}), [entityName, resolved, entityStates, currentState, transitions]);
|
|
44954
45268
|
const handleTest = useCallback(() => {
|
|
44955
45269
|
if (playState !== "editing") return;
|
|
44956
45270
|
if (testEvent) emit(`UI:${testEvent}`, {});
|
|
@@ -44959,7 +45273,7 @@ function StateArchitectBoard({
|
|
|
44959
45273
|
const results = [];
|
|
44960
45274
|
let testIdx = 0;
|
|
44961
45275
|
const runNextTest = () => {
|
|
44962
|
-
if (testIdx >=
|
|
45276
|
+
if (testIdx >= testCases.length) {
|
|
44963
45277
|
const allPassed = results.every((r) => r.passed);
|
|
44964
45278
|
setPlayState(allPassed ? "success" : "fail");
|
|
44965
45279
|
setTestResults(results);
|
|
@@ -44974,9 +45288,9 @@ function StateArchitectBoard({
|
|
|
44974
45288
|
}
|
|
44975
45289
|
return;
|
|
44976
45290
|
}
|
|
44977
|
-
const testCase =
|
|
45291
|
+
const testCase = testCases[testIdx];
|
|
44978
45292
|
if (!testCase) return;
|
|
44979
|
-
let state =
|
|
45293
|
+
let state = initialState;
|
|
44980
45294
|
for (const event of testCase.events) {
|
|
44981
45295
|
const trans = transitions.find((t2) => t2.from === state && t2.event === event);
|
|
44982
45296
|
if (trans) {
|
|
@@ -44994,53 +45308,57 @@ function StateArchitectBoard({
|
|
|
44994
45308
|
timerRef.current = setTimeout(runNextTest, stepDurationMs);
|
|
44995
45309
|
};
|
|
44996
45310
|
timerRef.current = setTimeout(runNextTest, stepDurationMs);
|
|
44997
|
-
}, [playState, transitions,
|
|
45311
|
+
}, [playState, transitions, testCases, initialState, stepDurationMs, testEvent, completeEvent, emit]);
|
|
44998
45312
|
const handleTryAgain = useCallback(() => {
|
|
44999
45313
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
45000
45314
|
setPlayState("editing");
|
|
45001
|
-
setCurrentState(
|
|
45315
|
+
setCurrentState(initialState);
|
|
45002
45316
|
setTestResults([]);
|
|
45003
|
-
}, [
|
|
45317
|
+
}, [initialState]);
|
|
45004
45318
|
const handleReset = useCallback(() => {
|
|
45005
45319
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
45006
|
-
setTransitions(
|
|
45320
|
+
setTransitions(entityTransitions);
|
|
45007
45321
|
setPlayState("editing");
|
|
45008
|
-
setCurrentState(
|
|
45322
|
+
setCurrentState(initialState);
|
|
45009
45323
|
setTestResults([]);
|
|
45010
|
-
setVariables(
|
|
45324
|
+
setVariables([...entityVariables]);
|
|
45011
45325
|
setSelectedState(null);
|
|
45012
45326
|
setAddingFrom(null);
|
|
45013
45327
|
setAttempts(0);
|
|
45014
|
-
}, [
|
|
45328
|
+
}, [entityTransitions, initialState, entityVariables]);
|
|
45015
45329
|
const codeData = useMemo(() => ({
|
|
45016
|
-
name:
|
|
45017
|
-
states:
|
|
45018
|
-
initialState
|
|
45330
|
+
name: entityName,
|
|
45331
|
+
states: entityStates,
|
|
45332
|
+
initialState,
|
|
45019
45333
|
transitions: transitions.map((t2) => ({
|
|
45020
45334
|
from: t2.from,
|
|
45021
45335
|
to: t2.to,
|
|
45022
45336
|
event: t2.event,
|
|
45023
45337
|
...t2.guardHint ? { guard: t2.guardHint } : {}
|
|
45024
45338
|
}))
|
|
45025
|
-
}), [
|
|
45339
|
+
}), [entityName, entityStates, initialState, transitions]);
|
|
45026
45340
|
if (!resolved) return null;
|
|
45341
|
+
const theme = resolved.theme ?? void 0;
|
|
45342
|
+
const themeBackground = theme?.background;
|
|
45343
|
+
const headerImage = str(resolved.headerImage);
|
|
45344
|
+
const hint = str(resolved.hint);
|
|
45027
45345
|
return /* @__PURE__ */ jsxs(
|
|
45028
45346
|
VStack,
|
|
45029
45347
|
{
|
|
45030
45348
|
className: cn("p-4 gap-6", className),
|
|
45031
45349
|
style: {
|
|
45032
|
-
backgroundImage:
|
|
45350
|
+
backgroundImage: themeBackground ? `url(${themeBackground})` : void 0,
|
|
45033
45351
|
backgroundSize: "cover",
|
|
45034
45352
|
backgroundPosition: "center"
|
|
45035
45353
|
},
|
|
45036
45354
|
children: [
|
|
45037
|
-
|
|
45355
|
+
headerImage && !headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsx("img", { src: headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : headerImage && headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
45038
45356
|
/* @__PURE__ */ jsxs(VStack, { gap: "xs", children: [
|
|
45039
|
-
/* @__PURE__ */ jsx(Typography, { variant: "h4", className: "text-foreground", children: resolved.title }),
|
|
45040
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-muted-foreground", children: resolved.description }),
|
|
45357
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h4", className: "text-foreground", children: str(resolved.title) }),
|
|
45358
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-muted-foreground", children: str(resolved.description) }),
|
|
45041
45359
|
/* @__PURE__ */ jsxs(HStack, { className: "items-center p-2 rounded bg-warning/10 border border-warning/30", gap: "xs", children: [
|
|
45042
45360
|
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-warning font-bold", children: t("game.hint") + ":" }),
|
|
45043
|
-
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-foreground", children:
|
|
45361
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-foreground", children: hint })
|
|
45044
45362
|
] })
|
|
45045
45363
|
] }),
|
|
45046
45364
|
/* @__PURE__ */ jsxs(HStack, { className: "flex-wrap items-start", gap: "lg", children: [
|
|
@@ -45088,14 +45406,14 @@ function StateArchitectBoard({
|
|
|
45088
45406
|
]
|
|
45089
45407
|
}
|
|
45090
45408
|
),
|
|
45091
|
-
|
|
45409
|
+
entityStates.map((state) => /* @__PURE__ */ jsx(
|
|
45092
45410
|
StateNode2,
|
|
45093
45411
|
{
|
|
45094
45412
|
name: state,
|
|
45095
45413
|
position: positions[state],
|
|
45096
45414
|
isCurrent: state === currentState,
|
|
45097
45415
|
isSelected: state === selectedState,
|
|
45098
|
-
isInitial: state ===
|
|
45416
|
+
isInitial: state === initialState,
|
|
45099
45417
|
onClick: () => handleStateClick(state)
|
|
45100
45418
|
},
|
|
45101
45419
|
state
|
|
@@ -45142,7 +45460,7 @@ function StateArchitectBoard({
|
|
|
45142
45460
|
/* @__PURE__ */ jsx(
|
|
45143
45461
|
VariablePanel,
|
|
45144
45462
|
{
|
|
45145
|
-
entityName
|
|
45463
|
+
entityName,
|
|
45146
45464
|
variables
|
|
45147
45465
|
}
|
|
45148
45466
|
),
|
|
@@ -45157,12 +45475,12 @@ function StateArchitectBoard({
|
|
|
45157
45475
|
resolved.showCodeView !== false && /* @__PURE__ */ jsx(CodeView, { data: codeData, label: "View Code" })
|
|
45158
45476
|
] })
|
|
45159
45477
|
] }),
|
|
45160
|
-
playState === "success" && /* @__PURE__ */ jsx(Box, { className: "p-4 rounded-container bg-success/20 border border-success text-center", children: /* @__PURE__ */ jsx(Typography, { variant: "h5", className: "text-success", children: resolved.successMessage || t("stateArchitect.allPassed") }) }),
|
|
45478
|
+
playState === "success" && /* @__PURE__ */ jsx(Box, { className: "p-4 rounded-container bg-success/20 border border-success text-center", children: /* @__PURE__ */ jsx(Typography, { variant: "h5", className: "text-success", children: str(resolved.successMessage) || t("stateArchitect.allPassed") }) }),
|
|
45161
45479
|
playState === "fail" && /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
45162
45480
|
/* @__PURE__ */ jsx(Box, { className: "p-4 rounded-container bg-warning/10 border border-warning/30 text-center", children: /* @__PURE__ */ jsx(Typography, { variant: "body1", className: "text-foreground font-medium", children: t(ENCOURAGEMENT_KEYS3[Math.min(attempts - 1, ENCOURAGEMENT_KEYS3.length - 1)] ?? ENCOURAGEMENT_KEYS3[0]) }) }),
|
|
45163
|
-
attempts >= 3 &&
|
|
45481
|
+
attempts >= 3 && hint && /* @__PURE__ */ jsx(Box, { className: "p-3 rounded-container bg-accent/10 border border-accent/30", children: /* @__PURE__ */ jsxs(HStack, { className: "items-start", gap: "xs", children: [
|
|
45164
45482
|
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-accent font-bold shrink-0", children: "\u{1F4A1} " + t("game.hint") + ":" }),
|
|
45165
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-foreground", children:
|
|
45483
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-foreground", children: hint })
|
|
45166
45484
|
] }) })
|
|
45167
45485
|
] }),
|
|
45168
45486
|
/* @__PURE__ */ jsxs(HStack, { gap: "sm", children: [
|
|
@@ -45192,6 +45510,7 @@ var init_StateArchitectBoard = __esm({
|
|
|
45192
45510
|
init_TransitionArrow();
|
|
45193
45511
|
init_VariablePanel();
|
|
45194
45512
|
init_CodeView();
|
|
45513
|
+
init_boardEntity();
|
|
45195
45514
|
ENCOURAGEMENT_KEYS3 = [
|
|
45196
45515
|
"puzzle.tryAgain1",
|
|
45197
45516
|
"puzzle.tryAgain2",
|
|
@@ -45228,8 +45547,8 @@ var init_StatsOrganism = __esm({
|
|
|
45228
45547
|
return /* @__PURE__ */ jsx(ErrorState, { message: error.message, className });
|
|
45229
45548
|
}
|
|
45230
45549
|
const stats = items.map((item) => ({
|
|
45231
|
-
value: item.value,
|
|
45232
|
-
label: item.label
|
|
45550
|
+
value: String(item.value ?? ""),
|
|
45551
|
+
label: String(item.label ?? "")
|
|
45233
45552
|
}));
|
|
45234
45553
|
return /* @__PURE__ */ jsx(
|
|
45235
45554
|
StatsGrid,
|
|
@@ -45346,10 +45665,10 @@ var init_StepFlowOrganism = __esm({
|
|
|
45346
45665
|
return /* @__PURE__ */ jsx(ErrorState, { message: error.message, className });
|
|
45347
45666
|
}
|
|
45348
45667
|
const steps = items.map((item) => ({
|
|
45349
|
-
number: item.number,
|
|
45350
|
-
title: item.title,
|
|
45351
|
-
description: item.description,
|
|
45352
|
-
icon: item.icon
|
|
45668
|
+
number: item.number != null ? Number(item.number) : void 0,
|
|
45669
|
+
title: String(item.title ?? ""),
|
|
45670
|
+
description: String(item.description ?? ""),
|
|
45671
|
+
icon: item.icon != null ? String(item.icon) : void 0
|
|
45353
45672
|
}));
|
|
45354
45673
|
return /* @__PURE__ */ jsxs(VStack, { gap: "lg", className: cn("w-full", className), children: [
|
|
45355
45674
|
(heading || subtitle) && /* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", className: "w-full", children: [
|
|
@@ -45522,13 +45841,13 @@ var init_TeamOrganism = __esm({
|
|
|
45522
45841
|
/* @__PURE__ */ jsx(SimpleGrid, { cols: cols > 0 ? cols : 1, gap: "lg", children: items.map((member) => /* @__PURE__ */ jsx(
|
|
45523
45842
|
TeamCard,
|
|
45524
45843
|
{
|
|
45525
|
-
name: member.name,
|
|
45526
|
-
nameAr: member.nameAr,
|
|
45527
|
-
role: member.role,
|
|
45528
|
-
bio: member.bio,
|
|
45529
|
-
avatar: member.avatar
|
|
45844
|
+
name: String(member.name ?? ""),
|
|
45845
|
+
nameAr: member.nameAr != null ? String(member.nameAr) : void 0,
|
|
45846
|
+
role: String(member.role ?? ""),
|
|
45847
|
+
bio: String(member.bio ?? ""),
|
|
45848
|
+
avatar: member.avatar != null ? String(member.avatar) : void 0
|
|
45530
45849
|
},
|
|
45531
|
-
member.id
|
|
45850
|
+
String(member.id ?? "")
|
|
45532
45851
|
)) })
|
|
45533
45852
|
] });
|
|
45534
45853
|
};
|
|
@@ -45586,7 +45905,7 @@ var init_Timeline = __esm({
|
|
|
45586
45905
|
}) => {
|
|
45587
45906
|
const { t } = useTranslate();
|
|
45588
45907
|
const entityData = Array.isArray(entity) ? entity : [];
|
|
45589
|
-
const items =
|
|
45908
|
+
const items = React80__default.useMemo(() => {
|
|
45590
45909
|
if (propItems) return propItems;
|
|
45591
45910
|
if (entityData.length === 0) return [];
|
|
45592
45911
|
return entityData.map((record, idx) => {
|
|
@@ -45743,7 +46062,7 @@ var init_TimerDisplay = __esm({
|
|
|
45743
46062
|
}
|
|
45744
46063
|
});
|
|
45745
46064
|
function extractToastProps(children) {
|
|
45746
|
-
if (!
|
|
46065
|
+
if (!React80__default.isValidElement(children)) {
|
|
45747
46066
|
if (typeof children === "string") {
|
|
45748
46067
|
return { message: children };
|
|
45749
46068
|
}
|
|
@@ -45781,7 +46100,7 @@ var init_ToastSlot = __esm({
|
|
|
45781
46100
|
eventBus.emit("UI:CLOSE");
|
|
45782
46101
|
};
|
|
45783
46102
|
if (!isVisible) return null;
|
|
45784
|
-
const isCustomContent =
|
|
46103
|
+
const isCustomContent = React80__default.isValidElement(children) && !message;
|
|
45785
46104
|
return /* @__PURE__ */ jsx(Box, { className: "fixed bottom-4 right-4 z-50", children: isCustomContent ? children : /* @__PURE__ */ jsx(
|
|
45786
46105
|
Toast,
|
|
45787
46106
|
{
|
|
@@ -45815,8 +46134,8 @@ function useBattleState(initialUnits, eventConfig = {}, callbacks = {}) {
|
|
|
45815
46134
|
const [turn, setTurn] = useState(1);
|
|
45816
46135
|
const [gameResult, setGameResult] = useState(null);
|
|
45817
46136
|
const checkGameEnd = useCallback((currentUnits) => {
|
|
45818
|
-
const pa = currentUnits.filter((u) => u
|
|
45819
|
-
const ea = currentUnits.filter((u) => u
|
|
46137
|
+
const pa = currentUnits.filter((u) => unitTeam(u) === "player" && unitHealth(u) > 0);
|
|
46138
|
+
const ea = currentUnits.filter((u) => unitTeam(u) === "enemy" && unitHealth(u) > 0);
|
|
45820
46139
|
if (pa.length === 0) {
|
|
45821
46140
|
setGameResult("defeat");
|
|
45822
46141
|
setPhase("game_over");
|
|
@@ -45834,34 +46153,36 @@ function useBattleState(initialUnits, eventConfig = {}, callbacks = {}) {
|
|
|
45834
46153
|
}
|
|
45835
46154
|
}, [onGameEnd, gameEndEvent, eventBus]);
|
|
45836
46155
|
const handleUnitClick = useCallback((unitId) => {
|
|
45837
|
-
const unit = units.find((u) => u.id === unitId);
|
|
46156
|
+
const unit = units.find((u) => str(u.id) === unitId);
|
|
45838
46157
|
if (!unit) return;
|
|
45839
46158
|
if (unitClickEvent) {
|
|
45840
46159
|
eventBus.emit(`UI:${unitClickEvent}`, { unitId });
|
|
45841
46160
|
}
|
|
45842
46161
|
if (phase === "observation" || phase === "selection") {
|
|
45843
|
-
if (unit
|
|
46162
|
+
if (unitTeam(unit) === "player") {
|
|
45844
46163
|
setSelectedUnitId(unitId);
|
|
45845
46164
|
setPhase("movement");
|
|
45846
46165
|
}
|
|
45847
46166
|
} else if (phase === "action") {
|
|
45848
|
-
const selectedUnit = units.find((u) => u.id === selectedUnitId);
|
|
46167
|
+
const selectedUnit = units.find((u) => str(u.id) === selectedUnitId);
|
|
45849
46168
|
if (!selectedUnit) return;
|
|
45850
|
-
if (unit
|
|
45851
|
-
const
|
|
45852
|
-
const
|
|
46169
|
+
if (unitTeam(unit) === "enemy") {
|
|
46170
|
+
const up = unitPosition(unit);
|
|
46171
|
+
const sp = unitPosition(selectedUnit);
|
|
46172
|
+
const dx = Math.abs(up.x - sp.x);
|
|
46173
|
+
const dy = Math.abs(up.y - sp.y);
|
|
45853
46174
|
if (dx <= 1 && dy <= 1 && dx + dy > 0) {
|
|
45854
|
-
const damage = calculateDamage2 ? calculateDamage2(selectedUnit, unit) : Math.max(1, selectedUnit.attack - unit.defense);
|
|
45855
|
-
const newHealth = Math.max(0, unit
|
|
46175
|
+
const damage = calculateDamage2 ? calculateDamage2(selectedUnit, unit) : Math.max(1, num(selectedUnit.attack) - num(unit.defense));
|
|
46176
|
+
const newHealth = Math.max(0, unitHealth(unit) - damage);
|
|
45856
46177
|
const updatedUnits = units.map(
|
|
45857
|
-
(u) => u.id === unit.id ? { ...u, health: newHealth } : u
|
|
46178
|
+
(u) => str(u.id) === str(unit.id) ? { ...u, health: newHealth } : u
|
|
45858
46179
|
);
|
|
45859
46180
|
setUnits(updatedUnits);
|
|
45860
46181
|
onAttack?.(selectedUnit, unit, damage);
|
|
45861
46182
|
if (attackEvent) {
|
|
45862
46183
|
eventBus.emit(`UI:${attackEvent}`, {
|
|
45863
|
-
attackerId: selectedUnit.id,
|
|
45864
|
-
targetId: unit.id,
|
|
46184
|
+
attackerId: str(selectedUnit.id),
|
|
46185
|
+
targetId: str(unit.id),
|
|
45865
46186
|
damage
|
|
45866
46187
|
});
|
|
45867
46188
|
}
|
|
@@ -45878,16 +46199,20 @@ function useBattleState(initialUnits, eventConfig = {}, callbacks = {}) {
|
|
|
45878
46199
|
eventBus.emit(`UI:${tileClickEvent}`, { x, y });
|
|
45879
46200
|
}
|
|
45880
46201
|
if (phase === "movement" && selectedUnitId) {
|
|
45881
|
-
const selectedUnit = units.find((u) => u.id === selectedUnitId);
|
|
46202
|
+
const selectedUnit = units.find((u) => str(u.id) === selectedUnitId);
|
|
45882
46203
|
if (!selectedUnit) return;
|
|
45883
|
-
const
|
|
45884
|
-
const
|
|
46204
|
+
const sp = unitPosition(selectedUnit);
|
|
46205
|
+
const dx = Math.abs(x - sp.x);
|
|
46206
|
+
const dy = Math.abs(y - sp.y);
|
|
45885
46207
|
const dist = dx + dy;
|
|
45886
|
-
if (dist > 0 && dist <= selectedUnit.movement) {
|
|
45887
|
-
if (!units.some((u) =>
|
|
46208
|
+
if (dist > 0 && dist <= num(selectedUnit.movement)) {
|
|
46209
|
+
if (!units.some((u) => {
|
|
46210
|
+
const p2 = unitPosition(u);
|
|
46211
|
+
return p2.x === x && p2.y === y && unitHealth(u) > 0;
|
|
46212
|
+
})) {
|
|
45888
46213
|
setUnits(
|
|
45889
46214
|
(prev) => prev.map(
|
|
45890
|
-
(u) => u.id === selectedUnitId ? { ...u, position: { x, y } } : u
|
|
46215
|
+
(u) => str(u.id) === selectedUnitId ? { ...u, position: { x, y } } : u
|
|
45891
46216
|
)
|
|
45892
46217
|
);
|
|
45893
46218
|
setPhase("action");
|
|
@@ -45930,12 +46255,13 @@ var init_useBattleState = __esm({
|
|
|
45930
46255
|
"components/game/organisms/hooks/useBattleState.ts"() {
|
|
45931
46256
|
"use client";
|
|
45932
46257
|
init_useEventBus();
|
|
46258
|
+
init_boardEntity();
|
|
45933
46259
|
}
|
|
45934
46260
|
});
|
|
45935
46261
|
function UncontrolledBattleBoard({ entity, ...rest }) {
|
|
45936
|
-
const resolved =
|
|
46262
|
+
const resolved = boardEntity(entity);
|
|
45937
46263
|
const battleState = useBattleState(
|
|
45938
|
-
resolved?.initialUnits
|
|
46264
|
+
rows(resolved?.initialUnits),
|
|
45939
46265
|
{
|
|
45940
46266
|
tileClickEvent: rest.tileClickEvent,
|
|
45941
46267
|
unitClickEvent: rest.unitClickEvent,
|
|
@@ -45971,10 +46297,23 @@ function UncontrolledBattleBoard({ entity, ...rest }) {
|
|
|
45971
46297
|
var init_UncontrolledBattleBoard = __esm({
|
|
45972
46298
|
"components/game/organisms/UncontrolledBattleBoard.tsx"() {
|
|
45973
46299
|
init_BattleBoard();
|
|
46300
|
+
init_boardEntity();
|
|
45974
46301
|
init_useBattleState();
|
|
45975
46302
|
UncontrolledBattleBoard.displayName = "UncontrolledBattleBoard";
|
|
45976
46303
|
}
|
|
45977
46304
|
});
|
|
46305
|
+
function heroPosition(h) {
|
|
46306
|
+
return vec2(h.position);
|
|
46307
|
+
}
|
|
46308
|
+
function heroOwner(h) {
|
|
46309
|
+
return str(h.owner);
|
|
46310
|
+
}
|
|
46311
|
+
function heroMovement(h) {
|
|
46312
|
+
return num(h.movement);
|
|
46313
|
+
}
|
|
46314
|
+
function hexPassable(h) {
|
|
46315
|
+
return h.passable !== false;
|
|
46316
|
+
}
|
|
45978
46317
|
function defaultIsInRange(from, to, range) {
|
|
45979
46318
|
return Math.abs(from.x - to.x) + Math.abs(from.y - to.y) <= range;
|
|
45980
46319
|
}
|
|
@@ -46005,36 +46344,36 @@ function WorldMapBoard({
|
|
|
46005
46344
|
className
|
|
46006
46345
|
}) {
|
|
46007
46346
|
const eventBus = useEventBus();
|
|
46008
|
-
const resolved =
|
|
46009
|
-
const hexes = resolved?.hexes
|
|
46010
|
-
const heroes = resolved?.heroes
|
|
46011
|
-
const features = resolved?.features
|
|
46012
|
-
const selectedHeroId = resolved?.selectedHeroId;
|
|
46347
|
+
const resolved = boardEntity(entity);
|
|
46348
|
+
const hexes = rows(resolved?.hexes);
|
|
46349
|
+
const heroes = rows(resolved?.heroes);
|
|
46350
|
+
const features = Array.isArray(resolved?.features) ? resolved.features : [];
|
|
46351
|
+
const selectedHeroId = resolved?.selectedHeroId ?? null;
|
|
46013
46352
|
const assetManifest = resolved?.assetManifest;
|
|
46014
46353
|
const backgroundImage = resolved?.backgroundImage;
|
|
46015
46354
|
const [hoveredTile, setHoveredTile] = useState(null);
|
|
46016
46355
|
const selectedHero = useMemo(
|
|
46017
|
-
() => heroes.find((h) => h.id === selectedHeroId) ?? null,
|
|
46356
|
+
() => heroes.find((h) => str(h.id) === selectedHeroId) ?? null,
|
|
46018
46357
|
[heroes, selectedHeroId]
|
|
46019
46358
|
);
|
|
46020
46359
|
const tiles = useMemo(
|
|
46021
46360
|
() => hexes.map((hex) => ({
|
|
46022
|
-
x: hex.x,
|
|
46023
|
-
y: hex.y,
|
|
46024
|
-
terrain: hex.terrain,
|
|
46025
|
-
terrainSprite: hex.terrainSprite
|
|
46361
|
+
x: num(hex.x),
|
|
46362
|
+
y: num(hex.y),
|
|
46363
|
+
terrain: str(hex.terrain),
|
|
46364
|
+
terrainSprite: hex.terrainSprite == null ? void 0 : str(hex.terrainSprite)
|
|
46026
46365
|
})),
|
|
46027
46366
|
[hexes]
|
|
46028
46367
|
);
|
|
46029
46368
|
const baseUnits = useMemo(
|
|
46030
46369
|
() => heroes.map((hero) => ({
|
|
46031
|
-
id: hero.id,
|
|
46032
|
-
position: hero
|
|
46033
|
-
name: hero.name,
|
|
46034
|
-
team: hero
|
|
46370
|
+
id: str(hero.id),
|
|
46371
|
+
position: heroPosition(hero),
|
|
46372
|
+
name: str(hero.name),
|
|
46373
|
+
team: heroOwner(hero) === "enemy" ? "enemy" : "player",
|
|
46035
46374
|
health: 100,
|
|
46036
46375
|
maxHealth: 100,
|
|
46037
|
-
sprite: hero.sprite
|
|
46376
|
+
sprite: hero.sprite == null ? void 0 : str(hero.sprite)
|
|
46038
46377
|
})),
|
|
46039
46378
|
[heroes]
|
|
46040
46379
|
);
|
|
@@ -46075,73 +46414,94 @@ function WorldMapBoard({
|
|
|
46075
46414
|
const isoUnits = useMemo(() => {
|
|
46076
46415
|
if (movingPositions.size === 0) return baseUnits;
|
|
46077
46416
|
return baseUnits.map((u) => {
|
|
46078
|
-
const pos = movingPositions.get(u.id);
|
|
46417
|
+
const pos = u.id == null ? void 0 : movingPositions.get(u.id);
|
|
46079
46418
|
return pos ? { ...u, position: pos } : u;
|
|
46080
46419
|
});
|
|
46081
46420
|
}, [baseUnits, movingPositions]);
|
|
46082
46421
|
const validMoves = useMemo(() => {
|
|
46083
|
-
if (!selectedHero || selectedHero
|
|
46422
|
+
if (!selectedHero || heroMovement(selectedHero) <= 0) return [];
|
|
46423
|
+
const sp = heroPosition(selectedHero);
|
|
46424
|
+
const sOwner = heroOwner(selectedHero);
|
|
46425
|
+
const range = heroMovement(selectedHero);
|
|
46084
46426
|
const moves = [];
|
|
46085
46427
|
hexes.forEach((hex) => {
|
|
46086
|
-
|
|
46087
|
-
|
|
46088
|
-
if (!
|
|
46089
|
-
if (
|
|
46090
|
-
|
|
46428
|
+
const hx = num(hex.x);
|
|
46429
|
+
const hy = num(hex.y);
|
|
46430
|
+
if (!hexPassable(hex)) return;
|
|
46431
|
+
if (hx === sp.x && hy === sp.y) return;
|
|
46432
|
+
if (!isInRange(sp, { x: hx, y: hy }, range)) return;
|
|
46433
|
+
if (heroes.some((h) => {
|
|
46434
|
+
const hp = heroPosition(h);
|
|
46435
|
+
return hp.x === hx && hp.y === hy && heroOwner(h) === sOwner;
|
|
46436
|
+
})) return;
|
|
46437
|
+
moves.push({ x: hx, y: hy });
|
|
46091
46438
|
});
|
|
46092
46439
|
return moves;
|
|
46093
46440
|
}, [selectedHero, hexes, heroes, isInRange]);
|
|
46094
46441
|
const attackTargets = useMemo(() => {
|
|
46095
|
-
if (!selectedHero || selectedHero
|
|
46096
|
-
|
|
46442
|
+
if (!selectedHero || heroMovement(selectedHero) <= 0) return [];
|
|
46443
|
+
const sp = heroPosition(selectedHero);
|
|
46444
|
+
const sOwner = heroOwner(selectedHero);
|
|
46445
|
+
const range = heroMovement(selectedHero);
|
|
46446
|
+
return heroes.filter((h) => heroOwner(h) !== sOwner).filter((h) => isInRange(sp, heroPosition(h), range)).map((h) => heroPosition(h));
|
|
46097
46447
|
}, [selectedHero, heroes, isInRange]);
|
|
46098
|
-
const maxY = Math.max(...hexes.map((h) => h.y), 0);
|
|
46448
|
+
const maxY = Math.max(...hexes.map((h) => num(h.y)), 0);
|
|
46099
46449
|
const baseOffsetX = (maxY + 1) * (TILE_WIDTH * scale / 2);
|
|
46100
46450
|
const tileToScreen = useCallback(
|
|
46101
46451
|
(tx, ty) => isoToScreen(tx, ty, scale, baseOffsetX),
|
|
46102
46452
|
[scale, baseOffsetX]
|
|
46103
46453
|
);
|
|
46104
46454
|
const hoveredHex = useMemo(
|
|
46105
|
-
() => hoveredTile ? hexes.find((h) => h.x === hoveredTile.x && h.y === hoveredTile.y) ?? null : null,
|
|
46455
|
+
() => hoveredTile ? hexes.find((h) => num(h.x) === hoveredTile.x && num(h.y) === hoveredTile.y) ?? null : null,
|
|
46106
46456
|
[hoveredTile, hexes]
|
|
46107
46457
|
);
|
|
46108
46458
|
const hoveredHero = useMemo(
|
|
46109
|
-
() => hoveredTile ? heroes.find((h) =>
|
|
46459
|
+
() => hoveredTile ? heroes.find((h) => {
|
|
46460
|
+
const hp = heroPosition(h);
|
|
46461
|
+
return hp.x === hoveredTile.x && hp.y === hoveredTile.y;
|
|
46462
|
+
}) ?? null : null,
|
|
46110
46463
|
[hoveredTile, heroes]
|
|
46111
46464
|
);
|
|
46112
46465
|
const handleTileClick = useCallback((x, y) => {
|
|
46113
46466
|
if (movementAnimRef.current) return;
|
|
46114
|
-
const hex = hexes.find((h) => h.x === x && h.y === y);
|
|
46467
|
+
const hex = hexes.find((h) => num(h.x) === x && num(h.y) === y);
|
|
46115
46468
|
if (!hex) return;
|
|
46116
46469
|
if (tileClickEvent) {
|
|
46117
46470
|
eventBus.emit(`UI:${tileClickEvent}`, { x, y });
|
|
46118
46471
|
}
|
|
46119
46472
|
if (selectedHero && validMoves.some((m) => m.x === x && m.y === y)) {
|
|
46120
|
-
|
|
46121
|
-
|
|
46473
|
+
const heroId = str(selectedHero.id);
|
|
46474
|
+
startMoveAnimation(heroId, { ...heroPosition(selectedHero) }, { x, y }, () => {
|
|
46475
|
+
onHeroMove?.(heroId, x, y);
|
|
46122
46476
|
if (heroMoveEvent) {
|
|
46123
|
-
eventBus.emit(`UI:${heroMoveEvent}`, { heroId
|
|
46477
|
+
eventBus.emit(`UI:${heroMoveEvent}`, { heroId, toX: x, toY: y });
|
|
46124
46478
|
}
|
|
46125
|
-
|
|
46126
|
-
|
|
46479
|
+
const feature = str(hex.feature);
|
|
46480
|
+
if (feature && feature !== "none") {
|
|
46481
|
+
onFeatureEnter?.(heroId, hex);
|
|
46127
46482
|
if (featureEnterEvent) {
|
|
46128
|
-
eventBus.emit(`UI:${featureEnterEvent}`, { heroId
|
|
46483
|
+
eventBus.emit(`UI:${featureEnterEvent}`, { heroId, feature, hex });
|
|
46129
46484
|
}
|
|
46130
46485
|
}
|
|
46131
46486
|
});
|
|
46132
46487
|
return;
|
|
46133
46488
|
}
|
|
46134
|
-
const enemy = heroes.find((h) =>
|
|
46489
|
+
const enemy = heroes.find((h) => {
|
|
46490
|
+
const hp = heroPosition(h);
|
|
46491
|
+
return hp.x === x && hp.y === y && heroOwner(h) === "enemy";
|
|
46492
|
+
});
|
|
46135
46493
|
if (selectedHero && enemy && attackTargets.some((t) => t.x === x && t.y === y)) {
|
|
46136
|
-
|
|
46494
|
+
const attackerId = str(selectedHero.id);
|
|
46495
|
+
const defenderId = str(enemy.id);
|
|
46496
|
+
onBattleEncounter?.(attackerId, defenderId);
|
|
46137
46497
|
if (battleEncounterEvent) {
|
|
46138
|
-
eventBus.emit(`UI:${battleEncounterEvent}`, { attackerId
|
|
46498
|
+
eventBus.emit(`UI:${battleEncounterEvent}`, { attackerId, defenderId });
|
|
46139
46499
|
}
|
|
46140
46500
|
}
|
|
46141
46501
|
}, [hexes, heroes, selectedHero, validMoves, attackTargets, startMoveAnimation, onHeroMove, onFeatureEnter, onBattleEncounter, eventBus, tileClickEvent, heroMoveEvent, featureEnterEvent, battleEncounterEvent]);
|
|
46142
46502
|
const handleUnitClick = useCallback((unitId) => {
|
|
46143
|
-
const hero = heroes.find((h) => h.id === unitId);
|
|
46144
|
-
if (hero && (hero
|
|
46503
|
+
const hero = heroes.find((h) => str(h.id) === unitId);
|
|
46504
|
+
if (hero && (heroOwner(hero) === "player" || allowMoveAllHeroes)) {
|
|
46145
46505
|
onHeroSelect?.(unitId);
|
|
46146
46506
|
if (heroSelectEvent) {
|
|
46147
46507
|
eventBus.emit(`UI:${heroSelectEvent}`, { heroId: unitId });
|
|
@@ -46214,6 +46574,7 @@ var init_WorldMapBoard = __esm({
|
|
|
46214
46574
|
init_Stack();
|
|
46215
46575
|
init_LoadingState();
|
|
46216
46576
|
init_IsometricCanvas2();
|
|
46577
|
+
init_boardEntity();
|
|
46217
46578
|
init_isometric();
|
|
46218
46579
|
WorldMapBoard.displayName = "WorldMapBoard";
|
|
46219
46580
|
}
|
|
@@ -46317,12 +46678,12 @@ var init_XPBar = __esm({
|
|
|
46317
46678
|
}
|
|
46318
46679
|
});
|
|
46319
46680
|
function lazyThree(name, loader) {
|
|
46320
|
-
const Lazy =
|
|
46681
|
+
const Lazy = React80__default.lazy(() => loader().then((m) => ({ default: m[name] })));
|
|
46321
46682
|
function ThreeWrapper(props) {
|
|
46322
|
-
return
|
|
46323
|
-
|
|
46683
|
+
return React80__default.createElement(
|
|
46684
|
+
React80__default.Suspense,
|
|
46324
46685
|
{ fallback: null },
|
|
46325
|
-
|
|
46686
|
+
React80__default.createElement(Lazy, props)
|
|
46326
46687
|
);
|
|
46327
46688
|
}
|
|
46328
46689
|
ThreeWrapper.displayName = `Lazy(${name})`;
|
|
@@ -46337,7 +46698,7 @@ var init_component_registry_generated = __esm({
|
|
|
46337
46698
|
init_ActionButtons();
|
|
46338
46699
|
init_ActionPalette();
|
|
46339
46700
|
init_ActionTile();
|
|
46340
|
-
|
|
46701
|
+
init_AnimatedCounter2();
|
|
46341
46702
|
init_AnimatedGraphic();
|
|
46342
46703
|
init_AnimatedReveal();
|
|
46343
46704
|
init_ArticleSection();
|
|
@@ -46608,7 +46969,7 @@ var init_component_registry_generated = __esm({
|
|
|
46608
46969
|
"ActionTile": ActionTile,
|
|
46609
46970
|
"Alert": AlertPattern,
|
|
46610
46971
|
"AlertPattern": AlertPattern,
|
|
46611
|
-
"AnimatedCounter":
|
|
46972
|
+
"AnimatedCounter": AnimatedCounter2,
|
|
46612
46973
|
"AnimatedGraphic": AnimatedGraphic,
|
|
46613
46974
|
"AnimatedReveal": AnimatedReveal,
|
|
46614
46975
|
"ArticleSection": ArticleSection,
|
|
@@ -46938,7 +47299,7 @@ function SuspenseConfigProvider({
|
|
|
46938
47299
|
config,
|
|
46939
47300
|
children
|
|
46940
47301
|
}) {
|
|
46941
|
-
return
|
|
47302
|
+
return React80__default.createElement(
|
|
46942
47303
|
SuspenseConfigContext.Provider,
|
|
46943
47304
|
{ value: config },
|
|
46944
47305
|
children
|
|
@@ -47423,7 +47784,7 @@ function renderPatternChildren(children, onDismiss, parentId = "root", parentPat
|
|
|
47423
47784
|
const key = `${parentId}-${index}-trait:${traitName}`;
|
|
47424
47785
|
return /* @__PURE__ */ jsx(TraitFrame, { traitName }, key);
|
|
47425
47786
|
}
|
|
47426
|
-
return /* @__PURE__ */ jsx(
|
|
47787
|
+
return /* @__PURE__ */ jsx(React80__default.Fragment, { children: child }, `${parentId}-${index}`);
|
|
47427
47788
|
}
|
|
47428
47789
|
if (!child || typeof child !== "object") return null;
|
|
47429
47790
|
const childId = `${parentId}-${index}`;
|
|
@@ -47463,14 +47824,14 @@ function isPatternConfig(value) {
|
|
|
47463
47824
|
if (value === null || value === void 0) return false;
|
|
47464
47825
|
if (typeof value !== "object") return false;
|
|
47465
47826
|
if (Array.isArray(value)) return false;
|
|
47466
|
-
if (
|
|
47827
|
+
if (React80__default.isValidElement(value)) return false;
|
|
47467
47828
|
if (value instanceof Date) return false;
|
|
47468
47829
|
if (typeof value === "function") return false;
|
|
47469
47830
|
const record = value;
|
|
47470
47831
|
return "type" in record && typeof record.type === "string";
|
|
47471
47832
|
}
|
|
47472
47833
|
function isPlainConfigObject(value) {
|
|
47473
|
-
if (
|
|
47834
|
+
if (React80__default.isValidElement(value)) return false;
|
|
47474
47835
|
if (value instanceof Date) return false;
|
|
47475
47836
|
const proto = Object.getPrototypeOf(value);
|
|
47476
47837
|
return proto === Object.prototype || proto === null;
|